From 1fb78b742be35cea97512b7e5e1233e57b8d1434 Mon Sep 17 00:00:00 2001 From: Kaelyn Takata Date: Tue, 11 Nov 2014 23:26:56 +0000 Subject: [PATCH] Create two helpers for running the typo-correction tree transform. One takes an Expr* and the other is a simple wrapper that takes an ExprResult instead, and handles checking whether the ExprResult is invalid. Additionally, allow an optional callback that is run on the full result of the tree transform, for filtering potential corrections based on the characteristics of the resulting expression once all of the typos have been replaced. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@221735 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Sema/Sema.h | 12 +++++++++++ lib/Sema/SemaExprCXX.cpp | 44 +++++++++++++++++++++++++-------------- 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 4ad7463767..f75c86983c 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -2718,6 +2718,18 @@ public: bool EnteringContext = false, const ObjCObjectPointerType *OPT = nullptr); + ExprResult + CorrectDelayedTyposInExpr(Expr *E, + llvm::function_ref Filter = + [](Expr *E) -> ExprResult { return E; }); + + ExprResult + CorrectDelayedTyposInExpr(ExprResult ER, + llvm::function_ref Filter = + [](Expr *E) -> ExprResult { return E; }) { + return ER.isInvalid() ? ER : CorrectDelayedTyposInExpr(ER.get(), Filter); + } + void diagnoseTypo(const TypoCorrection &Correction, const PartialDiagnostic &TypoDiag, bool ErrorRecovery = true); diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 9e05e82e9c..b035f8ff49 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -5919,6 +5919,7 @@ namespace { class TransformTypos : public TreeTransform { typedef TreeTransform BaseTransform; + llvm::function_ref ExprFilter; llvm::SmallSetVector TypoExprs; llvm::SmallDenseMap TransformCache; llvm::SmallDenseMap OverloadResolution; @@ -5987,7 +5988,8 @@ class TransformTypos : public TreeTransform { } public: - TransformTypos(Sema &SemaRef) : BaseTransform(SemaRef) {} + TransformTypos(Sema &SemaRef, llvm::function_ref &&Filter) + : BaseTransform(SemaRef), ExprFilter(std::move(Filter)) {} ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc, MultiExprArg Args, @@ -6012,6 +6014,9 @@ public: res = TransformExpr(E); error = Trap.hasErrorOccurred(); + if (!(error || res.isInvalid())) + res = ExprFilter(res.get()); + // Exit if either the transform was valid or if there were no TypoExprs // to transform that still have any untried correction candidates.. if (!(error || res.isInvalid()) || @@ -6060,6 +6065,25 @@ public: }; } +ExprResult Sema::CorrectDelayedTyposInExpr( + Expr *E, llvm::function_ref Filter) { + // If the current evaluation context indicates there are uncorrected typos + // and the current expression isn't guaranteed to not have typos, try to + // resolve any TypoExpr nodes that might be in the expression. + if (!ExprEvalContexts.empty() && ExprEvalContexts.back().NumTypos && + (E->isTypeDependent() || E->isValueDependent() || + E->isInstantiationDependent())) { + auto TyposResolved = DelayedTypos.size(); + auto Result = TransformTypos(*this, std::move(Filter)).Transform(E); + TyposResolved -= DelayedTypos.size(); + if (TyposResolved) { + ExprEvalContexts.back().NumTypos -= TyposResolved; + return Result; + } + } + return E; +} + ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC, bool DiscardedValue, bool IsConstexpr, @@ -6106,21 +6130,9 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC, return ExprError(); } - // If the current evaluation context indicates there are uncorrected typos - // and the current expression isn't guaranteed to not have typos, try to - // resolve any TypoExpr nodes that might be in the expression. - if (ExprEvalContexts.back().NumTypos && - (FullExpr.get()->isTypeDependent() || - FullExpr.get()->isValueDependent() || - FullExpr.get()->isInstantiationDependent())) { - auto TyposResolved = DelayedTypos.size(); - FullExpr = TransformTypos(*this).Transform(FullExpr.get()); - TyposResolved -= DelayedTypos.size(); - if (TyposResolved) - ExprEvalContexts.back().NumTypos -= TyposResolved; - if (FullExpr.isInvalid()) - return ExprError(); - } + FullExpr = CorrectDelayedTyposInExpr(FullExpr.get()); + if (FullExpr.isInvalid()) + return ExprError(); CheckCompletedExpr(FullExpr.get(), CC, IsConstexpr); -- 2.40.0