From: Rafael Espindola Date: Thu, 11 Mar 2010 14:07:00 +0000 (+0000) Subject: Correctly mangle address of member in template arguments. Fixes PR6460 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d9800728cc3e7f478eec4d4b19af5b808ac51942;p=clang Correctly mangle address of member in template arguments. Fixes PR6460 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98254 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp index 2e0580f5e7..b18e4bb9df 100644 --- a/lib/CodeGen/Mangle.cpp +++ b/lib/CodeGen/Mangle.cpp @@ -172,10 +172,12 @@ private: void mangleCXXCtorType(CXXCtorType T); void mangleCXXDtorType(CXXDtorType T); - void mangleTemplateArgs(const TemplateArgument *TemplateArgs, + void mangleTemplateArgs(const TemplateParameterList &PL, + const TemplateArgument *TemplateArgs, unsigned NumTemplateArgs); - void mangleTemplateArgs(const TemplateArgumentList &L); - void mangleTemplateArg(const TemplateArgument &A); + void mangleTemplateArgs(const TemplateParameterList &PL, + const TemplateArgumentList &AL); + void mangleTemplateArg(const NamedDecl *P, const TemplateArgument &A); void mangleTemplateParameter(unsigned Index); }; @@ -248,8 +250,10 @@ void CXXNameMangler::mangle(const NamedDecl *D, llvm::StringRef Prefix) { Out << Prefix; if (const FunctionDecl *FD = dyn_cast(D)) mangleFunctionEncoding(FD); + else if (const VarDecl *VD = dyn_cast(D)) + mangleName(VD); else - mangleName(cast(D)); + mangleName(cast(D)); } void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) { @@ -369,7 +373,8 @@ void CXXNameMangler::mangleName(const NamedDecl *ND) { const TemplateArgumentList *TemplateArgs = 0; if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) { mangleUnscopedTemplateName(TD); - mangleTemplateArgs(*TemplateArgs); + TemplateParameterList *TemplateParameters = TD->getTemplateParameters(); + mangleTemplateArgs(*TemplateParameters, *TemplateArgs); return; } @@ -391,7 +396,8 @@ void CXXNameMangler::mangleName(const TemplateDecl *TD, if (DC->isTranslationUnit() || isStdNamespace(DC)) { mangleUnscopedTemplateName(TD); - mangleTemplateArgs(TemplateArgs, NumTemplateArgs); + TemplateParameterList *TemplateParameters = TD->getTemplateParameters(); + mangleTemplateArgs(*TemplateParameters, TemplateArgs, NumTemplateArgs); } else { mangleNestedName(TD, TemplateArgs, NumTemplateArgs); } @@ -628,7 +634,8 @@ void CXXNameMangler::mangleNestedName(const NamedDecl *ND, const TemplateArgumentList *TemplateArgs = 0; if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) { mangleTemplatePrefix(TD); - mangleTemplateArgs(*TemplateArgs); + TemplateParameterList *TemplateParameters = TD->getTemplateParameters(); + mangleTemplateArgs(*TemplateParameters, *TemplateArgs); } else { manglePrefix(DC, NoFunction); @@ -645,7 +652,8 @@ void CXXNameMangler::mangleNestedName(const TemplateDecl *TD, Out << 'N'; mangleTemplatePrefix(TD); - mangleTemplateArgs(TemplateArgs, NumTemplateArgs); + TemplateParameterList *TemplateParameters = TD->getTemplateParameters(); + mangleTemplateArgs(*TemplateParameters, TemplateArgs, NumTemplateArgs); Out << 'E'; } @@ -702,7 +710,8 @@ void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) { const TemplateArgumentList *TemplateArgs = 0; if (const TemplateDecl *TD = isTemplate(cast(DC), TemplateArgs)) { mangleTemplatePrefix(TD); - mangleTemplateArgs(*TemplateArgs); + TemplateParameterList *TemplateParameters = TD->getTemplateParameters(); + mangleTemplateArgs(*TemplateParameters, *TemplateArgs); } else if(NoFunction && isa(DC)) return; @@ -1143,7 +1152,9 @@ void CXXNameMangler::mangleType(const TypenameType *T) { TemplateDecl *TD = TST->getTemplateName().getAsTemplateDecl(); assert(TD && "FIXME: Support dependent template names"); mangleTemplatePrefix(TD); - mangleTemplateArgs(TST->getArgs(), TST->getNumArgs()); + TemplateParameterList *TemplateParameters = TD->getTemplateParameters(); + mangleTemplateArgs(*TemplateParameters, TST->getArgs(), + TST->getNumArgs()); addSubstitution(QualType(TST, 0)); } } else if (const TemplateTypeParmType *TTPT = @@ -1521,24 +1532,27 @@ void CXXNameMangler::mangleCXXDtorType(CXXDtorType T) { } } -void CXXNameMangler::mangleTemplateArgs(const TemplateArgumentList &L) { +void CXXNameMangler::mangleTemplateArgs(const TemplateParameterList &PL, + const TemplateArgumentList &AL) { // ::= I + E Out << "I"; - for (unsigned i = 0, e = L.size(); i != e; ++i) - mangleTemplateArg(L[i]); + for (unsigned i = 0, e = AL.size(); i != e; ++i) + mangleTemplateArg(PL.getParam(i), AL[i]); Out << "E"; } -void CXXNameMangler::mangleTemplateArgs(const TemplateArgument *TemplateArgs, +void CXXNameMangler::mangleTemplateArgs(const TemplateParameterList &PL, + const TemplateArgument *TemplateArgs, unsigned NumTemplateArgs) { // ::= I + E Out << "I"; for (unsigned i = 0; i != NumTemplateArgs; ++i) - mangleTemplateArg(TemplateArgs[i]); + mangleTemplateArg(PL.getParam(i), TemplateArgs[i]); Out << "E"; } -void CXXNameMangler::mangleTemplateArg(const TemplateArgument &A) { +void CXXNameMangler::mangleTemplateArg(const NamedDecl *P, + const TemplateArgument &A) { // ::= # type or template // ::= X E # expression // ::= # simple expressions @@ -1566,18 +1580,33 @@ void CXXNameMangler::mangleTemplateArg(const TemplateArgument &A) { case TemplateArgument::Declaration: { // ::= L E # external name - // FIXME: Clang produces AST's where pointer-to-member-function expressions + // Clang produces AST's where pointer-to-member-function expressions // and pointer-to-function expressions are represented as a declaration not - // an expression; this is not how gcc represents them and this changes the - // mangling. + // an expression. We compensate for it here to produce the correct mangling. + NamedDecl *D = cast(A.getAsDecl()); + const NonTypeTemplateParmDecl *Parameter = cast(P); + bool compensateMangling = D->isCXXClassMember() && + !Parameter->getType()->isReferenceType(); + if (compensateMangling) { + Out << 'X'; + mangleOperatorName(OO_Amp, 1); + } + 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. - mangle(cast(A.getAsDecl()), "Z"); + if (compensateMangling) + mangle(D, "_Z"); + else + mangle(D, "Z"); Out << 'E'; + + if (compensateMangling) + Out << 'E'; + break; } } diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp index e18ca03d1b..3f966902a2 100644 --- a/test/CodeGenCXX/mangle.cpp +++ b/test/CodeGenCXX/mangle.cpp @@ -414,3 +414,42 @@ namespace test3 { get_p_2(obj); } } + +// CHECK: define void @_ZN5test41gEPNS_3zedIXadL_ZNS_3foo3barEEEEE +namespace test4 { + struct foo { int bar; }; + template + struct zed {}; + void g(zed<&foo::bar>*) + {} +} +// CHECK: define void @_ZN5test51gEPNS_3zedIXadL_ZNS_3foo3barEEEEE +namespace test5 { + struct foo { static int bar; }; + template + struct zed {}; + void g(zed<&foo::bar>*) + {} +} +// CHECK: define void @_ZN5test61gEPNS_3zedIXadL_ZNS_3foo3barEvEEEE +namespace test6 { + struct foo { int bar(); }; + template + struct zed {}; + void g(zed<&foo::bar>*) + {} +} +// CHECK: define void @_ZN5test71gEPNS_3zedIXadL_ZNS_3foo3barEvEEEE +namespace test7 { + struct foo { static int bar(); }; + template + struct zed {}; + void g(zed<&foo::bar>*) + {} +} +// CHECK: define void @_ZN5test81AILZNS_1B5valueEEE3incEv +namespace test8 { + template class A { void inc() { counter++; } }; + class B { static int value; }; + template class A; +}