Replaced bool parameters in SkipUntil function with single bit-based parameter.

llvm-svn: 194994
This commit is contained in:
Alexey Bataev 2013-11-18 08:17:37 +00:00
parent 39d0c93b70
commit ee6507dfdc
13 changed files with 271 additions and 235 deletions

View File

@ -736,32 +736,45 @@ private:
void CheckNestedObjCContexts(SourceLocation AtLoc); void CheckNestedObjCContexts(SourceLocation AtLoc);
public: public:
// Control flags for SkipUntil functions.
enum SkipUntilFlags {
StopAtSemi = 1 << 0, /// \brief Stop skipping at semicolon
/// \brief Stop skipping at specified token, but don't skip the token itself
StopBeforeMatch = 1 << 1,
StopAtCodeCompletion = 1 << 2 /// \brief Stop at code completion
};
friend LLVM_CONSTEXPR SkipUntilFlags operator|(SkipUntilFlags L,
SkipUntilFlags R) {
return static_cast<SkipUntilFlags>(static_cast<unsigned>(L) |
static_cast<unsigned>(R));
}
/// SkipUntil - Read tokens until we get to the specified token, then consume /// SkipUntil - Read tokens until we get to the specified token, then consume
/// it (unless DontConsume is true). Because we cannot guarantee that the /// it (unless StopBeforeMatch is specified). Because we cannot guarantee
/// token will ever occur, this skips to the next token, or to some likely /// that the token will ever occur, this skips to the next token, or to some
/// good stopping point. If StopAtSemi is true, skipping will stop at a ';' /// likely good stopping point. If Flags has StopAtSemi flag, skipping will
/// character. /// stop at a ';' character.
/// ///
/// If SkipUntil finds the specified token, it returns true, otherwise it /// If SkipUntil finds the specified token, it returns true, otherwise it
/// returns false. /// returns false.
bool SkipUntil(tok::TokenKind T, bool StopAtSemi = true, bool SkipUntil(tok::TokenKind T,
bool DontConsume = false, bool StopAtCodeCompletion = false) { SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)) {
return SkipUntil(llvm::makeArrayRef(T), StopAtSemi, DontConsume, return SkipUntil(llvm::makeArrayRef(T), Flags);
StopAtCodeCompletion);
} }
bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2, bool StopAtSemi = true, bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2,
bool DontConsume = false, bool StopAtCodeCompletion = false) { SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)) {
tok::TokenKind TokArray[] = {T1, T2}; tok::TokenKind TokArray[] = {T1, T2};
return SkipUntil(TokArray, StopAtSemi, DontConsume,StopAtCodeCompletion); return SkipUntil(TokArray, Flags);
} }
bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2, tok::TokenKind T3, bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2, tok::TokenKind T3,
bool StopAtSemi = true, bool DontConsume = false, SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)) {
bool StopAtCodeCompletion = false) {
tok::TokenKind TokArray[] = {T1, T2, T3}; tok::TokenKind TokArray[] = {T1, T2, T3};
return SkipUntil(TokArray, StopAtSemi, DontConsume,StopAtCodeCompletion); return SkipUntil(TokArray, Flags);
} }
bool SkipUntil(ArrayRef<tok::TokenKind> Toks, bool StopAtSemi = true, bool SkipUntil(ArrayRef<tok::TokenKind> Toks,
bool DontConsume = false, bool StopAtCodeCompletion = false); SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0));
/// SkipMalformedDecl - Read tokens until we get to some likely good stopping /// SkipMalformedDecl - Read tokens until we get to some likely good stopping
/// point for skipping past a simple-declaration. /// point for skipping past a simple-declaration.

View File

@ -868,7 +868,7 @@ public:
Revert(); Revert();
// Put back the original tokens. // Put back the original tokens.
Self.SkipUntil(EndKind, true, /*DontConsume*/true); Self.SkipUntil(EndKind, StopAtSemi | StopBeforeMatch);
if (Toks.size()) { if (Toks.size()) {
Token *Buffer = new Token[Toks.size()]; Token *Buffer = new Token[Toks.size()];
std::copy(Toks.begin() + 1, Toks.end(), Buffer); std::copy(Toks.begin() + 1, Toks.end(), Buffer);

View File

@ -124,11 +124,11 @@ void Parser::ParseGNUAttributes(ParsedAttributes &attrs,
ConsumeToken(); ConsumeToken();
if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
"attribute")) { "attribute")) {
SkipUntil(tok::r_paren, true); // skip until ) or ; SkipUntil(tok::r_paren, StopAtSemi); // skip until ) or ;
return; return;
} }
if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "(")) { if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "(")) {
SkipUntil(tok::r_paren, true); // skip until ) or ; SkipUntil(tok::r_paren, StopAtSemi); // skip until ) or ;
return; return;
} }
// Parse the attribute-list. e.g. __attribute__(( weak, alias("__f") )) // Parse the attribute-list. e.g. __attribute__(( weak, alias("__f") ))
@ -172,10 +172,10 @@ void Parser::ParseGNUAttributes(ParsedAttributes &attrs,
} }
} }
if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
SourceLocation Loc = Tok.getLocation(); SourceLocation Loc = Tok.getLocation();
if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
if (endLoc) if (endLoc)
*endLoc = Loc; *endLoc = Loc;
} }
@ -306,7 +306,7 @@ void Parser::ParseGNUAttributeArgs(IdentifierInfo *AttrName,
while (1) { while (1) {
ExprResult ArgExpr(ParseAssignmentExpression()); ExprResult ArgExpr(ParseAssignmentExpression());
if (ArgExpr.isInvalid()) { if (ArgExpr.isInvalid()) {
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return; return;
} }
ArgExprs.push_back(ArgExpr.release()); ArgExprs.push_back(ArgExpr.release());
@ -682,7 +682,8 @@ VersionTuple Parser::ParseVersionTuple(SourceRange &Range) {
if (!Tok.is(tok::numeric_constant)) { if (!Tok.is(tok::numeric_constant)) {
Diag(Tok, diag::err_expected_version); Diag(Tok, diag::err_expected_version);
SkipUntil(tok::comma, tok::r_paren, true, true, true); SkipUntil(tok::comma, tok::r_paren,
StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);
return VersionTuple(); return VersionTuple();
} }
@ -710,7 +711,8 @@ VersionTuple Parser::ParseVersionTuple(SourceRange &Range) {
if (AfterMajor == 0) { if (AfterMajor == 0) {
Diag(Tok, diag::err_expected_version); Diag(Tok, diag::err_expected_version);
SkipUntil(tok::comma, tok::r_paren, true, true, true); SkipUntil(tok::comma, tok::r_paren,
StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);
return VersionTuple(); return VersionTuple();
} }
@ -728,7 +730,8 @@ VersionTuple Parser::ParseVersionTuple(SourceRange &Range) {
if (ThisTokBegin[AfterMajor] != '.' || (AfterMajor + 1 == ActualLength)) { if (ThisTokBegin[AfterMajor] != '.' || (AfterMajor + 1 == ActualLength)) {
Diag(Tok, diag::err_expected_version); Diag(Tok, diag::err_expected_version);
SkipUntil(tok::comma, tok::r_paren, true, true, true); SkipUntil(tok::comma, tok::r_paren,
StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);
return VersionTuple(); return VersionTuple();
} }
@ -755,7 +758,8 @@ VersionTuple Parser::ParseVersionTuple(SourceRange &Range) {
// If what follows is not a '.', we have a problem. // If what follows is not a '.', we have a problem.
if (ThisTokBegin[AfterMinor] != '.') { if (ThisTokBegin[AfterMinor] != '.') {
Diag(Tok, diag::err_expected_version); Diag(Tok, diag::err_expected_version);
SkipUntil(tok::comma, tok::r_paren, true, true, true); SkipUntil(tok::comma, tok::r_paren,
StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);
return VersionTuple(); return VersionTuple();
} }
@ -769,7 +773,8 @@ VersionTuple Parser::ParseVersionTuple(SourceRange &Range) {
if (AfterSubminor != ActualLength) { if (AfterSubminor != ActualLength) {
Diag(Tok, diag::err_expected_version); Diag(Tok, diag::err_expected_version);
SkipUntil(tok::comma, tok::r_paren, true, true, true); SkipUntil(tok::comma, tok::r_paren,
StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);
return VersionTuple(); return VersionTuple();
} }
ConsumeToken(); ConsumeToken();
@ -813,7 +818,7 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
// Parse the platform name, // Parse the platform name,
if (Tok.isNot(tok::identifier)) { if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_availability_expected_platform); Diag(Tok, diag::err_availability_expected_platform);
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return; return;
} }
IdentifierLoc *Platform = ParseIdentifierLoc(); IdentifierLoc *Platform = ParseIdentifierLoc();
@ -837,7 +842,7 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
do { do {
if (Tok.isNot(tok::identifier)) { if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_availability_expected_change); Diag(Tok, diag::err_availability_expected_change);
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return; return;
} }
IdentifierInfo *Keyword = Tok.getIdentifierInfo(); IdentifierInfo *Keyword = Tok.getIdentifierInfo();
@ -860,7 +865,7 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
if (Tok.isNot(tok::equal)) { if (Tok.isNot(tok::equal)) {
Diag(Tok, diag::err_expected_equal_after) Diag(Tok, diag::err_expected_equal_after)
<< Keyword; << Keyword;
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return; return;
} }
ConsumeToken(); ConsumeToken();
@ -868,7 +873,7 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
if (Tok.isNot(tok::string_literal)) { // Also reject wide string literals. if (Tok.isNot(tok::string_literal)) { // Also reject wide string literals.
Diag(Tok, diag::err_expected_string_literal) Diag(Tok, diag::err_expected_string_literal)
<< /*Source='availability attribute'*/2; << /*Source='availability attribute'*/2;
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return; return;
} }
MessageExpr = ParseStringLiteralExpression(); MessageExpr = ParseStringLiteralExpression();
@ -879,7 +884,7 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
VersionTuple Version = ParseVersionTuple(VersionRange); VersionTuple Version = ParseVersionTuple(VersionRange);
if (Version.empty()) { if (Version.empty()) {
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return; return;
} }
@ -1260,7 +1265,7 @@ bool Parser::DiagnoseProhibitedCXX11Attribute() {
// Parse and discard the attributes. // Parse and discard the attributes.
SourceLocation BeginLoc = ConsumeBracket(); SourceLocation BeginLoc = ConsumeBracket();
ConsumeBracket(); ConsumeBracket();
SkipUntil(tok::r_square, /*StopAtSemi*/ false); SkipUntil(tok::r_square);
assert(Tok.is(tok::r_square) && "isCXX11AttributeSpecifier lied"); assert(Tok.is(tok::r_square) && "isCXX11AttributeSpecifier lied");
SourceLocation EndLoc = ConsumeBracket(); SourceLocation EndLoc = ConsumeBracket();
Diag(BeginLoc, diag::err_attributes_not_allowed) Diag(BeginLoc, diag::err_attributes_not_allowed)
@ -1491,7 +1496,7 @@ void Parser::SkipMalformedDecl() {
// Skip until matching }, then stop. We've probably skipped over // Skip until matching }, then stop. We've probably skipped over
// a malformed class or function definition or similar. // a malformed class or function definition or similar.
ConsumeBrace(); ConsumeBrace();
SkipUntil(tok::r_brace, /*StopAtSemi*/false); SkipUntil(tok::r_brace);
if (Tok.is(tok::comma) || Tok.is(tok::l_brace) || Tok.is(tok::kw_try)) { if (Tok.is(tok::comma) || Tok.is(tok::l_brace) || Tok.is(tok::kw_try)) {
// This declaration isn't over yet. Keep skipping. // This declaration isn't over yet. Keep skipping.
continue; continue;
@ -1502,12 +1507,12 @@ void Parser::SkipMalformedDecl() {
case tok::l_square: case tok::l_square:
ConsumeBracket(); ConsumeBracket();
SkipUntil(tok::r_square, /*StopAtSemi*/false); SkipUntil(tok::r_square);
continue; continue;
case tok::l_paren: case tok::l_paren:
ConsumeParen(); ConsumeParen();
SkipUntil(tok::r_paren, /*StopAtSemi*/false); SkipUntil(tok::r_paren);
continue; continue;
case tok::r_brace: case tok::r_brace:
@ -1620,7 +1625,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
} else { } else {
if (Tok.is(tok::l_brace)) { if (Tok.is(tok::l_brace)) {
Diag(Tok, diag::err_function_definition_not_allowed); Diag(Tok, diag::err_function_definition_not_allowed);
SkipUntil(tok::r_brace, true, true); SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
} }
} }
} }
@ -1711,7 +1716,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
// declaration specifier, just assume it was missing and continue parsing. // declaration specifier, just assume it was missing and continue parsing.
// Otherwise things are very confused and we skip to recover. // Otherwise things are very confused and we skip to recover.
if (!isDeclarationSpecifier()) { if (!isDeclarationSpecifier()) {
SkipUntil(tok::r_brace, true, true); SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
if (Tok.is(tok::semi)) if (Tok.is(tok::semi))
ConsumeToken(); ConsumeToken();
} }
@ -1728,7 +1733,7 @@ bool Parser::ParseAsmAttributesAfterDeclarator(Declarator &D) {
SourceLocation Loc; SourceLocation Loc;
ExprResult AsmLabel(ParseSimpleAsm(&Loc)); ExprResult AsmLabel(ParseSimpleAsm(&Loc));
if (AsmLabel.isInvalid()) { if (AsmLabel.isInvalid()) {
SkipUntil(tok::semi, true, true); SkipUntil(tok::semi, StopBeforeMatch);
return true; return true;
} }
@ -1795,7 +1800,7 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(Declarator &D,
DeclResult ThisRes = Actions.ActOnExplicitInstantiation( DeclResult ThisRes = Actions.ActOnExplicitInstantiation(
getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, D); getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, D);
if (ThisRes.isInvalid()) { if (ThisRes.isInvalid()) {
SkipUntil(tok::semi, true, true); SkipUntil(tok::semi, StopBeforeMatch);
return 0; return 0;
} }
ThisDecl = ThisRes.get(); ThisDecl = ThisRes.get();
@ -1871,7 +1876,7 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(Declarator &D,
} }
if (Init.isInvalid()) { if (Init.isInvalid()) {
SkipUntil(tok::comma, true, true); SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);
Actions.ActOnInitializerError(ThisDecl); Actions.ActOnInitializerError(ThisDecl);
} else } else
Actions.AddInitializerToDecl(ThisDecl, Init.take(), Actions.AddInitializerToDecl(ThisDecl, Init.take(),
@ -1892,7 +1897,7 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(Declarator &D,
if (ParseExpressionList(Exprs, CommaLocs)) { if (ParseExpressionList(Exprs, CommaLocs)) {
Actions.ActOnInitializerError(ThisDecl); Actions.ActOnInitializerError(ThisDecl);
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
@ -2299,7 +2304,7 @@ void Parser::ParseAlignmentSpecifier(ParsedAttributes &Attrs,
SourceLocation EllipsisLoc; SourceLocation EllipsisLoc;
ExprResult ArgExpr = ParseAlignArgument(T.getOpenLocation(), EllipsisLoc); ExprResult ArgExpr = ParseAlignArgument(T.getOpenLocation(), EllipsisLoc);
if (ArgExpr.isInvalid()) { if (ArgExpr.isInvalid()) {
SkipUntil(tok::r_paren); T.skipToEnd();
return; return;
} }
@ -3199,7 +3204,7 @@ ParseStructDeclaration(ParsingDeclSpec &DS, FieldCallback &Fields) {
ConsumeToken(); ConsumeToken();
ExprResult Res(ParseConstantExpression()); ExprResult Res(ParseConstantExpression());
if (Res.isInvalid()) if (Res.isInvalid())
SkipUntil(tok::semi, true, true); SkipUntil(tok::semi, StopBeforeMatch);
else else
DeclaratorInfo.BitfieldSize = Res.release(); DeclaratorInfo.BitfieldSize = Res.release();
} }
@ -3301,14 +3306,14 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
ConsumeToken(); ConsumeToken();
if (!Tok.isObjCAtKeyword(tok::objc_defs)) { if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
Diag(Tok, diag::err_unexpected_at); Diag(Tok, diag::err_unexpected_at);
SkipUntil(tok::semi, true); SkipUntil(tok::semi);
continue; continue;
} }
ConsumeToken(); ConsumeToken();
ExpectAndConsume(tok::l_paren, diag::err_expected_lparen); ExpectAndConsume(tok::l_paren, diag::err_expected_lparen);
if (!Tok.is(tok::identifier)) { if (!Tok.is(tok::identifier)) {
Diag(Tok, diag::err_expected_ident); Diag(Tok, diag::err_expected_ident);
SkipUntil(tok::semi, true); SkipUntil(tok::semi);
continue; continue;
} }
SmallVector<Decl *, 16> Fields; SmallVector<Decl *, 16> Fields;
@ -3327,7 +3332,7 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
} else { } else {
ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list); ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
// Skip to end of block or statement to avoid ext-warning on extra ';'. // Skip to end of block or statement to avoid ext-warning on extra ';'.
SkipUntil(tok::r_brace, true, true); SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
// If we stopped at a ';', eat it. // If we stopped at a ';', eat it.
if (Tok.is(tok::semi)) ConsumeToken(); if (Tok.is(tok::semi)) ConsumeToken();
} }
@ -3451,7 +3456,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
if (Tok.isNot(tok::l_brace)) { if (Tok.isNot(tok::l_brace)) {
// Has no name and is not a definition. // Has no name and is not a definition.
// Skip the rest of this declarator, up until the comma or semicolon. // Skip the rest of this declarator, up until the comma or semicolon.
SkipUntil(tok::comma, true); SkipUntil(tok::comma, StopAtSemi);
return; return;
} }
} }
@ -3463,7 +3468,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
Diag(Tok, diag::err_expected_ident_lbrace); Diag(Tok, diag::err_expected_ident_lbrace);
// Skip the rest of this declarator, up until the comma or semicolon. // Skip the rest of this declarator, up until the comma or semicolon.
SkipUntil(tok::comma, true); SkipUntil(tok::comma, StopAtSemi);
return; return;
} }
@ -3581,7 +3586,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
Diag(Tok.getLocation(), diag::err_friend_decl_defines_type) Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
<< SourceRange(DS.getFriendSpecLoc()); << SourceRange(DS.getFriendSpecLoc());
ConsumeBrace(); ConsumeBrace();
SkipUntil(tok::r_brace); SkipUntil(tok::r_brace, StopAtSemi);
TUK = Sema::TUK_Friend; TUK = Sema::TUK_Friend;
} else { } else {
TUK = Sema::TUK_Definition; TUK = Sema::TUK_Definition;
@ -3614,7 +3619,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
if (!getLangOpts().CPlusPlus11 || !SS.isSet()) { if (!getLangOpts().CPlusPlus11 || !SS.isSet()) {
// Skip the rest of this declarator, up until the comma or semicolon. // Skip the rest of this declarator, up until the comma or semicolon.
Diag(Tok, diag::err_enum_template); Diag(Tok, diag::err_enum_template);
SkipUntil(tok::comma, true); SkipUntil(tok::comma, StopAtSemi);
return; return;
} }
@ -3637,7 +3642,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
Diag(Tok, diag::err_enumerator_unnamed_no_def); Diag(Tok, diag::err_enumerator_unnamed_no_def);
// Skip the rest of this declarator, up until the comma or semicolon. // Skip the rest of this declarator, up until the comma or semicolon.
SkipUntil(tok::comma, true); SkipUntil(tok::comma, StopAtSemi);
return; return;
} }
@ -3681,7 +3686,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
// definition, consume the entire definition. // definition, consume the entire definition.
if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference) { if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference) {
ConsumeBrace(); ConsumeBrace();
SkipUntil(tok::r_brace); SkipUntil(tok::r_brace, StopAtSemi);
} }
DS.SetTypeSpecError(); DS.SetTypeSpecError();
@ -3742,7 +3747,7 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
EqualLoc = ConsumeToken(); EqualLoc = ConsumeToken();
AssignedVal = ParseConstantExpression(); AssignedVal = ParseConstantExpression();
if (AssignedVal.isInvalid()) if (AssignedVal.isInvalid())
SkipUntil(tok::comma, tok::r_brace, true, true); SkipUntil(tok::comma, tok::r_brace, StopAtSemi | StopBeforeMatch);
} }
// Install the enumerator constant into EnumDecl. // Install the enumerator constant into EnumDecl.
@ -5189,7 +5194,7 @@ void Parser::ParseFunctionDeclaratorIdentifierList(
// If this isn't an identifier, report the error and skip until ')'. // If this isn't an identifier, report the error and skip until ')'.
if (Tok.isNot(tok::identifier)) { if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident); Diag(Tok, diag::err_expected_ident);
SkipUntil(tok::r_paren, /*StopAtSemi=*/true, /*DontConsume=*/true); SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch);
// Forget we parsed anything. // Forget we parsed anything.
ParamInfo.clear(); ParamInfo.clear();
return; return;
@ -5368,7 +5373,7 @@ void Parser::ParseParameterDeclarationClause(
DefArgResult = ParseAssignmentExpression(); DefArgResult = ParseAssignmentExpression();
if (DefArgResult.isInvalid()) { if (DefArgResult.isInvalid()) {
Actions.ActOnParamDefaultArgumentError(Param); Actions.ActOnParamDefaultArgumentError(Param);
SkipUntil(tok::comma, tok::r_paren, true, true); SkipUntil(tok::comma, tok::r_paren, StopAtSemi | StopBeforeMatch);
} else { } else {
// Inform the actions module about the default argument // Inform the actions module about the default argument
Actions.ActOnParamDefaultArgument(Param, EqualLoc, Actions.ActOnParamDefaultArgument(Param, EqualLoc,
@ -5503,7 +5508,7 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
if (NumElements.isInvalid()) { if (NumElements.isInvalid()) {
D.setInvalidType(true); D.setInvalidType(true);
// If the expression was invalid, skip it. // If the expression was invalid, skip it.
SkipUntil(tok::r_square); SkipUntil(tok::r_square, StopAtSemi);
return; return;
} }
@ -5600,7 +5605,7 @@ void Parser::ParseAtomicSpecifier(DeclSpec &DS) {
TypeResult Result = ParseTypeName(); TypeResult Result = ParseTypeName();
if (Result.isInvalid()) { if (Result.isInvalid()) {
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return; return;
} }

View File

@ -124,13 +124,13 @@ Decl *Parser::ParseNamespace(unsigned Context,
<< SourceRange(ExtraNamespaceLoc.front(), ExtraIdentLoc.back()); << SourceRange(ExtraNamespaceLoc.front(), ExtraIdentLoc.back());
} }
Diag(T.getOpenLocation(), diag::err_namespace_nonnamespace_scope); Diag(T.getOpenLocation(), diag::err_namespace_nonnamespace_scope);
SkipUntil(tok::r_brace, false); SkipUntil(tok::r_brace);
return 0; return 0;
} }
if (!ExtraIdent.empty()) { if (!ExtraIdent.empty()) {
TentativeParsingAction TPA(*this); TentativeParsingAction TPA(*this);
SkipUntil(tok::r_brace, /*StopAtSemi*/false, /*DontConsume*/true); SkipUntil(tok::r_brace, StopBeforeMatch);
Token rBraceToken = Tok; Token rBraceToken = Tok;
TPA.Revert(); TPA.Revert();
@ -742,8 +742,7 @@ SourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) {
Result = ParseExpression(); Result = ParseExpression();
if (Result.isInvalid()) { if (Result.isInvalid()) {
DS.SetTypeSpecError(); DS.SetTypeSpecError();
if (SkipUntil(tok::r_paren, /*StopAtSemi=*/true, if (SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch)) {
/*DontConsume=*/true)) {
EndLoc = ConsumeParen(); EndLoc = ConsumeParen();
} else { } else {
if (PP.isBacktrackEnabled() && Tok.is(tok::semi)) { if (PP.isBacktrackEnabled() && Tok.is(tok::semi)) {
@ -826,7 +825,7 @@ void Parser::ParseUnderlyingTypeSpecifier(DeclSpec &DS) {
TypeResult Result = ParseTypeName(); TypeResult Result = ParseTypeName();
if (Result.isInvalid()) { if (Result.isInvalid()) {
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return; return;
} }
@ -1293,7 +1292,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
<< TemplateId->Name << static_cast<int>(TemplateId->Kind) << Range; << TemplateId->Name << static_cast<int>(TemplateId->Kind) << Range;
DS.SetTypeSpecError(); DS.SetTypeSpecError();
SkipUntil(tok::semi, false, true); SkipUntil(tok::semi, StopBeforeMatch);
return; return;
} }
} }
@ -1341,7 +1340,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
// Skip everything up to the semicolon, so that this looks like a proper // Skip everything up to the semicolon, so that this looks like a proper
// friend class (or template thereof) declaration. // friend class (or template thereof) declaration.
SkipUntil(tok::semi, true, true); SkipUntil(tok::semi, StopBeforeMatch);
TUK = Sema::TUK_Friend; TUK = Sema::TUK_Friend;
} else { } else {
// Okay, this is a class definition. // Okay, this is a class definition.
@ -1360,12 +1359,12 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
while (true) { while (true) {
if (Tok.is(tok::l_square) && NextToken().is(tok::l_square)) { if (Tok.is(tok::l_square) && NextToken().is(tok::l_square)) {
ConsumeBracket(); ConsumeBracket();
if (!SkipUntil(tok::r_square)) if (!SkipUntil(tok::r_square, StopAtSemi))
break; break;
} else if (Tok.is(tok::kw_alignas) && NextToken().is(tok::l_paren)) { } else if (Tok.is(tok::kw_alignas) && NextToken().is(tok::l_paren)) {
ConsumeToken(); ConsumeToken();
ConsumeParen(); ConsumeParen();
if (!SkipUntil(tok::r_paren)) if (!SkipUntil(tok::r_paren, StopAtSemi))
break; break;
} else { } else {
break; break;
@ -1430,7 +1429,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
<< DeclSpec::getSpecifierName(TagType); << DeclSpec::getSpecifierName(TagType);
} }
SkipUntil(tok::comma, true); SkipUntil(tok::comma, StopAtSemi);
return; return;
} }
@ -1673,7 +1672,7 @@ void Parser::ParseBaseClause(Decl *ClassDecl) {
if (Result.isInvalid()) { if (Result.isInvalid()) {
// Skip the rest of this base specifier, up until the comma or // Skip the rest of this base specifier, up until the comma or
// opening brace. // opening brace.
SkipUntil(tok::comma, tok::l_brace, true, true); SkipUntil(tok::comma, tok::l_brace, StopAtSemi | StopBeforeMatch);
} else { } else {
// Add this to our array of base specifiers. // Add this to our array of base specifiers.
BaseInfo.push_back(Result.get()); BaseInfo.push_back(Result.get());
@ -1955,7 +1954,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
Diag(Tok, diag::err_at_in_class); Diag(Tok, diag::err_at_in_class);
ConsumeToken(); ConsumeToken();
SkipUntil(tok::r_brace); SkipUntil(tok::r_brace, StopAtSemi);
return; return;
} }
@ -2056,7 +2055,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
if (Tok.is(tok::kw_namespace)) { if (Tok.is(tok::kw_namespace)) {
Diag(UsingLoc, diag::err_using_namespace_in_class); Diag(UsingLoc, diag::err_using_namespace_in_class);
SkipUntil(tok::semi, true, true); SkipUntil(tok::semi, StopBeforeMatch);
} else { } else {
SourceLocation DeclEnd; SourceLocation DeclEnd;
// Otherwise, it must be a using-declaration or an alias-declaration. // Otherwise, it must be a using-declaration or an alias-declaration.
@ -2112,7 +2111,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
// Error parsing the declarator? // Error parsing the declarator?
if (!DeclaratorInfo.hasName()) { if (!DeclaratorInfo.hasName()) {
// If so, skip until the semi-colon or a }. // If so, skip until the semi-colon or a }.
SkipUntil(tok::r_brace, true, true); SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
if (Tok.is(tok::semi)) if (Tok.is(tok::semi))
ConsumeToken(); ConsumeToken();
return; return;
@ -2131,7 +2130,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
EqualLoc = ConsumeToken(); EqualLoc = ConsumeToken();
Init = ParseInitializer(); Init = ParseInitializer();
if (Init.isInvalid()) if (Init.isInvalid())
SkipUntil(tok::comma, true, true); SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);
else else
HasInitializer = true; HasInitializer = true;
} }
@ -2169,7 +2168,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
if (!DeclaratorInfo.isFunctionDeclarator()) { if (!DeclaratorInfo.isFunctionDeclarator()) {
Diag(DeclaratorInfo.getIdentifierLoc(), diag::err_func_def_no_params); Diag(DeclaratorInfo.getIdentifierLoc(), diag::err_func_def_no_params);
ConsumeBrace(); ConsumeBrace();
SkipUntil(tok::r_brace, /*StopAtSemi*/false); SkipUntil(tok::r_brace);
// Consume the optional ';' // Consume the optional ';'
if (Tok.is(tok::semi)) if (Tok.is(tok::semi))
@ -2224,7 +2223,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
ConsumeToken(); ConsumeToken();
BitfieldSize = ParseConstantExpression(); BitfieldSize = ParseConstantExpression();
if (BitfieldSize.isInvalid()) if (BitfieldSize.isInvalid())
SkipUntil(tok::comma, true, true); SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);
} }
// If a simple-asm-expr is present, parse it. // If a simple-asm-expr is present, parse it.
@ -2232,7 +2231,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
SourceLocation Loc; SourceLocation Loc;
ExprResult AsmLabel(ParseSimpleAsm(&Loc)); ExprResult AsmLabel(ParseSimpleAsm(&Loc));
if (AsmLabel.isInvalid()) if (AsmLabel.isInvalid())
SkipUntil(tok::comma, true, true); SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);
DeclaratorInfo.setAsmLabel(AsmLabel.release()); DeclaratorInfo.setAsmLabel(AsmLabel.release());
DeclaratorInfo.SetRangeEnd(Loc); DeclaratorInfo.SetRangeEnd(Loc);
@ -2249,7 +2248,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
if ((Tok.is(tok::equal) || Tok.is(tok::l_brace)) && !HasInitializer) { if ((Tok.is(tok::equal) || Tok.is(tok::l_brace)) && !HasInitializer) {
if (BitfieldSize.get()) { if (BitfieldSize.get()) {
Diag(Tok, diag::err_bitfield_member_init); Diag(Tok, diag::err_bitfield_member_init);
SkipUntil(tok::comma, true, true); SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);
} else { } else {
HasInitializer = true; HasInitializer = true;
if (!DeclaratorInfo.isDeclarationOfFunction() && if (!DeclaratorInfo.isDeclarationOfFunction() &&
@ -2316,7 +2315,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
// A brace-or-equal-initializer for a member-declarator is not an // A brace-or-equal-initializer for a member-declarator is not an
// initializer in the grammar, so this is ill-formed. // initializer in the grammar, so this is ill-formed.
Diag(Tok, diag::err_incomplete_array_member_init); Diag(Tok, diag::err_incomplete_array_member_init);
SkipUntil(tok::comma, true, true); SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);
// Avoid later warnings about a class member of incomplete type. // Avoid later warnings about a class member of incomplete type.
if (ThisDecl) if (ThisDecl)
@ -2330,7 +2329,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
ThisDecl, DeclaratorInfo.isDeclarationOfFunction(), EqualLoc); ThisDecl, DeclaratorInfo.isDeclarationOfFunction(), EqualLoc);
if (Init.isInvalid()) if (Init.isInvalid())
SkipUntil(tok::comma, true, true); SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);
else if (ThisDecl) else if (ThisDecl)
Actions.AddInitializerToDecl(ThisDecl, Init.get(), EqualLoc.isInvalid(), Actions.AddInitializerToDecl(ThisDecl, Init.get(), EqualLoc.isInvalid(),
DS.containsPlaceholderType()); DS.containsPlaceholderType());
@ -2396,7 +2395,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
if (ExpectSemi && if (ExpectSemi &&
ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list)) { ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list)) {
// Skip to end of block or statement. // Skip to end of block or statement.
SkipUntil(tok::r_brace, true, true); SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
// If we stopped at a ';', eat it. // If we stopped at a ';', eat it.
if (Tok.is(tok::semi)) ConsumeToken(); if (Tok.is(tok::semi)) ConsumeToken();
return; return;
@ -2678,7 +2677,7 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
T.consumeClose(); T.consumeClose();
} else { } else {
SkipUntil(tok::r_brace, false, false); SkipUntil(tok::r_brace);
} }
// If attributes exist after class contents, parse them. // If attributes exist after class contents, parse them.
@ -2800,7 +2799,7 @@ void Parser::ParseConstructorInitializer(Decl *ConstructorDecl) {
} else { } else {
// Skip over garbage, until we get to '{'. Don't eat the '{'. // 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_lbrace_or_comma);
SkipUntil(tok::l_brace, true, true); SkipUntil(tok::l_brace, StopAtSemi | StopBeforeMatch);
break; break;
} }
} while (true); } while (true);
@ -2881,7 +2880,7 @@ Parser::MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {
ExprVector ArgExprs; ExprVector ArgExprs;
CommaLocsTy CommaLocs; CommaLocsTy CommaLocs;
if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, CommaLocs)) { if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, CommaLocs)) {
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return true; return true;
} }
@ -3263,7 +3262,7 @@ void Parser::ParseCXX11AttributeSpecifier(ParsedAttributes &attrs,
AttrName = TryParseCXX11AttributeIdentifier(AttrLoc); AttrName = TryParseCXX11AttributeIdentifier(AttrLoc);
if (!AttrName) { if (!AttrName) {
Diag(Tok.getLocation(), diag::err_expected_ident); Diag(Tok.getLocation(), diag::err_expected_ident);
SkipUntil(tok::r_square, tok::comma, true, true); SkipUntil(tok::r_square, tok::comma, StopAtSemi | StopBeforeMatch);
continue; continue;
} }
} }
@ -3289,7 +3288,7 @@ void Parser::ParseCXX11AttributeSpecifier(ParsedAttributes &attrs,
// FIXME: handle other formats of c++11 attribute arguments // FIXME: handle other formats of c++11 attribute arguments
ConsumeParen(); ConsumeParen();
SkipUntil(tok::r_paren, false); SkipUntil(tok::r_paren);
} }
} }
@ -3308,11 +3307,11 @@ void Parser::ParseCXX11AttributeSpecifier(ParsedAttributes &attrs,
} }
if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare)) if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare))
SkipUntil(tok::r_square, false); SkipUntil(tok::r_square);
if (endLoc) if (endLoc)
*endLoc = Tok.getLocation(); *endLoc = Tok.getLocation();
if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare)) if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare))
SkipUntil(tok::r_square, false); SkipUntil(tok::r_square);
} }
/// ParseCXX11Attributes - Parse a C++11 attribute-specifier-seq. /// ParseCXX11Attributes - Parse a C++11 attribute-specifier-seq.
@ -3380,7 +3379,7 @@ void Parser::ParseMicrosoftAttributes(ParsedAttributes &attrs,
while (Tok.is(tok::l_square)) { while (Tok.is(tok::l_square)) {
// FIXME: If this is actually a C++11 attribute, parse it as one. // FIXME: If this is actually a C++11 attribute, parse it as one.
ConsumeBracket(); ConsumeBracket();
SkipUntil(tok::r_square, true, true); SkipUntil(tok::r_square, StopAtSemi | StopBeforeMatch);
if (endLoc) *endLoc = Tok.getLocation(); if (endLoc) *endLoc = Tok.getLocation();
ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); ExpectAndConsume(tok::r_square, diag::err_expected_rsquare);
} }

View File

@ -1391,12 +1391,12 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
if (Tok.is(tok::greatergreatergreater)) { if (Tok.is(tok::greatergreatergreater)) {
ConsumeToken(); ConsumeToken();
} else if (LHS.isInvalid()) { } else if (LHS.isInvalid()) {
SkipUntil(tok::greatergreatergreater); SkipUntil(tok::greatergreatergreater, StopAtSemi);
} else { } else {
// There was an error closing the brackets // There was an error closing the brackets
Diag(Tok, diag::err_expected_ggg); Diag(Tok, diag::err_expected_ggg);
Diag(OpenLoc, diag::note_matching) << "<<<"; Diag(OpenLoc, diag::note_matching) << "<<<";
SkipUntil(tok::greatergreatergreater); SkipUntil(tok::greatergreatergreater, StopAtSemi);
LHS = ExprError(); LHS = ExprError();
} }
@ -1442,7 +1442,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
// Match the ')'. // Match the ')'.
if (LHS.isInvalid()) { if (LHS.isInvalid()) {
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
} else if (Tok.isNot(tok::r_paren)) { } else if (Tok.isNot(tok::r_paren)) {
PT.consumeClose(); PT.consumeClose();
LHS = ExprError(); LHS = ExprError();
@ -1696,7 +1696,7 @@ ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() {
RParenLoc = PP.getLocForEndOfToken(NameLoc); RParenLoc = PP.getLocForEndOfToken(NameLoc);
} else { } else {
Diag(Tok, diag::err_expected_parameter_pack); Diag(Tok, diag::err_expected_parameter_pack);
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
} }
} else if (Tok.is(tok::identifier)) { } else if (Tok.is(tok::identifier)) {
Name = Tok.getIdentifierInfo(); Name = Tok.getIdentifierInfo();
@ -1822,7 +1822,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
SourceLocation TypeLoc = Tok.getLocation(); SourceLocation TypeLoc = Tok.getLocation();
TypeResult Ty = ParseTypeName(); TypeResult Ty = ParseTypeName();
if (Ty.isInvalid()) { if (Ty.isInvalid()) {
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return ExprError(); return ExprError();
} }
@ -1832,7 +1832,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
// We must have at least one identifier here. // We must have at least one identifier here.
if (Tok.isNot(tok::identifier)) { if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident); Diag(Tok, diag::err_expected_ident);
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return ExprError(); return ExprError();
} }
@ -1854,7 +1854,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
if (Tok.isNot(tok::identifier)) { if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident); Diag(Tok, diag::err_expected_ident);
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return ExprError(); return ExprError();
} }
Comps.back().U.IdentInfo = Tok.getIdentifierInfo(); Comps.back().U.IdentInfo = Tok.getIdentifierInfo();
@ -1872,7 +1872,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
Comps.back().LocStart = ST.getOpenLocation(); Comps.back().LocStart = ST.getOpenLocation();
Res = ParseExpression(); Res = ParseExpression();
if (Res.isInvalid()) { if (Res.isInvalid()) {
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return Res; return Res;
} }
Comps.back().U.E = Res.release(); Comps.back().U.E = Res.release();
@ -1899,7 +1899,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
case tok::kw___builtin_choose_expr: { case tok::kw___builtin_choose_expr: {
ExprResult Cond(ParseAssignmentExpression()); ExprResult Cond(ParseAssignmentExpression());
if (Cond.isInvalid()) { if (Cond.isInvalid()) {
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return Cond; return Cond;
} }
if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren)) if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
@ -1907,7 +1907,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
ExprResult Expr1(ParseAssignmentExpression()); ExprResult Expr1(ParseAssignmentExpression());
if (Expr1.isInvalid()) { if (Expr1.isInvalid()) {
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return Expr1; return Expr1;
} }
if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren)) if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
@ -1915,7 +1915,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
ExprResult Expr2(ParseAssignmentExpression()); ExprResult Expr2(ParseAssignmentExpression());
if (Expr2.isInvalid()) { if (Expr2.isInvalid()) {
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return Expr2; return Expr2;
} }
if (Tok.isNot(tok::r_paren)) { if (Tok.isNot(tok::r_paren)) {
@ -1930,7 +1930,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
// The first argument is an expression to be converted, followed by a comma. // The first argument is an expression to be converted, followed by a comma.
ExprResult Expr(ParseAssignmentExpression()); ExprResult Expr(ParseAssignmentExpression());
if (Expr.isInvalid()) { if (Expr.isInvalid()) {
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return ExprError(); return ExprError();
} }
@ -1946,7 +1946,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
// Attempt to consume the r-paren. // Attempt to consume the r-paren.
if (Tok.isNot(tok::r_paren)) { if (Tok.isNot(tok::r_paren)) {
Diag(Tok, diag::err_expected_rparen); Diag(Tok, diag::err_expected_rparen);
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return ExprError(); return ExprError();
} }
@ -1958,7 +1958,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
// The first argument is an expression to be converted, followed by a comma. // The first argument is an expression to be converted, followed by a comma.
ExprResult Expr(ParseAssignmentExpression()); ExprResult Expr(ParseAssignmentExpression());
if (Expr.isInvalid()) { if (Expr.isInvalid()) {
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return ExprError(); return ExprError();
} }
@ -1974,7 +1974,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
// Attempt to consume the r-paren. // Attempt to consume the r-paren.
if (Tok.isNot(tok::r_paren)) { if (Tok.isNot(tok::r_paren)) {
Diag(Tok, diag::err_expected_rparen); Diag(Tok, diag::err_expected_rparen);
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return ExprError(); return ExprError();
} }
@ -2223,7 +2223,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
// Match the ')'. // Match the ')'.
if (Result.isInvalid()) { if (Result.isInvalid()) {
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return ExprError(); return ExprError();
} }
@ -2309,13 +2309,13 @@ ExprResult Parser::ParseGenericSelectionExpression() {
EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated); EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated);
ControllingExpr = ParseAssignmentExpression(); ControllingExpr = ParseAssignmentExpression();
if (ControllingExpr.isInvalid()) { if (ControllingExpr.isInvalid()) {
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return ExprError(); return ExprError();
} }
} }
if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "")) { if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "")) {
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return ExprError(); return ExprError();
} }
@ -2330,7 +2330,7 @@ ExprResult Parser::ParseGenericSelectionExpression() {
if (!DefaultLoc.isInvalid()) { if (!DefaultLoc.isInvalid()) {
Diag(Tok, diag::err_duplicate_default_assoc); Diag(Tok, diag::err_duplicate_default_assoc);
Diag(DefaultLoc, diag::note_previous_default_assoc); Diag(DefaultLoc, diag::note_previous_default_assoc);
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return ExprError(); return ExprError();
} }
DefaultLoc = ConsumeToken(); DefaultLoc = ConsumeToken();
@ -2339,7 +2339,7 @@ ExprResult Parser::ParseGenericSelectionExpression() {
ColonProtectionRAIIObject X(*this); ColonProtectionRAIIObject X(*this);
TypeResult TR = ParseTypeName(); TypeResult TR = ParseTypeName();
if (TR.isInvalid()) { if (TR.isInvalid()) {
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return ExprError(); return ExprError();
} }
Ty = TR.release(); Ty = TR.release();
@ -2347,7 +2347,7 @@ ExprResult Parser::ParseGenericSelectionExpression() {
Types.push_back(Ty); Types.push_back(Ty);
if (ExpectAndConsume(tok::colon, diag::err_expected_colon, "")) { if (ExpectAndConsume(tok::colon, diag::err_expected_colon, "")) {
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return ExprError(); return ExprError();
} }
@ -2355,7 +2355,7 @@ ExprResult Parser::ParseGenericSelectionExpression() {
// evaluated context. // evaluated context.
ExprResult ER(ParseAssignmentExpression()); ExprResult ER(ParseAssignmentExpression());
if (ER.isInvalid()) { if (ER.isInvalid()) {
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return ExprError(); return ExprError();
} }
Exprs.push_back(ER.release()); Exprs.push_back(ER.release());

View File

@ -637,9 +637,9 @@ ExprResult Parser::ParseLambdaExpression() {
Optional<unsigned> DiagID(ParseLambdaIntroducer(Intro)); Optional<unsigned> DiagID(ParseLambdaIntroducer(Intro));
if (DiagID) { if (DiagID) {
Diag(Tok, DiagID.getValue()); Diag(Tok, DiagID.getValue());
SkipUntil(tok::r_square); SkipUntil(tok::r_square, StopAtSemi);
SkipUntil(tok::l_brace); SkipUntil(tok::l_brace, StopAtSemi);
SkipUntil(tok::r_brace); SkipUntil(tok::r_brace, StopAtSemi);
return ExprError(); return ExprError();
} }
@ -1205,7 +1205,7 @@ ExprResult Parser::ParseCXXTypeid() {
// Match the ')'. // Match the ')'.
if (Result.isInvalid()) if (Result.isInvalid())
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
else { else {
T.consumeClose(); T.consumeClose();
RParenLoc = T.getCloseLocation(); RParenLoc = T.getCloseLocation();
@ -1255,7 +1255,7 @@ ExprResult Parser::ParseCXXUuidof() {
// Match the ')'. // Match the ')'.
if (Result.isInvalid()) if (Result.isInvalid())
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
else { else {
T.consumeClose(); T.consumeClose();
@ -1441,7 +1441,7 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
if (Tok.isNot(tok::r_paren)) { if (Tok.isNot(tok::r_paren)) {
if (ParseExpressionList(Exprs, CommaLocs)) { if (ParseExpressionList(Exprs, CommaLocs)) {
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return ExprError(); return ExprError();
} }
} }
@ -1527,7 +1527,7 @@ bool Parser::ParseCXXCondition(ExprResult &ExprOut,
SourceLocation Loc; SourceLocation Loc;
ExprResult AsmLabel(ParseSimpleAsm(&Loc)); ExprResult AsmLabel(ParseSimpleAsm(&Loc));
if (AsmLabel.isInvalid()) { if (AsmLabel.isInvalid()) {
SkipUntil(tok::semi); SkipUntil(tok::semi, StopAtSemi);
return true; return true;
} }
DeclaratorInfo.setAsmLabel(AsmLabel.release()); DeclaratorInfo.setAsmLabel(AsmLabel.release());
@ -1559,7 +1559,7 @@ bool Parser::ParseCXXCondition(ExprResult &ExprOut,
} else if (Tok.is(tok::l_paren)) { } else if (Tok.is(tok::l_paren)) {
// This was probably an attempt to initialize the variable. // This was probably an attempt to initialize the variable.
SourceLocation LParen = ConsumeParen(), RParen = LParen; SourceLocation LParen = ConsumeParen(), RParen = LParen;
if (SkipUntil(tok::r_paren, true, /*DontConsume=*/true)) if (SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch))
RParen = ConsumeParen(); RParen = ConsumeParen();
Diag(DeclOut ? DeclOut->getLocation() : LParen, Diag(DeclOut ? DeclOut->getLocation() : LParen,
diag::err_expected_init_in_condition_lparen) diag::err_expected_init_in_condition_lparen)
@ -2419,14 +2419,14 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
T.consumeOpen(); T.consumeOpen();
PlacementLParen = T.getOpenLocation(); PlacementLParen = T.getOpenLocation();
if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) { if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) {
SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch);
return ExprError(); return ExprError();
} }
T.consumeClose(); T.consumeClose();
PlacementRParen = T.getCloseLocation(); PlacementRParen = T.getCloseLocation();
if (PlacementRParen.isInvalid()) { if (PlacementRParen.isInvalid()) {
SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch);
return ExprError(); return ExprError();
} }
@ -2469,7 +2469,7 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
} }
} }
if (DeclaratorInfo.isInvalidType()) { if (DeclaratorInfo.isInvalidType()) {
SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch);
return ExprError(); return ExprError();
} }
@ -2484,14 +2484,14 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
if (Tok.isNot(tok::r_paren)) { if (Tok.isNot(tok::r_paren)) {
CommaLocsTy CommaLocs; CommaLocsTy CommaLocs;
if (ParseExpressionList(ConstructorArgs, CommaLocs)) { if (ParseExpressionList(ConstructorArgs, CommaLocs)) {
SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch);
return ExprError(); return ExprError();
} }
} }
T.consumeClose(); T.consumeClose();
ConstructorRParen = T.getCloseLocation(); ConstructorRParen = T.getCloseLocation();
if (ConstructorRParen.isInvalid()) { if (ConstructorRParen.isInvalid()) {
SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch);
return ExprError(); return ExprError();
} }
Initializer = Actions.ActOnParenListExpr(ConstructorLParen, Initializer = Actions.ActOnParenListExpr(ConstructorLParen,
@ -2532,7 +2532,7 @@ void Parser::ParseDirectNewDeclarator(Declarator &D) {
: ParseConstantExpression()); : ParseConstantExpression());
if (Size.isInvalid()) { if (Size.isInvalid()) {
// Recover // Recover
SkipUntil(tok::r_square); SkipUntil(tok::r_square, StopAtSemi);
return; return;
} }
first = false; first = false;
@ -2762,18 +2762,18 @@ ExprResult Parser::ParseBinaryTypeTrait() {
TypeResult LhsTy = ParseTypeName(); TypeResult LhsTy = ParseTypeName();
if (LhsTy.isInvalid()) { if (LhsTy.isInvalid()) {
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return ExprError(); return ExprError();
} }
if (ExpectAndConsume(tok::comma, diag::err_expected_comma)) { if (ExpectAndConsume(tok::comma, diag::err_expected_comma)) {
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return ExprError(); return ExprError();
} }
TypeResult RhsTy = ParseTypeName(); TypeResult RhsTy = ParseTypeName();
if (RhsTy.isInvalid()) { if (RhsTy.isInvalid()) {
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return ExprError(); return ExprError();
} }
@ -2852,8 +2852,8 @@ ExprResult Parser::ParseArrayTypeTrait() {
TypeResult Ty = ParseTypeName(); TypeResult Ty = ParseTypeName();
if (Ty.isInvalid()) { if (Ty.isInvalid()) {
SkipUntil(tok::comma); SkipUntil(tok::comma, StopAtSemi);
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return ExprError(); return ExprError();
} }
@ -2865,7 +2865,7 @@ ExprResult Parser::ParseArrayTypeTrait() {
} }
case ATT_ArrayExtent: { case ATT_ArrayExtent: {
if (ExpectAndConsume(tok::comma, diag::err_expected_comma)) { if (ExpectAndConsume(tok::comma, diag::err_expected_comma)) {
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return ExprError(); return ExprError();
} }
@ -3022,7 +3022,7 @@ Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
// Match the ')'. // Match the ')'.
if (Result.isInvalid()) { if (Result.isInvalid()) {
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return ExprError(); return ExprError();
} }

View File

@ -244,7 +244,7 @@ ExprResult Parser::ParseInitializerWithPotentialDesignator() {
bool IsExpr; bool IsExpr;
void *TypeOrExpr; void *TypeOrExpr;
if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) { if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) {
SkipUntil(tok::r_square); SkipUntil(tok::r_square, StopAtSemi);
return ExprError(); return ExprError();
} }
@ -285,7 +285,7 @@ ExprResult Parser::ParseInitializerWithPotentialDesignator() {
0); 0);
ConsumeToken(); // the identifier ConsumeToken(); // the identifier
if (!ReceiverType) { if (!ReceiverType) {
SkipUntil(tok::r_square); SkipUntil(tok::r_square, StopAtSemi);
return ExprError(); return ExprError();
} }
@ -312,7 +312,7 @@ ExprResult Parser::ParseInitializerWithPotentialDesignator() {
if (!Idx.get()) { if (!Idx.get()) {
Idx = ParseAssignmentExpression(); Idx = ParseAssignmentExpression();
if (Idx.isInvalid()) { if (Idx.isInvalid()) {
SkipUntil(tok::r_square); SkipUntil(tok::r_square, StopAtSemi);
return Idx; return Idx;
} }
} }
@ -340,7 +340,7 @@ ExprResult Parser::ParseInitializerWithPotentialDesignator() {
ExprResult RHS(ParseConstantExpression()); ExprResult RHS(ParseConstantExpression());
if (RHS.isInvalid()) { if (RHS.isInvalid()) {
SkipUntil(tok::r_square); SkipUntil(tok::r_square, StopAtSemi);
return RHS; return RHS;
} }
Desig.AddDesignator(Designator::getArrayRange(Idx.release(), Desig.AddDesignator(Designator::getArrayRange(Idx.release(),
@ -457,7 +457,7 @@ ExprResult Parser::ParseBraceInitializer() {
// immediately, it can't be an error, since there is no other way of // immediately, it can't be an error, since there is no other way of
// leaving this loop except through this if. // leaving this loop except through this if.
if (Tok.isNot(tok::comma)) { if (Tok.isNot(tok::comma)) {
SkipUntil(tok::r_brace, false, true); SkipUntil(tok::r_brace, StopBeforeMatch);
break; break;
} }
} }

View File

@ -403,7 +403,7 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey,
// method definitions. // method definitions.
if (ExpectAndConsumeSemi(diag::err_expected_semi_after_method_proto)) { if (ExpectAndConsumeSemi(diag::err_expected_semi_after_method_proto)) {
// We didn't find a semi and we error'ed out. Skip until a ';' or '@'. // We didn't find a semi and we error'ed out. Skip until a ';' or '@'.
SkipUntil(tok::at, /*StopAtSemi=*/true, /*DontConsume=*/true); SkipUntil(tok::at, StopAtSemi | StopBeforeMatch);
if (Tok.is(tok::semi)) if (Tok.is(tok::semi))
ConsumeToken(); ConsumeToken();
} }
@ -476,7 +476,7 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey,
// or something like that. // or something like that.
Diag(AtLoc, diag::err_objc_illegal_interface_qual); Diag(AtLoc, diag::err_objc_illegal_interface_qual);
// Skip until we see an '@' or '}' or ';'. // Skip until we see an '@' or '}' or ';'.
SkipUntil(tok::r_brace, tok::at); SkipUntil(tok::r_brace, tok::at, StopAtSemi);
break; break;
case tok::objc_implementation: case tok::objc_implementation:
@ -628,7 +628,7 @@ void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) {
if (!SelIdent) { if (!SelIdent) {
Diag(Tok, diag::err_objc_expected_selector_for_getter_setter) Diag(Tok, diag::err_objc_expected_selector_for_getter_setter)
<< IsSetter; << IsSetter;
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return; return;
} }
@ -646,7 +646,7 @@ void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) {
} }
} else { } else {
Diag(AttrName, diag::err_objc_expected_property_attr) << II; Diag(AttrName, diag::err_objc_expected_property_attr) << II;
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return; return;
} }
@ -943,7 +943,7 @@ ParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS,
else if (Tok.getLocation() == TypeStartLoc) { else if (Tok.getLocation() == TypeStartLoc) {
// If we didn't eat any tokens, then this isn't a type. // If we didn't eat any tokens, then this isn't a type.
Diag(Tok, diag::err_expected_type); Diag(Tok, diag::err_expected_type);
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
} else { } else {
// Otherwise, we found *something*, but didn't get a ')' in the right // Otherwise, we found *something*, but didn't get a ')' in the right
// place. Emit an error then return what we have as the type. // place. Emit an error then return what we have as the type.
@ -1020,7 +1020,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
Diag(Tok, diag::err_expected_selector_for_method) Diag(Tok, diag::err_expected_selector_for_method)
<< SourceRange(mLoc, Tok.getLocation()); << SourceRange(mLoc, Tok.getLocation());
// Skip until we get a ; or @. // Skip until we get a ; or @.
SkipUntil(tok::at, true /*StopAtSemi*/, true /*don't consume*/); SkipUntil(tok::at, StopAtSemi | StopBeforeMatch);
return 0; return 0;
} }
@ -1199,7 +1199,7 @@ ParseObjCProtocolReferences(SmallVectorImpl<Decl *> &Protocols,
if (Tok.isNot(tok::identifier)) { if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident); Diag(Tok, diag::err_expected_ident);
SkipUntil(tok::greater); SkipUntil(tok::greater, StopAtSemi);
return true; return true;
} }
ProtocolIdents.push_back(std::make_pair(Tok.getIdentifierInfo(), ProtocolIdents.push_back(std::make_pair(Tok.getIdentifierInfo(),
@ -1372,7 +1372,7 @@ void Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl,
} else { } else {
Diag(Tok, diag::err_expected_semi_decl_list); Diag(Tok, diag::err_expected_semi_decl_list);
// Skip to end of block or statement // Skip to end of block or statement
SkipUntil(tok::r_brace, true, true); SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
} }
} }
HelperActionsForIvarDeclarations(interfaceDecl, atLoc, HelperActionsForIvarDeclarations(interfaceDecl, atLoc,
@ -1534,7 +1534,7 @@ Parser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc) {
} }
if (Tok.isNot(tok::r_paren)) { if (Tok.isNot(tok::r_paren)) {
Diag(Tok, diag::err_expected_rparen); Diag(Tok, diag::err_expected_rparen);
SkipUntil(tok::r_paren, false); // don't stop at ';' SkipUntil(tok::r_paren); // don't stop at ';'
return DeclGroupPtrTy(); return DeclGroupPtrTy();
} }
rparenLoc = ConsumeParen(); rparenLoc = ConsumeParen();
@ -1809,7 +1809,7 @@ Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) {
Diag(Tok, diag::err_expected_rparen); Diag(Tok, diag::err_expected_rparen);
// Skip forward until we see a left brace, but don't consume it. // Skip forward until we see a left brace, but don't consume it.
SkipUntil(tok::l_brace, true, true); SkipUntil(tok::l_brace, StopAtSemi | StopBeforeMatch);
} }
// Require a compound statement. // Require a compound statement.
@ -1899,7 +1899,7 @@ StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
if (Tok.is(tok::r_paren)) if (Tok.is(tok::r_paren))
RParenLoc = ConsumeParen(); RParenLoc = ConsumeParen();
else // Skip over garbage, until we get to ')'. Eat the ')'. else // Skip over garbage, until we get to ')'. Eat the ')'.
SkipUntil(tok::r_paren, true, false); SkipUntil(tok::r_paren, StopAtSemi);
StmtResult CatchBody(true); StmtResult CatchBody(true);
if (Tok.is(tok::l_brace)) if (Tok.is(tok::l_brace))
@ -2032,7 +2032,7 @@ Decl *Parser::ParseObjCMethodDefinition() {
Diag(Tok, diag::err_expected_method_body); Diag(Tok, diag::err_expected_method_body);
// Skip over garbage, until we get to '{'. Don't eat the '{'. // Skip over garbage, until we get to '{'. Don't eat the '{'.
SkipUntil(tok::l_brace, true, true); SkipUntil(tok::l_brace, StopAtSemi | StopBeforeMatch);
// If we didn't find the '{', bail out. // If we didn't find the '{', bail out.
if (Tok.isNot(tok::l_brace)) if (Tok.isNot(tok::l_brace))
@ -2041,7 +2041,7 @@ Decl *Parser::ParseObjCMethodDefinition() {
if (!MDecl) { if (!MDecl) {
ConsumeBrace(); ConsumeBrace();
SkipUntil(tok::r_brace, /*StopAtSemi=*/false); SkipUntil(tok::r_brace);
return 0; return 0;
} }
@ -2351,7 +2351,7 @@ ExprResult Parser::ParseObjCMessageExpression() {
bool IsExpr; bool IsExpr;
void *TypeOrExpr = NULL; void *TypeOrExpr = NULL;
if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) { if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) {
SkipUntil(tok::r_square); SkipUntil(tok::r_square, StopAtSemi);
return ExprError(); return ExprError();
} }
@ -2379,7 +2379,7 @@ ExprResult Parser::ParseObjCMessageExpression() {
case Sema::ObjCClassMessage: case Sema::ObjCClassMessage:
if (!ReceiverType) { if (!ReceiverType) {
SkipUntil(tok::r_square); SkipUntil(tok::r_square, StopAtSemi);
return ExprError(); return ExprError();
} }
@ -2397,7 +2397,7 @@ ExprResult Parser::ParseObjCMessageExpression() {
// Otherwise, an arbitrary expression can be the receiver of a send. // Otherwise, an arbitrary expression can be the receiver of a send.
ExprResult Res(ParseExpression()); ExprResult Res(ParseExpression());
if (Res.isInvalid()) { if (Res.isInvalid()) {
SkipUntil(tok::r_square); SkipUntil(tok::r_square, StopAtSemi);
return Res; return Res;
} }
@ -2483,7 +2483,7 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
// We must manually skip to a ']', otherwise the expression skipper will // 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 // stop at the ']' when it skips to the ';'. We want it to skip beyond
// the enclosing expression. // the enclosing expression.
SkipUntil(tok::r_square); SkipUntil(tok::r_square, StopAtSemi);
return ExprError(); return ExprError();
} }
@ -2520,7 +2520,7 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
// We must manually skip to a ']', otherwise the expression skipper will // 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 // stop at the ']' when it skips to the ';'. We want it to skip beyond
// the enclosing expression. // the enclosing expression.
SkipUntil(tok::r_square); SkipUntil(tok::r_square, StopAtSemi);
return Res; return Res;
} }
@ -2564,7 +2564,7 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
// We must manually skip to a ']', otherwise the expression skipper will // 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 // stop at the ']' when it skips to the ';'. We want it to skip beyond
// the enclosing expression. // the enclosing expression.
SkipUntil(tok::r_square); SkipUntil(tok::r_square, StopAtSemi);
return Res; return Res;
} }
@ -2577,7 +2577,7 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
// We must manually skip to a ']', otherwise the expression skipper will // 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 // stop at the ']' when it skips to the ';'. We want it to skip beyond
// the enclosing expression. // the enclosing expression.
SkipUntil(tok::r_square); SkipUntil(tok::r_square, StopAtSemi);
return ExprError(); return ExprError();
} }
@ -2589,7 +2589,7 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
// We must manually skip to a ']', otherwise the expression skipper will // 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 // stop at the ']' when it skips to the ';'. We want it to skip beyond
// the enclosing expression. // the enclosing expression.
SkipUntil(tok::r_square); SkipUntil(tok::r_square, StopAtSemi);
return ExprError(); return ExprError();
} }
@ -2715,7 +2715,7 @@ ExprResult Parser::ParseObjCArrayLiteral(SourceLocation AtLoc) {
// We must manually skip to a ']', otherwise the expression skipper will // 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 // stop at the ']' when it skips to the ';'. We want it to skip beyond
// the enclosing expression. // the enclosing expression.
SkipUntil(tok::r_square); SkipUntil(tok::r_square, StopAtSemi);
return Res; return Res;
} }
@ -2750,7 +2750,7 @@ ExprResult Parser::ParseObjCDictionaryLiteral(SourceLocation AtLoc) {
// We must manually skip to a '}', otherwise the expression skipper will // 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 // stop at the '}' when it skips to the ';'. We want it to skip beyond
// the enclosing expression. // the enclosing expression.
SkipUntil(tok::r_brace); SkipUntil(tok::r_brace, StopAtSemi);
return KeyExpr; return KeyExpr;
} }
} }
@ -2759,7 +2759,7 @@ ExprResult Parser::ParseObjCDictionaryLiteral(SourceLocation AtLoc) {
ConsumeToken(); ConsumeToken();
} else { } else {
Diag(Tok, diag::err_expected_colon); Diag(Tok, diag::err_expected_colon);
SkipUntil(tok::r_brace); SkipUntil(tok::r_brace, StopAtSemi);
return ExprError(); return ExprError();
} }
@ -2768,7 +2768,7 @@ ExprResult Parser::ParseObjCDictionaryLiteral(SourceLocation AtLoc) {
// We must manually skip to a '}', otherwise the expression skipper will // 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 // stop at the '}' when it skips to the ';'. We want it to skip beyond
// the enclosing expression. // the enclosing expression.
SkipUntil(tok::r_brace); SkipUntil(tok::r_brace, StopAtSemi);
return ValueExpr; return ValueExpr;
} }

View File

@ -31,6 +31,7 @@ using namespace clang;
/// ///
Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirective() { Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirective() {
assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!"); assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
ParenBraceBracketBalancer BalancerRAIIObj(*this);
SourceLocation Loc = ConsumeToken(); SourceLocation Loc = ConsumeToken();
SmallVector<Expr *, 5> Identifiers; SmallVector<Expr *, 5> Identifiers;
@ -47,7 +48,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirective() {
if (Tok.isNot(tok::annot_pragma_openmp_end)) { if (Tok.isNot(tok::annot_pragma_openmp_end)) {
Diag(Tok, diag::warn_omp_extra_tokens_at_eol) Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
<< getOpenMPDirectiveName(OMPD_threadprivate); << getOpenMPDirectiveName(OMPD_threadprivate);
SkipUntil(tok::annot_pragma_openmp_end, false, true); SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
} }
// Skip the last annot_pragma_openmp_end. // Skip the last annot_pragma_openmp_end.
ConsumeToken(); ConsumeToken();
@ -65,7 +66,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirective() {
<< getOpenMPDirectiveName(DKind); << getOpenMPDirectiveName(DKind);
break; break;
} }
SkipUntil(tok::annot_pragma_openmp_end, false); SkipUntil(tok::annot_pragma_openmp_end);
return DeclGroupPtrTy(); return DeclGroupPtrTy();
} }
@ -80,6 +81,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirective() {
/// ///
StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective() { StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective() {
assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!"); assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
ParenBraceBracketBalancer BalancerRAIIObj(*this);
SmallVector<Expr *, 5> Identifiers; SmallVector<Expr *, 5> Identifiers;
SmallVector<OMPClause *, 5> Clauses; SmallVector<OMPClause *, 5> Clauses;
SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, NUM_OPENMP_CLAUSES> SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, NUM_OPENMP_CLAUSES>
@ -103,14 +105,14 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective() {
if (Tok.isNot(tok::annot_pragma_openmp_end)) { if (Tok.isNot(tok::annot_pragma_openmp_end)) {
Diag(Tok, diag::warn_omp_extra_tokens_at_eol) Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
<< getOpenMPDirectiveName(OMPD_threadprivate); << getOpenMPDirectiveName(OMPD_threadprivate);
SkipUntil(tok::annot_pragma_openmp_end, false, true); SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
} }
DeclGroupPtrTy Res = DeclGroupPtrTy Res =
Actions.ActOnOpenMPThreadprivateDirective(Loc, Actions.ActOnOpenMPThreadprivateDirective(Loc,
Identifiers); Identifiers);
Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation()); Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
} }
SkipUntil(tok::annot_pragma_openmp_end, false); SkipUntil(tok::annot_pragma_openmp_end);
break; break;
case OMPD_parallel: { case OMPD_parallel: {
ConsumeToken(); ConsumeToken();
@ -169,13 +171,13 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective() {
break; break;
case OMPD_unknown: case OMPD_unknown:
Diag(Tok, diag::err_omp_unknown_directive); Diag(Tok, diag::err_omp_unknown_directive);
SkipUntil(tok::annot_pragma_openmp_end, false); SkipUntil(tok::annot_pragma_openmp_end);
break; break;
case OMPD_task: case OMPD_task:
case NUM_OPENMP_DIRECTIVES: case NUM_OPENMP_DIRECTIVES:
Diag(Tok, diag::err_omp_unexpected_directive) Diag(Tok, diag::err_omp_unexpected_directive)
<< getOpenMPDirectiveName(DKind); << getOpenMPDirectiveName(DKind);
SkipUntil(tok::annot_pragma_openmp_end, false); SkipUntil(tok::annot_pragma_openmp_end);
break; break;
} }
return Directive; return Directive;
@ -212,17 +214,17 @@ bool Parser::ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind,
ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false)) { ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false)) {
IsCorrect = false; IsCorrect = false;
SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
false, true); StopBeforeMatch);
} else if (ParseUnqualifiedId(SS, false, false, false, ParsedType(), } else if (ParseUnqualifiedId(SS, false, false, false, ParsedType(),
TemplateKWLoc, Name)) { TemplateKWLoc, Name)) {
IsCorrect = false; IsCorrect = false;
SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
false, true); StopBeforeMatch);
} else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) && } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
Tok.isNot(tok::annot_pragma_openmp_end)) { Tok.isNot(tok::annot_pragma_openmp_end)) {
IsCorrect = false; IsCorrect = false;
SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
false, true); StopBeforeMatch);
Diag(PrevTok.getLocation(), diag::err_expected_ident) Diag(PrevTok.getLocation(), diag::err_expected_ident)
<< SourceRange(PrevTok.getLocation(), PrevTokLocation); << SourceRange(PrevTok.getLocation(), PrevTokLocation);
} else { } else {
@ -285,13 +287,13 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
case OMPC_unknown: case OMPC_unknown:
Diag(Tok, diag::warn_omp_extra_tokens_at_eol) Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
<< getOpenMPDirectiveName(DKind); << getOpenMPDirectiveName(DKind);
SkipUntil(tok::annot_pragma_openmp_end, false, true); SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
break; break;
case OMPC_threadprivate: case OMPC_threadprivate:
case NUM_OPENMP_CLAUSES: case NUM_OPENMP_CLAUSES:
Diag(Tok, diag::err_omp_unexpected_clause) Diag(Tok, diag::err_omp_unexpected_clause)
<< getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind); << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
SkipUntil(tok::comma, tok::annot_pragma_openmp_end, false, true); SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
break; break;
} }
return ErrorFound ? 0 : Clause; return ErrorFound ? 0 : Clause;
@ -355,7 +357,7 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {
Vars.push_back(VarExpr.take()); Vars.push_back(VarExpr.take());
} else { } else {
SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
false, true); StopBeforeMatch);
} }
// Skip ',' if any // Skip ',' if any
IsComma = Tok.is(tok::comma); IsComma = Tok.is(tok::comma);

View File

@ -201,7 +201,7 @@ Retry:
== ANK_Error) { == ANK_Error) {
// Handle errors here by skipping up to the next semicolon or '}', and // Handle errors here by skipping up to the next semicolon or '}', and
// eat the semicolon if that's what stopped us. // eat the semicolon if that's what stopped us.
SkipUntil(tok::r_brace, /*StopAtSemi=*/true, /*DontConsume=*/true); SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
if (Tok.is(tok::semi)) if (Tok.is(tok::semi))
ConsumeToken(); ConsumeToken();
return StmtError(); return StmtError();
@ -356,7 +356,7 @@ Retry:
// succeed. // succeed.
ExpectAndConsume(tok::semi, diag::err_expected_semi_after_stmt, SemiError); ExpectAndConsume(tok::semi, diag::err_expected_semi_after_stmt, SemiError);
// Skip until we see a } or ;, but don't eat it. // Skip until we see a } or ;, but don't eat it.
SkipUntil(tok::r_brace, true, true); SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
} }
return Res; return Res;
@ -373,7 +373,7 @@ StmtResult Parser::ParseExprStatement() {
// If the expression is invalid, skip ahead to the next semicolon or '}'. // If the expression is invalid, skip ahead to the next semicolon or '}'.
// Not doing this opens us up to the possibility of infinite loops if // Not doing this opens us up to the possibility of infinite loops if
// ParseExpression does not consume any tokens. // ParseExpression does not consume any tokens.
SkipUntil(tok::r_brace, /*StopAtSemi=*/true, /*DontConsume=*/true); SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
if (Tok.is(tok::semi)) if (Tok.is(tok::semi))
ConsumeToken(); ConsumeToken();
return Actions.ActOnExprStmtError(); return Actions.ActOnExprStmtError();
@ -617,7 +617,7 @@ StmtResult Parser::ParseCaseStatement(bool MissingCase, ExprResult Expr) {
ExprResult LHS(MissingCase ? Expr : ParseConstantExpression()); ExprResult LHS(MissingCase ? Expr : ParseConstantExpression());
MissingCase = false; MissingCase = false;
if (LHS.isInvalid()) { if (LHS.isInvalid()) {
SkipUntil(tok::colon); SkipUntil(tok::colon, StopAtSemi);
return StmtError(); return StmtError();
} }
@ -630,7 +630,7 @@ StmtResult Parser::ParseCaseStatement(bool MissingCase, ExprResult Expr) {
RHS = ParseConstantExpression(); RHS = ParseConstantExpression();
if (RHS.isInvalid()) { if (RHS.isInvalid()) {
SkipUntil(tok::colon); SkipUntil(tok::colon, StopAtSemi);
return StmtError(); return StmtError();
} }
} }
@ -1196,7 +1196,7 @@ StmtResult Parser::ParseSwitchStatement(SourceLocation *TrailingElseLoc) {
// will have no place to connect back with the switch. // will have no place to connect back with the switch.
if (Tok.is(tok::l_brace)) { if (Tok.is(tok::l_brace)) {
ConsumeBrace(); ConsumeBrace();
SkipUntil(tok::r_brace, false, false); SkipUntil(tok::r_brace);
} else } else
SkipUntil(tok::semi); SkipUntil(tok::semi);
return Switch; return Switch;
@ -1347,7 +1347,7 @@ StmtResult Parser::ParseDoStatement() {
if (!Body.isInvalid()) { if (!Body.isInvalid()) {
Diag(Tok, diag::err_expected_while); Diag(Tok, diag::err_expected_while);
Diag(DoLoc, diag::note_matching) << "do"; Diag(DoLoc, diag::note_matching) << "do";
SkipUntil(tok::semi, false, true); SkipUntil(tok::semi, StopBeforeMatch);
} }
return StmtError(); return StmtError();
} }
@ -1355,7 +1355,7 @@ StmtResult Parser::ParseDoStatement() {
if (Tok.isNot(tok::l_paren)) { if (Tok.isNot(tok::l_paren)) {
Diag(Tok, diag::err_expected_lparen_after) << "do/while"; Diag(Tok, diag::err_expected_lparen_after) << "do/while";
SkipUntil(tok::semi, false, true); SkipUntil(tok::semi, StopBeforeMatch);
return StmtError(); return StmtError();
} }
@ -1531,14 +1531,14 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
// for (expr : expr) { ... } // for (expr : expr) { ... }
Diag(Tok, diag::err_for_range_expected_decl) Diag(Tok, diag::err_for_range_expected_decl)
<< FirstPart.get()->getSourceRange(); << FirstPart.get()->getSourceRange();
SkipUntil(tok::r_paren, false, true); SkipUntil(tok::r_paren, StopBeforeMatch);
SecondPartIsInvalid = true; SecondPartIsInvalid = true;
} else { } else {
if (!Value.isInvalid()) { if (!Value.isInvalid()) {
Diag(Tok, diag::err_expected_semi_for); Diag(Tok, diag::err_expected_semi_for);
} else { } else {
// Skip until semicolon or rparen, don't consume it. // Skip until semicolon or rparen, don't consume it.
SkipUntil(tok::r_paren, true, true); SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch);
if (Tok.is(tok::semi)) if (Tok.is(tok::semi))
ConsumeToken(); ConsumeToken();
} }
@ -1570,7 +1570,7 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
Diag(Tok, diag::err_expected_semi_for); Diag(Tok, diag::err_expected_semi_for);
else else
// Skip until semicolon or rparen, don't consume it. // Skip until semicolon or rparen, don't consume it.
SkipUntil(tok::r_paren, true, true); SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch);
} }
if (Tok.is(tok::semi)) { if (Tok.is(tok::semi)) {
@ -1672,7 +1672,7 @@ StmtResult Parser::ParseGotoStatement() {
SourceLocation StarLoc = ConsumeToken(); SourceLocation StarLoc = ConsumeToken();
ExprResult R(ParseExpression()); ExprResult R(ParseExpression());
if (R.isInvalid()) { // Skip to the semicolon, but don't consume it. if (R.isInvalid()) { // Skip to the semicolon, but don't consume it.
SkipUntil(tok::semi, false, true); SkipUntil(tok::semi, StopBeforeMatch);
return StmtError(); return StmtError();
} }
Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.take()); Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.take());
@ -1731,7 +1731,7 @@ StmtResult Parser::ParseReturnStatement() {
} else } else
R = ParseExpression(); R = ParseExpression();
if (R.isInvalid()) { // Skip to the semicolon, but don't consume it. if (R.isInvalid()) { // Skip to the semicolon, but don't consume it.
SkipUntil(tok::semi, false, true); SkipUntil(tok::semi, StopBeforeMatch);
return StmtError(); return StmtError();
} }
} }
@ -2279,7 +2279,7 @@ StmtResult Parser::ParseAsmStatement(bool &msAsm) {
bool isVolatile = DS.getTypeQualifiers() & DeclSpec::TQ_volatile; bool isVolatile = DS.getTypeQualifiers() & DeclSpec::TQ_volatile;
if (Tok.isNot(tok::l_paren)) { if (Tok.isNot(tok::l_paren)) {
Diag(Tok, diag::err_expected_lparen_after) << "asm"; Diag(Tok, diag::err_expected_lparen_after) << "asm";
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return StmtError(); return StmtError();
} }
BalancedDelimiterTracker T(*this, tok::l_paren); BalancedDelimiterTracker T(*this, tok::l_paren);
@ -2398,7 +2398,7 @@ bool Parser::ParseAsmOperandsOpt(SmallVectorImpl<IdentifierInfo *> &Names,
if (Tok.isNot(tok::identifier)) { if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident); Diag(Tok, diag::err_expected_ident);
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return true; return true;
} }
@ -2412,14 +2412,14 @@ bool Parser::ParseAsmOperandsOpt(SmallVectorImpl<IdentifierInfo *> &Names,
ExprResult Constraint(ParseAsmStringLiteral()); ExprResult Constraint(ParseAsmStringLiteral());
if (Constraint.isInvalid()) { if (Constraint.isInvalid()) {
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return true; return true;
} }
Constraints.push_back(Constraint.release()); Constraints.push_back(Constraint.release());
if (Tok.isNot(tok::l_paren)) { if (Tok.isNot(tok::l_paren)) {
Diag(Tok, diag::err_expected_lparen_after) << "asm operand"; Diag(Tok, diag::err_expected_lparen_after) << "asm operand";
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return true; return true;
} }
@ -2429,7 +2429,7 @@ bool Parser::ParseAsmOperandsOpt(SmallVectorImpl<IdentifierInfo *> &Names,
ExprResult Res(ParseExpression()); ExprResult Res(ParseExpression());
T.consumeClose(); T.consumeClose();
if (Res.isInvalid()) { if (Res.isInvalid()) {
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren, StopAtSemi);
return true; return true;
} }
Exprs.push_back(Res.release()); Exprs.push_back(Res.release());
@ -2511,7 +2511,7 @@ bool Parser::trySkippingFunctionBody() {
if (!PP.isCodeCompletionEnabled()) { if (!PP.isCodeCompletionEnabled()) {
ConsumeBrace(); ConsumeBrace();
SkipUntil(tok::r_brace, /*StopAtSemi=*/false, /*DontConsume=*/false); SkipUntil(tok::r_brace);
return true; return true;
} }
@ -2519,8 +2519,7 @@ bool Parser::trySkippingFunctionBody() {
// the body contains the code-completion point. // the body contains the code-completion point.
TentativeParsingAction PA(*this); TentativeParsingAction PA(*this);
ConsumeBrace(); ConsumeBrace();
if (SkipUntil(tok::r_brace, /*StopAtSemi=*/false, /*DontConsume=*/false, if (SkipUntil(tok::r_brace, StopAtCodeCompletion)) {
/*StopAtCodeCompletion=*/true)) {
PA.Commit(); PA.Commit();
return true; return true;
} }

View File

@ -120,7 +120,7 @@ Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context,
if (ParseTemplateParameters(CurTemplateDepthTracker.getDepth(), if (ParseTemplateParameters(CurTemplateDepthTracker.getDepth(),
TemplateParams, LAngleLoc, RAngleLoc)) { TemplateParams, LAngleLoc, RAngleLoc)) {
// Skip until the semi-colon or a }. // Skip until the semi-colon or a }.
SkipUntil(tok::r_brace, true, true); SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
if (Tok.is(tok::semi)) if (Tok.is(tok::semi))
ConsumeToken(); ConsumeToken();
return 0; return 0;
@ -216,7 +216,7 @@ Parser::ParseSingleDeclarationAfterTemplate(
// Error parsing the declarator? // Error parsing the declarator?
if (!DeclaratorInfo.hasName()) { if (!DeclaratorInfo.hasName()) {
// If so, skip until the semi-colon or a }. // If so, skip until the semi-colon or a }.
SkipUntil(tok::r_brace, true, true); SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
if (Tok.is(tok::semi)) if (Tok.is(tok::semi))
ConsumeToken(); ConsumeToken();
return 0; return 0;
@ -276,7 +276,7 @@ Parser::ParseSingleDeclarationAfterTemplate(
if (Tok.is(tok::comma)) { if (Tok.is(tok::comma)) {
Diag(Tok, diag::err_multiple_template_declarators) Diag(Tok, diag::err_multiple_template_declarators)
<< (int)TemplateInfo.Kind; << (int)TemplateInfo.Kind;
SkipUntil(tok::semi, true, false); SkipUntil(tok::semi);
return ThisDecl; return ThisDecl;
} }
@ -349,7 +349,8 @@ Parser::ParseTemplateParameterList(unsigned Depth,
} else { } else {
// If we failed to parse a template parameter, skip until we find // If we failed to parse a template parameter, skip until we find
// a comma or closing brace. // a comma or closing brace.
SkipUntil(tok::comma, tok::greater, tok::greatergreater, true, true); SkipUntil(tok::comma, tok::greater, tok::greatergreater,
StopAtSemi | StopBeforeMatch);
} }
// Did we find a comma or the end of the template parameter list? // Did we find a comma or the end of the template parameter list?
@ -363,7 +364,8 @@ Parser::ParseTemplateParameterList(unsigned Depth,
// try to get out of the expression. This error is currently // try to get out of the expression. This error is currently
// subsumed by whatever goes on in ParseTemplateParameter. // subsumed by whatever goes on in ParseTemplateParameter.
Diag(Tok.getLocation(), diag::err_expected_comma_greater); Diag(Tok.getLocation(), diag::err_expected_comma_greater);
SkipUntil(tok::comma, tok::greater, tok::greatergreater, true, true); SkipUntil(tok::comma, tok::greater, tok::greatergreater,
StopAtSemi | StopBeforeMatch);
return false; return false;
} }
} }
@ -611,7 +613,8 @@ Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) {
if (DefaultArg.isInvalid()) { if (DefaultArg.isInvalid()) {
Diag(Tok.getLocation(), Diag(Tok.getLocation(),
diag::err_default_template_template_parameter_not_template); diag::err_default_template_template_parameter_not_template);
SkipUntil(tok::comma, tok::greater, tok::greatergreater, true, true); SkipUntil(tok::comma, tok::greater, tok::greatergreater,
StopAtSemi | StopBeforeMatch);
} }
} }
@ -661,7 +664,7 @@ Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) {
DefaultArg = ParseAssignmentExpression(); DefaultArg = ParseAssignmentExpression();
if (DefaultArg.isInvalid()) if (DefaultArg.isInvalid())
SkipUntil(tok::comma, tok::greater, true, true); SkipUntil(tok::comma, tok::greater, StopAtSemi | StopBeforeMatch);
} }
// Create the parameter. // Create the parameter.
@ -825,8 +828,10 @@ Parser::ParseTemplateIdAfterTemplateName(TemplateTy Template,
if (Invalid) { if (Invalid) {
// Try to find the closing '>'. // Try to find the closing '>'.
SkipUntil(tok::greater, true, !ConsumeLastToken); if (ConsumeLastToken)
SkipUntil(tok::greater, StopAtSemi);
else
SkipUntil(tok::greater, StopAtSemi | StopBeforeMatch);
return true; return true;
} }
} }
@ -1191,7 +1196,7 @@ Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs) {
} }
if (Arg.isInvalid()) { if (Arg.isInvalid()) {
SkipUntil(tok::comma, tok::greater, true, true); SkipUntil(tok::comma, tok::greater, StopAtSemi | StopBeforeMatch);
return true; return true;
} }

View File

@ -159,7 +159,7 @@ Parser::TPResult Parser::TryConsumeDeclarationSpecifier() {
if (Tok.isNot(tok::l_paren)) if (Tok.isNot(tok::l_paren))
return TPResult::Error(); return TPResult::Error();
ConsumeParen(); ConsumeParen();
if (!SkipUntil(tok::r_paren, false)) if (!SkipUntil(tok::r_paren))
return TPResult::Error(); return TPResult::Error();
break; break;
} }
@ -183,14 +183,14 @@ Parser::TPResult Parser::TryConsumeDeclarationSpecifier() {
Tok.is(tok::kw___declspec) || Tok.is(tok::kw_alignas)) { Tok.is(tok::kw___declspec) || Tok.is(tok::kw_alignas)) {
if (Tok.is(tok::l_square)) { if (Tok.is(tok::l_square)) {
ConsumeBracket(); ConsumeBracket();
if (!SkipUntil(tok::r_square, false)) if (!SkipUntil(tok::r_square))
return TPResult::Error(); return TPResult::Error();
} else { } else {
ConsumeToken(); ConsumeToken();
if (Tok.isNot(tok::l_paren)) if (Tok.isNot(tok::l_paren))
return TPResult::Error(); return TPResult::Error();
ConsumeParen(); ConsumeParen();
if (!SkipUntil(tok::r_paren, false)) if (!SkipUntil(tok::r_paren))
return TPResult::Error(); return TPResult::Error();
} }
} }
@ -294,7 +294,7 @@ Parser::TPResult Parser::TryParseInitDeclaratorList() {
if (Tok.is(tok::l_paren)) { if (Tok.is(tok::l_paren)) {
// Parse through the parens. // Parse through the parens.
ConsumeParen(); ConsumeParen();
if (!SkipUntil(tok::r_paren)) if (!SkipUntil(tok::r_paren, StopAtSemi))
return TPResult::Error(); return TPResult::Error();
} else if (Tok.is(tok::l_brace)) { } else if (Tok.is(tok::l_brace)) {
// A left-brace here is sufficient to disambiguate the parse; an // A left-brace here is sufficient to disambiguate the parse; an
@ -517,7 +517,7 @@ Parser::isCXX11AttributeSpecifier(bool Disambiguate,
if (!getLangOpts().ObjC1) { if (!getLangOpts().ObjC1) {
ConsumeBracket(); ConsumeBracket();
bool IsAttribute = SkipUntil(tok::r_square, false); bool IsAttribute = SkipUntil(tok::r_square);
IsAttribute &= Tok.is(tok::r_square); IsAttribute &= Tok.is(tok::r_square);
PA.Revert(); PA.Revert();
@ -589,7 +589,7 @@ Parser::isCXX11AttributeSpecifier(bool Disambiguate,
// Parse the attribute-argument-clause, if present. // Parse the attribute-argument-clause, if present.
if (Tok.is(tok::l_paren)) { if (Tok.is(tok::l_paren)) {
ConsumeParen(); ConsumeParen();
if (!SkipUntil(tok::r_paren, false)) { if (!SkipUntil(tok::r_paren)) {
IsAttribute = false; IsAttribute = false;
break; break;
} }
@ -1550,7 +1550,7 @@ Parser::TPResult Parser::TryParseTypeofSpecifier() {
assert(Tok.is(tok::l_paren) && "Expected '('"); assert(Tok.is(tok::l_paren) && "Expected '('");
// Parse through the parens after 'typeof'. // Parse through the parens after 'typeof'.
ConsumeParen(); ConsumeParen();
if (!SkipUntil(tok::r_paren)) if (!SkipUntil(tok::r_paren, StopAtSemi))
return TPResult::Error(); return TPResult::Error();
return TPResult::Ambiguous(); return TPResult::Ambiguous();
@ -1744,8 +1744,7 @@ Parser::TryParseParameterDeclarationClause(bool *InvalidAsDeclaration,
// '=' assignment-expression // '=' assignment-expression
// Parse through assignment-expression. // Parse through assignment-expression.
// FIXME: assignment-expression may contain an unparenthesized comma. // FIXME: assignment-expression may contain an unparenthesized comma.
if (!SkipUntil(tok::comma, tok::r_paren, true/*StopAtSemi*/, if (!SkipUntil(tok::comma, tok::r_paren, StopAtSemi | StopBeforeMatch))
true/*DontConsume*/))
return TPResult::Error(); return TPResult::Error();
} }
@ -1789,7 +1788,7 @@ Parser::TPResult Parser::TryParseFunctionDeclarator() {
return TPR; return TPR;
// Parse through the parens. // Parse through the parens.
if (!SkipUntil(tok::r_paren)) if (!SkipUntil(tok::r_paren, StopAtSemi))
return TPResult::Error(); return TPResult::Error();
// cv-qualifier-seq // cv-qualifier-seq
@ -1810,7 +1809,7 @@ Parser::TPResult Parser::TryParseFunctionDeclarator() {
// Parse through the parens after 'throw'. // Parse through the parens after 'throw'.
ConsumeParen(); ConsumeParen();
if (!SkipUntil(tok::r_paren)) if (!SkipUntil(tok::r_paren, StopAtSemi))
return TPResult::Error(); return TPResult::Error();
} }
if (Tok.is(tok::kw_noexcept)) { if (Tok.is(tok::kw_noexcept)) {
@ -1819,7 +1818,7 @@ Parser::TPResult Parser::TryParseFunctionDeclarator() {
if (Tok.is(tok::l_paren)) { if (Tok.is(tok::l_paren)) {
// Find the matching rparen. // Find the matching rparen.
ConsumeParen(); ConsumeParen();
if (!SkipUntil(tok::r_paren)) if (!SkipUntil(tok::r_paren, StopAtSemi))
return TPResult::Error(); return TPResult::Error();
} }
} }
@ -1831,7 +1830,7 @@ Parser::TPResult Parser::TryParseFunctionDeclarator() {
/// ///
Parser::TPResult Parser::TryParseBracketDeclarator() { Parser::TPResult Parser::TryParseBracketDeclarator() {
ConsumeBracket(); ConsumeBracket();
if (!SkipUntil(tok::r_square)) if (!SkipUntil(tok::r_square, StopAtSemi))
return TPResult::Error(); return TPResult::Error();
return TPResult::Ambiguous(); return TPResult::Ambiguous();

View File

@ -190,7 +190,7 @@ bool Parser::ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned DiagID,
Diag(Tok, DiagID) << Msg; Diag(Tok, DiagID) << Msg;
if (SkipToTok != tok::unknown) if (SkipToTok != tok::unknown)
SkipUntil(SkipToTok); SkipUntil(SkipToTok, StopAtSemi);
return true; return true;
} }
@ -253,16 +253,19 @@ void Parser::ConsumeExtraSemi(ExtraSemiKind Kind, unsigned TST) {
// Error recovery. // Error recovery.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
bool HasFlagsSet(Parser::SkipUntilFlags L, Parser::SkipUntilFlags R) {
return (static_cast<unsigned>(L) & static_cast<unsigned>(R)) != 0;
}
/// SkipUntil - Read tokens until we get to the specified token, then consume /// SkipUntil - Read tokens until we get to the specified token, then consume
/// it (unless DontConsume is true). Because we cannot guarantee that the /// it (unless no flag StopBeforeMatch). Because we cannot guarantee that the
/// token will ever occur, this skips to the next token, or to some likely /// token will ever occur, this skips to the next token, or to some likely
/// good stopping point. If StopAtSemi is true, skipping will stop at a ';' /// good stopping point. If StopAtSemi is true, skipping will stop at a ';'
/// character. /// character.
/// ///
/// If SkipUntil finds the specified token, it returns true, otherwise it /// If SkipUntil finds the specified token, it returns true, otherwise it
/// returns false. /// returns false.
bool Parser::SkipUntil(ArrayRef<tok::TokenKind> Toks, bool StopAtSemi, bool Parser::SkipUntil(ArrayRef<tok::TokenKind> Toks, SkipUntilFlags Flags) {
bool DontConsume, bool StopAtCodeCompletion) {
// We always want this function to skip at least one token if the first token // We always want this function to skip at least one token if the first token
// isn't T and if not at EOF. // isn't T and if not at EOF.
bool isFirstTokenSkipped = true; bool isFirstTokenSkipped = true;
@ -270,7 +273,7 @@ bool Parser::SkipUntil(ArrayRef<tok::TokenKind> Toks, bool StopAtSemi,
// If we found one of the tokens, stop and return true. // If we found one of the tokens, stop and return true.
for (unsigned i = 0, NumToks = Toks.size(); i != NumToks; ++i) { for (unsigned i = 0, NumToks = Toks.size(); i != NumToks; ++i) {
if (Tok.is(Toks[i])) { if (Tok.is(Toks[i])) {
if (DontConsume) { if (HasFlagsSet(Flags, StopBeforeMatch)) {
// Noop, don't consume the token. // Noop, don't consume the token.
} else { } else {
ConsumeAnyToken(); ConsumeAnyToken();
@ -282,8 +285,9 @@ bool Parser::SkipUntil(ArrayRef<tok::TokenKind> Toks, bool StopAtSemi,
// Important special case: The caller has given up and just wants us to // Important special case: The caller has given up and just wants us to
// skip the rest of the file. Do this without recursing, since we can // skip the rest of the file. Do this without recursing, since we can
// get here precisely because the caller detected too much recursion. // get here precisely because the caller detected too much recursion.
if (Toks.size() == 1 && Toks[0] == tok::eof && !StopAtSemi && if (Toks.size() == 1 && Toks[0] == tok::eof &&
!StopAtCodeCompletion) { !HasFlagsSet(Flags, StopAtSemi) &&
!HasFlagsSet(Flags, StopAtCodeCompletion)) {
while (Tok.getKind() != tok::eof) while (Tok.getKind() != tok::eof)
ConsumeAnyToken(); ConsumeAnyToken();
return true; return true;
@ -295,24 +299,33 @@ bool Parser::SkipUntil(ArrayRef<tok::TokenKind> Toks, bool StopAtSemi,
return false; return false;
case tok::code_completion: case tok::code_completion:
if (!StopAtCodeCompletion) if (!HasFlagsSet(Flags, StopAtCodeCompletion))
ConsumeToken(); ConsumeToken();
return false; return false;
case tok::l_paren: case tok::l_paren:
// Recursively skip properly-nested parens. // Recursively skip properly-nested parens.
ConsumeParen(); ConsumeParen();
SkipUntil(tok::r_paren, false, false, StopAtCodeCompletion); if (HasFlagsSet(Flags, StopAtCodeCompletion))
SkipUntil(tok::r_paren, StopAtCodeCompletion);
else
SkipUntil(tok::r_paren);
break; break;
case tok::l_square: case tok::l_square:
// Recursively skip properly-nested square brackets. // Recursively skip properly-nested square brackets.
ConsumeBracket(); ConsumeBracket();
SkipUntil(tok::r_square, false, false, StopAtCodeCompletion); if (HasFlagsSet(Flags, StopAtCodeCompletion))
SkipUntil(tok::r_square, StopAtCodeCompletion);
else
SkipUntil(tok::r_square);
break; break;
case tok::l_brace: case tok::l_brace:
// Recursively skip properly-nested braces. // Recursively skip properly-nested braces.
ConsumeBrace(); ConsumeBrace();
SkipUntil(tok::r_brace, false, false, StopAtCodeCompletion); if (HasFlagsSet(Flags, StopAtCodeCompletion))
SkipUntil(tok::r_brace, StopAtCodeCompletion);
else
SkipUntil(tok::r_brace);
break; break;
// Okay, we found a ']' or '}' or ')', which we think should be balanced. // Okay, we found a ']' or '}' or ')', which we think should be balanced.
@ -345,7 +358,7 @@ bool Parser::SkipUntil(ArrayRef<tok::TokenKind> Toks, bool StopAtSemi,
break; break;
case tok::semi: case tok::semi:
if (StopAtSemi) if (HasFlagsSet(Flags, StopAtSemi))
return false; return false;
// FALL THROUGH. // FALL THROUGH.
default: default:
@ -998,7 +1011,7 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
Diag(Tok, diag::err_expected_fn_body); Diag(Tok, diag::err_expected_fn_body);
// Skip over garbage, until we get to '{'. Don't eat the '{'. // Skip over garbage, until we get to '{'. Don't eat the '{'.
SkipUntil(tok::l_brace, true, true); SkipUntil(tok::l_brace, StopAtSemi | StopBeforeMatch);
// If we didn't find the '{', bail out. // If we didn't find the '{', bail out.
if (Tok.isNot(tok::l_brace)) if (Tok.isNot(tok::l_brace))
@ -1254,7 +1267,7 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) {
if (ExpectAndConsumeSemi(diag::err_expected_semi_declaration)) { if (ExpectAndConsumeSemi(diag::err_expected_semi_declaration)) {
// Skip to end of block or statement // Skip to end of block or statement
SkipUntil(tok::semi, true); SkipUntil(tok::semi);
if (Tok.is(tok::semi)) if (Tok.is(tok::semi))
ConsumeToken(); ConsumeToken();
} }
@ -1322,7 +1335,7 @@ Parser::ExprResult Parser::ParseSimpleAsm(SourceLocation *EndLoc) {
ExprResult Result(ParseAsmStringLiteral()); ExprResult Result(ParseAsmStringLiteral());
if (Result.isInvalid()) { if (Result.isInvalid()) {
SkipUntil(tok::r_paren, true, true); SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch);
if (EndLoc) if (EndLoc)
*EndLoc = Tok.getLocation(); *EndLoc = Tok.getLocation();
ConsumeAnyToken(); ConsumeAnyToken();
@ -1961,7 +1974,7 @@ bool BalancedDelimiterTracker::diagnoseOverflow() {
P.Diag(P.Tok, diag::err_bracket_depth_exceeded) P.Diag(P.Tok, diag::err_bracket_depth_exceeded)
<< P.getLangOpts().BracketDepth; << P.getLangOpts().BracketDepth;
P.Diag(P.Tok, diag::note_bracket_depth); P.Diag(P.Tok, diag::note_bracket_depth);
P.SkipUntil(tok::eof, false); P.SkipUntil(tok::eof);
return true; return true;
} }
@ -1996,13 +2009,14 @@ bool BalancedDelimiterTracker::diagnoseMissingClose() {
// token. // token.
if (P.Tok.isNot(tok::r_paren) && P.Tok.isNot(tok::r_brace) && if (P.Tok.isNot(tok::r_paren) && P.Tok.isNot(tok::r_brace) &&
P.Tok.isNot(tok::r_square) && P.Tok.isNot(tok::r_square) &&
P.SkipUntil(Close, FinalToken, /*StopAtSemi*/true, /*DontConsume*/true) && P.SkipUntil(Close, FinalToken,
Parser::StopAtSemi | Parser::StopBeforeMatch) &&
P.Tok.is(Close)) P.Tok.is(Close))
LClose = P.ConsumeAnyToken(); LClose = P.ConsumeAnyToken();
return true; return true;
} }
void BalancedDelimiterTracker::skipToEnd() { void BalancedDelimiterTracker::skipToEnd() {
P.SkipUntil(Close, false, true); P.SkipUntil(Close, Parser::StopBeforeMatch);
consumeClose(); consumeClose();
} }