]> granicus.if.org Git - clang/commitdiff
Add a callback for recovering using a typo correction.
authorKaelyn Takata <rikka@google.com>
Mon, 27 Oct 2014 18:07:42 +0000 (18:07 +0000)
committerKaelyn Takata <rikka@google.com>
Mon, 27 Oct 2014 18:07:42 +0000 (18:07 +0000)
Also keep track of the stack of Exprs visited during the tree transform
so the callback can be passed the parent of the TypoExpr.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@220697 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/Sema.h
include/clang/Sema/TypoCorrection.h
lib/Sema/SemaExprCXX.cpp
lib/Sema/SemaLookup.cpp

index 8664d23da76aa88c05e74e69283237ee874a7c08..ebcc4808b7c339b3fdbba1ce666eb30958e12673 100644 (file)
@@ -2592,6 +2592,8 @@ public:
                                                    bool VolatileThis);
 
   typedef std::function<void(const TypoCorrection &)> TypoDiagnosticGenerator;
+  typedef std::function<ExprResult(Sema &, TypoExpr *, TypoCorrection)>
+      TypoRecoveryCallback;
 
 private:
   bool CppLookupName(LookupResult &R, Scope *S);
@@ -2599,6 +2601,7 @@ private:
   struct TypoExprState {
     std::unique_ptr<TypoCorrectionConsumer> Consumer;
     TypoDiagnosticGenerator DiagHandler;
+    TypoRecoveryCallback RecoveryHandler;
   };
 
   /// \brief The set of unhandled TypoExprs and their associated state.
@@ -2606,7 +2609,8 @@ private:
 
   /// \brief Creates a new TypoExpr AST node.
   TypoExpr *createDelayedTypo(std::unique_ptr<TypoCorrectionConsumer> TCC,
-                              TypoDiagnosticGenerator TDG);
+                              TypoDiagnosticGenerator TDG,
+                              TypoRecoveryCallback TRC);
 
   // \brief The set of known/encountered (unique, canonicalized) NamespaceDecls.
   //
@@ -2718,7 +2722,7 @@ public:
                                CXXScopeSpec *SS,
                                std::unique_ptr<CorrectionCandidateCallback> CCC,
                                TypoDiagnosticGenerator TDG,
-                               CorrectTypoKind Mode,
+                               TypoRecoveryCallback TRC, CorrectTypoKind Mode,
                                DeclContext *MemberContext = nullptr,
                                bool EnteringContext = false,
                                const ObjCObjectPointerType *OPT = nullptr);
index e5c49124c61ddee9921636e1af0dacf3df2fd248..12f7f06d5c940090973f74f206583f6995dc7c88 100644 (file)
@@ -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 {
index 861fb068e7d2ddaf16db5d2f2348b662651b4c9c..1d9df2d4d453bd49d979c2b91021a44b78cdabe1 100644 (file)
@@ -5996,13 +5996,17 @@ public:
     // For the first TypoExpr and an uncached TypoExpr, find the next likely
     // typo correction and return it.
     while (TypoCorrection TC = State.Consumer->getNextCorrection()) {
-      LookupResult R(SemaRef,
-                     State.Consumer->getLookupResult().getLookupNameInfo(),
-                     State.Consumer->getLookupResult().getLookupKind());
-      if (!TC.isKeyword())
-        R.addDecl(TC.getCorrectionDecl());
-      ExprResult NE =
-          SemaRef.BuildDeclarationNameExpr(CXXScopeSpec(), R, false);
+      ExprResult NE;
+      if (State.RecoveryHandler) {
+        NE = State.RecoveryHandler(SemaRef, E, TC);
+      } else {
+        LookupResult R(SemaRef,
+                       State.Consumer->getLookupResult().getLookupNameInfo(),
+                       State.Consumer->getLookupResult().getLookupKind());
+        if (!TC.isKeyword())
+          R.addDecl(TC.getCorrectionDecl());
+        NE = SemaRef.BuildDeclarationNameExpr(CXXScopeSpec(), R, false);
+      }
       assert(!NE.isUnset() &&
              "Typo was transformed into a valid-but-null ExprResult");
       if (!NE.isInvalid())
index afb56fe99685dd453e5909908540b971119f27fc..eab819e15fc4c3f7d79e29ae23a4a49a83cd447f 100644 (file)
@@ -4332,6 +4332,9 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,
 /// \param TDG A TypoDiagnosticGenerator functor that will be used to print
 /// diagnostics when the actual typo correction is attempted.
 ///
+/// \param TRC A TypoRecoveryCallback functor that will be used to build an
+/// Expr from a typo correction candidate.
+///
 /// \param MemberContext if non-NULL, the context in which to look for
 /// a member access expression.
 ///
@@ -4350,7 +4353,7 @@ TypoExpr *Sema::CorrectTypoDelayed(
     const DeclarationNameInfo &TypoName, Sema::LookupNameKind LookupKind,
     Scope *S, CXXScopeSpec *SS,
     std::unique_ptr<CorrectionCandidateCallback> CCC,
-    TypoDiagnosticGenerator TDG, CorrectTypoKind Mode,
+    TypoDiagnosticGenerator TDG, TypoRecoveryCallback TRC, CorrectTypoKind Mode,
     DeclContext *MemberContext, bool EnteringContext,
     const ObjCObjectPointerType *OPT) {
   assert(CCC && "CorrectTypoDelayed requires a CorrectionCandidateCallback");
@@ -4375,7 +4378,7 @@ TypoExpr *Sema::CorrectTypoDelayed(
     return nullptr;
 
   ExprEvalContexts.back().NumTypos++;
-  return createDelayedTypo(std::move(Consumer), std::move(TDG));
+  return createDelayedTypo(std::move(Consumer), std::move(TDG), std::move(TRC));
 }
 
 void TypoCorrection::addCorrectionDecl(NamedDecl *CDecl) {
@@ -4575,14 +4578,15 @@ void Sema::diagnoseTypo(const TypoCorrection &Correction,
       << CorrectedQuotedStr << (ErrorRecovery ? FixItHint() : FixTypo);
 }
 
-TypoExpr *
-Sema::createDelayedTypo(std::unique_ptr<TypoCorrectionConsumer> TCC,
-                        TypoDiagnosticGenerator TDG) {
+TypoExpr *Sema::createDelayedTypo(std::unique_ptr<TypoCorrectionConsumer> TCC,
+                                  TypoDiagnosticGenerator TDG,
+                                  TypoRecoveryCallback TRC) {
   assert(TCC && "createDelayedTypo requires a valid TypoCorrectionConsumer");
   auto TE = new (Context) TypoExpr(Context.DependentTy);
   auto &State = DelayedTypos[TE];
   State.Consumer = std::move(TCC);
   State.DiagHandler = std::move(TDG);
+  State.RecoveryHandler = std::move(TRC);
   return TE;
 }