forked from OSchip/llvm-project
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:
parent
c8efda7f80
commit
c046497bf0
|
@ -1,6 +1,6 @@
|
||||||
LEVEL = ../../make
|
LEVEL = ../../make
|
||||||
|
|
||||||
OBJC_SOURCES := main.m
|
OBJCXX_SOURCES := main.mm
|
||||||
|
|
||||||
CFLAGS_EXTRAS += -w
|
CFLAGS_EXTRAS += -w
|
||||||
|
|
||||||
|
|
|
@ -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'])
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue