diff options
author | Simon Marchi <simon.marchi@ericsson.com> | 2018-08-10 22:27:53 +0000 |
---|---|---|
committer | Simon Marchi <simon.marchi@ericsson.com> | 2018-08-10 22:27:53 +0000 |
commit | 918f568ed9909dd23e209792cb4ca17e00d38dac (patch) | |
tree | 19f95ac5ef6c8b0a6678912893763b93c3a65eb4 /clang-tools-extra/unittests/clangd/TestFS.cpp | |
parent | 93ba973259f3615a11e868932b9477de00fcc6e5 (diff) |
[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
Diffstat (limited to 'clang-tools-extra/unittests/clangd/TestFS.cpp')
-rw-r--r-- | clang-tools-extra/unittests/clangd/TestFS.cpp | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/clang-tools-extra/unittests/clangd/TestFS.cpp b/clang-tools-extra/unittests/clangd/TestFS.cpp index b3081d6430b..d3112b92278 100644 --- a/clang-tools-extra/unittests/clangd/TestFS.cpp +++ b/clang-tools-extra/unittests/clangd/TestFS.cpp @@ -32,8 +32,10 @@ buildTestFS(llvm::StringMap<std::string> const &Files, return MemFS; } -MockCompilationDatabase::MockCompilationDatabase(bool UseRelPaths) - : ExtraClangFlags({"-ffreestanding"}), UseRelPaths(UseRelPaths) { +MockCompilationDatabase::MockCompilationDatabase(StringRef Directory, + StringRef RelPathPrefix) + : ExtraClangFlags({"-ffreestanding"}), Directory(Directory), + RelPathPrefix(RelPathPrefix) { // -ffreestanding avoids implicit stdc-predef.h. } @@ -42,12 +44,24 @@ MockCompilationDatabase::getCompileCommand(PathRef File) const { if (ExtraClangFlags.empty()) return None; - auto CommandLine = ExtraClangFlags; auto FileName = sys::path::filename(File); + + // Build the compile command. + auto CommandLine = ExtraClangFlags; CommandLine.insert(CommandLine.begin(), "clang"); - CommandLine.insert(CommandLine.end(), UseRelPaths ? FileName : File); - return {tooling::CompileCommand(sys::path::parent_path(File), FileName, - std::move(CommandLine), "")}; + if (RelPathPrefix.empty()) { + // Use the absolute path in the compile command. + CommandLine.push_back(File); + } else { + // Build a relative path using RelPathPrefix. + SmallString<32> RelativeFilePath(RelPathPrefix); + llvm::sys::path::append(RelativeFilePath, FileName); + CommandLine.push_back(RelativeFilePath.str()); + } + + return {tooling::CompileCommand( + Directory != StringRef() ? Directory : sys::path::parent_path(File), + FileName, std::move(CommandLine), "")}; } const char *testRoot() { |