[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