mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-14 11:39:35 +00:00
Moved Ref into its own header and implementation file
Reviewers: ioeric Subscribers: mgorny, jkorous, mgrang, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58778 llvm-svn: 355090
This commit is contained in:
parent
58724a61ac
commit
cb83ea6274
@ -13,9 +13,10 @@
|
||||
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_AST_H_
|
||||
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_AST_H_
|
||||
|
||||
#include "index/Index.h"
|
||||
#include "index/SymbolID.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "clang/Lex/MacroInfo.h"
|
||||
|
||||
namespace clang {
|
||||
class SourceManager;
|
||||
|
@ -62,6 +62,7 @@ add_clang_library(clangDaemon
|
||||
index/IndexAction.cpp
|
||||
index/MemIndex.cpp
|
||||
index/Merge.cpp
|
||||
index/Ref.cpp
|
||||
index/Serialization.cpp
|
||||
index/Symbol.cpp
|
||||
index/SymbolCollector.cpp
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "clang/Basic/TokenKinds.h"
|
||||
#include "clang/Lex/Lexer.h"
|
||||
#include "clang/Sema/DeclSpec.h"
|
||||
#include "clang/Sema/Lookup.h"
|
||||
#include "clang/Sema/Scope.h"
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include "Protocol.h"
|
||||
#include "Logger.h"
|
||||
#include "URI.h"
|
||||
#include "index/Index.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "llvm/ADT/Hashing.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
|
@ -5,11 +5,12 @@
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Quality.h"
|
||||
#include "AST.h"
|
||||
#include "FileDistance.h"
|
||||
#include "URI.h"
|
||||
#include "index/Index.h"
|
||||
#include "index/Symbol.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
|
@ -12,57 +12,11 @@
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <limits>
|
||||
|
||||
namespace clang {
|
||||
namespace clangd {
|
||||
|
||||
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, RefKind K) {
|
||||
if (K == RefKind::Unknown)
|
||||
return OS << "Unknown";
|
||||
static const std::vector<const char *> Messages = {"Decl", "Def", "Ref"};
|
||||
bool VisitedOnce = false;
|
||||
for (unsigned I = 0; I < Messages.size(); ++I) {
|
||||
if (static_cast<uint8_t>(K) & 1u << I) {
|
||||
if (VisitedOnce)
|
||||
OS << ", ";
|
||||
OS << Messages[I];
|
||||
VisitedOnce = true;
|
||||
}
|
||||
}
|
||||
return OS;
|
||||
}
|
||||
|
||||
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Ref &R) {
|
||||
return OS << R.Location << ":" << R.Kind;
|
||||
}
|
||||
|
||||
void RefSlab::Builder::insert(const SymbolID &ID, const Ref &S) {
|
||||
auto &M = Refs[ID];
|
||||
M.push_back(S);
|
||||
M.back().Location.FileURI =
|
||||
UniqueStrings.save(M.back().Location.FileURI).data();
|
||||
}
|
||||
|
||||
RefSlab RefSlab::Builder::build() && {
|
||||
// We can reuse the arena, as it only has unique strings and we need them all.
|
||||
// Reallocate refs on the arena to reduce waste and indirections when reading.
|
||||
std::vector<std::pair<SymbolID, llvm::ArrayRef<Ref>>> Result;
|
||||
Result.reserve(Refs.size());
|
||||
size_t NumRefs = 0;
|
||||
for (auto &Sym : Refs) {
|
||||
auto &SymRefs = Sym.second;
|
||||
llvm::sort(SymRefs);
|
||||
// FIXME: do we really need to dedup?
|
||||
SymRefs.erase(std::unique(SymRefs.begin(), SymRefs.end()), SymRefs.end());
|
||||
|
||||
NumRefs += SymRefs.size();
|
||||
auto *Array = Arena.Allocate<Ref>(SymRefs.size());
|
||||
std::uninitialized_copy(SymRefs.begin(), SymRefs.end(), Array);
|
||||
Result.emplace_back(Sym.first, llvm::ArrayRef<Ref>(Array, SymRefs.size()));
|
||||
}
|
||||
return RefSlab(std::move(Result), std::move(Arena), NumRefs);
|
||||
}
|
||||
|
||||
void SwapIndex::reset(std::unique_ptr<SymbolIndex> Index) {
|
||||
// Keep the old index alive, so we don't destroy it under lock (may be slow).
|
||||
std::shared_ptr<SymbolIndex> Pin;
|
||||
|
@ -9,116 +9,19 @@
|
||||
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_INDEX_H
|
||||
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_INDEX_H
|
||||
|
||||
#include "ExpectedTypes.h"
|
||||
#include "Ref.h"
|
||||
#include "Symbol.h"
|
||||
#include "SymbolID.h"
|
||||
#include "SymbolLocation.h"
|
||||
#include "clang/Index/IndexSymbol.h"
|
||||
#include "clang/Lex/Lexer.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/JSON.h"
|
||||
#include <array>
|
||||
#include <limits>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
namespace clang {
|
||||
namespace clangd {
|
||||
|
||||
// Describes the kind of a cross-reference.
|
||||
//
|
||||
// This is a bitfield which can be combined from different kinds.
|
||||
enum class RefKind : uint8_t {
|
||||
Unknown = 0,
|
||||
Declaration = static_cast<uint8_t>(index::SymbolRole::Declaration),
|
||||
Definition = static_cast<uint8_t>(index::SymbolRole::Definition),
|
||||
Reference = static_cast<uint8_t>(index::SymbolRole::Reference),
|
||||
All = Declaration | Definition | Reference,
|
||||
};
|
||||
inline RefKind operator|(RefKind L, RefKind R) {
|
||||
return static_cast<RefKind>(static_cast<uint8_t>(L) |
|
||||
static_cast<uint8_t>(R));
|
||||
}
|
||||
inline RefKind &operator|=(RefKind &L, RefKind R) { return L = L | R; }
|
||||
inline RefKind operator&(RefKind A, RefKind B) {
|
||||
return static_cast<RefKind>(static_cast<uint8_t>(A) &
|
||||
static_cast<uint8_t>(B));
|
||||
}
|
||||
llvm::raw_ostream &operator<<(llvm::raw_ostream &, RefKind);
|
||||
|
||||
// Represents a symbol occurrence in the source file.
|
||||
// Despite the name, it could be a declaration/definition/reference.
|
||||
//
|
||||
// WARNING: Location does not own the underlying data - Copies are shallow.
|
||||
struct Ref {
|
||||
// The source location where the symbol is named.
|
||||
SymbolLocation Location;
|
||||
RefKind Kind = RefKind::Unknown;
|
||||
};
|
||||
inline bool operator<(const Ref &L, const Ref &R) {
|
||||
return std::tie(L.Location, L.Kind) < std::tie(R.Location, R.Kind);
|
||||
}
|
||||
inline bool operator==(const Ref &L, const Ref &R) {
|
||||
return std::tie(L.Location, L.Kind) == std::tie(R.Location, R.Kind);
|
||||
}
|
||||
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Ref &);
|
||||
|
||||
// An efficient structure of storing large set of symbol references in memory.
|
||||
// Filenames are deduplicated.
|
||||
class RefSlab {
|
||||
public:
|
||||
using value_type = std::pair<SymbolID, llvm::ArrayRef<Ref>>;
|
||||
using const_iterator = std::vector<value_type>::const_iterator;
|
||||
using iterator = const_iterator;
|
||||
|
||||
RefSlab() = default;
|
||||
RefSlab(RefSlab &&Slab) = default;
|
||||
RefSlab &operator=(RefSlab &&RHS) = default;
|
||||
|
||||
const_iterator begin() const { return Refs.begin(); }
|
||||
const_iterator end() const { return Refs.end(); }
|
||||
/// Gets the number of symbols.
|
||||
size_t size() const { return Refs.size(); }
|
||||
size_t numRefs() const { return NumRefs; }
|
||||
bool empty() const { return Refs.empty(); }
|
||||
|
||||
size_t bytes() const {
|
||||
return sizeof(*this) + Arena.getTotalMemory() +
|
||||
sizeof(value_type) * Refs.size();
|
||||
}
|
||||
|
||||
// RefSlab::Builder is a mutable container that can 'freeze' to RefSlab.
|
||||
class Builder {
|
||||
public:
|
||||
Builder() : UniqueStrings(Arena) {}
|
||||
// Adds a ref to the slab. Deep copy: Strings will be owned by the slab.
|
||||
void insert(const SymbolID &ID, const Ref &S);
|
||||
// Consumes the builder to finalize the slab.
|
||||
RefSlab build() &&;
|
||||
|
||||
private:
|
||||
llvm::BumpPtrAllocator Arena;
|
||||
llvm::UniqueStringSaver UniqueStrings; // Contents on the arena.
|
||||
llvm::DenseMap<SymbolID, std::vector<Ref>> Refs;
|
||||
};
|
||||
|
||||
private:
|
||||
RefSlab(std::vector<value_type> Refs, llvm::BumpPtrAllocator Arena,
|
||||
size_t NumRefs)
|
||||
: Arena(std::move(Arena)), Refs(std::move(Refs)), NumRefs(NumRefs) {}
|
||||
|
||||
llvm::BumpPtrAllocator Arena;
|
||||
std::vector<value_type> Refs;
|
||||
// Number of all references.
|
||||
size_t NumRefs = 0;
|
||||
};
|
||||
|
||||
struct FuzzyFindRequest {
|
||||
/// \brief A query string for the fuzzy find. This is matched against symbols'
|
||||
/// un-qualified identifiers and should not contain qualifiers like "::".
|
||||
|
62
clang-tools-extra/clangd/index/Ref.cpp
Normal file
62
clang-tools-extra/clangd/index/Ref.cpp
Normal file
@ -0,0 +1,62 @@
|
||||
//===--- Ref.cpp -------------------------------------------------*- C++-*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Ref.h"
|
||||
|
||||
namespace clang {
|
||||
namespace clangd {
|
||||
|
||||
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, RefKind K) {
|
||||
if (K == RefKind::Unknown)
|
||||
return OS << "Unknown";
|
||||
static const std::vector<const char *> Messages = {"Decl", "Def", "Ref"};
|
||||
bool VisitedOnce = false;
|
||||
for (unsigned I = 0; I < Messages.size(); ++I) {
|
||||
if (static_cast<uint8_t>(K) & 1u << I) {
|
||||
if (VisitedOnce)
|
||||
OS << ", ";
|
||||
OS << Messages[I];
|
||||
VisitedOnce = true;
|
||||
}
|
||||
}
|
||||
return OS;
|
||||
}
|
||||
|
||||
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Ref &R) {
|
||||
return OS << R.Location << ":" << R.Kind;
|
||||
}
|
||||
|
||||
void RefSlab::Builder::insert(const SymbolID &ID, const Ref &S) {
|
||||
auto &M = Refs[ID];
|
||||
M.push_back(S);
|
||||
M.back().Location.FileURI =
|
||||
UniqueStrings.save(M.back().Location.FileURI).data();
|
||||
}
|
||||
|
||||
RefSlab RefSlab::Builder::build() && {
|
||||
// We can reuse the arena, as it only has unique strings and we need them all.
|
||||
// Reallocate refs on the arena to reduce waste and indirections when reading.
|
||||
std::vector<std::pair<SymbolID, llvm::ArrayRef<Ref>>> Result;
|
||||
Result.reserve(Refs.size());
|
||||
size_t NumRefs = 0;
|
||||
for (auto &Sym : Refs) {
|
||||
auto &SymRefs = Sym.second;
|
||||
llvm::sort(SymRefs);
|
||||
// FIXME: do we really need to dedup?
|
||||
SymRefs.erase(std::unique(SymRefs.begin(), SymRefs.end()), SymRefs.end());
|
||||
|
||||
NumRefs += SymRefs.size();
|
||||
auto *Array = Arena.Allocate<Ref>(SymRefs.size());
|
||||
std::uninitialized_copy(SymRefs.begin(), SymRefs.end(), Array);
|
||||
Result.emplace_back(Sym.first, llvm::ArrayRef<Ref>(Array, SymRefs.size()));
|
||||
}
|
||||
return RefSlab(std::move(Result), std::move(Arena), NumRefs);
|
||||
}
|
||||
|
||||
} // namespace clangd
|
||||
} // namespace clang
|
119
clang-tools-extra/clangd/index/Ref.h
Normal file
119
clang-tools-extra/clangd/index/Ref.h
Normal file
@ -0,0 +1,119 @@
|
||||
//===--- Ref.h ---------------------------------------------------*- C++-*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_REF_H
|
||||
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_REF_H
|
||||
|
||||
#include "SymbolID.h"
|
||||
#include "SymbolLocation.h"
|
||||
#include "clang/Index/IndexSymbol.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/Support/StringSaver.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
|
||||
namespace clang {
|
||||
namespace clangd {
|
||||
|
||||
/// Describes the kind of a cross-reference.
|
||||
///
|
||||
/// This is a bitfield which can be combined from different kinds.
|
||||
enum class RefKind : uint8_t {
|
||||
Unknown = 0,
|
||||
Declaration = static_cast<uint8_t>(index::SymbolRole::Declaration),
|
||||
Definition = static_cast<uint8_t>(index::SymbolRole::Definition),
|
||||
Reference = static_cast<uint8_t>(index::SymbolRole::Reference),
|
||||
All = Declaration | Definition | Reference,
|
||||
};
|
||||
|
||||
inline RefKind operator|(RefKind L, RefKind R) {
|
||||
return static_cast<RefKind>(static_cast<uint8_t>(L) |
|
||||
static_cast<uint8_t>(R));
|
||||
}
|
||||
inline RefKind &operator|=(RefKind &L, RefKind R) { return L = L | R; }
|
||||
inline RefKind operator&(RefKind A, RefKind B) {
|
||||
return static_cast<RefKind>(static_cast<uint8_t>(A) &
|
||||
static_cast<uint8_t>(B));
|
||||
}
|
||||
|
||||
llvm::raw_ostream &operator<<(llvm::raw_ostream &, RefKind);
|
||||
|
||||
/// Represents a symbol occurrence in the source file.
|
||||
/// Despite the name, it could be a declaration/definition/reference.
|
||||
///
|
||||
/// WARNING: Location does not own the underlying data - Copies are shallow.
|
||||
struct Ref {
|
||||
/// The source location where the symbol is named.
|
||||
SymbolLocation Location;
|
||||
RefKind Kind = RefKind::Unknown;
|
||||
};
|
||||
|
||||
inline bool operator<(const Ref &L, const Ref &R) {
|
||||
return std::tie(L.Location, L.Kind) < std::tie(R.Location, R.Kind);
|
||||
}
|
||||
inline bool operator==(const Ref &L, const Ref &R) {
|
||||
return std::tie(L.Location, L.Kind) == std::tie(R.Location, R.Kind);
|
||||
}
|
||||
|
||||
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Ref &);
|
||||
|
||||
/// An efficient structure of storing large set of symbol references in memory.
|
||||
/// Filenames are deduplicated.
|
||||
class RefSlab {
|
||||
public:
|
||||
using value_type = std::pair<SymbolID, llvm::ArrayRef<Ref>>;
|
||||
using const_iterator = std::vector<value_type>::const_iterator;
|
||||
using iterator = const_iterator;
|
||||
|
||||
RefSlab() = default;
|
||||
RefSlab(RefSlab &&Slab) = default;
|
||||
RefSlab &operator=(RefSlab &&RHS) = default;
|
||||
|
||||
const_iterator begin() const { return Refs.begin(); }
|
||||
const_iterator end() const { return Refs.end(); }
|
||||
/// Gets the number of symbols.
|
||||
size_t size() const { return Refs.size(); }
|
||||
size_t numRefs() const { return NumRefs; }
|
||||
bool empty() const { return Refs.empty(); }
|
||||
|
||||
size_t bytes() const {
|
||||
return sizeof(*this) + Arena.getTotalMemory() +
|
||||
sizeof(value_type) * Refs.size();
|
||||
}
|
||||
|
||||
/// RefSlab::Builder is a mutable container that can 'freeze' to RefSlab.
|
||||
class Builder {
|
||||
public:
|
||||
Builder() : UniqueStrings(Arena) {}
|
||||
/// Adds a ref to the slab. Deep copy: Strings will be owned by the slab.
|
||||
void insert(const SymbolID &ID, const Ref &S);
|
||||
/// Consumes the builder to finalize the slab.
|
||||
RefSlab build() &&;
|
||||
|
||||
private:
|
||||
llvm::BumpPtrAllocator Arena;
|
||||
llvm::UniqueStringSaver UniqueStrings; // Contents on the arena.
|
||||
llvm::DenseMap<SymbolID, std::vector<Ref>> Refs;
|
||||
};
|
||||
|
||||
private:
|
||||
RefSlab(std::vector<value_type> Refs, llvm::BumpPtrAllocator Arena,
|
||||
size_t NumRefs)
|
||||
: Arena(std::move(Arena)), Refs(std::move(Refs)), NumRefs(NumRefs) {}
|
||||
|
||||
llvm::BumpPtrAllocator Arena;
|
||||
std::vector<value_type> Refs;
|
||||
/// Number of all references.
|
||||
size_t NumRefs = 0;
|
||||
};
|
||||
|
||||
} // namespace clangd
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_REF_H
|
@ -11,6 +11,7 @@
|
||||
#include "CanonicalIncludes.h"
|
||||
#include "CodeComplete.h"
|
||||
#include "CodeCompletionStrings.h"
|
||||
#include "ExpectedTypes.h"
|
||||
#include "Logger.h"
|
||||
#include "SourceCode.h"
|
||||
#include "SymbolLocation.h"
|
||||
|
@ -10,10 +10,11 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "index/Index.h"
|
||||
#include "index/IndexAction.h"
|
||||
#include "index/Merge.h"
|
||||
#include "index/Ref.h"
|
||||
#include "index/Serialization.h"
|
||||
#include "index/Symbol.h"
|
||||
#include "index/SymbolCollector.h"
|
||||
#include "clang/Tooling/CommonOptionsParser.h"
|
||||
#include "clang/Tooling/Execution.h"
|
||||
|
Loading…
Reference in New Issue
Block a user