dblaikie updated this revision to Diff 508842. dblaikie added a comment. Remove `StaticDataMember` and classify static member variables of templates as variable templates
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D138247/new/ https://reviews.llvm.org/D138247 Files: clang/lib/Sema/SemaLambda.cpp clang/test/CodeGenCXX/mangle-lambdas.cpp Index: clang/test/CodeGenCXX/mangle-lambdas.cpp =================================================================== --- clang/test/CodeGenCXX/mangle-lambdas.cpp +++ clang/test/CodeGenCXX/mangle-lambdas.cpp @@ -290,6 +290,17 @@ // CHECK-LABEL: define linkonce_odr noundef i32 @_ZZZ3ft4IiEvvEN2lc2mfEiEd_NKUlvE_clEv +extern int ExternalVariable; +struct StaticInlineMember { + static constexpr auto x = [] { return ExternalVariable; }; +}; + +// CHECK-LABEL: define void @_Z23test_StaticInlineMemberv +// CHECK: call {{.*}} @_ZNK18StaticInlineMember1xMUlvE_clEv +void test_StaticInlineMember() { + StaticInlineMember::x(); +} + // Check linkage of the various lambdas. // CHECK-LABEL: define linkonce_odr noundef i32 @_ZZ11inline_funciENKUlvE_clEv // CHECK: ret i32 1 Index: clang/lib/Sema/SemaLambda.cpp =================================================================== --- clang/lib/Sema/SemaLambda.cpp +++ clang/lib/Sema/SemaLambda.cpp @@ -283,12 +283,14 @@ Normal, DefaultArgument, DataMember, - StaticDataMember, InlineVariable, VariableTemplate, Concept } Kind = Normal; + bool IsInNonspecializedTemplate = + inTemplateInstantiation() || CurContext->isDependentContext(); + // Default arguments of member function parameters that appear in a class // definition, as well as the initializers of data members, receive special // treatment. Identify them. @@ -299,10 +301,10 @@ if (LexicalDC->isRecord()) Kind = DefaultArgument; } else if (VarDecl *Var = dyn_cast<VarDecl>(ManglingContextDecl)) { - if (Var->getDeclContext()->isRecord()) - Kind = StaticDataMember; - else if (Var->getMostRecentDecl()->isInline()) + if (Var->getMostRecentDecl()->isInline()) Kind = InlineVariable; + else if (Var->getDeclContext()->isRecord() && IsInNonspecializedTemplate) + Kind = VariableTemplate; else if (Var->getDescribedVarTemplate()) Kind = VariableTemplate; else if (auto *VTS = dyn_cast<VarTemplateSpecializationDecl>(Var)) { @@ -319,12 +321,9 @@ // Itanium ABI [5.1.7]: // In the following contexts [...] the one-definition rule requires closure // types in different translation units to "correspond": - bool IsInNonspecializedTemplate = - inTemplateInstantiation() || CurContext->isDependentContext(); switch (Kind) { case Normal: { - // -- the bodies of non-exported nonspecialized template functions - // -- the bodies of inline functions + // -- the bodies of inline or templated functions if ((IsInNonspecializedTemplate && !(ManglingContextDecl && isa<ParmVarDecl>(ManglingContextDecl))) || isInInlineFunction(CurContext)) { @@ -341,21 +340,13 @@ // however the ManglingContextDecl is important for the purposes of // re-forming the template argument list of the lambda for constraint // evaluation. - case StaticDataMember: - // -- the initializers of nonspecialized static members of template classes - if (!IsInNonspecializedTemplate) - return std::make_tuple(nullptr, ManglingContextDecl); - // Fall through to get the current context. - [[fallthrough]]; - case DataMember: - // -- the in-class initializers of class members + // -- default member initializers case DefaultArgument: // -- default arguments appearing in class definitions case InlineVariable: - // -- the initializers of inline variables case VariableTemplate: - // -- the initializers of templated variables + // -- the initializers of inline or templated variables return std::make_tuple( &Context.getManglingNumberContext(ASTContext::NeedExtraManglingDecl, ManglingContextDecl),
Index: clang/test/CodeGenCXX/mangle-lambdas.cpp =================================================================== --- clang/test/CodeGenCXX/mangle-lambdas.cpp +++ clang/test/CodeGenCXX/mangle-lambdas.cpp @@ -290,6 +290,17 @@ // CHECK-LABEL: define linkonce_odr noundef i32 @_ZZZ3ft4IiEvvEN2lc2mfEiEd_NKUlvE_clEv +extern int ExternalVariable; +struct StaticInlineMember { + static constexpr auto x = [] { return ExternalVariable; }; +}; + +// CHECK-LABEL: define void @_Z23test_StaticInlineMemberv +// CHECK: call {{.*}} @_ZNK18StaticInlineMember1xMUlvE_clEv +void test_StaticInlineMember() { + StaticInlineMember::x(); +} + // Check linkage of the various lambdas. // CHECK-LABEL: define linkonce_odr noundef i32 @_ZZ11inline_funciENKUlvE_clEv // CHECK: ret i32 1 Index: clang/lib/Sema/SemaLambda.cpp =================================================================== --- clang/lib/Sema/SemaLambda.cpp +++ clang/lib/Sema/SemaLambda.cpp @@ -283,12 +283,14 @@ Normal, DefaultArgument, DataMember, - StaticDataMember, InlineVariable, VariableTemplate, Concept } Kind = Normal; + bool IsInNonspecializedTemplate = + inTemplateInstantiation() || CurContext->isDependentContext(); + // Default arguments of member function parameters that appear in a class // definition, as well as the initializers of data members, receive special // treatment. Identify them. @@ -299,10 +301,10 @@ if (LexicalDC->isRecord()) Kind = DefaultArgument; } else if (VarDecl *Var = dyn_cast<VarDecl>(ManglingContextDecl)) { - if (Var->getDeclContext()->isRecord()) - Kind = StaticDataMember; - else if (Var->getMostRecentDecl()->isInline()) + if (Var->getMostRecentDecl()->isInline()) Kind = InlineVariable; + else if (Var->getDeclContext()->isRecord() && IsInNonspecializedTemplate) + Kind = VariableTemplate; else if (Var->getDescribedVarTemplate()) Kind = VariableTemplate; else if (auto *VTS = dyn_cast<VarTemplateSpecializationDecl>(Var)) { @@ -319,12 +321,9 @@ // Itanium ABI [5.1.7]: // In the following contexts [...] the one-definition rule requires closure // types in different translation units to "correspond": - bool IsInNonspecializedTemplate = - inTemplateInstantiation() || CurContext->isDependentContext(); switch (Kind) { case Normal: { - // -- the bodies of non-exported nonspecialized template functions - // -- the bodies of inline functions + // -- the bodies of inline or templated functions if ((IsInNonspecializedTemplate && !(ManglingContextDecl && isa<ParmVarDecl>(ManglingContextDecl))) || isInInlineFunction(CurContext)) { @@ -341,21 +340,13 @@ // however the ManglingContextDecl is important for the purposes of // re-forming the template argument list of the lambda for constraint // evaluation. - case StaticDataMember: - // -- the initializers of nonspecialized static members of template classes - if (!IsInNonspecializedTemplate) - return std::make_tuple(nullptr, ManglingContextDecl); - // Fall through to get the current context. - [[fallthrough]]; - case DataMember: - // -- the in-class initializers of class members + // -- default member initializers case DefaultArgument: // -- default arguments appearing in class definitions case InlineVariable: - // -- the initializers of inline variables case VariableTemplate: - // -- the initializers of templated variables + // -- the initializers of inline or templated variables return std::make_tuple( &Context.getManglingNumberContext(ASTContext::NeedExtraManglingDecl, ManglingContextDecl),
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits