diff options
Diffstat (limited to 'lib/Parse/ParseExprCXX.cpp')
-rw-r--r-- | lib/Parse/ParseExprCXX.cpp | 231 |
1 files changed, 126 insertions, 105 deletions
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index fef52a567f..6e36c91a09 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -594,7 +594,10 @@ llvm::Optional<unsigned> Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro) typedef llvm::Optional<unsigned> DiagResult; assert(Tok.is(tok::l_square) && "Lambda expressions begin with '['."); - Intro.Range.setBegin(ConsumeBracket()); + BalancedDelimiterTracker T(*this, tok::l_square); + T.consumeOpen(); + + Intro.Range.setBegin(T.getOpenLocation()); bool first = true; @@ -649,8 +652,8 @@ llvm::Optional<unsigned> Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro) Intro.addCapture(Kind, Loc, Id); } - Intro.Range.setEnd(MatchRHSPunctuation(tok::r_square, - Intro.Range.getBegin())); + T.consumeClose(); + Intro.Range.setEnd(T.getCloseLocation()); return DiagResult(); } @@ -685,7 +688,10 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( Scope::FunctionPrototypeScope | Scope::DeclScope); - SourceLocation DeclLoc = ConsumeParen(), DeclEndLoc; + SourceLocation DeclLoc, DeclEndLoc; + BalancedDelimiterTracker T(*this, tok::l_paren); + T.consumeOpen(); + DeclLoc = T.getOpenLocation(); // Parse parameter-declaration-clause. ParsedAttributes Attr(AttrFactory); @@ -695,7 +701,8 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( if (Tok.isNot(tok::r_paren)) ParseParameterDeclarationClause(D, Attr, ParamInfo, EllipsisLoc); - DeclEndLoc = MatchRHSPunctuation(tok::r_paren, DeclLoc); + T.consumeClose(); + DeclEndLoc = T.getCloseLocation(); // Parse 'mutable'[opt]. SourceLocation MutableLoc; @@ -816,21 +823,23 @@ ExprResult Parser::ParseCXXCasts() { if (ExpectAndConsume(tok::greater, diag::err_expected_greater)) return ExprError(Diag(LAngleBracketLoc, diag::note_matching) << "<"); - SourceLocation LParenLoc = Tok.getLocation(), RParenLoc; + SourceLocation LParenLoc, RParenLoc; + BalancedDelimiterTracker T(*this, tok::l_paren); - if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, CastName)) + if (T.expectAndConsume(diag::err_expected_lparen_after, CastName)) return ExprError(); ExprResult Result = ParseExpression(); // Match the ')'. - RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); + T.consumeClose(); if (!Result.isInvalid() && !DeclaratorInfo.isInvalidType()) Result = Actions.ActOnCXXNamedCast(OpLoc, Kind, LAngleBracketLoc, DeclaratorInfo, RAngleBracketLoc, - LParenLoc, Result.take(), RParenLoc); + T.getOpenLocation(), Result.take(), + T.getCloseLocation()); return move(Result); } @@ -845,13 +854,13 @@ ExprResult Parser::ParseCXXTypeid() { assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!"); SourceLocation OpLoc = ConsumeToken(); - SourceLocation LParenLoc = Tok.getLocation(); - SourceLocation RParenLoc; + SourceLocation LParenLoc, RParenLoc; + BalancedDelimiterTracker T(*this, tok::l_paren); // typeid expressions are always parenthesized. - if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, - "typeid")) + if (T.expectAndConsume(diag::err_expected_lparen_after, "typeid")) return ExprError(); + LParenLoc = T.getOpenLocation(); ExprResult Result; @@ -859,8 +868,8 @@ ExprResult Parser::ParseCXXTypeid() { TypeResult Ty = ParseTypeName(); // Match the ')'. - RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); - + T.consumeClose(); + RParenLoc = T.getCloseLocation(); if (Ty.isInvalid() || RParenLoc.isInvalid()) return ExprError(); @@ -883,7 +892,8 @@ ExprResult Parser::ParseCXXTypeid() { if (Result.isInvalid()) SkipUntil(tok::r_paren); else { - RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); + T.consumeClose(); + RParenLoc = T.getCloseLocation(); if (RParenLoc.isInvalid()) return ExprError(); @@ -904,12 +914,10 @@ ExprResult Parser::ParseCXXUuidof() { assert(Tok.is(tok::kw___uuidof) && "Not '__uuidof'!"); SourceLocation OpLoc = ConsumeToken(); - SourceLocation LParenLoc = Tok.getLocation(); - SourceLocation RParenLoc; + BalancedDelimiterTracker T(*this, tok::l_paren); // __uuidof expressions are always parenthesized. - if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, - "__uuidof")) + if (T.expectAndConsume(diag::err_expected_lparen_after, "__uuidof")) return ExprError(); ExprResult Result; @@ -918,13 +926,14 @@ ExprResult Parser::ParseCXXUuidof() { TypeResult Ty = ParseTypeName(); // Match the ')'. - RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); + T.consumeClose(); if (Ty.isInvalid()) return ExprError(); - Result = Actions.ActOnCXXUuidof(OpLoc, LParenLoc, /*isType=*/true, - Ty.get().getAsOpaquePtr(), RParenLoc); + Result = Actions.ActOnCXXUuidof(OpLoc, T.getOpenLocation(), /*isType=*/true, + Ty.get().getAsOpaquePtr(), + T.getCloseLocation()); } else { EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated); Result = ParseExpression(); @@ -933,10 +942,11 @@ ExprResult Parser::ParseCXXUuidof() { if (Result.isInvalid()) SkipUntil(tok::r_paren); else { - RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); + T.consumeClose(); - Result = Actions.ActOnCXXUuidof(OpLoc, LParenLoc, /*isType=*/false, - Result.release(), RParenLoc); + Result = Actions.ActOnCXXUuidof(OpLoc, T.getOpenLocation(), + /*isType=*/false, + Result.release(), T.getCloseLocation()); } } @@ -1093,7 +1103,8 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { } else { GreaterThanIsOperatorScope G(GreaterThanIsOperator, true); - SourceLocation LParenLoc = ConsumeParen(); + BalancedDelimiterTracker T(*this, tok::l_paren); + T.consumeOpen(); ExprVector Exprs(Actions); CommaLocsTy CommaLocs; @@ -1106,7 +1117,7 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { } // Match the ')'. - SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); + T.consumeClose(); // TypeRep could be null, if it references an invalid typedef. if (!TypeRep) @@ -1114,8 +1125,9 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&& "Unexpected number of commas!"); - return Actions.ActOnCXXTypeConstructExpr(TypeRep, LParenLoc, move_arg(Exprs), - RParenLoc); + return Actions.ActOnCXXTypeConstructExpr(TypeRep, T.getOpenLocation(), + move_arg(Exprs), + T.getCloseLocation()); } } @@ -1651,16 +1663,15 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, // Consume the 'new' or 'delete'. SymbolLocations[SymbolIdx++] = ConsumeToken(); if (Tok.is(tok::l_square)) { - // Consume the '['. - SourceLocation LBracketLoc = ConsumeBracket(); - // Consume the ']'. - SourceLocation RBracketLoc = MatchRHSPunctuation(tok::r_square, - LBracketLoc); - if (RBracketLoc.isInvalid()) + // Consume the '[' and ']'. + BalancedDelimiterTracker T(*this, tok::l_square); + T.consumeOpen(); + T.consumeClose(); + if (T.getCloseLocation().isInvalid()) return true; - SymbolLocations[SymbolIdx++] = LBracketLoc; - SymbolLocations[SymbolIdx++] = RBracketLoc; + SymbolLocations[SymbolIdx++] = T.getOpenLocation(); + SymbolLocations[SymbolIdx++] = T.getCloseLocation(); Op = isNew? OO_Array_New : OO_Array_Delete; } else { Op = isNew? OO_New : OO_Delete; @@ -1677,31 +1688,29 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, #include "clang/Basic/OperatorKinds.def" case tok::l_paren: { - // Consume the '('. - SourceLocation LParenLoc = ConsumeParen(); - // Consume the ')'. - SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, - LParenLoc); - if (RParenLoc.isInvalid()) + // Consume the '(' and ')'. + BalancedDelimiterTracker T(*this, tok::l_paren); + T.consumeOpen(); + T.consumeClose(); + if (T.getCloseLocation().isInvalid()) return true; - SymbolLocations[SymbolIdx++] = LParenLoc; - SymbolLocations[SymbolIdx++] = RParenLoc; + SymbolLocations[SymbolIdx++] = T.getOpenLocation(); + SymbolLocations[SymbolIdx++] = T.getCloseLocation(); Op = OO_Call; break; } case tok::l_square: { - // Consume the '['. - SourceLocation LBracketLoc = ConsumeBracket(); - // Consume the ']'. - SourceLocation RBracketLoc = MatchRHSPunctuation(tok::r_square, - LBracketLoc); - if (RBracketLoc.isInvalid()) + // Consume the '[' and ']'. + BalancedDelimiterTracker T(*this, tok::l_square); + T.consumeOpen(); + T.consumeClose(); + if (T.getCloseLocation().isInvalid()) return true; - SymbolLocations[SymbolIdx++] = LBracketLoc; - SymbolLocations[SymbolIdx++] = RBracketLoc; + SymbolLocations[SymbolIdx++] = T.getOpenLocation(); + SymbolLocations[SymbolIdx++] = T.getCloseLocation(); Op = OO_Subscript; break; } @@ -2012,13 +2021,16 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) { Declarator DeclaratorInfo(DS, Declarator::CXXNewContext); if (Tok.is(tok::l_paren)) { // If it turns out to be a placement, we change the type location. - PlacementLParen = ConsumeParen(); + BalancedDelimiterTracker T(*this, tok::l_paren); + T.consumeOpen(); + PlacementLParen = T.getOpenLocation(); if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) { SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); return ExprError(); } - PlacementRParen = MatchRHSPunctuation(tok::r_paren, PlacementLParen); + T.consumeClose(); + PlacementRParen = T.getCloseLocation(); if (PlacementRParen.isInvalid()) { SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); return ExprError(); @@ -2026,18 +2038,19 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) { if (PlacementArgs.empty()) { // Reset the placement locations. There was no placement. - TypeIdParens = SourceRange(PlacementLParen, PlacementRParen); + TypeIdParens = T.getRange(); PlacementLParen = PlacementRParen = SourceLocation(); } else { // We still need the type. if (Tok.is(tok::l_paren)) { - TypeIdParens.setBegin(ConsumeParen()); + BalancedDelimiterTracker T(*this, tok::l_paren); + T.consumeOpen(); MaybeParseGNUAttributes(DeclaratorInfo); ParseSpecifierQualifierList(DS); DeclaratorInfo.SetSourceRange(DS.getSourceRange()); ParseDeclarator(DeclaratorInfo); - TypeIdParens.setEnd(MatchRHSPunctuation(tok::r_paren, - TypeIdParens.getBegin())); + T.consumeClose(); + TypeIdParens = T.getRange(); } else { MaybeParseGNUAttributes(DeclaratorInfo); if (ParseCXXTypeSpecifierSeq(DS)) @@ -2070,7 +2083,9 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) { SourceLocation ConstructorLParen, ConstructorRParen; if (Tok.is(tok::l_paren)) { - ConstructorLParen = ConsumeParen(); + BalancedDelimiterTracker T(*this, tok::l_paren); + T.consumeOpen(); + ConstructorLParen = T.getOpenLocation(); if (Tok.isNot(tok::r_paren)) { CommaLocsTy CommaLocs; if (ParseExpressionList(ConstructorArgs, CommaLocs)) { @@ -2078,7 +2093,8 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) { return ExprError(); } } - ConstructorRParen = MatchRHSPunctuation(tok::r_paren, ConstructorLParen); + T.consumeClose(); + ConstructorRParen = T.getCloseLocation(); if (ConstructorRParen.isInvalid()) { SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); return ExprError(); @@ -2105,7 +2121,9 @@ void Parser::ParseDirectNewDeclarator(Declarator &D) { // Parse the array dimensions. bool first = true; while (Tok.is(tok::l_square)) { - SourceLocation LLoc = ConsumeBracket(); + BalancedDelimiterTracker T(*this, tok::l_square); + T.consumeOpen(); + ExprResult Size(first ? ParseExpression() : ParseConstantExpression()); if (Size.isInvalid()) { @@ -2115,15 +2133,17 @@ void Parser::ParseDirectNewDeclarator(Declarator &D) { } first = false; - SourceLocation RLoc = MatchRHSPunctuation(tok::r_square, LLoc); + T.consumeClose(); ParsedAttributes attrs(AttrFactory); D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false, - Size.release(), LLoc, RLoc), - attrs, RLoc); + Size.release(), + T.getOpenLocation(), + T.getCloseLocation()), + attrs, T.getCloseLocation()); - if (RLoc.isInvalid()) + if (T.getCloseLocation().isInvalid()) return; } } @@ -2175,9 +2195,11 @@ Parser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) { bool ArrayDelete = false; if (Tok.is(tok::l_square)) { ArrayDelete = true; - SourceLocation LHS = ConsumeBracket(); - SourceLocation RHS = MatchRHSPunctuation(tok::r_square, LHS); - if (RHS.isInvalid()) + BalancedDelimiterTracker T(*this, tok::l_square); + + T.consumeOpen(); + T.consumeClose(); + if (T.getCloseLocation().isInvalid()) return ExprError(); } @@ -2275,8 +2297,8 @@ ExprResult Parser::ParseUnaryTypeTrait() { UnaryTypeTrait UTT = UnaryTypeTraitFromTokKind(Tok.getKind()); SourceLocation Loc = ConsumeToken(); - SourceLocation LParen = Tok.getLocation(); - if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen)) + BalancedDelimiterTracker T(*this, tok::l_paren); + if (T.expectAndConsume(diag::err_expected_lparen)) return ExprError(); // FIXME: Error reporting absolutely sucks! If the this fails to parse a type @@ -2284,12 +2306,12 @@ ExprResult Parser::ParseUnaryTypeTrait() { // specifiers. TypeResult Ty = ParseTypeName(); - SourceLocation RParen = MatchRHSPunctuation(tok::r_paren, LParen); + T.consumeClose(); if (Ty.isInvalid()) return ExprError(); - return Actions.ActOnUnaryTypeTrait(UTT, Loc, Ty.get(), RParen); + return Actions.ActOnUnaryTypeTrait(UTT, Loc, Ty.get(), T.getCloseLocation()); } /// ParseBinaryTypeTrait - Parse the built-in binary type-trait @@ -2303,8 +2325,8 @@ ExprResult Parser::ParseBinaryTypeTrait() { BinaryTypeTrait BTT = BinaryTypeTraitFromTokKind(Tok.getKind()); SourceLocation Loc = ConsumeToken(); - SourceLocation LParen = Tok.getLocation(); - if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen)) + BalancedDelimiterTracker T(*this, tok::l_paren); + if (T.expectAndConsume(diag::err_expected_lparen)) return ExprError(); TypeResult LhsTy = ParseTypeName(); @@ -2324,9 +2346,10 @@ ExprResult Parser::ParseBinaryTypeTrait() { return ExprError(); } - SourceLocation RParen = MatchRHSPunctuation(tok::r_paren, LParen); + T.consumeClose(); - return Actions.ActOnBinaryTypeTrait(BTT, Loc, LhsTy.get(), RhsTy.get(), RParen); + return Actions.ActOnBinaryTypeTrait(BTT, Loc, LhsTy.get(), RhsTy.get(), + T.getCloseLocation()); } /// ParseArrayTypeTrait - Parse the built-in array type-trait @@ -2340,8 +2363,8 @@ ExprResult Parser::ParseArrayTypeTrait() { ArrayTypeTrait ATT = ArrayTypeTraitFromTokKind(Tok.getKind()); SourceLocation Loc = ConsumeToken(); - SourceLocation LParen = Tok.getLocation(); - if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen)) + BalancedDelimiterTracker T(*this, tok::l_paren); + if (T.expectAndConsume(diag::err_expected_lparen)) return ExprError(); TypeResult Ty = ParseTypeName(); @@ -2353,8 +2376,9 @@ ExprResult Parser::ParseArrayTypeTrait() { switch (ATT) { case ATT_ArrayRank: { - SourceLocation RParen = MatchRHSPunctuation(tok::r_paren, LParen); - return Actions.ActOnArrayTypeTrait(ATT, Loc, Ty.get(), NULL, RParen); + T.consumeClose(); + return Actions.ActOnArrayTypeTrait(ATT, Loc, Ty.get(), NULL, + T.getCloseLocation()); } case ATT_ArrayExtent: { if (ExpectAndConsume(tok::comma, diag::err_expected_comma)) { @@ -2363,9 +2387,10 @@ ExprResult Parser::ParseArrayTypeTrait() { } ExprResult DimExpr = ParseExpression(); - SourceLocation RParen = MatchRHSPunctuation(tok::r_paren, LParen); + T.consumeClose(); - return Actions.ActOnArrayTypeTrait(ATT, Loc, Ty.get(), DimExpr.get(), RParen); + return Actions.ActOnArrayTypeTrait(ATT, Loc, Ty.get(), DimExpr.get(), + T.getCloseLocation()); } default: break; @@ -2383,15 +2408,16 @@ ExprResult Parser::ParseExpressionTrait() { ExpressionTrait ET = ExpressionTraitFromTokKind(Tok.getKind()); SourceLocation Loc = ConsumeToken(); - SourceLocation LParen = Tok.getLocation(); - if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen)) + BalancedDelimiterTracker T(*this, tok::l_paren); + if (T.expectAndConsume(diag::err_expected_lparen)) return ExprError(); ExprResult Expr = ParseExpression(); - SourceLocation RParen = MatchRHSPunctuation(tok::r_paren, LParen); + T.consumeClose(); - return Actions.ActOnExpressionTrait(ET, Loc, Expr.get(), RParen); + return Actions.ActOnExpressionTrait(ET, Loc, Expr.get(), + T.getCloseLocation()); } @@ -2401,8 +2427,7 @@ ExprResult Parser::ParseExpressionTrait() { ExprResult Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, ParsedType &CastTy, - SourceLocation LParenLoc, - SourceLocation &RParenLoc) { + BalancedDelimiterTracker &Tracker) { assert(getLang().CPlusPlus && "Should only be called for C++!"); assert(ExprType == CastExpr && "Compound literals are not ambiguous!"); assert(isTypeIdInParens() && "Not a type-id!"); @@ -2436,7 +2461,7 @@ Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, // the context that follows them. if (!ConsumeAndStoreUntil(tok::r_paren, Toks)) { // We didn't find the ')' we expected. - MatchRHSPunctuation(tok::r_paren, LParenLoc); + Tracker.consumeClose(); return ExprError(); } @@ -2481,15 +2506,14 @@ Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, ParseDeclarator(DeclaratorInfo); // Match the ')'. - if (Tok.is(tok::r_paren)) - RParenLoc = ConsumeParen(); - else - MatchRHSPunctuation(tok::r_paren, LParenLoc); + Tracker.consumeClose(); if (ParseAs == CompoundLiteral) { ExprType = CompoundLiteral; TypeResult Ty = ParseTypeName(); - return ParseCompoundLiteralExpression(Ty.get(), LParenLoc, RParenLoc); + return ParseCompoundLiteralExpression(Ty.get(), + Tracker.getOpenLocation(), + Tracker.getCloseLocation()); } // We parsed '(' type-id ')' and the thing after it wasn't a '{'. @@ -2500,9 +2524,9 @@ Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, // Result is what ParseCastExpression returned earlier. if (!Result.isInvalid()) - Result = Actions.ActOnCastExpr(getCurScope(), LParenLoc, - DeclaratorInfo, CastTy, - RParenLoc, Result.take()); + Result = Actions.ActOnCastExpr(getCurScope(), Tracker.getOpenLocation(), + DeclaratorInfo, CastTy, + Tracker.getCloseLocation(), Result.take()); return move(Result); } @@ -2512,7 +2536,8 @@ Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, ExprType = SimpleExpr; Result = ParseExpression(); if (!Result.isInvalid() && Tok.is(tok::r_paren)) - Result = Actions.ActOnParenExpr(LParenLoc, Tok.getLocation(), Result.take()); + Result = Actions.ActOnParenExpr(Tracker.getOpenLocation(), + Tok.getLocation(), Result.take()); // Match the ')'. if (Result.isInvalid()) { @@ -2520,10 +2545,6 @@ Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, return ExprError(); } - if (Tok.is(tok::r_paren)) - RParenLoc = ConsumeParen(); - else - MatchRHSPunctuation(tok::r_paren, LParenLoc); - + Tracker.consumeClose(); return move(Result); } |