From ee6507dfdc5da99f60ae14e489065b1b304d7e46 Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Mon, 18 Nov 2013 08:17:37 +0000 Subject: [PATCH] Replaced bool parameters in SkipUntil function with single bit-based parameter. llvm-svn: 194994 --- clang/include/clang/Parse/Parser.h | 45 +++++++----- clang/lib/Parse/ParseCXXInlineMethods.cpp | 2 +- clang/lib/Parse/ParseDecl.cpp | 87 ++++++++++++----------- clang/lib/Parse/ParseDeclCXX.cpp | 59 ++++++++------- clang/lib/Parse/ParseExpr.cpp | 44 ++++++------ clang/lib/Parse/ParseExprCXX.cpp | 42 +++++------ clang/lib/Parse/ParseInit.cpp | 10 +-- clang/lib/Parse/ParseObjc.cpp | 50 ++++++------- clang/lib/Parse/ParseOpenMP.cpp | 26 +++---- clang/lib/Parse/ParseStmt.cpp | 41 ++++++----- clang/lib/Parse/ParseTemplate.cpp | 25 ++++--- clang/lib/Parse/ParseTentative.cpp | 25 ++++--- clang/lib/Parse/Parser.cpp | 50 ++++++++----- 13 files changed, 271 insertions(+), 235 deletions(-) diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 01dafba6460c..00533f0e0449 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -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(static_cast(L) | + static_cast(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(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(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(0)) { tok::TokenKind TokArray[] = {T1, T2, T3}; - return SkipUntil(TokArray, StopAtSemi, DontConsume,StopAtCodeCompletion); + return SkipUntil(TokArray, Flags); } - bool SkipUntil(ArrayRef Toks, bool StopAtSemi = true, - bool DontConsume = false, bool StopAtCodeCompletion = false); + bool SkipUntil(ArrayRef Toks, + SkipUntilFlags Flags = static_cast(0)); /// SkipMalformedDecl - Read tokens until we get to some likely good stopping /// point for skipping past a simple-declaration. diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index 0c8ace59e350..779230516532 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -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); diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 36d704d31a99..77c1fe9caafe 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -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 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; } diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 0c3eab41f902..bf615f02bab9 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -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(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); } diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 65b9b82cdaa8..45f1b1da2e7f 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -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()); diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 4dd63e3763b8..fe357cf0ada6 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -637,9 +637,9 @@ ExprResult Parser::ParseLambdaExpression() { Optional 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(); } diff --git a/clang/lib/Parse/ParseInit.cpp b/clang/lib/Parse/ParseInit.cpp index 8311aa22075e..37f74bbcd51b 100644 --- a/clang/lib/Parse/ParseInit.cpp +++ b/clang/lib/Parse/ParseInit.cpp @@ -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; } } diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index 1dc71f1f8270..86f38cfee37a 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/lib/Parse/ParseObjc.cpp @@ -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 &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; } diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 992a4431c7a8..89e4147e285c 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -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 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 Identifiers; SmallVector Clauses; SmallVector, 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); diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index e32d61928d14..d1f2138db48f 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -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 &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 &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 &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; } diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index b050a06092ad..076edb93fa11 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -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; } diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp index b35d632d0adf..a1d6b13fdab8 100644 --- a/clang/lib/Parse/ParseTentative.cpp +++ b/clang/lib/Parse/ParseTentative.cpp @@ -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(); diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index c6eac18aa49c..60e83ac221c8 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(L) & static_cast(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 Toks, bool StopAtSemi, - bool DontConsume, bool StopAtCodeCompletion) { +bool Parser::SkipUntil(ArrayRef 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 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 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 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 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(); }