diff options
author | John McCall <rjmccall@apple.com> | 2009-09-11 06:45:03 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2009-09-11 06:45:03 +0000 |
commit | 136a6988960ac3aeb96f298da7a1a182db7217cd (patch) | |
tree | 09fb77402986a09d43cc27f50893bfa28496c44a | |
parent | a4d3282683b22608b05a3d4566c96af269d99c5c (diff) |
When stringizing a NamedDecl for a diagnostic, treat the template
specialization types differently.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81512 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/Decl.h | 22 | ||||
-rw-r--r-- | include/clang/AST/DeclTemplate.h | 4 | ||||
-rw-r--r-- | lib/AST/Decl.cpp | 12 | ||||
-rw-r--r-- | lib/AST/DeclTemplate.cpp | 13 | ||||
-rw-r--r-- | lib/Sema/Sema.cpp | 8 | ||||
-rw-r--r-- | test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp | 2 |
6 files changed, 58 insertions, 3 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index c4c7d26c51..70edcbb222 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -123,6 +123,24 @@ public: std::string getQualifiedNameAsString() const; std::string getQualifiedNameAsString(const PrintingPolicy &Policy) const; + /// getNameForDiagnostic - Appends a human-readable name for this + /// declaration into the given string. + /// + /// This is the method invoked by Sema when displaying a NamedDecl + /// in a diagnostic. It does not necessarily produce the same + /// result as getNameAsString(); for example, class template + /// specializations are printed with their template arguments. + /// + /// TODO: use an API that doesn't require so many temporary strings + virtual void getNameForDiagnostic(std::string &S, + const PrintingPolicy &Policy, + bool Qualified) const { + if (Qualified) + S += getQualifiedNameAsString(Policy); + else + S += getNameAsString(); + } + /// declarationReplaces - Determine whether this declaration, if /// known to be well-formed within its context, will replace the /// declaration OldD if introduced into scope. A declaration will @@ -839,6 +857,10 @@ public: StorageClass S = None, bool isInline = false, bool hasWrittenPrototype = true); + virtual void getNameForDiagnostic(std::string &S, + const PrintingPolicy &Policy, + bool Qualified) const; + virtual SourceRange getSourceRange() const { return SourceRange(getLocation(), EndRangeLoc); } diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index 0232d9382e..ced7639f87 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -926,6 +926,10 @@ public: virtual void Destroy(ASTContext& C); + virtual void getNameForDiagnostic(std::string &S, + const PrintingPolicy &Policy, + bool Qualified) const; + /// \brief Retrieve the template that this specialization specializes. ClassTemplateDecl *getSpecializedTemplate() const; diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 776a26595b..16936428f3 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -404,6 +404,18 @@ void FunctionDecl::Destroy(ASTContext& C) { Decl::Destroy(C); } +void FunctionDecl::getNameForDiagnostic(std::string &S, + const PrintingPolicy &Policy, + bool Qualified) const { + NamedDecl::getNameForDiagnostic(S, Policy, Qualified); + const TemplateArgumentList *TemplateArgs = getTemplateSpecializationArgs(); + if (TemplateArgs) + S += TemplateSpecializationType::PrintTemplateArgumentList( + TemplateArgs->getFlatArgumentList(), + TemplateArgs->flat_size(), + Policy); + +} Stmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const { for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) { diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp index b46f6275d3..77c2a21507 100644 --- a/lib/AST/DeclTemplate.cpp +++ b/lib/AST/DeclTemplate.cpp @@ -422,6 +422,19 @@ void ClassTemplateSpecializationDecl::Destroy(ASTContext &C) { CXXRecordDecl::Destroy(C); } +void +ClassTemplateSpecializationDecl::getNameForDiagnostic(std::string &S, + const PrintingPolicy &Policy, + bool Qualified) const { + NamedDecl::getNameForDiagnostic(S, Policy, Qualified); + + const TemplateArgumentList &TemplateArgs = getTemplateArgs(); + S += TemplateSpecializationType::PrintTemplateArgumentList( + TemplateArgs.getFlatArgumentList(), + TemplateArgs.flat_size(), + Policy); +} + ClassTemplateDecl * ClassTemplateSpecializationDecl::getSpecializedTemplate() const { if (SpecializedPartialSpecialization *PartialSpec diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index b158c85414..080266c75f 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -85,13 +85,17 @@ static void ConvertArgToStringFn(Diagnostic::ArgumentKind Kind, intptr_t Val, assert(ModLen == 0 && ArgLen == 0 && "Invalid modifier for DeclarationName argument"); } else if (Kind == Diagnostic::ak_nameddecl) { + bool Qualified; if (ModLen == 1 && Modifier[0] == 'q' && ArgLen == 0) - S = reinterpret_cast<NamedDecl*>(Val)->getQualifiedNameAsString(); + Qualified = true; else { assert(ModLen == 0 && ArgLen == 0 && "Invalid modifier for NamedDecl* argument"); - S = reinterpret_cast<NamedDecl*>(Val)->getNameAsString(); + Qualified = false; } + reinterpret_cast<NamedDecl*>(Val)->getNameForDiagnostic(S, + Context.PrintingPolicy, + Qualified); } else { llvm::raw_string_ostream OS(S); assert(Kind == Diagnostic::ak_nestednamespec); diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp index 0c9f294d2b..b76cb91a75 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp @@ -53,7 +53,7 @@ void e3(union B<A>::Member); void e4(enum B<A>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}} template <class T> struct C { - void foo(class B<T>::Member); // expected-error{{no type named 'Member' in 'B'}} + void foo(class B<T>::Member); // expected-error{{no type named 'Member' in 'B<int>'}} }; C<float> f1; |