1414#include " CodeGenerator.h"
1515#include " DPrint.h"
1616#include " Insights.h"
17- #include " InsightsBase.h"
1817#include " InsightsHelpers.h"
19- #include " InsightsMatchers.h"
2018#include " InsightsOnce.h"
2119#include " InsightsStrCat.h"
2220#include " NumberIterator.h"
@@ -202,7 +200,7 @@ class LambdaInitCaptureCodeGenerator final : public CodeGenerator
202200 explicit LambdaInitCaptureCodeGenerator (OutputFormatHelper& outputFormatHelper,
203201 LambdaStackType& lambdaStack,
204202 std::string_view varName)
205- : CodeGenerator{outputFormatHelper, lambdaStack}
203+ : CodeGenerator{outputFormatHelper, lambdaStack, ProcessingPrimaryTemplate::No }
206204 , mVarName {varName}
207205 {
208206 }
@@ -1097,6 +1095,7 @@ std::string EmitGlobalVariableCtors()
10971095
10981096 OutputFormatHelper ofm{};
10991097 ofm.AppendNewLine ();
1098+ ofm.AppendNewLine ();
11001099 CodeGeneratorVariant cg{ofm};
11011100 cg->InsertArg (cxaStartFun);
11021101
@@ -1128,6 +1127,30 @@ void CodeGenerator::EndLifetimeScope()
11281127}
11291128// -----------------------------------------------------------------------------
11301129
1130+ void CodeGenerator::InsertArg (const LinkageSpecDecl* stmt)
1131+ {
1132+ mOutputFormatHelper .Append (" extern \" " ,
1133+ (
1134+ #if IS_CLANG_NEWER_THAN(17)
1135+ LinkageSpecLanguageIDs::C
1136+ #else
1137+ LinkageSpecDecl::lang_c
1138+ #endif
1139+ == stmt->getLanguage ())
1140+ ? " C" sv
1141+ : " C++" sv,
1142+ " \" " );
1143+ mOutputFormatHelper .OpenScope ();
1144+
1145+ for (const auto * decl : stmt->decls ()) {
1146+ InsertArg (decl);
1147+ }
1148+
1149+ mOutputFormatHelper .CloseScope ();
1150+ mOutputFormatHelper .AppendNewLine ();
1151+ }
1152+ // -----------------------------------------------------------------------------
1153+
11311154void CodeGenerator::InsertArg (const VarDecl* stmt)
11321155{
11331156 if (auto * init = stmt->getInit ();
@@ -1454,6 +1477,10 @@ void CodeGenerator::InsertArg(const CoroutineSuspendExpr* stmt)
14541477 } else {
14551478 InsertArg (temporary);
14561479 }
1480+ } else if (const auto * unaryexpr = dyn_cast_or_null<UnaryOperator>(stmt->getOperand ())) {
1481+ if (const auto * callExpr = dyn_cast_or_null<CallExpr>(unaryexpr->getSubExpr ())) {
1482+ InsertArg (callExpr->getArg (0 ));
1483+ }
14571484 }
14581485}
14591486// -----------------------------------------------------------------------------
@@ -1476,7 +1503,8 @@ void CodeGenerator::InsertMethodBody(const FunctionDecl* stmt, const size_t posB
14761503 }
14771504 }
14781505
1479- return (FunctionDecl::TK_FunctionTemplate == stmt->getTemplatedKind ());
1506+ return (FunctionDecl::TK_FunctionTemplate == stmt->getTemplatedKind ()) or
1507+ (ProcessingPrimaryTemplate::Yes == mProcessingPrimaryTemplate );
14801508 };
14811509
14821510 if (stmt->doesThisDeclarationHaveABody ()) {
@@ -3010,7 +3038,7 @@ void CodeGenerator::InsertCXXMethodHeader(const CXXMethodDecl* stmt, OutputForma
30103038 // Traverse the ctor inline init statements first to find a potential CXXInheritedCtorInitExpr. This carries the
30113039 // name and the type. The CXXMethodDecl above knows only the type.
30123040 if (const auto * ctor = dyn_cast_or_null<CXXConstructorDecl>(stmt)) {
3013- CodeGeneratorVariant codeGenerator{initOutputFormatHelper, mLambdaStack };
3041+ CodeGeneratorVariant codeGenerator{initOutputFormatHelper, mLambdaStack , mProcessingPrimaryTemplate };
30143042 codeGenerator->mCurrentPos = mCurrentPos ;
30153043 codeGenerator->mCurrentFieldPos = mCurrentFieldPos ;
30163044 codeGenerator->mOutputFormatHelperOutside = &mOutputFormatHelper ;
@@ -3026,6 +3054,7 @@ void CodeGenerator::InsertCXXMethodHeader(const CXXMethodDecl* stmt, OutputForma
30263054 }
30273055
30283056 // in case of delegating or base initializer there is no member.
3057+ #if 0
30293058 if(const auto* member = init->getMember()) {
30303059 initOutputFormatHelper.Append(member->getName());
30313060 codeGenerator->InsertCurlysIfRequired(init->getInit());
@@ -3045,6 +3074,36 @@ void CodeGenerator::InsertCXXMethodHeader(const CXXMethodDecl* stmt, OutputForma
30453074
30463075 codeGenerator->WrapInCurliesIfNeeded(useCurlies, [&] { codeGenerator->InsertArg(inlineInit); });
30473076 }
3077+ #else
3078+ const auto * inlineInit = init->getInit ();
3079+
3080+ // in case of delegating or base initializer there is no member.
3081+ if (const auto * member = init->getMember ()) {
3082+ initOutputFormatHelper.Append (member->getName ());
3083+
3084+ if (isa<ParenListExpr>(inlineInit)) {
3085+ codeGenerator->WrapInParens ([&] { codeGenerator->InsertArg (inlineInit); });
3086+ } else {
3087+ codeGenerator->InsertCurlysIfRequired (inlineInit);
3088+ }
3089+
3090+ } else if (const auto * cxxInheritedCtorInitExpr = dyn_cast_or_null<CXXInheritedCtorInitExpr>(inlineInit)) {
3091+ cxxInheritedCtorDecl = cxxInheritedCtorInitExpr->getConstructor ();
3092+
3093+ codeGenerator->InsertArg (inlineInit);
3094+
3095+ // Insert the base class name only, if it is not a CXXContructorExpr and not a
3096+ // CXXDependentScopeMemberExpr which already carry the type.
3097+ } else if (init->isBaseInitializer () and not isa<CXXConstructExpr>(inlineInit)) {
3098+ initOutputFormatHelper.Append (GetUnqualifiedScopelessName (init->getBaseClass ()));
3099+
3100+ const auto braceKind = isa<ParenListExpr>(inlineInit) ? BraceKind::Parens : BraceKind::Curlys;
3101+
3102+ codeGenerator->WrapInParensOrCurlys (braceKind, [&] { codeGenerator->InsertArg (inlineInit); });
3103+ } else {
3104+ codeGenerator->InsertArg (inlineInit);
3105+ }
3106+ #endif
30483107 }
30493108 }
30503109
@@ -3069,7 +3128,7 @@ void CodeGenerator::InsertCXXMethodDecl(const CXXMethodDecl* stmt, SkipBody skip
30693128
30703129 InsertCXXMethodHeader (stmt, initOutputFormatHelper);
30713130
3072- if (not stmt->isUserProvided ()) {
3131+ if (not stmt->isUserProvided () or stmt-> isExplicitlyDefaulted () ) {
30733132 InsertTemplateGuardEnd (stmt);
30743133 return ;
30753134 }
@@ -3357,6 +3416,7 @@ void CodeGenerator::InsertArg(const NamespaceDecl* stmt)
33573416 }
33583417
33593418 mOutputFormatHelper .CloseScope ();
3419+ mOutputFormatHelper .AppendNewLine ();
33603420}
33613421// -----------------------------------------------------------------------------
33623422
@@ -3482,14 +3542,14 @@ void CodeGenerator::InsertArg(const CXXDeductionGuideDecl* stmt)
34823542 InsertTemplateSpecializationHeader ();
34833543 } else if (const auto * e = stmt->getDescribedFunctionTemplate ()) {
34843544 InsertTemplateParameters (*e->getTemplateParameters ());
3485- } else {
3486- InsertTemplateParameters (*deducedTemplate->getTemplateParameters ());
34873545 }
34883546
34893547 mOutputFormatHelper .Append (GetName (*deducedTemplate));
34903548
34913549 if (stmt->getNumParams ()) {
34923550 WrapInParens ([&] { mOutputFormatHelper .AppendParameterList (stmt->parameters ()); });
3551+ } else {
3552+ mOutputFormatHelper .Append (" ()" sv);
34933553 }
34943554
34953555 mOutputFormatHelper .AppendSemiNewLine (hlpArrow, GetName (stmt->getReturnType ()));
@@ -3510,12 +3570,21 @@ void CodeGenerator::InsertTemplate(const FunctionTemplateDecl* stmt, bool withSp
35103570{
35113571 LAMBDA_SCOPE_HELPER (TemplateHead);
35123572
3573+ mProcessingPrimaryTemplate = ProcessingPrimaryTemplate::Yes;
3574+
35133575 // InsertTemplateParameters(*stmt->getTemplateParameters());
35143576 InsertArg (stmt->getTemplatedDecl ());
35153577
3578+ mProcessingPrimaryTemplate = ProcessingPrimaryTemplate::No;
3579+
35163580 RETURN_IF (not withSpec);
35173581
35183582 for (const auto * spec : stmt->specializations ()) {
3583+ // For specializations we will see them later
3584+ if (spec->getPreviousDecl ()) {
3585+ continue ;
3586+ }
3587+
35193588 mOutputFormatHelper .AppendNewLine ();
35203589 InsertArg (spec);
35213590 mOutputFormatHelper .AppendNewLine ();
@@ -3885,7 +3954,7 @@ void CodeGenerator::InsertArg(const CXXRecordDecl* stmt)
38853954 if (P0315Visitor dt{cgLambdaInCtor}; dt.TraverseStmt (const_cast <Expr*>(expr))) {
38863955
38873956 OutputFormatHelper ofm{};
3888- CodeGeneratorVariant codeGenerator{ofm, mLambdaStack };
3957+ CodeGeneratorVariant codeGenerator{ofm, mLambdaStack , mProcessingPrimaryTemplate };
38893958
38903959 if (const auto * ctorExpr = dyn_cast_or_null<CXXConstructExpr>(expr);
38913960 ctorExpr and byConstRef and (1 == ctorExpr->getNumArgs ())) {
@@ -4545,7 +4614,7 @@ void CodeGenerator::HandleLambdaExpr(const LambdaExpr* lambda, LambdaHelper& lam
45454614 OutputFormatHelper& outputFormatHelper = lambdaHelper.buffer ();
45464615
45474616 outputFormatHelper.AppendNewLine ();
4548- LambdaCodeGenerator codeGenerator{outputFormatHelper, mLambdaStack };
4617+ LambdaCodeGenerator codeGenerator{outputFormatHelper, mLambdaStack , mProcessingPrimaryTemplate };
45494618 codeGenerator.mCapturedThisAsCopy = [&] {
45504619 for (const auto & c : lambda->captures ()) {
45514620 const auto captureKind = c.getCaptureKind ();
@@ -4649,24 +4718,35 @@ void CodeGenerator::InsertFunctionNameWithReturnType(const FunctionDecl& d
46494718 kwUsingSpace, BuildRetTypeName (decl), hlpAssing, GetName (desugaredReturnType));
46504719 }
46514720
4721+ if (isCXXMethodDecl and decl.isOutOfLine ()) {
4722+ if (const auto * parent = methodDecl->getParent ()) {
4723+ if (const auto * outerClasTemplateDecl = parent->getDescribedClassTemplate ()) {
4724+ InsertTemplateParameters (*outerClasTemplateDecl->getTemplateParameters ());
4725+ }
4726+ }
4727+ }
4728+
46524729 if (decl.isTemplated ()) {
46534730 if (decl.getDescribedTemplate ()) {
46544731 InsertTemplateParameters (*decl.getDescribedTemplate ()->getTemplateParameters ());
46554732 }
46564733
4657- } else if (decl.isFunctionTemplateSpecialization ()) {
4734+ } else if (decl.isFunctionTemplateSpecialization () or (isClassTemplateSpec and decl.isOutOfLine () and
4735+ (decl.getLexicalDeclContext () != methodDecl->getParent ()))) {
46584736 InsertTemplateSpecializationHeader ();
46594737 }
46604738
46614739 InsertAttributes (decl.attrs ());
46624740
46634741 if (not decl.isFunctionTemplateSpecialization () or (isCXXMethodDecl and isFirstCxxMethodDecl)) {
4664- mOutputFormatHelper .Append (GetStorageClassAsStringWithSpace (decl.getStorageClass ()));
4742+ if (not decl.isOutOfLine () or (decl.getStorageClass () == SC_Extern)) {
4743+ mOutputFormatHelper .Append (GetStorageClassAsStringWithSpace (decl.getStorageClass ()));
4744+ }
46654745
46664746 // [class.free]: Any allocation function for a class T is a static member (even if not explicitly declared
46674747 // static). (https://eel.is/c++draft/class.free#1)
46684748 // However, Clang does not add `static` to `getStorageClass` so this needs to be check independently.
4669- if (isCXXMethodDecl) {
4749+ if (isCXXMethodDecl and not decl. isOutOfLine () ) {
46704750 // GetStorageClassAsStringWithSpace already carries static, if the method was marked so explicitly
46714751 if ((not IsStaticStorageClass (methodDecl)) and (methodDecl->isStatic ())) {
46724752 mOutputFormatHelper .Append (kwStaticSpace);
@@ -4742,7 +4822,12 @@ void CodeGenerator::InsertFunctionNameWithReturnType(const FunctionDecl& d
47424822 OutputFormatHelper outputFormatHelper{};
47434823
47444824 if (methodDecl) {
4745- if (not isFirstCxxMethodDecl or InsertNamespace ()) {
4825+ if (not isFirstCxxMethodDecl or InsertNamespace () and decl.getQualifier ()) {
4826+ CodeGeneratorVariant cg{outputFormatHelper};
4827+ cg->InsertNamespace (decl.getQualifier ());
4828+
4829+ // This comes from a using Base::SomeFunc
4830+ } else if (not isFirstCxxMethodDecl or InsertNamespace () and not decl.getQualifier ()) {
47464831 const auto * parent = methodDecl->getParent ();
47474832 outputFormatHelper.Append (parent->getName ());
47484833
0 commit comments