[cfe-commits] r71861 - in /cfe/trunk: lib/CodeGen/Mangle.cpp test/CodeGenCXX/mangle.cpp

Anders Carlsson andersca at mac.com
Fri May 15 09:09:20 PDT 2009


Author: andersca
Date: Fri May 15 11:09:15 2009
New Revision: 71861

URL: http://llvm.org/viewvc/llvm-project?rev=71861&view=rev
Log:
Name mangling for class template specializations and template arguments.

Modified:
    cfe/trunk/lib/CodeGen/Mangle.cpp
    cfe/trunk/test/CodeGenCXX/mangle.cpp

Modified: cfe/trunk/lib/CodeGen/Mangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/Mangle.cpp?rev=71861&r1=71860&r2=71861&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/Mangle.cpp (original)
+++ cfe/trunk/lib/CodeGen/Mangle.cpp Fri May 15 11:09:15 2009
@@ -19,6 +19,7 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
 #include "clang/Basic/SourceManager.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/raw_ostream.h"
@@ -67,6 +68,9 @@
     void mangleExpression(Expr *E);
     void mangleCXXCtorType(CXXCtorType T);
     void mangleCXXDtorType(CXXDtorType T);
+    
+    void mangleTemplateArgumentList(const TemplateArgumentList &L);
+    void mangleTemplateArgument(const TemplateArgument &A);
   };
 }
 
@@ -290,8 +294,13 @@
 
   if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(DC))
     mangleSourceName(Namespace->getIdentifier());
-  else if (const RecordDecl *Record = dyn_cast<RecordDecl>(DC))
-    mangleSourceName(Record->getIdentifier());
+  else if (const RecordDecl *Record = dyn_cast<RecordDecl>(DC)) {
+    if (const ClassTemplateSpecializationDecl *D = 
+        dyn_cast<ClassTemplateSpecializationDecl>(Record)) {
+      mangleType(QualType(D->getTypeForDecl(), 0));
+    } else
+      mangleSourceName(Record->getIdentifier());
+  }
 }
 
 void 
@@ -571,6 +580,12 @@
     mangleName(T->getDecl()->getTypedefForAnonDecl());
   else
     mangleName(T->getDecl());
+  
+  // If this is a class template specialization, mangle the template
+  // arguments.
+  if (ClassTemplateSpecializationDecl *Spec 
+      = dyn_cast<ClassTemplateSpecializationDecl>(T->getDecl()))
+    mangleTemplateArgumentList(Spec->getTemplateArgs());
 }
 
 void CXXNameMangler::mangleType(const ArrayType *T) {
@@ -649,6 +664,53 @@
   }
 }
 
+void CXXNameMangler::mangleTemplateArgumentList(const TemplateArgumentList &L) {
+  // <template-args> ::= I <template-arg>+ E
+  Out << "I";
+  
+  for (unsigned i = 0, e = L.size(); i != e; ++i) {
+    const TemplateArgument &A = L[i];
+  
+    mangleTemplateArgument(A);
+  }
+  
+  Out << "E";
+}
+
+void CXXNameMangler::mangleTemplateArgument(const TemplateArgument &A) {
+  // <template-arg> ::= <type>			        # type or template
+  //                ::= X <expression> E    # expression
+  //                ::= <expr-primary>      # simple expressions
+  //                ::= I <template-arg>* E # argument pack
+  //                ::= sp <expression>     # pack expansion of (C++0x)
+  switch (A.getKind()) {
+  default:
+    assert(0 && "Unknown template argument kind!");
+  case TemplateArgument::Type:
+    mangleType(A.getAsType());
+    break;
+  case TemplateArgument::Integral:
+    //  <expr-primary> ::= L <type> <value number> E # integer literal
+
+    Out << 'L';
+    
+    mangleType(A.getIntegralType());
+    
+    const llvm::APSInt *Integral = A.getAsIntegral();
+    if (A.getIntegralType()->isBooleanType()) {
+      // Boolean values are encoded as 0/1.
+      Out << (Integral->getBoolValue() ? '1' : '0');
+    } else {
+      if (Integral->isNegative())
+        Out << 'n';
+      Integral->abs().print(Out, false);
+    }
+      
+    Out << 'E';
+    break;
+  }
+}
+
 namespace clang {
   /// \brief Mangles the name of the declaration D and emits that name
   /// to the given output stream.

Modified: cfe/trunk/test/CodeGenCXX/mangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle.cpp?rev=71861&r1=71860&r2=71861&view=diff

==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle.cpp Fri May 15 11:09:15 2009
@@ -49,5 +49,31 @@
 // RUN: grep "_ZGVZN1N1gEvE1a =" %t | count 1 &&
 namespace N { int h(); void g() { static int a = h(); } }
 
-// RUN: grep "_Z1fno" %t | count 1
+// RUN: grep "_Z1fno" %t | count 1 &&
 void f(__int128_t, __uint128_t) { } 
+
+template <typename T> struct S1 {};
+
+// RUN: grep "_Z1f2S1IiE" %t | count 1 &&
+void f(S1<int>) {}
+
+// RUN: grep "_Z1f2S1IdE" %t | count 1 &&
+void f(S1<double>) {}
+
+template <int N> struct S2 {};
+// RUN: grep "_Z1f2S2ILi100EE" %t | count 1 &&
+void f(S2<100>) {}
+
+// RUN: grep "_Z1f2S2ILin100EE" %t | count 1 &&
+void f(S2<-100>) {}
+
+template <bool B> struct S3 {};
+
+// RUN: grep "_Z1f2S3ILb1EE" %t | count 1 &&
+void f(S3<true>) {}
+
+// RUN: grep "_Z1f2S3ILb0EE" %t | count 1 &&
+void f(S3<false>) {}
+
+// RUN: grep "_Z2f22S3ILb1EE" %t | count 1 
+void f2(S3<100>) {}





More information about the cfe-commits mailing list