diff options
author | John McCall <rjmccall@apple.com> | 2012-01-06 05:06:35 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2012-01-06 05:06:35 +0000 |
commit | 092beef87b367e62f96c0057118ba540777de452 (patch) | |
tree | fe8a67a5373c590bb1a6f475cc0f76c1c53a281a | |
parent | 1a5d35539a16f3b2eb2426f3f23a8376b190741c (diff) |
Fix the mangling of class template arguments in a particular
dependent case. Thanks to Jason Merrill for pointing this out.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147653 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/AST/ItaniumMangle.cpp | 19 | ||||
-rw-r--r-- | test/CodeGenCXX/mangle-template.cpp | 9 |
2 files changed, 26 insertions, 2 deletions
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp index 1e71a627ce..7f2d5628a8 100644 --- a/lib/AST/ItaniumMangle.cpp +++ b/lib/AST/ItaniumMangle.cpp @@ -2899,11 +2899,26 @@ void CXXNameMangler::mangleTemplateArg(const NamedDecl *P, Out << "Dp"; mangleType(A.getAsTemplateOrTemplatePattern()); break; - case TemplateArgument::Expression: + case TemplateArgument::Expression: { + // It's possible to end up with a DeclRefExpr here in certain + // dependent cases, in which case we should mangle as a + // declaration. + const Expr *E = A.getAsExpr()->IgnoreParens(); + if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) { + const ValueDecl *D = DRE->getDecl(); + if (isa<VarDecl>(D) || isa<FunctionDecl>(D)) { + Out << "L"; + mangle(D, "_Z"); + Out << 'E'; + break; + } + } + Out << 'X'; - mangleExpression(A.getAsExpr()); + mangleExpression(E); Out << 'E'; break; + } case TemplateArgument::Integral: mangleIntegerLiteral(A.getIntegralType(), *A.getAsIntegral()); break; diff --git a/test/CodeGenCXX/mangle-template.cpp b/test/CodeGenCXX/mangle-template.cpp index f95e152154..1eb6a451c1 100644 --- a/test/CodeGenCXX/mangle-template.cpp +++ b/test/CodeGenCXX/mangle-template.cpp @@ -144,3 +144,12 @@ namespace test10 { f(i, d); } } + +// Report from Jason Merrill on cxx-abi-dev, 2012.01.04. +namespace test11 { + int cmp(char a, char b); + template <typename T, int (*cmp)(T, T)> struct A {}; + template <typename T> void f(A<T,cmp> &) {} + template void f<char>(A<char,cmp> &); + // CHECK: @_ZN6test111fIcEEvRNS_1AIT_L_ZNS_3cmpEccEEE( +} |