diff options
Diffstat (limited to 'lib/Parse/ParseExpr.cpp')
-rw-r--r-- | lib/Parse/ParseExpr.cpp | 148 |
1 files changed, 79 insertions, 69 deletions
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 4a0e1c5e34130..2a65eec8a0f63 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -441,7 +441,7 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { // is okay, to bind exactly as tightly. For example, compile A=B=C=D as // A=(B=(C=D)), where each paren is a level of recursion here. // The function takes ownership of the RHS. - RHS = ParseRHSOfBinaryExpression(RHS, + RHS = ParseRHSOfBinaryExpression(RHS, static_cast<prec::Level>(ThisPrec + !isRightAssoc)); RHSIsInitList = false; @@ -656,14 +656,14 @@ class CastExpressionIdValidator : public CorrectionCandidateCallback { /// /// id-expression: [C++ 5.1] /// unqualified-id -/// qualified-id +/// qualified-id /// /// unqualified-id: [C++ 5.1] /// identifier /// operator-function-id /// conversion-function-id -/// '~' class-name -/// template-id +/// '~' class-name +/// template-id /// /// new-expression: [C++ 5.3.4] /// '::'[opt] 'new' new-placement[opt] new-type-id @@ -729,7 +729,7 @@ class CastExpressionIdValidator : public CorrectionCandidateCallback { /// '__trivially_copyable' /// /// binary-type-trait: -/// [GNU] '__is_base_of' +/// [GNU] '__is_base_of' /// [MS] '__is_convertible_to' /// '__is_convertible' /// '__is_same' @@ -789,6 +789,10 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, // We have parsed the cast-expression and no postfix-expr pieces are // following. return Res; + case FoldExpr: + // We only parsed a fold-expression. There might be postfix-expr pieces + // afterwards; parse them now. + break; } break; @@ -807,7 +811,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, case tok::kw_false: Res = ParseCXXBoolLiteral(); break; - + case tok::kw___objc_yes: case tok::kw___objc_no: return ParseObjCBoolLiteral(); @@ -831,7 +835,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, return ExprError(); assert(Tok.isNot(tok::kw_decltype) && Tok.isNot(tok::kw___super)); return ParseCastExpression(isUnaryExpression, isAddressOfOperand); - + case tok::identifier: { // primary-expression: identifier // unqualified-id: identifier // constant: enumeration-constant @@ -953,14 +957,14 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, return ExprError(); } // Allow either an identifier or the keyword 'class' (in C++). - if (Tok.isNot(tok::identifier) && + if (Tok.isNot(tok::identifier) && !(getLangOpts().CPlusPlus && Tok.is(tok::kw_class))) { Diag(Tok, diag::err_expected_property_name); return ExprError(); } IdentifierInfo &PropertyName = *Tok.getIdentifierInfo(); SourceLocation PropertyLoc = ConsumeToken(); - + Res = Actions.ActOnClassPropertyRefExpr(II, PropertyName, ILoc, PropertyLoc); break; @@ -969,7 +973,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, // In an Objective-C method, if we have "super" followed by an identifier, // the token sequence is ill-formed. However, if there's a ':' or ']' after // that identifier, this is probably a message send with a missing open - // bracket. Treat it as such. + // bracket. Treat it as such. if (getLangOpts().ObjC1 && &II == Ident_super && !InMessageExpression && getCurScope()->isInObjcMethodScope() && ((Tok.is(tok::identifier) && @@ -979,17 +983,17 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, nullptr); break; } - + // If we have an Objective-C class name followed by an identifier // and either ':' or ']', this is an Objective-C class message // send that's missing the opening '['. Recovery // appropriately. Also take this path if we're performing code // completion after an Objective-C class name. - if (getLangOpts().ObjC1 && - ((Tok.is(tok::identifier) && !InMessageExpression) || + if (getLangOpts().ObjC1 && + ((Tok.is(tok::identifier) && !InMessageExpression) || Tok.is(tok::code_completion))) { const Token& Next = NextToken(); - if (Tok.is(tok::code_completion) || + if (Tok.is(tok::code_completion) || Next.is(tok::colon) || Next.is(tok::r_square)) if (ParsedType Typ = Actions.getTypeName(II, ILoc, getCurScope())) if (Typ.get()->isObjCObjectOrInterfaceType()) { @@ -1001,24 +1005,24 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, unsigned DiagID; DS.SetTypeSpecType(TST_typename, ILoc, PrevSpec, DiagID, Typ, Actions.getASTContext().getPrintingPolicy()); - + Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext); - TypeResult Ty = Actions.ActOnTypeName(getCurScope(), + TypeResult Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); if (Ty.isInvalid()) break; - Res = ParseObjCMessageExpressionBody(SourceLocation(), - SourceLocation(), + Res = ParseObjCMessageExpressionBody(SourceLocation(), + SourceLocation(), Ty.get(), nullptr); break; } } - + // Make sure to pass down the right value for isAddressOfOperand. if (isAddressOfOperand && isPostfixExpressionSuffixStart()) isAddressOfOperand = false; - + // Function designators are allowed to be undeclared (C99 6.5.1p2), so we // need to know whether or not this identifier is a function designator or // not. @@ -1175,7 +1179,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, if (getCurScope()->getFnParent() == nullptr) return ExprError(Diag(Tok, diag::err_address_of_label_outside_fn)); - + Diag(AmpAmpLoc, diag::ext_gnu_address_of_label); LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(), Tok.getLocation()); @@ -1380,7 +1384,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, T.consumeClose(); if (!Result.isInvalid()) - Result = Actions.ActOnNoexceptExpr(KeyLoc, T.getOpenLocation(), + Result = Actions.ActOnNoexceptExpr(KeyLoc, T.getOpenLocation(), Result.get(), T.getCloseLocation()); return Result; } @@ -1389,7 +1393,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, case tok::kw_##Spelling: #include "clang/Basic/TokenKinds.def" return ParseTypeTrait(); - + case tok::kw___array_rank: case tok::kw___array_extent: return ParseArrayTypeTrait(); @@ -1397,7 +1401,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, case tok::kw___is_lvalue_expr: case tok::kw___is_rvalue_expr: return ParseExpressionTrait(); - + case tok::at: { SourceLocation AtLoc = ConsumeToken(); return ParseObjCAtExpression(AtLoc); @@ -1485,16 +1489,16 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { case tok::code_completion: if (InMessageExpression) return LHS; - + Actions.CodeCompletePostfixExpression(getCurScope(), LHS); cutOffParsing(); return ExprError(); - + case tok::identifier: // If we see identifier: after an expression, and we're not already in a // message send, then this is probably a message send with a missing // opening bracket '['. - if (getLangOpts().ObjC1 && !InMessageExpression && + if (getLangOpts().ObjC1 && !InMessageExpression && (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) { LHS = ParseObjCMessageExpressionBody(SourceLocation(), SourceLocation(), nullptr, LHS.get()); @@ -1616,8 +1620,8 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { if (!LHS.isInvalid()) { ExprResult ECResult = Actions.ActOnCUDAExecConfigExpr(getCurScope(), - OpenLoc, - ExecConfigExprs, + OpenLoc, + ExecConfigExprs, CloseLoc); if (ECResult.isInvalid()) LHS = ExprError(); @@ -1631,7 +1635,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { ExprVector ArgExprs; CommaLocsTy CommaLocs; - + if (Tok.is(tok::code_completion)) { Actions.CodeCompleteCall(getCurScope(), LHS.get(), None); cutOffParsing(); @@ -1671,7 +1675,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { PT.consumeClose(); LHS = ExprError(); } else { - assert((ArgExprs.size() == 0 || + assert((ArgExprs.size() == 0 || ArgExprs.size()-1 == CommaLocs.size())&& "Unexpected number of commas!"); LHS = Actions.ActOnCallExpr(getCurScope(), LHS.get(), Loc, @@ -1712,7 +1716,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { if (LHS.isInvalid()) break; - ParseOptionalCXXScopeSpecifier(SS, ObjectType, + ParseOptionalCXXScopeSpecifier(SS, ObjectType, /*EnteringContext=*/false, &MayBePseudoDestructor); if (SS.isNotEmpty()) @@ -1745,7 +1749,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { } if (MayBePseudoDestructor && !LHS.isInvalid()) { - LHS = ParseCXXPseudoDestructor(LHS.get(), OpLoc, OpKind, SS, + LHS = ParseCXXPseudoDestructor(LHS.get(), OpLoc, OpKind, SS, ObjectType); break; } @@ -1766,24 +1770,24 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { // 'class' as if it were an identifier. // // This hack allows property access to the 'class' method because it is - // such a common method name. For other C++ keywords that are + // such a common method name. For other C++ keywords that are // Objective-C method names, one must use the message send syntax. IdentifierInfo *Id = Tok.getIdentifierInfo(); SourceLocation Loc = ConsumeToken(); Name.setIdentifier(Id, Loc); - } else if (ParseUnqualifiedId(SS, - /*EnteringContext=*/false, + } else if (ParseUnqualifiedId(SS, + /*EnteringContext=*/false, /*AllowDestructorName=*/true, /*AllowConstructorName=*/ - getLangOpts().MicrosoftExt, + getLangOpts().MicrosoftExt, /*AllowDeductionGuide=*/false, ObjectType, &TemplateKWLoc, Name)) { (void)Actions.CorrectDelayedTyposInExpr(LHS); LHS = ExprError(); } - + if (!LHS.isInvalid()) - LHS = Actions.ActOnMemberAccessExpr(getCurScope(), LHS.get(), OpLoc, + LHS = Actions.ActOnMemberAccessExpr(getCurScope(), LHS.get(), OpLoc, OpKind, SS, TemplateKWLoc, Name, CurParsedObjCImpl ? CurParsedObjCImpl->Dcl : nullptr); @@ -1878,7 +1882,7 @@ Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok, ParenParseOption ExprType = CastExpr; SourceLocation LParenLoc = Tok.getLocation(), RParenLoc; - Operand = ParseParenExpression(ExprType, true/*stopIfCastExpr*/, + Operand = ParseParenExpression(ExprType, true/*stopIfCastExpr*/, false, CastTy, RParenLoc); CastRange = SourceRange(LParenLoc, RParenLoc); @@ -1892,7 +1896,7 @@ Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok, if (getLangOpts().CPlusPlus || OpTok.isNot(tok::kw_typeof)) { // GNU typeof in C requires the expression to be parenthesized. Not so for // sizeof/alignof or in C++. Therefore, the parenthesized expression is - // the start of a unary-expression, but doesn't include any postfix + // the start of a unary-expression, but doesn't include any postfix // pieces. Parse these now if present. if (!Operand.isInvalid()) Operand = ParsePostfixExpressionSuffix(Operand.get()); @@ -1958,7 +1962,7 @@ ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() { } else { Diag(Tok, diag::err_sizeof_parameter_pack); } - + if (!Name) return ExprError(); @@ -1967,7 +1971,7 @@ ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() { Sema::ReuseLambdaContextDecl); return Actions.ActOnSizeofParameterPackExpr(getCurScope(), - OpTok.getLocation(), + OpTok.getLocation(), *Name, NameLoc, RParenLoc); } @@ -2202,15 +2206,15 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() { TypeResult DestTy = ParseTypeName(); if (DestTy.isInvalid()) return ExprError(); - + // Attempt to consume the r-paren. if (Tok.isNot(tok::r_paren)) { Diag(Tok, diag::err_expected) << tok::r_paren; SkipUntil(tok::r_paren, StopAtSemi); return ExprError(); } - - Res = Actions.ActOnAsTypeExpr(Expr.get(), DestTy.get(), StartLoc, + + Res = Actions.ActOnAsTypeExpr(Expr.get(), DestTy.get(), StartLoc, ConsumeParen()); break; } @@ -2231,15 +2235,15 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() { TypeResult DestTy = ParseTypeName(); if (DestTy.isInvalid()) return ExprError(); - + // Attempt to consume the r-paren. if (Tok.isNot(tok::r_paren)) { Diag(Tok, diag::err_expected) << tok::r_paren; SkipUntil(tok::r_paren, StopAtSemi); return ExprError(); } - - Res = Actions.ActOnConvertVectorExpr(Expr.get(), DestTy.get(), StartLoc, + + Res = Actions.ActOnConvertVectorExpr(Expr.get(), DestTy.get(), StartLoc, ConsumeParen()); break; } @@ -2294,7 +2298,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, CastTy = nullptr; if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteOrdinaryName(getCurScope(), + Actions.CodeCompleteOrdinaryName(getCurScope(), ExprType >= CompoundLiteral? Sema::PCC_ParenthesizedExpression : Sema::PCC_Expression); cutOffParsing(); @@ -2318,7 +2322,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, } BridgeCast = false; } - + // None of these cases should fall through with an invalid Result // unless they've already reported an error. if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) { @@ -2372,16 +2376,16 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, << FixItHint::CreateReplacement(BridgeKeywordLoc, "__bridge_retained"); } - + TypeResult Ty = ParseTypeName(); T.consumeClose(); ColonProtection.restore(); RParenLoc = T.getCloseLocation(); ExprResult SubExpr = ParseCastExpression(/*isUnaryExpression=*/false); - + if (Ty.isInvalid() || SubExpr.isInvalid()) return ExprError(); - + return Actions.ActOnObjCBridgedCast(getCurScope(), OpenLoc, Kind, BridgeKeywordLoc, Ty.get(), RParenLoc, SubExpr.get()); @@ -2407,8 +2411,8 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, ParseSpecifierQualifierList(DS); Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext); ParseDeclarator(DeclaratorInfo); - - // If our type is followed by an identifier and either ':' or ']', then + + // If our type is followed by an identifier and either ':' or ']', then // this is probably an Objective-C message send where the leading '[' is // missing. Recover as if that were the case. if (!DeclaratorInfo.isInvalidType() && Tok.is(tok::identifier) && @@ -2419,10 +2423,10 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, InMessageExpressionRAIIObject InMessage(*this, false); Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); } - Result = ParseObjCMessageExpressionBody(SourceLocation(), - SourceLocation(), + Result = ParseObjCMessageExpressionBody(SourceLocation(), + SourceLocation(), Ty.get(), nullptr); - } else { + } else { // Match the ')'. T.consumeClose(); ColonProtection.restore(); @@ -2499,7 +2503,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, // Reject the cast of super idiom in ObjC. if (Tok.is(tok::identifier) && getLangOpts().ObjC1 && - Tok.getIdentifierInfo() == Ident_super && + Tok.getIdentifierInfo() == Ident_super && getCurScope()->isInObjcMethodScope() && GetLookAheadToken(1).isNot(tok::period)) { Diag(Tok.getLocation(), diag::err_illegal_super_cast) @@ -2514,7 +2518,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, /*isTypeCast=*/IsTypeCast); if (!Result.isInvalid()) { Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc, - DeclaratorInfo, CastTy, + DeclaratorInfo, CastTy, RParenLoc, Result.get()); } return Result; @@ -2523,8 +2527,9 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, Diag(Tok, diag::err_expected_lbrace_in_compound_literal); return ExprError(); } - } else if (Tok.is(tok::ellipsis) && + } else if (ExprType >= FoldExpr && Tok.is(tok::ellipsis) && isFoldOperator(NextToken().getKind())) { + ExprType = FoldExpr; return ParseFoldExpression(ExprResult(), T); } else if (isTypeCast) { // Parse the expression-list. @@ -2536,9 +2541,11 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, if (!ParseSimpleExpressionList(ArgExprs, CommaLocs)) { // FIXME: If we ever support comma expressions as operands to // fold-expressions, we'll need to allow multiple ArgExprs here. - if (ArgExprs.size() == 1 && isFoldOperator(Tok.getKind()) && - NextToken().is(tok::ellipsis)) + if (ExprType >= FoldExpr && ArgExprs.size() == 1 && + isFoldOperator(Tok.getKind()) && NextToken().is(tok::ellipsis)) { + ExprType = FoldExpr; return ParseFoldExpression(ArgExprs[0], T); + } ExprType = SimpleExpr; Result = Actions.ActOnParenListExpr(OpenLoc, Tok.getLocation(), @@ -2553,10 +2560,13 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, // expressions are parsed correctly. Result = Actions.CorrectDelayedTyposInExpr(Result); } - ExprType = SimpleExpr; - if (isFoldOperator(Tok.getKind()) && NextToken().is(tok::ellipsis)) + if (ExprType >= FoldExpr && isFoldOperator(Tok.getKind()) && + NextToken().is(tok::ellipsis)) { + ExprType = FoldExpr; return ParseFoldExpression(Result, T); + } + ExprType = SimpleExpr; // Don't build a paren expression unless we actually match a ')'. if (!Result.isInvalid() && Tok.is(tok::r_paren)) @@ -2712,7 +2722,7 @@ ExprResult Parser::ParseGenericSelectionExpression() { if (T.getCloseLocation().isInvalid()) return ExprError(); - return Actions.ActOnGenericSelectionExpr(KeyLoc, DefaultLoc, + return Actions.ActOnGenericSelectionExpr(KeyLoc, DefaultLoc, T.getCloseLocation(), ControllingExpr.get(), Types, Exprs); @@ -2815,7 +2825,7 @@ bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs, Expr = ParseAssignmentExpression(); if (Tok.is(tok::ellipsis)) - Expr = Actions.ActOnPackExpansion(Expr.get(), ConsumeToken()); + Expr = Actions.ActOnPackExpansion(Expr.get(), ConsumeToken()); if (Expr.isInvalid()) { SkipUntil(tok::comma, tok::r_paren, StopBeforeMatch); SawError = true; @@ -2882,7 +2892,7 @@ void Parser::ParseBlockId(SourceLocation CaretLoc) { Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Type); return cutOffParsing(); } - + // Parse the specifier-qualifier-list piece. DeclSpec DS(AttrFactory); ParseSpecifierQualifierList(DS); |