forked from OSchip/llvm-project
When canonicalizing nested-name-specifiers involving dependent names
or dependent specializations, rip apart the dependent name/dependent specialization to recanonicalize its pieces, because nested-name-specifiers store "dependent-type::identifier" differently than types do. Fixes PR7419. llvm-svn: 118211
This commit is contained in:
parent
2eed7a1310
commit
3ade5704fe
|
@ -2723,9 +2723,33 @@ ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) {
|
|||
case NestedNameSpecifier::TypeSpec:
|
||||
case NestedNameSpecifier::TypeSpecWithTemplate: {
|
||||
QualType T = getCanonicalType(QualType(NNS->getAsType(), 0));
|
||||
return NestedNameSpecifier::Create(*this, 0,
|
||||
NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate,
|
||||
T.getTypePtr());
|
||||
|
||||
// If we have some kind of dependent-named type (e.g., "typename T::type"),
|
||||
// break it apart into its prefix and identifier, then reconsititute those
|
||||
// as the canonical nested-name-specifier. This is required to canonicalize
|
||||
// a dependent nested-name-specifier involving typedefs of dependent-name
|
||||
// types, e.g.,
|
||||
// typedef typename T::type T1;
|
||||
// typedef typename T1::type T2;
|
||||
if (const DependentNameType *DNT = T->getAs<DependentNameType>()) {
|
||||
NestedNameSpecifier *Prefix
|
||||
= getCanonicalNestedNameSpecifier(DNT->getQualifier());
|
||||
return NestedNameSpecifier::Create(*this, Prefix,
|
||||
const_cast<IdentifierInfo *>(DNT->getIdentifier()));
|
||||
}
|
||||
|
||||
if (const DependentTemplateSpecializationType *DTST
|
||||
= T->getAs<DependentTemplateSpecializationType>()) {
|
||||
NestedNameSpecifier *Prefix
|
||||
= getCanonicalNestedNameSpecifier(DTST->getQualifier());
|
||||
TemplateName Name
|
||||
= getDependentTemplateName(Prefix, DTST->getIdentifier());
|
||||
T = getTemplateSpecializationType(Name,
|
||||
DTST->getArgs(), DTST->getNumArgs());
|
||||
T = getCanonicalType(T);
|
||||
}
|
||||
|
||||
return NestedNameSpecifier::Create(*this, 0, false, T.getTypePtr());
|
||||
}
|
||||
|
||||
case NestedNameSpecifier::Global:
|
||||
|
|
|
@ -117,3 +117,20 @@ namespace PR6463 {
|
|||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
namespace PR7419 {
|
||||
template <typename T> struct S {
|
||||
typedef typename T::Y T2;
|
||||
typedef typename T2::Z T3;
|
||||
typedef typename T3::W T4;
|
||||
T4 *f();
|
||||
|
||||
typedef typename T::template Y<int> TT2;
|
||||
typedef typename TT2::template Z<float> TT3;
|
||||
typedef typename TT3::template W<double> TT4;
|
||||
TT4 g();
|
||||
};
|
||||
|
||||
template <typename T> typename T::Y::Z::W *S<T>::f() { }
|
||||
template <typename T> typename T::template Y<int>::template Z<float>::template W<double> S<T>::g() { }
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue