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;
};
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,

View File

@ -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<Language::TypeScavenger> CPlusPlusLanguage::GetTypeScavenger() {
class CPlusPlusTypeScavenger : public Language::TypeScavenger {
private:
class CPlusPlusTypeScavengerResult : public Language::TypeScavenger::Result {
class CPlusPlusTypeScavenger : public Language::ImageListTypeScavenger {
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;
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;
}
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());

View File

@ -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<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,
ConstString type_hint,
std::string &prefix,