Index: clangd/ClangdServer.cpp =================================================================== --- clangd/ClangdServer.cpp +++ clangd/ClangdServer.cpp @@ -305,7 +305,8 @@ llvm::Expected InpAST) { if (!InpAST) return CB(InpAST.takeError()); - CB(clangd::findDefinitions(InpAST->AST, Pos, Index)); + CB(clangd::findDefinitions(InpAST->AST, Pos, *FSProvider.getFileSystem(), + Index)); }; WorkScheduler.runWithAST("Definitions", File, Bind(Action, std::move(CB))); Index: clangd/XRefs.h =================================================================== --- clangd/XRefs.h +++ clangd/XRefs.h @@ -24,6 +24,7 @@ /// Get definition of symbol at a specified \p Pos. std::vector findDefinitions(ParsedAST &AST, Position Pos, + const vfs::FileSystem &VFS, const SymbolIndex *Index = nullptr); /// Returns highlights for all usages of a symbol at \p Pos. Index: clangd/XRefs.cpp =================================================================== --- clangd/XRefs.cpp +++ clangd/XRefs.cpp @@ -174,11 +174,17 @@ return {DeclMacrosFinder.takeDecls(), DeclMacrosFinder.takeMacroInfos()}; } -llvm::Optional -getAbsoluteFilePath(const FileEntry *F, const SourceManager &SourceMgr) { +llvm::Optional getAbsoluteFilePath(const FileEntry *F, + const SourceManager &SourceMgr, + const vfs::FileSystem &VFS) { SmallString<64> FilePath = F->tryGetRealPathName(); - if (FilePath.empty()) - FilePath = F->getName(); + + if (FilePath.empty()) { + if (VFS.getRealPath(F->getName(), FilePath) != std::error_code()) { + FilePath = F->getName(); + } + } + if (!llvm::sys::path::is_absolute(FilePath)) { if (!SourceMgr.getFileManager().makeAbsolutePath(FilePath)) { log("Could not turn relative path to absolute: " + FilePath); @@ -188,8 +194,9 @@ return FilePath.str().str(); } -llvm::Optional -makeLocation(ParsedAST &AST, const SourceRange &ValSourceRange) { +llvm::Optional makeLocation(ParsedAST &AST, + const SourceRange &ValSourceRange, + const vfs::FileSystem &VFS) { const SourceManager &SourceMgr = AST.getASTContext().getSourceManager(); const LangOptions &LangOpts = AST.getASTContext().getLangOpts(); SourceLocation LocStart = ValSourceRange.getBegin(); @@ -205,7 +212,7 @@ Range R = {Begin, End}; Location L; - auto FilePath = getAbsoluteFilePath(F, SourceMgr); + auto FilePath = getAbsoluteFilePath(F, SourceMgr, VFS); if (!FilePath) { log("failed to get path!"); return llvm::None; @@ -227,6 +234,7 @@ } // namespace std::vector findDefinitions(ParsedAST &AST, Position Pos, + const vfs::FileSystem &VFS, const SymbolIndex *Index) { const SourceManager &SourceMgr = AST.getASTContext().getSourceManager(); SourceLocation SourceLocationBeg = @@ -247,7 +255,7 @@ for (auto Item : Symbols.Macros) { auto Loc = Item.Info->getDefinitionLoc(); - auto L = makeLocation(AST, SourceRange(Loc, Loc)); + auto L = makeLocation(AST, SourceRange(Loc, Loc), VFS); if (L) Result.push_back(*L); } @@ -290,7 +298,7 @@ auto &Candidate = ResultCandidates[Key]; auto Loc = findNameLoc(D); - auto L = makeLocation(AST, SourceRange(Loc, Loc)); + auto L = makeLocation(AST, SourceRange(Loc, Loc), VFS); // The declaration in the identified symbols is a definition if possible // otherwise it is declaration. bool IsDef = GetDefinition(D) == D; @@ -309,7 +317,7 @@ std::string HintPath; const FileEntry *FE = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()); - if (auto Path = getAbsoluteFilePath(FE, SourceMgr)) + if (auto Path = getAbsoluteFilePath(FE, SourceMgr, VFS)) HintPath = *Path; // Query the index and populate the empty slot. Index->lookup( Index: unittests/clangd/TestTU.h =================================================================== --- unittests/clangd/TestTU.h +++ unittests/clangd/TestTU.h @@ -44,7 +44,7 @@ std::string HeaderCode; std::string HeaderFilename = "TestTU.h"; - ParsedAST build() const; + ParsedAST build(IntrusiveRefCntPtr *OutFS = nullptr) const; SymbolSlab headerSymbols() const; std::unique_ptr index() const; }; Index: unittests/clangd/TestTU.cpp =================================================================== --- unittests/clangd/TestTU.cpp +++ unittests/clangd/TestTU.cpp @@ -19,7 +19,7 @@ namespace clangd { using namespace llvm; -ParsedAST TestTU::build() const { +ParsedAST TestTU::build(IntrusiveRefCntPtr *OutFS) const { std::string FullFilename = testPath(Filename), FullHeaderName = testPath(HeaderFilename); std::vector Cmd = {"clang", FullFilename.c_str()}; @@ -29,11 +29,12 @@ Cmd.push_back("-include"); Cmd.push_back(FullHeaderName.c_str()); } - auto AST = ParsedAST::Build( - createInvocationFromCommandLine(Cmd), nullptr, - MemoryBuffer::getMemBufferCopy(Code), - std::make_shared(), - buildTestFS({{FullFilename, Code}, {FullHeaderName, HeaderCode}})); + auto FS = buildTestFS({{FullFilename, Code}, {FullHeaderName, HeaderCode}}); + if (OutFS) + *OutFS = FS; + auto AST = ParsedAST::Build(createInvocationFromCommandLine(Cmd), nullptr, + MemoryBuffer::getMemBufferCopy(Code), + std::make_shared(), FS); if (!AST.hasValue()) { ADD_FAILURE() << "Failed to build code:\n" << Code; llvm_unreachable("Failed to build TestTU!"); Index: unittests/clangd/XRefsTests.cpp =================================================================== --- unittests/clangd/XRefsTests.cpp +++ unittests/clangd/XRefsTests.cpp @@ -114,8 +114,9 @@ TU.HeaderCode = SymbolHeader.code(); auto Index = TU.index(); auto runFindDefinitionsWithIndex = [&Index](const Annotations &Main) { - auto AST = TestTU::withCode(Main.code()).build(); - return clangd::findDefinitions(AST, Main.point(), Index.get()); + IntrusiveRefCntPtr FS; + auto AST = TestTU::withCode(Main.code()).build(&FS); + return clangd::findDefinitions(AST, Main.point(), *FS, Index.get()); }; Annotations Test(R"cpp(// only declaration in AST. @@ -301,11 +302,12 @@ }; for (const char *Test : Tests) { Annotations T(Test); - auto AST = TestTU::withCode(T.code()).build(); + IntrusiveRefCntPtr FS; + auto AST = TestTU::withCode(T.code()).build(&FS); std::vector> ExpectedLocations; for (const auto &R : T.ranges()) ExpectedLocations.push_back(RangeIs(R)); - EXPECT_THAT(findDefinitions(AST, T.point()), + EXPECT_THAT(findDefinitions(AST, T.point(), *FS), ElementsAreArray(ExpectedLocations)) << Test; }