From af9a02c0cdaafab155de9b2f43bfad33a28429c3 Mon Sep 17 00:00:00 2001 From: Alp Toker Date: Tue, 24 Dec 2013 09:48:30 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@197972 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/Diagnostic.h | 15 ++++ include/clang/Basic/DiagnosticCommonKinds.td | 6 +- include/clang/Basic/DiagnosticParseKinds.td | 16 +---- include/clang/Basic/DiagnosticSemaKinds.td | 1 - include/clang/Basic/TokenKinds.h | 4 +- include/clang/Parse/Parser.h | 14 ++-- lib/Basic/Diagnostic.cpp | 29 ++++++++ lib/Lex/PPExpressions.cpp | 6 +- lib/Lex/PPMacroExpansion.cpp | 4 +- lib/Parse/ParseCXXInlineMethods.cpp | 28 ++++---- lib/Parse/ParseDecl.cpp | 29 ++++---- lib/Parse/ParseDeclCXX.cpp | 28 +++++--- lib/Parse/ParseExpr.cpp | 27 +++---- lib/Parse/ParseExprCXX.cpp | 4 +- lib/Parse/ParseInit.cpp | 2 +- lib/Parse/ParseObjc.cpp | 75 +++++++++++--------- lib/Parse/ParseOpenMP.cpp | 7 +- lib/Parse/ParsePragma.cpp | 6 +- lib/Parse/ParseStmt.cpp | 67 ++++++++--------- lib/Parse/ParseTemplate.cpp | 4 +- lib/Parse/Parser.cpp | 29 ++++---- lib/Sema/SemaExprObjC.cpp | 3 +- 22 files changed, 223 insertions(+), 181 deletions(-) diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h index 4eb080601b..2b0b3f9b28 100644 --- a/include/clang/Basic/Diagnostic.h +++ b/include/clang/Basic/Diagnostic.h @@ -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(I), DiagnosticsEngine::ak_tokenkind); + return DB; +} + inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, const IdentifierInfo *II) { DB.AddTaggedVal(reinterpret_cast(II), diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td index c54bafc07f..12c3e759ce 100644 --- a/include/clang/Basic/DiagnosticCommonKinds.td +++ b/include/clang/Basic/DiagnosticCommonKinds.td @@ -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">, diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index 0aa2f32481..2f14a50cf7 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -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, 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< diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 838ce63542..3a3c93da12 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -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">; diff --git a/include/clang/Basic/TokenKinds.h b/include/clang/Basic/TokenKinds.h index dcbe1da111..029cbdd48c 100644 --- a/include/clang/Basic/TokenKinds.h +++ b/include/clang/Basic/TokenKinds.h @@ -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 diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index bc33a7428f..1383698c3f 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -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. diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp index 45d4b539e8..4a6f070af7 100644 --- a/lib/Basic/Diagnostic.cpp +++ b/lib/Basic/Diagnostic.cpp @@ -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(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); diff --git a/lib/Lex/PPExpressions.cpp b/lib/Lex/PPExpressions.cpp index 87c0a6ace6..c561ec790e 100644 --- a/lib/Lex/PPExpressions.cpp +++ b/lib/Lex/PPExpressions.cpp @@ -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 :. diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp index 49acd2515d..8ad11c0a6b 100644 --- a/lib/Lex/PPMacroExpansion.cpp +++ b/lib/Lex/PPMacroExpansion.cpp @@ -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; } diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp index 594baa1eda..95502143b0 100644 --- a/lib/Parse/ParseCXXInlineMethods.cpp +++ b/lib/Parse/ParseCXXInlineMethods.cpp @@ -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; } } } diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index e8149d3c9f..27d8531c1f 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -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(); diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 4f86ba42db..cf86b43abb 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -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; } diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index db66ac52ff..9abc5a3aef 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -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(); } diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index 38bf76ae21..61dfbc6d58 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -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; } diff --git a/lib/Parse/ParseInit.cpp b/lib/Parse/ParseInit.cpp index 56d8edcdb4..c21dbba47a 100644 --- a/lib/Parse/ParseInit.cpp +++ b/lib/Parse/ParseInit.cpp @@ -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; } diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index 29356d0fc7..6f83707d05 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -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 &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; diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp index 89e4147e28..14404ce617 100644 --- a/lib/Parse/ParseOpenMP.cpp +++ b/lib/Parse/ParseOpenMP.cpp @@ -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; } diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp index 8a374e0fce..a225c766c1 100644 --- a/lib/Parse/ParsePragma.cpp +++ b/lib/Parse/ParsePragma.cpp @@ -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. diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index 142386402d..7f3be42fe6 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -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 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 &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; } diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp index 67004cefaf..03325db886 100644 --- a/lib/Parse/ParseTemplate.cpp +++ b/lib/Parse/ParseTemplate.cpp @@ -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; } diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 5224c6bdc1..d1424899ae 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -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 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. diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index 72c3471863..ca67094f80 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -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(); } } -- 2.40.0