xref: /llvm-project/lldb/bindings/interface/SBValueExtensions.i (revision 53fd724b256e1ccfcb04c90f7740f54e1801986d)
1 STRING_EXTENSION_OUTSIDE(SBValue)
2 %extend lldb::SBValue {
3 #ifdef SWIGPYTHON
4     %pythoncode %{
5         def __get_dynamic__ (self):
6             '''Helper function for the "SBValue.dynamic" property.'''
7             return self.GetDynamicValue (eDynamicCanRunTarget)
8 
9         class children_access(object):
10             '''A helper object that will lazily hand out child values when supplied an index.'''
11 
12             def __init__(self, sbvalue):
13                 self.sbvalue = sbvalue
14 
15             def __len__(self):
16                 if self.sbvalue:
17                     return int(self.sbvalue.GetNumChildren())
18                 return 0
19 
20             def __getitem__(self, key):
21                 if isinstance(key, int):
22                     count = len(self)
23                     if -count <= key < count:
24                         key %= count
25                         return self.sbvalue.GetChildAtIndex(key)
26                 return None
27 
28         def get_child_access_object(self):
29             '''An accessor function that returns a children_access() object which allows lazy member variable access from a lldb.SBValue object.'''
30             return self.children_access (self)
31 
32         def get_member_access_object(self):
33             '''An accessor function that returns an interface which provides subscript based lookup of child members.'''
34             class member_access:
35                 def __init__(self, valobj):
36                     self.valobj = valobj
37 
38                 def __getitem__(self, key):
39                     if isinstance(key, str):
40                         return self.valobj.GetChildMemberWithName(key)
41                     raise TypeError("member key must be a string")
42 
43             return member_access(self)
44 
45         def get_value_child_list(self):
46             '''An accessor function that returns a list() that contains all children in a lldb.SBValue object.'''
47             children = []
48             accessor = self.get_child_access_object()
49             for idx in range(len(accessor)):
50                 children.append(accessor[idx])
51             return children
52 
53         def __hex__(self):
54             return self.GetAddress()
55 
56         def __iter__(self):
57             '''Iterate over all child values of a lldb.SBValue object.'''
58             return lldb_iter(self, 'GetNumChildren', 'GetChildAtIndex')
59 
60         def __len__(self):
61             '''Return the number of child values of a lldb.SBValue object.'''
62             return self.GetNumChildren()
63 
64         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.''')
65         child = property(get_child_access_object, None, doc='''A read only property that returns an object that can access children of a variable by index (child_value = value.children[12]).''')
66         member = property(get_member_access_object, None, doc='''A read only property that returns an object that can access child members by name.''')
67         name = property(GetName, None, doc='''A read only property that returns the name of this value as a string.''')
68         type = property(GetType, None, doc='''A read only property that returns a lldb.SBType object that represents the type for this value.''')
69         size = property(GetByteSize, None, doc='''A read only property that returns the size in bytes of this value.''')
70         is_in_scope = property(IsInScope, None, doc='''A read only property that returns a boolean value that indicates whether this value is currently lexically in scope.''')
71         format = property(GetName, SetFormat, doc='''A read/write property that gets/sets the format used for lldb.SBValue().GetValue() for this value. See enumerations that start with "lldb.eFormat".''')
72         value = property(GetValue, SetValueFromCString, doc='''A read/write property that gets/sets value from a string.''')
73         value_type = property(GetValueType, None, doc='''A read only property that returns an lldb enumeration value (see enumerations that start with "lldb.eValueType") that represents the type of this value (local, argument, global, register, etc.).''')
74         changed = property(GetValueDidChange, None, doc='''A read only property that returns a boolean value that indicates if this value has changed since it was last updated.''')
75         data = property(GetData, None, doc='''A read only property that returns an lldb object (lldb.SBData) that represents the bytes that make up the value for this object.''')
76         load_addr = property(GetLoadAddress, None, doc='''A read only property that returns the load address of this value as an integer.''')
77         addr = property(GetAddress, None, doc='''A read only property that returns an lldb.SBAddress that represents the address of this value if it is in memory.''')
78         deref = property(Dereference, None, doc='''A read only property that returns an lldb.SBValue that is created by dereferencing this value.''')
79         address_of = property(AddressOf, None, doc='''A read only property that returns an lldb.SBValue that represents the address-of this value.''')
80         error = property(GetError, None, doc='''A read only property that returns the lldb.SBError that represents the error from the last time the variable value was calculated.''')
81         summary = property(GetSummary, None, doc='''A read only property that returns the summary for this value as a string''')
82         description = property(GetObjectDescription, None, doc='''A read only property that returns the language-specific description of this value as a string''')
83         dynamic = property(__get_dynamic__, None, doc='''A read only property that returns an lldb.SBValue that is created by finding the dynamic type of this value.''')
84         location = property(GetLocation, None, doc='''A read only property that returns the location of this value as a string.''')
85         target = property(GetTarget, None, doc='''A read only property that returns the lldb.SBTarget that this value is associated with.''')
86         process = property(GetProcess, None, doc='''A read only property that returns the lldb.SBProcess that this value is associated with, the returned value might be invalid and should be tested.''')
87         thread = property(GetThread, None, doc='''A read only property that returns the lldb.SBThread that this value is associated with, the returned value might be invalid and should be tested.''')
88         frame = property(GetFrame, None, doc='''A read only property that returns the lldb.SBFrame that this value is associated with, the returned value might be invalid and should be tested.''')
89         num_children = property(GetNumChildren, None, doc='''A read only property that returns the number of child lldb.SBValues that this value has.''')
90         unsigned = property(GetValueAsUnsigned, None, doc='''A read only property that returns the value of this SBValue as an usigned integer.''')
91         signed = property(GetValueAsSigned, None, doc='''A read only property that returns the value of this SBValue as a signed integer.''')
92 
93         def get_expr_path(self):
94             s = SBStream()
95             self.GetExpressionPath (s)
96             return s.GetData()
97 
98         path = property(get_expr_path, None, doc='''A read only property that returns the expression path that one can use to reach this value in an expression.''')
99 
100         def synthetic_child_from_expression(self, name, expr, options=None):
101             if options is None: options = lldb.SBExpressionOptions()
102             child = self.CreateValueFromExpression(name, expr, options)
103             child.SetSyntheticChildrenGenerated(True)
104             return child
105 
106         def synthetic_child_from_data(self, name, data, type):
107             child = self.CreateValueFromData(name, data, type)
108             child.SetSyntheticChildrenGenerated(True)
109             return child
110 
111         def synthetic_child_from_address(self, name, addr, type):
112             child = self.CreateValueFromAddress(name, addr, type)
113             child.SetSyntheticChildrenGenerated(True)
114             return child
115 
116         def __eol_test(val):
117             """Default function for end of list test takes an SBValue object.
118 
119             Return True if val is invalid or it corresponds to a null pointer.
120             Otherwise, return False.
121             """
122             if not val or val.GetValueAsUnsigned() == 0:
123                 return True
124             else:
125                 return False
126 
127         # ==================================================
128         # Iterator for lldb.SBValue treated as a linked list
129         # ==================================================
130         def linked_list_iter(self, next_item_name, end_of_list_test=__eol_test):
131             """Generator adaptor to support iteration for SBValue as a linked list.
132 
133             linked_list_iter() is a special purpose iterator to treat the SBValue as
134             the head of a list data structure, where you specify the child member
135             name which points to the next item on the list and you specify the
136             end-of-list test function which takes an SBValue for an item and returns
137             True if EOL is reached and False if not.
138 
139             linked_list_iter() also detects infinite loop and bails out early.
140 
141             The end_of_list_test arg, if omitted, defaults to the __eol_test
142             function above.
143 
144             For example,
145 
146             # Get Frame #0.
147             ...
148 
149             # Get variable 'task_head'.
150             task_head = frame0.FindVariable('task_head')
151             ...
152 
153             for t in task_head.linked_list_iter('next'):
154                 print t
155             """
156             if end_of_list_test(self):
157                 return
158             item = self
159             visited = set()
160             try:
161                 while not end_of_list_test(item) and not item.GetValueAsUnsigned() in visited:
162                     visited.add(item.GetValueAsUnsigned())
163                     yield item
164                     # Prepare for the next iteration.
165                     item = item.GetChildMemberWithName(next_item_name)
166             except:
167                 # Exception occurred.  Stop the generator.
168                 pass
169 
170             return
171     %}
172 #endif
173 }
174