[clang-tools-extra] r325029 - [clangd] Fixed findDefinitions to always return absolute paths.
Ilya Biryukov via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 13 09:47:16 PST 2018
Author: ibiryukov
Date: Tue Feb 13 09:47:16 2018
New Revision: 325029
URL: http://llvm.org/viewvc/llvm-project?rev=325029&view=rev
Log:
[clangd] Fixed findDefinitions to always return absolute paths.
Relative paths could be returned in some cases, e.g. when relative
path is used in compilation arguments. This led to crash when trying
to convert the path to URI.
Modified:
clang-tools-extra/trunk/clangd/XRefs.cpp
clang-tools-extra/trunk/unittests/clangd/TestFS.cpp
clang-tools-extra/trunk/unittests/clangd/TestFS.h
clang-tools-extra/trunk/unittests/clangd/XRefsTests.cpp
Modified: clang-tools-extra/trunk/clangd/XRefs.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/XRefs.cpp?rev=325029&r1=325028&r2=325029&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/XRefs.cpp (original)
+++ clang-tools-extra/trunk/clangd/XRefs.cpp Tue Feb 13 09:47:16 2018
@@ -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, c
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;
}
Modified: clang-tools-extra/trunk/unittests/clangd/TestFS.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/TestFS.cpp?rev=325029&r1=325028&r2=325029&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/TestFS.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/TestFS.cpp Tue Feb 13 09:47:16 2018
@@ -33,8 +33,10 @@ MockFSProvider::getTaggedFileSystem(Path
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::getCompileComma
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), "")};
}
Modified: clang-tools-extra/trunk/unittests/clangd/TestFS.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/TestFS.h?rev=325029&r1=325028&r2=325029&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/TestFS.h (original)
+++ clang-tools-extra/trunk/unittests/clangd/TestFS.h Tue Feb 13 09:47:16 2018
@@ -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.
Modified: clang-tools-extra/trunk/unittests/clangd/XRefsTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/XRefsTests.cpp?rev=325029&r1=325028&r2=325029&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/XRefsTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/XRefsTests.cpp Tue Feb 13 09:47:16 2018
@@ -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
More information about the cfe-commits
mailing list