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.
---
include/clang/Sema/Sema.h | 13 +++++++++++++
lib/Sema/SemaExprCXX.cpp | 40 ++++++++++++++++++++++++++--------------
2 files changed, 39 insertions(+), 14 deletions(-)
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 92e1019..f5a307b 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -2710,6 +2710,19 @@ public:
DeclContext *MemberContext = nullptr, 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(),
+ std::move(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 a434fa1..dc31588 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -5918,6 +5918,7 @@ namespace {
class TransformTypos : public TreeTransform<TransformTypos> {
typedef TreeTransform<TransformTypos> BaseTransform;
+ llvm::function_ref<ExprResult(Expr *)> ExprFilter;
llvm::SmallPtrSet<TypoExpr *, 2> TypoExprs;
llvm::SmallDenseMap<TypoExpr *, ExprResult, 2> TransformCache;
llvm::SmallDenseMap<OverloadExpr *, Expr *, 4> OverloadResolution;
@@ -5940,8 +5941,9 @@ class TransformTypos : public TreeTransform<TransformTypos> {
}
public:
- TransformTypos(Sema &SemaRef)
- : BaseTransform(SemaRef), FirstTypoExpr(nullptr) {}
+ TransformTypos(Sema &SemaRef, llvm::function_ref<ExprResult(Expr *)> &&Filter)
+ : BaseTransform(SemaRef), ExprFilter(std::move(Filter)),
+ FirstTypoExpr(nullptr) {}
ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,
MultiExprArg Args,
@@ -5966,6 +5968,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.
if (!(error || res.isInvalid()) || TypoExprs.empty())
@@ -6050,6 +6055,22 @@ public:
};
}
+ExprResult Sema::CorrectDelayedTyposInExpr(
+ Expr *E, llvm::function_ref<ExprResult(Expr *)> &&Filter) {
+ 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,
@@ -6096,18 +6117,9 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC,
return ExprError();
}
- 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);
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits