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