| 1296 | //----------------------------------------------------------------------------- |
| 1297 | |
| 1298 | std::string GetTypeNameAsParameter(const QualType& t, std::string_view varName, const Unqualified unqualified) |
| 1299 | { |
| 1300 | const bool isFunctionPointer = |
| 1301 | HasTypeWithSubType<ReferenceType, FunctionProtoType>(t.getCanonicalType()) or |
| 1302 | HasTypeWithSubType<ReferenceType, PointerType, FunctionProtoType>(t.getCanonicalType()); |
| 1303 | const bool isArrayRef = HasTypeWithSubType<ReferenceType, ArrayType>(t); |
| 1304 | // Special case for Issue81, auto returns an array-ref and to catch auto deducing an array (Issue106) |
| 1305 | const bool isAutoType = (nullptr != dyn_cast_or_null<AutoType>(t.getTypePtrOrNull())); |
| 1306 | const auto pointerToArrayBaseType = isAutoType ? t->getContainedAutoType()->getDeducedType() : t; |
| 1307 | const bool isPointerToArray = HasTypeWithSubType<PointerType, ArrayType>(pointerToArrayBaseType); |
| 1308 | // Only treat this as an array if it is a top-level arry. Typdef's et all can hide the arrayness. |
| 1309 | const bool isRawArrayType = |
| 1310 | t->isArrayType() and not(isa<TypedefType>(t) or isa<ElaboratedType>(t) or isa<UsingType>(t)); |
| 1311 | |
| 1312 | std::string typeName = details::GetName(t, unqualified); |
| 1313 | |
| 1314 | // Sometimes we get char const[2]. If we directly insert the typename we end up with char const__var[2] which is not |
| 1315 | // a valid type name. Hence check for this condition and, if necessary, insert a space before __var. |
| 1316 | auto getSpaceOrEmpty = [&](const std::string_view& needle) -> std::string_view { |
| 1317 | if(not Contains(typeName, needle)) { |
| 1318 | return " "; |
| 1319 | } |
| 1320 | |
| 1321 | return {}; |
| 1322 | }; |
| 1323 | |
| 1324 | if(isRawArrayType and not t->isLValueReferenceType()) { |
| 1325 | const auto space = getSpaceOrEmpty(" ["sv); |
| 1326 | InsertBefore(typeName, "["sv, StrCat(space, varName)); |
| 1327 | |
| 1328 | } else if(isArrayRef) { |
| 1329 | const bool isRValueRef{HasTypeWithSubType<RValueReferenceType, ArrayType>(t)}; |
| 1330 | const std::string_view contains{isRValueRef ? "(&&" : "(&"}; |
| 1331 | |
| 1332 | if(Contains(typeName, contains)) { |
| 1333 | InsertAfter(typeName, contains, varName); |
| 1334 | } else { |
| 1335 | const std::string_view insertBefore{isRValueRef ? "&&[" : "&["}; |
| 1336 | |
| 1337 | InsertBefore(typeName, insertBefore, "("sv); |
| 1338 | |
| 1339 | // check whether we are dealing with a function or an array |
| 1340 | if(Contains(typeName, contains)) { |
| 1341 | InsertAfter(typeName, contains, StrCat(varName, ")"sv)); |
| 1342 | } else { |
| 1343 | InsertAfter(typeName, typeName, StrCat(" "sv, varName)); |
| 1344 | } |
| 1345 | } |
| 1346 | |
| 1347 | } else if(isFunctionPointer) { |
| 1348 | const bool isRValueRef{HasTypeWithSubType<RValueReferenceType, FunctionProtoType>(t)}; |
| 1349 | const auto contains{[&]() { |
| 1350 | if(isRValueRef) { |
| 1351 | return "(&&"sv; |
| 1352 | } |
| 1353 | |
| 1354 | else if(HasTypeWithSubType<LValueReferenceType, PointerType, FunctionProtoType>(t)) { |
| 1355 | return "(*&"sv; |
no test coverage detected