Author: Haojian Wu Date: 2020-06-18T08:20:05+02:00 New Revision: 910689f0aa7207cd902716e0e32d243346a670e8
URL: https://github.com/llvm/llvm-project/commit/910689f0aa7207cd902716e0e32d243346a670e8 DIFF: https://github.com/llvm/llvm-project/commit/910689f0aa7207cd902716e0e32d243346a670e8.diff LOG: [AST] Move the "fallback to recovery expr" mechanism to CorrectDelayedTyposInExpr, NFC Summary: Also delete two overloads, which don't seem necessary. Reviewers: sammccall Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D82047 Added: Modified: clang/include/clang/Sema/Sema.h clang/lib/Parse/ParseDeclCXX.cpp clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaExpr.cpp clang/lib/Sema/SemaExprCXX.cpp clang/lib/Sema/SemaStmt.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 754339c0181b..8f619b80a3e7 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -3847,32 +3847,28 @@ class Sema final { /// \param InitDecl A VarDecl to avoid because the Expr being corrected is its /// initializer. /// + /// \param RecoverUncorrectedTypos If true, when typo correction fails, it + /// will rebuild the given Expr with all TypoExprs degraded to RecoveryExprs. + /// /// \param Filter A function applied to a newly rebuilt Expr to determine if /// it is an acceptable/usable result from a single combination of typo /// corrections. As long as the filter returns ExprError, diff erent /// combinations of corrections will be tried until all are exhausted. - ExprResult - CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl = nullptr, - llvm::function_ref<ExprResult(Expr *)> Filter = - [](Expr *E) -> ExprResult { return E; }); - - ExprResult - CorrectDelayedTyposInExpr(Expr *E, - llvm::function_ref<ExprResult(Expr *)> Filter) { - return CorrectDelayedTyposInExpr(E, nullptr, Filter); - } - - ExprResult - CorrectDelayedTyposInExpr(ExprResult ER, VarDecl *InitDecl = nullptr, - llvm::function_ref<ExprResult(Expr *)> Filter = - [](Expr *E) -> ExprResult { return E; }) { - return ER.isInvalid() ? ER : CorrectDelayedTyposInExpr(ER.get(), Filter); - } - - ExprResult - CorrectDelayedTyposInExpr(ExprResult ER, - llvm::function_ref<ExprResult(Expr *)> Filter) { - return CorrectDelayedTyposInExpr(ER, nullptr, Filter); + ExprResult CorrectDelayedTyposInExpr( + Expr *E, VarDecl *InitDecl = nullptr, + bool RecoverUncorrectedTypos = false, + llvm::function_ref<ExprResult(Expr *)> Filter = + [](Expr *E) -> ExprResult { return E; }); + + ExprResult CorrectDelayedTyposInExpr( + ExprResult ER, VarDecl *InitDecl = nullptr, + bool RecoverUncorrectedTypos = false, + llvm::function_ref<ExprResult(Expr *)> Filter = + [](Expr *E) -> ExprResult { return E; }) { + return ER.isInvalid() + ? ER + : CorrectDelayedTyposInExpr(ER.get(), InitDecl, + RecoverUncorrectedTypos, Filter); } void diagnoseTypo(const TypoCorrection &Correction, diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 8753c9292875..5c41fe7921a6 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -984,10 +984,10 @@ SourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) { EnterExpressionEvaluationContext Unevaluated( Actions, Sema::ExpressionEvaluationContext::Unevaluated, nullptr, Sema::ExpressionEvaluationContextRecord::EK_Decltype); - Result = - Actions.CorrectDelayedTyposInExpr(ParseExpression(), [](Expr *E) { - return E->hasPlaceholderType() ? ExprError() : E; - }); + Result = Actions.CorrectDelayedTyposInExpr( + ParseExpression(), /*InitDecl=*/nullptr, + /*RecoverUncorrectedTypos=*/false, + [](Expr *E) { return E->hasPlaceholderType() ? ExprError() : E; }); if (Result.isInvalid()) { DS.SetTypeSpecError(); if (SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch)) { diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 80469e3bedbe..5eebfb7dc1f0 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -12017,7 +12017,8 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) { // Try to correct any TypoExprs in the initialization arguments. for (size_t Idx = 0; Idx < Args.size(); ++Idx) { ExprResult Res = CorrectDelayedTyposInExpr( - Args[Idx], VDecl, [this, Entity, Kind](Expr *E) { + Args[Idx], VDecl, /*RecoverUncorrectedTypos=*/false, + [this, Entity, Kind](Expr *E) { InitializationSequence Init(*this, Entity, Kind, MultiExprArg(E)); return Init.Failed() ? ExprError() : E; }); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index ffc72140dcf4..78a2fdcfa9d6 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -13650,13 +13650,15 @@ CorrectDelayedTyposInBinOp(Sema &S, BinaryOperatorKind Opc, Expr *LHSExpr, // doesn't handle dependent types properly, so make sure any TypoExprs have // been dealt with before checking the operands. LHS = S.CorrectDelayedTyposInExpr(LHS); - RHS = S.CorrectDelayedTyposInExpr(RHS, [Opc, LHS](Expr *E) { - if (Opc != BO_Assign) - return ExprResult(E); - // Avoid correcting the RHS to the same Expr as the LHS. - Decl *D = getDeclFromExpr(E); - return (D && D == getDeclFromExpr(LHS.get())) ? ExprError() : E; - }); + RHS = S.CorrectDelayedTyposInExpr( + RHS, /*InitDecl=*/nullptr, /*RecoverUncorrectedTypos=*/false, + [Opc, LHS](Expr *E) { + if (Opc != BO_Assign) + return ExprResult(E); + // Avoid correcting the RHS to the same Expr as the LHS. + Decl *D = getDeclFromExpr(E); + return (D && D == getDeclFromExpr(LHS.get())) ? ExprError() : E; + }); } return std::make_pair(LHS, RHS); } diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index b3d04e40b5e9..0a0bb3952cd8 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -8253,6 +8253,7 @@ class TransformTypos : public TreeTransform<TransformTypos> { ExprResult Sema::CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl, + bool RecoverUncorrectedTypos, llvm::function_ref<ExprResult(Expr *)> Filter) { // If the current evaluation context indicates there are uncorrected typos // and the current expression isn't guaranteed to not have typos, try to @@ -8265,6 +8266,16 @@ Sema::CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl, TyposResolved -= DelayedTypos.size(); if (Result.isInvalid() || Result.get() != E) { ExprEvalContexts.back().NumTypos -= TyposResolved; + if (Result.isInvalid() && RecoverUncorrectedTypos) { + struct TyposReplace : TreeTransform<TyposReplace> { + TyposReplace(Sema &SemaRef) : TreeTransform(SemaRef) {} + ExprResult TransformTypoExpr(clang::TypoExpr *E) { + return this->SemaRef.CreateRecoveryExpr(E->getBeginLoc(), + E->getEndLoc(), {}); + } + } TT(*this); + return TT.TransformExpr(E); + } return Result; } assert(TyposResolved == 0 && "Corrected typo but got same Expr back?"); @@ -8303,20 +8314,10 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC, DiagnoseUnusedExprResult(FullExpr.get()); } - FullExpr = CorrectDelayedTyposInExpr(FullExpr.get()); - if (FullExpr.isInvalid()) { - // Typo-correction fails, we rebuild the broken AST with the typos degraded - // to RecoveryExpr. - struct TyposReplace : TreeTransform<TyposReplace> { - TyposReplace(Sema &SemaRef) : TreeTransform(SemaRef) {} - ExprResult TransformTypoExpr(TypoExpr *E) { - return this->SemaRef.CreateRecoveryExpr(E->getBeginLoc(), - E->getEndLoc(), {}); - } - } TT(*this); - - return TT.TransformExpr(FE); - } + FullExpr = CorrectDelayedTyposInExpr(FullExpr.get(), /*InitDecl=*/nullptr, + /*RecoverUncorrectedTypos=*/true); + if (FullExpr.isInvalid()) + return ExprError(); CheckCompletedExpr(FullExpr.get(), CC, IsConstexpr); diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 9d5672cff00a..d71f2cfe89d0 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -477,7 +477,9 @@ Sema::ActOnCaseExpr(SourceLocation CaseLoc, ExprResult Val) { return ER; }; - ExprResult Converted = CorrectDelayedTyposInExpr(Val, CheckAndFinish); + ExprResult Converted = CorrectDelayedTyposInExpr( + Val, /*InitDecl=*/nullptr, /*RecoverUncorrectedTypos=*/false, + CheckAndFinish); if (Converted.get() == Val.get()) Converted = CheckAndFinish(Val.get()); return Converted; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits