[clang] bb72638 - Revert "Fix bad mangling of <data-member-prefix> for a closure in the initializer of a variable at global namespace scope."
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Tue May 11 17:47:13 PDT 2021
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() {
More information about the cfe-commits
mailing list