Itanium ABI: Mangle <mangled-name> according to the ABI

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.

llvm-svn: 229644
This commit is contained in:
David Majnemer 2015-02-18 07:47:09 +00:00
parent 55ac42426e
commit 7ff7eb706a
4 changed files with 14 additions and 20 deletions

View File

@ -286,7 +286,7 @@ public:
#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);
@ -445,11 +445,11 @@ bool ItaniumMangleContextImpl::shouldMangleCXXName(const NamedDecl *D) {
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))
@ -3197,7 +3197,7 @@ recurse:
default:
// <expr-primary> ::= L <mangled-name> E # external name
Out << 'L';
mangle(D, "_Z");
mangle(D);
Out << 'E';
break;
@ -3550,7 +3550,7 @@ void CXXNameMangler::mangleTemplateArg(TemplateArgument A) {
const ValueDecl *D = DRE->getDecl();
if (isa<VarDecl>(D) || isa<FunctionDecl>(D)) {
Out << "L";
mangle(D, "_Z");
mangle(D);
Out << 'E';
break;
}
@ -3579,13 +3579,7 @@ void CXXNameMangler::mangleTemplateArg(TemplateArgument A) {
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)

View File

@ -4,7 +4,7 @@
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) {}
}
@ -12,7 +12,7 @@ namespace test1 {
// 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) {}
}
@ -49,11 +49,11 @@ int main(int) {}
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) {}
}
@ -164,11 +164,11 @@ namespace test12 {
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>();
}
}

View File

@ -455,7 +455,7 @@ namespace test7 {
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; };

View File

@ -240,7 +240,7 @@ namespace Test7 {
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();
}