From: Kaelyn Takata Date: Mon, 27 Oct 2014 18:07:42 +0000 (+0000) Subject: Add a callback for recovering using a typo correction. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fb608dd7d0896f85baf1f929dc39a2321d8a49b7;p=clang Add a callback for recovering using a typo correction. 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 --- diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 8664d23da7..ebcc4808b7 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -2592,6 +2592,8 @@ public: bool VolatileThis); typedef std::function TypoDiagnosticGenerator; + typedef std::function + TypoRecoveryCallback; private: bool CppLookupName(LookupResult &R, Scope *S); @@ -2599,6 +2601,7 @@ private: struct TypoExprState { std::unique_ptr 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 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 CCC, TypoDiagnosticGenerator TDG, - CorrectTypoKind Mode, + 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 e5c49124c6..12f7f06d5c 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 { diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 861fb068e7..1d9df2d4d4 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -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()) diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index afb56fe996..eab819e15f 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -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 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 TCC, - TypoDiagnosticGenerator TDG) { +TypoExpr *Sema::createDelayedTypo(std::unique_ptr 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; }