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