Add support for "type lookup" to find C and C++ types

This is an important first step in closing the functionality gap between "type lookup" and "images lookup -t"

rdar://28971388

llvm-svn: 285332
This commit is contained in:
Enrico Granata 2016-10-27 18:44:45 +00:00
parent c8efda7f80
commit c046497bf0
5 changed files with 104 additions and 4 deletions

View File

@ -1,6 +1,6 @@
LEVEL = ../../make LEVEL = ../../make
OBJC_SOURCES := main.m OBJCXX_SOURCES := main.mm
CFLAGS_EXTRAS += -w CFLAGS_EXTRAS += -w

View File

@ -22,7 +22,7 @@ class TypeLookupTestCase(TestBase):
# Call super's setUp(). # Call super's setUp().
TestBase.setUp(self) TestBase.setUp(self)
# Find the line number to break at. # Find the line number to break at.
self.line = line_number('main.m', '// break here') self.line = line_number('main.mm', '// break here')
@skipUnlessDarwin @skipUnlessDarwin
@skipIf(archs=['i386']) @skipIf(archs=['i386'])
@ -32,7 +32,7 @@ class TypeLookupTestCase(TestBase):
self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
lldbutil.run_break_set_by_file_and_line( lldbutil.run_break_set_by_file_and_line(
self, "main.m", self.line, num_expected_locations=1, loc_exact=True) self, "main.mm", self.line, num_expected_locations=1, loc_exact=True)
self.runCmd("run", RUN_SUCCEEDED) self.runCmd("run", RUN_SUCCEEDED)
@ -50,3 +50,5 @@ class TypeLookupTestCase(TestBase):
self.expect('type lookup NSObject', substrs=['NSObject', 'isa']) self.expect('type lookup NSObject', substrs=['NSObject', 'isa'])
self.expect('type lookup PleaseDontBeARealTypeThatExists', substrs=[ self.expect('type lookup PleaseDontBeARealTypeThatExists', substrs=[
"no type was found matching 'PleaseDontBeARealTypeThatExists'"]) "no type was found matching 'PleaseDontBeARealTypeThatExists'"])
self.expect('type lookup MyCPPClass', substrs=['setF', 'float getF'])
self.expect('type lookup MyClass', substrs=['setF', 'float getF'])

View File

@ -1,4 +1,4 @@
//===-- main.m ------------------------------------------------*- ObjC -*-===// //===-- main.mm -----------------------------------------------*- ObjC -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -9,8 +9,28 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
class MyCPPClass {
public:
MyCPPClass(float f) : f(f) {}
float setF(float f) {
float oldf = this->f;
this->f = f;
return oldf;
}
float getF() {
return f;
}
private:
float f;
};
typedef MyCPPClass MyClass;
int main (int argc, const char * argv[]) int main (int argc, const char * argv[])
{ {
MyClass my_cpp(3.1415);
return 0; // break here return 0; // break here
} }

View File

@ -28,6 +28,9 @@
#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"
@ -918,6 +921,79 @@ static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
#endif #endif
} }
std::unique_ptr<Language::TypeScavenger> 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<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());
}
lldb::TypeCategoryImplSP CPlusPlusLanguage::GetFormatters() { lldb::TypeCategoryImplSP CPlusPlusLanguage::GetFormatters() {
static std::once_flag g_initialize; static std::once_flag g_initialize;
static TypeCategoryImplSP g_category; static TypeCategoryImplSP g_category;

View File

@ -92,6 +92,8 @@ public:
return lldb::eLanguageTypeC_plus_plus; return lldb::eLanguageTypeC_plus_plus;
} }
std::unique_ptr<TypeScavenger> GetTypeScavenger() override;
lldb::TypeCategoryImplSP GetFormatters() override; lldb::TypeCategoryImplSP GetFormatters() override;
HardcodedFormatters::HardcodedSummaryFinder GetHardcodedSummaries() override; HardcodedFormatters::HardcodedSummaryFinder GetHardcodedSummaries() override;