r270039 - [Sema] Allow an external sema source to handle delayed typo corrections.
Benjamin Kramer via cfe-commits
cfe-commits at lists.llvm.org
Thu May 19 15:00:06 PDT 2016
r270144 should fix that failure.
On Thu, May 19, 2016 at 10:17 PM, Evgenii Stepanov
<eugeni.stepanov at gmail.com> wrote:
> 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