Support and use token kinds as diagnostic arguments

Introduce proper facilities to render token spellings using the diagnostic
formatter.

Replaces most of the hard-coded diagnostic messages related to expected tokens,
which all shared the same semantics but had to be multiply defined due to
variations in token order or quote marks.

The associated parser changes are largely mechanical but they expose
commonality in whole chunks of the parser that can now be factored away.

This commit uses C++11 typed enums along with a speculative legacy fallback
until the transition is complete.

Requires corresponding changes in LLVM r197895.

llvm-svn: 197972
This commit is contained in:
Alp Toker 2013-12-24 09:48:30 +00:00
parent 090a7cd76d
commit ec543279db
22 changed files with 223 additions and 181 deletions

View File

@ -18,6 +18,9 @@
#include "clang/Basic/DiagnosticIDs.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/SourceLocation.h"
#if !LLVM_HAS_STRONG_ENUMS
#include "clang/Basic/TokenKinds.h"
#endif
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
@ -35,6 +38,11 @@ namespace clang {
class Preprocessor;
class DiagnosticErrorTrap;
class StoredDiagnostic;
#if LLVM_HAS_STRONG_ENUMS
namespace tok {
enum TokenKind : unsigned;
}
#endif
/// \brief Annotates a diagnostic with some code that should be
/// inserted, removed, or replaced to fix the problem.
@ -151,6 +159,7 @@ public:
ak_c_string, ///< const char *
ak_sint, ///< int
ak_uint, ///< unsigned
ak_tokenkind, ///< enum TokenKind : unsigned
ak_identifierinfo, ///< IdentifierInfo
ak_qualtype, ///< QualType
ak_declarationname, ///< DeclarationName
@ -1027,6 +1036,12 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
return DB;
}
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
tok::TokenKind I) {
DB.AddTaggedVal(static_cast<unsigned>(I), DiagnosticsEngine::ak_tokenkind);
return DB;
}
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
const IdentifierInfo *II) {
DB.AddTaggedVal(reinterpret_cast<intptr_t>(II),

View File

@ -30,7 +30,7 @@ def note_type_being_defined : Note<
"definition of %0 is not complete until the closing '}'">;
/// note_matching - this is used as a continuation of a previous diagnostic,
/// e.g. to specify the '(' when we expected a ')'.
def note_matching : Note<"to match this '%0'">;
def note_matching : Note<"to match this %0">;
def note_using : Note<"using">;
def note_possibility : Note<"one possibility">;
@ -60,6 +60,10 @@ def err_invalid_numeric_udl : Error<
let CategoryName = "Parse Issue" in {
def err_expected : Error<"expected %0">;
def err_expected_either : Error<"expected %0 or %1">;
def err_expected_after : Error<"expected %1 after %0">;
def err_param_redefinition : Error<"redefinition of parameter %0">;
def warn_method_param_redefinition : Warning<"redefinition of method parameter %0">;
def warn_method_param_declaration : Warning<"redeclaration of method parameter %0">,

View File

@ -149,18 +149,10 @@ def err_expected_expression : Error<"expected expression">;
def err_expected_type : Error<"expected a type">;
def err_expected_external_declaration : Error<"expected external declaration">;
def err_extraneous_closing_brace : Error<"extraneous closing brace ('}')">;
def err_expected_ident : Error<"expected identifier">;
def err_expected_ident_lparen : Error<"expected identifier or '('">;
def err_expected_ident_lbrace : Error<"expected identifier or '{'">;
def err_expected_lbrace : Error<"expected '{'">;
def err_expected_lparen : Error<"expected '('">;
def err_expected_lparen_or_lbrace : Error<"expected '(' or '{'">;
def err_expected_rparen : Error<"expected ')'">;
def err_expected_lsquare : Error<"expected '['">;
def err_expected_rsquare : Error<"expected ']'">;
def err_expected_rbrace : Error<"expected '}'">;
def err_expected_greater : Error<"expected '>'">;
def err_expected_ggg : Error<"expected '>>>'">;
def err_expected_semi_declaration : Error<
"expected ';' at end of declaration">;
def err_expected_semi_decl_list : Error<
@ -186,12 +178,10 @@ def err_expected_method_body : Error<"expected method body">;
def err_invalid_token_after_toplevel_declarator : Error<
"expected ';' after top level declarator">;
def err_invalid_token_after_declarator_suggest_equal : Error<
"invalid '%0' at end of declaration; did you mean '='?">;
"invalid %0 at end of declaration; did you mean '='?">;
def err_expected_statement : Error<"expected statement">;
def err_expected_lparen_after : Error<"expected '(' after '%0'">;
def err_expected_lparen_after_id : Error<"expected '(' after %0">;
def err_expected_less_after : Error<"expected '<' after '%0'">;
def err_expected_equal_after : Error<"expected '=' after %0">;
def err_expected_comma : Error<"expected ','">;
def err_expected_lbrace_in_compound_literal : Error<
"expected '{' in compound literal">;
@ -218,7 +208,6 @@ def err_expected_semi_after_attribute_list : Error<
def err_expected_semi_after_static_assert : Error<
"expected ';' after static_assert">;
def err_expected_semi_for : Error<"expected ';' in 'for' statement specifier">;
def err_expected_colon_after : Error<"expected ':' after %0">;
def warn_missing_selector_name : Warning<
"%0 used as the name of the previous parameter rather than as part "
"of the selector">,
@ -481,9 +470,6 @@ def warn_cxx98_compat_noexcept_decl : Warning<
"noexcept specifications are incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
def err_expected_catch : Error<"expected catch">;
def err_expected_lbrace_or_comma : Error<"expected '{' or ','">;
def err_expected_rbrace_or_comma : Error<"expected '}' or ','">;
def err_expected_rsquare_or_comma : Error<"expected ']' or ','">;
def err_using_namespace_in_class : Error<
"'using namespace' is not allowed in classes">;
def err_constructor_bad_name : Error<

View File

@ -5752,7 +5752,6 @@ def err_incomplete_type_used_in_type_trait_expr : Error<
def err_dimension_expr_not_constant_integer : Error<
"dimension expression does not evaluate to a constant unsigned int">;
def err_expected_ident_or_lparen : Error<"expected identifier or '('">;
def err_typecheck_cond_incompatible_operands_null : Error<
"non-pointer operand type %0 incompatible with %select{NULL|nullptr}1">;

View File

@ -15,12 +15,14 @@
#ifndef LLVM_CLANG_TOKENKINDS_H
#define LLVM_CLANG_TOKENKINDS_H
#include "llvm/Support/Compiler.h"
namespace clang {
namespace tok {
/// \brief Provides a simple uniform namespace for tokens from all C languages.
enum TokenKind {
enum TokenKind LLVM_ENUM_INT_TYPE(unsigned) {
#define TOK(X) X,
#include "clang/Basic/TokenKinds.def"
NUM_TOKENS

View File

@ -342,16 +342,16 @@ private:
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok = false) {
if (isTokenParen())
return ConsumeParen();
else if (isTokenBracket())
if (isTokenBracket())
return ConsumeBracket();
else if (isTokenBrace())
if (isTokenBrace())
return ConsumeBrace();
else if (isTokenStringLiteral())
if (isTokenStringLiteral())
return ConsumeStringToken();
else if (ConsumeCodeCompletionTok && Tok.is(tok::code_completion))
return ConsumeCodeCompletionToken();
else
return ConsumeToken();
if (Tok.is(tok::code_completion))
return ConsumeCodeCompletionTok ? ConsumeCodeCompletionToken()
: handleUnexpectedCodeCompletionToken();
return ConsumeToken();
}
/// ConsumeParen - This consume method keeps the paren count up-to-date.

View File

@ -639,6 +639,16 @@ static void HandlePluralModifier(const Diagnostic &DInfo, unsigned ValNo,
}
}
/// \brief Returns the friendly name for a token kind that will / appear
// without quotes in diagnostic messages.
static const char *getTokenNameForDiagnostic(tok::TokenKind Kind) {
switch (Kind) {
case tok::identifier:
return "identifier";
default:
return 0;
}
}
/// FormatDiagnostic - Format this diagnostic into a string, substituting the
/// formal arguments into the %0 slots. The result is appended onto the Str
@ -812,6 +822,25 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
}
break;
}
// ---- TOKEN SPELLINGS ----
case DiagnosticsEngine::ak_tokenkind: {
tok::TokenKind Kind = static_cast<tok::TokenKind>(getRawArg(ArgNo));
assert(ModifierLen == 0 && "No modifiers for token kinds yet");
llvm::raw_svector_ostream Out(OutStr);
if (const char *S = getTokenNameForDiagnostic(Kind))
// Unquoted translatable token name.
Out << S;
else if (const char *S = tok::getTokenSimpleSpelling(Kind))
// Quoted token spelling, currently only covers punctuators.
Out << '\'' << S << '\'';
else if (const char *S = tok::getTokenName(Kind))
// Debug name, shouldn't appear in user-facing diagnostics.
Out << '<' << S << '>';
else
Out << "(null)";
break;
}
// ---- NAMES and TYPES ----
case DiagnosticsEngine::ak_identifierinfo: {
const IdentifierInfo *II = getArgIdentifier(ArgNo);

View File

@ -131,7 +131,7 @@ static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
if (PeekTok.isNot(tok::r_paren)) {
PP.Diag(PeekTok.getLocation(), diag::err_pp_missing_rparen) << "defined";
PP.Diag(LParenLoc, diag::note_matching) << "(";
PP.Diag(LParenLoc, diag::note_matching) << tok::l_paren;
return true;
}
// Consume the ).
@ -342,7 +342,7 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
if (PeekTok.isNot(tok::r_paren)) {
PP.Diag(PeekTok.getLocation(), diag::err_pp_expected_rparen)
<< Result.getRange();
PP.Diag(Start, diag::note_matching) << "(";
PP.Diag(Start, diag::note_matching) << tok::l_paren;
return true;
}
DT.State = DefinedTracker::Unknown;
@ -682,7 +682,7 @@ static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec,
if (PeekTok.isNot(tok::colon)) {
PP.Diag(PeekTok.getLocation(), diag::err_expected_colon)
<< LHS.getRange(), RHS.getRange();
PP.Diag(OpLoc, diag::note_matching) << "?";
PP.Diag(OpLoc, diag::note_matching) << tok::question;
return true;
}
// Consume the :.

View File

@ -1144,7 +1144,7 @@ static bool EvaluateHasIncludeCommon(Token &Tok,
if (Tok.isNot(tok::r_paren)) {
PP.Diag(PP.getLocForEndOfToken(FilenameLoc), diag::err_pp_missing_rparen)
<< II->getName();
PP.Diag(LParenLoc, diag::note_matching) << "(";
PP.Diag(LParenLoc, diag::note_matching) << tok::l_paren;
return false;
}
@ -1226,7 +1226,7 @@ static bool EvaluateBuildingModule(Token &Tok,
// Ensure we have a trailing ).
if (Tok.isNot(tok::r_paren)) {
PP.Diag(Tok.getLocation(), diag::err_pp_missing_rparen) << II->getName();
PP.Diag(LParenLoc, diag::note_matching) << "(";
PP.Diag(LParenLoc, diag::note_matching) << tok::l_paren;
return false;
}

View File

@ -670,7 +670,7 @@ bool Parser::ConsumeAndStoreFunctionPrologue(CachedTokens &Toks) {
/*StopAtSemi=*/true,
/*ConsumeFinalToken=*/false);
if (Tok.isNot(tok::l_brace))
return Diag(Tok.getLocation(), diag::err_expected_lbrace);
return Diag(Tok.getLocation(), diag::err_expected) << tok::l_brace;
Toks.push_back(Tok);
ConsumeBrace();
@ -703,8 +703,8 @@ bool Parser::ConsumeAndStoreFunctionPrologue(CachedTokens &Toks) {
Toks.push_back(Tok);
ConsumeParen();
if (!ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/true)) {
Diag(Tok.getLocation(), diag::err_expected_rparen);
Diag(OpenLoc, diag::note_matching) << "(";
Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
Diag(OpenLoc, diag::note_matching) << tok::l_paren;
return true;
}
}
@ -751,13 +751,15 @@ bool Parser::ConsumeAndStoreFunctionPrologue(CachedTokens &Toks) {
/*ConsumeFinalToken=*/false)) {
// We're not just missing the initializer, we're also missing the
// function body!
return Diag(Tok.getLocation(), diag::err_expected_lbrace);
return Diag(Tok.getLocation(), diag::err_expected) << tok::l_brace;
}
} else if (Tok.isNot(tok::l_paren) && Tok.isNot(tok::l_brace)) {
// We found something weird in a mem-initializer-id.
return Diag(Tok.getLocation(), getLangOpts().CPlusPlus11
? diag::err_expected_lparen_or_lbrace
: diag::err_expected_lparen);
if (getLangOpts().CPlusPlus11)
return Diag(Tok.getLocation(), diag::err_expected_either)
<< tok::l_paren << tok::l_brace;
else
return Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
}
tok::TokenKind kind = Tok.getKind();
@ -779,11 +781,10 @@ bool Parser::ConsumeAndStoreFunctionPrologue(CachedTokens &Toks) {
// Grab the initializer (or the subexpression of the template argument).
// FIXME: If we support lambdas here, we'll need to set StopAtSemi to false
// if we might be inside the braces of a lambda-expression.
if (!ConsumeAndStoreUntil(IsLParen ? tok::r_paren : tok::r_brace,
Toks, /*StopAtSemi=*/true)) {
Diag(Tok, IsLParen ? diag::err_expected_rparen :
diag::err_expected_rbrace);
Diag(OpenLoc, diag::note_matching) << (IsLParen ? "(" : "{");
tok::TokenKind CloseKind = IsLParen ? tok::r_paren : tok::r_brace;
if (!ConsumeAndStoreUntil(CloseKind, Toks, /*StopAtSemi=*/true)) {
Diag(Tok, diag::err_expected) << CloseKind;
Diag(OpenLoc, diag::note_matching) << kind;
return true;
}
@ -817,7 +818,8 @@ bool Parser::ConsumeAndStoreFunctionPrologue(CachedTokens &Toks) {
ConsumeBrace();
return false;
} else if (!MightBeTemplateArgument) {
return Diag(Tok.getLocation(), diag::err_expected_lbrace_or_comma);
return Diag(Tok.getLocation(), diag::err_expected_either) << tok::l_brace
<< tok::comma;
}
}
}

View File

@ -813,7 +813,7 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
// Opening '('.
BalancedDelimiterTracker T(*this, tok::l_paren);
if (T.consumeOpen()) {
Diag(Tok, diag::err_expected_lparen);
Diag(Tok, diag::err_expected) << tok::l_paren;
return;
}
@ -865,8 +865,7 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
}
if (Tok.isNot(tok::equal)) {
Diag(Tok, diag::err_expected_equal_after)
<< Keyword;
Diag(Tok, diag::err_expected_after) << Keyword << tok::equal;
SkipUntil(tok::r_paren, StopAtSemi);
return;
}
@ -978,7 +977,7 @@ void Parser::ParseObjCBridgeRelatedAttribute(IdentifierInfo &ObjCBridgeRelated,
// Opening '('.
BalancedDelimiterTracker T(*this, tok::l_paren);
if (T.consumeOpen()) {
Diag(Tok, diag::err_expected_lparen);
Diag(Tok, diag::err_expected) << tok::l_paren;
return;
}
@ -990,7 +989,7 @@ void Parser::ParseObjCBridgeRelatedAttribute(IdentifierInfo &ObjCBridgeRelated,
}
IdentifierLoc *RelatedClass = ParseIdentifierLoc();
if (!TryConsumeToken(tok::comma)) {
Diag(Tok, diag::err_expected_comma);
Diag(Tok, diag::err_expected) << tok::comma;
SkipUntil(tok::r_paren, StopAtSemi);
return;
}
@ -1009,7 +1008,7 @@ void Parser::ParseObjCBridgeRelatedAttribute(IdentifierInfo &ObjCBridgeRelated,
if (Tok.is(tok::colon))
Diag(Tok, diag::err_objcbridge_related_selector_name);
else
Diag(Tok, diag::err_expected_comma);
Diag(Tok, diag::err_expected) << tok::comma;
SkipUntil(tok::r_paren, StopAtSemi);
return;
}
@ -1019,7 +1018,7 @@ void Parser::ParseObjCBridgeRelatedAttribute(IdentifierInfo &ObjCBridgeRelated,
if (Tok.is(tok::identifier))
InstanceMethod = ParseIdentifierLoc();
else if (Tok.isNot(tok::r_paren)) {
Diag(Tok, diag::err_expected_rparen);
Diag(Tok, diag::err_expected) << tok::r_paren;
SkipUntil(tok::r_paren, StopAtSemi);
return;
}
@ -1271,14 +1270,14 @@ void Parser::ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName,
T.consumeOpen();
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident);
Diag(Tok, diag::err_expected) << tok::identifier;
T.skipToEnd();
return;
}
IdentifierLoc *ArgumentKind = ParseIdentifierLoc();
if (Tok.isNot(tok::comma)) {
Diag(Tok, diag::err_expected_comma);
Diag(Tok, diag::err_expected) << tok::comma;
T.skipToEnd();
return;
}
@ -1295,7 +1294,7 @@ void Parser::ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName,
bool MustBeNull = false;
while (TryConsumeToken(tok::comma)) {
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident);
Diag(Tok, diag::err_expected) << tok::identifier;
T.skipToEnd();
return;
}
@ -3471,7 +3470,7 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
ConsumeToken();
ExpectAndConsume(tok::l_paren, diag::err_expected_lparen);
if (!Tok.is(tok::identifier)) {
Diag(Tok, diag::err_expected_ident);
Diag(Tok, diag::err_expected) << tok::identifier;
SkipUntil(tok::semi);
continue;
}
@ -3612,7 +3611,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
return;
if (SS.isSet() && Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident);
Diag(Tok, diag::err_expected) << tok::identifier;
if (Tok.isNot(tok::l_brace)) {
// Has no name and is not a definition.
// Skip the rest of this declarator, up until the comma or semicolon.
@ -3625,7 +3624,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
// Must have either 'enum name' or 'enum {...}'.
if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) &&
!(AllowFixedUnderlyingType && Tok.is(tok::colon))) {
Diag(Tok, diag::err_expected_ident_lbrace);
Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
// Skip the rest of this declarator, up until the comma or semicolon.
SkipUntil(tok::comma, StopAtSemi);
@ -4924,7 +4923,7 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
<< getLangOpts().CPlusPlus;
}
} else
Diag(Tok, diag::err_expected_ident_lparen);
Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_paren;
D.SetIdentifier(0, Tok.getLocation());
D.setInvalidType(true);
}
@ -5316,7 +5315,7 @@ void Parser::ParseFunctionDeclaratorIdentifierList(
do {
// If this isn't an identifier, report the error and skip until ')'.
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident);
Diag(Tok, diag::err_expected) << tok::identifier;
SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch);
// Forget we parsed anything.
ParamInfo.clear();

View File

@ -91,7 +91,7 @@ Decl *Parser::ParseNamespace(unsigned Context,
if (Tok.is(tok::equal)) {
if (Ident == 0) {
Diag(Tok, diag::err_expected_ident);
Diag(Tok, diag::err_expected) << tok::identifier;
// Skip to end of the definition and eat the ';'.
SkipUntil(tok::semi);
return 0;
@ -111,8 +111,12 @@ Decl *Parser::ParseNamespace(unsigned Context,
Diag(ExtraNamespaceLoc[0], diag::err_nested_namespaces_with_double_colon)
<< SourceRange(ExtraNamespaceLoc.front(), ExtraIdentLoc.back());
}
Diag(Tok, Ident ? diag::err_expected_lbrace :
diag::err_expected_ident_lbrace);
if (Ident)
Diag(Tok, diag::err_expected) << tok::l_brace;
else
Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
return 0;
}
@ -649,7 +653,7 @@ Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){
BalancedDelimiterTracker T(*this, tok::l_paren);
if (T.consumeOpen()) {
Diag(Tok, diag::err_expected_lparen);
Diag(Tok, diag::err_expected) << tok::l_paren;
SkipMalformedDecl();
return 0;
}
@ -1202,7 +1206,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
DS.SetTypeSpecError();
if (SS.isSet())
if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
Diag(Tok, diag::err_expected_ident);
Diag(Tok, diag::err_expected) << tok::identifier;
}
TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;
@ -2798,7 +2802,8 @@ void Parser::ParseConstructorInitializer(Decl *ConstructorDecl) {
<< FixItHint::CreateInsertion(Loc, ", ");
} else {
// Skip over garbage, until we get to '{'. Don't eat the '{'.
Diag(Tok.getLocation(), diag::err_expected_lbrace_or_comma);
Diag(Tok.getLocation(), diag::err_expected_either) << tok::l_brace
<< tok::comma;
SkipUntil(tok::l_brace, StopAtSemi | StopBeforeMatch);
break;
}
@ -2896,9 +2901,10 @@ Parser::MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {
T.getCloseLocation(), EllipsisLoc);
}
Diag(Tok, getLangOpts().CPlusPlus11 ? diag::err_expected_lparen_or_lbrace
: diag::err_expected_lparen);
return true;
if (getLangOpts().CPlusPlus11)
return Diag(Tok, diag::err_expected_either) << tok::l_paren << tok::l_brace;
else
return Diag(Tok, diag::err_expected) << tok::l_paren;
}
/// \brief Parse a C++ exception-specification if present (C++0x [except.spec]).
@ -3261,7 +3267,7 @@ void Parser::ParseCXX11AttributeSpecifier(ParsedAttributes &attrs,
AttrName = TryParseCXX11AttributeIdentifier(AttrLoc);
if (!AttrName) {
Diag(Tok.getLocation(), diag::err_expected_ident);
Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
SkipUntil(tok::r_square, tok::comma, StopAtSemi | StopBeforeMatch);
continue;
}
@ -3393,7 +3399,7 @@ void Parser::ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,
BalancedDelimiterTracker Braces(*this, tok::l_brace);
if (Braces.consumeOpen()) {
Diag(Tok, diag::err_expected_lbrace);
Diag(Tok, diag::err_expected) << tok::l_brace;
return;
}

View File

@ -294,7 +294,7 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
Diag(Tok, diag::err_expected_colon)
<< FixItHint::CreateInsertion(FILoc, FIText);
Diag(OpToken, diag::note_matching) << "?";
Diag(OpToken, diag::note_matching) << tok::question;
ColonLoc = Tok.getLocation();
}
}
@ -915,7 +915,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
case tok::ampamp: { // unary-expression: '&&' identifier
SourceLocation AmpAmpLoc = ConsumeToken();
if (Tok.isNot(tok::identifier))
return ExprError(Diag(Tok, diag::err_expected_ident));
return ExprError(Diag(Tok, diag::err_expected) << tok::identifier);
if (getCurScope()->getFnParent() == 0)
return ExprError(Diag(Tok, diag::err_address_of_label_outside_fn));
@ -1289,8 +1289,8 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
SkipUntil(tok::greatergreatergreater, StopAtSemi);
} else {
// There was an error closing the brackets
Diag(Tok, diag::err_expected_ggg);
Diag(OpenLoc, diag::note_matching) << "<<<";
Diag(Tok, diag::err_expected) << tok::greatergreatergreater;
Diag(OpenLoc, diag::note_matching) << tok::lesslessless;
SkipUntil(tok::greatergreatergreater, StopAtSemi);
LHS = ExprError();
}
@ -1512,7 +1512,8 @@ Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok,
isCastExpr = false;
if (OpTok.is(tok::kw_typeof) && !getLangOpts().CPlusPlus) {
Diag(Tok,diag::err_expected_lparen_after_id) << OpTok.getIdentifierInfo();
Diag(Tok, diag::err_expected_after) << OpTok.getIdentifierInfo()
<< tok::l_paren;
return ExprError();
}
@ -1684,8 +1685,8 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
// All of these start with an open paren.
if (Tok.isNot(tok::l_paren))
return ExprError(Diag(Tok, diag::err_expected_lparen_after_id)
<< BuiltinII);
return ExprError(Diag(Tok, diag::err_expected_after) << BuiltinII
<< tok::l_paren);
BalancedDelimiterTracker PT(*this, tok::l_paren);
PT.consumeOpen();
@ -1703,7 +1704,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
TypeResult Ty = ParseTypeName();
if (Tok.isNot(tok::r_paren)) {
Diag(Tok, diag::err_expected_rparen);
Diag(Tok, diag::err_expected) << tok::r_paren;
Expr = ExprError();
}
@ -1726,7 +1727,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
// We must have at least one identifier here.
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident);
Diag(Tok, diag::err_expected) << tok::identifier;
SkipUntil(tok::r_paren, StopAtSemi);
return ExprError();
}
@ -1748,7 +1749,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
Comps.back().LocStart = ConsumeToken();
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident);
Diag(Tok, diag::err_expected) << tok::identifier;
SkipUntil(tok::r_paren, StopAtSemi);
return ExprError();
}
@ -1814,7 +1815,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
return Expr2;
}
if (Tok.isNot(tok::r_paren)) {
Diag(Tok, diag::err_expected_rparen);
Diag(Tok, diag::err_expected) << tok::r_paren;
return ExprError();
}
Res = Actions.ActOnChooseExpr(StartLoc, Cond.take(), Expr1.take(),
@ -1840,7 +1841,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
// Attempt to consume the r-paren.
if (Tok.isNot(tok::r_paren)) {
Diag(Tok, diag::err_expected_rparen);
Diag(Tok, diag::err_expected) << tok::r_paren;
SkipUntil(tok::r_paren, StopAtSemi);
return ExprError();
}
@ -1868,7 +1869,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
// Attempt to consume the r-paren.
if (Tok.isNot(tok::r_paren)) {
Diag(Tok, diag::err_expected_rparen);
Diag(Tok, diag::err_expected) << tok::r_paren;
SkipUntil(tok::r_paren, StopAtSemi);
return ExprError();
}

View File

@ -1187,7 +1187,7 @@ ExprResult Parser::ParseCXXCasts() {
SourceLocation RAngleBracketLoc = Tok.getLocation();
if (ExpectAndConsume(tok::greater, diag::err_expected_greater))
return ExprError(Diag(LAngleBracketLoc, diag::note_matching) << "<");
return ExprError(Diag(LAngleBracketLoc, diag::note_matching) << tok::less);
SourceLocation LParenLoc, RParenLoc;
BalancedDelimiterTracker T(*this, tok::l_paren);
@ -2163,7 +2163,7 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
SuffixLoc = ConsumeToken();
TokLocs.push_back(SuffixLoc);
} else {
Diag(Tok.getLocation(), diag::err_expected_ident);
Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
return true;
}

View File

@ -493,7 +493,7 @@ bool Parser::ParseMicrosoftIfExistsBraceInitializer(ExprVector &InitExprs,
BalancedDelimiterTracker Braces(*this, tok::l_brace);
if (Braces.consumeOpen()) {
Diag(Tok, diag::err_expected_lbrace);
Diag(Tok, diag::err_expected) << tok::l_brace;
return false;
}

View File

@ -107,7 +107,7 @@ Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) {
while (1) {
MaybeSkipAttributes(tok::objc_class);
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident);
Diag(Tok, diag::err_expected) << tok::identifier;
SkipUntil(tok::semi);
return Actions.ConvertDeclToDeclGroup(0);
}
@ -195,7 +195,8 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
MaybeSkipAttributes(tok::objc_interface);
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident); // missing class or category name.
Diag(Tok, diag::err_expected)
<< tok::identifier; // missing class or category name.
return 0;
}
@ -222,7 +223,8 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
categoryLoc = ConsumeToken();
}
else if (!getLangOpts().ObjC2) {
Diag(Tok, diag::err_expected_ident); // missing category name.
Diag(Tok, diag::err_expected)
<< tok::identifier; // missing category name.
return 0;
}
@ -274,7 +276,8 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
}
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident); // missing super class name.
Diag(Tok, diag::err_expected)
<< tok::identifier; // missing super class name.
return 0;
}
superClassId = Tok.getIdentifierInfo();
@ -1086,7 +1089,8 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
}
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident); // missing argument name.
Diag(Tok, diag::err_expected)
<< tok::identifier; // missing argument name.
break;
}
@ -1198,7 +1202,7 @@ ParseObjCProtocolReferences(SmallVectorImpl<Decl *> &Protocols,
}
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident);
Diag(Tok, diag::err_expected) << tok::identifier;
SkipUntil(tok::greater, StopAtSemi);
return true;
}
@ -1412,7 +1416,7 @@ Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
MaybeSkipAttributes(tok::objc_protocol);
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident); // missing protocol name.
Diag(Tok, diag::err_expected) << tok::identifier; // missing protocol name.
return DeclGroupPtrTy();
}
// Save the protocol name, then consume it.
@ -1436,7 +1440,7 @@ Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
while (1) {
ConsumeToken(); // the ','
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident);
Diag(Tok, diag::err_expected) << tok::identifier;
SkipUntil(tok::semi);
return DeclGroupPtrTy();
}
@ -1505,7 +1509,8 @@ Parser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc) {
MaybeSkipAttributes(tok::objc_implementation);
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident); // missing class or category name.
Diag(Tok, diag::err_expected)
<< tok::identifier; // missing class or category name.
return DeclGroupPtrTy();
}
// We have a class or category name - consume it.
@ -1529,11 +1534,12 @@ Parser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc) {
categoryId = Tok.getIdentifierInfo();
categoryLoc = ConsumeToken();
} else {
Diag(Tok, diag::err_expected_ident); // missing category name.
Diag(Tok, diag::err_expected)
<< tok::identifier; // missing category name.
return DeclGroupPtrTy();
}
if (Tok.isNot(tok::r_paren)) {
Diag(Tok, diag::err_expected_rparen);
Diag(Tok, diag::err_expected) << tok::r_paren;
SkipUntil(tok::r_paren); // don't stop at ';'
return DeclGroupPtrTy();
}
@ -1556,7 +1562,8 @@ Parser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc) {
// We have a super class
ConsumeToken();
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident); // missing super class name.
Diag(Tok, diag::err_expected)
<< tok::identifier; // missing super class name.
return DeclGroupPtrTy();
}
superClassId = Tok.getIdentifierInfo();
@ -1655,13 +1662,13 @@ Decl *Parser::ParseObjCAtAliasDeclaration(SourceLocation atLoc) {
"ParseObjCAtAliasDeclaration(): Expected @compatibility_alias");
ConsumeToken(); // consume compatibility_alias
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident);
Diag(Tok, diag::err_expected) << tok::identifier;
return 0;
}
IdentifierInfo *aliasId = Tok.getIdentifierInfo();
SourceLocation aliasLoc = ConsumeToken(); // consume alias-name
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident);
Diag(Tok, diag::err_expected) << tok::identifier;
return 0;
}
IdentifierInfo *classId = Tok.getIdentifierInfo();
@ -1716,7 +1723,7 @@ Decl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
}
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident);
Diag(Tok, diag::err_expected) << tok::identifier;
break;
}
propertyIvar = Tok.getIdentifierInfo();
@ -1751,7 +1758,7 @@ Decl *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
}
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident);
Diag(Tok, diag::err_expected) << tok::identifier;
SkipUntil(tok::semi);
return 0;
}
@ -1806,7 +1813,7 @@ Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) {
ConsumeParen(); // ')'
} else {
if (!operand.isInvalid())
Diag(Tok, diag::err_expected_rparen);
Diag(Tok, diag::err_expected) << tok::r_paren;
// Skip forward until we see a left brace, but don't consume it.
SkipUntil(tok::l_brace, StopAtSemi | StopBeforeMatch);
@ -1815,7 +1822,7 @@ Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) {
// Require a compound statement.
if (Tok.isNot(tok::l_brace)) {
if (!operand.isInvalid())
Diag(Tok, diag::err_expected_lbrace);
Diag(Tok, diag::err_expected) << tok::l_brace;
return StmtError();
}
@ -1855,7 +1862,7 @@ StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
ConsumeToken(); // consume try
if (Tok.isNot(tok::l_brace)) {
Diag(Tok, diag::err_expected_lbrace);
Diag(Tok, diag::err_expected) << tok::l_brace;
return StmtError();
}
StmtVector CatchStmts;
@ -1905,7 +1912,7 @@ StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
if (Tok.is(tok::l_brace))
CatchBody = ParseCompoundStatementBody();
else
Diag(Tok, diag::err_expected_lbrace);
Diag(Tok, diag::err_expected) << tok::l_brace;
if (CatchBody.isInvalid())
CatchBody = Actions.ActOnNullStmt(Tok.getLocation());
@ -1931,7 +1938,7 @@ StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
if (Tok.is(tok::l_brace))
FinallyBody = ParseCompoundStatementBody();
else
Diag(Tok, diag::err_expected_lbrace);
Diag(Tok, diag::err_expected) << tok::l_brace;
if (FinallyBody.isInvalid())
FinallyBody = Actions.ActOnNullStmt(Tok.getLocation());
FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc,
@ -1957,7 +1964,7 @@ StmtResult
Parser::ParseObjCAutoreleasePoolStmt(SourceLocation atLoc) {
ConsumeToken(); // consume autoreleasepool
if (Tok.isNot(tok::l_brace)) {
Diag(Tok, diag::err_expected_lbrace);
Diag(Tok, diag::err_expected) << tok::l_brace;
return StmtError();
}
// Enter a scope to hold everything within the compound stmt. Compound
@ -2572,7 +2579,7 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
KeyExprs.push_back(Res.release());
}
} else if (!selIdent) {
Diag(Tok, diag::err_expected_ident); // missing selector name.
Diag(Tok, diag::err_expected) << tok::identifier; // missing selector name.
// We must manually skip to a ']', otherwise the expression skipper will
// stop at the ']' when it skips to the ';'. We want it to skip beyond
@ -2730,7 +2737,8 @@ ExprResult Parser::ParseObjCArrayLiteral(SourceLocation AtLoc) {
if (Tok.is(tok::comma))
ConsumeToken(); // Eat the ','.
else if (Tok.isNot(tok::r_square))
return ExprError(Diag(Tok, diag::err_expected_rsquare_or_comma));
return ExprError(Diag(Tok, diag::err_expected_either) << tok::r_square
<< tok::comma);
}
SourceLocation EndLoc = ConsumeBracket(); // location of ']'
MultiExprArg Args(ElementExprs);
@ -2755,10 +2763,8 @@ ExprResult Parser::ParseObjCDictionaryLiteral(SourceLocation AtLoc) {
}
}
if (Tok.is(tok::colon)) {
ConsumeToken();
} else {
Diag(Tok, diag::err_expected_colon);
if (!TryConsumeToken(tok::colon)) {
Diag(Tok, diag::err_expected) << tok::colon;
SkipUntil(tok::r_brace, StopAtSemi);
return ExprError();
}
@ -2774,9 +2780,9 @@ ExprResult Parser::ParseObjCDictionaryLiteral(SourceLocation AtLoc) {
// Parse the ellipsis that designates this as a pack expansion.
SourceLocation EllipsisLoc;
if (Tok.is(tok::ellipsis) && getLangOpts().CPlusPlus)
EllipsisLoc = ConsumeToken();
if (getLangOpts().CPlusPlus)
TryConsumeToken(tok::ellipsis, EllipsisLoc);
// We have a valid expression. Collect it in a vector so we can
// build the argument list.
ObjCDictionaryElement Element = {
@ -2787,7 +2793,8 @@ ExprResult Parser::ParseObjCDictionaryLiteral(SourceLocation AtLoc) {
if (Tok.is(tok::comma))
ConsumeToken(); // Eat the ','.
else if (Tok.isNot(tok::r_brace))
return ExprError(Diag(Tok, diag::err_expected_rbrace_or_comma));
return ExprError(Diag(Tok, diag::err_expected_either) << tok::r_brace
<< tok::comma);
}
SourceLocation EndLoc = ConsumeBrace();
@ -2834,7 +2841,7 @@ Parser::ParseObjCProtocolExpression(SourceLocation AtLoc) {
T.consumeOpen();
if (Tok.isNot(tok::identifier))
return ExprError(Diag(Tok, diag::err_expected_ident));
return ExprError(Diag(Tok, diag::err_expected) << tok::identifier);
IdentifierInfo *protocolId = Tok.getIdentifierInfo();
SourceLocation ProtoIdLoc = ConsumeToken();
@ -2869,7 +2876,7 @@ ExprResult Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) {
IdentifierInfo *SelIdent = ParseObjCSelectorPiece(sLoc);
if (!SelIdent && // missing selector name.
Tok.isNot(tok::colon) && Tok.isNot(tok::coloncolon))
return ExprError(Diag(Tok, diag::err_expected_ident));
return ExprError(Diag(Tok, diag::err_expected) << tok::identifier);
KeyIdents.push_back(SelIdent);
unsigned nColons = 0;

View File

@ -225,8 +225,9 @@ bool Parser::ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind,
IsCorrect = false;
SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
StopBeforeMatch);
Diag(PrevTok.getLocation(), diag::err_expected_ident)
<< SourceRange(PrevTok.getLocation(), PrevTokLocation);
Diag(PrevTok.getLocation(), diag::err_expected)
<< tok::identifier
<< SourceRange(PrevTok.getLocation(), PrevTokLocation);
} else {
DeclarationNameInfo NameInfo = Actions.GetNameFromUnqualifiedId(Name);
ExprResult Res = Actions.ActOnOpenMPIdExpression(getCurScope(), SS,
@ -241,7 +242,7 @@ bool Parser::ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind,
}
if (NoIdentIsFound) {
Diag(Tok, diag::err_expected_ident);
Diag(Tok, diag::err_expected) << tok::identifier;
IsCorrect = false;
}

View File

@ -130,7 +130,7 @@ StmtResult Parser::HandlePragmaCaptured()
ConsumeToken();
if (Tok.isNot(tok::l_brace)) {
PP.Diag(Tok, diag::err_expected_lbrace);
PP.Diag(Tok, diag::err_expected) << tok::l_brace;
return StmtError();
}
@ -815,7 +815,7 @@ void PragmaDetectMismatchHandler::HandlePragma(Preprocessor &PP,
SourceLocation CommentLoc = Tok.getLocation();
PP.Lex(Tok);
if (Tok.isNot(tok::l_paren)) {
PP.Diag(CommentLoc, diag::err_expected_lparen);
PP.Diag(CommentLoc, diag::err_expected) << tok::l_paren;
return;
}
@ -838,7 +838,7 @@ void PragmaDetectMismatchHandler::HandlePragma(Preprocessor &PP,
return;
if (Tok.isNot(tok::r_paren)) {
PP.Diag(Tok.getLocation(), diag::err_expected_rparen);
PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
return;
}
PP.Lex(Tok); // Eat the r_paren.

View File

@ -412,7 +412,7 @@ StmtResult Parser::ParseSEHTryBlock() {
///
StmtResult Parser::ParseSEHTryBlockCommon(SourceLocation TryLoc) {
if(Tok.isNot(tok::l_brace))
return StmtError(Diag(Tok,diag::err_expected_lbrace));
return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
StmtResult TryBlock(ParseCompoundStatement());
if(TryBlock.isInvalid())
@ -624,10 +624,8 @@ StmtResult Parser::ParseCaseStatement(bool MissingCase, ExprResult Expr) {
// GNU case range extension.
SourceLocation DotDotDotLoc;
ExprResult RHS;
if (Tok.is(tok::ellipsis)) {
Diag(Tok, diag::ext_gnu_case_range);
DotDotDotLoc = ConsumeToken();
if (TryConsumeToken(tok::ellipsis, DotDotDotLoc)) {
Diag(DotDotDotLoc, diag::ext_gnu_case_range);
RHS = ParseConstantExpression();
if (RHS.isInvalid()) {
SkipUntil(tok::colon, StopAtSemi);
@ -637,18 +635,17 @@ StmtResult Parser::ParseCaseStatement(bool MissingCase, ExprResult Expr) {
ColonProtection.restore();
if (Tok.is(tok::colon)) {
ColonLoc = ConsumeToken();
if (TryConsumeToken(tok::colon, ColonLoc)) {
// Treat "case blah;" as a typo for "case blah:".
} else if (Tok.is(tok::semi)) {
ColonLoc = ConsumeToken();
Diag(ColonLoc, diag::err_expected_colon_after) << "'case'"
<< FixItHint::CreateReplacement(ColonLoc, ":");
} else if (TryConsumeToken(tok::semi, ColonLoc)) {
Diag(ColonLoc, diag::err_expected_after)
<< "'case'" << tok::colon
<< FixItHint::CreateReplacement(ColonLoc, ":");
} else {
SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation);
Diag(ExpectedLoc, diag::err_expected_colon_after) << "'case'"
<< FixItHint::CreateInsertion(ExpectedLoc, ":");
Diag(ExpectedLoc, diag::err_expected_after)
<< "'case'" << tok::colon
<< FixItHint::CreateInsertion(ExpectedLoc, ":");
ColonLoc = ExpectedLoc;
}
@ -713,18 +710,17 @@ StmtResult Parser::ParseDefaultStatement() {
SourceLocation DefaultLoc = ConsumeToken(); // eat the 'default'.
SourceLocation ColonLoc;
if (Tok.is(tok::colon)) {
ColonLoc = ConsumeToken();
if (TryConsumeToken(tok::colon, ColonLoc)) {
// Treat "default;" as a typo for "default:".
} else if (Tok.is(tok::semi)) {
ColonLoc = ConsumeToken();
Diag(ColonLoc, diag::err_expected_colon_after) << "'default'"
<< FixItHint::CreateReplacement(ColonLoc, ":");
} else if (TryConsumeToken(tok::semi, ColonLoc)) {
Diag(ColonLoc, diag::err_expected_after)
<< "'default'" << tok::colon
<< FixItHint::CreateReplacement(ColonLoc, ":");
} else {
SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation);
Diag(ExpectedLoc, diag::err_expected_colon_after) << "'default'"
<< FixItHint::CreateInsertion(ExpectedLoc, ":");
Diag(ExpectedLoc, diag::err_expected_after)
<< "'default'" << tok::colon
<< FixItHint::CreateInsertion(ExpectedLoc, ":");
ColonLoc = ExpectedLoc;
}
@ -867,7 +863,7 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
SmallVector<Decl *, 8> DeclsInGroup;
while (1) {
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident);
Diag(Tok, diag::err_expected) << tok::identifier;
break;
}
@ -875,9 +871,8 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
SourceLocation IdLoc = ConsumeToken();
DeclsInGroup.push_back(Actions.LookupOrCreateLabel(II, IdLoc, LabelLoc));
if (!Tok.is(tok::comma))
if (!TryConsumeToken(tok::comma))
break;
ConsumeToken();
}
DeclSpec DS(AttrFactory);
@ -1346,7 +1341,7 @@ StmtResult Parser::ParseDoStatement() {
if (Tok.isNot(tok::kw_while)) {
if (!Body.isInvalid()) {
Diag(Tok, diag::err_expected_while);
Diag(DoLoc, diag::note_matching) << "do";
Diag(DoLoc, diag::note_matching) << "'do'";
SkipUntil(tok::semi, StopBeforeMatch);
}
return StmtError();
@ -1677,7 +1672,7 @@ StmtResult Parser::ParseGotoStatement() {
}
Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.take());
} else {
Diag(Tok, diag::err_expected_ident);
Diag(Tok, diag::err_expected) << tok::identifier;
return StmtError();
}
@ -2115,12 +2110,12 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) {
if (InBraces && BraceCount != savedBraceCount) {
// __asm without closing brace (this can happen at EOF).
Diag(Tok, diag::err_expected_rbrace);
Diag(LBraceLoc, diag::note_matching) << "{";
Diag(Tok, diag::err_expected) << tok::r_brace;
Diag(LBraceLoc, diag::note_matching) << tok::l_brace;
return StmtError();
} else if (NumTokensRead == 0) {
// Empty __asm.
Diag(Tok, diag::err_expected_lbrace);
Diag(Tok, diag::err_expected) << tok::l_brace;
return StmtError();
}
@ -2400,7 +2395,7 @@ bool Parser::ParseAsmOperandsOpt(SmallVectorImpl<IdentifierInfo *> &Names,
T.consumeOpen();
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident);
Diag(Tok, diag::err_expected) << tok::identifier;
SkipUntil(tok::r_paren, StopAtSemi);
return true;
}
@ -2561,7 +2556,7 @@ StmtResult Parser::ParseCXXTryBlock() {
///
StmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc, bool FnTry) {
if (Tok.isNot(tok::l_brace))
return StmtError(Diag(Tok, diag::err_expected_lbrace));
return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
// FIXME: Possible draft standard bug: attribute-specifier should be allowed?
StmtResult TryBlock(ParseCompoundStatement(/*isStmtExpr=*/false,
@ -2665,7 +2660,7 @@ StmtResult Parser::ParseCXXCatchBlock(bool FnCatch) {
return StmtError();
if (Tok.isNot(tok::l_brace))
return StmtError(Diag(Tok, diag::err_expected_lbrace));
return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
// FIXME: Possible draft standard bug: attribute-specifier should be allowed?
StmtResult Block(ParseCompoundStatement());
@ -2686,7 +2681,7 @@ void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {
// inside these braces escaping to the surrounding code.
if (Result.Behavior == IEB_Dependent) {
if (!Tok.is(tok::l_brace)) {
Diag(Tok, diag::err_expected_lbrace);
Diag(Tok, diag::err_expected) << tok::l_brace;
return;
}
@ -2706,7 +2701,7 @@ void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {
BalancedDelimiterTracker Braces(*this, tok::l_brace);
if (Braces.consumeOpen()) {
Diag(Tok, diag::err_expected_lbrace);
Diag(Tok, diag::err_expected) << tok::l_brace;
return;
}

View File

@ -496,7 +496,7 @@ Decl *Parser::ParseTypeParameter(unsigned Depth, unsigned Position) {
// Unnamed template parameter. Don't have to do anything here, just
// don't consume this token.
} else {
Diag(Tok.getLocation(), diag::err_expected_ident);
Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
return 0;
}
@ -577,7 +577,7 @@ Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) {
// Unnamed template parameter. Don't have to do anything here, just
// don't consume this token.
} else {
Diag(Tok.getLocation(), diag::err_expected_ident);
Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
return 0;
}

View File

@ -195,8 +195,11 @@ bool Parser::ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned DiagID,
}
bool Parser::ExpectAndConsumeSemi(unsigned DiagID) {
if (Tok.is(tok::semi) || Tok.is(tok::code_completion)) {
ConsumeToken();
if (TryConsumeToken(tok::semi))
return false;
if (Tok.is(tok::code_completion)) {
handleUnexpectedCodeCompletionToken();
return false;
}
@ -310,7 +313,7 @@ bool Parser::SkipUntil(ArrayRef<tok::TokenKind> Toks, SkipUntilFlags Flags) {
case tok::code_completion:
if (!HasFlagsSet(Flags, StopAtCodeCompletion))
ConsumeToken();
handleUnexpectedCodeCompletionToken();
return false;
case tok::l_paren:
@ -1813,8 +1816,8 @@ bool Parser::isTokenEqualOrEqualTypo() {
case tok::pipeequal: // |=
case tok::equalequal: // ==
Diag(Tok, diag::err_invalid_token_after_declarator_suggest_equal)
<< getTokenSimpleSpelling(Kind)
<< FixItHint::CreateReplacement(SourceRange(Tok.getLocation()), "=");
<< Kind
<< FixItHint::CreateReplacement(SourceRange(Tok.getLocation()), "=");
case tok::equal:
return true;
}
@ -1943,7 +1946,7 @@ void Parser::ParseMicrosoftIfExistsExternalDeclaration() {
BalancedDelimiterTracker Braces(*this, tok::l_brace);
if (Braces.consumeOpen()) {
Diag(Tok, diag::err_expected_lbrace);
Diag(Tok, diag::err_expected) << tok::l_brace;
return;
}
@ -2044,17 +2047,9 @@ bool BalancedDelimiterTracker::expectAndConsume(unsigned DiagID,
bool BalancedDelimiterTracker::diagnoseMissingClose() {
assert(!P.Tok.is(Close) && "Should have consumed closing delimiter");
const char *LHSName = "unknown";
diag::kind DID;
switch (Close) {
default: llvm_unreachable("Unexpected balanced token");
case tok::r_paren : LHSName = "("; DID = diag::err_expected_rparen; break;
case tok::r_brace : LHSName = "{"; DID = diag::err_expected_rbrace; break;
case tok::r_square: LHSName = "["; DID = diag::err_expected_rsquare; break;
}
P.Diag(P.Tok, DID);
P.Diag(LOpen, diag::note_matching) << LHSName;
P.Diag(P.Tok, diag::err_expected) << Close;
P.Diag(LOpen, diag::note_matching) << Kind;
// If we're not already at some kind of closing bracket, skip to our closing
// token.

View File

@ -1699,7 +1699,8 @@ ActOnClassPropertyRefExpr(IdentifierInfo &receiverName,
}
if (IFace == 0) {
Diag(receiverNameLoc, diag::err_expected_ident_or_lparen);
Diag(receiverNameLoc, diag::err_expected_either) << tok::identifier
<< tok::l_paren;
return ExprError();
}
}