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;
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(
+}