blob: b99f21e1e347164a177eb09df282ccf97dfc43ba [file] [log] [blame]
//===-- TypeSystem.cpp ------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// 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;
using namespace lldb;
TypeSystem::TypeSystem(LLVMCastKind kind) : m_kind(kind), m_sym_file(nullptr) {}
TypeSystem::~TypeSystem() {}
static lldb::TypeSystemSP CreateInstanceHelper(lldb::LanguageType language,
Module *module, Target *target) {
uint32_t i = 0;
TypeSystemCreateInstance create_callback;
while ((create_callback = PluginManager::GetTypeSystemCreateCallbackAtIndex(
i++)) != nullptr) {
lldb::TypeSystemSP type_system_sp =
create_callback(language, module, target);
if (type_system_sp)
return type_system_sp;
}
return lldb::TypeSystemSP();
}
lldb::TypeSystemSP TypeSystem::CreateInstance(lldb::LanguageType language,
Module *module) {
return CreateInstanceHelper(language, module, nullptr);
}
lldb::TypeSystemSP TypeSystem::CreateInstance(lldb::LanguageType language,
Target *target) {
return CreateInstanceHelper(language, nullptr, target);
}
bool TypeSystem::IsAnonymousType(lldb::opaque_compiler_type_t type) {
return false;
}
CompilerType TypeSystem::GetArrayType(lldb::opaque_compiler_type_t type,
uint64_t size) {
return CompilerType();
}
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);
}
TemplateArgumentKind
TypeSystem::GetTemplateArgumentKind(opaque_compiler_type_t type, size_t idx) {
return eTemplateArgumentKindNull;
}
CompilerType TypeSystem::GetTypeTemplateArgument(opaque_compiler_type_t type,
size_t idx) {
return CompilerType();
}
llvm::Optional<CompilerType::IntegralTemplateArgument>
TypeSystem::GetIntegralTemplateArgument(opaque_compiler_type_t type,
size_t idx) {
return llvm::None;
}
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;
}