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);
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
/// it (unless DontConsume is true). Because we cannot guarantee that the
/// 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 ';'
/// character.
/// it (unless StopBeforeMatch is specified). Because we cannot guarantee
/// that the token will ever occur, this skips to the next token, or to some
/// likely good stopping point. If Flags has StopAtSemi flag, skipping will
/// stop at a ';' character.
///
/// If SkipUntil finds the specified token, it returns true, otherwise it
/// returns false.
bool SkipUntil(tok::TokenKind T, bool StopAtSemi = true,
bool DontConsume = false, bool StopAtCodeCompletion = false) {
return SkipUntil(llvm::makeArrayRef(T), StopAtSemi, DontConsume,
StopAtCodeCompletion);
bool SkipUntil(tok::TokenKind T,
SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)) {
return SkipUntil(llvm::makeArrayRef(T), Flags);
}
bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2, bool StopAtSemi = true,
bool DontConsume = false, bool StopAtCodeCompletion = false) {
bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2,
SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)) {
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 StopAtSemi = true, bool DontConsume = false,
bool StopAtCodeCompletion = false) {
SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)) {
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 DontConsume = false, bool StopAtCodeCompletion = false);
bool SkipUntil(ArrayRef<tok::TokenKind> Toks,
SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0));
/// SkipMalformedDecl - Read tokens until we get to some likely good stopping
/// point for skipping past a simple-declaration.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -244,7 +244,7 @@ ExprResult Parser::ParseInitializerWithPotentialDesignator() {
bool IsExpr;
void *TypeOrExpr;
if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) {
SkipUntil(tok::r_square);
SkipUntil(tok::r_square, StopAtSemi);
return ExprError();
}
@ -285,7 +285,7 @@ ExprResult Parser::ParseInitializerWithPotentialDesignator() {
0);
ConsumeToken(); // the identifier
if (!ReceiverType) {
SkipUntil(tok::r_square);
SkipUntil(tok::r_square, StopAtSemi);
return ExprError();
}
@ -312,7 +312,7 @@ ExprResult Parser::ParseInitializerWithPotentialDesignator() {
if (!Idx.get()) {
Idx = ParseAssignmentExpression();
if (Idx.isInvalid()) {
SkipUntil(tok::r_square);
SkipUntil(tok::r_square, StopAtSemi);
return Idx;
}
}
@ -340,7 +340,7 @@ ExprResult Parser::ParseInitializerWithPotentialDesignator() {
ExprResult RHS(ParseConstantExpression());
if (RHS.isInvalid()) {
SkipUntil(tok::r_square);
SkipUntil(tok::r_square, StopAtSemi);
return RHS;
}
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
// leaving this loop except through this if.
if (Tok.isNot(tok::comma)) {
SkipUntil(tok::r_brace, false, true);
SkipUntil(tok::r_brace, StopBeforeMatch);
break;
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -190,7 +190,7 @@ bool Parser::ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned DiagID,
Diag(Tok, DiagID) << Msg;
if (SkipToTok != tok::unknown)
SkipUntil(SkipToTok);
SkipUntil(SkipToTok, StopAtSemi);
return true;
}
@ -253,16 +253,19 @@ void Parser::ConsumeExtraSemi(ExtraSemiKind Kind, unsigned TST) {
// 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
/// 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
/// good stopping point. If StopAtSemi is true, skipping will stop at a ';'
/// character.
///
/// If SkipUntil finds the specified token, it returns true, otherwise it
/// returns false.
bool Parser::SkipUntil(ArrayRef<tok::TokenKind> Toks, bool StopAtSemi,
bool DontConsume, bool StopAtCodeCompletion) {
bool Parser::SkipUntil(ArrayRef<tok::TokenKind> Toks, SkipUntilFlags Flags) {
// We always want this function to skip at least one token if the first token
// isn't T and if not at EOF.
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.
for (unsigned i = 0, NumToks = Toks.size(); i != NumToks; ++i) {
if (Tok.is(Toks[i])) {
if (DontConsume) {
if (HasFlagsSet(Flags, StopBeforeMatch)) {
// Noop, don't consume the token.
} else {
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
// skip the rest of the file. Do this without recursing, since we can
// get here precisely because the caller detected too much recursion.
if (Toks.size() == 1 && Toks[0] == tok::eof && !StopAtSemi &&
!StopAtCodeCompletion) {
if (Toks.size() == 1 && Toks[0] == tok::eof &&
!HasFlagsSet(Flags, StopAtSemi) &&
!HasFlagsSet(Flags, StopAtCodeCompletion)) {
while (Tok.getKind() != tok::eof)
ConsumeAnyToken();
return true;
@ -295,24 +299,33 @@ bool Parser::SkipUntil(ArrayRef<tok::TokenKind> Toks, bool StopAtSemi,
return false;
case tok::code_completion:
if (!StopAtCodeCompletion)
if (!HasFlagsSet(Flags, StopAtCodeCompletion))
ConsumeToken();
return false;
case tok::l_paren:
// Recursively skip properly-nested parens.
ConsumeParen();
SkipUntil(tok::r_paren, false, false, StopAtCodeCompletion);
if (HasFlagsSet(Flags, StopAtCodeCompletion))
SkipUntil(tok::r_paren, StopAtCodeCompletion);
else
SkipUntil(tok::r_paren);
break;
case tok::l_square:
// Recursively skip properly-nested square brackets.
ConsumeBracket();
SkipUntil(tok::r_square, false, false, StopAtCodeCompletion);
if (HasFlagsSet(Flags, StopAtCodeCompletion))
SkipUntil(tok::r_square, StopAtCodeCompletion);
else
SkipUntil(tok::r_square);
break;
case tok::l_brace:
// Recursively skip properly-nested braces.
ConsumeBrace();
SkipUntil(tok::r_brace, false, false, StopAtCodeCompletion);
if (HasFlagsSet(Flags, StopAtCodeCompletion))
SkipUntil(tok::r_brace, StopAtCodeCompletion);
else
SkipUntil(tok::r_brace);
break;
// 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;
case tok::semi:
if (StopAtSemi)
if (HasFlagsSet(Flags, StopAtSemi))
return false;
// FALL THROUGH.
default:
@ -998,7 +1011,7 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
Diag(Tok, diag::err_expected_fn_body);
// 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 (Tok.isNot(tok::l_brace))
@ -1254,7 +1267,7 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) {
if (ExpectAndConsumeSemi(diag::err_expected_semi_declaration)) {
// Skip to end of block or statement
SkipUntil(tok::semi, true);
SkipUntil(tok::semi);
if (Tok.is(tok::semi))
ConsumeToken();
}
@ -1322,7 +1335,7 @@ Parser::ExprResult Parser::ParseSimpleAsm(SourceLocation *EndLoc) {
ExprResult Result(ParseAsmStringLiteral());
if (Result.isInvalid()) {
SkipUntil(tok::r_paren, true, true);
SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch);
if (EndLoc)
*EndLoc = Tok.getLocation();
ConsumeAnyToken();
@ -1961,7 +1974,7 @@ bool BalancedDelimiterTracker::diagnoseOverflow() {
P.Diag(P.Tok, diag::err_bracket_depth_exceeded)
<< P.getLangOpts().BracketDepth;
P.Diag(P.Tok, diag::note_bracket_depth);
P.SkipUntil(tok::eof, false);
P.SkipUntil(tok::eof);
return true;
}
@ -1996,13 +2009,14 @@ bool BalancedDelimiterTracker::diagnoseMissingClose() {
// token.
if (P.Tok.isNot(tok::r_paren) && P.Tok.isNot(tok::r_brace) &&
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))
LClose = P.ConsumeAnyToken();
return true;
}
void BalancedDelimiterTracker::skipToEnd() {
P.SkipUntil(Close, false, true);
P.SkipUntil(Close, Parser::StopBeforeMatch);
consumeClose();
}