diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-08-26 00:04:55 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-08-26 00:04:55 +0000 |
commit | dacd434c49658286c380c7b4c357d76d53cb4aa1 (patch) | |
tree | 96445b18410c013f21aabb19f3fe17348fbfb225 /lib/AST/NestedNameSpecifier.cpp | |
parent | ec7738776ba68576db5d8316af399d1f983245ee (diff) |
Improve diagnostics and recovery when the nested-name-specifier of a
qualified name does not actually refer into a class/class
template/class template partial specialization.
Improve printing of nested-name-specifiers to eliminate redudant
qualifiers. Also, make it possible to output a nested-name-specifier
through a DiagnosticBuilder, although there are relatively few places
that will use this leeway.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80056 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/NestedNameSpecifier.cpp')
-rw-r--r-- | lib/AST/NestedNameSpecifier.cpp | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/lib/AST/NestedNameSpecifier.cpp b/lib/AST/NestedNameSpecifier.cpp index 90ec4d33fd..0376f9db6b 100644 --- a/lib/AST/NestedNameSpecifier.cpp +++ b/lib/AST/NestedNameSpecifier.cpp @@ -131,15 +131,33 @@ NestedNameSpecifier::print(llvm::raw_ostream &OS, std::string TypeStr; Type *T = getAsType(); - // If this is a qualified name type, suppress the qualification: - // it's part of our nested-name-specifier sequence anyway. FIXME: - // We should be able to assert that this doesn't happen. - if (const QualifiedNameType *QualT = dyn_cast<QualifiedNameType>(T)) - T = QualT->getNamedType().getTypePtr(); - PrintingPolicy InnerPolicy(Policy); InnerPolicy.SuppressTagKind = true; - T->getAsStringInternal(TypeStr, InnerPolicy); + + // Nested-name-specifiers are intended to contain minimally-qualified + // types. An actual QualifiedNameType will not occur, since we'll store + // just the type that is referred to in the nested-name-specifier (e.g., + // a TypedefType, TagType, etc.). However, when we are dealing with + // dependent template-id types (e.g., Outer<T>::template Inner<U>), + // the type requires its own nested-name-specifier for uniqueness, so we + // suppress that nested-name-specifier during printing. + assert(!isa<QualifiedNameType>(T) && + "Qualified name type in nested-name-specifier"); + if (const TemplateSpecializationType *SpecType + = dyn_cast<TemplateSpecializationType>(T)) { + // Print the template name without its corresponding + // nested-name-specifier. + SpecType->getTemplateName().print(OS, InnerPolicy, true); + + // Print the template argument list. + TypeStr = TemplateSpecializationType::PrintTemplateArgumentList( + SpecType->getArgs(), + SpecType->getNumArgs(), + InnerPolicy); + } else { + // Print the type normally + T->getAsStringInternal(TypeStr, InnerPolicy); + } OS << TypeStr; break; } |