]> granicus.if.org Git - clang/commitdiff
Create two helpers for running the typo-correction tree transform.
authorKaelyn Takata <rikka@google.com>
Tue, 11 Nov 2014 23:26:56 +0000 (23:26 +0000)
committerKaelyn Takata <rikka@google.com>
Tue, 11 Nov 2014 23:26:56 +0000 (23:26 +0000)
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
lib/Sema/SemaExprCXX.cpp

index 4ad7463767d6bd2f7eb89f77df810011130f4794..f75c86983cbc9e8b4f713ce4dee554f5136c8232 100644 (file)
@@ -2718,6 +2718,18 @@ public:
                                bool EnteringContext = false,
                                const ObjCObjectPointerType *OPT = nullptr);
 
+  ExprResult
+  CorrectDelayedTyposInExpr(Expr *E,
+                            llvm::function_ref<ExprResult(Expr *)> Filter =
+                                [](Expr *E) -> ExprResult { return E; });
+
+  ExprResult
+  CorrectDelayedTyposInExpr(ExprResult ER,
+                            llvm::function_ref<ExprResult(Expr *)> 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);
index 9e05e82e9c9a06c0a75ad92bd6f6122afb327532..b035f8ff49cc045106f48e76744f6c716a59cf50 100644 (file)
@@ -5919,6 +5919,7 @@ namespace {
 class TransformTypos : public TreeTransform<TransformTypos> {
   typedef TreeTransform<TransformTypos> BaseTransform;
 
+  llvm::function_ref<ExprResult(Expr *)> ExprFilter;
   llvm::SmallSetVector<TypoExpr *, 2> TypoExprs;
   llvm::SmallDenseMap<TypoExpr *, ExprResult, 2> TransformCache;
   llvm::SmallDenseMap<OverloadExpr *, Expr *, 4> OverloadResolution;
@@ -5987,7 +5988,8 @@ class TransformTypos : public TreeTransform<TransformTypos> {
   }
 
 public:
-  TransformTypos(Sema &SemaRef) : BaseTransform(SemaRef) {}
+  TransformTypos(Sema &SemaRef, llvm::function_ref<ExprResult(Expr *)> &&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<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
+  // 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);