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