Mercurial > hg > CbC > CbC_llvm
diff clang/lib/Parse/ParseExpr.cpp @ 173:0572611fdcc8 llvm10 llvm12
reorgnization done
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 25 May 2020 11:55:54 +0900 |
parents | 1d019706d866 |
children | f935e5e0dbe7 2e18cbf3894f |
line wrap: on
line diff
--- a/clang/lib/Parse/ParseExpr.cpp Mon May 25 11:50:15 2020 +0900 +++ b/clang/lib/Parse/ParseExpr.cpp Mon May 25 11:55:54 2020 +0900 @@ -625,13 +625,31 @@ SourceRange(Actions.getExprRange(LHS.get()).getBegin(), Actions.getExprRange(RHS.get()).getEnd())); - LHS = Actions.ActOnBinOp(getCurScope(), OpToken.getLocation(), - OpToken.getKind(), LHS.get(), RHS.get()); - + ExprResult BinOp = + Actions.ActOnBinOp(getCurScope(), OpToken.getLocation(), + OpToken.getKind(), LHS.get(), RHS.get()); + if (BinOp.isInvalid()) + BinOp = Actions.CreateRecoveryExpr(LHS.get()->getBeginLoc(), + RHS.get()->getEndLoc(), + {LHS.get(), RHS.get()}); + + LHS = BinOp; } else { - LHS = Actions.ActOnConditionalOp(OpToken.getLocation(), ColonLoc, - LHS.get(), TernaryMiddle.get(), - RHS.get()); + ExprResult CondOp = Actions.ActOnConditionalOp( + OpToken.getLocation(), ColonLoc, LHS.get(), TernaryMiddle.get(), + RHS.get()); + if (CondOp.isInvalid()) { + std::vector<clang::Expr *> Args; + // TernaryMiddle can be null for the GNU conditional expr extension. + if (TernaryMiddle.get()) + Args = {LHS.get(), TernaryMiddle.get(), RHS.get()}; + else + Args = {LHS.get(), RHS.get()}; + CondOp = Actions.CreateRecoveryExpr(LHS.get()->getBeginLoc(), + RHS.get()->getEndLoc(), Args); + } + + LHS = CondOp; } // In this case, ActOnBinOp or ActOnConditionalOp performed the // CorrectDelayedTyposInExpr check. @@ -1006,7 +1024,7 @@ assert(Tok.isNot(tok::kw_decltype) && Tok.isNot(tok::kw___super)); return ParseCastExpression(ParseKind, isAddressOfOperand, isTypeCast, isVectorLiteral, NotPrimaryExpression); - + case tok::identifier: { // primary-expression: identifier // unqualified-id: identifier // constant: enumeration-constant @@ -1305,9 +1323,14 @@ UnconsumeToken(SavedTok); return ExprError(); } - if (!Res.isInvalid()) + if (!Res.isInvalid()) { + Expr *Arg = Res.get(); Res = Actions.ActOnUnaryOp(getCurScope(), SavedTok.getLocation(), - SavedKind, Res.get()); + SavedKind, Arg); + if (Res.isInvalid()) + Res = Actions.CreateRecoveryExpr(SavedTok.getLocation(), + Arg->getEndLoc(), Arg); + } return Res; } case tok::amp: { // unary-expression: '&' cast-expression @@ -1317,8 +1340,13 @@ SourceLocation SavedLoc = ConsumeToken(); PreferredType.enterUnary(Actions, Tok.getLocation(), tok::amp, SavedLoc); Res = ParseCastExpression(AnyCastExpr, true); - if (!Res.isInvalid()) - Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get()); + if (!Res.isInvalid()) { + Expr *Arg = Res.get(); + Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Arg); + if (Res.isInvalid()) + Res = Actions.CreateRecoveryExpr(Tok.getLocation(), Arg->getEndLoc(), + Arg); + } return Res; } @@ -1334,8 +1362,12 @@ SourceLocation SavedLoc = ConsumeToken(); PreferredType.enterUnary(Actions, Tok.getLocation(), SavedKind, SavedLoc); Res = ParseCastExpression(AnyCastExpr); - if (!Res.isInvalid()) - Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get()); + if (!Res.isInvalid()) { + Expr *Arg = Res.get(); + Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Arg); + if (Res.isInvalid()) + Res = Actions.CreateRecoveryExpr(SavedLoc, Arg->getEndLoc(), Arg); + } return Res; } @@ -1396,6 +1428,7 @@ case tok::kw_dynamic_cast: case tok::kw_reinterpret_cast: case tok::kw_static_cast: + case tok::kw_addrspace_cast: if (NotPrimaryExpression) *NotPrimaryExpression = true; Res = ParseCXXCasts(); @@ -1418,10 +1451,12 @@ case tok::kw_this: Res = ParseCXXThis(); break; - + case tok::kw___builtin_unique_stable_name: + Res = ParseUniqueStableNameExpression(); + break; case tok::annot_typename: if (isStartOfObjCClassMessageMissingOpenBracket()) { - ParsedType Type = getTypeAnnotation(Tok); + TypeResult Type = getTypeAnnotation(Tok); // Fake up a Declarator to use with ActOnTypeName. DeclSpec DS(AttrFactory); @@ -1458,6 +1493,7 @@ case tok::kw_long: case tok::kw___int64: case tok::kw___int128: + case tok::kw__ExtInt: case tok::kw_signed: case tok::kw_unsigned: case tok::kw_half: @@ -1529,7 +1565,8 @@ // type, translate it into a type and continue parsing as a // cast expression. CXXScopeSpec SS; - ParseOptionalCXXScopeSpecifier(SS, nullptr, + ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, + /*ObjectHadErrors=*/false, /*EnteringContext=*/false); AnnotateTemplateIdTokenAsType(SS); return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr, @@ -1940,12 +1977,18 @@ PT.consumeClose(); LHS = ExprError(); } else { - assert((ArgExprs.size() == 0 || - ArgExprs.size()-1 == CommaLocs.size())&& - "Unexpected number of commas!"); - LHS = Actions.ActOnCallExpr(getCurScope(), LHS.get(), Loc, - ArgExprs, Tok.getLocation(), + assert( + (ArgExprs.size() == 0 || ArgExprs.size() - 1 == CommaLocs.size()) && + "Unexpected number of commas!"); + Expr *Fn = LHS.get(); + SourceLocation RParLoc = Tok.getLocation(); + LHS = Actions.ActOnCallExpr(getCurScope(), Fn, Loc, ArgExprs, RParLoc, ExecConfig); + if (LHS.isInvalid()) { + ArgExprs.insert(ArgExprs.begin(), Fn); + LHS = + Actions.CreateRecoveryExpr(Fn->getBeginLoc(), RParLoc, ArgExprs); + } PT.consumeClose(); } @@ -1977,15 +2020,22 @@ return ParsePostfixExpressionSuffix(Base); } - LHS = Actions.ActOnStartCXXMemberReference(getCurScope(), Base, - OpLoc, OpKind, ObjectType, + LHS = Actions.ActOnStartCXXMemberReference(getCurScope(), Base, OpLoc, + OpKind, ObjectType, MayBePseudoDestructor); - if (LHS.isInvalid()) + if (LHS.isInvalid()) { + // Clang will try to perform expression based completion as a + // fallback, which is confusing in case of member references. So we + // stop here without any completions. + if (Tok.is(tok::code_completion)) { + cutOffParsing(); + return ExprError(); + } break; - - ParseOptionalCXXScopeSpecifier(SS, ObjectType, - /*EnteringContext=*/false, - &MayBePseudoDestructor); + } + ParseOptionalCXXScopeSpecifier( + SS, ObjectType, LHS.get() && LHS.get()->containsErrors(), + /*EnteringContext=*/false, &MayBePseudoDestructor); if (SS.isNotEmpty()) ObjectType = nullptr; } @@ -2045,14 +2095,13 @@ IdentifierInfo *Id = Tok.getIdentifierInfo(); SourceLocation Loc = ConsumeToken(); Name.setIdentifier(Id, Loc); - } else if (ParseUnqualifiedId(SS, - /*EnteringContext=*/false, - /*AllowDestructorName=*/true, - /*AllowConstructorName=*/ - getLangOpts().MicrosoftExt && - SS.isNotEmpty(), - /*AllowDeductionGuide=*/false, - ObjectType, &TemplateKWLoc, Name)) { + } else if (ParseUnqualifiedId( + SS, ObjectType, LHS.get() && LHS.get()->containsErrors(), + /*EnteringContext=*/false, + /*AllowDestructorName=*/true, + /*AllowConstructorName=*/ + getLangOpts().MicrosoftExt && SS.isNotEmpty(), + /*AllowDeductionGuide=*/false, &TemplateKWLoc, Name)) { (void)Actions.CorrectDelayedTyposInExpr(LHS); LHS = ExprError(); } @@ -2062,15 +2111,25 @@ OpKind, SS, TemplateKWLoc, Name, CurParsedObjCImpl ? CurParsedObjCImpl->Dcl : nullptr); - if (!LHS.isInvalid() && Tok.is(tok::less)) - checkPotentialAngleBracket(LHS); + if (!LHS.isInvalid()) { + if (Tok.is(tok::less)) + checkPotentialAngleBracket(LHS); + } else if (OrigLHS && Name.isValid()) { + // Preserve the LHS if the RHS is an invalid member. + LHS = Actions.CreateRecoveryExpr(OrigLHS->getBeginLoc(), + Name.getEndLoc(), {OrigLHS}); + } break; } case tok::plusplus: // postfix-expression: postfix-expression '++' case tok::minusminus: // postfix-expression: postfix-expression '--' if (!LHS.isInvalid()) { + Expr *Arg = LHS.get(); LHS = Actions.ActOnPostfixUnaryOp(getCurScope(), Tok.getLocation(), - Tok.getKind(), LHS.get()); + Tok.getKind(), Arg); + if (LHS.isInvalid()) + LHS = Actions.CreateRecoveryExpr(Arg->getBeginLoc(), + Tok.getLocation(), Arg); } ConsumeToken(); break; @@ -2180,6 +2239,43 @@ } +ExprResult Parser::ParseUniqueStableNameExpression() { + assert(Tok.is(tok::kw___builtin_unique_stable_name) && + "Not __bulitin_unique_stable_name"); + + SourceLocation OpLoc = ConsumeToken(); + BalancedDelimiterTracker T(*this, tok::l_paren); + + // typeid expressions are always parenthesized. + if (T.expectAndConsume(diag::err_expected_lparen_after, + "__builtin_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()); + } + + 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()); +} + /// Parse a sizeof or alignof expression. /// /// \verbatim @@ -2561,6 +2657,33 @@ return ParsePostfixExpressionSuffix(Res.get()); } +bool Parser::tryParseOpenMPArrayShapingCastPart() { + assert(Tok.is(tok::l_square) && "Expected open bracket"); + bool ErrorFound = true; + TentativeParsingAction TPA(*this); + do { + if (Tok.isNot(tok::l_square)) + break; + // Consume '[' + ConsumeBracket(); + // Skip inner expression. + while (!SkipUntil(tok::r_square, tok::annot_pragma_openmp_end, + StopAtSemi | StopBeforeMatch)) + ; + if (Tok.isNot(tok::r_square)) + break; + // Consume ']' + ConsumeBracket(); + // Found ')' - done. + if (Tok.is(tok::r_paren)) { + ErrorFound = false; + break; + } + } while (Tok.isNot(tok::annot_pragma_openmp_end)); + TPA.Revert(); + return !ErrorFound; +} + /// ParseParenExpression - This parses the unit that starts with a '(' token, /// based on what is allowed by ExprType. The actual thing parsed is returned /// in ExprType. If stopIfCastExpr is true, it will only return the parsed type, @@ -2585,6 +2708,8 @@ /// '(' '...' fold-operator cast-expression ')' /// '(' cast-expression fold-operator '...' /// fold-operator cast-expression ')' +/// [OPENMP] Array shaping operation +/// '(' '[' expression ']' { '[' expression ']' } cast-expression /// \endverbatim ExprResult Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, @@ -2655,7 +2780,8 @@ // If the substmt parsed correctly, build the AST node. if (!Stmt.isInvalid()) { - Result = Actions.ActOnStmtExpr(OpenLoc, Stmt.get(), Tok.getLocation()); + Result = Actions.ActOnStmtExpr(getCurScope(), OpenLoc, Stmt.get(), + Tok.getLocation()); } else { Actions.ActOnStmtExprError(); } @@ -2690,7 +2816,7 @@ PreferredType.enterTypeCast(Tok.getLocation(), Ty.get().get()); ExprResult SubExpr = ParseCastExpression(AnyCastExpr); - + if (Ty.isInvalid() || SubExpr.isInvalid()) return ExprError(); @@ -2860,6 +2986,38 @@ Result = Actions.ActOnParenListExpr(OpenLoc, Tok.getLocation(), ArgExprs); } + } else if (getLangOpts().OpenMP >= 50 && OpenMPDirectiveParsing && + ExprType == CastExpr && Tok.is(tok::l_square) && + tryParseOpenMPArrayShapingCastPart()) { + bool ErrorFound = false; + SmallVector<Expr *, 4> OMPDimensions; + SmallVector<SourceRange, 4> OMPBracketsRanges; + do { + BalancedDelimiterTracker TS(*this, tok::l_square); + TS.consumeOpen(); + ExprResult NumElements = + Actions.CorrectDelayedTyposInExpr(ParseExpression()); + if (!NumElements.isUsable()) { + ErrorFound = true; + while (!SkipUntil(tok::r_square, tok::r_paren, + StopAtSemi | StopBeforeMatch)) + ; + } + TS.consumeClose(); + OMPDimensions.push_back(NumElements.get()); + OMPBracketsRanges.push_back(TS.getRange()); + } while (Tok.isNot(tok::r_paren)); + // Match the ')'. + T.consumeClose(); + RParenLoc = T.getCloseLocation(); + Result = Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()); + if (ErrorFound) { + Result = ExprError(); + } else if (!Result.isInvalid()) { + Result = Actions.ActOnOMPArrayShapingExpr( + Result.get(), OpenLoc, RParenLoc, OMPDimensions, OMPBracketsRanges); + } + return Result; } else { InMessageExpressionRAIIObject InMessage(*this, false);