We attempted to be compatible with GCC's buggy mangling for templates
with a declaration for a template argument.
However, we weren't completely successful in copying their bug in cases
like:
char foo;
template <char &C> decltype(C) f() { return foo; };
template char &f<foo>();
Instead, just follow the ABI specification. This fixes PR22621.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@229644
91177308-0d34-0410-b5e6-
96231b3b80d8
#endif
raw_ostream &getStream() { return Out; }
- void mangle(const NamedDecl *D, StringRef Prefix = "_Z");
+ void mangle(const NamedDecl *D);
void mangleCallOffset(int64_t NonVirtual, int64_t Virtual);
void mangleNumber(const llvm::APSInt &I);
void mangleNumber(int64_t Number);
return true;
}
-void CXXNameMangler::mangle(const NamedDecl *D, StringRef Prefix) {
+void CXXNameMangler::mangle(const NamedDecl *D) {
// <mangled-name> ::= _Z <encoding>
// ::= <data name>
// ::= <special-name>
- Out << Prefix;
+ Out << "_Z";
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
mangleFunctionEncoding(FD);
else if (const VarDecl *VD = dyn_cast<VarDecl>(D))
default:
// <expr-primary> ::= L <mangled-name> E # external name
Out << 'L';
- mangle(D, "_Z");
+ mangle(D);
Out << 'E';
break;
const ValueDecl *D = DRE->getDecl();
if (isa<VarDecl>(D) || isa<FunctionDecl>(D)) {
Out << "L";
- mangle(D, "_Z");
+ mangle(D);
Out << 'E';
break;
}
Out << 'L';
// References to external entities use the mangled name; if the name would
// not normally be manged then mangle it as unqualified.
- //
- // FIXME: The ABI specifies that external names here should have _Z, but
- // gcc leaves this off.
- if (compensateMangling)
- mangle(D, "_Z");
- else
- mangle(D, "Z");
+ mangle(D);
Out << 'E';
if (compensateMangling)
namespace test1 {
int x;
template <int& D> class T { };
-// CHECK: void @_ZN5test12f0ENS_1TILZNS_1xEEEE(
+// CHECK: void @_ZN5test12f0ENS_1TIL_ZNS_1xEEEE(
void f0(T<x> a0) {}
}
// CHECK: void @_ZN5test12f0Ef
void f0(float) {}
template<void (&)(float)> struct t1 {};
-// CHECK: void @_ZN5test12f1ENS_2t1ILZNS_2f0EfEEE(
+// CHECK: void @_ZN5test12f1ENS_2t1IL_ZNS_2f0EfEEE(
void f1(t1<f0> a0) {}
}
namespace test5 {
template<void (&)(float)> struct t1 {};
-// CHECK: void @_ZN5test52f1ENS_2t1ILZ8test5_f0EEE(
+// CHECK: void @_ZN5test52f1ENS_2t1IL_Z8test5_f0EEE(
void f1(t1<test5_f0> a0) {}
template<int (&)(int)> struct t2 {};
-// CHECK: void @_ZN5test52f2ENS_2t2ILZ4mainEEE
+// CHECK: void @_ZN5test52f2ENS_2t2IL_Z4mainEEE
void f2(t2<main> a0) {}
}
void use() {
// CHECK-LABEL: define internal void @_ZN6test124testIFivEXadL_ZNS_L1fEvEEEEvv(
test<int(), &f>();
- // CHECK-LABEL: define internal void @_ZN6test124testIRFivELZNS_L1fEvEEEvv(
+ // CHECK-LABEL: define internal void @_ZN6test124testIRFivEL_ZNS_L1fEvEEEvv(
test<int(&)(), f>();
// CHECK-LABEL: define internal void @_ZN6test124testIPKiXadL_ZNS_L1nEEEEEvv(
test<const int*, &n>();
- // CHECK-LABEL: define internal void @_ZN6test124testIRKiLZNS_L1nEEEEvv(
+ // CHECK-LABEL: define internal void @_ZN6test124testIRKiL_ZNS_L1nEEEEvv(
test<const int&, n>();
}
}
void g(zed<&foo::bar>*)
{}
}
-// CHECK-LABEL: define weak_odr void @_ZN5test81AILZNS_1B5valueEEE3incEv
+// CHECK-LABEL: define weak_odr void @_ZN5test81AIL_ZNS_1B5valueEEE3incEv
namespace test8 {
template <int &counter> class A { void inc() { counter++; } };
class B { public: static int value; };
class B : public A {};
B b; // top of file
- // CHECK-LABEL: define linkonce_odr hidden void @_ZN5Test74ArefILZNS_1aEEE3fooEv()
+ // CHECK-LABEL: define linkonce_odr hidden void @_ZN5Test74ArefIL_ZNS_1aEEE3fooEv()
void test() {
Aref<a>::foo();
}