summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/Parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Parse/Parser.cpp')
-rw-r--r--clang/lib/Parse/Parser.cpp50
1 files changed, 32 insertions, 18 deletions
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index c6eac18aa49..60e83ac221c 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -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();
}
OpenPOWER on IntegriCloud