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

Douglas Gregor dgregor at apple.com
Tue Apr 27 22:58:56 PDT 2010


Author: dgregor
Date: Wed Apr 28 00:58:56 2010
New Revision: 102490

URL: http://llvm.org/viewvc/llvm-project?rev=102490&view=rev
Log:
Improve name mangling for dependent template names (e.g., typename
T::template apply<U>), handling a few cases where we previously failed
and performing substitutions on such dependent names. Fixes a crash in
Boost.PropertyTree.

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

Modified: cfe/trunk/lib/CodeGen/Mangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/Mangle.cpp?rev=102490&r1=102489&r2=102490&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/Mangle.cpp (original)
+++ cfe/trunk/lib/CodeGen/Mangle.cpp Wed Apr 28 00:58:56 2010
@@ -111,6 +111,7 @@
 private:
   bool mangleSubstitution(const NamedDecl *ND);
   bool mangleSubstitution(QualType T);
+  bool mangleSubstitution(TemplateName Template);
   bool mangleSubstitution(uintptr_t Ptr);
 
   bool mangleStandardSubstitution(const NamedDecl *ND);
@@ -121,6 +122,7 @@
     addSubstitution(reinterpret_cast<uintptr_t>(ND));
   }
   void addSubstitution(QualType T);
+  void addSubstitution(TemplateName Template);
   void addSubstitution(uintptr_t Ptr);
 
   void mangleUnresolvedScope(NestedNameSpecifier *Qualifier);
@@ -138,6 +140,7 @@
                              unsigned KnownArity);
   void mangleUnscopedName(const NamedDecl *ND);
   void mangleUnscopedTemplateName(const TemplateDecl *ND);
+  void mangleUnscopedTemplateName(TemplateName);
   void mangleSourceName(const IdentifierInfo *II);
   void mangleLocalName(const NamedDecl *ND);
   void mangleNestedName(const NamedDecl *ND, const DeclContext *DC,
@@ -431,6 +434,31 @@
   addSubstitution(ND);
 }
 
+void CXXNameMangler::mangleUnscopedTemplateName(TemplateName Template) {
+  //     <unscoped-template-name> ::= <unscoped-name>
+  //                              ::= <substitution>
+  if (TemplateDecl *TD = Template.getAsTemplateDecl())
+    return mangleUnscopedTemplateName(TD);
+  
+  if (mangleSubstitution(Template))
+    return;
+
+  // FIXME: How to cope with operators here?
+  DependentTemplateName *Dependent = Template.getAsDependentTemplateName();
+  assert(Dependent && "Not a dependent template name?");
+  if (!Dependent->isIdentifier()) {
+    // FIXME: We can't possibly know the arity of the operator here!
+    Diagnostic &Diags = Context.getDiags();
+    unsigned DiagID = Diags.getCustomDiagID(Diagnostic::Error,
+                                      "cannot mangle dependent operator name");
+    Diags.Report(FullSourceLoc(), DiagID);
+    return;
+  }
+  
+  mangleSourceName(Dependent->getIdentifier());
+  addSubstitution(Template);
+}
+
 void CXXNameMangler::mangleNumber(int64_t Number) {
   //  <number> ::= [n] <non-negative decimal integer>
   if (Number < 0) {
@@ -764,15 +792,7 @@
   DependentTemplateName *Dependent = Template.getAsDependentTemplateName();
   assert(Dependent && "Unknown template name kind?");
   mangleUnresolvedScope(Dependent->getQualifier());
-  if (Dependent->isIdentifier())
-    mangleSourceName(Dependent->getIdentifier());
-  else {
-    // FIXME: We can't possibly know the arity of the operator here!
-    Diagnostic &Diags = Context.getDiags();
-    unsigned DiagID = Diags.getCustomDiagID(Diagnostic::Error,
-                                 "cannot mangle dependent operator name");
-    Diags.Report(FullSourceLoc(), DiagID);
-  }
+  mangleUnscopedTemplateName(Template);
 }
 
 void CXXNameMangler::mangleTemplatePrefix(const TemplateDecl *ND) {
@@ -1199,17 +1219,42 @@
 }
 
 void CXXNameMangler::mangleType(const TemplateSpecializationType *T) {
-  TemplateDecl *TD = T->getTemplateName().getAsTemplateDecl();
-  assert(TD && "FIXME: Support dependent template names!");
-
-  mangleName(TD, T->getArgs(), T->getNumArgs());
+  if (TemplateDecl *TD = T->getTemplateName().getAsTemplateDecl()) {
+    mangleName(TD, T->getArgs(), T->getNumArgs());
+  } else {
+    if (mangleSubstitution(QualType(T, 0)))
+      return;
+    
+    mangleTemplatePrefix(T->getTemplateName());
+    
+    // FIXME: GCC does not appear to mangle the template arguments when
+    // the template in question is a dependent template name. Should we
+    // emulate that badness?
+    mangleTemplateArgs(T->getTemplateName(), T->getArgs(), T->getNumArgs());
+    addSubstitution(QualType(T, 0));
+  }
 }
 
 void CXXNameMangler::mangleType(const DependentNameType *T) {
   // Typename types are always nested
   Out << 'N';
-  mangleUnresolvedScope(T->getQualifier());
-  mangleSourceName(T->getIdentifier());
+  if (T->getIdentifier()) {
+    mangleUnresolvedScope(T->getQualifier());
+    mangleSourceName(T->getIdentifier());
+  } else {
+    const TemplateSpecializationType *TST = T->getTemplateId();
+    if (!mangleSubstitution(QualType(TST, 0))) {
+      mangleTemplatePrefix(TST->getTemplateName());
+      
+      // FIXME: GCC does not appear to mangle the template arguments when
+      // the template in question is a dependent template name. Should we
+      // emulate that badness?
+      mangleTemplateArgs(TST->getTemplateName(), TST->getArgs(),
+                         TST->getNumArgs());    
+      addSubstitution(QualType(TST, 0));
+    }
+  }
+    
   Out << 'E';
 }
 
@@ -1743,6 +1788,15 @@
   return mangleSubstitution(TypePtr);
 }
 
+bool CXXNameMangler::mangleSubstitution(TemplateName Template) {
+  if (TemplateDecl *TD = Template.getAsTemplateDecl())
+    return mangleSubstitution(TD);
+  
+  Template = Context.getASTContext().getCanonicalTemplateName(Template);
+  return mangleSubstitution(
+                      reinterpret_cast<uintptr_t>(Template.getAsVoidPointer()));
+}
+
 bool CXXNameMangler::mangleSubstitution(uintptr_t Ptr) {
   llvm::DenseMap<uintptr_t, unsigned>::iterator I = Substitutions.find(Ptr);
   if (I == Substitutions.end())
@@ -1921,6 +1975,14 @@
   addSubstitution(TypePtr);
 }
 
+void CXXNameMangler::addSubstitution(TemplateName Template) {
+  if (TemplateDecl *TD = Template.getAsTemplateDecl())
+    return addSubstitution(TD);
+  
+  Template = Context.getASTContext().getCanonicalTemplateName(Template);
+  addSubstitution(reinterpret_cast<uintptr_t>(Template.getAsVoidPointer()));
+}
+
 void CXXNameMangler::addSubstitution(uintptr_t Ptr) {
   unsigned SeqID = Substitutions.size();
 

Modified: cfe/trunk/test/CodeGenCXX/mangle-template.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-template.cpp?rev=102490&r1=102489&r2=102490&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-template.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-template.cpp Wed Apr 28 00:58:56 2010
@@ -127,3 +127,20 @@
     f<int, X>();
   }
 }
+
+namespace test10 {
+  template<typename T>
+  struct X {
+    template<typename U>
+    struct definition {
+    };
+  };
+
+  // CHECK: _ZN6test101fIidEENS_1XIT_E10definitionIT0_EES2_S5_
+  template<typename T, typename U>
+  typename X<T>::template definition<U> f(T, U) { }
+
+  void g(int i, double d) {
+    f(i, d);
+  }
+}





More information about the cfe-commits mailing list