[ms-cxxabi] Don't consider function templates for name backrefs

They don't seem to be used for back references, presumably because a
function template is unlikely to reoccur, while a class template name
may reoccur as a type.

This fixes a mangling issue for llvm::hash_combine() in Hashing.h.

Reviewers: timurrrr

Differential Revision: http://llvm-reviews.chandlerc.com/D1078

llvm-svn: 186233
This commit is contained in:
Reid Kleckner 2013-07-13 00:43:39 +00:00
parent fa74085f60
commit c16c44714b
3 changed files with 44 additions and 2 deletions

View File

@ -421,7 +421,16 @@ MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
// Check if we have a template. // Check if we have a template.
const TemplateArgumentList *TemplateArgs = 0; const TemplateArgumentList *TemplateArgs = 0;
if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) { if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
// We have a template. // Function templates aren't considered for name back referencing. This
// makes sense since function templates aren't likely to occur multiple
// times in a symbol.
// FIXME: Test alias template mangling with MSVC 2013.
if (!isa<ClassTemplateDecl>(TD)) {
mangleTemplateInstantiationName(TD, *TemplateArgs);
return;
}
// We have a class template.
// Here comes the tricky thing: if we need to mangle something like // Here comes the tricky thing: if we need to mangle something like
// void foo(A::X<Y>, B::X<Y>), // void foo(A::X<Y>, B::X<Y>),
// the X<Y> part is aliased. However, if you need to mangle // the X<Y> part is aliased. However, if you need to mangle

View File

@ -107,7 +107,7 @@ void call_l_foo(L* l) { l->foo(I<A>()); }
void foo(I<A> x) {} void foo(I<A> x) {}
// CHECK: "\01?foo@PR13207@@YAXV?$I@VA@PR13207@@@1@@Z" // CHECK: "\01?foo@PR13207@@YAXV?$I@VA@PR13207@@@1@@Z"
void foo2(I<A> x, I<A> y) { } void foo2(I<A> x, I<A> y) { }
// CHECK "\01?foo2@PR13207@@YAXV?$I@VA@PR13207@@@1@0@Z" // CHECK: "\01?foo2@PR13207@@YAXV?$I@VA@PR13207@@@1@0@Z"
void bar(J<A,B> x) {} void bar(J<A,B> x) {}
// CHECK: "\01?bar@PR13207@@YAXV?$J@VA@PR13207@@VB@2@@1@@Z" // CHECK: "\01?bar@PR13207@@YAXV?$J@VA@PR13207@@VB@2@@1@@Z"
void spam(K<A,B,C> x) {} void spam(K<A,B,C> x) {}
@ -163,3 +163,31 @@ void foobar(NC::Y<NB::Y<NA::Y<NA::X> > > x) {}
// CHECK: "\01?foobar@NC@PR13207@@YAXV?$Y@V?$Y@V?$Y@VX@NA@PR13207@@@NA@PR13207@@@NB@PR13207@@@12@@Z" // CHECK: "\01?foobar@NC@PR13207@@YAXV?$Y@V?$Y@V?$Y@VX@NA@PR13207@@@NA@PR13207@@@NB@PR13207@@@12@@Z"
} }
} }
// Function template names are not considered for backreferencing, but normal
// function names are.
namespace fn_space {
struct RetVal { int hash; };
template <typename T>
RetVal fun_tmpl(const T &t) { return RetVal(); }
RetVal fun_normal(int t) { return RetVal(); }
void fun_instantiate() {
fun_normal(1);
fun_tmpl(1);
}
// CHECK: "\01?fun_normal@fn_space@@YA?AURetVal@1@H@Z"
// CHECK: "\01??$fun_tmpl@H@fn_space@@YA?AURetVal@0@ABH@Z"
template <typename T, RetVal (*F)(T)>
RetVal fun_tmpl_recurse(T t) {
if (!t)
return RetVal();
return F(t - 1);
}
RetVal ident(int x) { return RetVal(); }
void fun_instantiate2() {
fun_tmpl_recurse<int, fun_tmpl_recurse<int, ident> >(10);
}
// CHECK: "\01??$fun_tmpl_recurse@H$1??$fun_tmpl_recurse@H$1?ident@fn_space@@YA?AURetVal@2@H@Z@fn_space@@YA?AURetVal@1@H@Z@fn_space@@YA?AURetVal@0@H@Z"
// CHECK: "\01??$fun_tmpl_recurse@H$1?ident@fn_space@@YA?AURetVal@2@H@Z@fn_space@@YA?AURetVal@0@H@Z"
}

View File

@ -61,3 +61,8 @@ void h2(void (*f_ptr)(void *), void *arg) {}
PInt3Func h3(PInt3Func x, PInt3Func y, int* z) { return 0; } PInt3Func h3(PInt3Func x, PInt3Func y, int* z) { return 0; }
// CHECK: "\01?h3@@YAP6APAHPAH0@ZP6APAH00@Z10@Z" // CHECK: "\01?h3@@YAP6APAHPAH0@ZP6APAH00@Z10@Z"
namespace foo {
void foo() { }
// CHECK: "\01?foo@0@YAXXZ"
}