[lld][WebAssembly] Perform data relocations during start function
[llvm-project.git] / lldb / source / Symbol / TypeSystem.cpp
blob3092dc0bf0a4fa31576e315335d03f8dbdbcb660
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 //===----------------------------------------------------------------------===//
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"
15 #include <set>
17 using namespace lldb_private;
18 using namespace lldb;
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();
30 return {};
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) {
42 uint32_t i = 0;
43 TypeSystemCreateInstance create_callback;
44 while ((create_callback = PluginManager::GetTypeSystemCreateCallbackAtIndex(
45 i++)) != nullptr) {
46 lldb::TypeSystemSP type_system_sp =
47 create_callback(language, module, target);
48 if (type_system_sp)
49 return type_system_sp;
52 return lldb::TypeSystemSP();
55 lldb::TypeSystemSP TypeSystem::CreateInstance(lldb::LanguageType language,
56 Module *module) {
57 return CreateInstanceHelper(language, module, nullptr);
60 lldb::TypeSystemSP TypeSystem::CreateInstance(lldb::LanguageType language,
61 Target *target) {
62 return CreateInstanceHelper(language, nullptr, target);
65 #ifndef NDEBUG
66 bool TypeSystem::Verify(lldb::opaque_compiler_type_t type) { return true; }
67 #endif
69 bool TypeSystem::IsAnonymousType(lldb::opaque_compiler_type_t type) {
70 return false;
73 CompilerType TypeSystem::GetArrayType(lldb::opaque_compiler_type_t type,
74 uint64_t size) {
75 return CompilerType();
78 CompilerType
79 TypeSystem::GetLValueReferenceType(lldb::opaque_compiler_type_t type) {
80 return CompilerType();
83 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();
96 CompilerType
97 TypeSystem::AddVolatileModifier(lldb::opaque_compiler_type_t type) {
98 return CompilerType();
101 CompilerType
102 TypeSystem::AddRestrictModifier(lldb::opaque_compiler_type_t type) {
103 return CompilerType();
106 CompilerType TypeSystem::CreateTypedef(lldb::opaque_compiler_type_t type,
107 const char *name,
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) {
122 return 0;
125 TemplateArgumentKind
126 TypeSystem::GetTemplateArgumentKind(opaque_compiler_type_t type, size_t idx) {
127 return eTemplateArgumentKindNull;
130 CompilerType TypeSystem::GetTypeTemplateArgument(opaque_compiler_type_t type,
131 size_t idx) {
132 return CompilerType();
135 llvm::Optional<CompilerType::IntegralTemplateArgument>
136 TypeSystem::GetIntegralTemplateArgument(opaque_compiler_type_t type,
137 size_t idx) {
138 return llvm::None;
141 LazyBool TypeSystem::ShouldPrintAsOneLiner(void *type, ValueObject *valobj) {
142 return eLazyBoolCalculate;
145 bool TypeSystem::IsMeaninglessWithoutDynamicResolution(void *type) {
146 return false;
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,
164 size_t arg_idx) {
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) {
176 return {};
179 #pragma mark TypeSystemMap
181 TypeSystemMap::TypeSystemMap() : m_mutex(), m_map() {}
183 TypeSystemMap::~TypeSystemMap() = default;
185 void TypeSystemMap::Clear() {
186 collection map;
188 std::lock_guard<std::mutex> guard(m_mutex);
189 map = m_map;
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();
200 map.clear();
202 std::lock_guard<std::mutex> guard(m_mutex);
203 m_map.clear();
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))
218 break;
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();
235 if (type_system)
236 return *type_system;
237 return llvm::make_error<llvm::StringError>(
238 "TypeSystem for language " +
239 llvm::StringRef(Language::GetNameForLanguageType(language)) +
240 " doesn't exist",
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)) +
254 " doesn't exist",
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
266 // back
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)) +
274 " doesn't exist",
275 llvm::inconvertibleErrorCode());
278 llvm::Expected<TypeSystem &>
279 TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language,
280 Module *module, bool can_create) {
281 if (can_create) {
282 return GetTypeSystemForLanguage(
283 language, llvm::Optional<CreateCallback>([language, module]() {
284 return TypeSystem::CreateInstance(language, module);
285 }));
287 return GetTypeSystemForLanguage(language);
290 llvm::Expected<TypeSystem &>
291 TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language,
292 Target *target, bool can_create) {
293 if (can_create) {
294 return GetTypeSystemForLanguage(
295 language, llvm::Optional<CreateCallback>([language, target]() {
296 return TypeSystem::CreateInstance(language, target);
297 }));
299 return GetTypeSystemForLanguage(language);