summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHaojian Wu <hokein@google.com>2018-08-17 08:15:22 +0000
committerHaojian Wu <hokein@google.com>2018-08-17 08:15:22 +0000
commit4c0c37df4cccbee18f2a886d0ccb3bc8cc59be6b (patch)
treee24c71905aeba025d0ab473fa2ca9e825327cf3d
parente2d47dd1bb0dcae478db891273635672c3dc969e (diff)
downloadbcm5719-llvm-4c0c37df4cccbee18f2a886d0ccb3bc8cc59be6b.tar.gz
bcm5719-llvm-4c0c37df4cccbee18f2a886d0ccb3bc8cc59be6b.zip
[clangd] Always use the latest preamble
Summary: Fix an inconsistent behavior of using `LastBuiltPreamble`/`NewPreamble` in TUScheduler (see the test for details), AST should always use NewPreamble. This patch makes LastBuiltPreamble always point to NewPreamble. Preamble rarely fails to build, even there are errors in headers, so we assume it would not cause performace issue for code completion. Reviewers: ilya-biryukov Reviewed By: ilya-biryukov Subscribers: javed.absar, ioeric, MaskRay, jkorous, arphaman, cfe-commits Differential Revision: https://reviews.llvm.org/D50695 llvm-svn: 340001
-rw-r--r--clang-tools-extra/clangd/TUScheduler.cpp3
-rw-r--r--clang-tools-extra/unittests/clangd/XRefsTests.cpp45
2 files changed, 46 insertions, 2 deletions
diff --git a/clang-tools-extra/clangd/TUScheduler.cpp b/clang-tools-extra/clangd/TUScheduler.cpp
index f985e7d7fa3..4d65886e65f 100644
--- a/clang-tools-extra/clangd/TUScheduler.cpp
+++ b/clang-tools-extra/clangd/TUScheduler.cpp
@@ -370,8 +370,7 @@ void ASTWorker::update(
bool CanReuseAST = InputsAreTheSame && (OldPreamble == NewPreamble);
{
std::lock_guard<std::mutex> Lock(Mutex);
- if (NewPreamble)
- LastBuiltPreamble = NewPreamble;
+ LastBuiltPreamble = NewPreamble;
}
// Before doing the expensive AST reparse, we want to release our reference
// to the old preamble, so it can be freed if there are no other references
diff --git a/clang-tools-extra/unittests/clangd/XRefsTests.cpp b/clang-tools-extra/unittests/clangd/XRefsTests.cpp
index b08af32df21..2558cdefaaa 100644
--- a/clang-tools-extra/unittests/clangd/XRefsTests.cpp
+++ b/clang-tools-extra/unittests/clangd/XRefsTests.cpp
@@ -1021,6 +1021,51 @@ TEST(GoToInclude, All) {
EXPECT_THAT(*Locations, IsEmpty());
}
+TEST(GoToDefinition, WithPreamble) {
+ // Test stragety: AST should always use the latest preamble instead of last
+ // good preamble.
+ MockFSProvider FS;
+ IgnoreDiagnostics DiagConsumer;
+ MockCompilationDatabase CDB;
+ ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
+
+ auto FooCpp = testPath("foo.cpp");
+ auto FooCppUri = URIForFile{FooCpp};
+ // The trigger locations must be the same.
+ Annotations FooWithHeader(R"cpp(#include "fo^o.h")cpp");
+ Annotations FooWithoutHeader(R"cpp(double [[fo^o]]();)cpp");
+
+ FS.Files[FooCpp] = FooWithHeader.code();
+
+ auto FooH = testPath("foo.h");
+ auto FooHUri = URIForFile{FooH};
+ Annotations FooHeader(R"cpp([[]])cpp");
+ FS.Files[FooH] = FooHeader.code();
+
+ runAddDocument(Server, FooCpp, FooWithHeader.code());
+ // GoToDefinition goes to a #include file: the result comes from the preamble.
+ EXPECT_THAT(
+ cantFail(runFindDefinitions(Server, FooCpp, FooWithHeader.point())),
+ ElementsAre(Location{FooHUri, FooHeader.range()}));
+
+ // Only preamble is built, and no AST is built in this request.
+ Server.addDocument(FooCpp, FooWithoutHeader.code(), WantDiagnostics::No);
+ // We build AST here, and it should use the latest preamble rather than the
+ // stale one.
+ EXPECT_THAT(
+ cantFail(runFindDefinitions(Server, FooCpp, FooWithoutHeader.point())),
+ ElementsAre(Location{FooCppUri, FooWithoutHeader.range()}));
+
+ // Reset test environment.
+ runAddDocument(Server, FooCpp, FooWithHeader.code());
+ // Both preamble and AST are built in this request.
+ Server.addDocument(FooCpp, FooWithoutHeader.code(), WantDiagnostics::Yes);
+ // Use the AST being built in above request.
+ EXPECT_THAT(
+ cantFail(runFindDefinitions(Server, FooCpp, FooWithoutHeader.point())),
+ ElementsAre(Location{FooCppUri, FooWithoutHeader.range()}));
+}
+
} // namespace
} // namespace clangd
} // namespace clang
OpenPOWER on IntegriCloud