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 size_t TypeSystem::GetNumTemplateArguments(lldb::opaque_compiler_type_t type) { 105 return 0; 106 } 107 108 TemplateArgumentKind 109 TypeSystem::GetTemplateArgumentKind(opaque_compiler_type_t type, size_t idx) { 110 return eTemplateArgumentKindNull; 111 } 112 113 CompilerType TypeSystem::GetTypeTemplateArgument(opaque_compiler_type_t type, 114 size_t idx) { 115 return CompilerType(); 116 } 117 118 llvm::Optional<CompilerType::IntegralTemplateArgument> 119 TypeSystem::GetIntegralTemplateArgument(opaque_compiler_type_t type, 120 size_t idx) { 121 return llvm::None; 122 } 123 124 LazyBool TypeSystem::ShouldPrintAsOneLiner(void *type, ValueObject *valobj) { 125 return eLazyBoolCalculate; 126 } 127 128 bool TypeSystem::IsMeaninglessWithoutDynamicResolution(void *type) { 129 return false; 130 } 131 132 ConstString TypeSystem::DeclGetMangledName(void *opaque_decl) { 133 return ConstString(); 134 } 135 136 CompilerDeclContext TypeSystem::DeclGetDeclContext(void *opaque_decl) { 137 return CompilerDeclContext(); 138 } 139 140 CompilerType TypeSystem::DeclGetFunctionReturnType(void *opaque_decl) { 141 return CompilerType(); 142 } 143 144 size_t TypeSystem::DeclGetFunctionNumArguments(void *opaque_decl) { return 0; } 145 146 CompilerType TypeSystem::DeclGetFunctionArgumentType(void *opaque_decl, 147 size_t arg_idx) { 148 return CompilerType(); 149 } 150 151 std::vector<CompilerDecl> 152 TypeSystem::DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name, 153 bool ignore_imported_decls) { 154 return std::vector<CompilerDecl>(); 155 } 156 157 #pragma mark TypeSystemMap 158 159 TypeSystemMap::TypeSystemMap() 160 : m_mutex(), m_map(), m_clear_in_progress(false) {} 161 162 TypeSystemMap::~TypeSystemMap() {} 163 164 void TypeSystemMap::Clear() { 165 collection map; 166 { 167 std::lock_guard<std::mutex> guard(m_mutex); 168 map = m_map; 169 m_clear_in_progress = true; 170 } 171 std::set<TypeSystem *> visited; 172 for (auto pair : map) { 173 TypeSystem *type_system = pair.second.get(); 174 if (type_system && !visited.count(type_system)) { 175 visited.insert(type_system); 176 type_system->Finalize(); 177 } 178 } 179 map.clear(); 180 { 181 std::lock_guard<std::mutex> guard(m_mutex); 182 m_map.clear(); 183 m_clear_in_progress = false; 184 } 185 } 186 187 void TypeSystemMap::ForEach(std::function<bool(TypeSystem *)> const &callback) { 188 std::lock_guard<std::mutex> guard(m_mutex); 189 // Use a std::set so we only call the callback once for each unique 190 // TypeSystem instance 191 std::set<TypeSystem *> visited; 192 for (auto pair : m_map) { 193 TypeSystem *type_system = pair.second.get(); 194 if (type_system && !visited.count(type_system)) { 195 visited.insert(type_system); 196 if (callback(type_system) == false) 197 break; 198 } 199 } 200 } 201 202 TypeSystem *TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language, 203 Module *module, 204 bool can_create) { 205 std::lock_guard<std::mutex> guard(m_mutex); 206 collection::iterator pos = m_map.find(language); 207 if (pos != m_map.end()) 208 return pos->second.get(); 209 210 for (const auto &pair : m_map) { 211 if (pair.second && pair.second->SupportsLanguage(language)) { 212 // Add a new mapping for "language" to point to an already existing 213 // TypeSystem that supports this language 214 AddToMap(language, pair.second); 215 return pair.second.get(); 216 } 217 } 218 219 if (!can_create) 220 return nullptr; 221 222 // Cache even if we get a shared pointer that contains null type system back 223 lldb::TypeSystemSP type_system_sp = 224 TypeSystem::CreateInstance(language, module); 225 AddToMap(language, type_system_sp); 226 return type_system_sp.get(); 227 } 228 229 TypeSystem *TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language, 230 Target *target, 231 bool can_create) { 232 std::lock_guard<std::mutex> guard(m_mutex); 233 collection::iterator pos = m_map.find(language); 234 if (pos != m_map.end()) 235 return pos->second.get(); 236 237 for (const auto &pair : m_map) { 238 if (pair.second && pair.second->SupportsLanguage(language)) { 239 // Add a new mapping for "language" to point to an already existing 240 // TypeSystem that supports this language 241 242 AddToMap(language, pair.second); 243 return pair.second.get(); 244 } 245 } 246 247 if (!can_create) 248 return nullptr; 249 250 // Cache even if we get a shared pointer that contains null type system back 251 lldb::TypeSystemSP type_system_sp; 252 if (!m_clear_in_progress) 253 type_system_sp = TypeSystem::CreateInstance(language, target); 254 255 AddToMap(language, type_system_sp); 256 return type_system_sp.get(); 257 } 258 259 void TypeSystemMap::AddToMap(lldb::LanguageType language, 260 lldb::TypeSystemSP const &type_system_sp) { 261 if (!m_clear_in_progress) 262 m_map[language] = type_system_sp; 263 } 264