Author: Richard Smith Date: 2021-05-11T17:46:18-07:00 New Revision: bb726383ac7554857c62edd2d19e83dc713165ee
URL: https://github.com/llvm/llvm-project/commit/bb726383ac7554857c62edd2d19e83dc713165ee DIFF: https://github.com/llvm/llvm-project/commit/bb726383ac7554857c62edd2d19e83dc713165ee.diff LOG: Revert "Fix bad mangling of <data-member-prefix> for a closure in the initializer of a variable at global namespace scope." This reverts commit 697ac15a0fc71888c372667bdbc5583ab42d4695, for which review was not complete. That change was accidentally pushed when an unrelated change was pushed. Added: Modified: clang/include/clang/Basic/CodeGenOptions.h clang/include/clang/Basic/LangOptions.h clang/lib/AST/ItaniumMangle.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/test/CodeGenCXX/clang-abi-compat.cpp clang/test/CodeGenCXX/lambda-expressions-nested-linkage.cpp clang/test/CodeGenCXX/mangle-lambda-explicit-template-params.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h index 3f06dd3a3f82..8f75886d84d5 100644 --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -75,6 +75,23 @@ class CodeGenOptions : public CodeGenOptionsBase { LocalExecTLSModel }; + /// Clang versions with diff erent platform ABI conformance. + enum class ClangABI { + /// Attempt to be ABI-compatible with code generated by Clang 3.8.x + /// (SVN r257626). This causes <1 x long long> to be passed in an + /// integer register instead of an SSE register on x64_64. + Ver3_8, + + /// Attempt to be ABI-compatible with code generated by Clang 4.0.x + /// (SVN r291814). This causes move operations to be ignored when + /// determining whether a class type can be passed or returned directly. + Ver4, + + /// Conform to the underlying platform's C and C++ ABIs as closely + /// as we can. + Latest + }; + enum StructReturnConventionKind { SRCK_Default, // No special option was passed. SRCK_OnStack, // Small structs on the stack (-fpcc-struct-return). diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 524b79b13814..5ccac6367a5f 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -164,18 +164,13 @@ class LangOptions : public LangOptionsBase { Ver9, /// Attempt to be ABI-compatible with code generated by Clang 11.0.x - /// (git 2e10b7a39b93). This causes clang to pass unions with a 256-bit + /// (git 2e10b7a39b93). This causes clang to pass unions with a 256-bit /// vector member on the stack instead of using registers, to not properly /// mangle substitutions for template names in some cases, and to mangle /// declaration template arguments without a cast to the parameter type /// even when that can lead to mangling collisions. Ver11, - /// Attempt to be ABI-compatible with code generated by Clang 12.0.x - /// (git 8e464dd76bef). This causes clang to mangle lambdas within - /// global-scope inline variables incorrectly. - Ver12, - /// Conform to the underlying platform's C and C++ ABIs as closely /// as we can. Latest diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 84757c448361..79fec683b701 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -538,16 +538,11 @@ class CXXNameMangler { void mangleNestedName(const TemplateDecl *TD, const TemplateArgument *TemplateArgs, unsigned NumTemplateArgs); - void mangleNestedNameWithClosurePrefix(GlobalDecl GD, - const NamedDecl *PrefixND, - const AbiTagList *AdditionalAbiTags); void manglePrefix(NestedNameSpecifier *qualifier); void manglePrefix(const DeclContext *DC, bool NoFunction=false); void manglePrefix(QualType type); void mangleTemplatePrefix(GlobalDecl GD, bool NoFunction=false); void mangleTemplatePrefix(TemplateName Template); - const NamedDecl *getClosurePrefix(const Decl *ND); - void mangleClosurePrefix(const NamedDecl *ND, bool NoFunction = false); bool mangleUnresolvedTypeOrSimpleId(QualType DestroyedType, StringRef Prefix = ""); void mangleOperatorName(DeclarationName Name, unsigned Arity); @@ -987,13 +982,6 @@ void CXXNameMangler::mangleNameWithAbiTags(GlobalDecl GD, if (Module *M = ND->getOwningModuleForLinkage()) mangleModuleName(M); - // Closures can require a nested-name mangling even if they're semantically - // in the global namespace. - if (const NamedDecl *PrefixND = getClosurePrefix(ND)) { - mangleNestedNameWithClosurePrefix(GD, PrefixND, AdditionalAbiTags); - return; - } - if (DC->isTranslationUnit() || isStdNamespace(DC)) { // Check if we have a template. const TemplateArgumentList *TemplateArgs = nullptr; @@ -1668,7 +1656,8 @@ void CXXNameMangler::mangleNestedName(GlobalDecl GD, if (GlobalDecl TD = isTemplate(GD, TemplateArgs)) { mangleTemplatePrefix(TD, NoFunction); mangleTemplateArgs(asTemplateName(TD), *TemplateArgs); - } else { + } + else { manglePrefix(DC, NoFunction); mangleUnqualifiedName(GD, AdditionalAbiTags); } @@ -1688,23 +1677,6 @@ void CXXNameMangler::mangleNestedName(const TemplateDecl *TD, Out << 'E'; } -void CXXNameMangler::mangleNestedNameWithClosurePrefix( - GlobalDecl GD, const NamedDecl *PrefixND, - const AbiTagList *AdditionalAbiTags) { - // A <closure-prefix> represents a variable or field, not a regular - // DeclContext, so needs special handling. In this case we're mangling a - // limited form of <nested-name>: - // - // <nested-name> ::= N <closure-prefix> <closure-type-name> E - - Out << 'N'; - - mangleClosurePrefix(PrefixND); - mangleUnqualifiedName(GD, AdditionalAbiTags); - - Out << 'E'; -} - static GlobalDecl getParentOfLocalEntity(const DeclContext *DC) { GlobalDecl GD; // The Itanium spec says: @@ -1780,10 +1752,7 @@ void CXXNameMangler::mangleLocalName(GlobalDecl GD, if (D == RD) { mangleUnqualifiedName(RD, AdditionalAbiTags); } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) { - if (const NamedDecl *PrefixND = getClosurePrefix(BD)) - mangleClosurePrefix(PrefixND, true /*NoFunction*/); - else - manglePrefix(getEffectiveDeclContext(BD), true /*NoFunction*/); + manglePrefix(getEffectiveDeclContext(BD), true /*NoFunction*/); assert(!AdditionalAbiTags && "Block cannot have additional abi tags"); mangleUnqualifiedBlock(BD); } else { @@ -1833,20 +1802,13 @@ void CXXNameMangler::mangleBlockForPrefix(const BlockDecl *Block) { mangleLocalName(Block, /* AdditionalAbiTags */ nullptr); return; } - if (const NamedDecl *PrefixND = getClosurePrefix(Block)) - mangleClosurePrefix(PrefixND); - else - manglePrefix(DC); + manglePrefix(getEffectiveDeclContext(Block)); mangleUnqualifiedBlock(Block); } void CXXNameMangler::mangleUnqualifiedBlock(const BlockDecl *Block) { - // When trying to be ABI-compatibility with clang 12 and before, mangle a - // <data-member-prefix> now, with no substitutions and no <template-args>. if (Decl *Context = Block->getBlockManglingContextDecl()) { - if (getASTContext().getLangOpts().getClangABICompat() <= - LangOptions::ClangABI::Ver12 && - (isa<VarDecl>(Context) || isa<FieldDecl>(Context)) && + if ((isa<VarDecl>(Context) || isa<FieldDecl>(Context)) && Context->getDeclContext()->isRecord()) { const auto *ND = cast<NamedDecl>(Context); if (ND->getIdentifier()) { @@ -1919,13 +1881,20 @@ void CXXNameMangler::mangleTemplateParamDecl(const NamedDecl *Decl) { } void CXXNameMangler::mangleLambda(const CXXRecordDecl *Lambda) { - // When trying to be ABI-compatibility with clang 12 and before, mangle a - // <data-member-prefix> now, with no substitutions. + // If the context of a closure type is an initializer for a class member + // (static or nonstatic), it is encoded in a qualified name with a final + // <prefix> of the form: + // + // <data-member-prefix> := <member source-name> M + // + // Technically, the data-member-prefix is part of the <prefix>. However, + // since a closure type will always be mangled with a prefix, it's easier + // to emit that last part of the prefix here. if (Decl *Context = Lambda->getLambdaContextDecl()) { - if (getASTContext().getLangOpts().getClangABICompat() <= - LangOptions::ClangABI::Ver12 && - (isa<VarDecl>(Context) || isa<FieldDecl>(Context)) && + if ((isa<VarDecl>(Context) || isa<FieldDecl>(Context)) && !isa<ParmVarDecl>(Context)) { + // FIXME: 'inline auto [a, b] = []{ return ... };' does not get a + // reasonable mangling here. if (const IdentifierInfo *Name = cast<NamedDecl>(Context)->getIdentifier()) { mangleSourceName(Name); @@ -2008,7 +1977,6 @@ void CXXNameMangler::manglePrefix(NestedNameSpecifier *qualifier) { void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) { // <prefix> ::= <prefix> <unqualified-name> // ::= <template-prefix> <template-args> - // ::= <closure-prefix> // ::= <template-param> // ::= # empty // ::= <substitution> @@ -2027,14 +1995,11 @@ void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) { if (mangleSubstitution(ND)) return; - // Check if we have a template-prefix or a closure-prefix. + // Check if we have a template. const TemplateArgumentList *TemplateArgs = nullptr; if (GlobalDecl TD = isTemplate(ND, TemplateArgs)) { mangleTemplatePrefix(TD); mangleTemplateArgs(asTemplateName(TD), *TemplateArgs); - } else if (const NamedDecl *PrefixND = getClosurePrefix(ND)) { - mangleClosurePrefix(PrefixND, NoFunction); - mangleUnqualifiedName(ND, nullptr); } else { manglePrefix(getEffectiveDeclContext(ND), NoFunction); mangleUnqualifiedName(ND, nullptr); @@ -2100,50 +2065,6 @@ void CXXNameMangler::mangleTemplatePrefix(GlobalDecl GD, addSubstitution(ND); } -const NamedDecl *CXXNameMangler::getClosurePrefix(const Decl *ND) { - if (getASTContext().getLangOpts().getClangABICompat() <= - LangOptions::ClangABI::Ver12) - return nullptr; - - const NamedDecl *Context = nullptr; - if (auto *Block = dyn_cast<BlockDecl>(ND)) { - Context = dyn_cast_or_null<NamedDecl>(Block->getBlockManglingContextDecl()); - } else if (auto *RD = dyn_cast<CXXRecordDecl>(ND)) { - if (RD->isLambda()) - Context = dyn_cast_or_null<NamedDecl>(RD->getLambdaContextDecl()); - } - if (!Context) - return nullptr; - - // Only lambdas within the initializer of a non-local variable or non-static - // data member get a <closure-prefix>. - if ((isa<VarDecl>(Context) && cast<VarDecl>(Context)->hasGlobalStorage()) || - isa<FieldDecl>(Context)) - return Context; - - return nullptr; -} - -void CXXNameMangler::mangleClosurePrefix(const NamedDecl *ND, bool NoFunction) { - // <closure-prefix> ::= [ <prefix> ] <unqualified-name> M - // ::= <template-prefix> <template-args> M - if (mangleSubstitution(ND)) - return; - - const TemplateArgumentList *TemplateArgs = nullptr; - if (GlobalDecl TD = isTemplate(ND, TemplateArgs)) { - mangleTemplatePrefix(TD, NoFunction); - mangleTemplateArgs(asTemplateName(TD), *TemplateArgs); - } else { - manglePrefix(getEffectiveDeclContext(ND), NoFunction); - mangleUnqualifiedName(ND, nullptr); - } - - Out << 'M'; - - addSubstitution(ND); -} - /// Mangles a template name under the production <type>. Required for /// template template arguments. /// <type> ::= <class-enum-type> diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index e8e0e2d08c61..0c5066a2f8cd 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -3509,8 +3509,6 @@ void CompilerInvocation::GenerateLangArgs(const LangOptions &Opts, GenerateArg(Args, OPT_fclang_abi_compat_EQ, "9.0", SA); else if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver11) GenerateArg(Args, OPT_fclang_abi_compat_EQ, "11.0", SA); - else if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver12) - GenerateArg(Args, OPT_fclang_abi_compat_EQ, "12.0", SA); if (Opts.getSignReturnAddressScope() == LangOptions::SignReturnAddressScopeKind::All) @@ -3972,8 +3970,6 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, Opts.setClangABICompat(LangOptions::ClangABI::Ver9); else if (Major <= 11) Opts.setClangABICompat(LangOptions::ClangABI::Ver11); - else if (Major <= 12) - Opts.setClangABICompat(LangOptions::ClangABI::Ver12); } else if (Ver != "latest") { Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << A->getValue(); diff --git a/clang/test/CodeGenCXX/clang-abi-compat.cpp b/clang/test/CodeGenCXX/clang-abi-compat.cpp index 5dd22265d8f1..80311aa320fe 100644 --- a/clang/test/CodeGenCXX/clang-abi-compat.cpp +++ b/clang/test/CodeGenCXX/clang-abi-compat.cpp @@ -13,13 +13,11 @@ // RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=11 %s -emit-llvm -o - \ // RUN: | FileCheck --check-prefixes=CHECK,V39,V5,PRE12,PRE12-CXX17 %s // RUN: %clang_cc1 -std=c++20 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=11 %s -emit-llvm -o - \ -// RUN: | FileCheck --check-prefixes=CHECK,V39,V5,PRE12,PRE12-CXX17,PRE12-CXX20,PRE13-CXX20 %s -// RUN: %clang_cc1 -std=c++20 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=12 %s -emit-llvm -o - \ -// RUN: | FileCheck --check-prefixes=CHECK,V39,V5,V12,V12-CXX17,V12-CXX20,PRE13-CXX20 %s +// RUN: | FileCheck --check-prefixes=CHECK,V39,V5,PRE12,PRE12-CXX17,PRE12-CXX20 %s // RUN: %clang_cc1 -std=c++98 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=latest %s -emit-llvm -o - -Wno-c++11-extensions \ // RUN: | FileCheck --check-prefixes=CHECK,V39,V5,V12 %s // RUN: %clang_cc1 -std=c++20 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=latest %s -emit-llvm -o - \ -// RUN: | FileCheck --check-prefixes=CHECK,V39,V5,V12,V12-CXX17,V12-CXX20,V13-CXX20 %s +// RUN: | FileCheck --check-prefixes=CHECK,V39,V5,V12,V12-CXX17,V12-CXX20 %s typedef __attribute__((vector_size(8))) long long v1xi64; void clang39(v1xi64) {} @@ -138,12 +136,3 @@ template void test8<2>(matrix1xN<2> a); void test9(void) __attribute__((enable_if(1, ""))) {} } - -#if __cplusplus >= 202002L -// PRE13-CXX20: @_Z15observe_lambdasI17inline_var_lambdaMUlvE_17inline_var_lambdaMUlvE0_PiS2_S0_S1_EiT_T0_T1_T2_ -// V13-CXX20: @_Z15observe_lambdasIN17inline_var_lambdaMUlvE_ENS0_UlvE0_EPiS3_S1_S2_EiT_T0_T1_T2_ -template <typename T, typename U, typename V, typename W, typename = T, typename = U> -int observe_lambdas(T, U, V, W) { return 0; } -inline auto inline_var_lambda = observe_lambdas([]{}, []{}, (int*)0, (int*)0); -int use_inline_var_lambda() { return inline_var_lambda; } -#endif diff --git a/clang/test/CodeGenCXX/lambda-expressions-nested-linkage.cpp b/clang/test/CodeGenCXX/lambda-expressions-nested-linkage.cpp index 228e42999b41..3bbd910152a2 100644 --- a/clang/test/CodeGenCXX/lambda-expressions-nested-linkage.cpp +++ b/clang/test/CodeGenCXX/lambda-expressions-nested-linkage.cpp @@ -22,13 +22,6 @@ namespace non_template { L l; } -// It's important that this is not in a namespace; we're testing the mangling -// of lambdas in top-level inline variables here. -inline auto lambda_in_inline_variable = [] {}; -template<typename T> struct Wrap {}; -// CHECK-LABEL: define {{.*}} @_Z30test_lambda_in_inline_variable4WrapIN25lambda_in_inline_variableMUlvE_EE -void test_lambda_in_inline_variable(Wrap<decltype(lambda_in_inline_variable)>) {} - namespace lambdas_in_NSDMIs_template_class { template<class T> struct L { diff --git a/clang/test/CodeGenCXX/mangle-lambda-explicit-template-params.cpp b/clang/test/CodeGenCXX/mangle-lambda-explicit-template-params.cpp index 5907cf259b42..45fdec30f988 100644 --- a/clang/test/CodeGenCXX/mangle-lambda-explicit-template-params.cpp +++ b/clang/test/CodeGenCXX/mangle-lambda-explicit-template-params.cpp @@ -38,7 +38,7 @@ template<typename T, int> struct X {}; inline auto pack = []<typename ...T, T ...N>(T (&...)[N]) {}; int arr1[] = {1}; int arr2[] = {1, 2}; -// CHECK: @_ZNK4packMUlTpTyTpTnT_DpRAT0__S0_E_clIJiiEJLi1ELi2EEEEDaS3_( +// CHECK: @_ZNK4packMUlTpTyTpTnT_DpRAT0__S_E_clIJiiEJLi1ELi2EEEEDaS2_( void use_pack() { pack(arr1, arr2); } inline void collision() { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits