Mercurial > hg > CbC > CbC_llvm
diff clang/lib/Parse/ParseExpr.cpp @ 207:2e18cbf3894f
LLVM12
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 08 Jun 2021 06:07:14 +0900 |
parents | 0572611fdcc8 |
children | dd44ba33042e c4bab56944e8 |
line wrap: on
line diff
--- a/clang/lib/Parse/ParseExpr.cpp Mon May 25 11:55:54 2020 +0900 +++ b/clang/lib/Parse/ParseExpr.cpp Tue Jun 08 06:07:14 2021 +0900 @@ -159,9 +159,9 @@ /// Parse an expr that doesn't include (top-level) commas. ExprResult Parser::ParseAssignmentExpression(TypeCastState isTypeCast) { if (Tok.is(tok::code_completion)) { + cutOffParsing(); Actions.CodeCompleteExpression(getCurScope(), PreferredType.get(Tok.getLocation())); - cutOffParsing(); return ExprError(); } @@ -920,6 +920,11 @@ auto SavedType = PreferredType; NotCastExpr = false; + // Are postfix-expression suffix operators permitted after this + // cast-expression? If not, and we find some, we'll parse them anyway and + // diagnose them. + bool AllowSuffix = true; + // This handles all of cast-expression, unary-expression, postfix-expression, // and primary-expression. We handle them together like this for efficiency // and to simplify handling of an expression starting with a '(' token: which @@ -929,8 +934,7 @@ // If the parsed tokens consist of a primary-expression, the cases below // break out of the switch; at the end we call ParsePostfixExpressionSuffix // to handle the postfix expression suffixes. Cases that cannot be followed - // by postfix exprs should return without invoking - // ParsePostfixExpressionSuffix. + // by postfix exprs should set AllowSuffix to false. switch (SavedKind) { case tok::l_paren: { // If this expression is limited to being a unary-expression, the paren can @@ -953,8 +957,11 @@ Res = ParseParenExpression(ParenExprType, false/*stopIfCastExr*/, isTypeCast == IsTypeCast, CastTy, RParenLoc); + // FIXME: What should we do if a vector literal is followed by a + // postfix-expression suffix? Usually postfix operators are permitted on + // literals. if (isVectorLiteral) - return Res; + return Res; switch (ParenExprType) { case SimpleExpr: break; // Nothing else to do. @@ -992,14 +999,19 @@ case tok::kw___objc_yes: case tok::kw___objc_no: - return ParseObjCBoolLiteral(); + Res = ParseObjCBoolLiteral(); + break; case tok::kw_nullptr: Diag(Tok, diag::warn_cxx98_compat_nullptr); - return Actions.ActOnCXXNullPtrLiteral(ConsumeToken()); + Res = Actions.ActOnCXXNullPtrLiteral(ConsumeToken()); + break; case tok::annot_primary_expr: + case tok::annot_overload_set: Res = getExprAnnotation(Tok); + if (!Res.isInvalid() && Tok.getKind() == tok::annot_overload_set) + Res = Actions.ActOnNameClassifiedAsOverloadSet(getCurScope(), Res.get()); ConsumeAnnotationToken(); if (!Res.isInvalid() && Tok.is(tok::less)) checkPotentialAngleBracket(Res); @@ -1144,9 +1156,9 @@ ConsumeToken(); if (Tok.is(tok::code_completion) && &II != Ident_super) { + cutOffParsing(); Actions.CodeCompleteObjCClassPropertyRefExpr( getCurScope(), II, ILoc, ExprStatementTokLoc == ILoc); - cutOffParsing(); return ExprError(); } // Allow either an identifier or the keyword 'class' (in C++). @@ -1199,7 +1211,7 @@ DS.SetTypeSpecType(TST_typename, ILoc, PrevSpec, DiagID, Typ, Actions.getASTContext().getPrintingPolicy()); - Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext); + Declarator DeclaratorInfo(DS, DeclaratorContext::TypeName); TypeResult Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); if (Ty.isInvalid()) @@ -1280,7 +1292,8 @@ Res = ParseGenericSelectionExpression(); break; case tok::kw___builtin_available: - return ParseAvailabilityCheckExpr(Tok.getLocation()); + Res = ParseAvailabilityCheckExpr(Tok.getLocation()); + break; case tok::kw___builtin_va_arg: case tok::kw___builtin_offsetof: case tok::kw___builtin_choose_expr: @@ -1292,9 +1305,11 @@ case tok::kw___builtin_LINE: if (NotPrimaryExpression) *NotPrimaryExpression = true; + // This parses the complete suffix; we can return early. return ParseBuiltinPrimaryExpression(); case tok::kw___null: - return Actions.ActOnGNUNullExpr(ConsumeToken()); + Res = Actions.ActOnGNUNullExpr(ConsumeToken()); + break; case tok::plusplus: // unary-expression: '++' unary-expression [C99] case tok::minusminus: { // unary-expression: '--' unary-expression [C99] @@ -1406,7 +1421,9 @@ case tok::kw___builtin_omp_required_simd_align: if (NotPrimaryExpression) *NotPrimaryExpression = true; - return ParseUnaryExprOrTypeTraitExpression(); + AllowSuffix = false; + Res = ParseUnaryExprOrTypeTraitExpression(); + break; case tok::ampamp: { // unary-expression: '&&' identifier if (NotPrimaryExpression) *NotPrimaryExpression = true; @@ -1422,7 +1439,8 @@ Tok.getLocation()); Res = Actions.ActOnAddrLabel(AmpAmpLoc, Tok.getLocation(), LD); ConsumeToken(); - return Res; + AllowSuffix = false; + break; } case tok::kw_const_cast: case tok::kw_dynamic_cast: @@ -1451,9 +1469,10 @@ case tok::kw_this: Res = ParseCXXThis(); break; - case tok::kw___builtin_unique_stable_name: - Res = ParseUniqueStableNameExpression(); + case tok::kw___builtin_sycl_unique_stable_name: + Res = ParseSYCLUniqueStableNameExpression(); break; + case tok::annot_typename: if (isStartOfObjCClassMessageMissingOpenBracket()) { TypeResult Type = getTypeAnnotation(Tok); @@ -1469,7 +1488,7 @@ PrevSpec, DiagID, Type, Actions.getASTContext().getPrintingPolicy()); - Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext); + Declarator DeclaratorInfo(DS, DeclaratorContext::TypeName); TypeResult Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); if (Ty.isInvalid()) break; @@ -1499,6 +1518,7 @@ case tok::kw_half: case tok::kw_float: case tok::kw_double: + case tok::kw___bf16: case tok::kw__Float16: case tok::kw___float128: case tok::kw_void: @@ -1616,12 +1636,16 @@ if (Tok.is(tok::kw_new)) { if (NotPrimaryExpression) *NotPrimaryExpression = true; - return ParseCXXNewExpression(true, CCLoc); + Res = ParseCXXNewExpression(true, CCLoc); + AllowSuffix = false; + break; } if (Tok.is(tok::kw_delete)) { if (NotPrimaryExpression) *NotPrimaryExpression = true; - return ParseCXXDeleteExpression(true, CCLoc); + Res = ParseCXXDeleteExpression(true, CCLoc); + AllowSuffix = false; + break; } // This is not a type name or scope specifier, it is an invalid expression. @@ -1632,15 +1656,21 @@ case tok::kw_new: // [C++] new-expression if (NotPrimaryExpression) *NotPrimaryExpression = true; - return ParseCXXNewExpression(false, Tok.getLocation()); + Res = ParseCXXNewExpression(false, Tok.getLocation()); + AllowSuffix = false; + break; case tok::kw_delete: // [C++] delete-expression if (NotPrimaryExpression) *NotPrimaryExpression = true; - return ParseCXXDeleteExpression(false, Tok.getLocation()); + Res = ParseCXXDeleteExpression(false, Tok.getLocation()); + AllowSuffix = false; + break; case tok::kw_requires: // [C++2a] requires-expression - return ParseRequiresExpression(); + Res = ParseRequiresExpression(); + AllowSuffix = false; + break; case tok::kw_noexcept: { // [C++0x] 'noexcept' '(' expression ')' if (NotPrimaryExpression) @@ -1656,32 +1686,36 @@ // which is an unevaluated operand, can throw an exception. EnterExpressionEvaluationContext Unevaluated( Actions, Sema::ExpressionEvaluationContext::Unevaluated); - ExprResult Result = ParseExpression(); + Res = ParseExpression(); T.consumeClose(); - if (!Result.isInvalid()) - Result = Actions.ActOnNoexceptExpr(KeyLoc, T.getOpenLocation(), - Result.get(), T.getCloseLocation()); - return Result; + if (!Res.isInvalid()) + Res = Actions.ActOnNoexceptExpr(KeyLoc, T.getOpenLocation(), Res.get(), + T.getCloseLocation()); + AllowSuffix = false; + break; } #define TYPE_TRAIT(N,Spelling,K) \ case tok::kw_##Spelling: #include "clang/Basic/TokenKinds.def" - return ParseTypeTrait(); + Res = ParseTypeTrait(); + break; case tok::kw___array_rank: case tok::kw___array_extent: if (NotPrimaryExpression) *NotPrimaryExpression = true; - return ParseArrayTypeTrait(); + Res = ParseArrayTypeTrait(); + break; case tok::kw___is_lvalue_expr: case tok::kw___is_rvalue_expr: if (NotPrimaryExpression) *NotPrimaryExpression = true; - return ParseExpressionTrait(); + Res = ParseExpressionTrait(); + break; case tok::at: { if (NotPrimaryExpression) @@ -1693,9 +1727,9 @@ Res = ParseBlockLiteralExpression(); break; case tok::code_completion: { + cutOffParsing(); Actions.CodeCompleteExpression(getCurScope(), PreferredType.get(Tok.getLocation())); - cutOffParsing(); return ExprError(); } case tok::l_square: @@ -1738,10 +1772,47 @@ // parsed. return Res; + if (!AllowSuffix) { + // FIXME: Don't parse a primary-expression suffix if we encountered a parse + // error already. + if (Res.isInvalid()) + return Res; + + switch (Tok.getKind()) { + case tok::l_square: + case tok::l_paren: + case tok::plusplus: + case tok::minusminus: + // "expected ';'" or similar is probably the right diagnostic here. Let + // the caller decide what to do. + if (Tok.isAtStartOfLine()) + return Res; + + LLVM_FALLTHROUGH; + case tok::period: + case tok::arrow: + break; + + default: + return Res; + } + + // This was a unary-expression for which a postfix-expression suffix is + // not permitted by the grammar (eg, a sizeof expression or + // new-expression or similar). Diagnose but parse the suffix anyway. + Diag(Tok.getLocation(), diag::err_postfix_after_unary_requires_parens) + << Tok.getKind() << Res.get()->getSourceRange() + << FixItHint::CreateInsertion(Res.get()->getBeginLoc(), "(") + << FixItHint::CreateInsertion(PP.getLocForEndOfToken(PrevTokLocation), + ")"); + } + // These can be followed by postfix-expr pieces. PreferredType = SavedType; Res = ParsePostfixExpressionSuffix(Res); - if (getLangOpts().OpenCL) + if (getLangOpts().OpenCL && + !getActions().getOpenCLOptions().isAvailableOption( + "__cl_clang_function_pointers", getLangOpts())) if (Expr *PostfixExpr = Res.get()) { QualType Ty = PostfixExpr->getType(); if (!Ty.isNull() && Ty->isFunctionType()) { @@ -1788,9 +1859,9 @@ if (InMessageExpression) return LHS; + cutOffParsing(); Actions.CodeCompletePostfixExpression( getCurScope(), LHS, PreferredType.get(Tok.getLocation())); - cutOffParsing(); return ExprError(); case tok::identifier: @@ -1829,8 +1900,8 @@ BalancedDelimiterTracker T(*this, tok::l_square); T.consumeOpen(); Loc = T.getOpenLocation(); - ExprResult Idx, Length; - SourceLocation ColonLoc; + ExprResult Idx, Length, Stride; + SourceLocation ColonLocFirst, ColonLocSecond; PreferredType.enterSubscript(Actions, Tok.getLocation(), LHS.get()); if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); @@ -1844,10 +1915,22 @@ } if (Tok.is(tok::colon)) { // Consume ':' - ColonLoc = ConsumeToken(); - if (Tok.isNot(tok::r_square)) + ColonLocFirst = ConsumeToken(); + if (Tok.isNot(tok::r_square) && + (getLangOpts().OpenMP < 50 || + ((Tok.isNot(tok::colon) && getLangOpts().OpenMP >= 50)))) Length = ParseExpression(); } + if (getLangOpts().OpenMP >= 50 && + (OMPClauseKind == llvm::omp::Clause::OMPC_to || + OMPClauseKind == llvm::omp::Clause::OMPC_from) && + Tok.is(tok::colon)) { + // Consume ':' + ColonLocSecond = ConsumeToken(); + if (Tok.isNot(tok::r_square)) { + Stride = ParseExpression(); + } + } } else Idx = ParseExpression(); @@ -1857,10 +1940,11 @@ Idx = Actions.CorrectDelayedTyposInExpr(Idx); Length = Actions.CorrectDelayedTyposInExpr(Length); if (!LHS.isInvalid() && !Idx.isInvalid() && !Length.isInvalid() && - Tok.is(tok::r_square)) { - if (ColonLoc.isValid()) { - LHS = Actions.ActOnOMPArraySectionExpr(LHS.get(), Loc, Idx.get(), - ColonLoc, Length.get(), RLoc); + !Stride.isInvalid() && Tok.is(tok::r_square)) { + if (ColonLocFirst.isValid() || ColonLocSecond.isValid()) { + LHS = Actions.ActOnOMPArraySectionExpr( + LHS.get(), Loc, Idx.get(), ColonLocFirst, ColonLocSecond, + Length.get(), Stride.get(), RLoc); } else { LHS = Actions.ActOnArraySubscriptExpr(getCurScope(), LHS.get(), Loc, Idx.get(), RLoc); @@ -2059,12 +2143,12 @@ CorrectedBase = Base; // Code completion for a member access expression. + cutOffParsing(); Actions.CodeCompleteMemberReferenceExpr( getCurScope(), Base, CorrectedBase, OpLoc, OpKind == tok::arrow, Base && ExprStatementTokLoc == Base->getBeginLoc(), PreferredType.get(Tok.getLocation())); - cutOffParsing(); return ExprError(); } @@ -2182,15 +2266,20 @@ if (isTypeIdUnambiguously()) { DeclSpec DS(AttrFactory); ParseSpecifierQualifierList(DS); - Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext); + Declarator DeclaratorInfo(DS, DeclaratorContext::TypeName); ParseDeclarator(DeclaratorInfo); SourceLocation LParenLoc = PP.getLocForEndOfToken(OpTok.getLocation()); SourceLocation RParenLoc = PP.getLocForEndOfToken(PrevTokLocation); - Diag(LParenLoc, diag::err_expected_parentheses_around_typename) - << OpTok.getName() - << FixItHint::CreateInsertion(LParenLoc, "(") - << FixItHint::CreateInsertion(RParenLoc, ")"); + if (LParenLoc.isInvalid() || RParenLoc.isInvalid()) { + Diag(OpTok.getLocation(), + diag::err_expected_parentheses_around_typename) + << OpTok.getName(); + } else { + Diag(LParenLoc, diag::err_expected_parentheses_around_typename) + << OpTok.getName() << FixItHint::CreateInsertion(LParenLoc, "(") + << FixItHint::CreateInsertion(RParenLoc, ")"); + } isCastExpr = true; return ExprEmpty(); } @@ -2238,42 +2327,32 @@ return Operand; } - -ExprResult Parser::ParseUniqueStableNameExpression() { - assert(Tok.is(tok::kw___builtin_unique_stable_name) && - "Not __bulitin_unique_stable_name"); +/// Parse a __builtin_sycl_unique_stable_name expression. Accepts a type-id as +/// a parameter. +ExprResult Parser::ParseSYCLUniqueStableNameExpression() { + assert(Tok.is(tok::kw___builtin_sycl_unique_stable_name) && + "Not __bulitin_sycl_unique_stable_name"); SourceLocation OpLoc = ConsumeToken(); BalancedDelimiterTracker T(*this, tok::l_paren); - // typeid expressions are always parenthesized. + // __builtin_sycl_unique_stable_name expressions are always parenthesized. if (T.expectAndConsume(diag::err_expected_lparen_after, - "__builtin_unique_stable_name")) + "__builtin_sycl_unique_stable_name")) return ExprError(); - if (isTypeIdInParens()) { - TypeResult Ty = ParseTypeName(); - T.consumeClose(); - - if (Ty.isInvalid()) - return ExprError(); - - return Actions.ActOnUniqueStableNameExpr(OpLoc, T.getOpenLocation(), - T.getCloseLocation(), Ty.get()); + TypeResult Ty = ParseTypeName(); + + if (Ty.isInvalid()) { + T.skipToEnd(); + return ExprError(); } - EnterExpressionEvaluationContext Unevaluated( - Actions, Sema::ExpressionEvaluationContext::Unevaluated); - ExprResult Result = ParseExpression(); - - if (Result.isInvalid()) { - SkipUntil(tok::r_paren, StopAtSemi); - return Result; - } - - T.consumeClose(); - return Actions.ActOnUniqueStableNameExpr(OpLoc, T.getOpenLocation(), - T.getCloseLocation(), Result.get()); + if (T.consumeClose()) + return ExprError(); + + return Actions.ActOnSYCLUniqueStableNameExpr(OpLoc, T.getOpenLocation(), + T.getCloseLocation(), Ty.get()); } /// Parse a sizeof or alignof expression. @@ -2729,10 +2808,10 @@ CastTy = nullptr; if (Tok.is(tok::code_completion)) { + cutOffParsing(); Actions.CodeCompleteExpression( getCurScope(), PreferredType.get(Tok.getLocation()), /*IsParenthesized=*/ExprType >= CompoundLiteral); - cutOffParsing(); return ExprError(); } @@ -2759,6 +2838,8 @@ if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) { Diag(Tok, diag::ext_gnu_statement_expr); + checkCompoundToken(OpenLoc, tok::l_paren, CompoundToken::StmtExprBegin); + if (!getCurScope()->getFnParent() && !getCurScope()->getBlockParent()) { Result = ExprError(Diag(OpenLoc, diag::err_stmtexpr_file_scope)); } else { @@ -2843,7 +2924,7 @@ // Parse the type declarator. DeclSpec DS(AttrFactory); ParseSpecifierQualifierList(DS); - Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext); + Declarator DeclaratorInfo(DS, DeclaratorContext::TypeName); ParseDeclarator(DeclaratorInfo); // If our type is followed by an identifier and either ':' or ']', then @@ -3067,6 +3148,7 @@ assert(Tok.is(tok::l_brace) && "Not a compound literal!"); if (!getLangOpts().C99) // Compound literals don't exist in C90. Diag(LParenLoc, diag::ext_c99_compound_literal); + PreferredType.enterTypeCast(Tok.getLocation(), Ty.get()); ExprResult Result = ParseInitializer(); if (!Result.isInvalid() && Ty) return Actions.ActOnCompoundLiteral(LParenLoc, Ty, RParenLoc, Result.get()); @@ -3243,8 +3325,9 @@ : diag::ext_fold_expression); T.consumeClose(); - return Actions.ActOnCXXFoldExpr(T.getOpenLocation(), LHS.get(), Kind, - EllipsisLoc, RHS.get(), T.getCloseLocation()); + return Actions.ActOnCXXFoldExpr(getCurScope(), T.getOpenLocation(), LHS.get(), + Kind, EllipsisLoc, RHS.get(), + T.getCloseLocation()); } /// ParseExpressionList - Used for C/C++ (argument-)expression-list. @@ -3359,8 +3442,9 @@ /// \endverbatim void Parser::ParseBlockId(SourceLocation CaretLoc) { if (Tok.is(tok::code_completion)) { + cutOffParsing(); Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Type); - return cutOffParsing(); + return; } // Parse the specifier-qualifier-list piece. @@ -3368,8 +3452,8 @@ ParseSpecifierQualifierList(DS); // Parse the block-declarator. - Declarator DeclaratorInfo(DS, DeclaratorContext::BlockLiteralContext); - DeclaratorInfo.setFunctionDefinitionKind(FDK_Definition); + Declarator DeclaratorInfo(DS, DeclaratorContext::BlockLiteral); + DeclaratorInfo.setFunctionDefinitionKind(FunctionDefinitionKind::Definition); ParseDeclarator(DeclaratorInfo); MaybeParseGNUAttributes(DeclaratorInfo); @@ -3407,8 +3491,8 @@ // Parse the return type if present. DeclSpec DS(AttrFactory); - Declarator ParamInfo(DS, DeclaratorContext::BlockLiteralContext); - ParamInfo.setFunctionDefinitionKind(FDK_Definition); + Declarator ParamInfo(DS, DeclaratorContext::BlockLiteral); + ParamInfo.setFunctionDefinitionKind(FunctionDefinitionKind::Definition); // FIXME: Since the return type isn't actually parsed, it can't be used to // fill ParamInfo with an initial valid range, so do it manually. ParamInfo.SetSourceRange(SourceRange(Tok.getLocation(), Tok.getLocation())); @@ -3545,8 +3629,8 @@ } else { // Parse the platform name. if (Tok.is(tok::code_completion)) { + cutOffParsing(); Actions.CodeCompleteAvailabilityPlatformName(); - cutOffParsing(); return None; } if (Tok.isNot(tok::identifier)) {