From: Reid Kleckner Date: Sat, 13 Jul 2013 00:43:39 +0000 (+0000) Subject: [ms-cxxabi] Don't consider function templates for name backrefs X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3be37d1d2d5733523e516e5a6b22c576e740230e;p=clang [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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@186233 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp index 143472f059..88548ae991 100644 --- a/lib/AST/MicrosoftMangle.cpp +++ b/lib/AST/MicrosoftMangle.cpp @@ -421,7 +421,16 @@ MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, // Check if we have a template. const TemplateArgumentList *TemplateArgs = 0; 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(TD)) { + mangleTemplateInstantiationName(TD, *TemplateArgs); + return; + } + + // We have a class template. // Here comes the tricky thing: if we need to mangle something like // void foo(A::X, B::X), // the X part is aliased. However, if you need to mangle diff --git a/test/CodeGenCXX/mangle-ms-back-references-pr13207.cpp b/test/CodeGenCXX/mangle-ms-back-references-pr13207.cpp index fbc6492348..e10cc8e329 100644 --- a/test/CodeGenCXX/mangle-ms-back-references-pr13207.cpp +++ b/test/CodeGenCXX/mangle-ms-back-references-pr13207.cpp @@ -107,7 +107,7 @@ void call_l_foo(L* l) { l->foo(I()); } void foo(I x) {} // CHECK: "\01?foo@PR13207@@YAXV?$I@VA@PR13207@@@1@@Z" void foo2(I x, I 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 x) {} // CHECK: "\01?bar@PR13207@@YAXV?$J@VA@PR13207@@VB@2@@1@@Z" void spam(K x) {} @@ -163,3 +163,31 @@ void foobar(NC::Y > > x) {} // 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 +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 +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 >(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" +} diff --git a/test/CodeGenCXX/mangle-ms-back-references.cpp b/test/CodeGenCXX/mangle-ms-back-references.cpp index 5f93590cf2..4f17326888 100644 --- a/test/CodeGenCXX/mangle-ms-back-references.cpp +++ b/test/CodeGenCXX/mangle-ms-back-references.cpp @@ -61,3 +61,8 @@ void h2(void (*f_ptr)(void *), void *arg) {} PInt3Func h3(PInt3Func x, PInt3Func y, int* z) { return 0; } // CHECK: "\01?h3@@YAP6APAHPAH0@ZP6APAH00@Z10@Z" + +namespace foo { +void foo() { } +// CHECK: "\01?foo@0@YAXXZ" +}