From 63db2395f655136ce9013e60b93f0a8b3638dd35 Mon Sep 17 00:00:00 2001 From: Enrico Granata Date: Tue, 1 Nov 2016 18:50:49 +0000 Subject: [PATCH] Implement a general type scavenger that can dig types from debug info + a filtering mechanism to accept/reject results thusly obtained Implement the C++ type lookup support in terms of this general scavenger The idea is that we may want other languages to do debug info based search (exclusively, or as an add-on to runtime/module based searching) and it makes sense to avoid duplicating this functionality llvm-svn: 285727 --- lldb/include/lldb/Target/Language.h | 38 +++++++++ .../Language/CPlusPlus/CPlusPlusLanguage.cpp | 79 +++---------------- lldb/source/Target/Language.cpp | 33 ++++++++ 3 files changed, 81 insertions(+), 69 deletions(-) diff --git a/lldb/include/lldb/Target/Language.h b/lldb/include/lldb/Target/Language.h index 588d46e60414..12d6572eaa5a 100644 --- a/lldb/include/lldb/Target/Language.h +++ b/lldb/include/lldb/Target/Language.h @@ -57,6 +57,44 @@ public: ResultSet &results) = 0; }; + class ImageListTypeScavenger : public TypeScavenger { + class Result : public Language::TypeScavenger::Result { + public: + Result(CompilerType type) + : Language::TypeScavenger::Result(), m_compiler_type(type) {} + + bool IsValid() override { return m_compiler_type.IsValid(); } + + bool DumpToStream(Stream &stream, bool print_help_if_available) override { + if (IsValid()) { + m_compiler_type.DumpTypeDescription(&stream); + stream.EOL(); + return true; + } + return false; + } + + ~Result() override = default; + + private: + CompilerType m_compiler_type; + }; + + protected: + ImageListTypeScavenger() = default; + + ~ImageListTypeScavenger() override = default; + + // is this type something we should accept? it's usually going to be a + // filter by language + maybe some sugar tweaking + // returning an empty type means rejecting this candidate entirely; + // any other result will be accepted as a valid match + virtual CompilerType AdjustForInclusion(CompilerType &candidate) = 0; + + bool Find_Impl(ExecutionContextScope *exe_scope, const char *key, + ResultSet &results) override; + }; + enum class FunctionNameRepresentation { eName, eNameWithArgs, diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index 7c3f3c433bd9..fc70948d3a8e 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -28,9 +28,6 @@ #include "lldb/DataFormatters/DataVisualization.h" #include "lldb/DataFormatters/FormattersHelpers.h" #include "lldb/DataFormatters/VectorType.h" -#include "lldb/Symbol/SymbolFile.h" -#include "lldb/Symbol/TypeList.h" -#include "lldb/Target/Target.h" #include "BlockPointer.h" #include "CxxStringTypes.h" @@ -922,73 +919,17 @@ static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { } std::unique_ptr CPlusPlusLanguage::GetTypeScavenger() { - class CPlusPlusTypeScavenger : public Language::TypeScavenger { - private: - class CPlusPlusTypeScavengerResult : public Language::TypeScavenger::Result { - public: - CPlusPlusTypeScavengerResult(CompilerType type) - : Language::TypeScavenger::Result(), m_compiler_type(type) {} - - bool IsValid() override { return m_compiler_type.IsValid(); } - - bool DumpToStream(Stream &stream, bool print_help_if_available) override { - if (IsValid()) { - m_compiler_type.DumpTypeDescription(&stream); - stream.EOL(); - return true; - } - return false; - } - - ~CPlusPlusTypeScavengerResult() override = default; - - private: - CompilerType m_compiler_type; - }; - - protected: - CPlusPlusTypeScavenger() = default; - - ~CPlusPlusTypeScavenger() override = default; - - bool Find_Impl(ExecutionContextScope *exe_scope, const char *key, - ResultSet &results) override { - bool result = false; - - Target *target = exe_scope->CalculateTarget().get(); - if (target) { - const auto &images(target->GetImages()); - SymbolContext null_sc; - ConstString cs_key(key); - llvm::DenseSet searched_sym_files; - TypeList matches; - images.FindTypes(null_sc, - cs_key, - false, - UINT32_MAX, - searched_sym_files, - matches); - for (const auto& match : matches.Types()) { - if (match.get()) { - CompilerType compiler_type(match->GetFullCompilerType()); - LanguageType lang_type(compiler_type.GetMinimumLanguage()); - // other plugins will find types for other languages - here we only do C and C++ - if (!Language::LanguageIsC(lang_type) && !Language::LanguageIsCPlusPlus(lang_type)) - continue; - if (compiler_type.IsTypedefType()) - compiler_type = compiler_type.GetTypedefedType(); - std::unique_ptr scavengeresult( - new CPlusPlusTypeScavengerResult(compiler_type)); - results.insert(std::move(scavengeresult)); - result = true; - } - } - } - - return result; + class CPlusPlusTypeScavenger : public Language::ImageListTypeScavenger { + public: + virtual CompilerType AdjustForInclusion(CompilerType &candidate) override { + LanguageType lang_type(candidate.GetMinimumLanguage()); + if (!Language::LanguageIsC(lang_type) && + !Language::LanguageIsCPlusPlus(lang_type)) + return CompilerType(); + if (candidate.IsTypedefType()) + return candidate.GetTypedefedType(); + return candidate; } - - friend class lldb_private::CPlusPlusLanguage; }; return std::unique_ptr(new CPlusPlusTypeScavenger()); diff --git a/lldb/source/Target/Language.cpp b/lldb/source/Target/Language.cpp index 904c18780f47..938d80ac1758 100644 --- a/lldb/source/Target/Language.cpp +++ b/lldb/source/Target/Language.cpp @@ -16,6 +16,9 @@ #include "lldb/Core/PluginManager.h" #include "lldb/Core/Stream.h" +#include "lldb/Symbol/SymbolFile.h" +#include "lldb/Symbol/TypeList.h" +#include "lldb/Target/Target.h" using namespace lldb; using namespace lldb_private; @@ -341,6 +344,36 @@ size_t Language::TypeScavenger::Find(ExecutionContextScope *exe_scope, return 0; } +bool Language::ImageListTypeScavenger::Find_Impl( + ExecutionContextScope *exe_scope, const char *key, ResultSet &results) { + bool result = false; + + Target *target = exe_scope->CalculateTarget().get(); + if (target) { + const auto &images(target->GetImages()); + SymbolContext null_sc; + ConstString cs_key(key); + llvm::DenseSet searched_sym_files; + TypeList matches; + images.FindTypes(null_sc, cs_key, false, UINT32_MAX, searched_sym_files, + matches); + for (const auto &match : matches.Types()) { + if (match.get()) { + CompilerType compiler_type(match->GetFullCompilerType()); + compiler_type = AdjustForInclusion(compiler_type); + if (!compiler_type) + continue; + std::unique_ptr scavengeresult( + new Result(compiler_type)); + results.insert(std::move(scavengeresult)); + result = true; + } + } + } + + return result; +} + bool Language::GetFormatterPrefixSuffix(ValueObject &valobj, ConstString type_hint, std::string &prefix,