218, mHelper{lambdaCallerType, GetBuffer(outputFormatHelper)}
220 mStack.
push(mHelper);
226 if(not mStack.empty()) {
227 mStack.pop()->finish();
237 for(
auto& l : mStack) {
238 switch(l.callerType()) {
250 return outputFormatHelper;
256 return isArrow ?
"->"sv :
"."sv;
284 if(not stmt->isImplicitAccess()) {
298 auto& langOpts{
GetLangOpts(*rangeForStmt->getLoopVariable())};
299 const bool onlyCpp11{not langOpts.CPlusPlus17};
301 auto* rwStmt =
const_cast<CXXForRangeStmt*
>(rangeForStmt);
303 StmtsContainer outerScopeStmts{};
306 outerScopeStmts.Add(rangeForStmt->getInit());
309 outerScopeStmts.Add(rangeForStmt->getRangeStmt());
312 outerScopeStmts.Add(rangeForStmt->getBeginStmt());
313 outerScopeStmts.Add(rangeForStmt->getEndStmt());
317 StmtsContainer bodyStmts{};
318 bodyStmts.Add(rangeForStmt->getLoopVarStmt());
321 bodyStmts.AddBodyStmts(rwStmt->getBody());
323 const auto& ctx = rangeForStmt->getLoopVariable()->getASTContext();
327 auto* declStmt = [&]() -> DeclStmt* {
329 return mkDeclStmt(rwStmt->getBeginStmt() ? rwStmt->getBeginStmt()->getSingleDecl() : nullptr,
330 rwStmt->getEndStmt() ? rwStmt->getEndStmt()->getSingleDecl() : nullptr);
336 auto* innerScope =
mkCompoundStmt(bodyStmts, rangeForStmt->getBeginLoc(), rangeForStmt->getEndLoc());
338 auto* forStmt =
new(ctx) ForStmt(ctx,
341 rwStmt->getLoopVariable(),
344 rangeForStmt->getBeginLoc(),
345 rangeForStmt->getEndLoc(),
346 rangeForStmt->getEndLoc());
348 outerScopeStmts.Add(forStmt);
350 auto* outerScope =
mkCompoundStmt(outerScopeStmts, rangeForStmt->getBeginLoc(), rangeForStmt->getEndLoc());
359 const NestedNameSpecifier
364 const bool hasTemplateKeyword)
368 declName.getAsString());
396 const auto* templatedDecl = stmt->getTemplatedDecl();
415 for(
OnceTrue first{};
const auto* spec : stmt->specializations()) {
416 if(TSK_ExplicitSpecialization == spec->getSpecializationKind()) {
506 if(stmt->getSubStmt()) {
514 const bool hasInit{stmt->getInit() or stmt->getConditionVariable()};
538 auto* rwStmt =
const_cast<WhileStmt*
>(stmt);
539 auto* conditionVar{rwStmt->getConditionVariable()};
555 if(not conditionVar) {
559 StmtsContainer bodyStmts{};
561 bodyStmts.AddBodyStmts(rwStmt->getBody());
562 bodyStmts.AddBodyStmts(
Assign(conditionVar, conditionVar->getInit()));
578 const CXXRecordDecl& cxxRecordDecl)
580 if(cxxRecordDecl.isLambda()) {
581 llvm::DenseMap<const ValueDecl*, FieldDecl*> captures{};
582 FieldDecl* thisCapture{};
584 cxxRecordDecl.getCaptureFields(captures, thisCapture);
586 if(&fieldDecl == thisCapture) {
589 for(
const auto& [key, value] : captures) {
590 if(&fieldDecl == value) {
609 const auto* base = stmt->getBase();
610 const bool skipBase{[&] {
611 if(
const auto* implicitCast = dyn_cast_or_null<ImplicitCastExpr>(base)) {
612 if(CastKind::CK_UncheckedDerivedToBase == implicitCast->getCastKind()) {
614 return isa<CXXThisExpr>(implicitCast->IgnoreImpCasts());
627 const auto* meDecl = stmt->getMemberDecl();
628 bool skipTemplateArgs{
false};
629 const auto name = [&]() -> std::string {
632 if(
const auto* m = dyn_cast_or_null<CXXMethodDecl>(meDecl)) {
633 if(
const auto* rd = m->getParent(); rd and rd->isLambda() and isa<CXXConversionDecl>(m)) {
634 skipTemplateArgs =
true;
641 else if(
const auto* fd = dyn_cast_or_null<FieldDecl>(meDecl)) {
642 if(
const auto* cxxRecordDecl = dyn_cast_or_null<CXXRecordDecl>(fd->getParent())) {
644 return fieldName.value();
652 if(
const auto* convDecl = dyn_cast_or_null<CXXConversionDecl>(meDecl)) {
656 return stmt->getMemberNameInfo().getName().getAsString();
669 if(
const auto cxxMethod = dyn_cast_or_null<CXXMethodDecl>(meDecl)) {
670 if(
const auto* tmplArgs = cxxMethod->getTemplateSpecializationArgs()) {
671 OutputFormatHelper ofm{};
676 for(
OnceFalse needsComma{};
const auto& arg : tmplArgs->asArray()) {
677 if(arg.getKind() == TemplateArgument::Integral) {
678 ofm.AppendComma(needsComma);
680 ofm.Append(arg.getAsIntegral());
691 }
else if(not isa<CXXConversionDecl>(meDecl)) {
704 if(not stmt->isArgumentType()) {
705 const auto* argExpr = stmt->getArgumentExpr();
706 const bool needsParens{not isa<ParenExpr>(argExpr)};
718 const auto& type = stmt->getType();
719 const bool isSigned = type->isSignedIntegerType();
738 if(stmt->isTypeOperand()) {
739 mOutputFormatHelper.Append(GetName(stmt->getTypeOperand(const_cast<ASTContext&>(GetGlobalAST()))));
741 InsertArg(stmt->getExprOperand());
751 BackupAndRestore _{
mLastExpr, stmt->getLHS()};
753 const bool needLHSParens{isa<BinaryOperator>(stmt->getLHS()->IgnoreImpCasts())};
758 const bool needRHSParens{isa<BinaryOperator>(stmt->getRHS()->IgnoreImpCasts())};
767 const bool needLHSParens{isa<BinaryOperator>(stmt->getLHS()->IgnoreImpCasts())};
773 const bool needCast{stmt->getLHS()->getType() != stmt->getComputationLHSType()};
779 if(stmt->getDependence() != ExprDependenceScope::ExprDependence::None) {
780 InsertArg(stmt->getLHS());
782 clang::ExprResult res = stmt->getLHS();
786 if(const auto resultingType = GetGlobalCI().getSema().PrepareScalarCast(res, stmt->getComputationLHSType());
787 resultingType != CK_NoOp) {
788 const QualType castDestType = stmt->getComputationLHSType();
789 FormatCast(kwStaticCast, castDestType, stmt->getLHS(), resultingType);
791 InsertArg(stmt->getLHS());
797 " "sv, BinaryOperator::getOpcodeStr(BinaryOperator::getOpForCompoundAssignment(stmt->getOpcode())),
" "sv);
799 const bool needRHSParens{isa<BinaryOperator>(stmt->getRHS()->IgnoreImpCasts())};
819 return VarDecl::getStorageClassSpecifierString(sc);
830 if(not ret.empty()) {
840 std::string qualifiers{};
842 if(vd.isInline() or vd.isInlineSpecified()) {
848 if(vd.isConstexpr()) {
858 std::string name{std::move(defaultName)};
860 if(
const auto* tvd = dyn_cast_or_null<VarTemplateSpecializationDecl>(decl)) {
864 codeGenerator->InsertTemplateArgs(tvd->getTemplateArgs());
866 name += outputFormatHelper;
883 if(isa<DecompositionDecl>(expr->getDecl())) {
890 for(
const auto* child : stmt->children()) {
915 bool mHaveTemporary{};
917 std::string mTempName{};
918 std::vector<VarDecl*> mDecls{};
922 : codeGenerator{_codeGenerator}
923 , mPrevStmt{const_cast<
Stmt*>(stmt)}
929 for(
auto d : mDecls) {
935 if(
auto* expr = dyn_cast_or_null<CXXConstructExpr>(stmt)) {
940 auto* vd =
Variable(mTempName, expr->getType(), dummy->getDeclContext());
941 dummy->getDeclContext()->addDecl(vd);
942 vd->setInit(
const_cast<CXXConstructExpr*
>(expr));
943 vd->setStorageClass(SC_None);
947 auto* vd = ImplicitParamDecl::Create(
const_cast<ASTContext&
>(ctx),
948 ctx.getTranslationUnitDecl(),
950 &ctx.Idents.get(mTempName),
952 ImplicitParamKind::Other);
959 }
else if(
auto* expr = dyn_cast_or_null<InitListExpr>(stmt)) {
961 auto* vd =
Variable(mTempName, expr->getType());
962 vd->setInit(
const_cast<InitListExpr*
>(expr));
975 bool Found()
const {
return mFound; }
977 std::string
Name()
const {
return mTempName; }
984 auto* vd =
Variable(mTempName, expr->getType());
990 auto* ctorConstructExpr = CXXConstructExpr::Create(
GetGlobalAST(),
993 expr->getConstructor(),
995 {expr->getArgs(), expr->getNumArgs()},
996 expr->hadMultipleCandidates(),
997 expr->isListInitialization(),
998 expr->isStdInitListInitialization(),
999 expr->requiresZeroInitialization(),
1000 expr->getConstructionKind(),
1001 expr->getParenOrBraceRange());
1003 vd->setInit(ctorConstructExpr);
1009 mDecls.push_back(vd);
1013 void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr* stmt)
1017 const auto name =
MakeLineColumnName(ctx.getSourceManager(), stmt->getBeginLoc(),
"temp"sv);
1020 auto* vd =
Variable(name, stmt->getType());
1034 vd->setInit(stmt->getSubExpr());
1039 if(SD_FullExpression == stmt->getStorageDuration() and not mHaveTemporary) {
1041 mHaveTemporary =
true;
1042 }
else if(
const auto* extending = stmt->getExtendingDecl()) {
1046 mDecls.push_back(vd);
1051 auto* tmp = mPrevStmt;
1054 for(
auto* child : stmt->children()) {
1070 static SmallVector<std::pair<std::pair<const CXXRecordDecl*, const CXXRecordDecl*>, VarDecl*>, 10>
1078 auto iter = std::ranges::find_if(
1079 gVtables, [&](
const auto& e) {
return (e.first.first == record) and (e.first.second == recordB); });
1082 iter = std::ranges::find_if(
gVtables, [&](
const auto& e) {
return e.first.first == record; });
1085 return std::distance(
gVtables.begin(), iter);
1089void PushVtableEntry(
const CXXRecordDecl* record,
const CXXRecordDecl* recordB, VarDecl* decl)
1091 gVtables.push_back({{record, recordB}, decl});
1120 ofm.AppendNewLine();
1124 SmallVector<Expr*, 16> mInitExprs{};
1131 ofm.AppendNewLine();
1135 vtable->setInit(
InitList(mInitExprs, vtable->getType()));
1137 cg->InsertArg(vtable);
1139 ofm.AppendNewLine();
1142 cg->InsertArg(cxaStartFun);
1153 ofm.AppendNewLine();
1154 cg->InsertArg(cxaAtExitFun);
1156 return ofm.GetString();
1181 return stmt and stmt->getNumExprs() and isa_and_nonnull<PackExpansionExpr>(stmt->getExpr(0)) and
1182 stmt->getType().isNull();
1191 for(
const auto* decl : stmt->decls()) {
1203 pp.adjustForCPlusPlus();
1207 ::llvm::raw_string_ostream stream{init};
1208 param.printAsInit(stream, pp);
1216 "static constexpr ",
GetName(param.getType().getUnqualifiedType()),
" ", varName, init);
1224 for(
const auto& arg : array) {
1225 if(TemplateArgument::Declaration != arg.getKind()) {
1227 }
else if(
const auto decl = dyn_cast_or_null<TemplateParamObjectDecl>(arg.getAsDecl())) {
1236 if(
const auto* fd = dyn_cast_or_null<FunctionDecl>(&decl)) {
1237 if(
const auto* specArgs = fd->getTemplateSpecializationArgs()) {
1240 }
else if(
const auto* vd = dyn_cast_or_null<VarTemplateSpecializationDecl>(&decl)) {
1242 }
else if(
const auto* clsTemplateSpe = dyn_cast_or_null<ClassTemplateSpecializationDecl>(&decl)) {
1252 if(
auto* init = stmt->getInit();
1254 (not(isa<CallExpr>(init) or
1255 (isa<ExprWithCleanups>(init) and
1256 (isa<CallExpr>(dyn_cast_or_null<ExprWithCleanups>(init)->getSubExpr()) or
1257 isa<MaterializeTemporaryExpr>(dyn_cast_or_null<ExprWithCleanups>(init)->getSubExpr())))))) {
1265 if(BindingDeclFinder isBindingDecl{}; isBindingDecl.Find(stmt->getInit())) {
1272 TemporaryDeclFinder temporaryFinder{*
this, stmt->getInit()};
1280 const bool needsGuard = stmt->isOutOfLine() and isTemplateInstantiation(stmt->getTemplateSpecializationKind());
1284 if(stmt->isOutOfLine()) {
1285 if(
const auto* recordDecl = dyn_cast_or_null<CXXRecordDecl>(stmt->getDeclContext())) {
1286 if(
const auto* classTmpl = recordDecl->getDescribedClassTemplate()) {
1292 if(isa<VarTemplateSpecializationDecl>(stmt)) {
1294 }
else if(needsGuard) {
1308 const bool isMemberPointer{isa<MemberPointerType>(desugaredType.getTypePtrOrNull())};
1309 if(desugaredType->isFunctionPointerType() or isMemberPointer) {
1310 const auto lineNo =
GetSM(*stmt).getSpellingLineNumber(stmt->getSourceRange().getBegin());
1312 const auto funcPtrName{
StrCat(ptrPrefix, lineNo)};
1320 const auto scope = [&] {
1321 if(
const auto* ctx = stmt->getDeclContext(); stmt->getLexicalDeclContext() != ctx) {
1322 OutputFormatHelper scopeOfm{};
1323 scopeOfm.Append(
GetDeclContext(ctx, WithTemplateParameters::Yes));
1328 return std::string{};
1337 const std::string_view pointer = [&]() {
1342 if(stmt->getType()->isAnyPointerType()) {
1351 if(
const auto* init = stmt->getInit()) {
1352 if(
const auto* ctorExpr = dyn_cast_or_null<CXXConstructExpr>(init);
1367 if(stmt->hasGlobalStorage()) {
1368 if(ctorExpr->getConstructor()->isDefaultConstructor() and
1369 ctorExpr->getConstructor()->getParent()->hasTrivialDefaultConstructor()) {
1380 stmt->getType(), stmt,
ArgsToExprVector(ctorExpr), DoCast::No, AsReference::Yes);
1396 if(MyOptional<const InitListExpr*> initList{dyn_cast_or_null<InitListExpr>(init)};
1398 initList.and_then(CanonicalType).and_then(Isa<RecordType>).and_not(IsPointer).and_then(IsPOD) and
1399 not isa<ArrayType>(stmt->getType())) {
1404 if(stmt->hasGlobalStorage()) {
1413 initList.and_then(CanonicalType)
1414 .and_then(Isa<RecordType>)
1417 (0 == initList.value()->getNumInits()))) {
1421 if(not(ctorExpr and ctorExpr->getConstructor()->isDefaultConstructor() and
1422 ctorExpr->getConstructor()->getParent()->hasTrivialDefaultConstructor())) {
1424 const bool isPrimaryTemplatePackExpansionExpr{
1427 if(not isa<CXXParenListInitExpr>(init) and not isPrimaryTemplatePackExpansionExpr) {
1433 stmt->getType()->isRValueReferenceType()) {
1435 if(GetInsightsOptions().UseShow2C) {
1436 mOutputFormatHelper.Append(
"&");
1449 (stmt->getStorageDuration() == SD_Static) and
1450 (stmt->getDeclContext()->isNamespace() or
1451 (is{stmt->getStorageClass()}.any_of(SC_Static, SC_Extern)))) {
1455 if(stmt->isNRVOVariable()) {
1464 if(
const auto* decompDecl = dyn_cast_or_null<DecompositionDecl>(stmt)) {
1467 codeGenerator.InsertDecompositionBindings(*decompDecl);
1472 mOutputFormatHelper.InsertEndIfTemplateGuard();
1479 if(not(cxxMethodDecl and cxxMethodDecl->isLambdaStaticInvoker())) {
1492 if(not cxxMethodDecl->getReturnType()->isVoidType()) {
1498 if(cxxMethodDecl->isFunctionTemplateSpecialization()) {
1502 if(cxxMethodDecl->isTemplated()) {
1503 if(cxxMethodDecl->getDescribedTemplate()) {
1505 TemplateParamsOnly::Yes);
1514 OutputFormatHelper::NameOnly::Yes,
1515 OutputFormatHelper::GenMissingParamName::Yes);
1530 const SourceLocation& instLoc,
1531 std::string_view text)
1533 const auto lineNo = sm.getSpellingLineNumber(instLoc);
1534 const auto& fileId = sm.getFileID(instLoc);
1535 if(
const auto file = sm.getFileEntryRefForID(fileId)) {
1536 const auto fileWithDirName = file->getName();
1537 const auto fileName = llvm::sys::path::filename(fileWithDirName);
1540 text =
"First instantiated from: "sv;
1550 if(stmt->isTemplateInstantiation() and stmt->isFunctionTemplateSpecialization()) {
1559 if(stmt->isTemplateInstantiation() and stmt->isFunctionTemplateSpecialization()) {
1582 if(isa<CoyieldExpr>(stmt)) {
1589 if(
const auto* matTemp = dyn_cast_or_null<MaterializeTemporaryExpr>(stmt->getCommonExpr())) {
1590 const auto* temporary = matTemp->getSubExpr();
1592 if(
const auto* memExpr = dyn_cast_or_null<CXXMemberCallExpr>(temporary)) {
1593 ForEachArg(memExpr->arguments(), [&](
const auto& arg) { InsertArg(arg); });
1599 }
else if(
const auto* unaryexpr = dyn_cast_or_null<UnaryOperator>(stmt->getOperand())) {
1600 if(
const auto* callExpr = dyn_cast_or_null<CallExpr>(unaryexpr->getSubExpr())) {
1616 auto IsPrimaryTemplate = [&] {
1618 if(
const auto* cxxMethod = dyn_cast_or_null<CXXMethodDecl>(stmt)) {
1619 if(
const auto* tmpl = cxxMethod->getParent()->getDescribedClassTemplate();
1620 tmpl and not isa<ClassTemplateSpecializationDecl>(cxxMethod->getParent())) {
1625 return (FunctionDecl::TK_FunctionTemplate == stmt->getTemplatedKind()) or
1629 if(stmt->doesThisDeclarationHaveABody()) {
1634 if(
const auto* corBody = dyn_cast_or_null<CoroutineBodyStmt>(stmt->getBody());
1635 (
nullptr != corBody) and not IsPrimaryTemplate() and
GetInsightsOptions().ShowCoroutineTransformation) {
1638 codeGenerator.InsertCoroutine(*stmt, corBody);
1640 const auto exSpec = stmt->getExceptionSpecType();
1641 const bool showNoexcept =
1645 if(stmt->hasImplicitReturnZero()) {
1647 [](
const Stmt* e) { return isa<ReturnStmt>(e); });
1650 const auto* body = stmt->getBody();
1659 for(
const auto* param : stmt->parameters()) {
1660 auto paramType = param->getType();
1661 const bool isPassByValue{not paramType->isPointerType() and not paramType->isReferenceType()};
1662 if(
const auto* rd = paramType->getAsRecordDecl(); rd and isPassByValue) {
1686 dt.TraverseType(stmt->getReturnType());
1689 for(
const auto& param : stmt->parameters()) {
1690 P0315Visitor dt{*
this};
1691 dt.TraverseType(param->getType());
1695 if(
const auto* deductionGuide = dyn_cast_or_null<CXXDeductionGuideDecl>(stmt)) {
1697 }
else if(
const auto* ctor = dyn_cast_or_null<CXXConstructorDecl>(stmt)) {
1702 RETURN_IF(isa<CXXConversionDecl>(stmt) and not stmt->hasBody());
1720 if(typeConstraint) {
1722 sstream.
Print(*typeConstraint);
1724 return sstream.str();
1748 expr = expr->IgnoreParenImpCasts();
1751 if(Expr::EvalResult evalResult{};
1752 isa<CXXFunctionalCastExpr>(expr) and
1753 expr->EvaluateAsConstantExpr(evalResult,
GetGlobalAST(), ConstantExprKind::Normal)) {
1754 return std::pair<QualType, APValue>{expr->getType(), evalResult.Val};
1762 const TemplateParamsOnly templateParamsOnly)
1764 const bool full{TemplateParamsOnly::No == templateParamsOnly};
1767 for(
const auto* param : list) {
1768 if(
const auto* nonTmplParam = dyn_cast_or_null<NonTypeTemplateParmDecl>(param);
1769 nonTmplParam and nonTmplParam->hasDefaultArgument()) {
1772 auto* init =
GetGlobalAST().getTemplateParamObjectDecl(val->first, val->second);
1784 for(
OnceFalse needsComma{};
const auto* param : list) {
1787 const auto& typeName =
GetName(*param);
1789 if(
const auto* tt = dyn_cast_or_null<TemplateTypeParmDecl>(param)) {
1791 if(tt->wasDeclaredWithTypename()) {
1793 }
else if(not tt->hasTypeConstraint()) {
1800 if(0 == typeName.size() or tt->isImplicit() ) {
1805 not typeConstraint.empty()) {
1814 if(tt->hasDefaultArgument() and not tt->defaultArgumentWasInherited()) {
1815 const auto& defaultArg = tt->getDefaultArgument();
1817 if(
const auto decltypeType = dyn_cast_or_null<DecltypeType>(defaultArg.getArgument().getAsType())) {
1820 InsertArg(decltypeType->getUnderlyingExpr());
1828 }
else if(
const auto* nonTmplParam = dyn_cast_or_null<NonTypeTemplateParmDecl>(param)) {
1830 if(
const auto nttpType = nonTmplParam->getType();
1831 nttpType->isFunctionPointerType() or nttpType->isMemberFunctionPointerType()) {
1836 GetName(nttpType),
" "sv,
Ellipsis(nonTmplParam->isParameterPack()), typeName);
1839 if(nonTmplParam->hasDefaultArgument()) {
1846 }
else if(
const auto* tmplTmplParam = dyn_cast_or_null<TemplateTemplateParmDecl>(param)) {
1851 if(tmplTmplParam->hasDefaultArgument()) {
1877 SmallVector<const ClassTemplateSpecializationDecl*, 10> specializations{};
1880 for(
const auto* spec : stmt->specializations()) {
1883 if(TSK_ImplicitInstantiation == spec->getSpecializationKind()) {
1884 specializations.push_back(spec);
1889 ranges::sort(specializations,
1890 [](
const ClassTemplateSpecializationDecl* a,
const ClassTemplateSpecializationDecl* b) {
1891 return a->getPointOfInstantiation() < b->getPointOfInstantiation();
1894 for(
const auto* spec : specializations) {
1902 for(
OnceFalse needsComma{};
const auto& expr : stmt->children()) {
1922 OnceFalse needsComma{uint64_t{0} != startAt};
1923 for_each(startAt, size, [&](
auto) {
1924 ret.AppendComma(needsComma);
1929 return ret.GetString();
1940 ((stmt->getNumInits() > 1) or stmt->getArrayFiller() or
1941 ((0 < stmt->getNumInits()) and isa<ImplicitValueInitExpr>(stmt->getInit(0))))),
1943 mOutputFormatHelper.IncreaseIndent();
1945 ForEachArg(stmt->inits(), [&](const auto& init) { InsertArg(init); });
1948 if(stmt->getType().getCanonicalType()->isScalarType()) {
1959 if(
const auto* filler = stmt->getArrayFiller()) {
1960 OutputFormatHelper ofm{};
1965 dyn_cast_or_null<ConstantArrayType>(stmt->getType().getTypePtrOrNull()),
1967 stmt->getNumInits());
1973 mOutputFormatHelper.DecreaseIndent();
1979 const auto* subExpr = stmt->getExpr();
1989 if(stmt->isArrayForm()) {
2007 dt.TraverseType(stmt->getType());
2015 if(
const auto& arguments = stmt->arguments(); not arguments.empty()) {
2016 ForEachArg(stmt->arguments(), [&](
const auto& arg) { InsertArg(arg); });
2044 if(stmt->getNumTemplateArgs()) {
2059 auto operatorStr = BinaryOperator::getOpcodeStr(stmt->getOperator());
2063 const auto* init = stmt->getInit();
2065 if(stmt->isLeftFold()) {
2068 mOutputFormatHelper.Append(
" "sv, operatorStr,
" "sv);
2076 if(stmt->isRightFold()) {
2090 if(stmt->isFullySubstituted()) {
2091 const auto* constExpr = dyn_cast_or_null<ConstantExpr>(stmt->getIndexExpr());
2094 constExpr->getAPValueResult().getInt());
2107 const auto& constructorDecl = *stmt->getConstructor();
2112 OutputFormatHelper::NameOnly::Yes,
2113 OutputFormatHelper::GenMissingParamName::Yes);
2156 StringRef opCodeName = UnaryOperator::getOpcodeStr(stmt->getOpcode());
2157 const bool insertBefore{not stmt->isPostfix()};
2165 if(not insertBefore) {
2173 StringStream stream{};
2174 stream.Print(*stmt);
2182 Error(stmt,
"ArrayInitIndexExpr should not be reached in CodeGenerator");
2188 if((not
GetInsightsOptions().UseAltArraySubscriptionSyntax) or stmt->getLHS()->isLValue()) {
2209 const uint64_t size = stmt->getArraySize().getZExtValue();
2213 codeGenerator.
InsertArg(stmt->getSubExpr());
2230 if(insideDecltype) {
2238 if(
const auto* declRefExpr = dyn_cast_or_null<DeclRefExpr>(stmt->getCallee()->IgnoreImpCasts())) {
2239 if(
const auto* fd = dyn_cast_or_null<FunctionDecl>(declRefExpr->getDecl())) {
2240 if((not declRefExpr->getNumTemplateArgs() and
GetInsightsOptions().ShowAllCallExprTemplateParameters) or
2241 isa<UserDefinedLiteral>(stmt)) {
2248 auto* funcDecl = dyn_cast_or_null<FunctionDecl>(stmt->getCalleeDecl());
2251 ForEachArg(stmt->arguments(), [&](
const auto* arg) {
2254 if(const auto* tmpExpr = dyn_cast_or_null<CXXBindTemporaryExpr>(arg)) {
2255 if(const auto* tmp = dyn_cast_or_null<CXXTemporaryObjectExpr>(tmpExpr->getSubExpr())) {
2256 if(GetInsightsOptions().UseShow2C) {
2261 } else if(GetInsightsOptions().ShowLifetime) {
2262 mOutputFormatHelper.Append(GetName(*tmp));
2268 if(
GetInsightsOptions().UseShow2C and funcDecl and (funcDecl->getNumParams() >= parmIdx) and
2270 if(auto* unop = dyn_cast_or_null<UnaryOperator>(arg); not unop or (unop->getOpcode() != UO_AddrOf)) {
2279 if(insideDecltype) {
2280 mLambdaStack.back().setCallerType(LambdaCallerType::Decltype);
2283 mCurrentCallExprPos.reset();
2289 const QualType castDestType = stmt->getTypeAsWritten();
2290 const Expr* subExpr = stmt->getSubExpr();
2292 FormatCast(stmt->getCastName(), castDestType, subExpr, stmt->getCastKind());
2298 const Expr* subExpr = stmt->getSubExpr();
2299 const auto castKind = stmt->getCastKind();
2302 auto isMatchingCast = [](
const CastKind kind,
const bool hideImplicitCasts,
const bool showXValueCasts) {
2304 case CastKind::CK_Dependent: [[fallthrough]];
2305 case CastKind::CK_IntegralCast: [[fallthrough]];
2306 case CastKind::CK_IntegralToBoolean: [[fallthrough]];
2307 case CastKind::CK_IntegralToPointer: [[fallthrough]];
2308 case CastKind::CK_PointerToIntegral: [[fallthrough]];
2309 case CastKind::CK_BitCast: [[fallthrough]];
2310 case CastKind::CK_UncheckedDerivedToBase: [[fallthrough]];
2311 case CastKind::CK_ToUnion:
2314 case CastKind::CK_AtomicToNonAtomic: [[fallthrough]];
2315 case CastKind::CK_DerivedToBase: [[fallthrough]];
2316 case CastKind::CK_FloatingCast: [[fallthrough]];
2317 case CastKind::CK_IntegralToFloating: [[fallthrough]];
2318 case CastKind::CK_FloatingToIntegral: [[fallthrough]];
2319 case CastKind::CK_NonAtomicToAtomic:
return true;
2322 if((showXValueCasts or not hideImplicitCasts) and (CastKind::CK_NoOp == kind)) {
2327 if(not hideImplicitCasts) {
2329 case CastKind::CK_NullToPointer: [[fallthrough]];
2330 case CastKind::CK_NullToMemberPointer: [[fallthrough]];
2333 case CastKind::CK_NoOp: [[fallthrough]];
2334 case CastKind::CK_ArrayToPointerDecay:
return true;
2341 }(castKind, hideImplicitCasts, stmt->isXValue() or
ShowXValueCasts());
2343 if(not isMatchingCast) {
2351 }
else if(isa<IntegerLiteral>(subExpr) and hideImplicitCasts) {
2356 }
else if(stmt->isPartOfExplicitCast()) {
2365 if(isa<CStyleCastExpr>(subExpr) or isa<CXXNamedCastExpr>(subExpr)) {
2373 const QualType castDestType{[&] {
2374 auto type{stmt->getType()};
2377 if(not type->isDependentType()) {
2378 type = type.getCanonicalType();
2383 if(VK_XValue == stmt->getValueKind()) {
2390 FormatCast(castName, castDestType, subExpr, castKind);
2397 if(
const auto* tmplObjParam = dyn_cast_or_null<TemplateParamObjectDecl>(stmt->getDecl())) {
2400 }
else if(
const auto* vd = dyn_cast_or_null<VarDecl>(stmt->getDecl());
2402 const auto* init = vd->getInit();
2404 if(
const auto* dref = dyn_cast_or_null<DeclRefExpr>(init)) {
2408 }
else if(
const auto* inList = dyn_cast_or_null<InitListExpr>(init)) {
2414 if(
const auto* ctx = stmt->getDecl()->getDeclContext(); not ctx->isFunctionOrMethod() and
2415 not isa<NonTypeTemplateParmDecl>(stmt->getDecl()) and
2417 if(
const auto qualifier = stmt->getQualifier();
2420 qualifier.getKind() == NestedNameSpecifier::Kind::Global
2422 qualifier->getKind() == NestedNameSpecifier::SpecifierKind::Global
2431 OutputFormatHelper ofm{};
2443 if(
const auto* varTmplSpecDecl = dyn_cast_or_null<VarTemplateSpecializationDecl>(stmt->getDecl())) {
2462 if(requiresImplicitReturnZero) {
2476template<
typename... Args>
2479 return (... and not isa<Args>(stmt));
2485 for(
const auto* item : stmt->body()) {
2513 if(
const auto* conditionVar = stmt->getConditionVariable()) {
2517 if(
const auto* init = stmt->getInit()) {
2520 if(not isa<DeclStmt>(init)) {
2529 const bool hasInit{stmt->getInit() or stmt->getConditionVariable()};
2540 not stmt->isConsteval(),
2542 mShowConstantExprValue = ShowConstantExprValue::Yes;
2544 InsertArg(stmt->getCond());
2546 mShowConstantExprValue = ShowConstantExprValue::No;
2548 AddSpaceAtTheEnd::Yes);
2556 if(
const auto* elsePart = stmt->getElse()) {
2580 std::string_view mContinueLabel{};
2587 , mContinueLabel{continueLabel}
2608 auto* tmp = mPrevStmt;
2611 for(
auto* child : stmt->children()) {
2627 auto* rwStmt =
const_cast<ForStmt*
>(stmt);
2629 StmtsContainer bodyStmts{};
2631 auto continueLabel =
MakeLineColumnName(ctx.getSourceManager(), stmt->getBeginLoc(),
"__continue_"sv);
2632 const bool insertLabel = ContinueASTTransformer{rwStmt->getBody(), continueLabel}.found;
2634 bodyStmts.AddBodyStmts(rwStmt->getBody());
2638 bodyStmts.Add(
Label(continueLabel));
2641 bodyStmts.Add(rwStmt->getInc());
2643 auto* condition = [&]() -> Expr* {
2644 if(rwStmt->getCond()) {
2645 return rwStmt->getCond();
2651 auto* outerBody =
mkCompoundStmt(bodyStmts, stmt->getBeginLoc(), stmt->getEndLoc());
2652 auto* whileStmt = WhileStmt::Create(
2653 ctx,
nullptr, condition, outerBody, stmt->getBeginLoc(), stmt->getLParenLoc(), stmt->getRParenLoc());
2655 StmtsContainer outerScopeStmts{};
2656 outerScopeStmts.Add(rwStmt->getInit());
2657 outerScopeStmts.Add(whileStmt);
2659 auto* outerScopeBody =
mkCompoundStmt(outerScopeStmts, stmt->getBeginLoc(), stmt->getEndLoc());
2673 if(
const auto* init = stmt->getInit()) {
2674 MultiStmtDeclCodeGenerator codeGenerator{
2675 mOutputFormatHelper, mLambdaStack, InsertVarDecl(nullptr)};
2687 AddSpaceAtTheEnd::Yes);
2693 mOutputFormatHelper.AppendNewLine();
2699 if(not type.isNull()) {
2700 if(
auto* typePtr = type.getTypePtrOrNull()) {
2701 if(
auto pointee = typePtr->getPointeeType(); not pointee.isNull()) {
2702 return pointee.isConstQualified();
2713 const auto castKind = stmt->getCastKind();
2714 const QualType castDestType = stmt->getType().getCanonicalType();
2718 FormatCast(castName, castDestType, stmt->getSubExpr(), castKind);
2730 if(stmt->getNumPlacementArgs()) {
2734 ForEachArg(stmt->placement_arguments(), [&](
const auto& placementArg) { InsertArg(placementArg); });
2738 if(
const auto* ctorExpr = stmt->getConstructExpr()) {
2742 auto name =
GetName(stmt->getAllocatedType());
2745 if(stmt->isArray()) {
2746 OutputFormatHelper ofm{};
2750 codeGenerator->
InsertArg(stmt->getArraySize().value());
2765 if(stmt->hasInitializer()) {
2775 const auto* temporary = stmt->getSubExpr();
2784 const auto* callee = dyn_cast_or_null<DeclRefExpr>(stmt->getCallee()->IgnoreImpCasts());
2785 const bool isCXXMethod{callee and isa<CXXMethodDecl>(callee->getDecl())};
2787 if(2 == stmt->getNumArgs()) {
2788 auto getArg = [&](
unsigned idx) {
2789 const auto* arg = stmt->getArg(idx);
2794 arg = arg->IgnoreImpCasts();
2797 return dyn_cast_or_null<DeclRefExpr>(arg);
2800 const auto* param1 = getArg(0);
2801 const auto* param2 = getArg(1);
2803 if(callee and param1 and param2) {
2804 const std::string replace = [&]() {
2806 auto nameWithTmplArguments = [](
const auto param) {
2810 if(isa<CXXMethodDecl>(callee->getDecl())) {
2811 return StrCat(nameWithTmplArguments(param1),
2815 nameWithTmplArguments(param2),
2820 nameWithTmplArguments(param1),
2822 nameWithTmplArguments(param2),
2833 auto cb = stmt->child_begin();
2834 const auto* fallbackArg0 = stmt->getArg(0);
2838 std::advance(cb, 1);
2840 const auto* arg1 = *cb;
2842 std::advance(cb, 1);
2845 if(not isCXXMethod) {
2848 if(
const auto* adl = dyn_cast_or_null<UnresolvedLookupExpr>(stmt->getCallee())) {
2859 if(isa<DeclRefExpr>(fallbackArg0)) {
2868 const OverloadedOperatorKind opKind = stmt->getOperator();
2876 const auto childRange = llvm::make_range(cb, stmt->child_end());
2879 ForEachArg(childRange, [&](
const auto& child) {
2880 if(not isCXXMethod) {
2897 [](
const LambdaCapture& c) { return (c.getCaptureKind() == LCK_StarThis); })) {
2914 const bool isConstructor{isa<CXXConstructExpr>(stmt->getSubExpr())};
2915 const bool isStdListInit{isa<CXXStdInitializerListExpr>(stmt->getSubExpr())};
2916 const bool isListInitialization{stmt->getLParenLoc().isInvalid()};
2917 const bool needsParens{not isConstructor and not isListInitialization and not isStdListInit};
2920 if(not isConstructor and not isStdListInit) {
2942 StringStream stream{};
2943 stream.Print(*stmt);
2945 auto str = std::move(stream.str());
2947 if(str ==
"'\\x00'"sv) {
2949 }
else if(str ==
"'\\xff'"sv) {
2961 if(
const auto* functionName = stmt->getFunctionName()) {
2964 const auto name = PredefinedExpr::getIdentKindName(stmt->getIdentKind());
2974 TemporaryDeclFinder temporaryFinder{*
this, not
mProcessingVarDecl ? stmt->getSubExpr() :
nullptr};
2988 const QualType& type = t.getCanonicalType();
2990 if(type->isScalarType()) {
2991 switch(type->getScalarTypeKind()) {
2992 case Type::STK_CPointer:
2993 case Type::STK_BlockPointer:
2994 case Type::STK_ObjCObjectPointer:
2995 case Type::STK_MemberPointer:
return std::string{
kwNullptr};
2997 case Type::STK_Bool:
return std::string{
kwFalse};
2999 case Type::STK_Integral:
3000 case Type::STK_Floating:
3001 if(
const auto* bt = type->getAs<BuiltinType>()) {
3002 switch(bt->getKind()) {
3004 case BuiltinType::Char_U:
3005 case BuiltinType::UChar:
3006 case BuiltinType::Char_S:
3007 case BuiltinType::SChar:
return "'\\0'";
3008 case BuiltinType::WChar_U:
3009 case BuiltinType::WChar_S:
return "L'\\0'";
3010 case BuiltinType::Char16:
return "u'\\0'";
3011 case BuiltinType::Char32:
return "U'\\0'";
3013 case BuiltinType::Half:
3014 case BuiltinType::Float:
return "0.0f";
3015 case BuiltinType::Double:
return "0.0";
3022 case Type::STK_FloatingComplex:
3023 case Type::STK_IntegralComplex:
3024 if(
const auto* complexType = type->getAs<ComplexType>()) {
3030 case Type::STK_FixedPoint:
Error(
"STK_FixedPoint is not implemented");
break;
3033 }
else if(
const auto* tt = dyn_cast_or_null<ConstantArrayType>(t.getTypePtrOrNull())) {
3034 const auto& elementType{tt->getElementType()};
3040 return std::string{
"0"sv};
3076 if(not stmt->getCaughtType().isNull()) {
3077 mOutputFormatHelper.Append(
3078 GetTypeNameAsParameter(stmt->getCaughtType(), stmt->getExceptionDecl()->getName()));
3080 mOutputFormatHelper.Append(kwElipsis);
3083 AddSpaceAtTheEnd::Yes);
3100 if(
const auto value = stmt->getAPValueResult(); value.isInt()) {
3112 const auto& underlyingType = stmt->getUnderlyingType();
3115 P0315Visitor dt{*
this};
3116 dt.TraverseType(underlyingType);
3120 if(
auto* templateSpecializationType = underlyingType->getAs<TemplateSpecializationType>()) {
3121 const bool carriesNamespace{[&] {
3122 if(
const auto tn = templateSpecializationType->getTemplateName();
3123 (TemplateName::QualifiedTemplate == tn.getKind()) or (TemplateName::DependentTemplate == tn.getKind())) {
3124 if(
const auto* qtn = tn.getAsQualifiedTemplateName()) {
3125 return static_cast<bool>(qtn->getQualifier());
3132#if not IS_CLANG_NEWER_THAN(22)
3133 if(
const auto* elaboratedType = underlyingType->getAs<ElaboratedType>()) {
3134 if(templateSpecializationType->isSugared() and not carriesNamespace) {
3140 if(TemplateName::DependentTemplate == templateSpecializationType->getTemplateName().getKind()) {
3144 if(templateSpecializationType->isSugared() and not carriesNamespace) {
3146 if(
const auto* typedefType = dyn_cast_or_null<TypedefType>(underlyingType.getTypePtrOrNull())) {
3152 StringStream stream{};
3153 stream.Print(*templateSpecializationType);
3159#if not IS_CLANG_NEWER_THAN(22)
3160 }
else if(
auto* depSpecType = underlyingType->getAs<DependentTemplateSpecializationType>()) {
3163 InsertNamespace(depSpecType->getDependentTemplateName().getQualifier());
3189 CXXConstructorDecl* cxxInheritedCtorDecl{
nullptr};
3193 if(
const auto* ctor = dyn_cast_or_null<CXXConstructorDecl>(stmt)) {
3200 for(
OnceTrue first{};
const auto* init : ctor->inits()) {
3203 initOutputFormatHelper.
Append(
": "sv);
3205 initOutputFormatHelper.
Append(
", "sv);
3210 if(
const auto* member = init->getMember()) {
3211 initOutputFormatHelper.
Append(member->getName());
3214 const auto* inlineInit = init->getInit();
3215 bool useCurlies{
false};
3217 if(
const auto* cxxInheritedCtorInitExpr = dyn_cast_or_null<CXXInheritedCtorInitExpr>(inlineInit)) {
3218 cxxInheritedCtorDecl = cxxInheritedCtorInitExpr->getConstructor();
3222 }
else if(init->isBaseInitializer() and not isa<CXXConstructExpr>(inlineInit)) {
3230 const auto* inlineInit = init->getInit();
3233 if(
const auto* member = init->getMember()) {
3234 initOutputFormatHelper.
Append(member->getName());
3236 if(isa<ParenListExpr>(inlineInit)) {
3242 }
else if(
const auto* cxxInheritedCtorInitExpr = dyn_cast_or_null<CXXInheritedCtorInitExpr>(inlineInit)) {
3243 cxxInheritedCtorDecl = cxxInheritedCtorInitExpr->getConstructor();
3249 }
else if(init->isBaseInitializer() and not isa<CXXConstructExpr>(inlineInit)) {
3276 if(not stmt->isUserProvided() or stmt->isExplicitlyDefaulted()) {
3283 if(isa<CXXConversionDecl>(stmt)) {
3284 if(stmt->getParent()->isLambda() and not stmt->doesThisDeclarationHaveABody()) {
3289 if(
const auto* invoker = stmt->getParent()->getLambdaStaticInvoker()) {
3290 mOutputFormatHelper.AppendSemiNewLine(invoker->getName());
3292 mOutputFormatHelper.AppendSemiNewLine(kwOperator,
"()"sv);
3298 if((SkipBody::No == skipBody) and stmt->doesThisDeclarationHaveABody() and not stmt->isLambdaStaticInvoker()) {
3307 if(SkipBody::No == skipBody) {
3319 not stmt->isExplicitlyDefaulted() and not stmt->isDeleted());
3329 if(stmt->isScoped()) {
3330 if(stmt->isScopedUsingClassTag()) {
3339 if(stmt->isFixed()) {
3351 ForEachArg(stmt->enumerators(), [&](
const auto* value) {
3353 mOutputFormatHelper.AppendNewLine();
3364 AddSpaceAtTheEnd::No);
3366 mOutputFormatHelper.AppendSemiNewLine();
3367 mOutputFormatHelper.AppendNewLine();
3377 if(
const auto* initExpr = stmt->getInitExpr()) {
3394 static const std::string_view spaces{
" "sv};
3396 if(offset >= spaces.size()) {
3399 return spaces.substr(0, spaces.size() - offset);
3407 P0315Visitor dt{*
this};
3409 auto type =
GetType(stmt->getType());
3410 dt.TraverseType(type);
3415 if(stmt->isMutable()) {
3419 if(
const auto* cxxRecordDecl = dyn_cast_or_null<CXXRecordDecl>(stmt->getParent())) {
3420 std::string name{
GetName(*stmt)};
3423 name = std::move(fieldName.value());
3428 if(
const auto* constantExpr = dyn_cast_or_null<ConstantExpr>(stmt->getBitWidth())) {
3434 if(
const auto* initializer = stmt->getInClassInitializer();
3435 stmt->hasInClassInitializer() and initializer and cxxRecordDecl->isAggregate()) {
3436 const bool isConstructorExpr{isa<CXXConstructExpr>(initializer) or isa<ExprWithCleanups>(initializer)};
3437 if((ICIS_ListInit != stmt->getInClassInitStyle()) or isConstructorExpr) {
3448 const auto* fieldClass = stmt->getParent();
3450 auto effectiveFieldSize{
GetGlobalAST().getTypeInfoInChars(type).Width.getQuantity()};
3451 auto getFieldOffsetInBytes = [&recordLayout](
const FieldDecl* field) {
3452 return recordLayout.getFieldOffset(field->getFieldIndex()) / 8;
3454 auto fieldOffset = getFieldOffsetInBytes(stmt);
3466 const auto expectedOffset = fieldOffset + effectiveFieldSize;
3467 const auto nextOffset = [&]() -> uint64_t {
3469 if(
const auto next = stmt->getFieldIndex() + 1; recordLayout.getFieldCount() > next) {
3471 const auto* field = *std::next(fieldClass->fields().begin(), next);
3473 return getFieldOffsetInBytes(field);
3477 return recordLayout.getSize().getQuantity();
3480 if(expectedOffset < nextOffset) {
3481 const auto padding = nextOffset - expectedOffset;
3506 if(not stmt->isFailed()) {
3518 if(stmt->getMessage()) {
3531 if(
const auto& name =
GetName(*stmt->getNominatedNamespace()); not name.empty()) {
3541 if(stmt->isInline()) {
3549 if(not stmt->isAnonymousNamespace()) {
3557 for(
const auto* decl : stmt->decls()) {
3580 if(stmt->shadow_size()) {
3581 for(
const auto* shadow : stmt->shadows()) {
3582 RETURN_IF(isa<ConstructorUsingShadowDecl>(shadow));
3584 if(
const auto* shadowUsing = dyn_cast_or_null<UsingShadowDecl>(shadow)) {
3585 if(
const auto* targetDecl = shadowUsing->getTargetDecl(); not isa<TypeAliasDecl>(targetDecl)) {
3586 UsingCodeGenerator codeGenerator{ofm};
3600 if(not ofm.empty()) {
3625 if(
const auto* typeInfo = stmt->getFriendType()) {
3628 }
else if(
const auto* fd = dyn_cast_or_null<FunctionDecl>(stmt->getFriendDecl())) {
3631 }
else if(
const auto* fdt = dyn_cast_or_null<FunctionTemplateDecl>(stmt->getFriendDecl())) {
3636 if(
const auto* ctd = dyn_cast_or_null<ClassTemplateDecl>(stmt->getFriendDecl())) {
3657 RETURN_IF(DeductionCandidate::Copy == stmt->getDeductionCandidateKind());
3659 const bool isImplicit{stmt->isImplicit()};
3660 const bool noSpecializations = [&] {
3661 if(
const auto* dt = stmt->getDescribedFunctionTemplate()) {
3662 return dt->specializations().empty();
3669 RETURN_IF(not stmt->isUsed() and isImplicit and noSpecializations);
3671 const bool isSpecialization{stmt->isFunctionTemplateSpecialization()};
3672 const bool needsTemplateGuard{isImplicit or isSpecialization};
3674 if(needsTemplateGuard) {
3678 const auto* deducedTemplate = stmt->getDeducedTemplate();
3680 if(isSpecialization) {
3682 }
else if(
const auto* e = stmt->getDescribedFunctionTemplate()) {
3688 if(stmt->getNumParams()) {
3696 if(needsTemplateGuard) {
3715 for(
const auto* spec : stmt->specializations()) {
3717 if(spec->getPreviousDecl()) {
3744 for(
const auto& attr : stmt->getAttrs()) {
3754 if(stmt->hasAttrs()) {
3765 for(
const auto& attr : attrs) {
3774 RETURN_IF(attr::Override == attr.getKind());
3777 RETURN_IF(attr::Final == attr.getKind());
3780 RETURN_IF(attr::NoInline == attr.getKind());
3782#if IS_CLANG_NEWER_THAN(20)
3784 RETURN_IF(attr::InferredNoReturn == attr.getKind());
3788 if(
const auto* alignedAttr = dyn_cast_or_null<AlignedAttr>(&attr)) {
3789 auto insert = [&](
const QualType type,
const TemplateTypeParmType* tmplTypeParam) {
3796 Ellipsis(tmplTypeParam->isParameterPack()),
3800 if(alignedAttr->isAlignmentExpr()) {
3801 if(
const auto* unaryExpr = dyn_cast_or_null<UnaryExprOrTypeTraitExpr>(alignedAttr->getAlignmentExpr())) {
3802 if(
const auto* tmplTypeParam =
3803 dyn_cast_or_null<TemplateTypeParmType>(unaryExpr->getArgumentType().getTypePtrOrNull())) {
3804 insert(unaryExpr->getArgumentType(), tmplTypeParam);
3808 }
else if(
const auto* tmplTypeParam =
3809 alignedAttr->getAlignmentType()->getType()->getAs<TemplateTypeParmType>()) {
3810 insert(alignedAttr->getAlignmentType()->getType(), tmplTypeParam);
3817 pp.adjustForCPlusPlus();
3819 attr.printPretty(stream, pp);
3822 std::string_view start{stream.str()};
3835 const auto* classTemplatePartialSpecializationDecl = dyn_cast_or_null<ClassTemplatePartialSpecializationDecl>(stmt);
3836 const auto* classTemplateSpecializationDecl = dyn_cast_or_null<ClassTemplateSpecializationDecl>(stmt);
3840 const bool isClassTemplateSpecialization{classTemplatePartialSpecializationDecl or classTemplateSpecializationDecl};
3841 const bool tmplRequiresIfDef{[&] {
3842 if(classTemplatePartialSpecializationDecl) {
3843 return classTemplatePartialSpecializationDecl->isImplicit();
3845 }
else if(classTemplateSpecializationDecl) {
3846 return not classTemplateSpecializationDecl->isExplicitInstantiationOrSpecialization();
3853 if(tmplRequiresIfDef) {
3858 if(isClassTemplateSpecialization) {
3859 if(tmplRequiresIfDef) {
3861 classTemplateSpecializationDecl->getPointOfInstantiation());
3865 if(classTemplatePartialSpecializationDecl) {
3871 }
else if(stmt->getLexicalDeclContext() != stmt->getDeclContext()) {
3872 if(
const auto* parent = dyn_cast_or_null<CXXRecordDecl>(stmt->getDeclContext())) {
3873 if(
const auto* outerClasTemplateDecl = parent->getDescribedClassTemplate()) {
3885 if(classTemplateSpecializationDecl) {
3889 if(stmt->hasAttr<FinalAttr>()) {
3894 if(not stmt->hasDefinition() or not stmt->isCompleteDefinition()) {
3899 if(stmt->getNumBases()) {
3902 ForEachArg(stmt->bases(), [&](
const auto& base) {
3903 mOutputFormatHelper.Append(getAccessSpelling(base.getAccessSpecifier()),
3905 ValueOrDefault(base.isVirtual(), kwVirtualSpace),
3906 GetName(base.getType()),
3907 Ellipsis(base.isPackExpansion()));
3914 " /* size: "sv, recordLayout.getSize(),
", align: "sv, recordLayout.getAlignment(),
" */"sv);
3923 for(
size_t offset{};
const auto& base : stmt->bases()) {
3924 const auto& baseRecordLayout =
GetRecordLayout(base.getType()->getAsRecordDecl());
3925 const auto baseVar =
StrCat(
"/* base ("sv,
GetName(base.getType()),
")"sv);
3926 const auto size = baseRecordLayout.getSize().getQuantity();
3929 baseVar,
GetSpaces(baseVar.size()),
" offset: "sv, offset,
", size: "sv, size,
" */"sv);
3937 const bool isLambda{stmt->isLambda()};
3938 Decl::Kind formerKind{};
3939 AccessSpecifier lastAccess{stmt->isClass() ? AS_private : AS_public};
3940 for(
OnceTrue firstRecordDecl{}, firstDecl{};
const auto* d : stmt->decls()) {
3941 if(isa<CXXRecordDecl>(d) and firstRecordDecl) {
3947 if(not firstDecl and (d->getKind() != formerKind)) {
3951 if((isLambda and isa<CXXDestructorDecl>(d)) and not d->isUsed()) {
3957 if(lastAccess != d->getAccess()) {
3958 lastAccess = d->getAccess();
3961 if(not isa<AccessSpecDecl>(d)) {
3966 if(isa<FieldDecl>(d) and isLambda) {
3978 formerKind = d->getKind();
3982 if(isLambda and stmt->lambdaIsDefaultConstructibleAndAssignable()) {
3983 if(AS_public != lastAccess) {
3990 if(stmt->hasConstexprDefaultConstructor()) {
4012 for(
const auto* decl : stmt->decls()) {
4026 if(stmt->isPartiallySubstituted()) {
4028 }
else if(not stmt->isValueDependent()) {
4043 TemporaryDeclFinder temporaryFinder{*
this, stmt->getRetValue(),
true};
4047 if(
const auto* retVal = stmt->getRetValue()) {
4050 if(not temporaryFinder.Found()) {
4051 if(
const auto* nrvoVD = stmt->getNRVOCandidate()) {
4092 if(
const auto* namedConcept = stmt->getNamedConcept()) {
4097 if(not stmt->isValueDependent()) {
4109 const auto localParameters = stmt->getLocalParameters();
4111 not localParameters.empty(),
4112 [&] { mOutputFormatHelper.AppendParameterList(localParameters); },
4113 AddSpaceAtTheEnd::Yes);
4121 for(
const auto& requirement : stmt->getRequirements()) {
4122 if(
const auto* typeRequirement = dyn_cast_or_null<concepts::TypeRequirement>(requirement)) {
4123 if(typeRequirement->isSubstitutionFailure()) {
4130 }
else if(
const auto* exprRequirement = dyn_cast_or_null<concepts::ExprRequirement>(requirement)) {
4131 if(exprRequirement->isExprSubstitutionFailure()) {
4136 WrapInCurliesIfNeeded(exprRequirement->isCompound(), [&] { InsertArg(exprRequirement->getExpr()); });
4138 if(exprRequirement->hasNoexceptRequirement()) {
4142 if(
const auto& returnTypeRequirement = exprRequirement->getReturnTypeRequirement();
4143 not returnTypeRequirement.isEmpty()) {
4145 not typeConstraint.empty()) {
4150 }
else if(
const auto* nestedRequirement = dyn_cast_or_null<concepts::NestedRequirement>(requirement)) {
4153 if(nestedRequirement->hasInvalidConstraint()) {
4158 InsertArg(nestedRequirement->getConstraintExpr());
4179 const auto typeName{
GetName(stmt->getType(), Unqualified::Yes)};
4185 const auto* subExpr = stmt->getSubExpr();
4187 if(
const auto* dref = dyn_cast_or_null<DeclRefExpr>(subExpr); dref and
GetInsightsOptions().ShowLifetime) {
4188 const auto size =
GetSize(dyn_cast_or_null<ConstantArrayType>(subExpr->getType()));
4194 std::string modifiers{};
4198 auto& ofmToInsert = [&]() ->
decltype(
auto) {
4210 OutputFormatHelper ofm{};
4211 ofm.SetIndent(ofmToInsert, OutputFormatHelper::SkipIndenting::Yes);
4213 const auto size = [&]() ->
size_t {
4214 if(
const auto* mat = dyn_cast<MaterializeTemporaryExpr>(subExpr)) {
4215 if(
const auto* list = dyn_cast_or_null<InitListExpr>(mat->getSubExpr())) {
4216 return list->getNumInits();
4223 auto internalListName =
4229 ofm.AppendSemiNewLine();
4231 ofmToInsert.InsertAt(variableInsertPos, ofm);
4266#define SUPPORTED_DECL(type) \
4267 if(isa<type>(stmt)) { \
4268 InsertArg(static_cast<const type*>(stmt)); \
4272#define IGNORED_DECL SUPPORTED_DECL