From 7ff7eb706a0b05548efa696559b0a0a67ef5bf35 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Wed, 18 Feb 2015 07:47:09 +0000 Subject: [PATCH] Itanium ABI: Mangle 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 decltype(C) f() { return foo; }; template char &f(); Instead, just follow the ABI specification. This fixes PR22621. llvm-svn: 229644 --- clang/lib/AST/ItaniumMangle.cpp | 18 ++++++------------ clang/test/CodeGenCXX/mangle-template.cpp | 12 ++++++------ clang/test/CodeGenCXX/mangle.cpp | 2 +- clang/test/CodeGenCXX/visibility.cpp | 2 +- 4 files changed, 14 insertions(+), 20 deletions(-) diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 0d10bb1d9907..f56e242d374a 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -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) { // ::= _Z // ::= // ::= - Out << Prefix; + Out << "_Z"; if (const FunctionDecl *FD = dyn_cast(D)) mangleFunctionEncoding(FD); else if (const VarDecl *VD = dyn_cast(D)) @@ -3197,7 +3197,7 @@ recurse: default: // ::= L 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(D) || isa(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) diff --git a/clang/test/CodeGenCXX/mangle-template.cpp b/clang/test/CodeGenCXX/mangle-template.cpp index 998096a57be4..28db27173ec4 100644 --- a/clang/test/CodeGenCXX/mangle-template.cpp +++ b/clang/test/CodeGenCXX/mangle-template.cpp @@ -4,7 +4,7 @@ namespace test1 { int x; template class T { }; -// CHECK: void @_ZN5test12f0ENS_1TILZNS_1xEEEE( +// CHECK: void @_ZN5test12f0ENS_1TIL_ZNS_1xEEEE( void f0(T a0) {} } @@ -12,7 +12,7 @@ namespace test1 { // CHECK: void @_ZN5test12f0Ef void f0(float) {} template struct t1 {}; -// CHECK: void @_ZN5test12f1ENS_2t1ILZNS_2f0EfEEE( +// CHECK: void @_ZN5test12f1ENS_2t1IL_ZNS_2f0EfEEE( void f1(t1 a0) {} } @@ -49,11 +49,11 @@ int main(int) {} namespace test5 { template struct t1 {}; -// CHECK: void @_ZN5test52f1ENS_2t1ILZ8test5_f0EEE( +// CHECK: void @_ZN5test52f1ENS_2t1IL_Z8test5_f0EEE( void f1(t1 a0) {} template struct t2 {}; -// CHECK: void @_ZN5test52f2ENS_2t2ILZ4mainEEE +// CHECK: void @_ZN5test52f2ENS_2t2IL_Z4mainEEE void f2(t2
a0) {} } @@ -164,11 +164,11 @@ namespace test12 { void use() { // CHECK-LABEL: define internal void @_ZN6test124testIFivEXadL_ZNS_L1fEvEEEEvv( test(); - // CHECK-LABEL: define internal void @_ZN6test124testIRFivELZNS_L1fEvEEEvv( + // CHECK-LABEL: define internal void @_ZN6test124testIRFivEL_ZNS_L1fEvEEEvv( test(); // CHECK-LABEL: define internal void @_ZN6test124testIPKiXadL_ZNS_L1nEEEEEvv( test(); - // CHECK-LABEL: define internal void @_ZN6test124testIRKiLZNS_L1nEEEEvv( + // CHECK-LABEL: define internal void @_ZN6test124testIRKiL_ZNS_L1nEEEEvv( test(); } } diff --git a/clang/test/CodeGenCXX/mangle.cpp b/clang/test/CodeGenCXX/mangle.cpp index e15d54086a64..c12fe5014f89 100644 --- a/clang/test/CodeGenCXX/mangle.cpp +++ b/clang/test/CodeGenCXX/mangle.cpp @@ -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 class A { void inc() { counter++; } }; class B { public: static int value; }; diff --git a/clang/test/CodeGenCXX/visibility.cpp b/clang/test/CodeGenCXX/visibility.cpp index e0271099e2a9..7239cbe00225 100644 --- a/clang/test/CodeGenCXX/visibility.cpp +++ b/clang/test/CodeGenCXX/visibility.cpp @@ -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::foo(); }