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