diff options
Diffstat (limited to 'clang/lib/Parse/Parser.cpp')
-rw-r--r-- | clang/lib/Parse/Parser.cpp | 50 |
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(); } |