diff --git a/lldb/include/lldb/Symbol/TypeSystem.h b/lldb/include/lldb/Symbol/TypeSystem.h --- a/lldb/include/lldb/Symbol/TypeSystem.h +++ b/lldb/include/lldb/Symbol/TypeSystem.h @@ -523,6 +523,22 @@ ///multi-threaded environments. collection m_map; bool m_clear_in_progress; + +private: + typedef llvm::function_ref CreateCallback; + /// Finds the type system for the given language. If no type system could be + /// found for a language and a CreateCallback was provided, the value returned + /// by the callback will be treated as the TypeSystem for the language. + /// + /// \param language The language for which the type system should be found. + /// \param create_callback A callback that will be called if no previously + /// created TypeSystem that fits the given language + /// could found. Can be omitted if a non-existent + /// type system should be treated as an error instead. + /// \return The found type system or an error. + llvm::Expected GetTypeSystemForLanguage( + lldb::LanguageType language, + llvm::Optional create_callback = llvm::None); }; } // namespace lldb_private diff --git a/lldb/source/Symbol/TypeSystem.cpp b/lldb/source/Symbol/TypeSystem.cpp --- a/lldb/source/Symbol/TypeSystem.cpp +++ b/lldb/source/Symbol/TypeSystem.cpp @@ -224,9 +224,9 @@ } } -llvm::Expected -TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language, - Module *module, bool can_create) { +llvm::Expected TypeSystemMap::GetTypeSystemForLanguage( + lldb::LanguageType language, + llvm::Optional create_callback) { llvm::Error error = llvm::Error::success(); assert(!error); // Check the success value when assertions are enabled std::lock_guard guard(m_mutex); @@ -268,7 +268,7 @@ } } - if (!can_create) { + if (!create_callback) { error = llvm::make_error( "Unable to find type system for language " + llvm::StringRef(Language::GetNameForLanguageType(language)), @@ -276,7 +276,7 @@ } else { // Cache even if we get a shared pointer that contains a null type system // back - auto type_system_sp = TypeSystem::CreateInstance(language, module); + TypeSystemSP type_system_sp = (*create_callback)(); m_map[language] = type_system_sp; if (type_system_sp.get()) { llvm::consumeError(std::move(error)); @@ -295,69 +295,24 @@ llvm::Expected 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 guard(m_mutex); - if (m_clear_in_progress) { - error = llvm::make_error( - "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( - "TypeSystem for language " + - llvm::StringRef(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 - m_map[language] = pair.second; - if (pair.second.get()) { - llvm::consumeError(std::move(error)); - return *pair.second.get(); - } - error = llvm::make_error( - "TypeSystem for language " + - llvm::StringRef(Language::GetNameForLanguageType(language)) + - " doesn't exist", - llvm::inconvertibleErrorCode()); - return std::move(error); - } - } - - if (!can_create) { - error = llvm::make_error( - "Unable to find type system for language " + - llvm::StringRef(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( - "TypeSystem for language " + - llvm::StringRef(Language::GetNameForLanguageType(language)) + - " doesn't exist", - llvm::inconvertibleErrorCode()); - } + Module *module, bool can_create) { + if (can_create) { + return GetTypeSystemForLanguage( + language, llvm::Optional([language, module]() { + return TypeSystem::CreateInstance(language, module); + })); } + return GetTypeSystemForLanguage(language); +} - return std::move(error); +llvm::Expected +TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language, + Target *target, bool can_create) { + if (can_create) { + return GetTypeSystemForLanguage( + language, llvm::Optional([language, target]() { + return TypeSystem::CreateInstance(language, target); + })); + } + return GetTypeSystemForLanguage(language); }