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* qualifier,
360 const bool hasTemplateKeyword)
364 declName.getAsString());
388 const auto* templatedDecl = stmt->getTemplatedDecl();
407 for(
OnceTrue first{};
const auto* spec : stmt->specializations()) {
408 if(TSK_ExplicitSpecialization == spec->getSpecializationKind()) {
498 if(stmt->getSubStmt()) {
506 const bool hasInit{stmt->getInit() or stmt->getConditionVariable()};
530 auto* rwStmt =
const_cast<WhileStmt*
>(stmt);
531 auto* conditionVar{rwStmt->getConditionVariable()};
547 if(not conditionVar) {
551 StmtsContainer bodyStmts{};
553 bodyStmts.AddBodyStmts(rwStmt->getBody());
554 bodyStmts.AddBodyStmts(
Assign(conditionVar, conditionVar->getInit()));
570 const CXXRecordDecl& cxxRecordDecl)
572 if(cxxRecordDecl.isLambda()) {
573 llvm::DenseMap<const ValueDecl*, FieldDecl*> captures{};
574 FieldDecl* thisCapture{};
576 cxxRecordDecl.getCaptureFields(captures, thisCapture);
578 if(&fieldDecl == thisCapture) {
581 for(
const auto& [key, value] : captures) {
582 if(&fieldDecl == value) {
601 const auto* base = stmt->getBase();
602 const bool skipBase{[&] {
603 if(
const auto* implicitCast = dyn_cast_or_null<ImplicitCastExpr>(base)) {
604 if(CastKind::CK_UncheckedDerivedToBase == implicitCast->getCastKind()) {
606 return isa<CXXThisExpr>(implicitCast->IgnoreImpCasts());
619 const auto* meDecl = stmt->getMemberDecl();
620 bool skipTemplateArgs{
false};
621 const auto name = [&]() -> std::string {
624 if(
const auto* m = dyn_cast_or_null<CXXMethodDecl>(meDecl)) {
625 if(
const auto* rd = m->getParent(); rd and rd->isLambda() and isa<CXXConversionDecl>(m)) {
626 skipTemplateArgs =
true;
633 else if(
const auto* fd = dyn_cast_or_null<FieldDecl>(meDecl)) {
634 if(
const auto* cxxRecordDecl = dyn_cast_or_null<CXXRecordDecl>(fd->getParent())) {
636 return fieldName.value();
644 if(
const auto* convDecl = dyn_cast_or_null<CXXConversionDecl>(meDecl)) {
648 return stmt->getMemberNameInfo().getName().getAsString();
661 if(
const auto cxxMethod = dyn_cast_or_null<CXXMethodDecl>(meDecl)) {
662 if(
const auto* tmplArgs = cxxMethod->getTemplateSpecializationArgs()) {
663 OutputFormatHelper ofm{};
668 for(
OnceFalse needsComma{};
const auto& arg : tmplArgs->asArray()) {
669 if(arg.getKind() == TemplateArgument::Integral) {
670 ofm.AppendComma(needsComma);
672 ofm.Append(arg.getAsIntegral());
683 }
else if(not isa<CXXConversionDecl>(meDecl)) {
696 if(not stmt->isArgumentType()) {
697 const auto* argExpr = stmt->getArgumentExpr();
698 const bool needsParens{not isa<ParenExpr>(argExpr)};
710 const auto& type = stmt->getType();
711 const bool isSigned = type->isSignedIntegerType();
730 if(stmt->isTypeOperand()) {
731 mOutputFormatHelper.Append(GetName(stmt->getTypeOperand(const_cast<ASTContext&>(GetGlobalAST()))));
733 InsertArg(stmt->getExprOperand());
743 BackupAndRestore _{
mLastExpr, stmt->getLHS()};
745 const bool needLHSParens{isa<BinaryOperator>(stmt->getLHS()->IgnoreImpCasts())};
750 const bool needRHSParens{isa<BinaryOperator>(stmt->getRHS()->IgnoreImpCasts())};
759 const bool needLHSParens{isa<BinaryOperator>(stmt->getLHS()->IgnoreImpCasts())};
765 const bool needCast{stmt->getLHS()->getType() != stmt->getComputationLHSType()};
771 if(stmt->getDependence() != ExprDependenceScope::ExprDependence::None) {
772 InsertArg(stmt->getLHS());
774 clang::ExprResult res = stmt->getLHS();
778 if(const auto resultingType = GetGlobalCI().getSema().PrepareScalarCast(res, stmt->getComputationLHSType());
779 resultingType != CK_NoOp) {
780 const QualType castDestType = stmt->getComputationLHSType();
781 FormatCast(kwStaticCast, castDestType, stmt->getLHS(), resultingType);
783 InsertArg(stmt->getLHS());
789 " "sv, BinaryOperator::getOpcodeStr(BinaryOperator::getOpForCompoundAssignment(stmt->getOpcode())),
" "sv);
791 const bool needRHSParens{isa<BinaryOperator>(stmt->getRHS()->IgnoreImpCasts())};
811 return VarDecl::getStorageClassSpecifierString(sc);
822 if(not ret.empty()) {
832 std::string qualifiers{};
834 if(vd.isInline() or vd.isInlineSpecified()) {
840 if(vd.isConstexpr()) {
850 std::string name{std::move(defaultName)};
852 if(
const auto* tvd = dyn_cast_or_null<VarTemplateSpecializationDecl>(decl)) {
856 codeGenerator->InsertTemplateArgs(tvd->getTemplateArgs());
858 name += outputFormatHelper;
875 if(isa<DecompositionDecl>(expr->getDecl())) {
882 for(
const auto* child : stmt->children()) {
907 bool mHaveTemporary{};
909 std::string mTempName{};
910 std::vector<VarDecl*> mDecls{};
914 : codeGenerator{_codeGenerator}
915 , mPrevStmt{const_cast<
Stmt*>(stmt)}
921 for(
auto d : mDecls) {
927 if(
auto* expr = dyn_cast_or_null<CXXConstructExpr>(stmt)) {
932 auto* vd =
Variable(mTempName, expr->getType(), dummy->getDeclContext());
933 dummy->getDeclContext()->addDecl(vd);
934 vd->setInit(
const_cast<CXXConstructExpr*
>(expr));
935 vd->setStorageClass(SC_None);
939 auto* vd = ImplicitParamDecl::Create(
const_cast<ASTContext&
>(ctx),
940 ctx.getTranslationUnitDecl(),
942 &ctx.Idents.get(mTempName),
944 ImplicitParamKind::Other);
951 }
else if(
auto* expr = dyn_cast_or_null<InitListExpr>(stmt)) {
953 auto* vd =
Variable(mTempName, expr->getType());
954 vd->setInit(
const_cast<InitListExpr*
>(expr));
967 bool Found()
const {
return mFound; }
969 std::string
Name()
const {
return mTempName; }
976 auto* vd =
Variable(mTempName, expr->getType());
982 auto* ctorConstructExpr = CXXConstructExpr::Create(
GetGlobalAST(),
985 expr->getConstructor(),
987 {expr->getArgs(), expr->getNumArgs()},
988 expr->hadMultipleCandidates(),
989 expr->isListInitialization(),
990 expr->isStdInitListInitialization(),
991 expr->requiresZeroInitialization(),
992 expr->getConstructionKind(),
993 expr->getParenOrBraceRange());
995 vd->setInit(ctorConstructExpr);
1001 mDecls.push_back(vd);
1005 void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr* stmt)
1009 const auto name =
MakeLineColumnName(ctx.getSourceManager(), stmt->getBeginLoc(),
"temp"sv);
1012 auto* vd =
Variable(name, stmt->getType());
1026 vd->setInit(stmt->getSubExpr());
1031 if(SD_FullExpression == stmt->getStorageDuration() and not mHaveTemporary) {
1033 mHaveTemporary =
true;
1034 }
else if(
const auto* extending = stmt->getExtendingDecl()) {
1038 mDecls.push_back(vd);
1043 auto* tmp = mPrevStmt;
1046 for(
auto* child : stmt->children()) {
1062 static SmallVector<std::pair<std::pair<const CXXRecordDecl*, const CXXRecordDecl*>, VarDecl*>, 10>
1070 auto iter = std::ranges::find_if(
1071 gVtables, [&](
const auto& e) {
return (e.first.first == record) and (e.first.second == recordB); });
1074 iter = std::ranges::find_if(
gVtables, [&](
const auto& e) {
return e.first.first == record; });
1077 return std::distance(
gVtables.begin(), iter);
1081void PushVtableEntry(
const CXXRecordDecl* record,
const CXXRecordDecl* recordB, VarDecl* decl)
1083 gVtables.push_back({{record, recordB}, decl});
1112 ofm.AppendNewLine();
1116 SmallVector<Expr*, 16> mInitExprs{};
1123 ofm.AppendNewLine();
1127 vtable->setInit(
InitList(mInitExprs, vtable->getType()));
1129 cg->InsertArg(vtable);
1131 ofm.AppendNewLine();
1134 cg->InsertArg(cxaStartFun);
1145 ofm.AppendNewLine();
1146 cg->InsertArg(cxaAtExitFun);
1148 return ofm.GetString();
1173 return stmt and stmt->getNumExprs() and isa_and_nonnull<PackExpansionExpr>(stmt->getExpr(0)) and
1174 stmt->getType().isNull();
1183 for(
const auto* decl : stmt->decls()) {
1195 pp.adjustForCPlusPlus();
1199 ::llvm::raw_string_ostream stream{init};
1200 param.printAsInit(stream, pp);
1208 "static constexpr ",
GetName(param.getType().getUnqualifiedType()),
" ", varName, init);
1216 for(
const auto& arg : array) {
1217 if(TemplateArgument::Declaration != arg.getKind()) {
1219 }
else if(
const auto decl = dyn_cast_or_null<TemplateParamObjectDecl>(arg.getAsDecl())) {
1228 if(
const auto* fd = dyn_cast_or_null<FunctionDecl>(&decl)) {
1229 if(
const auto* specArgs = fd->getTemplateSpecializationArgs()) {
1232 }
else if(
const auto* vd = dyn_cast_or_null<VarTemplateSpecializationDecl>(&decl)) {
1234 }
else if(
const auto* clsTemplateSpe = dyn_cast_or_null<ClassTemplateSpecializationDecl>(&decl)) {
1244 if(
auto* init = stmt->getInit();
1246 (not(isa<CallExpr>(init) or
1247 (isa<ExprWithCleanups>(init) and
1248 (isa<CallExpr>(dyn_cast_or_null<ExprWithCleanups>(init)->getSubExpr()) or
1249 isa<MaterializeTemporaryExpr>(dyn_cast_or_null<ExprWithCleanups>(init)->getSubExpr())))))) {
1257 if(BindingDeclFinder isBindingDecl{}; isBindingDecl.Find(stmt->getInit())) {
1264 TemporaryDeclFinder temporaryFinder{*
this, stmt->getInit()};
1272 const bool needsGuard = stmt->isOutOfLine() and isTemplateInstantiation(stmt->getTemplateSpecializationKind());
1276 if(stmt->isOutOfLine()) {
1277 if(
const auto* recordDecl = dyn_cast_or_null<CXXRecordDecl>(stmt->getDeclContext())) {
1278 if(
const auto* classTmpl = recordDecl->getDescribedClassTemplate()) {
1284 if(isa<VarTemplateSpecializationDecl>(stmt)) {
1286 }
else if(needsGuard) {
1300 const bool isMemberPointer{isa<MemberPointerType>(desugaredType.getTypePtrOrNull())};
1301 if(desugaredType->isFunctionPointerType() or isMemberPointer) {
1302 const auto lineNo =
GetSM(*stmt).getSpellingLineNumber(stmt->getSourceRange().getBegin());
1304 const auto funcPtrName{
StrCat(ptrPrefix, lineNo)};
1312 const auto scope = [&] {
1313 if(
const auto* ctx = stmt->getDeclContext(); stmt->getLexicalDeclContext() != ctx) {
1314 OutputFormatHelper scopeOfm{};
1315 scopeOfm.Append(
GetDeclContext(ctx, WithTemplateParameters::Yes));
1320 return std::string{};
1329 const std::string_view pointer = [&]() {
1334 if(stmt->getType()->isAnyPointerType()) {
1343 if(
const auto* init = stmt->getInit()) {
1344 if(
const auto* ctorExpr = dyn_cast_or_null<CXXConstructExpr>(init);
1359 if(stmt->hasGlobalStorage()) {
1360 if(ctorExpr->getConstructor()->isDefaultConstructor() and
1361 ctorExpr->getConstructor()->getParent()->hasTrivialDefaultConstructor()) {
1372 stmt->getType(), stmt,
ArgsToExprVector(ctorExpr), DoCast::No, AsReference::Yes);
1388 if(MyOptional<const InitListExpr*> initList{dyn_cast_or_null<InitListExpr>(init)};
1390 initList.and_then(CanonicalType).and_then(Isa<RecordType>).and_not(IsPointer).and_then(IsPOD) and
1391 not isa<ArrayType>(stmt->getType())) {
1396 if(stmt->hasGlobalStorage()) {
1405 initList.and_then(CanonicalType)
1406 .and_then(Isa<RecordType>)
1409 (0 == initList.value()->getNumInits()))) {
1413 if(not(ctorExpr and ctorExpr->getConstructor()->isDefaultConstructor() and
1414 ctorExpr->getConstructor()->getParent()->hasTrivialDefaultConstructor())) {
1416 const bool isPrimaryTemplatePackExpansionExpr{
1419 if(not isa<CXXParenListInitExpr>(init) and not isPrimaryTemplatePackExpansionExpr) {
1425 stmt->getType()->isRValueReferenceType()) {
1427 if(GetInsightsOptions().UseShow2C) {
1428 mOutputFormatHelper.Append(
"&");
1441 (stmt->getStorageDuration() == SD_Static) and
1442 (stmt->getDeclContext()->isNamespace() or
1443 (is{stmt->getStorageClass()}.any_of(SC_Static, SC_Extern)))) {
1447 if(stmt->isNRVOVariable()) {
1456 if(
const auto* decompDecl = dyn_cast_or_null<DecompositionDecl>(stmt)) {
1459 codeGenerator.InsertDecompositionBindings(*decompDecl);
1464 mOutputFormatHelper.InsertEndIfTemplateGuard();
1471 if(not(cxxMethodDecl and cxxMethodDecl->isLambdaStaticInvoker())) {
1484 if(not cxxMethodDecl->getReturnType()->isVoidType()) {
1490 if(cxxMethodDecl->isFunctionTemplateSpecialization()) {
1494 if(cxxMethodDecl->isTemplated()) {
1495 if(cxxMethodDecl->getDescribedTemplate()) {
1497 TemplateParamsOnly::Yes);
1506 OutputFormatHelper::NameOnly::Yes,
1507 OutputFormatHelper::GenMissingParamName::Yes);
1522 const SourceLocation& instLoc,
1523 std::string_view text)
1525 const auto lineNo = sm.getSpellingLineNumber(instLoc);
1526 const auto& fileId = sm.getFileID(instLoc);
1527 if(
const auto file = sm.getFileEntryRefForID(fileId)) {
1528 const auto fileWithDirName = file->getName();
1529 const auto fileName = llvm::sys::path::filename(fileWithDirName);
1532 text =
"First instantiated from: "sv;
1542 if(stmt->isTemplateInstantiation() and stmt->isFunctionTemplateSpecialization()) {
1551 if(stmt->isTemplateInstantiation() and stmt->isFunctionTemplateSpecialization()) {
1574 if(isa<CoyieldExpr>(stmt)) {
1581 if(
const auto* matTemp = dyn_cast_or_null<MaterializeTemporaryExpr>(stmt->getCommonExpr())) {
1582 const auto* temporary = matTemp->getSubExpr();
1584 if(
const auto* memExpr = dyn_cast_or_null<CXXMemberCallExpr>(temporary)) {
1585 ForEachArg(memExpr->arguments(), [&](
const auto& arg) { InsertArg(arg); });
1591 }
else if(
const auto* unaryexpr = dyn_cast_or_null<UnaryOperator>(stmt->getOperand())) {
1592 if(
const auto* callExpr = dyn_cast_or_null<CallExpr>(unaryexpr->getSubExpr())) {
1608 auto IsPrimaryTemplate = [&] {
1610 if(
const auto* cxxMethod = dyn_cast_or_null<CXXMethodDecl>(stmt)) {
1611 if(
const auto* tmpl = cxxMethod->getParent()->getDescribedClassTemplate();
1612 tmpl and not isa<ClassTemplateSpecializationDecl>(cxxMethod->getParent())) {
1617 return (FunctionDecl::TK_FunctionTemplate == stmt->getTemplatedKind()) or
1621 if(stmt->doesThisDeclarationHaveABody()) {
1626 if(
const auto* corBody = dyn_cast_or_null<CoroutineBodyStmt>(stmt->getBody());
1627 (
nullptr != corBody) and not IsPrimaryTemplate() and
GetInsightsOptions().ShowCoroutineTransformation) {
1630 codeGenerator.InsertCoroutine(*stmt, corBody);
1632 const auto exSpec = stmt->getExceptionSpecType();
1633 const bool showNoexcept =
1637 if(stmt->hasImplicitReturnZero()) {
1639 [](
const Stmt* e) { return isa<ReturnStmt>(e); });
1642 const auto* body = stmt->getBody();
1651 for(
const auto* param : stmt->parameters()) {
1652 auto paramType = param->getType();
1653 const bool isPassByValue{not paramType->isPointerType() and not paramType->isReferenceType()};
1654 if(
const auto* rd = paramType->getAsRecordDecl(); rd and isPassByValue) {
1678 dt.TraverseType(stmt->getReturnType());
1681 for(
const auto& param : stmt->parameters()) {
1682 P0315Visitor dt{*
this};
1683 dt.TraverseType(param->getType());
1687 if(
const auto* deductionGuide = dyn_cast_or_null<CXXDeductionGuideDecl>(stmt)) {
1689 }
else if(
const auto* ctor = dyn_cast_or_null<CXXConstructorDecl>(stmt)) {
1694 RETURN_IF(isa<CXXConversionDecl>(stmt) and not stmt->hasBody());
1712 if(typeConstraint) {
1714 sstream.
Print(*typeConstraint);
1716 return sstream.str();
1740 expr = expr->IgnoreParenImpCasts();
1743 if(Expr::EvalResult evalResult{};
1744 isa<CXXFunctionalCastExpr>(expr) and
1745 expr->EvaluateAsConstantExpr(evalResult,
GetGlobalAST(), ConstantExprKind::Normal)) {
1746 return std::pair<QualType, APValue>{expr->getType(), evalResult.Val};
1754 const TemplateParamsOnly templateParamsOnly)
1756 const bool full{TemplateParamsOnly::No == templateParamsOnly};
1759 for(
const auto* param : list) {
1760 if(
const auto* nonTmplParam = dyn_cast_or_null<NonTypeTemplateParmDecl>(param);
1761 nonTmplParam and nonTmplParam->hasDefaultArgument()) {
1764 auto* init =
GetGlobalAST().getTemplateParamObjectDecl(val->first, val->second);
1776 for(
OnceFalse needsComma{};
const auto* param : list) {
1779 const auto& typeName =
GetName(*param);
1781 if(
const auto* tt = dyn_cast_or_null<TemplateTypeParmDecl>(param)) {
1783 if(tt->wasDeclaredWithTypename()) {
1785 }
else if(not tt->hasTypeConstraint()) {
1792 if(0 == typeName.size() or tt->isImplicit() ) {
1797 not typeConstraint.empty()) {
1806 if(tt->hasDefaultArgument() and not tt->defaultArgumentWasInherited()) {
1807 const auto& defaultArg = tt->getDefaultArgument();
1809 if(
const auto decltypeType = dyn_cast_or_null<DecltypeType>(defaultArg.getArgument().getAsType())) {
1812 InsertArg(decltypeType->getUnderlyingExpr());
1820 }
else if(
const auto* nonTmplParam = dyn_cast_or_null<NonTypeTemplateParmDecl>(param)) {
1822 if(
const auto nttpType = nonTmplParam->getType();
1823 nttpType->isFunctionPointerType() or nttpType->isMemberFunctionPointerType()) {
1828 GetName(nttpType),
" "sv,
Ellipsis(nonTmplParam->isParameterPack()), typeName);
1831 if(nonTmplParam->hasDefaultArgument()) {
1838 }
else if(
const auto* tmplTmplParam = dyn_cast_or_null<TemplateTemplateParmDecl>(param)) {
1843 if(tmplTmplParam->hasDefaultArgument()) {
1869 SmallVector<const ClassTemplateSpecializationDecl*, 10> specializations{};
1872 for(
const auto* spec : stmt->specializations()) {
1875 if(TSK_ImplicitInstantiation == spec->getSpecializationKind()) {
1876 specializations.push_back(spec);
1881 ranges::sort(specializations,
1882 [](
const ClassTemplateSpecializationDecl* a,
const ClassTemplateSpecializationDecl* b) {
1883 return a->getPointOfInstantiation() < b->getPointOfInstantiation();
1886 for(
const auto* spec : specializations) {
1894 for(
OnceFalse needsComma{};
const auto& expr : stmt->children()) {
1914 OnceFalse needsComma{uint64_t{0} != startAt};
1915 for_each(startAt, size, [&](
auto) {
1916 ret.AppendComma(needsComma);
1921 return ret.GetString();
1932 ((stmt->getNumInits() > 1) or stmt->getArrayFiller() or
1933 ((0 < stmt->getNumInits()) and isa<ImplicitValueInitExpr>(stmt->getInit(0))))),
1935 mOutputFormatHelper.IncreaseIndent();
1937 ForEachArg(stmt->inits(), [&](const auto& init) { InsertArg(init); });
1940 if(stmt->getType().getCanonicalType()->isScalarType()) {
1951 if(
const auto* filler = stmt->getArrayFiller()) {
1952 OutputFormatHelper ofm{};
1957 dyn_cast_or_null<ConstantArrayType>(stmt->getType().getTypePtrOrNull()),
1959 stmt->getNumInits());
1965 mOutputFormatHelper.DecreaseIndent();
1971 const auto* subExpr = stmt->getExpr();
1981 if(stmt->isArrayForm()) {
1999 dt.TraverseType(stmt->getType());
2007 if(
const auto& arguments = stmt->arguments(); not arguments.empty()) {
2008 ForEachArg(stmt->arguments(), [&](
const auto& arg) { InsertArg(arg); });
2036 if(stmt->getNumTemplateArgs()) {
2051 auto operatorStr = BinaryOperator::getOpcodeStr(stmt->getOperator());
2055 const auto* init = stmt->getInit();
2057 if(stmt->isLeftFold()) {
2060 mOutputFormatHelper.Append(
" "sv, operatorStr,
" "sv);
2068 if(stmt->isRightFold()) {
2082 if(stmt->isFullySubstituted()) {
2083 const auto* constExpr = dyn_cast_or_null<ConstantExpr>(stmt->getIndexExpr());
2086 constExpr->getAPValueResult().getInt());
2099 const auto& constructorDecl = *stmt->getConstructor();
2104 OutputFormatHelper::NameOnly::Yes,
2105 OutputFormatHelper::GenMissingParamName::Yes);
2148 StringRef opCodeName = UnaryOperator::getOpcodeStr(stmt->getOpcode());
2149 const bool insertBefore{not stmt->isPostfix()};
2157 if(not insertBefore) {
2165 StringStream stream{};
2166 stream.Print(*stmt);
2174 Error(stmt,
"ArrayInitIndexExpr should not be reached in CodeGenerator");
2180 if((not
GetInsightsOptions().UseAltArraySubscriptionSyntax) or stmt->getLHS()->isLValue()) {
2201 const uint64_t size = stmt->getArraySize().getZExtValue();
2205 codeGenerator.
InsertArg(stmt->getSubExpr());
2222 if(insideDecltype) {
2230 if(
const auto* declRefExpr = dyn_cast_or_null<DeclRefExpr>(stmt->getCallee()->IgnoreImpCasts())) {
2231 if(
const auto* fd = dyn_cast_or_null<FunctionDecl>(declRefExpr->getDecl())) {
2232 if((not declRefExpr->getNumTemplateArgs() and
GetInsightsOptions().ShowAllCallExprTemplateParameters) or
2233 isa<UserDefinedLiteral>(stmt)) {
2240 auto* funcDecl = dyn_cast_or_null<FunctionDecl>(stmt->getCalleeDecl());
2243 ForEachArg(stmt->arguments(), [&](
const auto* arg) {
2246 if(const auto* tmpExpr = dyn_cast_or_null<CXXBindTemporaryExpr>(arg)) {
2247 if(const auto* tmp = dyn_cast_or_null<CXXTemporaryObjectExpr>(tmpExpr->getSubExpr())) {
2248 if(GetInsightsOptions().UseShow2C) {
2253 } else if(GetInsightsOptions().ShowLifetime) {
2254 mOutputFormatHelper.Append(GetName(*tmp));
2260 if(
GetInsightsOptions().UseShow2C and funcDecl and (funcDecl->getNumParams() >= parmIdx) and
2262 if(auto* unop = dyn_cast_or_null<UnaryOperator>(arg); not unop or (unop->getOpcode() != UO_AddrOf)) {
2271 if(insideDecltype) {
2272 mLambdaStack.back().setCallerType(LambdaCallerType::Decltype);
2275 mCurrentCallExprPos.reset();
2281 const QualType castDestType = stmt->getTypeAsWritten();
2282 const Expr* subExpr = stmt->getSubExpr();
2284 FormatCast(stmt->getCastName(), castDestType, subExpr, stmt->getCastKind());
2290 const Expr* subExpr = stmt->getSubExpr();
2291 const auto castKind = stmt->getCastKind();
2294 auto isMatchingCast = [](
const CastKind kind,
const bool hideImplicitCasts,
const bool showXValueCasts) {
2296 case CastKind::CK_Dependent: [[fallthrough]];
2297 case CastKind::CK_IntegralCast: [[fallthrough]];
2298 case CastKind::CK_IntegralToBoolean: [[fallthrough]];
2299 case CastKind::CK_IntegralToPointer: [[fallthrough]];
2300 case CastKind::CK_PointerToIntegral: [[fallthrough]];
2301 case CastKind::CK_BitCast: [[fallthrough]];
2302 case CastKind::CK_UncheckedDerivedToBase: [[fallthrough]];
2303 case CastKind::CK_ToUnion:
2306 case CastKind::CK_AtomicToNonAtomic: [[fallthrough]];
2307 case CastKind::CK_DerivedToBase: [[fallthrough]];
2308 case CastKind::CK_FloatingCast: [[fallthrough]];
2309 case CastKind::CK_IntegralToFloating: [[fallthrough]];
2310 case CastKind::CK_FloatingToIntegral: [[fallthrough]];
2311 case CastKind::CK_NonAtomicToAtomic:
return true;
2314 if((showXValueCasts or not hideImplicitCasts) and (CastKind::CK_NoOp == kind)) {
2319 if(not hideImplicitCasts) {
2321 case CastKind::CK_NullToPointer: [[fallthrough]];
2322 case CastKind::CK_NullToMemberPointer: [[fallthrough]];
2325 case CastKind::CK_NoOp: [[fallthrough]];
2326 case CastKind::CK_ArrayToPointerDecay:
return true;
2333 }(castKind, hideImplicitCasts, stmt->isXValue() or
ShowXValueCasts());
2335 if(not isMatchingCast) {
2343 }
else if(isa<IntegerLiteral>(subExpr) and hideImplicitCasts) {
2348 }
else if(stmt->isPartOfExplicitCast()) {
2357 if(isa<CStyleCastExpr>(subExpr) or isa<CXXNamedCastExpr>(subExpr)) {
2365 const QualType castDestType{[&] {
2366 auto type{stmt->getType()};
2369 if(not type->isDependentType()) {
2370 type = type.getCanonicalType();
2375 if(VK_XValue == stmt->getValueKind()) {
2382 FormatCast(castName, castDestType, subExpr, castKind);
2389 if(
const auto* tmplObjParam = dyn_cast_or_null<TemplateParamObjectDecl>(stmt->getDecl())) {
2392 }
else if(
const auto* vd = dyn_cast_or_null<VarDecl>(stmt->getDecl());
2394 const auto* init = vd->getInit();
2396 if(
const auto* dref = dyn_cast_or_null<DeclRefExpr>(init)) {
2400 }
else if(
const auto* inList = dyn_cast_or_null<InitListExpr>(init)) {
2406 if(
const auto* ctx = stmt->getDecl()->getDeclContext(); not ctx->isFunctionOrMethod() and
2407 not isa<NonTypeTemplateParmDecl>(stmt->getDecl()) and
2409 if(
const auto* qualifier = stmt->getQualifier();
2410 qualifier and (qualifier->getKind() == NestedNameSpecifier::SpecifierKind::Global)) {
2417 OutputFormatHelper ofm{};
2429 if(
const auto* varTmplSpecDecl = dyn_cast_or_null<VarTemplateSpecializationDecl>(stmt->getDecl())) {
2448 if(requiresImplicitReturnZero) {
2462template<
typename... Args>
2465 return (... and not isa<Args>(stmt));
2471 for(
const auto* item : stmt->body()) {
2499 if(
const auto* conditionVar = stmt->getConditionVariable()) {
2503 if(
const auto* init = stmt->getInit()) {
2506 if(not isa<DeclStmt>(init)) {
2515 const bool hasInit{stmt->getInit() or stmt->getConditionVariable()};
2526 not stmt->isConsteval(),
2528 mShowConstantExprValue = ShowConstantExprValue::Yes;
2530 InsertArg(stmt->getCond());
2532 mShowConstantExprValue = ShowConstantExprValue::No;
2534 AddSpaceAtTheEnd::Yes);
2542 if(
const auto* elsePart = stmt->getElse()) {
2566 std::string_view mContinueLabel{};
2573 , mContinueLabel{continueLabel}
2594 auto* tmp = mPrevStmt;
2597 for(
auto* child : stmt->children()) {
2613 auto* rwStmt =
const_cast<ForStmt*
>(stmt);
2615 StmtsContainer bodyStmts{};
2617 auto continueLabel =
MakeLineColumnName(ctx.getSourceManager(), stmt->getBeginLoc(),
"__continue_"sv);
2618 const bool insertLabel = ContinueASTTransformer{rwStmt->getBody(), continueLabel}.found;
2620 bodyStmts.AddBodyStmts(rwStmt->getBody());
2624 bodyStmts.Add(
Label(continueLabel));
2627 bodyStmts.Add(rwStmt->getInc());
2629 auto* condition = [&]() -> Expr* {
2630 if(rwStmt->getCond()) {
2631 return rwStmt->getCond();
2637 auto* outerBody =
mkCompoundStmt(bodyStmts, stmt->getBeginLoc(), stmt->getEndLoc());
2638 auto* whileStmt = WhileStmt::Create(
2639 ctx,
nullptr, condition, outerBody, stmt->getBeginLoc(), stmt->getLParenLoc(), stmt->getRParenLoc());
2641 StmtsContainer outerScopeStmts{};
2642 outerScopeStmts.Add(rwStmt->getInit());
2643 outerScopeStmts.Add(whileStmt);
2645 auto* outerScopeBody =
mkCompoundStmt(outerScopeStmts, stmt->getBeginLoc(), stmt->getEndLoc());
2659 if(
const auto* init = stmt->getInit()) {
2660 MultiStmtDeclCodeGenerator codeGenerator{
2661 mOutputFormatHelper, mLambdaStack, InsertVarDecl(nullptr)};
2673 AddSpaceAtTheEnd::Yes);
2679 mOutputFormatHelper.AppendNewLine();
2685 if(not type.isNull()) {
2686 if(
auto* typePtr = type.getTypePtrOrNull()) {
2687 if(
auto pointee = typePtr->getPointeeType(); not pointee.isNull()) {
2688 return pointee.isConstQualified();
2699 const auto castKind = stmt->getCastKind();
2700 const QualType castDestType = stmt->getType().getCanonicalType();
2704 FormatCast(castName, castDestType, stmt->getSubExpr(), castKind);
2716 if(stmt->getNumPlacementArgs()) {
2720 ForEachArg(stmt->placement_arguments(), [&](
const auto& placementArg) { InsertArg(placementArg); });
2724 if(
const auto* ctorExpr = stmt->getConstructExpr()) {
2728 auto name =
GetName(stmt->getAllocatedType());
2731 if(stmt->isArray()) {
2732 OutputFormatHelper ofm{};
2736 codeGenerator->
InsertArg(stmt->getArraySize().value());
2751 if(stmt->hasInitializer()) {
2761 const auto* temporary = stmt->getSubExpr();
2770 const auto* callee = dyn_cast_or_null<DeclRefExpr>(stmt->getCallee()->IgnoreImpCasts());
2771 const bool isCXXMethod{callee and isa<CXXMethodDecl>(callee->getDecl())};
2773 if(2 == stmt->getNumArgs()) {
2774 auto getArg = [&](
unsigned idx) {
2775 const auto* arg = stmt->getArg(idx);
2780 arg = arg->IgnoreImpCasts();
2783 return dyn_cast_or_null<DeclRefExpr>(arg);
2786 const auto* param1 = getArg(0);
2787 const auto* param2 = getArg(1);
2789 if(callee and param1 and param2) {
2790 const std::string replace = [&]() {
2792 auto nameWithTmplArguments = [](
const auto param) {
2796 if(isa<CXXMethodDecl>(callee->getDecl())) {
2797 return StrCat(nameWithTmplArguments(param1),
2801 nameWithTmplArguments(param2),
2806 nameWithTmplArguments(param1),
2808 nameWithTmplArguments(param2),
2819 auto cb = stmt->child_begin();
2820 const auto* fallbackArg0 = stmt->getArg(0);
2824 std::advance(cb, 1);
2826 const auto* arg1 = *cb;
2828 std::advance(cb, 1);
2831 if(not isCXXMethod) {
2834 if(
const auto* adl = dyn_cast_or_null<UnresolvedLookupExpr>(stmt->getCallee())) {
2845 if(isa<DeclRefExpr>(fallbackArg0)) {
2854 const OverloadedOperatorKind opKind = stmt->getOperator();
2862 const auto childRange = llvm::make_range(cb, stmt->child_end());
2865 ForEachArg(childRange, [&](
const auto& child) {
2866 if(not isCXXMethod) {
2883 [](
const LambdaCapture& c) { return (c.getCaptureKind() == LCK_StarThis); })) {
2900 const bool isConstructor{isa<CXXConstructExpr>(stmt->getSubExpr())};
2901 const bool isStdListInit{isa<CXXStdInitializerListExpr>(stmt->getSubExpr())};
2902 const bool isListInitialization{stmt->getLParenLoc().isInvalid()};
2903 const bool needsParens{not isConstructor and not isListInitialization and not isStdListInit};
2906 if(not isConstructor and not isStdListInit) {
2928 StringStream stream{};
2929 stream.Print(*stmt);
2931 auto str = std::move(stream.str());
2933 if(str ==
"'\\x00'"sv) {
2935 }
else if(str ==
"'\\xff'"sv) {
2947 if(
const auto* functionName = stmt->getFunctionName()) {
2950 const auto name = PredefinedExpr::getIdentKindName(stmt->getIdentKind());
2960 TemporaryDeclFinder temporaryFinder{*
this, not
mProcessingVarDecl ? stmt->getSubExpr() :
nullptr};
2974 const QualType& type = t.getCanonicalType();
2976 if(type->isScalarType()) {
2977 switch(type->getScalarTypeKind()) {
2978 case Type::STK_CPointer:
2979 case Type::STK_BlockPointer:
2980 case Type::STK_ObjCObjectPointer:
2981 case Type::STK_MemberPointer:
return std::string{
kwNullptr};
2983 case Type::STK_Bool:
return std::string{
kwFalse};
2985 case Type::STK_Integral:
2986 case Type::STK_Floating:
2987 if(
const auto* bt = type->getAs<BuiltinType>()) {
2988 switch(bt->getKind()) {
2990 case BuiltinType::Char_U:
2991 case BuiltinType::UChar:
2992 case BuiltinType::Char_S:
2993 case BuiltinType::SChar:
return "'\\0'";
2994 case BuiltinType::WChar_U:
2995 case BuiltinType::WChar_S:
return "L'\\0'";
2996 case BuiltinType::Char16:
return "u'\\0'";
2997 case BuiltinType::Char32:
return "U'\\0'";
2999 case BuiltinType::Half:
3000 case BuiltinType::Float:
return "0.0f";
3001 case BuiltinType::Double:
return "0.0";
3008 case Type::STK_FloatingComplex:
3009 case Type::STK_IntegralComplex:
3010 if(
const auto* complexType = type->getAs<ComplexType>()) {
3016 case Type::STK_FixedPoint:
Error(
"STK_FixedPoint is not implemented");
break;
3019 }
else if(
const auto* tt = dyn_cast_or_null<ConstantArrayType>(t.getTypePtrOrNull())) {
3020 const auto& elementType{tt->getElementType()};
3026 return std::string{
"0"sv};
3062 if(not stmt->getCaughtType().isNull()) {
3063 mOutputFormatHelper.Append(
3064 GetTypeNameAsParameter(stmt->getCaughtType(), stmt->getExceptionDecl()->getName()));
3066 mOutputFormatHelper.Append(kwElipsis);
3069 AddSpaceAtTheEnd::Yes);
3086 if(
const auto value = stmt->getAPValueResult(); value.isInt()) {
3098 const auto& underlyingType = stmt->getUnderlyingType();
3101 P0315Visitor dt{*
this};
3102 dt.TraverseType(underlyingType);
3106 if(
auto* templateSpecializationType = underlyingType->getAs<TemplateSpecializationType>()) {
3107 const bool carriesNamespace{[&] {
3108 if(
const auto tn = templateSpecializationType->getTemplateName();
3109 (TemplateName::QualifiedTemplate == tn.getKind()) or (TemplateName::DependentTemplate == tn.getKind())) {
3110 const auto* qtn = tn.getAsQualifiedTemplateName();
3112 return qtn->getQualifier() !=
nullptr;
3118 if(
const auto* elaboratedType = underlyingType->getAs<ElaboratedType>()) {
3119 if(templateSpecializationType->isSugared() and not carriesNamespace) {
3125 StringStream stream{};
3126 stream.Print(*templateSpecializationType);
3132 }
else if(
auto* depSpecType = underlyingType->getAs<DependentTemplateSpecializationType>()) {
3135#if IS_CLANG_NEWER_THAN(20)
3136 InsertNamespace(depSpecType->getDependentTemplateName().getQualifier());
3167 CXXConstructorDecl* cxxInheritedCtorDecl{
nullptr};
3171 if(
const auto* ctor = dyn_cast_or_null<CXXConstructorDecl>(stmt)) {
3178 for(
OnceTrue first{};
const auto* init : ctor->inits()) {
3181 initOutputFormatHelper.
Append(
": "sv);
3183 initOutputFormatHelper.
Append(
", "sv);
3188 if(
const auto* member = init->getMember()) {
3189 initOutputFormatHelper.
Append(member->getName());
3192 const auto* inlineInit = init->getInit();
3193 bool useCurlies{
false};
3195 if(
const auto* cxxInheritedCtorInitExpr = dyn_cast_or_null<CXXInheritedCtorInitExpr>(inlineInit)) {
3196 cxxInheritedCtorDecl = cxxInheritedCtorInitExpr->getConstructor();
3200 }
else if(init->isBaseInitializer() and not isa<CXXConstructExpr>(inlineInit)) {
3208 const auto* inlineInit = init->getInit();
3211 if(
const auto* member = init->getMember()) {
3212 initOutputFormatHelper.
Append(member->getName());
3214 if(isa<ParenListExpr>(inlineInit)) {
3220 }
else if(
const auto* cxxInheritedCtorInitExpr = dyn_cast_or_null<CXXInheritedCtorInitExpr>(inlineInit)) {
3221 cxxInheritedCtorDecl = cxxInheritedCtorInitExpr->getConstructor();
3227 }
else if(init->isBaseInitializer() and not isa<CXXConstructExpr>(inlineInit)) {
3254 if(not stmt->isUserProvided() or stmt->isExplicitlyDefaulted()) {
3261 if(isa<CXXConversionDecl>(stmt)) {
3262 if(stmt->getParent()->isLambda() and not stmt->doesThisDeclarationHaveABody()) {
3267 if(
const auto* invoker = stmt->getParent()->getLambdaStaticInvoker()) {
3268 mOutputFormatHelper.AppendSemiNewLine(invoker->getName());
3270 mOutputFormatHelper.AppendSemiNewLine(kwOperator,
"()"sv);
3276 if((SkipBody::No == skipBody) and stmt->doesThisDeclarationHaveABody() and not stmt->isLambdaStaticInvoker()) {
3285 if(SkipBody::No == skipBody) {
3297 not stmt->isExplicitlyDefaulted() and not stmt->isDeleted());
3307 if(stmt->isScoped()) {
3308 if(stmt->isScopedUsingClassTag()) {
3317 if(stmt->isFixed()) {
3329 ForEachArg(stmt->enumerators(), [&](
const auto* value) {
3331 mOutputFormatHelper.AppendNewLine();
3342 AddSpaceAtTheEnd::No);
3344 mOutputFormatHelper.AppendSemiNewLine();
3345 mOutputFormatHelper.AppendNewLine();
3355 if(
const auto* initExpr = stmt->getInitExpr()) {
3372 static const std::string_view spaces{
" "sv};
3374 if(offset >= spaces.size()) {
3377 return spaces.substr(0, spaces.size() - offset);
3385 P0315Visitor dt{*
this};
3387 auto type =
GetType(stmt->getType());
3388 dt.TraverseType(type);
3393 if(stmt->isMutable()) {
3397 if(
const auto* cxxRecordDecl = dyn_cast_or_null<CXXRecordDecl>(stmt->getParent())) {
3398 std::string name{
GetName(*stmt)};
3401 name = std::move(fieldName.value());
3406 if(
const auto* constantExpr = dyn_cast_or_null<ConstantExpr>(stmt->getBitWidth())) {
3412 if(
const auto* initializer = stmt->getInClassInitializer();
3413 stmt->hasInClassInitializer() and initializer and cxxRecordDecl->isAggregate()) {
3414 const bool isConstructorExpr{isa<CXXConstructExpr>(initializer) or isa<ExprWithCleanups>(initializer)};
3415 if((ICIS_ListInit != stmt->getInClassInitStyle()) or isConstructorExpr) {
3426 const auto* fieldClass = stmt->getParent();
3428 auto effectiveFieldSize{
GetGlobalAST().getTypeInfoInChars(type).Width.getQuantity()};
3429 auto getFieldOffsetInBytes = [&recordLayout](
const FieldDecl* field) {
3430 return recordLayout.getFieldOffset(field->getFieldIndex()) / 8;
3432 auto fieldOffset = getFieldOffsetInBytes(stmt);
3444 const auto expectedOffset = fieldOffset + effectiveFieldSize;
3445 const auto nextOffset = [&]() -> uint64_t {
3447 if(
const auto next = stmt->getFieldIndex() + 1; recordLayout.getFieldCount() > next) {
3449 const auto* field = *std::next(fieldClass->fields().begin(), next);
3451 return getFieldOffsetInBytes(field);
3455 return recordLayout.getSize().getQuantity();
3458 if(expectedOffset < nextOffset) {
3459 const auto padding = nextOffset - expectedOffset;
3484 if(not stmt->isFailed()) {
3496 if(stmt->getMessage()) {
3509 if(
const auto& name =
GetName(*stmt->getNominatedNamespace()); not name.empty()) {
3519 if(stmt->isInline()) {
3527 if(not stmt->isAnonymousNamespace()) {
3535 for(
const auto* decl : stmt->decls()) {
3558 if(stmt->shadow_size()) {
3559 for(
const auto* shadow : stmt->shadows()) {
3560 RETURN_IF(isa<ConstructorUsingShadowDecl>(shadow));
3562 if(
const auto* shadowUsing = dyn_cast_or_null<UsingShadowDecl>(shadow)) {
3563 if(
const auto* targetDecl = shadowUsing->getTargetDecl(); not isa<TypeAliasDecl>(targetDecl)) {
3564 UsingCodeGenerator codeGenerator{ofm};
3578 if(not ofm.empty()) {
3603 if(
const auto* typeInfo = stmt->getFriendType()) {
3606 }
else if(
const auto* fd = dyn_cast_or_null<FunctionDecl>(stmt->getFriendDecl())) {
3609 }
else if(
const auto* fdt = dyn_cast_or_null<FunctionTemplateDecl>(stmt->getFriendDecl())) {
3614 if(
const auto* ctd = dyn_cast_or_null<ClassTemplateDecl>(stmt->getFriendDecl())) {
3635 RETURN_IF(DeductionCandidate::Copy == stmt->getDeductionCandidateKind());
3637 const bool isImplicit{stmt->isImplicit()};
3638 const bool noSpecializations = [&] {
3639 if(
const auto* dt = stmt->getDescribedFunctionTemplate()) {
3640 return dt->specializations().empty();
3647 RETURN_IF(not stmt->isUsed() and isImplicit and noSpecializations);
3649 const bool isSpecialization{stmt->isFunctionTemplateSpecialization()};
3650 const bool needsTemplateGuard{isImplicit or isSpecialization};
3652 if(needsTemplateGuard) {
3656 const auto* deducedTemplate = stmt->getDeducedTemplate();
3658 if(isSpecialization) {
3660 }
else if(
const auto* e = stmt->getDescribedFunctionTemplate()) {
3666 if(stmt->getNumParams()) {
3674 if(needsTemplateGuard) {
3693 for(
const auto* spec : stmt->specializations()) {
3695 if(spec->getPreviousDecl()) {
3722 for(
const auto& attr : stmt->getAttrs()) {
3732 if(stmt->hasAttrs()) {
3743 for(
const auto& attr : attrs) {
3752 RETURN_IF(attr::Override == attr.getKind());
3755 RETURN_IF(attr::Final == attr.getKind());
3758 RETURN_IF(attr::NoInline == attr.getKind());
3760#if IS_CLANG_NEWER_THAN(20)
3762 RETURN_IF(attr::InferredNoReturn == attr.getKind());
3766 if(
const auto* alignedAttr = dyn_cast_or_null<AlignedAttr>(&attr)) {
3767 auto insert = [&](
const QualType type,
const TemplateTypeParmType* tmplTypeParam) {
3774 Ellipsis(tmplTypeParam->isParameterPack()),
3778 if(alignedAttr->isAlignmentExpr()) {
3779 if(
const auto* unaryExpr = dyn_cast_or_null<UnaryExprOrTypeTraitExpr>(alignedAttr->getAlignmentExpr())) {
3780 if(
const auto* tmplTypeParam =
3781 dyn_cast_or_null<TemplateTypeParmType>(unaryExpr->getArgumentType().getTypePtrOrNull())) {
3782 insert(unaryExpr->getArgumentType(), tmplTypeParam);
3786 }
else if(
const auto* tmplTypeParam =
3787 alignedAttr->getAlignmentType()->getType()->getAs<TemplateTypeParmType>()) {
3788 insert(alignedAttr->getAlignmentType()->getType(), tmplTypeParam);
3795 pp.adjustForCPlusPlus();
3797 attr.printPretty(stream, pp);
3800 std::string_view start{stream.str()};
3813 const auto* classTemplatePartialSpecializationDecl = dyn_cast_or_null<ClassTemplatePartialSpecializationDecl>(stmt);
3814 const auto* classTemplateSpecializationDecl = dyn_cast_or_null<ClassTemplateSpecializationDecl>(stmt);
3818 const bool isClassTemplateSpecialization{classTemplatePartialSpecializationDecl or classTemplateSpecializationDecl};
3819 const bool tmplRequiresIfDef{[&] {
3820 if(classTemplatePartialSpecializationDecl) {
3821 return classTemplatePartialSpecializationDecl->isImplicit();
3823 }
else if(classTemplateSpecializationDecl) {
3824 return not classTemplateSpecializationDecl->isExplicitInstantiationOrSpecialization();
3831 if(tmplRequiresIfDef) {
3836 if(isClassTemplateSpecialization) {
3837 if(tmplRequiresIfDef) {
3839 classTemplateSpecializationDecl->getPointOfInstantiation());
3843 if(classTemplatePartialSpecializationDecl) {
3849 }
else if(stmt->getLexicalDeclContext() != stmt->getDeclContext()) {
3850 if(
const auto* parent = dyn_cast_or_null<CXXRecordDecl>(stmt->getDeclContext())) {
3851 if(
const auto* outerClasTemplateDecl = parent->getDescribedClassTemplate()) {
3863 if(classTemplateSpecializationDecl) {
3867 if(stmt->hasAttr<FinalAttr>()) {
3872 if(not stmt->hasDefinition() or not stmt->isCompleteDefinition()) {
3877 if(stmt->getNumBases()) {
3880 ForEachArg(stmt->bases(), [&](
const auto& base) {
3881 mOutputFormatHelper.Append(getAccessSpelling(base.getAccessSpecifier()),
3883 ValueOrDefault(base.isVirtual(), kwVirtualSpace),
3884 GetName(base.getType()),
3885 Ellipsis(base.isPackExpansion()));
3892 " /* size: "sv, recordLayout.getSize(),
", align: "sv, recordLayout.getAlignment(),
" */"sv);
3901 for(
size_t offset{};
const auto& base : stmt->bases()) {
3902 const auto& baseRecordLayout =
GetRecordLayout(base.getType()->getAsRecordDecl());
3903 const auto baseVar =
StrCat(
"/* base ("sv,
GetName(base.getType()),
")"sv);
3904 const auto size = baseRecordLayout.getSize().getQuantity();
3907 baseVar,
GetSpaces(baseVar.size()),
" offset: "sv, offset,
", size: "sv, size,
" */"sv);
3915 const bool isLambda{stmt->isLambda()};
3916 Decl::Kind formerKind{};
3917 AccessSpecifier lastAccess{stmt->isClass() ? AS_private : AS_public};
3918 for(
OnceTrue firstRecordDecl{}, firstDecl{};
const auto* d : stmt->decls()) {
3919 if(isa<CXXRecordDecl>(d) and firstRecordDecl) {
3925 if(not firstDecl and (d->getKind() != formerKind)) {
3929 if((isLambda and isa<CXXDestructorDecl>(d)) and not d->isUsed()) {
3935 if(lastAccess != d->getAccess()) {
3936 lastAccess = d->getAccess();
3939 if(not isa<AccessSpecDecl>(d)) {
3944 if(isa<FieldDecl>(d) and isLambda) {
3956 formerKind = d->getKind();
3960 if(isLambda and stmt->lambdaIsDefaultConstructibleAndAssignable()) {
3961 if(AS_public != lastAccess) {
3968 if(stmt->hasConstexprDefaultConstructor()) {
3990 for(
const auto* decl : stmt->decls()) {
4004 if(stmt->isPartiallySubstituted()) {
4006 }
else if(not stmt->isValueDependent()) {
4021 TemporaryDeclFinder temporaryFinder{*
this, stmt->getRetValue(),
true};
4025 if(
const auto* retVal = stmt->getRetValue()) {
4028 if(not temporaryFinder.Found()) {
4029 if(
const auto* nrvoVD = stmt->getNRVOCandidate()) {
4070 if(
const auto* namedConcept = stmt->getNamedConcept()) {
4075 if(not stmt->isValueDependent()) {
4087 const auto localParameters = stmt->getLocalParameters();
4089 not localParameters.empty(),
4090 [&] { mOutputFormatHelper.AppendParameterList(localParameters); },
4091 AddSpaceAtTheEnd::Yes);
4099 for(
const auto& requirement : stmt->getRequirements()) {
4100 if(
const auto* typeRequirement = dyn_cast_or_null<concepts::TypeRequirement>(requirement)) {
4101 if(typeRequirement->isSubstitutionFailure()) {
4108 }
else if(
const auto* exprRequirement = dyn_cast_or_null<concepts::ExprRequirement>(requirement)) {
4109 if(exprRequirement->isExprSubstitutionFailure()) {
4114 WrapInCurliesIfNeeded(exprRequirement->isCompound(), [&] { InsertArg(exprRequirement->getExpr()); });
4116 if(exprRequirement->hasNoexceptRequirement()) {
4120 if(
const auto& returnTypeRequirement = exprRequirement->getReturnTypeRequirement();
4121 not returnTypeRequirement.isEmpty()) {
4123 not typeConstraint.empty()) {
4128 }
else if(
const auto* nestedRequirement = dyn_cast_or_null<concepts::NestedRequirement>(requirement)) {
4131 if(nestedRequirement->hasInvalidConstraint()) {
4136 InsertArg(nestedRequirement->getConstraintExpr());
4157 const auto typeName{
GetName(stmt->getType(), Unqualified::Yes)};
4163 const auto* subExpr = stmt->getSubExpr();
4165 if(
const auto* dref = dyn_cast_or_null<DeclRefExpr>(subExpr); dref and
GetInsightsOptions().ShowLifetime) {
4166 const auto size =
GetSize(dyn_cast_or_null<ConstantArrayType>(subExpr->getType()));
4172 std::string modifiers{};
4176 auto& ofmToInsert = [&]() ->
decltype(
auto) {
4188 OutputFormatHelper ofm{};
4189 ofm.SetIndent(ofmToInsert, OutputFormatHelper::SkipIndenting::Yes);
4191 const auto size = [&]() ->
size_t {
4192 if(
const auto* mat = dyn_cast<MaterializeTemporaryExpr>(subExpr)) {
4193 if(
const auto* list = dyn_cast_or_null<InitListExpr>(mat->getSubExpr())) {
4194 return list->getNumInits();
4201 auto internalListName =
4207 ofm.AppendSemiNewLine();
4209 ofmToInsert.InsertAt(variableInsertPos, ofm);
4244#define SUPPORTED_DECL(type) \
4245 if(isa<type>(stmt)) { \
4246 InsertArg(static_cast<const type*>(stmt)); \
4250#define IGNORED_DECL SUPPORTED_DECL