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 | 053f691d5e2a94ee8cf9aeaa337475549690cd09 (patch) | |
tree | c4a5d951aaa02b14256015630dd709d1ec4b9b1c /clang/lib/AST/NestedNameSpecifier.cpp | |
parent | 7e3f0e4e0df371cb56732f5bd6995e34a4cf3089 (diff) | |
download | bcm5719-llvm-053f691d5e2a94ee8cf9aeaa337475549690cd09.tar.gz bcm5719-llvm-053f691d5e2a94ee8cf9aeaa337475549690cd09.zip |
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.
llvm-svn: 80056
Diffstat (limited to 'clang/lib/AST/NestedNameSpecifier.cpp')
-rw-r--r-- | clang/lib/AST/NestedNameSpecifier.cpp | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/clang/lib/AST/NestedNameSpecifier.cpp b/clang/lib/AST/NestedNameSpecifier.cpp index 90ec4d33fdf..0376f9db6be 100644 --- a/clang/lib/AST/NestedNameSpecifier.cpp +++ b/clang/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; } |