r270039 - [Sema] Allow an external sema source to handle delayed typo corrections.
Evgenii Stepanov via cfe-commits
cfe-commits at lists.llvm.org
Thu May 19 13:17:48 PDT 2016
Looks like this commit broke the bot:
http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-
bootstrap/builds/11738/steps/check-clang%20ubsan/logs/stdio
On Thu, May 19, 2016 at 3:52 AM, Benjamin Kramer via cfe-commits
<cfe-commits at lists.llvm.org> wrote:
> Author: d0k
> Date: Thu May 19 05:46:10 2016
> New Revision: 270039
>
> URL: http://llvm.org/viewvc/llvm-project?rev=270039&view=rev
> Log:
> [Sema] Allow an external sema source to handle delayed typo corrections.
>
> This probably isn't perfectly perfect but allows correcting function calls
> again.
>
> Modified:
> cfe/trunk/lib/Sema/SemaLookup.cpp
> cfe/trunk/unittests/Sema/ExternalSemaSourceTest.cpp
>
> Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=270039&r1=270038&r2=270039&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaLookup.cpp Thu May 19 05:46:10 2016
> @@ -4781,11 +4781,19 @@ TypoExpr *Sema::CorrectTypoDelayed(
> const ObjCObjectPointerType *OPT) {
> assert(CCC && "CorrectTypoDelayed requires a CorrectionCandidateCallback");
>
> - TypoCorrection Empty;
> auto Consumer = makeTypoCorrectionConsumer(
> TypoName, LookupKind, S, SS, std::move(CCC), MemberContext,
> EnteringContext, OPT, Mode == CTK_ErrorRecovery);
>
> + // Give the external sema source a chance to correct the typo.
> + TypoCorrection ExternalTypo;
> + if (ExternalSource && Consumer) {
> + ExternalTypo = ExternalSource->CorrectTypo(
> + TypoName, LookupKind, S, SS, *CCC, MemberContext, EnteringContext, OPT);
> + if (ExternalTypo)
> + Consumer->addCorrection(ExternalTypo);
> + }
> +
> if (!Consumer || Consumer->empty())
> return nullptr;
>
> @@ -4793,7 +4801,7 @@ TypoExpr *Sema::CorrectTypoDelayed(
> // is not more that about a third of the length of the typo's identifier.
> unsigned ED = Consumer->getBestEditDistance(true);
> IdentifierInfo *Typo = TypoName.getName().getAsIdentifierInfo();
> - if (ED > 0 && Typo->getName().size() / ED < 3)
> + if (!ExternalTypo && ED > 0 && Typo->getName().size() / ED < 3)
> return nullptr;
>
> ExprEvalContexts.back().NumTypos++;
>
> Modified: cfe/trunk/unittests/Sema/ExternalSemaSourceTest.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Sema/ExternalSemaSourceTest.cpp?rev=270039&r1=270038&r2=270039&view=diff
> ==============================================================================
> --- cfe/trunk/unittests/Sema/ExternalSemaSourceTest.cpp (original)
> +++ cfe/trunk/unittests/Sema/ExternalSemaSourceTest.cpp Thu May 19 05:46:10 2016
> @@ -39,19 +39,18 @@ public:
> bool Result;
> };
>
> -// \brief Counts the number of err_using_directive_member_suggest diagnostics
> -// correcting from one namespace to another while still passing all diagnostics
> -// along a chain of consumers.
> -class NamespaceDiagnosticWatcher : public clang::DiagnosticConsumer {
> +/// Counts the number of typo-correcting diagnostics correcting from one name to
> +/// another while still passing all diagnostics along a chain of consumers.
> +class DiagnosticWatcher : public clang::DiagnosticConsumer {
> DiagnosticConsumer *Chained;
> - std::string FromNS;
> - std::string ToNS;
> + std::string FromName;
> + std::string ToName;
>
> public:
> - NamespaceDiagnosticWatcher(StringRef From, StringRef To)
> - : Chained(nullptr), FromNS(From), ToNS("'"), SeenCount(0) {
> - ToNS.append(To);
> - ToNS.append("'");
> + DiagnosticWatcher(StringRef From, StringRef To)
> + : Chained(nullptr), FromName(From), ToName("'"), SeenCount(0) {
> + ToName.append(To);
> + ToName.append("'");
> }
>
> void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
> @@ -61,7 +60,12 @@ public:
> if (Info.getID() - 1 == diag::err_using_directive_member_suggest) {
> const IdentifierInfo *Ident = Info.getArgIdentifier(0);
> const std::string &CorrectedQuotedStr = Info.getArgStdStr(1);
> - if (Ident->getName() == FromNS && CorrectedQuotedStr == ToNS)
> + if (Ident->getName() == FromName && CorrectedQuotedStr == ToName)
> + ++SeenCount;
> + } else if (Info.getID() == diag::err_no_member_suggest) {
> + auto Ident = DeclarationName::getFromOpaqueInteger(Info.getRawArg(0));
> + const std::string &CorrectedQuotedStr = Info.getArgStdStr(3);
> + if (Ident.getAsString() == FromName && CorrectedQuotedStr == ToName)
> ++SeenCount;
> }
> }
> @@ -78,7 +82,7 @@ public:
> return false;
> }
>
> - NamespaceDiagnosticWatcher *Chain(DiagnosticConsumer *ToChain) {
> + DiagnosticWatcher *Chain(DiagnosticConsumer *ToChain) {
> Chained = ToChain;
> return this;
> }
> @@ -130,11 +134,53 @@ public:
> int CallCount;
> };
>
> -// \brief Chains together a vector of NamespaceDiagnosticWatchers and
> +class FunctionTypoProvider : public clang::ExternalSemaSource {
> + std::string CorrectFrom;
> + std::string CorrectTo;
> + Sema *CurrentSema;
> +
> +public:
> + FunctionTypoProvider(StringRef From, StringRef To)
> + : CorrectFrom(From), CorrectTo(To), CurrentSema(nullptr), CallCount(0) {}
> +
> + void InitializeSema(Sema &S) override { CurrentSema = &S; }
> +
> + void ForgetSema() override { CurrentSema = nullptr; }
> +
> + TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, int LookupKind,
> + Scope *S, CXXScopeSpec *SS,
> + CorrectionCandidateCallback &CCC,
> + DeclContext *MemberContext, bool EnteringContext,
> + const ObjCObjectPointerType *OPT) override {
> + ++CallCount;
> + if (CurrentSema && Typo.getName().getAsString() == CorrectFrom) {
> + DeclContext *DestContext = nullptr;
> + ASTContext &Context = CurrentSema->getASTContext();
> + if (SS)
> + DestContext = CurrentSema->computeDeclContext(*SS, EnteringContext);
> + if (!DestContext)
> + DestContext = Context.getTranslationUnitDecl();
> + IdentifierInfo *ToIdent =
> + CurrentSema->getPreprocessor().getIdentifierInfo(CorrectTo);
> + auto *NewFunction = FunctionDecl::Create(
> + Context, DestContext, SourceLocation(), SourceLocation(), ToIdent,
> + Context.getFunctionType(Context.VoidTy, {}, {}), nullptr, SC_Static);
> + DestContext->addDecl(NewFunction);
> + TypoCorrection Correction(ToIdent);
> + Correction.addCorrectionDecl(NewFunction);
> + return Correction;
> + }
> + return TypoCorrection();
> + }
> +
> + int CallCount;
> +};
> +
> +// \brief Chains together a vector of DiagnosticWatchers and
> // adds a vector of ExternalSemaSources to the CompilerInstance before
> // performing semantic analysis.
> class ExternalSemaSourceInstaller : public clang::ASTFrontendAction {
> - std::vector<NamespaceDiagnosticWatcher *> Watchers;
> + std::vector<DiagnosticWatcher *> Watchers;
> std::vector<clang::ExternalSemaSource *> Sources;
> std::unique_ptr<DiagnosticConsumer> OwnedClient;
>
> @@ -170,16 +216,14 @@ public:
> Sources.push_back(Source);
> }
>
> - void PushWatcher(NamespaceDiagnosticWatcher *Watcher) {
> - Watchers.push_back(Watcher);
> - }
> + void PushWatcher(DiagnosticWatcher *Watcher) { Watchers.push_back(Watcher); }
> };
>
> -// Make sure that the NamespaceDiagnosticWatcher is not miscounting.
> +// Make sure that the DiagnosticWatcher is not miscounting.
> TEST(ExternalSemaSource, SanityCheck) {
> std::unique_ptr<ExternalSemaSourceInstaller> Installer(
> new ExternalSemaSourceInstaller);
> - NamespaceDiagnosticWatcher Watcher("AAB", "BBB");
> + DiagnosticWatcher Watcher("AAB", "BBB");
> Installer->PushWatcher(&Watcher);
> std::vector<std::string> Args(1, "-std=c++11");
> ASSERT_TRUE(clang::tooling::runToolOnCodeWithArgs(
> @@ -193,7 +237,7 @@ TEST(ExternalSemaSource, ExternalTypoCor
> std::unique_ptr<ExternalSemaSourceInstaller> Installer(
> new ExternalSemaSourceInstaller);
> NamespaceTypoProvider Provider("AAB", "BBB");
> - NamespaceDiagnosticWatcher Watcher("AAB", "BBB");
> + DiagnosticWatcher Watcher("AAB", "BBB");
> Installer->PushSource(&Provider);
> Installer->PushWatcher(&Watcher);
> std::vector<std::string> Args(1, "-std=c++11");
> @@ -211,7 +255,7 @@ TEST(ExternalSemaSource, ExternalTypoCor
> NamespaceTypoProvider First("XXX", "BBB");
> NamespaceTypoProvider Second("AAB", "CCC");
> NamespaceTypoProvider Third("AAB", "DDD");
> - NamespaceDiagnosticWatcher Watcher("AAB", "CCC");
> + DiagnosticWatcher Watcher("AAB", "CCC");
> Installer->PushSource(&First);
> Installer->PushSource(&Second);
> Installer->PushSource(&Third);
> @@ -225,6 +269,21 @@ TEST(ExternalSemaSource, ExternalTypoCor
> ASSERT_EQ(1, Watcher.SeenCount);
> }
>
> +TEST(ExternalSemaSource, ExternalDelayedTypoCorrection) {
> + std::unique_ptr<ExternalSemaSourceInstaller> Installer(
> + new ExternalSemaSourceInstaller);
> + FunctionTypoProvider Provider("aaa", "bbb");
> + DiagnosticWatcher Watcher("aaa", "bbb");
> + Installer->PushSource(&Provider);
> + Installer->PushWatcher(&Watcher);
> + std::vector<std::string> Args(1, "-std=c++11");
> + ASSERT_TRUE(clang::tooling::runToolOnCodeWithArgs(
> + Installer.release(), "namespace AAA { } void foo() { AAA::aaa(); }",
> + Args));
> + ASSERT_LE(0, Provider.CallCount);
> + ASSERT_EQ(1, Watcher.SeenCount);
> +}
> +
> // We should only try MaybeDiagnoseMissingCompleteType if we can't otherwise
> // solve the problem.
> TEST(ExternalSemaSource, TryOtherTacticsBeforeDiagnosing) {
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list