let CategoryName = "Lexical or Preprocessor Issue" in {
-def err_expected_colon : Error<"expected ':'">;
def err_expected_colon_after_setter_name : Error<
"method name referenced in property setter attribute "
"must end with ':'">;
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_lparen : Error<"expected '('">;
-def err_expected_rparen : Error<"expected ')'">;
-def err_expected_rsquare : Error<"expected ']'">;
-def err_expected_greater : Error<"expected '>'">;
def err_expected_semi_declaration : Error<
"expected ';' at end of declaration">;
def err_expected_semi_decl_list : Error<
def err_expected_statement : Error<"expected statement">;
def err_expected_lparen_after : Error<"expected '(' after '%0'">;
def err_expected_less_after : Error<"expected '<' after '%0'">;
-def err_expected_comma : Error<"expected ','">;
def err_expected_lbrace_in_compound_literal : Error<
"expected '{' in compound literal">;
def err_expected_while : Error<"expected 'while' in do/while loop">;
-def err_expected_semi_after : Error<"expected ';' after %0">;
def err_expected_semi_after_stmt : Error<"expected ';' after %0 statement">;
def err_expected_semi_after_expr : Error<"expected ';' after expression">;
def err_extraneous_token_before_semi : Error<"extraneous '%0' before ';'">;
"expected a qualified name after 'typename'">;
def warn_expected_qualified_after_typename : ExtWarn<
"expected a qualified name after 'typename'">;
-def err_expected_semi_after_tagdecl : Error<
- "expected ';' after %0">;
def err_typename_refers_to_non_type_template : Error<
"typename specifier refers to a non-type template">;
/// ExpectAndConsume - The parser expects that 'ExpectedTok' is next in the
/// input. If so, it is consumed and false is returned.
///
- /// If the input is malformed, this emits the specified diagnostic. Next, if
- /// SkipToTok is specified, it calls SkipUntil(SkipToTok). Finally, true is
+ /// If a trivial punctuator misspelling is encountered, a FixIt error
+ /// diagnostic is issued and false is returned after recovery.
+ ///
+ /// If the input is malformed, this emits the specified diagnostic and true is
/// returned.
- bool ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned Diag,
- const char *DiagMsg = "",
- tok::TokenKind SkipToTok = tok::unknown);
+ bool ExpectAndConsume(tok::TokenKind ExpectedTok,
+ unsigned Diag = diag::err_expected,
+ const char *DiagMsg = "");
/// \brief The parser expects a semicolon and, if present, will consume it.
///
Diag(KWLoc, diag::err_default_delete_in_multiple_declaration)
<< Delete;
SkipUntil(tok::semi);
- } else {
- ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
- Delete ? "delete" : "default", tok::semi);
+ } else if (ExpectAndConsume(tok::semi, diag::err_expected_after,
+ Delete ? "delete" : "default")) {
+ SkipUntil(tok::semi);
}
return FnD;
AttributeList::AS_GNU);
}
}
- if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
+ if (ExpectAndConsume(tok::r_paren))
SkipUntil(tok::r_paren, StopAtSemi);
SourceLocation Loc = Tok.getLocation();
- if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
+ if (ExpectAndConsume(tok::r_paren))
SkipUntil(tok::r_paren, StopAtSemi);
if (endLoc)
*endLoc = Loc;
}
SourceLocation RParen = Tok.getLocation();
- if (!ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) {
+ if (!ExpectAndConsume(tok::r_paren)) {
SourceLocation AttrLoc = ScopeLoc.isValid() ? ScopeLoc : AttrNameLoc;
Attrs.addNew(AttrName, SourceRange(AttrLoc, RParen), ScopeName, ScopeLoc,
ArgExprs.data(), ArgExprs.size(), Syntax);
IdentifierLoc *Platform = ParseIdentifierLoc();
// Parse the ',' following the platform name.
- if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::r_paren))
+ if (ExpectAndConsume(tok::comma)) {
+ SkipUntil(tok::r_paren, StopAtSemi);
return;
+ }
// If we haven't grabbed the pointers for the identifiers
// "introduced", "deprecated", and "obsoleted", do so now.
}
UnavailableLoc = KeywordLoc;
- if (Tok.isNot(tok::comma))
- break;
-
- ConsumeToken();
- continue;
+ if (TryConsumeToken(tok::comma))
+ continue;
+ break;
}
if (Tok.isNot(tok::equal)) {
SourceLocation KWLoc = ConsumeToken();
BalancedDelimiterTracker T(*this, tok::l_paren);
- if (T.expectAndConsume(diag::err_expected_lparen))
+ if (T.expectAndConsume())
return;
SourceLocation EllipsisLoc;
return false;
Diag(PP.getLocForEndOfToken(DS.getRepAsDecl()->getLocEnd()),
- diag::err_expected_semi_after_tagdecl)
- << DeclSpec::getSpecifierName(DS.getTypeSpecType());
+ diag::err_expected_after)
+ << DeclSpec::getSpecifierName(DS.getTypeSpecType()) << tok::semi;
// Try to recover from the typo, by dropping the tag definition and parsing
// the problematic tokens as a type.
continue;
}
ConsumeToken();
- ExpectAndConsume(tok::l_paren, diag::err_expected_lparen);
+ ExpectAndConsume(tok::l_paren);
if (!Tok.is(tok::identifier)) {
Diag(Tok, diag::err_expected) << tok::identifier;
SkipUntil(tok::semi);
Tok.getIdentifierInfo(), Fields);
FieldDecls.insert(FieldDecls.end(), Fields.begin(), Fields.end());
ConsumeToken();
- ExpectAndConsume(tok::r_paren, diag::err_expected_rparen);
+ ExpectAndConsume(tok::r_paren);
}
if (TryConsumeToken(tok::semi))
TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration;
if (Tok.isNot(tok::semi)) {
// A semicolon was missing after this declaration. Diagnose and recover.
- ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl,
- "enum");
+ ExpectAndConsume(tok::semi, diag::err_expected_after, "enum");
PP.EnterToken(Tok);
Tok.setKind(tok::semi);
}
// was probably forgotten.
bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope;
if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
- ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl, "enum");
+ ExpectAndConsume(tok::semi, diag::err_expected_after, "enum");
// Push this token back into the preprocessor and change our current token
// to ';' so that the rest of the code recovers as though there were an
// ';' after the definition.
// Eat the ';'.
DeclEnd = Tok.getLocation();
- ExpectAndConsume(tok::semi, diag::err_expected_semi_after_namespace_name,
- "", tok::semi);
+ if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after_namespace_name))
+ SkipUntil(tok::semi);
return Actions.ActOnNamespaceAliasDef(getCurScope(), NamespaceLoc, AliasLoc, Alias,
SS, IdentLoc, Ident);
// Eat ';'.
DeclEnd = Tok.getLocation();
- ExpectAndConsume(tok::semi,
- GNUAttr ? diag::err_expected_semi_after_attribute_list
- : diag::err_expected_semi_after_namespace_name,
- "", tok::semi);
+ if (ExpectAndConsume(tok::semi,
+ GNUAttr ? diag::err_expected_semi_after_attribute_list
+ : diag::err_expected_semi_after_namespace_name))
+ SkipUntil(tok::semi);
return Actions.ActOnUsingDirective(getCurScope(), UsingLoc, NamespcLoc, SS,
IdentLoc, NamespcName, attrs.getList());
// Eat ';'.
DeclEnd = Tok.getLocation();
- ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
- !Attrs.empty() ? "attributes list" :
- IsAliasDecl ? "alias declaration" : "using declaration",
- tok::semi);
+ if (ExpectAndConsume(tok::semi, diag::err_expected_after,
+ !Attrs.empty() ? "attributes list"
+ : IsAliasDecl ? "alias declaration"
+ : "using declaration"))
+ SkipUntil(tok::semi);
// Diagnose an attempt to declare a templated using-declaration.
// In C++11, alias-declarations can be templates:
return 0;
}
- if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::semi))
+ if (ExpectAndConsume(tok::comma)) {
+ SkipUntil(tok::semi);
return 0;
+ }
if (!isTokenStringLiteral()) {
Diag(Tok, diag::err_expected_string_literal)
TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration;
if (Tok.isNot(tok::semi)) {
// A semicolon was missing after this declaration. Diagnose and recover.
- ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl,
- DeclSpec::getSpecifierName(TagType));
+ ExpectAndConsume(tok::semi, diag::err_expected_after,
+ DeclSpec::getSpecifierName(TagType));
PP.EnterToken(Tok);
Tok.setKind(tok::semi);
}
if (TUK == Sema::TUK_Definition &&
(TemplateInfo.Kind || !isValidAfterTypeSpecifier(false))) {
if (Tok.isNot(tok::semi)) {
- ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl,
- DeclSpec::getSpecifierName(TagType));
+ ExpectAndConsume(tok::semi, diag::err_expected_after,
+ DeclSpec::getSpecifierName(TagType));
// Push this token back into the preprocessor and change our current token
// to ';' so that the rest of the code recovers as though there were an
// ';' after the definition.
}
// TODO: recover from mistakenly-qualified operator declarations.
- if (ExpectAndConsume(tok::semi,
- diag::err_expected_semi_after,
- "access declaration",
- tok::semi))
+ if (ExpectAndConsume(tok::semi, diag::err_expected_after,
+ "access declaration")) {
+ SkipUntil(tok::semi);
return;
+ }
Actions.ActOnUsingDeclaration(getCurScope(), AS,
/* HasUsingKeyword */ false,
}
}
- if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare))
+ if (ExpectAndConsume(tok::r_square))
SkipUntil(tok::r_square);
if (endLoc)
*endLoc = Tok.getLocation();
- if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare))
+ if (ExpectAndConsume(tok::r_square))
SkipUntil(tok::r_square);
}
ConsumeBracket();
SkipUntil(tok::r_square, StopAtSemi | StopBeforeMatch);
if (endLoc) *endLoc = Tok.getLocation();
- ExpectAndConsume(tok::r_square, diag::err_expected_rsquare);
+ ExpectAndConsume(tok::r_square);
}
}
}
if (!LHS.isInvalid()) {
- if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen, ""))
+ if (ExpectAndConsume(tok::l_paren))
LHS = ExprError();
else
Loc = PrevTokLocation;
case tok::kw___builtin_va_arg: {
ExprResult Expr(ParseAssignmentExpression());
- if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
+ if (ExpectAndConsume(tok::comma)) {
+ SkipUntil(tok::r_paren, StopAtSemi);
Expr = ExprError();
+ }
TypeResult Ty = ParseTypeName();
return ExprError();
}
- if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
+ if (ExpectAndConsume(tok::comma)) {
+ SkipUntil(tok::r_paren, StopAtSemi);
return ExprError();
+ }
// We must have at least one identifier here.
if (Tok.isNot(tok::identifier)) {
SkipUntil(tok::r_paren, StopAtSemi);
return Cond;
}
- if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
+ if (ExpectAndConsume(tok::comma)) {
+ SkipUntil(tok::r_paren, StopAtSemi);
return ExprError();
+ }
ExprResult Expr1(ParseAssignmentExpression());
if (Expr1.isInvalid()) {
SkipUntil(tok::r_paren, StopAtSemi);
return Expr1;
}
- if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
+ if (ExpectAndConsume(tok::comma)) {
+ SkipUntil(tok::r_paren, StopAtSemi);
return ExprError();
+ }
ExprResult Expr2(ParseAssignmentExpression());
if (Expr2.isInvalid()) {
SkipUntil(tok::r_paren, StopAtSemi);
return ExprError();
}
-
- if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",
- tok::r_paren))
+
+ if (ExpectAndConsume(tok::comma)) {
+ SkipUntil(tok::r_paren, StopAtSemi);
return ExprError();
-
+ }
+
// Second argument is the type to bitcast to.
TypeResult DestTy = ParseTypeName();
if (DestTy.isInvalid())
SkipUntil(tok::r_paren, StopAtSemi);
return ExprError();
}
-
- if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",
- tok::r_paren))
+
+ if (ExpectAndConsume(tok::comma)) {
+ SkipUntil(tok::r_paren, StopAtSemi);
return ExprError();
-
+ }
+
// Second argument is the type to bitcast to.
TypeResult DestTy = ParseTypeName();
if (DestTy.isInvalid())
Tok.is(tok::kw___bridge_retained) ||
Tok.is(tok::kw___bridge_retain)));
if (BridgeCast && !getLangOpts().ObjCAutoRefCount) {
- if (Tok.isNot(tok::kw___bridge)) {
+ if (!TryConsumeToken(tok::kw___bridge)) {
StringRef BridgeCastName = Tok.getName();
SourceLocation BridgeKeywordLoc = ConsumeToken();
if (!PP.getSourceManager().isInSystemHeader(BridgeKeywordLoc))
<< BridgeCastName
<< FixItHint::CreateReplacement(BridgeKeywordLoc, "");
}
- else
- ConsumeToken(); // consume __bridge
BridgeCast = false;
}
Diag(KeyLoc, diag::ext_c11_generic_selection);
BalancedDelimiterTracker T(*this, tok::l_paren);
- if (T.expectAndConsume(diag::err_expected_lparen))
+ if (T.expectAndConsume())
return ExprError();
ExprResult ControllingExpr;
}
}
- if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "")) {
+ if (ExpectAndConsume(tok::comma)) {
SkipUntil(tok::r_paren, StopAtSemi);
return ExprError();
}
}
Types.push_back(Ty);
- if (ExpectAndConsume(tok::colon, diag::err_expected_colon, "")) {
+ if (ExpectAndConsume(tok::colon)) {
SkipUntil(tok::r_paren, StopAtSemi);
return ExprError();
}
SourceLocation RAngleBracketLoc = Tok.getLocation();
- if (ExpectAndConsume(tok::greater, diag::err_expected_greater))
+ if (ExpectAndConsume(tok::greater))
return ExprError(Diag(LAngleBracketLoc, diag::note_matching) << tok::less);
SourceLocation LParenLoc, RParenLoc;
SourceLocation Loc = ConsumeToken();
BalancedDelimiterTracker Parens(*this, tok::l_paren);
- if (Parens.expectAndConsume(diag::err_expected_lparen))
+ if (Parens.expectAndConsume())
return ExprError();
SmallVector<ParsedType, 2> Args;
SourceLocation Loc = ConsumeToken();
BalancedDelimiterTracker T(*this, tok::l_paren);
- if (T.expectAndConsume(diag::err_expected_lparen))
+ if (T.expectAndConsume())
return ExprError();
TypeResult Ty = ParseTypeName();
T.getCloseLocation());
}
case ATT_ArrayExtent: {
- if (ExpectAndConsume(tok::comma, diag::err_expected_comma)) {
+ if (ExpectAndConsume(tok::comma)) {
SkipUntil(tok::r_paren, StopAtSemi);
return ExprError();
}
SourceLocation Loc = ConsumeToken();
BalancedDelimiterTracker T(*this, tok::l_paren);
- if (T.expectAndConsume(diag::err_expected_lparen))
+ if (T.expectAndConsume())
return ExprError();
ExprResult Expr = ParseExpression();
ClassLocs.push_back(Tok.getLocation());
ConsumeToken();
- if (Tok.isNot(tok::comma))
+ if (!TryConsumeToken(tok::comma))
break;
-
- ConsumeToken();
}
// Consume the ';'.
- if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@class"))
+ if (ExpectAndConsume(tok::semi, diag::err_expected_after, "@class"))
return Actions.ConvertDeclToDeclGroup(0);
return Actions.ActOnForwardClassDeclaration(atLoc, ClassNames.data(),
unsigned DiagID = IsSetter ? diag::err_objc_expected_equal_for_setter :
diag::err_objc_expected_equal_for_getter;
- if (ExpectAndConsume(tok::equal, DiagID, "", tok::r_paren))
+ if (ExpectAndConsume(tok::equal, DiagID)) {
+ SkipUntil(tok::r_paren, StopAtSemi);
return;
+ }
if (Tok.is(tok::code_completion)) {
if (IsSetter)
DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_setter);
DS.setSetterName(SelIdent);
- if (ExpectAndConsume(tok::colon,
- diag::err_expected_colon_after_setter_name, "",
- tok::r_paren))
+ if (ExpectAndConsume(tok::colon,
+ diag::err_expected_colon_after_setter_name)) {
+ SkipUntil(tok::r_paren, StopAtSemi);
return;
+ }
} else {
DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_getter);
DS.setGetterName(SelIdent);
Sema::ObjCArgInfo ArgInfo;
// Each iteration parses a single keyword argument.
- if (Tok.isNot(tok::colon)) {
- Diag(Tok, diag::err_expected) << tok::colon;
+ if (ExpectAndConsume(tok::colon))
break;
- }
- ConsumeToken(); // Eat the ':'.
ArgInfo.Type = ParsedType();
if (Tok.is(tok::l_paren)) // Parse the argument type if present.
ProtocolLocs.push_back(Tok.getLocation());
ConsumeToken();
- if (Tok.isNot(tok::comma))
+ if (!TryConsumeToken(tok::comma))
break;
- ConsumeToken();
}
// Consume the '>'.
}
// Set the default visibility to private.
- if (Tok.is(tok::at)) { // parse objc-visibility-spec
- ConsumeToken(); // eat the @ sign
-
+ if (TryConsumeToken(tok::at)) { // parse objc-visibility-spec
if (Tok.is(tok::code_completion)) {
Actions.CodeCompleteObjCAtVisibility(getCurScope());
return cutOffParsing();
IdentifierInfo *protocolName = Tok.getIdentifierInfo();
SourceLocation nameLoc = ConsumeToken();
- if (Tok.is(tok::semi)) { // forward declaration of one protocol.
+ if (TryConsumeToken(tok::semi)) { // forward declaration of one protocol.
IdentifierLocPair ProtoInfo(protocolName, nameLoc);
- ConsumeToken();
return Actions.ActOnForwardProtocolDeclaration(AtLoc, &ProtoInfo, 1,
attrs.getList());
}
break;
}
// Consume the ';'.
- if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@protocol"))
+ if (ExpectAndConsume(tok::semi, diag::err_expected_after, "@protocol"))
return DeclGroupPtrTy();
return Actions.ActOnForwardProtocolDeclaration(AtLoc,
// We have a class implementation
SourceLocation superClassLoc;
IdentifierInfo *superClassId = 0;
- if (Tok.is(tok::colon)) {
+ if (TryConsumeToken(tok::colon)) {
// We have a super class
- ConsumeToken();
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected)
<< tok::identifier; // missing super class name.
}
IdentifierInfo *classId = Tok.getIdentifierInfo();
SourceLocation classLoc = ConsumeToken(); // consume class-name;
- ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
- "@compatibility_alias");
+ ExpectAndConsume(tok::semi, diag::err_expected_after, "@compatibility_alias");
return Actions.ActOnCompatibilityAlias(atLoc, aliasId, aliasLoc,
classId, classLoc);
}
IdentifierInfo *propertyId = Tok.getIdentifierInfo();
SourceLocation propertyLoc = ConsumeToken(); // consume property name
SourceLocation propertyIvarLoc;
- if (Tok.is(tok::equal)) {
+ if (TryConsumeToken(tok::equal)) {
// property '=' ivar-name
- ConsumeToken(); // consume '='
-
if (Tok.is(tok::code_completion)) {
Actions.CodeCompleteObjCPropertySynthesizeIvar(getCurScope(), propertyId);
cutOffParsing();
break;
ConsumeToken(); // consume ','
}
- ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@synthesize");
+ ExpectAndConsume(tok::semi, diag::err_expected_after, "@synthesize");
return 0;
}
break;
ConsumeToken(); // consume ','
}
- ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@dynamic");
+ ExpectAndConsume(tok::semi, diag::err_expected_after, "@dynamic");
return 0;
}
}
}
// consume ';'
- ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@throw");
+ ExpectAndConsume(tok::semi, diag::err_expected_after, "@throw");
return Actions.ActOnObjCAtThrowStmt(atLoc, Res.take(), getCurScope());
}
KeyIdents.push_back(selIdent);
KeyLocs.push_back(Loc);
- if (Tok.isNot(tok::colon)) {
- Diag(Tok, diag::err_expected) << tok::colon;
+ if (ExpectAndConsume(tok::colon)) {
// 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
// the enclosing expression.
return ExprError();
}
- ConsumeToken(); // Eat the ':'.
/// Parse the expression after ':'
if (Tok.is(tok::code_completion)) {
}
}
- if (!TryConsumeToken(tok::colon)) {
- Diag(Tok, diag::err_expected) << tok::colon;
+ if (ExpectAndConsume(tok::colon)) {
SkipUntil(tok::r_brace, StopAtSemi);
return ExprError();
}
KeyExpr.get(), ValueExpr.get(), EllipsisLoc, None
};
Elements.push_back(Element);
-
- if (Tok.is(tok::comma))
- ConsumeToken(); // Eat the ','.
- else if (Tok.isNot(tok::r_brace))
+
+ if (!TryConsumeToken(tok::comma) && Tok.isNot(tok::r_brace))
return ExprError(Diag(Tok, diag::err_expected_either) << tok::r_brace
<< tok::comma);
}
unsigned nColons = 0;
if (Tok.isNot(tok::r_paren)) {
while (1) {
- if (Tok.is(tok::coloncolon)) { // Handle :: in C++.
+ if (TryConsumeToken(tok::coloncolon)) { // Handle :: in C++.
++nColons;
KeyIdents.push_back(0);
- } else if (Tok.isNot(tok::colon))
- return ExprError(Diag(Tok, diag::err_expected) << tok::colon);
-
+ } else if (ExpectAndConsume(tok::colon)) // Otherwise expect ':'.
+ return ExprError();
++nColons;
- ConsumeToken(); // Eat the ':' or '::'.
+
if (Tok.is(tok::r_paren))
break;
raii2(Ident___exception_code, false),
raii3(Ident_GetExceptionCode, false);
- if(ExpectAndConsume(tok::l_paren,diag::err_expected_lparen))
+ if (ExpectAndConsume(tok::l_paren))
return StmtError();
ParseScope ExpectScope(this, Scope::DeclScope | Scope::ControlScope);
if(FilterExpr.isInvalid())
return StmtError();
- if(ExpectAndConsume(tok::r_paren,diag::err_expected_rparen))
+ if (ExpectAndConsume(tok::r_paren))
return StmtError();
StmtResult Block(ParseCompoundStatement());
SubStmt = Actions.ProcessStmtAttributes(
SubStmt.get(), TempAttrs.getList(), TempAttrs.Range);
} else {
- Diag(Tok, diag::err_expected_semi_after) << "__attribute__";
+ Diag(Tok, diag::err_expected_after) << "__attribute__" << tok::semi;
}
}
SourceLocation CatchLoc = ConsumeToken();
BalancedDelimiterTracker T(*this, tok::l_paren);
- if (T.expectAndConsume(diag::err_expected_lparen))
+ if (T.expectAndConsume())
return StmtError();
// C++ 3.3.2p3:
Tok.setKind(tok::greater);
RAngleLoc = Tok.getLocation();
Tok.setLocation(Tok.getLocation().getLocWithOffset(1));
- } else if (Tok.is(tok::greater))
- RAngleLoc = ConsumeToken();
- else if (Failed) {
- Diag(Tok.getLocation(), diag::err_expected_greater);
+ } else if (!TryConsumeToken(tok::greater, RAngleLoc) && Failed) {
+ Diag(Tok.getLocation(), diag::err_expected) << tok::greater;
return true;
}
return false;
switch (Tok.getKind()) {
default:
- Diag(Tok.getLocation(), diag::err_expected_greater);
+ Diag(Tok.getLocation(), diag::err_expected) << tok::greater;
return true;
case tok::greater:
}
}
-/// ExpectAndConsume - The parser expects that 'ExpectedTok' is next in the
-/// input. If so, it is consumed and false is returned.
-///
-/// If the input is malformed, this emits the specified diagnostic. Next, if
-/// SkipToTok is specified, it calls SkipUntil(SkipToTok). Finally, true is
-/// returned.
bool Parser::ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned DiagID,
- const char *Msg, tok::TokenKind SkipToTok) {
+ const char *Msg) {
if (Tok.is(ExpectedTok) || Tok.is(tok::code_completion)) {
ConsumeAnyToken();
return false;
// Detect common single-character typos and resume.
if (IsCommonTypo(ExpectedTok, Tok)) {
SourceLocation Loc = Tok.getLocation();
- Diag(Loc, DiagID)
- << Msg
- << FixItHint::CreateReplacement(SourceRange(Loc),
- getTokenSimpleSpelling(ExpectedTok));
+ DiagnosticBuilder DB = Diag(Loc, DiagID);
+ DB << FixItHint::CreateReplacement(SourceRange(Loc),
+ getTokenSimpleSpelling(ExpectedTok));
+ if (DiagID == diag::err_expected)
+ DB << ExpectedTok;
+ else if (DiagID == diag::err_expected_after)
+ DB << Msg << ExpectedTok;
+ else
+ DB << Msg;
ConsumeAnyToken();
// Pretend there wasn't a problem.
return false;
}
- const char *Spelling = 0;
SourceLocation EndLoc = PP.getLocForEndOfToken(PrevTokLocation);
- if (EndLoc.isValid() &&
- (Spelling = tok::getTokenSimpleSpelling(ExpectedTok))) {
- // Show what code to insert to fix this problem.
- Diag(EndLoc, DiagID)
- << Msg
- << FixItHint::CreateInsertion(EndLoc, Spelling);
- } else
- Diag(Tok, DiagID) << Msg;
+ const char *Spelling = 0;
+ if (EndLoc.isValid())
+ Spelling = tok::getTokenSimpleSpelling(ExpectedTok);
+
+ DiagnosticBuilder DB =
+ Spelling
+ ? Diag(EndLoc, DiagID) << FixItHint::CreateInsertion(EndLoc, Spelling)
+ : Diag(Tok, DiagID);
+ if (DiagID == diag::err_expected)
+ DB << ExpectedTok;
+ else if (DiagID == diag::err_expected_after)
+ DB << Msg << ExpectedTok;
+ else
+ DB << Msg;
- if (SkipToTok != tok::unknown)
- SkipUntil(SkipToTok, StopAtSemi);
return true;
}
SourceLocation EndLoc;
ExprResult Result(ParseSimpleAsm(&EndLoc));
- ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
+ ExpectAndConsume(tok::semi, diag::err_expected_after,
"top-level asm block");
if (Result.isInvalid())
// safe because we're always the sole owner.
D.getMutableDeclSpec().abort();
- if (Tok.is(tok::equal)) {
+ if (TryConsumeToken(tok::equal)) {
assert(getLangOpts().CPlusPlus && "Only C++ function definitions have '='");
- ConsumeToken();
-
Actions.ActOnFinishFunctionBody(Res, 0, false);
bool Delete = false;
SourceLocation KWLoc;
- if (Tok.is(tok::kw_delete)) {
- Diag(Tok, getLangOpts().CPlusPlus11 ?
- diag::warn_cxx98_compat_deleted_function :
- diag::ext_deleted_function);
-
- KWLoc = ConsumeToken();
+ if (TryConsumeToken(tok::kw_delete, KWLoc)) {
+ Diag(KWLoc, getLangOpts().CPlusPlus11
+ ? diag::warn_cxx98_compat_deleted_function
+ : diag::ext_deleted_function);
Actions.SetDeclDeleted(Res, KWLoc);
Delete = true;
- } else if (Tok.is(tok::kw_default)) {
- Diag(Tok, getLangOpts().CPlusPlus11 ?
- diag::warn_cxx98_compat_defaulted_function :
- diag::ext_defaulted_function);
-
- KWLoc = ConsumeToken();
+ } else if (TryConsumeToken(tok::kw_default, KWLoc)) {
+ Diag(KWLoc, getLangOpts().CPlusPlus11
+ ? diag::warn_cxx98_compat_defaulted_function
+ : diag::ext_defaulted_function);
Actions.SetDeclDefaulted(Res, KWLoc);
} else {
llvm_unreachable("function definition after = not 'delete' or 'default'");
Diag(KWLoc, diag::err_default_delete_in_multiple_declaration)
<< Delete;
SkipUntil(tok::semi);
- } else {
- ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
- Delete ? "delete" : "default", tok::semi);
+ } else if (ExpectAndConsume(tok::semi, diag::err_expected_after,
+ Delete ? "delete" : "default")) {
+ SkipUntil(tok::semi);
}
return Res;
}
bool BalancedDelimiterTracker::expectAndConsume(unsigned DiagID,
- const char *Msg,
- tok::TokenKind SkipToToc ) {
+ const char *Msg,
+ tok::TokenKind SkipToTok) {
LOpen = P.Tok.getLocation();
- if (P.ExpectAndConsume(Kind, DiagID, Msg, SkipToToc))
+ if (P.ExpectAndConsume(Kind, DiagID, Msg)) {
+ if (SkipToTok != tok::unknown)
+ P.SkipUntil(SkipToTok, Parser::StopAtSemi);
return true;
-
+ }
+
if (getDepth() < MaxDepth)
return false;
return diagnoseOverflow();
}
-
- bool expectAndConsume(unsigned DiagID,
+
+ bool expectAndConsume(unsigned DiagID = diag::err_expected,
const char *Msg = "",
tok::TokenKind SkipToTok = tok::unknown);
bool consumeClose() {