forked from OSchip/llvm-project
Add an helper class lldb.formatters.synth.PythonObjectSyntheticChildProvider
This class enables one to easily write a synthetic child provider by writing a class that returns pairs of names and primitive Python values - the base class then converts those into LLDB SBValues Comes with a test case llvm-svn: 280172
This commit is contained in:
parent
d01704b149
commit
42ff957e25
|
@ -0,0 +1,57 @@
|
|||
import lldb
|
||||
|
||||
class PythonObjectSyntheticChildProvider(object):
|
||||
def __init__(self, value, internal_dict):
|
||||
self.value = value
|
||||
self.values = self.make_children()
|
||||
self.built_values = {}
|
||||
self.bo = self.value.target.byte_order
|
||||
self.ps = self.value.target.addr_size
|
||||
|
||||
def make_children(self):
|
||||
pass
|
||||
|
||||
def num_children(self):
|
||||
return len(self.values)
|
||||
|
||||
def get_child_index(self, name):
|
||||
i = 0
|
||||
for N, value in self.values:
|
||||
if N == name: return i
|
||||
i += 1
|
||||
return None
|
||||
|
||||
def update(self):
|
||||
pass
|
||||
|
||||
def has_children(self):
|
||||
return len(self.values) > 0
|
||||
|
||||
def gen_child(self, name, value):
|
||||
data = None; type = None
|
||||
if isinstance(value, int):
|
||||
data = lldb.SBData.CreateDataFromUInt32Array(self.bo, self.ps, [value])
|
||||
type = self.value.target.GetBasicType(lldb.eBasicTypeInt)
|
||||
elif isinstance(value, long):
|
||||
data = lldb.SBData.CreateDataFromUInt64Array(self.bo, self.ps, [value])
|
||||
type = self.value.target.GetBasicType(lldb.eBasicTypeLong)
|
||||
elif isinstance(value, float):
|
||||
data = lldb.SBData.CreateDataFromDoubleArray(self.bo, self.ps, [value])
|
||||
type = self.value.target.GetBasicType(lldb.eBasicTypeDouble)
|
||||
elif isinstance(value, str):
|
||||
data = lldb.SBData.CreateDataFromCString(self.bo, self.ps, value)
|
||||
type = self.value.target.GetBasicType(lldb.eBasicTypeChar).GetArrayType(len(value))
|
||||
if (data is not None) and (type is not None):
|
||||
return self.value.CreateValueFromData(name, data, type)
|
||||
return None
|
||||
|
||||
def get_child_at_index(self, index):
|
||||
if index in self.built_values:
|
||||
return self.built_values[index]
|
||||
|
||||
bv = None
|
||||
|
||||
name, value = self.values[index]
|
||||
bv = self.gen_child(name, value)
|
||||
self.built_values[index] = bv
|
||||
return bv
|
|
@ -0,0 +1,5 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
CXX_SOURCES := main.cpp
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -0,0 +1,58 @@
|
|||
"""
|
||||
Test lldb data formatter subsystem.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
|
||||
|
||||
import datetime
|
||||
import os, time
|
||||
import lldb
|
||||
from lldbsuite.test.decorators import *
|
||||
from lldbsuite.test.lldbtest import *
|
||||
from lldbsuite.test import lldbutil
|
||||
|
||||
class PrintArrayTestCase(TestBase):
|
||||
|
||||
mydir = TestBase.compute_mydir(__file__)
|
||||
|
||||
def test_print_array(self):
|
||||
"""Test that expr -Z works"""
|
||||
self.build()
|
||||
self.provider_data_formatter_commands()
|
||||
|
||||
def setUp(self):
|
||||
# Call super's setUp().
|
||||
TestBase.setUp(self)
|
||||
# Find the line number to break at.
|
||||
self.line = line_number('main.cpp', 'break here')
|
||||
|
||||
def provider_data_formatter_commands(self):
|
||||
"""Test that the PythonObjectSyntheticChildProvider helper class works"""
|
||||
self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
|
||||
|
||||
lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
|
||||
|
||||
self.runCmd("run", RUN_SUCCEEDED)
|
||||
|
||||
# The stop reason of the thread should be breakpoint.
|
||||
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
|
||||
substrs = ['stopped',
|
||||
'stop reason = breakpoint'])
|
||||
|
||||
# This is the function to remove the custom formats in order to have a
|
||||
# clean slate for the next test case.
|
||||
def cleanup():
|
||||
self.runCmd('type format clear', check=False)
|
||||
self.runCmd('type summary clear', check=False)
|
||||
self.runCmd('type synth clear', check=False)
|
||||
|
||||
# Execute the cleanup function during test case tear down.
|
||||
self.addTearDownHook(cleanup)
|
||||
|
||||
self.runCmd('command script import provider.py')
|
||||
self.runCmd('type synthetic add Foo --python-class provider.SyntheticChildrenProvider')
|
||||
self.expect('frame variable f.Name', substrs=['"Enrico"'])
|
||||
self.expect('frame variable f', substrs=['ID = 123456', 'Name = "Enrico"', 'Rate = 1.25'])
|
||||
self.expect('expression f', substrs=['ID = 123456', 'Name = "Enrico"', 'Rate = 1.25'])
|
|
@ -0,0 +1,20 @@
|
|||
//===-- main.cpp -------------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
struct Foo
|
||||
{
|
||||
double x;
|
||||
int y;
|
||||
Foo() : x(3.1415), y(1234) {}
|
||||
};
|
||||
|
||||
int main() {
|
||||
Foo f;
|
||||
return 0; // break here
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
import lldb
|
||||
import lldb.formatters
|
||||
|
||||
class SyntheticChildrenProvider(lldb.formatters.synth.PythonObjectSyntheticChildProvider):
|
||||
def __init__(self, value, internal_dict):
|
||||
lldb.formatters.synth.PythonObjectSyntheticChildProvider.__init__(self, value, internal_dict)
|
||||
|
||||
def make_children(self):
|
||||
return [("ID", 123456),
|
||||
("Name", "Enrico"),
|
||||
("Rate", 1.25)]
|
||||
|
|
@ -273,6 +273,7 @@ create_python_package "/runtime" ""
|
|||
# lldb/formatters
|
||||
# having these files copied here ensures that lldb/formatters is a valid package itself
|
||||
package_files="${SRC_ROOT}/examples/summaries/cocoa/cache.py
|
||||
${SRC_ROOT}/examples/summaries/synth.py
|
||||
${SRC_ROOT}/examples/summaries/cocoa/metrics.py
|
||||
${SRC_ROOT}/examples/summaries/cocoa/attrib_fromdict.py
|
||||
${SRC_ROOT}/examples/summaries/cocoa/Logger.py"
|
||||
|
|
Loading…
Reference in New Issue