| // |
| // TypeSystem.cpp |
| // lldb |
| // |
| // Created by Ryan Brown on 3/29/15. |
| // |
| // |
| |
| #include "lldb/Symbol/TypeSystem.h" |
| |
| #include <set> |
| |
| #include "lldb/Core/PluginManager.h" |
| #include "lldb/Symbol/CompilerType.h" |
| |
| using namespace lldb_private; |
| |
| TypeSystem::TypeSystem(LLVMCastKind kind) : |
| m_kind (kind), |
| m_sym_file (nullptr) |
| { |
| } |
| |
| TypeSystem::~TypeSystem() |
| { |
| } |
| |
| lldb::TypeSystemSP |
| TypeSystem::CreateInstance (lldb::LanguageType language, Module *module) |
| { |
| uint32_t i = 0; |
| TypeSystemCreateInstance create_callback; |
| while ((create_callback = PluginManager::GetTypeSystemCreateCallbackAtIndex (i++)) != nullptr) |
| { |
| lldb::TypeSystemSP type_system_sp = create_callback(language, module, nullptr); |
| if (type_system_sp) |
| return type_system_sp; |
| } |
| |
| return lldb::TypeSystemSP(); |
| } |
| |
| lldb::TypeSystemSP |
| TypeSystem::CreateInstance (lldb::LanguageType language, Target *target) |
| { |
| uint32_t i = 0; |
| TypeSystemCreateInstance create_callback; |
| while ((create_callback = PluginManager::GetTypeSystemCreateCallbackAtIndex (i++)) != nullptr) |
| { |
| lldb::TypeSystemSP type_system_sp = create_callback(language, nullptr, target); |
| if (type_system_sp) |
| return type_system_sp; |
| } |
| |
| return lldb::TypeSystemSP(); |
| } |
| |
| bool |
| TypeSystem::IsAnonymousType (lldb::opaque_compiler_type_t type) |
| { |
| return false; |
| } |
| |
| CompilerType |
| TypeSystem::GetLValueReferenceType (lldb::opaque_compiler_type_t type) |
| { |
| return CompilerType(); |
| } |
| |
| CompilerType |
| TypeSystem::GetRValueReferenceType (lldb::opaque_compiler_type_t type) |
| { |
| return CompilerType(); |
| } |
| |
| CompilerType |
| TypeSystem::AddConstModifier (lldb::opaque_compiler_type_t type) |
| { |
| return CompilerType(); |
| } |
| |
| CompilerType |
| TypeSystem::AddVolatileModifier (lldb::opaque_compiler_type_t type) |
| { |
| return CompilerType(); |
| } |
| |
| CompilerType |
| TypeSystem::AddRestrictModifier (lldb::opaque_compiler_type_t type) |
| { |
| return CompilerType(); |
| } |
| |
| CompilerType |
| TypeSystem::CreateTypedef (lldb::opaque_compiler_type_t type, const char *name, const CompilerDeclContext &decl_ctx) |
| { |
| return CompilerType(); |
| } |
| |
| CompilerType |
| TypeSystem::GetBuiltinTypeByName (const ConstString &name) |
| { |
| return CompilerType(); |
| } |
| |
| CompilerType |
| TypeSystem::GetTypeForFormatters (void* type) |
| { |
| return CompilerType(this, type); |
| } |
| |
| LazyBool |
| TypeSystem::ShouldPrintAsOneLiner (void* type, ValueObject* valobj) |
| { |
| return eLazyBoolCalculate; |
| } |
| |
| bool |
| TypeSystem::IsMeaninglessWithoutDynamicResolution (void* type) |
| { |
| return false; |
| } |
| |
| ConstString |
| TypeSystem::DeclGetMangledName (void *opaque_decl) |
| { |
| return ConstString(); |
| } |
| |
| CompilerDeclContext |
| TypeSystem::DeclGetDeclContext (void *opaque_decl) |
| { |
| return CompilerDeclContext(); |
| } |
| |
| CompilerType |
| TypeSystem::DeclGetFunctionReturnType(void *opaque_decl) |
| { |
| return CompilerType(); |
| } |
| |
| size_t |
| TypeSystem::DeclGetFunctionNumArguments(void *opaque_decl) |
| { |
| return 0; |
| } |
| |
| CompilerType |
| TypeSystem::DeclGetFunctionArgumentType (void *opaque_decl, size_t arg_idx) |
| { |
| return CompilerType(); |
| } |
| |
| |
| std::vector<CompilerDecl> |
| TypeSystem::DeclContextFindDeclByName (void *opaque_decl_ctx, |
| ConstString name, |
| bool ignore_imported_decls) |
| { |
| return std::vector<CompilerDecl>(); |
| } |
| |
| |
| #pragma mark TypeSystemMap |
| |
| TypeSystemMap::TypeSystemMap() : m_mutex(), m_map(), m_clear_in_progress(false) |
| { |
| } |
| |
| TypeSystemMap::~TypeSystemMap() |
| { |
| } |
| |
| void |
| TypeSystemMap::Clear () |
| { |
| collection map; |
| { |
| std::lock_guard<std::mutex> guard(m_mutex); |
| map = m_map; |
| m_clear_in_progress = true; |
| } |
| std::set<TypeSystem *> visited; |
| for (auto pair : map) |
| { |
| TypeSystem *type_system = pair.second.get(); |
| if (type_system && !visited.count(type_system)) |
| { |
| visited.insert(type_system); |
| type_system->Finalize(); |
| } |
| } |
| map.clear(); |
| { |
| std::lock_guard<std::mutex> guard(m_mutex); |
| m_map.clear(); |
| m_clear_in_progress = false; |
| } |
| } |
| |
| |
| void |
| TypeSystemMap::ForEach (std::function <bool(TypeSystem *)> const &callback) |
| { |
| std::lock_guard<std::mutex> guard(m_mutex); |
| // Use a std::set so we only call the callback once for each unique |
| // TypeSystem instance |
| std::set<TypeSystem *> visited; |
| for (auto pair : m_map) |
| { |
| TypeSystem *type_system = pair.second.get(); |
| if (type_system && !visited.count(type_system)) |
| { |
| visited.insert(type_system); |
| if (callback (type_system) == false) |
| break; |
| } |
| } |
| } |
| |
| TypeSystem * |
| TypeSystemMap::GetTypeSystemForLanguage (lldb::LanguageType language, Module *module, bool can_create) |
| { |
| std::lock_guard<std::mutex> guard(m_mutex); |
| collection::iterator pos = m_map.find(language); |
| if (pos != m_map.end()) |
| return pos->second.get(); |
| |
| for (const auto &pair : m_map) |
| { |
| if (pair.second && pair.second->SupportsLanguage(language)) |
| { |
| // Add a new mapping for "language" to point to an already existing |
| // TypeSystem that supports this language |
| AddToMap(language, pair.second); |
| return pair.second.get(); |
| } |
| } |
| |
| if (!can_create) |
| return nullptr; |
| |
| // Cache even if we get a shared pointer that contains null type system back |
| lldb::TypeSystemSP type_system_sp = TypeSystem::CreateInstance (language, module); |
| AddToMap (language, type_system_sp); |
| return type_system_sp.get(); |
| } |
| |
| TypeSystem * |
| TypeSystemMap::GetTypeSystemForLanguage (lldb::LanguageType language, Target *target, bool can_create) |
| { |
| std::lock_guard<std::mutex> guard(m_mutex); |
| collection::iterator pos = m_map.find(language); |
| if (pos != m_map.end()) |
| return pos->second.get(); |
| |
| for (const auto &pair : m_map) |
| { |
| if (pair.second && pair.second->SupportsLanguage(language)) |
| { |
| // Add a new mapping for "language" to point to an already existing |
| // TypeSystem that supports this language |
| |
| AddToMap(language, pair.second); |
| return pair.second.get(); |
| } |
| } |
| |
| if (!can_create) |
| return nullptr; |
| |
| // Cache even if we get a shared pointer that contains null type system back |
| lldb::TypeSystemSP type_system_sp; |
| if (!m_clear_in_progress) |
| type_system_sp = TypeSystem::CreateInstance (language, target); |
| |
| AddToMap(language, type_system_sp); |
| return type_system_sp.get(); |
| } |
| |
| void |
| TypeSystemMap::AddToMap (lldb::LanguageType language, lldb::TypeSystemSP const &type_system_sp) |
| { |
| if (!m_clear_in_progress) |
| m_map[language] = type_system_sp; |
| } |