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

Douglas Gregor dgregor at apple.com
Thu Apr 22 20:10:43 PDT 2010


Author: dgregor
Date: Thu Apr 22 22:10:43 2010
New Revision: 102167

URL: http://llvm.org/viewvc/llvm-project?rev=102167&view=rev
Log:
Mangle dependent template names such as the nested-name-specifier in

  T::apply <U>::type

Fixes PR6899, although I want to dig a little deeper into the FIXME
for dependent template names that refer to operators.

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=102167&r1=102166&r2=102167&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/Mangle.cpp (original)
+++ cfe/trunk/lib/CodeGen/Mangle.cpp Thu Apr 22 22:10:43 2010
@@ -147,6 +147,7 @@
                         unsigned NumTemplateArgs);
   void manglePrefix(const DeclContext *DC, bool NoFunction=false);
   void mangleTemplatePrefix(const TemplateDecl *ND);
+  void mangleTemplatePrefix(TemplateName Template);
   void mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity);
   void mangleQualifiers(Qualifiers Quals);
 
@@ -172,6 +173,9 @@
   void mangleCXXCtorType(CXXCtorType T);
   void mangleCXXDtorType(CXXDtorType T);
 
+  void mangleTemplateArgs(TemplateName Template,
+                          const TemplateArgument *TemplateArgs,
+                          unsigned NumTemplateArgs);  
   void mangleTemplateArgs(const TemplateParameterList &PL,
                           const TemplateArgument *TemplateArgs,
                           unsigned NumTemplateArgs);
@@ -473,11 +477,12 @@
     if (const TemplateSpecializationType *TST =
         dyn_cast<TemplateSpecializationType>(QTy)) {
       if (!mangleSubstitution(QualType(TST, 0))) {
-        TemplateDecl *TD = TST->getTemplateName().getAsTemplateDecl();
-        assert(TD && "FIXME: Support dependent template names");
-        mangleTemplatePrefix(TD);
-        TemplateParameterList *TemplateParameters = TD->getTemplateParameters();
-        mangleTemplateArgs(*TemplateParameters, TST->getArgs(),
+        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));
       }
@@ -739,6 +744,33 @@
   addSubstitution(cast<NamedDecl>(DC));
 }
 
+void CXXNameMangler::mangleTemplatePrefix(TemplateName Template) {
+  // <template-prefix> ::= <prefix> <template unqualified-name>
+  //                   ::= <template-param>
+  //                   ::= <substitution>
+  if (TemplateDecl *TD = Template.getAsTemplateDecl())
+    return mangleTemplatePrefix(TD);
+
+  if (QualifiedTemplateName *Qualified = Template.getAsQualifiedTemplateName())
+    mangleUnresolvedScope(Qualified->getQualifier());
+  
+  if (OverloadedTemplateStorage *Overloaded
+                                      = Template.getAsOverloadedTemplate()) {
+    mangleUnqualifiedName(0, (*Overloaded->begin())->getDeclName(), 
+                          UnknownArity);
+    return;
+  }
+   
+  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 for mangling operators!
+  }
+}
+
 void CXXNameMangler::mangleTemplatePrefix(const TemplateDecl *ND) {
   // <template-prefix> ::= <prefix> <template unqualified-name>
   //                   ::= <template-param>
@@ -1574,6 +1606,20 @@
   }
 }
 
+void CXXNameMangler::mangleTemplateArgs(TemplateName Template,
+                                        const TemplateArgument *TemplateArgs,
+                                        unsigned NumTemplateArgs) {
+  if (TemplateDecl *TD = Template.getAsTemplateDecl())
+    return mangleTemplateArgs(*TD->getTemplateParameters(), TemplateArgs,
+                              NumTemplateArgs);
+  
+  // <template-args> ::= I <template-arg>+ E
+  Out << 'I';
+  for (unsigned i = 0; i != NumTemplateArgs; ++i)
+    mangleTemplateArg(0, TemplateArgs[i]);
+  Out << 'E';
+}
+
 void CXXNameMangler::mangleTemplateArgs(const TemplateParameterList &PL,
                                         const TemplateArgumentList &AL) {
   // <template-args> ::= I <template-arg>+ E
@@ -1608,7 +1654,7 @@
     break;
   case TemplateArgument::Template:
     assert(A.getAsTemplate().getAsTemplateDecl() &&
-           "FIXME: Support dependent template names");
+           "Can't get dependent template names here");
     mangleName(A.getAsTemplate().getAsTemplateDecl());
     break;
   case TemplateArgument::Expression:
@@ -1620,6 +1666,7 @@
     mangleIntegerLiteral(A.getIntegralType(), *A.getAsIntegral());
     break;
   case TemplateArgument::Declaration: {
+    assert(P && "Missing template parameter for declaration argument");
     //  <expr-primary> ::= L <mangled-name> E # external name
 
     // Clang produces AST's where pointer-to-member-function expressions

Modified: cfe/trunk/test/CodeGenCXX/mangle-template.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-template.cpp?rev=102167&r1=102166&r2=102167&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-template.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-template.cpp Thu Apr 22 22:10:43 2010
@@ -104,3 +104,26 @@
   // CHECK: define weak_odr void @_ZN5test81fIiEEvNS_5int_cIXsrNS_4metaIT_E4typeE5valueEEE
   template void f<int>(int_c<sizeof(int)>);
 }
+
+namespace test9 {
+  template<typename T>
+  struct supermeta {
+    template<typename U>
+    struct apply {
+      typedef T U::*type;
+    };
+  };
+
+  struct X { };
+
+  template<typename T, typename U>
+  typename supermeta<T>::template apply<U>::type f();
+
+  void test_f() {
+    // CHECK: @_ZN5test91fIiNS_1XEEENS_9supermetaIT_E5applyIT0_E4typeEv()
+    // Note: GCC incorrectly mangles this as
+    // _ZN5test91fIiNS_1XEEENS_9supermetaIT_E5apply4typeEv, while EDG
+    // gets it right.
+    f<int, X>();
+  }
+}





More information about the cfe-commits mailing list