1 //===-- TypeSystem.cpp ----------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "lldb/Symbol/TypeSystem.h"
10 #include "lldb/Core/PluginManager.h"
11 #include "lldb/Expression/UtilityFunction.h"
12 #include "lldb/Symbol/CompilerType.h"
13 #include "lldb/Target/Language.h"
17 using namespace lldb_private
;
20 /// A 64-bit SmallBitVector is only small up to 64-7 bits, and the
21 /// setBitsInMask interface wants to write full bytes.
22 static const size_t g_num_small_bitvector_bits
= 64 - 8;
23 static_assert(eNumLanguageTypes
< g_num_small_bitvector_bits
,
24 "Languages bit vector is no longer small on 64 bit systems");
25 LanguageSet::LanguageSet() : bitvector(eNumLanguageTypes
, false) {}
27 llvm::Optional
<LanguageType
> LanguageSet::GetSingularLanguage() {
28 if (bitvector
.count() == 1)
29 return (LanguageType
)bitvector
.find_first();
33 void LanguageSet::Insert(LanguageType language
) { bitvector
.set(language
); }
34 size_t LanguageSet::Size() const { return bitvector
.count(); }
35 bool LanguageSet::Empty() const { return bitvector
.none(); }
36 bool LanguageSet::operator[](unsigned i
) const { return bitvector
[i
]; }
38 TypeSystem::~TypeSystem() = default;
40 static lldb::TypeSystemSP
CreateInstanceHelper(lldb::LanguageType language
,
41 Module
*module
, Target
*target
) {
43 TypeSystemCreateInstance create_callback
;
44 while ((create_callback
= PluginManager::GetTypeSystemCreateCallbackAtIndex(
46 lldb::TypeSystemSP type_system_sp
=
47 create_callback(language
, module
, target
);
49 return type_system_sp
;
52 return lldb::TypeSystemSP();
55 lldb::TypeSystemSP
TypeSystem::CreateInstance(lldb::LanguageType language
,
57 return CreateInstanceHelper(language
, module
, nullptr);
60 lldb::TypeSystemSP
TypeSystem::CreateInstance(lldb::LanguageType language
,
62 return CreateInstanceHelper(language
, nullptr, target
);
66 bool TypeSystem::Verify(lldb::opaque_compiler_type_t type
) { return true; }
69 bool TypeSystem::IsAnonymousType(lldb::opaque_compiler_type_t type
) {
73 CompilerType
TypeSystem::GetArrayType(lldb::opaque_compiler_type_t type
,
75 return CompilerType();
79 TypeSystem::GetLValueReferenceType(lldb::opaque_compiler_type_t type
) {
80 return CompilerType();
84 TypeSystem::GetRValueReferenceType(lldb::opaque_compiler_type_t type
) {
85 return CompilerType();
88 CompilerType
TypeSystem::GetAtomicType(lldb::opaque_compiler_type_t type
) {
89 return CompilerType();
92 CompilerType
TypeSystem::AddConstModifier(lldb::opaque_compiler_type_t type
) {
93 return CompilerType();
97 TypeSystem::AddVolatileModifier(lldb::opaque_compiler_type_t type
) {
98 return CompilerType();
102 TypeSystem::AddRestrictModifier(lldb::opaque_compiler_type_t type
) {
103 return CompilerType();
106 CompilerType
TypeSystem::CreateTypedef(lldb::opaque_compiler_type_t type
,
108 const CompilerDeclContext
&decl_ctx
,
109 uint32_t opaque_payload
) {
110 return CompilerType();
113 CompilerType
TypeSystem::GetBuiltinTypeByName(ConstString name
) {
114 return CompilerType();
117 CompilerType
TypeSystem::GetTypeForFormatters(void *type
) {
118 return CompilerType(this, type
);
121 size_t TypeSystem::GetNumTemplateArguments(lldb::opaque_compiler_type_t type
) {
126 TypeSystem::GetTemplateArgumentKind(opaque_compiler_type_t type
, size_t idx
) {
127 return eTemplateArgumentKindNull
;
130 CompilerType
TypeSystem::GetTypeTemplateArgument(opaque_compiler_type_t type
,
132 return CompilerType();
135 llvm::Optional
<CompilerType::IntegralTemplateArgument
>
136 TypeSystem::GetIntegralTemplateArgument(opaque_compiler_type_t type
,
141 LazyBool
TypeSystem::ShouldPrintAsOneLiner(void *type
, ValueObject
*valobj
) {
142 return eLazyBoolCalculate
;
145 bool TypeSystem::IsMeaninglessWithoutDynamicResolution(void *type
) {
149 ConstString
TypeSystem::DeclGetMangledName(void *opaque_decl
) {
150 return ConstString();
153 CompilerDeclContext
TypeSystem::DeclGetDeclContext(void *opaque_decl
) {
154 return CompilerDeclContext();
157 CompilerType
TypeSystem::DeclGetFunctionReturnType(void *opaque_decl
) {
158 return CompilerType();
161 size_t TypeSystem::DeclGetFunctionNumArguments(void *opaque_decl
) { return 0; }
163 CompilerType
TypeSystem::DeclGetFunctionArgumentType(void *opaque_decl
,
165 return CompilerType();
168 std::vector
<CompilerDecl
>
169 TypeSystem::DeclContextFindDeclByName(void *opaque_decl_ctx
, ConstString name
,
170 bool ignore_imported_decls
) {
171 return std::vector
<CompilerDecl
>();
174 std::unique_ptr
<UtilityFunction
>
175 TypeSystem::CreateUtilityFunction(std::string text
, std::string name
) {
179 #pragma mark TypeSystemMap
181 TypeSystemMap::TypeSystemMap() : m_mutex(), m_map() {}
183 TypeSystemMap::~TypeSystemMap() = default;
185 void TypeSystemMap::Clear() {
188 std::lock_guard
<std::mutex
> guard(m_mutex
);
190 m_clear_in_progress
= true;
192 std::set
<TypeSystem
*> visited
;
193 for (auto pair
: map
) {
194 TypeSystem
*type_system
= pair
.second
.get();
195 if (type_system
&& !visited
.count(type_system
)) {
196 visited
.insert(type_system
);
197 type_system
->Finalize();
202 std::lock_guard
<std::mutex
> guard(m_mutex
);
204 m_clear_in_progress
= false;
208 void TypeSystemMap::ForEach(std::function
<bool(TypeSystem
*)> const &callback
) {
209 std::lock_guard
<std::mutex
> guard(m_mutex
);
210 // Use a std::set so we only call the callback once for each unique
211 // TypeSystem instance
212 std::set
<TypeSystem
*> visited
;
213 for (auto pair
: m_map
) {
214 TypeSystem
*type_system
= pair
.second
.get();
215 if (type_system
&& !visited
.count(type_system
)) {
216 visited
.insert(type_system
);
217 if (!callback(type_system
))
223 llvm::Expected
<TypeSystem
&> TypeSystemMap::GetTypeSystemForLanguage(
224 lldb::LanguageType language
,
225 llvm::Optional
<CreateCallback
> create_callback
) {
226 std::lock_guard
<std::mutex
> guard(m_mutex
);
227 if (m_clear_in_progress
)
228 return llvm::make_error
<llvm::StringError
>(
229 "Unable to get TypeSystem because TypeSystemMap is being cleared",
230 llvm::inconvertibleErrorCode());
232 collection::iterator pos
= m_map
.find(language
);
233 if (pos
!= m_map
.end()) {
234 auto *type_system
= pos
->second
.get();
237 return llvm::make_error
<llvm::StringError
>(
238 "TypeSystem for language " +
239 llvm::StringRef(Language::GetNameForLanguageType(language
)) +
241 llvm::inconvertibleErrorCode());
244 for (const auto &pair
: m_map
) {
245 if (pair
.second
&& pair
.second
->SupportsLanguage(language
)) {
246 // Add a new mapping for "language" to point to an already existing
247 // TypeSystem that supports this language
248 m_map
[language
] = pair
.second
;
249 if (pair
.second
.get())
250 return *pair
.second
.get();
251 return llvm::make_error
<llvm::StringError
>(
252 "TypeSystem for language " +
253 llvm::StringRef(Language::GetNameForLanguageType(language
)) +
255 llvm::inconvertibleErrorCode());
259 if (!create_callback
)
260 return llvm::make_error
<llvm::StringError
>(
261 "Unable to find type system for language " +
262 llvm::StringRef(Language::GetNameForLanguageType(language
)),
263 llvm::inconvertibleErrorCode());
265 // Cache even if we get a shared pointer that contains a null type system
267 TypeSystemSP type_system_sp
= (*create_callback
)();
268 m_map
[language
] = type_system_sp
;
269 if (type_system_sp
.get())
270 return *type_system_sp
.get();
271 return llvm::make_error
<llvm::StringError
>(
272 "TypeSystem for language " +
273 llvm::StringRef(Language::GetNameForLanguageType(language
)) +
275 llvm::inconvertibleErrorCode());
278 llvm::Expected
<TypeSystem
&>
279 TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language
,
280 Module
*module
, bool can_create
) {
282 return GetTypeSystemForLanguage(
283 language
, llvm::Optional
<CreateCallback
>([language
, module
]() {
284 return TypeSystem::CreateInstance(language
, module
);
287 return GetTypeSystemForLanguage(language
);
290 llvm::Expected
<TypeSystem
&>
291 TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language
,
292 Target
*target
, bool can_create
) {
294 return GetTypeSystemForLanguage(
295 language
, llvm::Optional
<CreateCallback
>([language
, target
]() {
296 return TypeSystem::CreateInstance(language
, target
);
299 return GetTypeSystemForLanguage(language
);