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