ilya-biryukov created this revision. ilya-biryukov added a reviewer: sammccall. Herald added subscribers: ioeric, jkorous-apple, klimek.
When parser backtracks, we might receive multiple code completion callbacks. Previously we had a failing assertion there, now we take first results and hope they are good enough. Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D44567 Files: clangd/CodeComplete.cpp unittests/clangd/CodeCompleteTests.cpp Index: unittests/clangd/CodeCompleteTests.cpp =================================================================== --- unittests/clangd/CodeCompleteTests.cpp +++ unittests/clangd/CodeCompleteTests.cpp @@ -608,6 +608,42 @@ EXPECT_THAT(Results.items, Not(Contains(Labeled("clang::")))); } +TEST(CompletionTest, BacktrackCrashes) { + // Sema calls code completion callbacks twice in these cases. + auto Results = completions(R"cpp( + namespace ns { + struct FooBarBaz {}; + } // namespace ns + + int foo(ns::FooBar^ + )cpp"); + + EXPECT_THAT(Results.items, ElementsAre(Labeled("FooBarBaz"))); + + Results = completions(R"cpp( + struct FooBarBaz {}; + void test() { + if (FooBarBaz * x^) {} + } +)cpp"); +} + +TEST(CompletionTest, CompleteInExcludedPPBranch) { + auto Results = completions(R"cpp( + int bar(int param_in_bar) { + } + + int foo(int param_in_foo) { +#if 0 + par^ +#endif + } +)cpp"); + + EXPECT_THAT(Results.items, Contains(Labeled("param_in_foo"))); + EXPECT_THAT(Results.items, Not(Contains(Labeled("param_in_bar")))); +} + SignatureHelp signatures(StringRef Text) { MockFSProvider FS; MockCompilationDatabase CDB; Index: clangd/CodeComplete.cpp =================================================================== --- clangd/CodeComplete.cpp +++ clangd/CodeComplete.cpp @@ -450,8 +450,14 @@ void ProcessCodeCompleteResults(class Sema &S, CodeCompletionContext Context, CodeCompletionResult *InResults, unsigned NumResults) override final { + if (CCSema) { + log(llvm::formatv("ProcessCodeCompleteResults called multiple times." + "Previous ContextKind: '{0}'. New ContextKind: '{1}'", + getCompletionKindString(this->CCContext.getKind()), + getCompletionKindString(Context.getKind()))); + return; + } // Record the completion context. - assert(!CCSema && "ProcessCodeCompleteResults called multiple times!"); CCSema = &S; CCContext = Context;
Index: unittests/clangd/CodeCompleteTests.cpp =================================================================== --- unittests/clangd/CodeCompleteTests.cpp +++ unittests/clangd/CodeCompleteTests.cpp @@ -608,6 +608,42 @@ EXPECT_THAT(Results.items, Not(Contains(Labeled("clang::")))); } +TEST(CompletionTest, BacktrackCrashes) { + // Sema calls code completion callbacks twice in these cases. + auto Results = completions(R"cpp( + namespace ns { + struct FooBarBaz {}; + } // namespace ns + + int foo(ns::FooBar^ + )cpp"); + + EXPECT_THAT(Results.items, ElementsAre(Labeled("FooBarBaz"))); + + Results = completions(R"cpp( + struct FooBarBaz {}; + void test() { + if (FooBarBaz * x^) {} + } +)cpp"); +} + +TEST(CompletionTest, CompleteInExcludedPPBranch) { + auto Results = completions(R"cpp( + int bar(int param_in_bar) { + } + + int foo(int param_in_foo) { +#if 0 + par^ +#endif + } +)cpp"); + + EXPECT_THAT(Results.items, Contains(Labeled("param_in_foo"))); + EXPECT_THAT(Results.items, Not(Contains(Labeled("param_in_bar")))); +} + SignatureHelp signatures(StringRef Text) { MockFSProvider FS; MockCompilationDatabase CDB; Index: clangd/CodeComplete.cpp =================================================================== --- clangd/CodeComplete.cpp +++ clangd/CodeComplete.cpp @@ -450,8 +450,14 @@ void ProcessCodeCompleteResults(class Sema &S, CodeCompletionContext Context, CodeCompletionResult *InResults, unsigned NumResults) override final { + if (CCSema) { + log(llvm::formatv("ProcessCodeCompleteResults called multiple times." + "Previous ContextKind: '{0}'. New ContextKind: '{1}'", + getCompletionKindString(this->CCContext.getKind()), + getCompletionKindString(Context.getKind()))); + return; + } // Record the completion context. - assert(!CCSema && "ProcessCodeCompleteResults called multiple times!"); CCSema = &S; CCContext = Context;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits