-
Notifications
You must be signed in to change notification settings - Fork 171
/
Copy pathcpp_entity_index.cpp
88 lines (77 loc) · 3.21 KB
/
cpp_entity_index.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// Copyright (C) 2017-2023 Jonathan Müller and cppast contributors
// SPDX-License-Identifier: MIT
#include <cppast/cpp_entity_index.hpp>
#include <cppast/cpp_entity.hpp>
#include <cppast/cpp_entity_kind.hpp>
#include <cppast/cpp_file.hpp>
#include <cppast/detail/assert.hpp>
using namespace cppast;
cpp_entity_index::duplicate_definition_error::duplicate_definition_error()
: std::logic_error("duplicate registration of entity definition")
{}
void cpp_entity_index::register_definition(cpp_entity_id id,
type_safe::object_ref<const cpp_entity> entity) const
{
DEBUG_ASSERT(entity->kind() != cpp_entity_kind::namespace_t,
detail::precondition_error_handler{}, "must not be a namespace");
std::lock_guard<std::mutex> lock(mutex_);
auto result = map_.emplace(std::move(id), value(entity, true));
if (!result.second)
{
// already in map, override declaration
auto& value = result.first->second;
if (value.is_definition && !is_template(value.entity->kind()) && entity->parent()
&& !is_template(entity->parent().value().kind()))
// allow duplicate definition of templates
// this handles things such as SFINAE
throw duplicate_definition_error();
value.is_definition = true;
value.entity = entity;
}
}
bool cpp_entity_index::register_file(cpp_entity_id id,
type_safe::object_ref<const cpp_file> file) const
{
std::lock_guard<std::mutex> lock(mutex_);
return map_.emplace(std::move(id), value(file, true)).second;
}
void cpp_entity_index::register_forward_declaration(
cpp_entity_id id, type_safe::object_ref<const cpp_entity> entity) const
{
std::lock_guard<std::mutex> lock(mutex_);
map_.emplace(std::move(id), value(entity, false));
}
void cpp_entity_index::register_namespace(cpp_entity_id id,
type_safe::object_ref<const cpp_namespace> ns) const
{
std::lock_guard<std::mutex> lock(mutex_);
ns_[std::move(id)].push_back(ns);
}
type_safe::optional_ref<const cpp_entity> cpp_entity_index::lookup(
const cpp_entity_id& id) const noexcept
{
std::lock_guard<std::mutex> lock(mutex_);
auto iter = map_.find(id);
if (iter == map_.end())
return {};
return type_safe::ref(iter->second.entity.get());
}
type_safe::optional_ref<const cpp_entity> cpp_entity_index::lookup_definition(
const cpp_entity_id& id) const noexcept
{
std::lock_guard<std::mutex> lock(mutex_);
auto iter = map_.find(id);
if (iter == map_.end() || !iter->second.is_definition)
return {};
return type_safe::ref(iter->second.entity.get());
}
auto cpp_entity_index::lookup_namespace(const cpp_entity_id& id) const noexcept
-> type_safe::array_ref<type_safe::object_ref<const cpp_namespace>>
{
std::lock_guard<std::mutex> lock(mutex_);
auto iter = ns_.find(id);
if (iter == ns_.end())
return nullptr;
auto& vec = iter->second;
return type_safe::ref(vec.data(), vec.size());
}