]> granicus.if.org Git - clang/commitdiff
Handle mangling of TemplateSpecializationType.
authorAnders Carlsson <andersca@mac.com>
Fri, 18 Sep 2009 02:42:01 +0000 (02:42 +0000)
committerAnders Carlsson <andersca@mac.com>
Fri, 18 Sep 2009 02:42:01 +0000 (02:42 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82189 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/Mangle.cpp
test/CodeGenCXX/mangle.cpp

index aaa771b21de2cef95076b899e3bb7e5013012576..d0edb02a693b2e81ad94d9513d1642198731106a 100644 (file)
@@ -69,12 +69,18 @@ namespace {
 
     void mangleFunctionEncoding(const FunctionDecl *FD);
     void mangleName(const NamedDecl *ND);
+    void mangleName(const TemplateDecl *TD, 
+                    const TemplateArgument *TemplateArgs,
+                    unsigned NumTemplateArgs);
     void mangleUnqualifiedName(const NamedDecl *ND);
     void mangleUnscopedName(const NamedDecl *ND);
-    void mangleUnscopedTemplateName(const FunctionDecl *ND);
+    void mangleUnscopedTemplateName(const NamedDecl *ND);
     void mangleSourceName(const IdentifierInfo *II);
     void mangleLocalName(const NamedDecl *ND);
     void mangleNestedName(const NamedDecl *ND);
+    void mangleNestedName(const TemplateDecl *TD, 
+                          const TemplateArgument *TemplateArgs,
+                          unsigned NumTemplateArgs);
     void manglePrefix(const DeclContext *DC);
     void mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity);
     void mangleCVQualifiers(unsigned Quals);
@@ -93,6 +99,8 @@ namespace {
     void mangleCXXCtorType(CXXCtorType T);
     void mangleCXXDtorType(CXXDtorType T);
 
+    void mangleTemplateArgs(const TemplateArgument *TemplateArgs,
+                            unsigned NumTemplateArgs);
     void mangleTemplateArgumentList(const TemplateArgumentList &L);
     void mangleTemplateArgument(const TemplateArgument &A);
   };
@@ -268,6 +276,24 @@ void CXXNameMangler::mangleName(const NamedDecl *ND) {
     mangleNestedName(ND);
 }
 
+void CXXNameMangler::mangleName(const TemplateDecl *TD, 
+                                const TemplateArgument *TemplateArgs,
+                                unsigned NumTemplateArgs) {
+  const DeclContext *DC = TD->getDeclContext();
+  while (isa<LinkageSpecDecl>(DC)) {
+    assert(cast<LinkageSpecDecl>(DC)->getLanguage() == 
+           LinkageSpecDecl::lang_cxx && "Unexpected linkage decl!");
+    DC = DC->getParent();
+  }
+  if (DC->isTranslationUnit() || isStdNamespace(DC)) {
+    mangleUnscopedTemplateName(cast<NamedDecl>(TD->getTemplatedDecl()));
+    mangleTemplateArgs(TemplateArgs, NumTemplateArgs);
+  } else {
+    mangleNestedName(TD, TemplateArgs, NumTemplateArgs);
+  }
+}
+
 void CXXNameMangler::mangleUnscopedName(const NamedDecl *ND) {
   //  <unscoped-name> ::= <unqualified-name>
   //                  ::= St <unqualified-name>   # ::std::
@@ -277,14 +303,14 @@ void CXXNameMangler::mangleUnscopedName(const NamedDecl *ND) {
   mangleUnqualifiedName(ND);
 }
 
-void CXXNameMangler::mangleUnscopedTemplateName(const FunctionDecl *FD) {
+void CXXNameMangler::mangleUnscopedTemplateName(const NamedDecl *ND) {
   //     <unscoped-template-name> ::= <unscoped-name>
   //                              ::= <substitution>
-  if (mangleSubstitution(FD))
+  if (mangleSubstitution(ND))
     return;
   
-  mangleUnscopedName(FD);
-  addSubstitution(FD);
+  mangleUnscopedName(ND);
+  addSubstitution(ND);
 }
 
 void CXXNameMangler::mangleCalloffset(int64_t nv, int64_t v) {
@@ -419,6 +445,17 @@ void CXXNameMangler::mangleNestedName(const NamedDecl *ND) {
   Out << 'E';
 }
 
+void CXXNameMangler::mangleNestedName(const TemplateDecl *TD, 
+                                      const TemplateArgument *TemplateArgs,
+                                      unsigned NumTemplateArgs) {
+  Out << 'N';
+  manglePrefix(TD->getDeclContext());
+  mangleUnqualifiedName(TD->getTemplatedDecl());
+  
+  mangleTemplateArgs(TemplateArgs, NumTemplateArgs);
+  Out << 'E';
+}
+
 void CXXNameMangler::mangleLocalName(const NamedDecl *ND) {
   // <local-name> := Z <function encoding> E <entity name> [<discriminator>]
   //              := Z <function encoding> E s [<discriminator>]
@@ -827,8 +864,10 @@ void CXXNameMangler::mangleType(const FixedWidthIntType *T) {
 }
 
 void CXXNameMangler::mangleType(const TemplateSpecializationType *T) {
-  // TSTs are never canonical unless they're dependent.
-  assert(false && "can't mangle dependent template specializations yet");
+  TemplateDecl *TD = T->getTemplateName().getAsTemplateDecl();
+  assert(TD && "FIXME: Support dependent template names!");
+  
+  mangleName(TD, T->getArgs(), T->getNumArgs());
 }
 
 void CXXNameMangler::mangleType(const TypenameType *T) {
@@ -896,6 +935,18 @@ void CXXNameMangler::mangleTemplateArgumentList(const TemplateArgumentList &L) {
   Out << "E";
 }
 
+void CXXNameMangler::mangleTemplateArgs(const TemplateArgument *TemplateArgs,
+                                        unsigned NumTemplateArgs) {
+  // <template-args> ::= I <template-arg>+ E
+  Out << "I";
+  
+  for (unsigned i = 0; i != NumTemplateArgs; ++i) {
+    mangleTemplateArgument(TemplateArgs[i]);
+  }
+  
+  Out << "E";
+}
+
 void CXXNameMangler::mangleTemplateArgument(const TemplateArgument &A) {
   // <template-arg> ::= <type>              # type or template
   //                ::= X <expression> E    # expression
index 98db0845c779117f411c16bd406528882bac8ffc..8d302248a1ada15c39a6e40464a683f440afc3ae 100644 (file)
@@ -92,15 +92,24 @@ template<typename T, typename U> void ft1(U u, T t) { }
 
 template<typename T> void ft2(T t, void (*)(T), void (*)(T)) { }
 
+template<typename T, typename U = S1<T> > struct S4 { };
+template<typename T> void ft3(S4<T>*) {  }
+
+void g() {
+  ft2<int>(0);
+}
+extern "C++" {
+  // CHECK: @_Z1hv
+ void h() { } 
+}
+
 void g() {
   // CHECK: @_Z3ft1IidEvT0_T_
   ft1<int, double>(1, 0);
   
   // CHECK: @_Z3ft2IcEvT_PFvS0_ES2_
   ft2<char>(1, 0, 0);
-}
-
-extern "C++" {
-  // CHECK: @_Z1hv
- void h() { } 
+  
+  // CHECK: @_Z3ft3IiEvP2S4IT_2S1IS1_EE
+  ft3<int>(0);
 }