modify-python-lldb.py: clean up __iter__ and __len__ support

Summary:
Instead of modifying the swig-generated code, just add the appropriate
methods to the interface files in order to get the swig to do the
generation for us.

This is a straight-forward move from the python script to the interface
files. The single class which has nontrivial handling in the script
(SBModule) has been left for a separate patch.

For the cases where I did not find any tests exercising the
iteration/length methods (i.e., no tests failed after I stopped emitting
them), I tried to add basic tests for that functionality.

Reviewers: zturner, jingham, amccarth

Subscribers: jdoerfert, lldb-commits

Differential Revision: https://reviews.llvm.org/D60119

llvm-svn: 357572
This commit is contained in:
Pavel Labath 2019-04-03 11:48:38 +00:00
parent 02599de2e1
commit 4da5a1dbab
20 changed files with 130 additions and 36 deletions

View File

@ -34,6 +34,9 @@ class DebuggerAPITestCase(TestBase):
self.dbg.SetPrompt(None)
self.dbg.SetCurrentPlatform(None)
self.dbg.SetCurrentPlatformSDKRoot(None)
fresh_dbg = lldb.SBDebugger()
self.assertEquals(len(fresh_dbg), 0)
@add_test_categories(['pyapi'])
def test_debugger_delete_invalid_target(self):

View File

@ -12,5 +12,6 @@ def fuzz_obj(obj):
obj.GetLineEntryAtIndex(0xffffffff)
obj.FindLineEntryIndex(0, 0xffffffff, None)
obj.GetDescription(lldb.SBStream())
len(obj)
for line_entry in obj:
s = str(line_entry)

View File

@ -48,3 +48,4 @@ def fuzz_obj(obj):
obj.GetNumSupportedHardwareWatchpoints(error)
for thread in obj:
s = str(thread)
len(obj)

View File

@ -21,3 +21,4 @@ def fuzz_obj(obj):
obj.GetDescription(lldb.SBStream())
for subsec in obj:
s = str(subsec)
len(obj)

View File

@ -36,3 +36,4 @@ def fuzz_obj(obj):
obj.Clear()
for frame in obj:
s = str(frame)
len(obj)

View File

@ -102,3 +102,9 @@ class SymbolContextAPITestCase(TestBase):
self.assertTrue(
function.GetName() == symbol.GetName() and symbol.GetName() == 'c',
"The symbol name should be 'c'")
sc_list = lldb.SBSymbolContextList()
sc_list.Append(context)
self.assertEqual(len(sc_list), 1)
for sc in sc_list:
self.assertEqual(lineEntry, sc.GetLineEntry())

View File

@ -77,9 +77,6 @@ one_liner_docstring_pattern = re.compile(
# This supports the iteration protocol.
iter_def = " def __iter__(self): return lldb_iter(self, '%s', '%s')"
module_iter = " def module_iter(self): return lldb_iter(self, '%s', '%s')"
breakpoint_iter = " def breakpoint_iter(self): return lldb_iter(self, '%s', '%s')"
watchpoint_iter = " def watchpoint_iter(self): return lldb_iter(self, '%s', '%s')"
section_iter = " def section_iter(self): return lldb_iter(self, '%s', '%s')"
compile_unit_iter = " def compile_unit_iter(self): return lldb_iter(self, '%s', '%s')"
@ -100,28 +97,7 @@ symbol_in_section_iter_def = '''
#
# This dictionary defines a mapping from classname to (getsize, getelem) tuple.
#
d = {'SBBreakpoint': ('GetNumLocations', 'GetLocationAtIndex'),
'SBCompileUnit': ('GetNumLineEntries', 'GetLineEntryAtIndex'),
'SBDebugger': ('GetNumTargets', 'GetTargetAtIndex'),
'SBModule': ('GetNumSymbols', 'GetSymbolAtIndex'),
'SBProcess': ('GetNumThreads', 'GetThreadAtIndex'),
'SBSection': ('GetNumSubSections', 'GetSubSectionAtIndex'),
'SBThread': ('GetNumFrames', 'GetFrameAtIndex'),
'SBInstructionList': ('GetSize', 'GetInstructionAtIndex'),
'SBStringList': ('GetSize', 'GetStringAtIndex',),
'SBSymbolContextList': ('GetSize', 'GetContextAtIndex'),
'SBTypeList': ('GetSize', 'GetTypeAtIndex'),
'SBValueList': ('GetSize', 'GetValueAtIndex'),
'SBType': ('GetNumberChildren', 'GetChildAtIndex'),
'SBValue': ('GetNumChildren', 'GetChildAtIndex'),
# SBTarget needs special processing, see below.
'SBTarget': {'module': ('GetNumModules', 'GetModuleAtIndex'),
'breakpoint': ('GetNumBreakpoints', 'GetBreakpointAtIndex'),
'watchpoint': ('GetNumWatchpoints', 'GetWatchpointAtIndex')
},
d = {'SBModule': ('GetNumSymbols', 'GetSymbolAtIndex'),
# SBModule has an additional section_iter(), see below.
'SBModule-section': ('GetNumSections', 'GetSectionAtIndex'),
@ -238,16 +214,9 @@ for line in content.splitlines():
if match:
# We found the beginning of the __init__ method definition.
# This is a good spot to insert the iter support.
#
# But note that SBTarget has three types of iterations.
if cls == "SBTarget":
new_content.add_line(module_iter % (d[cls]['module']))
new_content.add_line(breakpoint_iter % (d[cls]['breakpoint']))
new_content.add_line(watchpoint_iter % (d[cls]['watchpoint']))
else:
if (state & DEFINING_ITERATOR):
new_content.add_line(iter_def % d[cls])
new_content.add_line(len_def % d[cls][0])
new_content.add_line(iter_def % d[cls])
new_content.add_line(len_def % d[cls][0])
# SBModule has extra SBSection, SBCompileUnit iterators and
# symbol_in_section_iter()!

View File

@ -287,7 +287,17 @@ public:
for idx in range(len(accessor)):
locations.append(accessor[idx])
return locations
def __iter__(self):
'''Iterate over all breakpoint locations in a lldb.SBBreakpoint
object.'''
return lldb_iter(self, 'GetNumLocations', 'GetLocationAtIndex')
def __len__(self):
'''Return the number of breakpoint locations in a lldb.SBBreakpoint
object.'''
return self.GetNumLocations()
__swig_getmethods__["locations"] = get_breakpoint_location_list
if _newclass: locations = property(get_breakpoint_location_list, None, doc='''A read only property that returns a list() of lldb.SBBreakpointLocation objects for this breakpoint.''')

View File

@ -120,6 +120,15 @@ public:
operator != (const lldb::SBCompileUnit &rhs) const;
%pythoncode %{
def __iter__(self):
'''Iterate over all line entries in a lldb.SBCompileUnit object.'''
return lldb_iter(self, 'GetNumLineEntries', 'GetLineEntryAtIndex')
def __len__(self):
'''Return the number of line entries in a lldb.SBCompileUnit
object.'''
return self.GetNumLineEntries()
__swig_getmethods__["file"] = GetFileSpec
if _newclass: file = property(GetFileSpec, None, doc='''A read only property that returns the same result an lldb object that represents the source file (lldb.SBFileSpec) for the compile unit.''')

View File

@ -435,6 +435,17 @@ public:
lldb::SBError
RunREPL (lldb::LanguageType language, const char *repl_options);
%pythoncode%{
def __iter__(self):
'''Iterate over all targets in a lldb.SBDebugger object.'''
return lldb_iter(self, 'GetNumTargets', 'GetTargetAtIndex')
def __len__(self):
'''Return the number of targets in a lldb.SBDebugger object.'''
return self.GetNumTargets()
%}
}; // class SBDebugger
} // namespace lldb

View File

@ -64,6 +64,11 @@ public:
DumpEmulationForAllInstructions (const char *triple);
%pythoncode %{
def __iter__(self):
'''Iterate over all instructions in a lldb.SBInstructionList
object.'''
return lldb_iter(self, 'GetSize', 'GetInstructionAtIndex')
def __len__(self):
'''Access len of the instruction list.'''
return int(self.GetSize())

View File

@ -497,6 +497,15 @@ public:
for idx in range(len(accessor)):
threads.append(accessor[idx])
return threads
def __iter__(self):
'''Iterate over all threads in a lldb.SBProcess object.'''
return lldb_iter(self, 'GetNumThreads', 'GetThreadAtIndex')
def __len__(self):
'''Return the number of threads in a lldb.SBProcess object.'''
return self.GetNumThreads()
__swig_getmethods__["threads"] = get_process_thread_list
if _newclass: threads = property(get_process_thread_list, None, doc='''A read only property that returns a list() of lldb.SBThread objects for this process.''')

View File

@ -118,6 +118,14 @@ public:
operator != (const lldb::SBSection &rhs);
%pythoncode %{
def __iter__(self):
'''Iterate over all subsections in a lldb.SBSection object.'''
return lldb_iter(self, 'GetNumSubSections', 'GetSubSectionAtIndex')
def __len__(self):
'''Return the number of subsections in a lldb.SBSection object.'''
return self.GetNumSubSections()
def get_addr(self):
return SBAddress(self, 0)

View File

@ -40,6 +40,16 @@ public:
void
Clear ();
%pythoncode%{
def __iter__(self):
'''Iterate over all strings in a lldb.SBStringList object.'''
return lldb_iter(self, 'GetSize', 'GetStringAtIndex')
def __len__(self):
'''Return the number of strings in a lldb.SBStringList object.'''
return self.GetSize()
%}
};
} // namespace lldb

View File

@ -62,6 +62,11 @@ public:
Clear();
%pythoncode %{
def __iter__(self):
'''Iterate over all symbol contexts in a lldb.SBSymbolContextList
object.'''
return lldb_iter(self, 'GetSize', 'GetContextAtIndex')
def __len__(self):
return int(self.GetSize())

View File

@ -1103,6 +1103,21 @@ public:
modules.append(self.GetModuleAtIndex(idx))
return modules
def module_iter(self):
'''Returns an iterator over all modules in a lldb.SBTarget
object.'''
return lldb_iter(self, 'GetNumModules', 'GetModuleAtIndex')
def breakpoint_iter(self):
'''Returns an iterator over all breakpoints in a lldb.SBTarget
object.'''
return lldb_iter(self, 'GetNumBreakpoints', 'GetBreakpointAtIndex')
def watchpoint_iter(self):
'''Returns an iterator over all watchpoints in a lldb.SBTarget
object.'''
return lldb_iter(self, 'GetNumWatchpoints', 'GetWatchpointAtIndex')
__swig_getmethods__["modules"] = get_modules_array
if _newclass: modules = property(get_modules_array, None, doc='''A read only property that returns a list() of lldb.SBModule objects contained in this target. This list is a list all modules that the target currently is tracking (the main executable and all dependent shared libraries).''')

View File

@ -428,6 +428,14 @@ public:
SafeToCallFunctions ();
%pythoncode %{
def __iter__(self):
'''Iterate over all frames in a lldb.SBThread object.'''
return lldb_iter(self, 'GetNumFrames', 'GetFrameAtIndex')
def __len__(self):
'''Return the number of frames in a lldb.SBThread object.'''
return self.GetNumFrames()
class frames_access(object):
'''A helper object that will lazily hand out frames for a thread when supplied an index.'''
def __init__(self, sbthread):

View File

@ -509,6 +509,16 @@ public:
GetSize();
~SBTypeList();
%pythoncode%{
def __iter__(self):
'''Iterate over all types in a lldb.SBTypeList object.'''
return lldb_iter(self, 'GetSize', 'GetTypeAtIndex')
def __len__(self):
'''Return the number of types in a lldb.SBTypeList object.'''
return self.GetSize()
%}
};
} // namespace lldb

View File

@ -495,6 +495,14 @@ public:
for idx in range(len(accessor)):
children.append(accessor[idx])
return children
def __iter__(self):
'''Iterate over all child values of a lldb.SBValue object.'''
return lldb_iter(self, 'GetNumChildren', 'GetChildAtIndex')
def __len__(self):
'''Return the number of child values of a lldb.SBValue object.'''
return self.GetNumChildren()
__swig_getmethods__["children"] = get_value_child_list
if _newclass: children = property(get_value_child_list, None, doc='''A read only property that returns a list() of lldb.SBValue objects for the children of the value.''')

View File

@ -102,6 +102,10 @@ public:
GetFirstValueByName (const char* name) const;
%pythoncode %{
def __iter__(self):
'''Iterate over all values in a lldb.SBValueList object.'''
return lldb_iter(self, 'GetSize', 'GetValueAtIndex')
def __len__(self):
return int(self.GetSize())