summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang-tools-extra/clangd/XRefs.cpp12
-rw-r--r--clang-tools-extra/unittests/clangd/TestFS.cpp12
-rw-r--r--clang-tools-extra/unittests/clangd/TestFS.h5
-rw-r--r--clang-tools-extra/unittests/clangd/XRefsTests.cpp30
4 files changed, 51 insertions, 8 deletions
diff --git a/clang-tools-extra/clangd/XRefs.cpp b/clang-tools-extra/clangd/XRefs.cpp
index e7ded2ee1e8..6f43353dce6 100644
--- a/clang-tools-extra/clangd/XRefs.cpp
+++ b/clang-tools-extra/clangd/XRefs.cpp
@@ -11,6 +11,7 @@
#include "URI.h"
#include "clang/Index/IndexDataConsumer.h"
#include "clang/Index/IndexingAction.h"
+#include "llvm/Support/Path.h"
namespace clang {
namespace clangd {
using namespace llvm;
@@ -138,10 +139,17 @@ getDeclarationLocation(ParsedAST &AST, const SourceRange &ValSourceRange) {
Range R = {Begin, End};
Location L;
- StringRef FilePath = F->tryGetRealPathName();
+ SmallString<64> FilePath = F->tryGetRealPathName();
if (FilePath.empty())
FilePath = F->getName();
- L.uri.file = FilePath;
+ if (!llvm::sys::path::is_absolute(FilePath)) {
+ if (!SourceMgr.getFileManager().makeAbsolutePath(FilePath)) {
+ log("Could not turn relative path to absolute: " + FilePath);
+ return llvm::None;
+ }
+ }
+
+ L.uri.file = FilePath.str();
L.range = R;
return L;
}
diff --git a/clang-tools-extra/unittests/clangd/TestFS.cpp b/clang-tools-extra/unittests/clangd/TestFS.cpp
index 55506e6c4e0..38cef894074 100644
--- a/clang-tools-extra/unittests/clangd/TestFS.cpp
+++ b/clang-tools-extra/unittests/clangd/TestFS.cpp
@@ -33,8 +33,10 @@ MockFSProvider::getTaggedFileSystem(PathRef File) {
return make_tagged(FS, Tag);
}
-MockCompilationDatabase::MockCompilationDatabase()
- : ExtraClangFlags({"-ffreestanding"}) {} // Avoid implicit stdc-predef.h.
+MockCompilationDatabase::MockCompilationDatabase(bool UseRelPaths)
+ : ExtraClangFlags({"-ffreestanding"}), UseRelPaths(UseRelPaths) {
+ // -ffreestanding avoids implicit stdc-predef.h.
+}
llvm::Optional<tooling::CompileCommand>
MockCompilationDatabase::getCompileCommand(PathRef File) const {
@@ -42,10 +44,10 @@ MockCompilationDatabase::getCompileCommand(PathRef File) const {
return llvm::None;
auto CommandLine = ExtraClangFlags;
+ auto FileName = llvm::sys::path::filename(File);
CommandLine.insert(CommandLine.begin(), "clang");
- CommandLine.insert(CommandLine.end(), File.str());
- return {tooling::CompileCommand(llvm::sys::path::parent_path(File),
- llvm::sys::path::filename(File),
+ CommandLine.insert(CommandLine.end(), UseRelPaths ? FileName : File);
+ return {tooling::CompileCommand(llvm::sys::path::parent_path(File), FileName,
std::move(CommandLine), "")};
}
diff --git a/clang-tools-extra/unittests/clangd/TestFS.h b/clang-tools-extra/unittests/clangd/TestFS.h
index 6ff1c662201..5edde1fff9e 100644
--- a/clang-tools-extra/unittests/clangd/TestFS.h
+++ b/clang-tools-extra/unittests/clangd/TestFS.h
@@ -37,12 +37,15 @@ public:
// A Compilation database that returns a fixed set of compile flags.
class MockCompilationDatabase : public GlobalCompilationDatabase {
public:
- MockCompilationDatabase();
+ /// When \p UseRelPaths is true, uses relative paths in compile commands.
+ /// When \p UseRelPaths is false, uses absoulte paths.
+ MockCompilationDatabase(bool UseRelPaths = false);
llvm::Optional<tooling::CompileCommand>
getCompileCommand(PathRef File) const override;
std::vector<std::string> ExtraClangFlags;
+ const bool UseRelPaths;
};
// Returns an absolute (fake) test directory for this OS.
diff --git a/clang-tools-extra/unittests/clangd/XRefsTests.cpp b/clang-tools-extra/unittests/clangd/XRefsTests.cpp
index 59e30725ba0..50d24c50113 100644
--- a/clang-tools-extra/unittests/clangd/XRefsTests.cpp
+++ b/clang-tools-extra/unittests/clangd/XRefsTests.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "Annotations.h"
#include "ClangdUnit.h"
+#include "Compiler.h"
#include "Matchers.h"
#include "TestFS.h"
#include "XRefs.h"
@@ -37,6 +38,11 @@ using testing::Field;
using testing::Matcher;
using testing::UnorderedElementsAreArray;
+class IgnoreDiagnostics : public DiagnosticsConsumer {
+ void onDiagnosticsReady(
+ PathRef File, Tagged<std::vector<DiagWithFixIts>> Diagnostics) override {}
+};
+
// FIXME: this is duplicated with FileIndexTests. Share it.
ParsedAST build(StringRef Code) {
auto TestFile = getVirtualTestFilePath("Foo.cpp");
@@ -227,6 +233,30 @@ TEST(GoToDefinition, All) {
}
}
+TEST(GoToDefinition, RelPathsInCompileCommand) {
+ Annotations SourceAnnotations(R"cpp(
+[[int foo]];
+int baz = f^oo;
+)cpp");
+
+ IgnoreDiagnostics DiagConsumer;
+ MockCompilationDatabase CDB(/*UseRelPaths=*/true);
+ MockFSProvider FS;
+ ClangdServer Server(CDB, DiagConsumer, FS, /*AsyncThreadsCount=*/0,
+ /*StorePreambleInMemory=*/true);
+
+ auto FooCpp = getVirtualTestFilePath("foo.cpp");
+ FS.Files[FooCpp] = "";
+
+ Server.addDocument(FooCpp, SourceAnnotations.code());
+ auto Locations = Server.findDefinitions(FooCpp, SourceAnnotations.point());
+ EXPECT_TRUE(bool(Locations)) << "findDefinitions returned an error";
+
+ EXPECT_THAT(Locations->Value,
+ ElementsAre(Location{URIForFile{FooCpp.str()},
+ SourceAnnotations.range()}));
+}
+
} // namespace
} // namespace clangd
} // namespace clang
OpenPOWER on IntegriCloud