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 for (auto create_callback : PluginManager::GetTypeSystemCreateCallbacks()) {
45 if (auto type_system_sp = create_callback(language, module, target))
46 return type_system_sp;
47 }
48 return {};
49}
50
52 Module *module) {
53 return CreateInstanceHelper(language, module, nullptr);
54}
55
57 Target *target) {
58 return CreateInstanceHelper(language, nullptr, target);
59}
60
61#ifndef NDEBUG
63#endif
64
68
73
78
83
87
91
96
101
106
108 const char *name,
109 const CompilerDeclContext &decl_ctx,
110 uint32_t opaque_payload) {
111 return CompilerType();
112}
113
117
119 return CompilerType(weak_from_this(), type);
120}
121
125
126llvm::Expected<CompilerType>
128 ExecutionContextScope *exe_scope) {
129 return llvm::createStringError(
130 "Integral promotion is not implemented for this TypeSystem");
131}
132
136
138 bool expand_pack) {
139 return 0;
140}
141
144 bool expand_pack) {
146}
147
149 size_t idx, bool expand_pack) {
150 return CompilerType();
151}
152
153std::optional<CompilerType::IntegralTemplateArgument>
155 bool expand_pack) {
156 return std::nullopt;
157}
158
162
164 return false;
165}
166
168 return GetTypeName(type, false);
169}
170
172 return ConstString();
173}
174
178
182
183size_t TypeSystem::DeclGetFunctionNumArguments(void *opaque_decl) { return 0; }
184
186 size_t arg_idx) {
187 return CompilerType();
188}
189
190std::vector<lldb_private::CompilerContext>
192 return {};
193}
194
195std::vector<lldb_private::CompilerContext>
197 return {};
198}
199
200std::vector<CompilerDecl>
202 bool ignore_imported_decls) {
203 return std::vector<CompilerDecl>();
204}
205
206std::unique_ptr<UtilityFunction>
207TypeSystem::CreateUtilityFunction(std::string text, std::string name) {
208 return {};
209}
210
211std::optional<llvm::json::Value> TypeSystem::ReportStatistics() {
212 return std::nullopt;
213}
214
219
220#pragma mark TypeSystemMap
221
223
225
227 collection map;
228 {
229 std::lock_guard<std::mutex> guard(m_mutex);
230 map = m_map;
231 m_clear_in_progress = true;
232 }
233 llvm::DenseSet<TypeSystem *> visited;
234 for (auto &pair : map) {
235 if (visited.count(pair.second.get()))
236 continue;
237 visited.insert(pair.second.get());
238 if (lldb::TypeSystemSP type_system = pair.second)
239 type_system->Finalize();
240 }
241 map.clear();
242 {
243 std::lock_guard<std::mutex> guard(m_mutex);
244 m_map.clear();
245 m_clear_in_progress = false;
246 }
247}
248
250 std::function<bool(lldb::TypeSystemSP)> const &callback) {
251
252 // The callback may call into this function again causing
253 // us to lock m_mutex twice if we held it across the callback.
254 // Since we just care about guarding access to 'm_map', make
255 // a local copy and iterate over that instead.
256 collection map_snapshot;
257 {
258 std::lock_guard<std::mutex> guard(m_mutex);
259 map_snapshot = m_map;
260 }
261
262 // Use a std::set so we only call the callback once for each unique
263 // TypeSystem instance.
264 llvm::DenseSet<TypeSystem *> visited;
265 for (auto &pair : map_snapshot) {
266 TypeSystem *type_system = pair.second.get();
267 if (!type_system || visited.count(type_system))
268 continue;
269 visited.insert(type_system);
270 assert(type_system);
271 if (!callback(pair.second))
272 break;
273 }
274}
275
276llvm::Expected<lldb::TypeSystemSP> TypeSystemMap::GetTypeSystemForLanguage(
277 lldb::LanguageType language,
278 std::optional<CreateCallback> create_callback) {
279 std::lock_guard<std::mutex> guard(m_mutex);
281 return llvm::createStringError(
282 "Unable to get TypeSystem because TypeSystemMap is being cleared");
283
284 collection::iterator pos = m_map.find(language);
285 if (pos != m_map.end()) {
286 if (pos->second) {
287 assert(!pos->second->weak_from_this().expired());
288 return pos->second;
289 }
290 return llvm::createStringError(
291 "TypeSystem for language " +
292 llvm::StringRef(Language::GetNameForLanguageType(language)) +
293 " doesn't exist");
294 }
295
296 for (const auto &pair : m_map) {
297 if (pair.second && pair.second->SupportsLanguage(language)) {
298 // Add a new mapping for "language" to point to an already existing
299 // TypeSystem that supports this language
300 m_map[language] = pair.second;
301 if (pair.second)
302 return pair.second;
303 return llvm::createStringError(
304 "TypeSystem for language " +
305 llvm::StringRef(Language::GetNameForLanguageType(language)) +
306 " doesn't exist");
307 }
308 }
309
310 if (!create_callback)
311 return llvm::createStringError(
312 "Unable to find type system for language " +
313 llvm::StringRef(Language::GetNameForLanguageType(language)));
314 // Cache even if we get a shared pointer that contains a null type system
315 // back.
316 TypeSystemSP type_system_sp = (*create_callback)();
317 m_map[language] = type_system_sp;
318 if (type_system_sp)
319 return type_system_sp;
320 return llvm::createStringError(
321 "TypeSystem for language " +
322 llvm::StringRef(Language::GetNameForLanguageType(language)) +
323 " doesn't exist");
324}
325
326llvm::Expected<lldb::TypeSystemSP>
328 Module *module, bool can_create) {
329 if (can_create) {
331 language, std::optional<CreateCallback>([language, module]() {
332 return TypeSystem::CreateInstance(language, module);
333 }));
334 }
335 return GetTypeSystemForLanguage(language);
336}
337
338llvm::Expected<lldb::TypeSystemSP>
340 Target *target, bool can_create) {
341 if (can_create) {
343 language, std::optional<CreateCallback>([language, target]() {
344 return TypeSystem::CreateInstance(language, target);
345 }));
346 }
347 return GetTypeSystemForLanguage(language);
348}
349
351 if (language == eLanguageTypeUnknown || language >= eNumLanguageTypes)
352 return false;
353
354 LanguageSet languages =
356 if (languages.Empty())
357 return false;
358 return languages[language];
359}
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...
static TypeSystemSP CreateInstanceHelper(lldb::LanguageType language, Module *module, Target *target)
Represents a generic declaration context in a program.
Generic representation of a type in a programming language.
A uniqued constant string class.
Definition ConstString.h:40
"lldb/Target/ExecutionContextScope.h" Inherit from this if your object can reconstruct its execution ...
static const char * GetNameForLanguageType(lldb::LanguageType language)
Returns the internal LLDB name for the specified language.
Definition Language.cpp:305
A class that describes an executable image and its associated object and symbol files.
Definition Module.h:90
static llvm::SmallVector< TypeSystemCreateInstance > GetTypeSystemCreateCallbacks()
static LanguageSet GetAllTypeSystemSupportedLanguagesForTypes()
llvm::DenseMap< uint16_t, lldb::TypeSystemSP > collection
Definition TypeSystem.h:597
std::mutex m_mutex
A mutex to keep this object happy in multi-threaded environments.
Definition TypeSystem.h:598
llvm::Expected< lldb::TypeSystemSP > GetTypeSystemForLanguage(lldb::LanguageType language, Module *module, bool can_create)
void ForEach(std::function< bool(lldb::TypeSystemSP)> const &callback)
Interface for representing a type system.
Definition TypeSystem.h:70
virtual std::unique_ptr< UtilityFunction > CreateUtilityFunction(std::string text, std::string name)
virtual bool IsMeaninglessWithoutDynamicResolution(void *type)
virtual size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type, bool expand_pack)
virtual CompilerType GetBuiltinTypeByName(ConstString name)
virtual CompilerType GetTypeTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx, bool expand_pack)
virtual CompilerType GetTypeForFormatters(void *type)
virtual CompilerType AddRestrictModifier(lldb::opaque_compiler_type_t type)
virtual CompilerType GetAtomicType(lldb::opaque_compiler_type_t type)
virtual ConstString GetMangledTypeName(lldb::opaque_compiler_type_t type)
Defaults to GetTypeName(type).
virtual CompilerType GetLValueReferenceType(lldb::opaque_compiler_type_t type)
virtual std::vector< CompilerDecl > DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name, const bool ignore_imported_decls)
virtual ConstString GetTypeName(lldb::opaque_compiler_type_t type, bool BaseOnly)=0
virtual bool IsPromotableIntegerType(lldb::opaque_compiler_type_t type)
Checks if the type is eligible for integral promotion.
virtual std::optional< llvm::json::Value > ReportStatistics()
virtual CompilerType CreateTypedef(lldb::opaque_compiler_type_t type, const char *name, const CompilerDeclContext &decl_ctx, uint32_t opaque_payload)
virtual LazyBool ShouldPrintAsOneLiner(void *type, ValueObject *valobj)
virtual llvm::Expected< CompilerType > DoIntegralPromotion(CompilerType from, ExecutionContextScope *exe_scope)
Perform integral promotion on a given type.
virtual CompilerType AddConstModifier(lldb::opaque_compiler_type_t type)
virtual CompilerType AddPtrAuthModifier(lldb::opaque_compiler_type_t type, uint32_t payload)
virtual CompilerType DeclGetFunctionReturnType(void *opaque_decl)
virtual CompilerType DeclGetFunctionArgumentType(void *opaque_decl, size_t arg_idx)
virtual CompilerType GetRValueReferenceType(lldb::opaque_compiler_type_t type)
virtual std::vector< lldb_private::CompilerContext > DeclGetCompilerContext(void *opaque_decl)
virtual std::vector< lldb_private::CompilerContext > DeclContextGetCompilerContext(void *opaque_decl_ctx)
virtual bool IsAnonymousType(lldb::opaque_compiler_type_t type)
virtual ConstString DeclGetMangledName(void *opaque_decl)
virtual CompilerType GetArrayType(lldb::opaque_compiler_type_t type, uint64_t size)
static bool SupportsLanguageStatic(lldb::LanguageType language)
virtual CompilerDeclContext GetCompilerDeclContextForType(const CompilerType &type)
Returns the direct parent context of specified type.
virtual std::optional< CompilerType::IntegralTemplateArgument > GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx, bool expand_pack)
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 ...
virtual lldb::TemplateArgumentKind GetTemplateArgumentKind(lldb::opaque_compiler_type_t type, size_t idx, bool expand_pack)
static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language, Module *module)
virtual bool IsTemplateType(lldb::opaque_compiler_type_t type)
virtual size_t DeclGetFunctionNumArguments(void *opaque_decl)
virtual CompilerDeclContext DeclGetDeclContext(void *opaque_decl)
virtual CompilerType AddVolatileModifier(lldb::opaque_compiler_type_t type)
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::TypeSystem > TypeSystemSP
void * opaque_compiler_type_t
Definition lldb-types.h:90
LanguageType
Programming language type.
@ eLanguageTypeUnknown
Unknown or invalid language value.
@ eTemplateArgumentKindNull
A SmallBitVector that represents a set of source languages (lldb::LanguageType).
Definition Type.h:38
llvm::SmallBitVector bitvector
Definition Type.h:39
std::optional< lldb::LanguageType > GetSingularLanguage()
If the set contains a single language only, return it.
bool operator[](unsigned i) const
void Insert(lldb::LanguageType language)