add support for inserting a DeclarationName into a diagnostic directly
without calling getAsString(). This implicitly puts quotes around the name, so diagnostics need to be tweaked to accommodate this. llvm-svn: 59916
This commit is contained in:
parent
d125393d24
commit
f7e69d5a77
|
@ -22,11 +22,11 @@ namespace llvm {
|
|||
}
|
||||
|
||||
namespace clang {
|
||||
class CXXSpecialName; // a private class used by DeclarationName
|
||||
class CXXOperatorIdName; // a private class used by DeclarationName
|
||||
class DeclarationNameExtra; // a private class used by DeclarationName
|
||||
class CXXSpecialName;
|
||||
class CXXOperatorIdName;
|
||||
class DeclarationNameExtra;
|
||||
class IdentifierInfo;
|
||||
class MultiKeywordSelector; // a private class used by Selector and DeclarationName
|
||||
class MultiKeywordSelector;
|
||||
|
||||
/// DeclarationName - The name of a declaration. In the common case,
|
||||
/// this just stores an IdentifierInfo pointer to a normal
|
||||
|
@ -198,6 +198,12 @@ public:
|
|||
/// name as an opaque integer.
|
||||
uintptr_t getAsOpaqueInteger() const { return Ptr; }
|
||||
|
||||
static DeclarationName getFromOpaqueInteger(uintptr_t P) {
|
||||
DeclarationName N;
|
||||
N.Ptr = P;
|
||||
return N;
|
||||
}
|
||||
|
||||
/// getCXXNameType - If this name is one of the C++ names (of a
|
||||
/// constructor, destructor, or conversion function), return the
|
||||
/// type associated with that name.
|
||||
|
@ -314,6 +320,16 @@ public:
|
|||
DeclarationName getCXXOperatorName(OverloadedOperatorKind Op);
|
||||
};
|
||||
|
||||
/// Insertion operator for diagnostics. This allows sending DeclarationName's
|
||||
/// into a diagnostic with <<.
|
||||
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
DeclarationName N) {
|
||||
DB.AddTaggedVal(N.getAsOpaqueInteger(),
|
||||
Diagnostic::ak_declarationname);
|
||||
return DB;
|
||||
}
|
||||
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
namespace llvm {
|
||||
|
|
|
@ -1494,7 +1494,6 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
|||
Diagnostic::ak_qualtype);
|
||||
return DB;
|
||||
}
|
||||
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
|
|
|
@ -335,7 +335,8 @@ public:
|
|||
case Diagnostic::ak_identifierinfo:
|
||||
R.addString(Info.getArgIdentifier(i)->getName());
|
||||
break;
|
||||
case Diagnostic::ak_qualtype: {
|
||||
case Diagnostic::ak_qualtype:
|
||||
case Diagnostic::ak_declarationname: {
|
||||
llvm::SmallString<64> Str;
|
||||
Info.getDiags()->ConvertArgToString(Info.getArgKind(i),
|
||||
Info.getRawArg(i), 0, 0, 0, 0, Str);
|
||||
|
|
|
@ -68,7 +68,8 @@ public:
|
|||
ak_sint, // int
|
||||
ak_uint, // unsigned
|
||||
ak_identifierinfo, // IdentifierInfo
|
||||
ak_qualtype // QualType
|
||||
ak_qualtype, // QualType
|
||||
ak_declarationname // DeclarationName
|
||||
};
|
||||
|
||||
private:
|
||||
|
|
|
@ -1218,9 +1218,9 @@ DIAG(err_typecheck_bool_condition, ERROR,
|
|||
DIAG(err_expected_class_or_namespace, ERROR,
|
||||
"expected a class or namespace")
|
||||
DIAG(err_invalid_declarator_scope, ERROR,
|
||||
"definition or redeclaration for '%0' not in a namespace enclosing '%1'")
|
||||
"definition or redeclaration of '%0' not in a namespace enclosing '%1'")
|
||||
DIAG(err_invalid_declarator_in_function, ERROR,
|
||||
"definition or redeclaration for '%0' not allowed inside a function")
|
||||
"definition or redeclaration of %0 not allowed inside a function")
|
||||
DIAG(err_not_tag_in_scope, ERROR,
|
||||
"'%0' does not name a tag member in the specified scope")
|
||||
|
||||
|
|
|
@ -536,6 +536,7 @@ FormatDiagnostic(llvm::SmallVectorImpl<char> &OutStr) const {
|
|||
break;
|
||||
}
|
||||
case Diagnostic::ak_qualtype:
|
||||
case Diagnostic::ak_declarationname:
|
||||
OutStr.push_back('\'');
|
||||
getDiags()->ConvertArgToString(getArgKind(ArgNo), getRawArg(ArgNo),
|
||||
Modifier, ModifierLen,
|
||||
|
|
|
@ -22,17 +22,24 @@ using namespace clang;
|
|||
|
||||
/// ConvertQualTypeToStringFn - This function is used to pretty print the
|
||||
/// specified QualType as a string in diagnostics.
|
||||
static void ConvertArgToStringFn(Diagnostic::ArgumentKind Kind, intptr_t QT,
|
||||
static void ConvertArgToStringFn(Diagnostic::ArgumentKind Kind, intptr_t Val,
|
||||
const char *Modifier, unsigned ML,
|
||||
const char *Argument, unsigned ArgLen,
|
||||
llvm::SmallVectorImpl<char> &Output) {
|
||||
assert(ML == 0 && ArgLen == 0 && "Invalid modifier for QualType argument");
|
||||
assert(Kind == Diagnostic::ak_qualtype);
|
||||
|
||||
QualType Ty(QualType::getFromOpaquePtr(reinterpret_cast<void*>(QT)));
|
||||
std::string S;
|
||||
if (Kind == Diagnostic::ak_qualtype) {
|
||||
QualType Ty(QualType::getFromOpaquePtr(reinterpret_cast<void*>(Val)));
|
||||
|
||||
// FIXME: Playing with std::string is really slow.
|
||||
std::string S = Ty.getAsString();
|
||||
// FIXME: Playing with std::string is really slow.
|
||||
S = Ty.getAsString();
|
||||
} else {
|
||||
assert(Kind == Diagnostic::ak_declarationname);
|
||||
|
||||
DeclarationName N = DeclarationName::getFromOpaqueInteger(Val);
|
||||
S = N.getAsString();
|
||||
}
|
||||
Output.append(S.begin(), S.end());
|
||||
}
|
||||
|
||||
|
|
|
@ -856,10 +856,9 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) {
|
|||
SourceLocation L = D.getIdentifierLoc();
|
||||
SourceRange R = D.getCXXScopeSpec().getRange();
|
||||
if (isa<FunctionDecl>(CurContext)) {
|
||||
Diag(L, diag::err_invalid_declarator_in_function)
|
||||
<< Name.getAsString() << R;
|
||||
Diag(L, diag::err_invalid_declarator_in_function) << Name << R;
|
||||
} else {
|
||||
Diag(L, diag::err_invalid_declarator_scope)
|
||||
Diag(L, diag::err_invalid_declarator_scope)
|
||||
<< Name.getAsString() << cast<NamedDecl>(DC)->getName() << R;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,11 +21,11 @@ void C2::m() {
|
|||
}
|
||||
|
||||
namespace B {
|
||||
void ::A::Af() {} // expected-error {{definition or redeclaration for 'Af' not in a namespace enclosing 'A'}}
|
||||
void ::A::Af() {} // expected-error {{definition or redeclaration of 'Af' not in a namespace enclosing 'A'}}
|
||||
}
|
||||
|
||||
void f1() {
|
||||
void A::Af(); // expected-error {{definition or redeclaration for 'Af' not allowed inside a function}}
|
||||
void A::Af(); // expected-error {{definition or redeclaration of 'Af' not allowed inside a function}}
|
||||
}
|
||||
|
||||
void f2() {
|
||||
|
|
Loading…
Reference in New Issue