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
This commit is contained in:
Enrico Granata 2016-11-01 18:50:49 +00:00
parent 4190199568
commit 63db2395f6
3 changed files with 81 additions and 69 deletions

View File

@ -57,6 +57,44 @@ public:
ResultSet &results) = 0; 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 { enum class FunctionNameRepresentation {
eName, eName,
eNameWithArgs, eNameWithArgs,

View File

@ -28,9 +28,6 @@
#include "lldb/DataFormatters/DataVisualization.h" #include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/DataFormatters/FormattersHelpers.h" #include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/DataFormatters/VectorType.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 "BlockPointer.h"
#include "CxxStringTypes.h" #include "CxxStringTypes.h"
@ -922,73 +919,17 @@ static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
} }
std::unique_ptr<Language::TypeScavenger> CPlusPlusLanguage::GetTypeScavenger() { std::unique_ptr<Language::TypeScavenger> CPlusPlusLanguage::GetTypeScavenger() {
class CPlusPlusTypeScavenger : public Language::TypeScavenger { class CPlusPlusTypeScavenger : public Language::ImageListTypeScavenger {
private:
class CPlusPlusTypeScavengerResult : public Language::TypeScavenger::Result {
public: public:
CPlusPlusTypeScavengerResult(CompilerType type) virtual CompilerType AdjustForInclusion(CompilerType &candidate) override {
: Language::TypeScavenger::Result(), m_compiler_type(type) {} LanguageType lang_type(candidate.GetMinimumLanguage());
if (!Language::LanguageIsC(lang_type) &&
bool IsValid() override { return m_compiler_type.IsValid(); } !Language::LanguageIsCPlusPlus(lang_type))
return CompilerType();
bool DumpToStream(Stream &stream, bool print_help_if_available) override { if (candidate.IsTypedefType())
if (IsValid()) { return candidate.GetTypedefedType();
m_compiler_type.DumpTypeDescription(&stream); return candidate;
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<SymbolFile*> 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<Language::TypeScavenger::Result> scavengeresult(
new CPlusPlusTypeScavengerResult(compiler_type));
results.insert(std::move(scavengeresult));
result = true;
}
}
}
return result;
}
friend class lldb_private::CPlusPlusLanguage;
}; };
return std::unique_ptr<TypeScavenger>(new CPlusPlusTypeScavenger()); return std::unique_ptr<TypeScavenger>(new CPlusPlusTypeScavenger());

View File

@ -16,6 +16,9 @@
#include "lldb/Core/PluginManager.h" #include "lldb/Core/PluginManager.h"
#include "lldb/Core/Stream.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;
using namespace lldb_private; using namespace lldb_private;
@ -341,6 +344,36 @@ size_t Language::TypeScavenger::Find(ExecutionContextScope *exe_scope,
return 0; 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<SymbolFile *> 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<Language::TypeScavenger::Result> scavengeresult(
new Result(compiler_type));
results.insert(std::move(scavengeresult));
result = true;
}
}
}
return result;
}
bool Language::GetFormatterPrefixSuffix(ValueObject &valobj, bool Language::GetFormatterPrefixSuffix(ValueObject &valobj,
ConstString type_hint, ConstString type_hint,
std::string &prefix, std::string &prefix,