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);
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;
}
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,
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()) ||
};
}
+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,
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);