diff options
Diffstat (limited to 'clang/lib/Parse/ParseExpr.cpp')
-rw-r--r-- | clang/lib/Parse/ParseExpr.cpp | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index b4ba0bc8d8c..3d57ba9cbe0 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -277,6 +277,7 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { // 'logical-OR-expression' as we might expect. TernaryMiddle = ParseExpression(); if (TernaryMiddle.isInvalid()) { + Actions.CorrectDelayedTyposInExpr(LHS); LHS = ExprError(); TernaryMiddle = nullptr; } @@ -345,9 +346,11 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { else RHS = ParseCastExpression(false); - if (RHS.isInvalid()) + if (RHS.isInvalid()) { + Actions.CorrectDelayedTyposInExpr(LHS); LHS = ExprError(); - + } + // Remember the precedence of this operator and get the precedence of the // operator immediately to the right of the RHS. prec::Level ThisPrec = NextTokPrec; @@ -376,8 +379,10 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { static_cast<prec::Level>(ThisPrec + !isRightAssoc)); RHSIsInitList = false; - if (RHS.isInvalid()) + if (RHS.isInvalid()) { + Actions.CorrectDelayedTyposInExpr(LHS); LHS = ExprError(); + } NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator, getLangOpts().CPlusPlus11); @@ -413,7 +418,9 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { LHS = Actions.ActOnConditionalOp(OpToken.getLocation(), ColonLoc, LHS.get(), TernaryMiddle.get(), RHS.get()); - } + } else + // Ensure potential typos in the RHS aren't left undiagnosed. + Actions.CorrectDelayedTyposInExpr(RHS); } } @@ -441,7 +448,7 @@ class CastExpressionIdValidator : public CorrectionCandidateCallback { public: CastExpressionIdValidator(bool AllowTypes, bool AllowNonTypes) : AllowNonTypes(AllowNonTypes) { - WantTypeSpecifiers = AllowTypes; + WantTypeSpecifiers = WantFunctionLikeCasts = AllowTypes; } bool ValidateCandidate(const TypoCorrection &candidate) override { @@ -899,13 +906,20 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, UnqualifiedId Name; CXXScopeSpec ScopeSpec; SourceLocation TemplateKWLoc; + Token Replacement; auto Validator = llvm::make_unique<CastExpressionIdValidator>( isTypeCast != NotTypeCast, isTypeCast != IsTypeCast); Validator->IsAddressOfOperand = isAddressOfOperand; Name.setIdentifier(&II, ILoc); - Res = Actions.ActOnIdExpression(getCurScope(), ScopeSpec, TemplateKWLoc, - Name, Tok.is(tok::l_paren), - isAddressOfOperand, std::move(Validator)); + Res = Actions.ActOnIdExpression( + getCurScope(), ScopeSpec, TemplateKWLoc, Name, Tok.is(tok::l_paren), + isAddressOfOperand, std::move(Validator), + /*IsInlineAsmIdentifier=*/false, &Replacement); + if (!Res.isInvalid() && !Res.get()) { + UnconsumeToken(Replacement); + return ParseCastExpression(isUnaryExpression, isAddressOfOperand, + NotCastExpr, isTypeCast); + } break; } case tok::char_constant: // constant: character-constant |