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