mirror of
https://github.com/llvm/llvm-project.git
synced 2025-05-12 12:06:06 +00:00

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 llvm-svn: 339483
82 lines
3.1 KiB
C++
82 lines
3.1 KiB
C++
//===--- SourceCode.h - Manipulating source code as strings -----*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Various code that examines C++ source code without using heavy AST machinery
|
|
// (and often not even the lexer). To be used sparingly!
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_SOURCECODE_H
|
|
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SOURCECODE_H
|
|
#include "Protocol.h"
|
|
#include "clang/Basic/Diagnostic.h"
|
|
#include "clang/Basic/SourceLocation.h"
|
|
#include "clang/Tooling/Core/Replacement.h"
|
|
|
|
namespace clang {
|
|
class SourceManager;
|
|
|
|
namespace clangd {
|
|
|
|
/// Turn a [line, column] pair into an offset in Code.
|
|
///
|
|
/// If P.character exceeds the line length, returns the offset at end-of-line.
|
|
/// (If !AllowColumnsBeyondLineLength, then returns an error instead).
|
|
/// If the line number is out of range, returns an error.
|
|
///
|
|
/// The returned value is in the range [0, Code.size()].
|
|
llvm::Expected<size_t>
|
|
positionToOffset(llvm::StringRef Code, Position P,
|
|
bool AllowColumnsBeyondLineLength = true);
|
|
|
|
/// Turn an offset in Code into a [line, column] pair.
|
|
/// The offset must be in range [0, Code.size()].
|
|
Position offsetToPosition(llvm::StringRef Code, size_t Offset);
|
|
|
|
/// Turn a SourceLocation into a [line, column] pair.
|
|
/// FIXME: This should return an error if the location is invalid.
|
|
Position sourceLocToPosition(const SourceManager &SM, SourceLocation Loc);
|
|
|
|
// Converts a half-open clang source range to an LSP range.
|
|
// Note that clang also uses closed source ranges, which this can't handle!
|
|
Range halfOpenToRange(const SourceManager &SM, CharSourceRange R);
|
|
|
|
// Converts an offset to a clang line/column (1-based, columns are bytes).
|
|
// The offset must be in range [0, Code.size()].
|
|
// Prefer to use SourceManager if one is available.
|
|
std::pair<size_t, size_t> offsetToClangLineColumn(llvm::StringRef Code,
|
|
size_t Offset);
|
|
|
|
/// From "a::b::c", return {"a::b::", "c"}. Scope is empty if there's no
|
|
/// qualifier.
|
|
std::pair<llvm::StringRef, llvm::StringRef>
|
|
splitQualifiedName(llvm::StringRef QName);
|
|
|
|
TextEdit replacementToEdit(StringRef Code, const tooling::Replacement &R);
|
|
|
|
std::vector<TextEdit> replacementsToEdits(StringRef Code,
|
|
const tooling::Replacements &Repls);
|
|
|
|
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
|