]> granicus.if.org Git - clang/commitdiff
MS ABI: Mangle variable templates properly
authorDavid Majnemer <david.majnemer@gmail.com>
Tue, 4 Mar 2014 05:38:05 +0000 (05:38 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Tue, 4 Mar 2014 05:38:05 +0000 (05:38 +0000)
We wouldn't recognize variable templates as being templates leading us
to leave the template arguments off of the mangled name.  This would
allow two unrelated templates to map to the same mangled name.

N.B.  While MSVC doesn't support variable templates as of this date,
this mangling is the most likely thing they will choose to use.  Their
demangler can successfully demangle our manglings with the template
arguments shown.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@202789 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/MicrosoftMangle.cpp
test/CodeGenCXX/mangle-ms-cxx14.cpp [new file with mode: 0644]

index 72ab3732e2d7059e0d5c6877dcd767ddae28d75f..a610e157d906cc529c39fef60d11af83ca6da0fc 100644 (file)
@@ -562,6 +562,13 @@ isTemplate(const NamedDecl *ND, const TemplateArgumentList *&TemplateArgs) {
     return Spec->getSpecializedTemplate();
   }
 
+  // Check if we have a variable template.
+  if (const VarTemplateSpecializationDecl *Spec =
+          dyn_cast<VarTemplateSpecializationDecl>(ND)) {
+    TemplateArgs = &Spec->getTemplateArgs();
+    return Spec->getSpecializedTemplate();
+  }
+
   return 0;
 }
 
@@ -585,7 +592,6 @@ MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
       return;
     }
 
-    // We have a class template.
     // Here comes the tricky thing: if we need to mangle something like
     //   void foo(A::X<Y>, B::X<Y>),
     // the X<Y> part is aliased. However, if you need to mangle
diff --git a/test/CodeGenCXX/mangle-ms-cxx14.cpp b/test/CodeGenCXX/mangle-ms-cxx14.cpp
new file mode 100644 (file)
index 0000000..5bf0e96
--- /dev/null
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -std=c++1y -fms-extensions -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
+
+template <typename> int x = 0;
+
+// CHECK: "\01??$x@X@@3HA"
+template <> int x<void>;
+// CHECK: "\01??$x@H@@3HA"
+template <> int x<int>;