diff options
Diffstat (limited to 'source/Symbol/TypeSystem.cpp')
-rw-r--r-- | source/Symbol/TypeSystem.cpp | 192 |
1 files changed, 143 insertions, 49 deletions
diff --git a/source/Symbol/TypeSystem.cpp b/source/Symbol/TypeSystem.cpp index fb9c8e71acb35..c63f24aea3354 100644 --- a/source/Symbol/TypeSystem.cpp +++ b/source/Symbol/TypeSystem.cpp @@ -20,10 +20,29 @@ #include "lldb/Core/PluginManager.h" #include "lldb/Symbol/CompilerType.h" +#include "lldb/Target/Language.h" using namespace lldb_private; using namespace lldb; +/// A 64-bit SmallBitVector is only small up to 64-7 bits, and the +/// setBitsInMask interface wants to write full bytes. +static const size_t g_num_small_bitvector_bits = 64 - 8; +static_assert(eNumLanguageTypes < g_num_small_bitvector_bits, + "Languages bit vector is no longer small on 64 bit systems"); +LanguageSet::LanguageSet() : bitvector(eNumLanguageTypes, 0) {} + +llvm::Optional<LanguageType> LanguageSet::GetSingularLanguage() { + if (bitvector.count() == 1) + return (LanguageType)bitvector.find_first(); + return {}; +} + +void LanguageSet::Insert(LanguageType language) { bitvector.set(language); } +size_t LanguageSet::Size() const { return bitvector.count(); } +bool LanguageSet::Empty() const { return bitvector.none(); } +bool LanguageSet::operator[](unsigned i) const { return bitvector[i]; } + TypeSystem::TypeSystem(LLVMCastKind kind) : m_kind(kind), m_sym_file(nullptr) {} TypeSystem::~TypeSystem() {} @@ -198,65 +217,140 @@ void TypeSystemMap::ForEach(std::function<bool(TypeSystem *)> const &callback) { } } -TypeSystem *TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language, - Module *module, - bool can_create) { +llvm::Expected<TypeSystem &> +TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language, + Module *module, bool can_create) { + llvm::Error error = llvm::Error::success(); + assert(!error); // Check the success value when assertions are enabled 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 (m_clear_in_progress) { + error = llvm::make_error<llvm::StringError>( + "Unable to get TypeSystem because TypeSystemMap is being cleared", + llvm::inconvertibleErrorCode()); + } else { + collection::iterator pos = m_map.find(language); + if (pos != m_map.end()) { + auto *type_system = pos->second.get(); + if (type_system) { + llvm::consumeError(std::move(error)); + return *type_system; + } + error = llvm::make_error<llvm::StringError>( + "TypeSystem for language " + + llvm::toStringRef(Language::GetNameForLanguageType(language)) + + " doesn't exist", + llvm::inconvertibleErrorCode()); + return std::move(error); } - } - if (!can_create) - return nullptr; + 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 + m_map[language] = pair.second; + if (pair.second.get()) { + llvm::consumeError(std::move(error)); + return *pair.second.get(); + } + error = llvm::make_error<llvm::StringError>( + "TypeSystem for language " + + llvm::toStringRef(Language::GetNameForLanguageType(language)) + + " doesn't exist", + llvm::inconvertibleErrorCode()); + return std::move(error); + } + } + + if (!can_create) { + error = llvm::make_error<llvm::StringError>( + "Unable to find type system for language " + + llvm::toStringRef(Language::GetNameForLanguageType(language)), + llvm::inconvertibleErrorCode()); + } else { + // Cache even if we get a shared pointer that contains a null type system + // back + auto type_system_sp = TypeSystem::CreateInstance(language, module); + m_map[language] = type_system_sp; + if (type_system_sp.get()) { + llvm::consumeError(std::move(error)); + return *type_system_sp.get(); + } + error = llvm::make_error<llvm::StringError>( + "TypeSystem for language " + + llvm::toStringRef(Language::GetNameForLanguageType(language)) + + " doesn't exist", + llvm::inconvertibleErrorCode()); + } + } - // 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(); + return std::move(error); } -TypeSystem *TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language, - Target *target, - bool can_create) { +llvm::Expected<TypeSystem &> +TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language, + Target *target, bool can_create) { + llvm::Error error = llvm::Error::success(); + assert(!error); // Check the success value when assertions are enabled std::lock_guard<std::mutex> guard(m_mutex); - collection::iterator pos = m_map.find(language); - if (pos != m_map.end()) - return pos->second.get(); + if (m_clear_in_progress) { + error = llvm::make_error<llvm::StringError>( + "Unable to get TypeSystem because TypeSystemMap is being cleared", + llvm::inconvertibleErrorCode()); + } else { + collection::iterator pos = m_map.find(language); + if (pos != m_map.end()) { + auto *type_system = pos->second.get(); + if (type_system) { + llvm::consumeError(std::move(error)); + return *type_system; + } + error = llvm::make_error<llvm::StringError>( + "TypeSystem for language " + + llvm::toStringRef(Language::GetNameForLanguageType(language)) + + " doesn't exist", + llvm::inconvertibleErrorCode()); + return std::move(error); + } - 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 + 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 + m_map[language] = pair.second; + if (pair.second.get()) { + llvm::consumeError(std::move(error)); + return *pair.second.get(); + } + error = llvm::make_error<llvm::StringError>( + "TypeSystem for language " + + llvm::toStringRef(Language::GetNameForLanguageType(language)) + + " doesn't exist", + llvm::inconvertibleErrorCode()); + return std::move(error); + } + } - AddToMap(language, pair.second); - return pair.second.get(); + if (!can_create) { + error = llvm::make_error<llvm::StringError>( + "Unable to find type system for language " + + llvm::toStringRef(Language::GetNameForLanguageType(language)), + llvm::inconvertibleErrorCode()); + } else { + // Cache even if we get a shared pointer that contains a null type system + // back + auto type_system_sp = TypeSystem::CreateInstance(language, target); + m_map[language] = type_system_sp; + if (type_system_sp.get()) { + llvm::consumeError(std::move(error)); + return *type_system_sp.get(); + } + error = llvm::make_error<llvm::StringError>( + "TypeSystem for language " + + llvm::toStringRef(Language::GetNameForLanguageType(language)) + + " doesn't exist", + llvm::inconvertibleErrorCode()); } } - 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; + return std::move(error); } |