Correctly mangle dependent TypenameType.

Fixes PR6625.

llvm-svn: 98707
This commit is contained in:
Rafael Espindola 2010-03-17 04:28:11 +00:00
parent c871bac79b
commit cd7eef900f
2 changed files with 36 additions and 24 deletions

View File

@ -469,8 +469,26 @@ void CXXNameMangler::mangleUnresolvedScope(NestedNameSpecifier *Qualifier) {
mangleName(Qualifier->getAsNamespace());
break;
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate:
mangleType(QualType(Qualifier->getAsType(), 0));
case NestedNameSpecifier::TypeSpecWithTemplate: {
const Type *QTy = Qualifier->getAsType();
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(),
TST->getNumArgs());
addSubstitution(QualType(TST, 0));
}
} else {
// We use the QualType mangle type variant here because it handles
// substitutions.
mangleType(QualType(QTy, 0));
}
}
break;
case NestedNameSpecifier::Identifier:
// Member expressions can have these without prefixes.
@ -1144,29 +1162,8 @@ void CXXNameMangler::mangleType(const TemplateSpecializationType *T) {
void CXXNameMangler::mangleType(const TypenameType *T) {
// Typename types are always nested
Out << 'N';
const Type *QTy = T->getQualifier()->getAsType();
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(),
TST->getNumArgs());
addSubstitution(QualType(TST, 0));
}
} else if (const TemplateTypeParmType *TTPT =
dyn_cast<TemplateTypeParmType>(QTy)) {
// We use the QualType mangle type variant here because it handles
// substitutions.
mangleType(QualType(TTPT, 0));
} else
assert(false && "Unhandled type!");
mangleUnresolvedScope(T->getQualifier());
mangleSourceName(T->getIdentifier());
Out << 'E';
}

View File

@ -453,3 +453,18 @@ namespace test8 {
class B { static int value; };
template class A<B::value>;
}
// CHECK: declare void @_ZN5test91fIiNS_3barEEEvRKNT0_3baz1XE
namespace test9 {
template<class T>
struct foo {
typedef T X;
};
struct bar {
typedef foo<int> baz;
};
template <class zaz, class zed>
void f(const typename zed::baz::X&);
void g() {
f<int, bar>( 0);
}
}