diff options
Diffstat (limited to 'clang-tools-extra/clangd')
-rw-r--r-- | clang-tools-extra/clangd/FindSymbols.cpp | 2 | ||||
-rw-r--r-- | clang-tools-extra/clangd/SourceCode.cpp | 34 | ||||
-rw-r--r-- | clang-tools-extra/clangd/SourceCode.h | 15 | ||||
-rw-r--r-- | clang-tools-extra/clangd/XRefs.cpp | 4 |
4 files changed, 39 insertions, 16 deletions
diff --git a/clang-tools-extra/clangd/FindSymbols.cpp b/clang-tools-extra/clangd/FindSymbols.cpp index c1ee678977d..cc7f084f26a 100644 --- a/clang-tools-extra/clangd/FindSymbols.cpp +++ b/clang-tools-extra/clangd/FindSymbols.cpp @@ -193,7 +193,7 @@ public: const FileEntry *F = SM.getFileEntryForID(SM.getMainFileID()); if (!F) return; - auto FilePath = getAbsoluteFilePath(F, SM); + auto FilePath = getRealPath(F, SM); if (FilePath) MainFileUri = URIForFile(*FilePath); } diff --git a/clang-tools-extra/clangd/SourceCode.cpp b/clang-tools-extra/clangd/SourceCode.cpp index 88ec2c95683..931ad3c0f20 100644 --- a/clang-tools-extra/clangd/SourceCode.cpp +++ b/clang-tools-extra/clangd/SourceCode.cpp @@ -185,18 +185,34 @@ std::vector<TextEdit> replacementsToEdits(StringRef Code, return Edits; } -llvm::Optional<std::string> -getAbsoluteFilePath(const FileEntry *F, const SourceManager &SourceMgr) { - SmallString<64> FilePath = F->tryGetRealPathName(); - if (FilePath.empty()) - FilePath = F->getName(); - if (!llvm::sys::path::is_absolute(FilePath)) { - if (!SourceMgr.getFileManager().makeAbsolutePath(FilePath)) { - log("Could not turn relative path to absolute: {0}", FilePath); +llvm::Optional<std::string> getRealPath(const FileEntry *F, + const SourceManager &SourceMgr) { + // Ideally, we get the real path from the FileEntry object. + SmallString<128> FilePath = F->tryGetRealPathName(); + if (!FilePath.empty()) { + return FilePath.str().str(); + } + + // Otherwise, we try to compute ourselves. + vlog("FileEntry for {0} did not contain the real path.", F->getName()); + + llvm::SmallString<128> Path = F->getName(); + + if (!llvm::sys::path::is_absolute(Path)) { + if (!SourceMgr.getFileManager().makeAbsolutePath(Path)) { + log("Could not turn relative path to absolute: {0}", Path); return llvm::None; } } - return FilePath.str().str(); + + llvm::SmallString<128> RealPath; + if (SourceMgr.getFileManager().getVirtualFileSystem()->getRealPath( + Path, RealPath)) { + log("Could not compute real path: {0}", Path); + return Path.str().str(); + } + + return RealPath.str().str(); } TextEdit toTextEdit(const FixItHint &FixIt, const SourceManager &M, diff --git a/clang-tools-extra/clangd/SourceCode.h b/clang-tools-extra/clangd/SourceCode.h index cb0c6728781..e633a1570d1 100644 --- a/clang-tools-extra/clangd/SourceCode.h +++ b/clang-tools-extra/clangd/SourceCode.h @@ -62,13 +62,20 @@ TextEdit replacementToEdit(StringRef Code, const tooling::Replacement &R); std::vector<TextEdit> replacementsToEdits(StringRef Code, const tooling::Replacements &Repls); -/// Get the absolute file path of a given file entry. -llvm::Optional<std::string> getAbsoluteFilePath(const FileEntry *F, - const SourceManager &SourceMgr); - TextEdit toTextEdit(const FixItHint &FixIt, const SourceManager &M, const LangOptions &L); +/// Get the real/canonical path of \p F. This means: +/// +/// - Absolute path +/// - Symlinks resolved +/// - No "." or ".." component +/// - No duplicate or trailing directory separator +/// +/// This function should be used when sending paths to clients, so that paths +/// are normalized as much as possible. +llvm::Optional<std::string> getRealPath(const FileEntry *F, + const SourceManager &SourceMgr); } // namespace clangd } // namespace clang #endif diff --git a/clang-tools-extra/clangd/XRefs.cpp b/clang-tools-extra/clangd/XRefs.cpp index e95730ba7e8..f5e2b1e12da 100644 --- a/clang-tools-extra/clangd/XRefs.cpp +++ b/clang-tools-extra/clangd/XRefs.cpp @@ -192,7 +192,7 @@ makeLocation(ParsedAST &AST, const SourceRange &ValSourceRange) { Range R = {Begin, End}; Location L; - auto FilePath = getAbsoluteFilePath(F, SourceMgr); + auto FilePath = getRealPath(F, SourceMgr); if (!FilePath) { log("failed to get path!"); return llvm::None; @@ -286,7 +286,7 @@ std::vector<Location> findDefinitions(ParsedAST &AST, Position Pos, std::string HintPath; const FileEntry *FE = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()); - if (auto Path = getAbsoluteFilePath(FE, SourceMgr)) + if (auto Path = getRealPath(FE, SourceMgr)) HintPath = *Path; // Query the index and populate the empty slot. Index->lookup( |