LLDB mainline
TypeSystem.cpp
Go to the documentation of this file.
1//===-- TypeSystem.cpp ----------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
14
15#include "llvm/ADT/DenseSet.h"
16#include <optional>
17
18using namespace lldb_private;
19using namespace lldb;
20
21/// A 64-bit SmallBitVector is only small up to 64-7 bits, and the
22/// setBitsInMask interface wants to write full bytes.
23static const size_t g_num_small_bitvector_bits = 64 - 8;
25 "Languages bit vector is no longer small on 64 bit systems");
27
28std::optional<LanguageType> LanguageSet::GetSingularLanguage() {
29 if (bitvector.count() == 1)
30 return (LanguageType)bitvector.find_first();
31 return {};
32}
33
34void LanguageSet::Insert(LanguageType language) { bitvector.set(language); }
35size_t LanguageSet::Size() const { return bitvector.count(); }
36bool LanguageSet::Empty() const { return bitvector.none(); }
37bool LanguageSet::operator[](unsigned i) const { return bitvector[i]; }
38
39TypeSystem::TypeSystem() = default;
40TypeSystem::~TypeSystem() = default;
41
43 Module *module, Target *target) {
44 uint32_t i = 0;
45 TypeSystemCreateInstance create_callback;
47 i++)) != nullptr) {
48 if (auto type_system_sp = create_callback(language, module, target))
49 return type_system_sp;
50 }
51
52 return {};
53}
54
56 Module *module) {
57 return CreateInstanceHelper(language, module, nullptr);
58}
59
61 Target *target) {
62 return CreateInstanceHelper(language, nullptr, target);
63}
64
65#ifndef NDEBUG
67#endif
68
70 return false;
71}
72
74 uint64_t size) {
75 return CompilerType();
76}
77
80 return CompilerType();
81}
82
85 return CompilerType();
86}
87
89 return CompilerType();
90}
91
93 return CompilerType();
94}
95
98 return CompilerType();
99}
100
103 return CompilerType();
104}
105
107 const char *name,
108 const CompilerDeclContext &decl_ctx,
109 uint32_t opaque_payload) {
110 return CompilerType();
111}
112
114 return CompilerType();
115}
116
118 return CompilerType(weak_from_this(), type);
119}
120
122 return false;
123}
124
126 bool expand_pack) {
127 return 0;
128}
129
132 bool expand_pack) {
134}
135
137 size_t idx, bool expand_pack) {
138 return CompilerType();
139}
140
141std::optional<CompilerType::IntegralTemplateArgument>
143 bool expand_pack) {
144 return std::nullopt;
145}
146
148 return eLazyBoolCalculate;
149}
150
152 return false;
153}
154
156 return ConstString();
157}
158
160 return CompilerDeclContext();
161}
162
164 return CompilerType();
165}
166
167size_t TypeSystem::DeclGetFunctionNumArguments(void *opaque_decl) { return 0; }
168
170 size_t arg_idx) {
171 return CompilerType();
172}
173
174std::vector<CompilerDecl>
176 bool ignore_imported_decls) {
177 return std::vector<CompilerDecl>();
178}
179
180std::unique_ptr<UtilityFunction>
181TypeSystem::CreateUtilityFunction(std::string text, std::string name) {
182 return {};
183}
184
185std::optional<llvm::json::Value> TypeSystem::ReportStatistics() {
186 return std::nullopt;
187}
188
189#pragma mark TypeSystemMap
190
191TypeSystemMap::TypeSystemMap() : m_mutex(), m_map() {}
192
194
196 collection map;
197 {
198 std::lock_guard<std::mutex> guard(m_mutex);
199 map = m_map;
200 m_clear_in_progress = true;
201 }
202 llvm::DenseSet<TypeSystem *> visited;
203 for (auto &pair : map) {
204 if (visited.count(pair.second.get()))
205 continue;
206 visited.insert(pair.second.get());
207 if (lldb::TypeSystemSP type_system = pair.second)
208 type_system->Finalize();
209 }
210 map.clear();
211 {
212 std::lock_guard<std::mutex> guard(m_mutex);
213 m_map.clear();
214 m_clear_in_progress = false;
215 }
216}
217
219 std::function<bool(lldb::TypeSystemSP)> const &callback) {
220
221 // The callback may call into this function again causing
222 // us to lock m_mutex twice if we held it across the callback.
223 // Since we just care about guarding access to 'm_map', make
224 // a local copy and iterate over that instead.
225 collection map_snapshot;
226 {
227 std::lock_guard<std::mutex> guard(m_mutex);
228 map_snapshot = m_map;
229 }
230
231 // Use a std::set so we only call the callback once for each unique
232 // TypeSystem instance.
233 llvm::DenseSet<TypeSystem *> visited;
234 for (auto &pair : map_snapshot) {
235 TypeSystem *type_system = pair.second.get();
236 if (!type_system || visited.count(type_system))
237 continue;
238 visited.insert(type_system);
239 assert(type_system);
240 if (!callback(pair.second))
241 break;
242 }
243}
244
245llvm::Expected<lldb::TypeSystemSP> TypeSystemMap::GetTypeSystemForLanguage(
246 lldb::LanguageType language,
247 std::optional<CreateCallback> create_callback) {
248 std::lock_guard<std::mutex> guard(m_mutex);
250 return llvm::make_error<llvm::StringError>(
251 "Unable to get TypeSystem because TypeSystemMap is being cleared",
252 llvm::inconvertibleErrorCode());
253
254 collection::iterator pos = m_map.find(language);
255 if (pos != m_map.end()) {
256 if (pos->second) {
257 assert(!pos->second->weak_from_this().expired());
258 return pos->second;
259 }
260 return llvm::make_error<llvm::StringError>(
261 "TypeSystem for language " +
262 llvm::StringRef(Language::GetNameForLanguageType(language)) +
263 " doesn't exist",
264 llvm::inconvertibleErrorCode());
265 }
266
267 for (const auto &pair : m_map) {
268 if (pair.second && pair.second->SupportsLanguage(language)) {
269 // Add a new mapping for "language" to point to an already existing
270 // TypeSystem that supports this language
271 m_map[language] = pair.second;
272 if (pair.second)
273 return pair.second;
274 return llvm::make_error<llvm::StringError>(
275 "TypeSystem for language " +
276 llvm::StringRef(Language::GetNameForLanguageType(language)) +
277 " doesn't exist",
278 llvm::inconvertibleErrorCode());
279 }
280 }
281
282 if (!create_callback)
283 return llvm::make_error<llvm::StringError>(
284 "Unable to find type system for language " +
285 llvm::StringRef(Language::GetNameForLanguageType(language)),
286 llvm::inconvertibleErrorCode());
287
288 // Cache even if we get a shared pointer that contains a null type system
289 // back.
290 TypeSystemSP type_system_sp = (*create_callback)();
291 m_map[language] = type_system_sp;
292 if (type_system_sp)
293 return type_system_sp;
294 return llvm::make_error<llvm::StringError>(
295 "TypeSystem for language " +
296 llvm::StringRef(Language::GetNameForLanguageType(language)) +
297 " doesn't exist",
298 llvm::inconvertibleErrorCode());
299}
300
301llvm::Expected<lldb::TypeSystemSP>
303 Module *module, bool can_create) {
304 if (can_create) {
306 language, std::optional<CreateCallback>([language, module]() {
307 return TypeSystem::CreateInstance(language, module);
308 }));
309 }
310 return GetTypeSystemForLanguage(language);
311}
312
313llvm::Expected<lldb::TypeSystemSP>
315 Target *target, bool can_create) {
316 if (can_create) {
318 language, std::optional<CreateCallback>([language, target]() {
319 return TypeSystem::CreateInstance(language, target);
320 }));
321 }
322 return GetTypeSystemForLanguage(language);
323}
static const size_t g_num_small_bitvector_bits
A 64-bit SmallBitVector is only small up to 64-7 bits, and the setBitsInMask interface wants to write...
Definition: TypeSystem.cpp:23
static TypeSystemSP CreateInstanceHelper(lldb::LanguageType language, Module *module, Target *target)
Definition: TypeSystem.cpp:42
Represents a generic declaration context in a program.
Generic representation of a type in a programming language.
Definition: CompilerType.h:36
A uniqued constant string class.
Definition: ConstString.h:40
static const char * GetNameForLanguageType(lldb::LanguageType language)
Definition: Language.cpp:235
A class that describes an executable image and its associated object and symbol files.
Definition: Module.h:88
static TypeSystemCreateInstance GetTypeSystemCreateCallbackAtIndex(uint32_t idx)
llvm::DenseMap< uint16_t, lldb::TypeSystemSP > collection
Definition: TypeSystem.h:559
std::mutex m_mutex
A mutex to keep this object happy in multi-threaded environments.
Definition: TypeSystem.h:560
llvm::Expected< lldb::TypeSystemSP > GetTypeSystemForLanguage(lldb::LanguageType language, Module *module, bool can_create)
Definition: TypeSystem.cpp:302
void ForEach(std::function< bool(lldb::TypeSystemSP)> const &callback)
Definition: TypeSystem.cpp:218
Interface for representing a type system.
Definition: TypeSystem.h:77
virtual std::unique_ptr< UtilityFunction > CreateUtilityFunction(std::string text, std::string name)
Definition: TypeSystem.cpp:181
virtual bool IsMeaninglessWithoutDynamicResolution(void *type)
Definition: TypeSystem.cpp:151
virtual size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type, bool expand_pack)
Definition: TypeSystem.cpp:125
virtual CompilerType GetBuiltinTypeByName(ConstString name)
Definition: TypeSystem.cpp:113
virtual CompilerType GetTypeTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx, bool expand_pack)
Definition: TypeSystem.cpp:136
virtual CompilerType GetTypeForFormatters(void *type)
Definition: TypeSystem.cpp:117
virtual CompilerType AddRestrictModifier(lldb::opaque_compiler_type_t type)
Definition: TypeSystem.cpp:102
virtual CompilerType GetAtomicType(lldb::opaque_compiler_type_t type)
Definition: TypeSystem.cpp:88
virtual CompilerType GetLValueReferenceType(lldb::opaque_compiler_type_t type)
Definition: TypeSystem.cpp:79
virtual std::vector< CompilerDecl > DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name, const bool ignore_imported_decls)
Definition: TypeSystem.cpp:175
virtual std::optional< llvm::json::Value > ReportStatistics()
Definition: TypeSystem.cpp:185
virtual CompilerType CreateTypedef(lldb::opaque_compiler_type_t type, const char *name, const CompilerDeclContext &decl_ctx, uint32_t opaque_payload)
Definition: TypeSystem.cpp:106
virtual LazyBool ShouldPrintAsOneLiner(void *type, ValueObject *valobj)
Definition: TypeSystem.cpp:147
virtual CompilerType AddConstModifier(lldb::opaque_compiler_type_t type)
Definition: TypeSystem.cpp:92
virtual CompilerType DeclGetFunctionReturnType(void *opaque_decl)
Definition: TypeSystem.cpp:163
virtual CompilerType DeclGetFunctionArgumentType(void *opaque_decl, size_t arg_idx)
Definition: TypeSystem.cpp:169
virtual CompilerType GetRValueReferenceType(lldb::opaque_compiler_type_t type)
Definition: TypeSystem.cpp:84
virtual bool IsAnonymousType(lldb::opaque_compiler_type_t type)
Definition: TypeSystem.cpp:69
virtual ConstString DeclGetMangledName(void *opaque_decl)
Definition: TypeSystem.cpp:155
virtual CompilerType GetArrayType(lldb::opaque_compiler_type_t type, uint64_t size)
Definition: TypeSystem.cpp:73
virtual std::optional< CompilerType::IntegralTemplateArgument > GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx, bool expand_pack)
Definition: TypeSystem.cpp:142
virtual bool Verify(lldb::opaque_compiler_type_t type)=0
Verify the integrity of the type to catch CompilerTypes that mix and match invalid TypeSystem/Opaque ...
Definition: TypeSystem.cpp:66
virtual lldb::TemplateArgumentKind GetTemplateArgumentKind(lldb::opaque_compiler_type_t type, size_t idx, bool expand_pack)
Definition: TypeSystem.cpp:131
static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language, Module *module)
Definition: TypeSystem.cpp:55
virtual bool IsTemplateType(lldb::opaque_compiler_type_t type)
Definition: TypeSystem.cpp:121
virtual size_t DeclGetFunctionNumArguments(void *opaque_decl)
Definition: TypeSystem.cpp:167
virtual CompilerDeclContext DeclGetDeclContext(void *opaque_decl)
Definition: TypeSystem.cpp:159
virtual CompilerType AddVolatileModifier(lldb::opaque_compiler_type_t type)
Definition: TypeSystem.cpp:97
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
Definition: SBAddress.h:15
std::shared_ptr< lldb_private::TypeSystem > TypeSystemSP
Definition: lldb-forward.h:444
void * opaque_compiler_type_t
Definition: lldb-types.h:86
LanguageType
Programming language type.
@ eNumLanguageTypes
@ eTemplateArgumentKindNull
llvm::SmallBitVector bitvector
Definition: TypeSystem.h:46
std::optional< lldb::LanguageType > GetSingularLanguage()
If the set contains a single language only, return it.
Definition: TypeSystem.cpp:28
bool operator[](unsigned i) const
Definition: TypeSystem.cpp:37
void Insert(lldb::LanguageType language)
Definition: TypeSystem.cpp:34