summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/unittests/clangd/XRefsTests.cpp
diff options
context:
space:
mode:
authorSimon Marchi <simon.marchi@ericsson.com>2018-08-10 22:27:53 +0000
committerSimon Marchi <simon.marchi@ericsson.com>2018-08-10 22:27:53 +0000
commit25f1f7325feac42b3bf05fd408e15b6a6be7d81c (patch)
tree1fd566738ae682a9d51df0b76d627cc3e69185fa /clang-tools-extra/unittests/clangd/XRefsTests.cpp
parente99ba6e1f9f1a682292247ad7898e1e133d51fe5 (diff)
downloadbcm5719-llvm-25f1f7325feac42b3bf05fd408e15b6a6be7d81c.tar.gz
bcm5719-llvm-25f1f7325feac42b3bf05fd408e15b6a6be7d81c.zip
[clangd] Avoid duplicates in findDefinitions response
Summary: When compile_commands.json contains some source files expressed as relative paths, we can get duplicate responses to findDefinitions. The responses only differ by the URI, which are different versions of the same file: "result": [ { ... "uri": "file:///home/emaisin/src/ls-interact/cpp-test/build/../src/first.h" }, { ... "uri": "file:///home/emaisin/src/ls-interact/cpp-test/src/first.h" } ] In getAbsoluteFilePath, we try to obtain the realpath of the FileEntry by calling tryGetRealPathName. However, this can fail and return an empty string. It may be bug a bug in clang, but in any case we should fall back to computing it ourselves if it happens. I changed getAbsoluteFilePath so that if tryGetRealPathName succeeds, we return right away (a real path is always absolute). Otherwise, we try to build an absolute path, as we did before, but we also call VFS->getRealPath to make sure to get the canonical path (e.g. without any ".." in it). Reviewers: malaperle Subscribers: hokein, ilya-biryukov, ioeric, MaskRay, jkorous, cfe-commits Differential Revision: https://reviews.llvm.org/D48687 llvm-svn: 339483
Diffstat (limited to 'clang-tools-extra/unittests/clangd/XRefsTests.cpp')
-rw-r--r--clang-tools-extra/unittests/clangd/XRefsTests.cpp50
1 files changed, 44 insertions, 6 deletions
diff --git a/clang-tools-extra/unittests/clangd/XRefsTests.cpp b/clang-tools-extra/unittests/clangd/XRefsTests.cpp
index 3383dd54341..b08af32df21 100644
--- a/clang-tools-extra/unittests/clangd/XRefsTests.cpp
+++ b/clang-tools-extra/unittests/clangd/XRefsTests.cpp
@@ -312,27 +312,65 @@ TEST(GoToDefinition, All) {
}
TEST(GoToDefinition, RelPathsInCompileCommand) {
+ // The source is in "/clangd-test/src".
+ // We build in "/clangd-test/build".
+
Annotations SourceAnnotations(R"cpp(
+#include "header_in_preamble.h"
int [[foo]];
-int baz = f^oo;
+#include "header_not_in_preamble.h"
+int baz = f$p1^oo + bar_pre$p2^amble + bar_not_pre$p3^amble;
+)cpp");
+
+ Annotations HeaderInPreambleAnnotations(R"cpp(
+int [[bar_preamble]];
+)cpp");
+
+ Annotations HeaderNotInPreambleAnnotations(R"cpp(
+int [[bar_not_preamble]];
)cpp");
+ // Make the compilation paths appear as ../src/foo.cpp in the compile
+ // commands.
+ SmallString<32> RelPathPrefix("..");
+ llvm::sys::path::append(RelPathPrefix, "src");
+ std::string BuildDir = testPath("build");
+ MockCompilationDatabase CDB(BuildDir, RelPathPrefix);
+
IgnoreDiagnostics DiagConsumer;
- MockCompilationDatabase CDB(/*UseRelPaths=*/true);
MockFSProvider FS;
ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
- auto FooCpp = testPath("foo.cpp");
+ // Fill the filesystem.
+ auto FooCpp = testPath("src/foo.cpp");
FS.Files[FooCpp] = "";
+ auto HeaderInPreambleH = testPath("src/header_in_preamble.h");
+ FS.Files[HeaderInPreambleH] = HeaderInPreambleAnnotations.code();
+ auto HeaderNotInPreambleH = testPath("src/header_not_in_preamble.h");
+ FS.Files[HeaderNotInPreambleH] = HeaderNotInPreambleAnnotations.code();
- Server.addDocument(FooCpp, SourceAnnotations.code());
runAddDocument(Server, FooCpp, SourceAnnotations.code());
+
+ // Go to a definition in main source file.
auto Locations =
- runFindDefinitions(Server, FooCpp, SourceAnnotations.point());
+ runFindDefinitions(Server, FooCpp, SourceAnnotations.point("p1"));
EXPECT_TRUE(bool(Locations)) << "findDefinitions returned an error";
-
EXPECT_THAT(*Locations, ElementsAre(Location{URIForFile{FooCpp},
SourceAnnotations.range()}));
+
+ // Go to a definition in header_in_preamble.h.
+ Locations = runFindDefinitions(Server, FooCpp, SourceAnnotations.point("p2"));
+ EXPECT_TRUE(bool(Locations)) << "findDefinitions returned an error";
+ EXPECT_THAT(*Locations,
+ ElementsAre(Location{URIForFile{HeaderInPreambleH},
+ HeaderInPreambleAnnotations.range()}));
+
+ // Go to a definition in header_not_in_preamble.h.
+ Locations = runFindDefinitions(Server, FooCpp, SourceAnnotations.point("p3"));
+ EXPECT_TRUE(bool(Locations)) << "findDefinitions returned an error";
+ EXPECT_THAT(*Locations,
+ ElementsAre(Location{URIForFile{HeaderNotInPreambleH},
+ HeaderNotInPreambleAnnotations.range()}));
}
TEST(Hover, All) {
OpenPOWER on IntegriCloud