diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h index 4eb080601be4..2b0b3f9b28ca 100644 --- a/clang/include/clang/Basic/Diagnostic.h +++ b/clang/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/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td index c54bafc07fe8..12c3e759ce4d 100644 --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/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/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 0aa2f32481cc..2f14a50cf70b 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/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/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 838ce635423e..3a3c93da1253 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/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/clang/include/clang/Basic/TokenKinds.h b/clang/include/clang/Basic/TokenKinds.h index dcbe1da1115d..029cbdd48c80 100644 --- a/clang/include/clang/Basic/TokenKinds.h +++ b/clang/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/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index bc33a7428f4b..1383698c3f04 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/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/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp index 45d4b539e8c2..4a6f070af703 100644 --- a/clang/lib/Basic/Diagnostic.cpp +++ b/clang/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/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp index 87c0a6ace6cb..c561ec790e5f 100644 --- a/clang/lib/Lex/PPExpressions.cpp +++ b/clang/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/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index 49acd2515d65..8ad11c0a6b95 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/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/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index 594baa1edaad..95502143b0f7 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/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/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index e8149d3c9fdd..27d8531c1fdb 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/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/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 4f86ba42db2c..cf86b43abb9d 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/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/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index db66ac52ffca..9abc5a3aefa3 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/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/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 38bf76ae2134..61dfbc6d58c0 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/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/clang/lib/Parse/ParseInit.cpp b/clang/lib/Parse/ParseInit.cpp index 56d8edcdb41b..c21dbba47a7c 100644 --- a/clang/lib/Parse/ParseInit.cpp +++ b/clang/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/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index 29356d0fc74b..6f83707d05b0 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/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/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 89e4147e285c..14404ce61760 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/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/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index 8a374e0fce61..a225c766c115 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/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/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 142386402dff..7f3be42fe6c6 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/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/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index 67004cefaf96..03325db88606 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/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/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 5224c6bdc192..d1424899aec8 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/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/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index 72c3471863cf..ca67094f80f2 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/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(); } }