diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-11-04 00:09:33 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-11-04 00:09:33 +0000 |
commit | 264bf66d55563dd86a3d7e06738aa427de512d2c (patch) | |
tree | efd540c533339c3547d6e54d9441bb676bfc8ae6 /lib/AST/ASTContext.cpp | |
parent | 06de2cfe0b46e525ba8618536b12aecfbd12d127 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@118211 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ASTContext.cpp')
-rw-r--r-- | lib/AST/ASTContext.cpp | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 366fe7d28f..7ed1035c0f 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -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: |