mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-01 01:31:26 +00:00
Mark identifier prefixes as substitutable
The Itanium C++ ABI says prefixes are substitutable. For most prefixes we already handle this: the manglePrefix(const DeclContext *, bool) and manglePrefix(QualType) overloads explicitly handles substitutions or defer to functions that handle substitutions on their behalf. The manglePrefix(NestedNameSpecifier *) overload, however, is different and handles some cases implicitly, but not all. The Identifier case was not handled; this change adds handling for it, as well as a test case. Reviewed By: erichkeane Differential Revision: https://reviews.llvm.org/D122663
This commit is contained in:
parent
2534dc120a
commit
fed7be096f
@ -265,6 +265,10 @@ C++ Language Changes in Clang
|
||||
``std::move_if_noexcept``, ``std::addressof``, and ``std::as_const``. These
|
||||
are now treated as compiler builtins and implemented directly, rather than
|
||||
instantiating the definition from the standard library.
|
||||
- Fixed mangling of nested dependent names such as ``T::a::b``, where ``T`` is a
|
||||
template parameter, to conform to the Itanium C++ ABI and be compatible with
|
||||
GCC. This breaks binary compatibility with code compiled with earlier versions
|
||||
of clang; use the ``-fclang-abi-compat=14`` option to get the old mangling.
|
||||
|
||||
C++20 Feature Support
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -218,6 +218,10 @@ public:
|
||||
/// This causes clang to not pack non-POD members of packed structs.
|
||||
Ver13,
|
||||
|
||||
/// Attempt to be ABI-compatible with code generated by Clang 14.0.x.
|
||||
/// This causes clang to mangle dependent nested names incorrectly.
|
||||
Ver14,
|
||||
|
||||
/// Conform to the underlying platform's C and C++ ABIs as closely
|
||||
/// as we can.
|
||||
Latest
|
||||
|
@ -443,6 +443,7 @@ public:
|
||||
private:
|
||||
|
||||
bool mangleSubstitution(const NamedDecl *ND);
|
||||
bool mangleSubstitution(NestedNameSpecifier *NNS);
|
||||
bool mangleSubstitution(QualType T);
|
||||
bool mangleSubstitution(TemplateName Template);
|
||||
bool mangleSubstitution(uintptr_t Ptr);
|
||||
@ -456,6 +457,11 @@ private:
|
||||
|
||||
addSubstitution(reinterpret_cast<uintptr_t>(ND));
|
||||
}
|
||||
void addSubstitution(NestedNameSpecifier *NNS) {
|
||||
NNS = Context.getASTContext().getCanonicalNestedNameSpecifier(NNS);
|
||||
|
||||
addSubstitution(reinterpret_cast<uintptr_t>(NNS));
|
||||
}
|
||||
void addSubstitution(QualType T);
|
||||
void addSubstitution(TemplateName Template);
|
||||
void addSubstitution(uintptr_t Ptr);
|
||||
@ -2036,12 +2042,21 @@ void CXXNameMangler::manglePrefix(NestedNameSpecifier *qualifier) {
|
||||
return;
|
||||
|
||||
case NestedNameSpecifier::Identifier:
|
||||
// Clang 14 and before did not consider this substitutable.
|
||||
bool Clang14Compat = getASTContext().getLangOpts().getClangABICompat() <=
|
||||
LangOptions::ClangABI::Ver14;
|
||||
if (!Clang14Compat && mangleSubstitution(qualifier))
|
||||
return;
|
||||
|
||||
// Member expressions can have these without prefixes, but that
|
||||
// should end up in mangleUnresolvedPrefix instead.
|
||||
assert(qualifier->getPrefix());
|
||||
manglePrefix(qualifier->getPrefix());
|
||||
|
||||
mangleSourceName(qualifier->getAsIdentifier());
|
||||
|
||||
if (!Clang14Compat)
|
||||
addSubstitution(qualifier);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -6009,6 +6024,14 @@ bool CXXNameMangler::mangleSubstitution(const NamedDecl *ND) {
|
||||
return mangleSubstitution(reinterpret_cast<uintptr_t>(ND));
|
||||
}
|
||||
|
||||
bool CXXNameMangler::mangleSubstitution(NestedNameSpecifier *NNS) {
|
||||
assert(NNS->getKind() == NestedNameSpecifier::Identifier &&
|
||||
"mangleSubstitution(NestedNameSpecifier *) is only used for "
|
||||
"identifier nested name specifiers.");
|
||||
NNS = Context.getASTContext().getCanonicalNestedNameSpecifier(NNS);
|
||||
return mangleSubstitution(reinterpret_cast<uintptr_t>(NNS));
|
||||
}
|
||||
|
||||
/// Determine whether the given type has any qualifiers that are relevant for
|
||||
/// substitutions.
|
||||
static bool hasMangledSubstitutionQualifiers(QualType T) {
|
||||
|
@ -3518,6 +3518,8 @@ void CompilerInvocation::GenerateLangArgs(const LangOptions &Opts,
|
||||
GenerateArg(Args, OPT_fclang_abi_compat_EQ, "12.0", SA);
|
||||
else if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver13)
|
||||
GenerateArg(Args, OPT_fclang_abi_compat_EQ, "13.0", SA);
|
||||
else if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver14)
|
||||
GenerateArg(Args, OPT_fclang_abi_compat_EQ, "14.0", SA);
|
||||
|
||||
if (Opts.getSignReturnAddressScope() ==
|
||||
LangOptions::SignReturnAddressScopeKind::All)
|
||||
@ -4026,6 +4028,8 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
|
||||
Opts.setClangABICompat(LangOptions::ClangABI::Ver12);
|
||||
else if (Major <= 13)
|
||||
Opts.setClangABICompat(LangOptions::ClangABI::Ver13);
|
||||
else if (Major <= 14)
|
||||
Opts.setClangABICompat(LangOptions::ClangABI::Ver14);
|
||||
} else if (Ver != "latest") {
|
||||
Diags.Report(diag::err_drv_invalid_value)
|
||||
<< A->getAsString(Args) << A->getValue();
|
||||
|
@ -1,25 +1,27 @@
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -std=c++98 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=3.0 %s -emit-llvm -o - -Wno-c++11-extensions \
|
||||
// RUN: | FileCheck --check-prefixes=CHECK,PRE39,PRE5,PRE12 %s
|
||||
// RUN: | FileCheck --check-prefixes=CHECK,PRE39,PRE5,PRE12,PRE15 %s
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -std=c++17 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=3.0 %s -emit-llvm -o - \
|
||||
// RUN: | FileCheck --check-prefixes=CHECK,PRE39,PRE5,PRE12 %s
|
||||
// RUN: | FileCheck --check-prefixes=CHECK,PRE39,PRE5,PRE12,PRE15 %s
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -std=c++17 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=3.8 %s -emit-llvm -o - \
|
||||
// RUN: | FileCheck --check-prefixes=CHECK,PRE39,PRE5,PRE12 %s
|
||||
// RUN: | FileCheck --check-prefixes=CHECK,PRE39,PRE5,PRE12,PRE15 %s
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -std=c++17 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=3.9 %s -emit-llvm -o - \
|
||||
// RUN: | FileCheck --check-prefixes=CHECK,V39,PRE5,PRE12 %s
|
||||
// RUN: | FileCheck --check-prefixes=CHECK,V39,PRE5,PRE12,PRE15 %s
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -std=c++17 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=4.0 %s -emit-llvm -o - \
|
||||
// RUN: | FileCheck --check-prefixes=CHECK,V39,PRE5,PRE12 %s
|
||||
// RUN: | FileCheck --check-prefixes=CHECK,V39,PRE5,PRE12,PRE15 %s
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -std=c++17 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=5 %s -emit-llvm -o - \
|
||||
// RUN: | FileCheck --check-prefixes=CHECK,V39,V5,PRE12,PRE12-CXX17 %s
|
||||
// RUN: | FileCheck --check-prefixes=CHECK,V39,V5,PRE12,PRE12-CXX17,PRE15 %s
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -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: | FileCheck --check-prefixes=CHECK,V39,V5,PRE12,PRE12-CXX17,PRE15 %s
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -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: | FileCheck --check-prefixes=CHECK,V39,V5,PRE12,PRE12-CXX17,PRE12-CXX20,PRE13-CXX20,PRE15 %s
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -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,V12,V12-CXX17,V12-CXX20,PRE13-CXX20,PRE15 %s
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -std=c++20 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=14 %s -emit-llvm -o - \
|
||||
// RUN: | FileCheck --check-prefixes=CHECK,V39,V5,V12,V12-CXX17,V12-CXX20,V13-CXX20,PRE15 %s
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -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: | FileCheck --check-prefixes=CHECK,V39,V5,V12,V15 %s
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -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,V13-CXX20,V15 %s
|
||||
|
||||
typedef __attribute__((vector_size(8))) long long v1xi64;
|
||||
void clang39(v1xi64) {}
|
||||
@ -147,3 +149,14 @@ 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
|
||||
|
||||
struct X {
|
||||
struct Y {
|
||||
using a = int;
|
||||
using b = int;
|
||||
};
|
||||
};
|
||||
template <typename T> void test10(typename T::Y::a, typename T::Y::b, float*, float*) {}
|
||||
// PRE15: @_Z6test10I1XEvNT_1Y1aENS1_1Y1bEPfS4_
|
||||
// V15: @_Z6test10I1XEvNT_1Y1aENS2_1bEPfS5_
|
||||
template void test10<X>(int, int, float*, float*);
|
||||
|
@ -1155,3 +1155,15 @@ namespace test60 {
|
||||
// CHECK-LABEL: @_ZN6test601fIiEEvDTplL_ZNS_1aEEcvT__EE
|
||||
template void f<int>(int);
|
||||
}
|
||||
|
||||
namespace test61 {
|
||||
struct X {
|
||||
struct Y {
|
||||
using a = int;
|
||||
using b = int;
|
||||
};
|
||||
};
|
||||
template <typename T> void f(typename T::Y::a, typename T::Y::b) {}
|
||||
// CHECK-LABEL: @_ZN6test611fINS_1XEEEvNT_1Y1aENS3_1bE
|
||||
template void f<X>(int, int);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user