forked from OSchip/llvm-project
116 lines
3.4 KiB
C++
116 lines
3.4 KiB
C++
//===--- Relation.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_RELATION_H
|
|
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_RELATION_H
|
|
|
|
#include "SymbolID.h"
|
|
#include "SymbolLocation.h"
|
|
#include "clang/Index/IndexSymbol.h"
|
|
#include "llvm/ADT/iterator_range.h"
|
|
#include <cstdint>
|
|
#include <utility>
|
|
|
|
namespace clang {
|
|
namespace clangd {
|
|
|
|
/// Represents a relation between two symbols.
|
|
/// For an example "A is a base class of B" may be represented
|
|
/// as { Subject = A, Predicate = RelationBaseOf, Object = B }.
|
|
struct Relation {
|
|
SymbolID Subject;
|
|
index::SymbolRole Predicate;
|
|
SymbolID Object;
|
|
|
|
bool operator==(const Relation &Other) const {
|
|
return std::tie(Subject, Predicate, Object) ==
|
|
std::tie(Other.Subject, Other.Predicate, Other.Object);
|
|
}
|
|
// SPO order
|
|
bool operator<(const Relation &Other) const {
|
|
return std::tie(Subject, Predicate, Object) <
|
|
std::tie(Other.Subject, Other.Predicate, Other.Object);
|
|
}
|
|
};
|
|
|
|
class RelationSlab {
|
|
public:
|
|
using value_type = Relation;
|
|
using const_iterator = std::vector<value_type>::const_iterator;
|
|
using iterator = const_iterator;
|
|
|
|
RelationSlab() = default;
|
|
RelationSlab(RelationSlab &&Slab) = default;
|
|
RelationSlab &operator=(RelationSlab &&RHS) = default;
|
|
|
|
const_iterator begin() const { return Relations.begin(); }
|
|
const_iterator end() const { return Relations.end(); }
|
|
size_t size() const { return Relations.size(); }
|
|
bool empty() const { return Relations.empty(); }
|
|
|
|
size_t bytes() const {
|
|
return sizeof(*this) + sizeof(value_type) * Relations.capacity();
|
|
}
|
|
|
|
/// Lookup all relations matching the given subject and predicate.
|
|
llvm::iterator_range<iterator> lookup(const SymbolID &Subject,
|
|
index::SymbolRole Predicate) const;
|
|
|
|
/// RelationSlab::Builder is a mutable container that can 'freeze' to
|
|
/// RelationSlab.
|
|
class Builder {
|
|
public:
|
|
/// Adds a relation to the slab.
|
|
void insert(const Relation &R) { Relations.push_back(R); }
|
|
|
|
/// Consumes the builder to finalize the slab.
|
|
RelationSlab build() &&;
|
|
|
|
private:
|
|
std::vector<Relation> Relations;
|
|
};
|
|
|
|
private:
|
|
RelationSlab(std::vector<Relation> Relations)
|
|
: Relations(std::move(Relations)) {}
|
|
|
|
std::vector<Relation> Relations;
|
|
};
|
|
|
|
} // namespace clangd
|
|
} // namespace clang
|
|
|
|
namespace llvm {
|
|
|
|
// Support index::SymbolRole as a DenseMap key for the purpose of looking up
|
|
// relations.
|
|
template <> struct DenseMapInfo<clang::index::SymbolRole> {
|
|
static inline clang::index::SymbolRole getEmptyKey() {
|
|
// Choose an enumerator that's not a relation.
|
|
return clang::index::SymbolRole::Declaration;
|
|
}
|
|
|
|
static inline clang::index::SymbolRole getTombstoneKey() {
|
|
// Choose another enumerator that's not a relation.
|
|
return clang::index::SymbolRole::Definition;
|
|
}
|
|
|
|
static unsigned getHashValue(const clang::index::SymbolRole &Key) {
|
|
return hash_value(Key);
|
|
}
|
|
|
|
static bool isEqual(const clang::index::SymbolRole &LHS,
|
|
const clang::index::SymbolRole &RHS) {
|
|
return LHS == RHS;
|
|
}
|
|
};
|
|
|
|
} // namespace llvm
|
|
|
|
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_RELATION_H
|