Skip to content

Commit d9e4405

Browse files
authored
Merge pull request #1843 from jimingham/type-enum-iterators
Add python enumerators for SBTypeEnumMemberList, and some tests for t…
2 parents c410cd3 + 815b4c0 commit d9e4405

File tree

3 files changed

+80
-13
lines changed

3 files changed

+80
-13
lines changed

lldb/bindings/interface/SBTypeEnumMember.i

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,18 @@ protected:
7171
SBTypeEnumMember (const lldb::TypeEnumMemberImplSP &);
7272
};
7373

74-
%feature(
75-
"docstring",
76-
"Represents a list of SBTypeEnumMembers."
77-
) SBTypeEnumMemberList;
74+
%feature("docstring",
75+
"Represents a list of SBTypeEnumMembers.
76+
SBTypeEnumMemberList supports SBTypeEnumMember iteration.
77+
It also supports [] access either by index, or by enum
78+
element name by doing:
79+
80+
myType = target.FindFirstType('MyEnumWithElementA')
81+
members = myType.GetEnumMembers()
82+
first_elem = members[0]
83+
elem_A = members['A']
84+
85+
") SBTypeEnumMemberList;
7886

7987
class SBTypeEnumMemberList
8088
{
@@ -99,6 +107,29 @@ public:
99107
uint32_t
100108
GetSize();
101109

110+
#ifdef SWIGPYTHON
111+
%pythoncode %{
112+
def __iter__(self):
113+
'''Iterate over all members in a lldb.SBTypeEnumMemberList object.'''
114+
return lldb_iter(self, 'GetSize', 'GetTypeEnumMemberAtIndex')
115+
116+
def __len__(self):
117+
'''Return the number of members in a lldb.SBTypeEnumMemberList object.'''
118+
return self.GetSize()
119+
120+
def __getitem__(self, key):
121+
num_elements = self.GetSize()
122+
if type(key) is int:
123+
if key < num_elements:
124+
return self.GetTypeEnumMemberAtIndex(key)
125+
elif type(key) is str:
126+
for idx in range(num_elements):
127+
item = self.GetTypeEnumMemberAtIndex(idx)
128+
if item.name == key:
129+
return item
130+
return None
131+
%}
132+
#endif
102133

103134
private:
104135
std::unique_ptr<lldb_private::TypeEnumMemberListImpl> m_opaque_ap;

lldb/test/API/lang/c/enum_types/TestEnumTypes.py

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,9 @@ def setUp(self):
1818
# Find the line number to break inside main().
1919
self.line = line_number('main.c', '// Set break point at this line.')
2020

21-
def test(self):
22-
"""Test 'image lookup -t days' and check for correct display and enum value printing."""
21+
def test_command_line(self):
22+
"""Test 'image lookup -t enum_test_days' and check for correct display and enum value printing."""
2323
self.build()
24-
exe = self.getBuildArtifact("a.out")
25-
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
2624

2725
lldbutil.run_to_source_breakpoint(
2826
self, '// Breakpoint for bitfield', lldb.SBFileSpec("main.c"))
@@ -63,10 +61,10 @@ def test(self):
6361
self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
6462
substrs=[' resolved, hit count = 1'])
6563

66-
# Look up information about the 'days' enum type.
64+
# Look up information about the 'enum_test_days' enum type.
6765
# Check for correct display.
68-
self.expect("image lookup -t days", DATA_TYPES_DISPLAYED_CORRECTLY,
69-
substrs=['enum days {',
66+
self.expect("image lookup -t enum_test_days", DATA_TYPES_DISPLAYED_CORRECTLY,
67+
substrs=['enum enum_test_days {',
7068
'Monday',
7169
'Tuesday',
7270
'Wednesday',
@@ -124,3 +122,41 @@ def test(self):
124122
'check for valid enumeration value',
125123
substrs=[enum_value])
126124
lldbutil.continue_to_breakpoint(self.process(), bkpt)
125+
126+
def check_enum_members(self, members):
127+
name_matches = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday", "kNumDays"]
128+
value_matches = [-3, -2, -1, 0, 1, 2, 3, 4]
129+
130+
# First test that the list of members from the type works
131+
num_matches = len(name_matches)
132+
self.assertEqual(len(members), num_matches, "enum_members returns the right number of elements")
133+
for idx in range(0, num_matches):
134+
member = members[idx]
135+
self.assertTrue(member.IsValid(), "Got a valid member for idx: %d"%(idx))
136+
self.assertEqual(member.name, name_matches[idx], "Name matches for %d"%(idx))
137+
self.assertEqual(member.signed, value_matches[idx], "Value matches for %d"%(idx))
138+
139+
def test_api(self):
140+
"""Test the the SBTypeEnumMember API's work correctly for enum_test_days"""
141+
self.build()
142+
target = lldbutil.run_to_breakpoint_make_target(self)
143+
144+
types = target.FindTypes("enum_test_days")
145+
self.assertEqual(len(types), 1, "Found more than one enum_test_days type...")
146+
type = types.GetTypeAtIndex(0)
147+
148+
# First check using the Python list returned by the type:
149+
self.check_enum_members(type.enum_members)
150+
151+
# Now use the SBTypeEnumMemberList.
152+
member_list = type.GetEnumMembers()
153+
self.check_enum_members(member_list)
154+
155+
# Now check that the by name accessor works:
156+
for member in member_list:
157+
name = member.name
158+
check_member = member_list[name]
159+
self.assertTrue(check_member.IsValid(), "Got a valid member for %s."%(name))
160+
self.assertEqual(name, check_member.name, "Got back the right name")
161+
self.assertEqual(member.unsigned, check_member.unsigned)
162+

lldb/test/API/lang/c/enum_types/main.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ int main (int argc, char const *argv[])
2525
Beta = 4
2626
};
2727

28-
enum days {
28+
enum enum_test_days {
2929
Monday = -3,
3030
Tuesday,
3131
Wednesday,
@@ -40,7 +40,7 @@ int main (int argc, char const *argv[])
4040
int nonsense = a + b + c + ab + ac + all;
4141
enum non_bitfield omega = Alpha | Beta;
4242

43-
enum days day;
43+
enum enum_test_days day;
4444
struct foo f;
4545
f.op = NULL; // Breakpoint for bitfield
4646
for (day = Monday - 1; day <= kNumDays + 1; day++)

0 commit comments

Comments
 (0)