1 //===-- TypeSystem.cpp ------------------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 //
11 // TypeSystem.cpp
12 // lldb
13 //
14 // Created by Ryan Brown on 3/29/15.
15 //
16 //
17
18 #include "lldb/Symbol/TypeSystem.h"
19
20 #include <set>
21
22 #include "lldb/Core/PluginManager.h"
23 #include "lldb/Symbol/CompilerType.h"
24
25 using namespace lldb_private;
26 using namespace lldb;
27
TypeSystem(LLVMCastKind kind)28 TypeSystem::TypeSystem(LLVMCastKind kind) : m_kind(kind), m_sym_file(nullptr) {}
29
~TypeSystem()30 TypeSystem::~TypeSystem() {}
31
CreateInstanceHelper(lldb::LanguageType language,Module * module,Target * target)32 static lldb::TypeSystemSP CreateInstanceHelper(lldb::LanguageType language,
33 Module *module, Target *target) {
34 uint32_t i = 0;
35 TypeSystemCreateInstance create_callback;
36 while ((create_callback = PluginManager::GetTypeSystemCreateCallbackAtIndex(
37 i++)) != nullptr) {
38 lldb::TypeSystemSP type_system_sp =
39 create_callback(language, module, target);
40 if (type_system_sp)
41 return type_system_sp;
42 }
43
44 return lldb::TypeSystemSP();
45 }
46
CreateInstance(lldb::LanguageType language,Module * module)47 lldb::TypeSystemSP TypeSystem::CreateInstance(lldb::LanguageType language,
48 Module *module) {
49 return CreateInstanceHelper(language, module, nullptr);
50 }
51
CreateInstance(lldb::LanguageType language,Target * target)52 lldb::TypeSystemSP TypeSystem::CreateInstance(lldb::LanguageType language,
53 Target *target) {
54 return CreateInstanceHelper(language, nullptr, target);
55 }
56
IsAnonymousType(lldb::opaque_compiler_type_t type)57 bool TypeSystem::IsAnonymousType(lldb::opaque_compiler_type_t type) {
58 return false;
59 }
60
GetArrayType(lldb::opaque_compiler_type_t type,uint64_t size)61 CompilerType TypeSystem::GetArrayType(lldb::opaque_compiler_type_t type,
62 uint64_t size) {
63 return CompilerType();
64 }
65
66 CompilerType
GetLValueReferenceType(lldb::opaque_compiler_type_t type)67 TypeSystem::GetLValueReferenceType(lldb::opaque_compiler_type_t type) {
68 return CompilerType();
69 }
70
71 CompilerType
GetRValueReferenceType(lldb::opaque_compiler_type_t type)72 TypeSystem::GetRValueReferenceType(lldb::opaque_compiler_type_t type) {
73 return CompilerType();
74 }
75
AddConstModifier(lldb::opaque_compiler_type_t type)76 CompilerType TypeSystem::AddConstModifier(lldb::opaque_compiler_type_t type) {
77 return CompilerType();
78 }
79
80 CompilerType
AddVolatileModifier(lldb::opaque_compiler_type_t type)81 TypeSystem::AddVolatileModifier(lldb::opaque_compiler_type_t type) {
82 return CompilerType();
83 }
84
85 CompilerType
AddRestrictModifier(lldb::opaque_compiler_type_t type)86 TypeSystem::AddRestrictModifier(lldb::opaque_compiler_type_t type) {
87 return CompilerType();
88 }
89
CreateTypedef(lldb::opaque_compiler_type_t type,const char * name,const CompilerDeclContext & decl_ctx)90 CompilerType TypeSystem::CreateTypedef(lldb::opaque_compiler_type_t type,
91 const char *name,
92 const CompilerDeclContext &decl_ctx) {
93 return CompilerType();
94 }
95
GetBuiltinTypeByName(const ConstString & name)96 CompilerType TypeSystem::GetBuiltinTypeByName(const ConstString &name) {
97 return CompilerType();
98 }
99
GetTypeForFormatters(void * type)100 CompilerType TypeSystem::GetTypeForFormatters(void *type) {
101 return CompilerType(this, type);
102 }
103
GetNumTemplateArguments(lldb::opaque_compiler_type_t type)104 size_t TypeSystem::GetNumTemplateArguments(lldb::opaque_compiler_type_t type) {
105 return 0;
106 }
107
108 TemplateArgumentKind
GetTemplateArgumentKind(opaque_compiler_type_t type,size_t idx)109 TypeSystem::GetTemplateArgumentKind(opaque_compiler_type_t type, size_t idx) {
110 return eTemplateArgumentKindNull;
111 }
112
GetTypeTemplateArgument(opaque_compiler_type_t type,size_t idx)113 CompilerType TypeSystem::GetTypeTemplateArgument(opaque_compiler_type_t type,
114 size_t idx) {
115 return CompilerType();
116 }
117
118 llvm::Optional<CompilerType::IntegralTemplateArgument>
GetIntegralTemplateArgument(opaque_compiler_type_t type,size_t idx)119 TypeSystem::GetIntegralTemplateArgument(opaque_compiler_type_t type,
120 size_t idx) {
121 return llvm::None;
122 }
123
ShouldPrintAsOneLiner(void * type,ValueObject * valobj)124 LazyBool TypeSystem::ShouldPrintAsOneLiner(void *type, ValueObject *valobj) {
125 return eLazyBoolCalculate;
126 }
127
IsMeaninglessWithoutDynamicResolution(void * type)128 bool TypeSystem::IsMeaninglessWithoutDynamicResolution(void *type) {
129 return false;
130 }
131
DeclGetMangledName(void * opaque_decl)132 ConstString TypeSystem::DeclGetMangledName(void *opaque_decl) {
133 return ConstString();
134 }
135
DeclGetDeclContext(void * opaque_decl)136 CompilerDeclContext TypeSystem::DeclGetDeclContext(void *opaque_decl) {
137 return CompilerDeclContext();
138 }
139
DeclGetFunctionReturnType(void * opaque_decl)140 CompilerType TypeSystem::DeclGetFunctionReturnType(void *opaque_decl) {
141 return CompilerType();
142 }
143
DeclGetFunctionNumArguments(void * opaque_decl)144 size_t TypeSystem::DeclGetFunctionNumArguments(void *opaque_decl) { return 0; }
145
DeclGetFunctionArgumentType(void * opaque_decl,size_t arg_idx)146 CompilerType TypeSystem::DeclGetFunctionArgumentType(void *opaque_decl,
147 size_t arg_idx) {
148 return CompilerType();
149 }
150
151 std::vector<CompilerDecl>
DeclContextFindDeclByName(void * opaque_decl_ctx,ConstString name,bool ignore_imported_decls)152 TypeSystem::DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name,
153 bool ignore_imported_decls) {
154 return std::vector<CompilerDecl>();
155 }
156
157 #pragma mark TypeSystemMap
158
TypeSystemMap()159 TypeSystemMap::TypeSystemMap()
160 : m_mutex(), m_map(), m_clear_in_progress(false) {}
161
~TypeSystemMap()162 TypeSystemMap::~TypeSystemMap() {}
163
Clear()164 void TypeSystemMap::Clear() {
165 collection map;
166 {
167 std::lock_guard<std::mutex> guard(m_mutex);
168 map = m_map;
169 m_clear_in_progress = true;
170 }
171 std::set<TypeSystem *> visited;
172 for (auto pair : map) {
173 TypeSystem *type_system = pair.second.get();
174 if (type_system && !visited.count(type_system)) {
175 visited.insert(type_system);
176 type_system->Finalize();
177 }
178 }
179 map.clear();
180 {
181 std::lock_guard<std::mutex> guard(m_mutex);
182 m_map.clear();
183 m_clear_in_progress = false;
184 }
185 }
186
ForEach(std::function<bool (TypeSystem *)> const & callback)187 void TypeSystemMap::ForEach(std::function<bool(TypeSystem *)> const &callback) {
188 std::lock_guard<std::mutex> guard(m_mutex);
189 // Use a std::set so we only call the callback once for each unique
190 // TypeSystem instance
191 std::set<TypeSystem *> visited;
192 for (auto pair : m_map) {
193 TypeSystem *type_system = pair.second.get();
194 if (type_system && !visited.count(type_system)) {
195 visited.insert(type_system);
196 if (!callback(type_system))
197 break;
198 }
199 }
200 }
201
GetTypeSystemForLanguage(lldb::LanguageType language,Module * module,bool can_create)202 TypeSystem *TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language,
203 Module *module,
204 bool can_create) {
205 std::lock_guard<std::mutex> guard(m_mutex);
206 collection::iterator pos = m_map.find(language);
207 if (pos != m_map.end())
208 return pos->second.get();
209
210 for (const auto &pair : m_map) {
211 if (pair.second && pair.second->SupportsLanguage(language)) {
212 // Add a new mapping for "language" to point to an already existing
213 // TypeSystem that supports this language
214 AddToMap(language, pair.second);
215 return pair.second.get();
216 }
217 }
218
219 if (!can_create)
220 return nullptr;
221
222 // Cache even if we get a shared pointer that contains null type system back
223 lldb::TypeSystemSP type_system_sp =
224 TypeSystem::CreateInstance(language, module);
225 AddToMap(language, type_system_sp);
226 return type_system_sp.get();
227 }
228
GetTypeSystemForLanguage(lldb::LanguageType language,Target * target,bool can_create)229 TypeSystem *TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language,
230 Target *target,
231 bool can_create) {
232 std::lock_guard<std::mutex> guard(m_mutex);
233 collection::iterator pos = m_map.find(language);
234 if (pos != m_map.end())
235 return pos->second.get();
236
237 for (const auto &pair : m_map) {
238 if (pair.second && pair.second->SupportsLanguage(language)) {
239 // Add a new mapping for "language" to point to an already existing
240 // TypeSystem that supports this language
241
242 AddToMap(language, pair.second);
243 return pair.second.get();
244 }
245 }
246
247 if (!can_create)
248 return nullptr;
249
250 // Cache even if we get a shared pointer that contains null type system back
251 lldb::TypeSystemSP type_system_sp;
252 if (!m_clear_in_progress)
253 type_system_sp = TypeSystem::CreateInstance(language, target);
254
255 AddToMap(language, type_system_sp);
256 return type_system_sp.get();
257 }
258
AddToMap(lldb::LanguageType language,lldb::TypeSystemSP const & type_system_sp)259 void TypeSystemMap::AddToMap(lldb::LanguageType language,
260 lldb::TypeSystemSP const &type_system_sp) {
261 if (!m_clear_in_progress)
262 m_map[language] = type_system_sp;
263 }
264