143 lines
4.0 KiB
C++
143 lines
4.0 KiB
C++
#pragma once
|
|
|
|
#include <bitset>
|
|
#include <cstdint>
|
|
#include <deque>
|
|
#include <vector>
|
|
|
|
#include "llvm/ADT/DenseSet.h"
|
|
#include "llvm/ADT/StringMap.h"
|
|
#include "llvm/ADT/BitVector.h"
|
|
|
|
namespace clice::index {
|
|
|
|
struct Contextual {
|
|
/// The actual element id,
|
|
std::uint32_t element_id;
|
|
|
|
constexpr inline static std::uint32_t FLAG = (1ull << 31);
|
|
|
|
static Contextual from(bool is_dependent, std::uint32_t offset) {
|
|
Contextual ctx;
|
|
ctx.element_id = offset;
|
|
if(!is_dependent) {
|
|
ctx.element_id |= FLAG;
|
|
}
|
|
return ctx;
|
|
}
|
|
|
|
bool is_dependent() {
|
|
return (element_id & FLAG) == 0;
|
|
}
|
|
|
|
std::uint32_t offset() {
|
|
return element_id & ~FLAG;
|
|
}
|
|
};
|
|
|
|
/// A header context could be represented by file:include.
|
|
/// In the following context, hctx means "header context" and cctx means
|
|
/// "canonical context". So hcid is header context id and ccid is
|
|
/// canonical context id.
|
|
class Contexts {
|
|
public:
|
|
std::uint32_t file_count() {
|
|
return header_contexts.size();
|
|
}
|
|
|
|
/// The count of active header contexts in this index.
|
|
std::uint32_t header_context_count() {
|
|
return max_hctx_id - erased_hctx_ids.size();
|
|
}
|
|
|
|
/// The count of active canonical contexts in this index.
|
|
std::uint32_t canonical_context_count() {
|
|
return max_cctx_id - erased_cctx_ids.size();
|
|
}
|
|
|
|
/// Whether this contexts has only one single context.
|
|
bool is_single_header_context() {
|
|
return max_hctx_id == 1 && erased_hctx_ids.empty();
|
|
}
|
|
|
|
auto erased_flag() {
|
|
Bitmap map;
|
|
map.set();
|
|
for(auto cctx_id: erased_cctx_ids) {
|
|
map.reset(cctx_id);
|
|
}
|
|
return map;
|
|
}
|
|
|
|
|
|
|
|
/// Get a new header context id.
|
|
std::uint32_t alloc_hctx_id();
|
|
|
|
/// Get a new canonical context id.
|
|
std::uint32_t alloc_cctx_id();
|
|
|
|
std::uint32_t alloc_dependent_elem_id() {
|
|
auto id = dependent_elem_states.size();
|
|
dependent_elem_states.emplace_back(false);
|
|
return id;
|
|
}
|
|
|
|
std::uint32_t alloc_independent_elem_id() {
|
|
auto id = independent_elem_states.size();
|
|
independent_elem_states.emplace_back();
|
|
return id;
|
|
}
|
|
|
|
void remove(this Contexts& self, llvm::StringRef path);
|
|
|
|
public:
|
|
/// The max header context id.
|
|
std::uint32_t max_hctx_id = 0;
|
|
|
|
/// The max canonical context id.
|
|
std::uint32_t max_cctx_id = 0;
|
|
|
|
/// The erased header context id. if a header context is erased,
|
|
/// we add its id for later reusing.
|
|
std::deque<std::uint32_t> erased_hctx_ids;
|
|
|
|
/// Same as above but for canonical context id.
|
|
std::deque<std::uint32_t> erased_cctx_ids;
|
|
|
|
struct HeaderContext {
|
|
/// The include location id of this header context.
|
|
std::uint32_t include;
|
|
|
|
/// The header context id of this header context.
|
|
std::uint32_t hctx_id;
|
|
|
|
/// The canonical context id of this header context.
|
|
std::uint32_t cctx_id;
|
|
};
|
|
|
|
/// A map between source file path and its header contexts.
|
|
llvm::StringMap<llvm::SmallVector<HeaderContext>> header_contexts;
|
|
|
|
/// A map between canonical context id and corresponding ref counts
|
|
/// referenced by header contexts.
|
|
llvm::SmallVector<std::uint32_t> cctx_hctx_refs;
|
|
|
|
/// A map between canonical context id and corresponding ref counts
|
|
/// referenced by contextual elements.
|
|
llvm::SmallVector<std::uint32_t> cctx_element_refs;
|
|
|
|
using Bitmap = std::bitset<64>; /// use llvm::BitVector?
|
|
|
|
/// A map between dependent element id and its state, for dependent element
|
|
/// we use bitmap to store states. Each bit in bitmap represents whether
|
|
/// this element occurs in corresponding canonical context id.
|
|
llvm::SmallVector<Bitmap> dependent_elem_states;
|
|
|
|
/// A map between independent element id and its state, for independent element
|
|
/// we directly store the header context ids that it occurs in.
|
|
std::vector<llvm::DenseSet<std::uint32_t>> independent_elem_states;
|
|
};
|
|
|
|
} // namespace clice::index
|