зеркало из https://github.com/microsoft/clang-1.git
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
This commit is contained in:
Родитель
a4d3282683
Коммит
136a698896
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче