---
include/clang/AST/Expr.h | 5 ++++-
include/clang/Sema/Sema.h | 3 ++-
include/clang/Sema/TypoCorrection.h | 8 ++++++++
lib/Sema/SemaExprCXX.cpp | 24 ++++++++++++++++--------
lib/Sema/SemaLookup.cpp | 13 +++++++++----
5 files changed, 39 insertions(+), 14 deletions(-)
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 23d0a31..9af222d 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -4833,13 +4833,15 @@ public:
class TypoCorrectionConsumer;
class TypoDiagnosticGenerator;
+class TypoRecoveryCallback;
/// TypoExpr - Internal placeholder for expressions where typo correction
/// still needs to be performed and/or an error diagnostic emitted.
class TypoExpr : public Expr {
public:
TypoExpr(std::unique_ptr<TypoCorrectionConsumer> TCC,
- std::unique_ptr<TypoDiagnosticGenerator> TDG);
+ std::unique_ptr<TypoDiagnosticGenerator> TDG,
+ std::unique_ptr<TypoRecoveryCallback> TRC);
child_range children() { return child_range(); }
SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
@@ -4849,6 +4851,7 @@ public:
std::unique_ptr<TypoCorrectionConsumer> Consumer;
std::unique_ptr<TypoDiagnosticGenerator> DiagHandler;
+ std::unique_ptr<TypoRecoveryCallback> RecoveryHandler;
};
} // end namespace clang
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 2f5589d..1b11460 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -2667,7 +2667,8 @@ public:
const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind,
Scope *S, CXXScopeSpec *SS,
std::unique_ptr<CorrectionCandidateCallback> CCC,
- std::unique_ptr<TypoDiagnosticGenerator> TDG, CorrectTypoKind Mode,
+ std::unique_ptr<TypoDiagnosticGenerator> TDG,
+ std::unique_ptr<TypoRecoveryCallback> TRC, CorrectTypoKind Mode,
DeclContext *MemberContext = nullptr, bool EnteringContext = false,
const ObjCObjectPointerType *OPT = nullptr);
diff --git a/include/clang/Sema/TypoCorrection.h b/include/clang/Sema/TypoCorrection.h
index 135b187..ed5ce65 100644
--- a/include/clang/Sema/TypoCorrection.h
+++ b/include/clang/Sema/TypoCorrection.h
@@ -17,6 +17,7 @@
#include "clang/AST/DeclCXX.h"
#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/Ownership.h"
#include "llvm/ADT/SmallVector.h"
namespace clang {
@@ -360,6 +361,13 @@ class TypoDiagnosticGenerator {
virtual void operator()(TypoCorrection &TC) = 0;
virtual ~TypoDiagnosticGenerator() = default;
};
+
+class TypoRecoveryCallback {
+public:
+ virtual ExprResult operator()(Sema &SemaRef, TypoExpr *TE, TypoCorrection &TC,
+ Expr *Parent) = 0;
+ virtual ~TypoRecoveryCallback() = default;
+};
}
#endif
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 9dc0e01..c05fc87 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -6001,16 +6001,24 @@ public:
return TransformCache[E];
}
+ Expr *Parent =
+ ExprStack.size() > 1 ? ExprStack[ExprStack.size() - 2] : nullptr;
+
// For the first TypoExpr and an uncached TypoExpr, find the next likely
// typo correction and return it.
- while (TypoCorrection TC = E->Consumer->getNextCorrection()) {
- LookupResult R(SemaRef,
- E->Consumer->getLookupResult().getLookupNameInfo(),
- E->Consumer->getLookupResult().getLookupKind());
- if (!TC.isKeyword())
- R.addDecl(TC.getCorrectionDecl());
- return TransformCache[E] =
- SemaRef.BuildDeclarationNameExpr(CXXScopeSpec(), R, false);
+ while (TypoCorrection &TC = E->Consumer->getNextCorrection()) {
+ if (!E->RecoveryHandler) {
+ LookupResult R(SemaRef,
+ E->Consumer->getLookupResult().getLookupNameInfo(),
+ E->Consumer->getLookupResult().getLookupKind());
+ if (!TC.isKeyword())
+ R.addDecl(TC.getCorrectionDecl());
+ return TransformCache[E] =
+ SemaRef.BuildDeclarationNameExpr(CXXScopeSpec(), R, false);
+ }
+ ExprResult NE = (*E->RecoveryHandler)(SemaRef, E, TC, Parent);
+ if (!NE.isInvalid())
+ return TransformCache[E] = NE;
}
return TransformCache[E] = ExprError();
}
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index 5be0e1b..94ede79 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -4352,7 +4352,8 @@ TypoExpr *Sema::CorrectTypoDelayed(
const DeclarationNameInfo &TypoName, Sema::LookupNameKind LookupKind,
Scope *S, CXXScopeSpec *SS,
std::unique_ptr<CorrectionCandidateCallback> CCC,
- std::unique_ptr<TypoDiagnosticGenerator> TDG, CorrectTypoKind Mode,
+ std::unique_ptr<TypoDiagnosticGenerator> TDG,
+ std::unique_ptr<TypoRecoveryCallback> TRC, CorrectTypoKind Mode,
DeclContext *MemberContext, bool EnteringContext,
const ObjCObjectPointerType *OPT) {
assert(CCC && "CorrectTypoDelayed requires a CorrectionCandidateCallback");
@@ -4376,7 +4377,8 @@ TypoExpr *Sema::CorrectTypoDelayed(
return nullptr;
ExprEvalContexts.back().NumTypos++;
- return new (Context) TypoExpr(std::move(Consumer), std::move(TDG));
+ return new (Context)
+ TypoExpr(std::move(Consumer), std::move(TDG), std::move(TRC));
}
void TypoCorrection::addCorrectionDecl(NamedDecl *CDecl) {
@@ -4582,17 +4584,20 @@ void Sema::diagnoseTypo(const TypoCorrection &Correction,
}
TypoExpr::TypoExpr(std::unique_ptr<TypoCorrectionConsumer> TCC,
- std::unique_ptr<TypoDiagnosticGenerator> TDG)
+ std::unique_ptr<TypoDiagnosticGenerator> TDG,
+ std::unique_ptr<TypoRecoveryCallback> TRC)
: Expr(TypoExprClass, TCC->getContext().DependentTy, VK_LValue, OK_Ordinary,
/*isTypeDependent*/ true,
/*isValueDependent*/ true,
/*isInstantiationDependent*/ true,
/*containsUnexpandedParameterPack*/ false),
- Consumer(std::move(TCC)), DiagHandler(std::move(TDG)) {
+ Consumer(std::move(TCC)), DiagHandler(std::move(TDG)),
+ RecoveryHandler(std::move(TRC)) {
assert(Consumer && "TypoExpr requires a valid TypoCorrectionConsumer");
}
void TypoExpr::clear() {
Consumer.reset(nullptr);
DiagHandler.reset(nullptr);
+ RecoveryHandler.reset(nullptr);
}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits