xref: /freebsd/contrib/llvm-project/lldb/bindings/interface/SBValueExtensions.i (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
106c3fb27SDimitry Andric STRING_EXTENSION_OUTSIDE(SBValue)
206c3fb27SDimitry Andric %extend lldb::SBValue {
306c3fb27SDimitry Andric #ifdef SWIGPYTHON
406c3fb27SDimitry Andric     %pythoncode %{
506c3fb27SDimitry Andric         def __get_dynamic__ (self):
606c3fb27SDimitry Andric             '''Helper function for the "SBValue.dynamic" property.'''
706c3fb27SDimitry Andric             return self.GetDynamicValue (eDynamicCanRunTarget)
806c3fb27SDimitry Andric 
906c3fb27SDimitry Andric         class children_access(object):
1006c3fb27SDimitry Andric             '''A helper object that will lazily hand out thread for a process when supplied an index.'''
1106c3fb27SDimitry Andric 
1206c3fb27SDimitry Andric             def __init__(self, sbvalue):
1306c3fb27SDimitry Andric                 self.sbvalue = sbvalue
1406c3fb27SDimitry Andric 
1506c3fb27SDimitry Andric             def __len__(self):
1606c3fb27SDimitry Andric                 if self.sbvalue:
1706c3fb27SDimitry Andric                     return int(self.sbvalue.GetNumChildren())
1806c3fb27SDimitry Andric                 return 0
1906c3fb27SDimitry Andric 
2006c3fb27SDimitry Andric             def __getitem__(self, key):
2106c3fb27SDimitry Andric                 if isinstance(key, int):
2206c3fb27SDimitry Andric                     count = len(self)
2306c3fb27SDimitry Andric                     if -count <= key < count:
2406c3fb27SDimitry Andric                         key %= count
2506c3fb27SDimitry Andric                         return self.sbvalue.GetChildAtIndex(key)
2606c3fb27SDimitry Andric                 return None
2706c3fb27SDimitry Andric 
2806c3fb27SDimitry Andric         def get_child_access_object(self):
2906c3fb27SDimitry Andric             '''An accessor function that returns a children_access() object which allows lazy member variable access from a lldb.SBValue object.'''
3006c3fb27SDimitry Andric             return self.children_access (self)
3106c3fb27SDimitry Andric 
3206c3fb27SDimitry Andric         def get_value_child_list(self):
3306c3fb27SDimitry Andric             '''An accessor function that returns a list() that contains all children in a lldb.SBValue object.'''
3406c3fb27SDimitry Andric             children = []
3506c3fb27SDimitry Andric             accessor = self.get_child_access_object()
3606c3fb27SDimitry Andric             for idx in range(len(accessor)):
3706c3fb27SDimitry Andric                 children.append(accessor[idx])
3806c3fb27SDimitry Andric             return children
3906c3fb27SDimitry Andric 
40*5f757f3fSDimitry Andric         def __hex__(self):
41*5f757f3fSDimitry Andric             return self.GetAddress()
42*5f757f3fSDimitry Andric 
4306c3fb27SDimitry Andric         def __iter__(self):
4406c3fb27SDimitry Andric             '''Iterate over all child values of a lldb.SBValue object.'''
4506c3fb27SDimitry Andric             return lldb_iter(self, 'GetNumChildren', 'GetChildAtIndex')
4606c3fb27SDimitry Andric 
4706c3fb27SDimitry Andric         def __len__(self):
4806c3fb27SDimitry Andric             '''Return the number of child values of a lldb.SBValue object.'''
4906c3fb27SDimitry Andric             return self.GetNumChildren()
5006c3fb27SDimitry Andric 
5106c3fb27SDimitry Andric         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.''')
5206c3fb27SDimitry Andric         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]).''')
5306c3fb27SDimitry Andric         name = property(GetName, None, doc='''A read only property that returns the name of this value as a string.''')
5406c3fb27SDimitry Andric         type = property(GetType, None, doc='''A read only property that returns a lldb.SBType object that represents the type for this value.''')
5506c3fb27SDimitry Andric         size = property(GetByteSize, None, doc='''A read only property that returns the size in bytes of this value.''')
5606c3fb27SDimitry Andric         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.''')
5706c3fb27SDimitry Andric         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".''')
5806c3fb27SDimitry Andric         value = property(GetValue, SetValueFromCString, doc='''A read/write property that gets/sets value from a string.''')
5906c3fb27SDimitry Andric         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.).''')
6006c3fb27SDimitry Andric         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.''')
6106c3fb27SDimitry Andric         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.''')
6206c3fb27SDimitry Andric         load_addr = property(GetLoadAddress, None, doc='''A read only property that returns the load address of this value as an integer.''')
6306c3fb27SDimitry Andric         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.''')
6406c3fb27SDimitry Andric         deref = property(Dereference, None, doc='''A read only property that returns an lldb.SBValue that is created by dereferencing this value.''')
6506c3fb27SDimitry Andric         address_of = property(AddressOf, None, doc='''A read only property that returns an lldb.SBValue that represents the address-of this value.''')
6606c3fb27SDimitry Andric         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.''')
6706c3fb27SDimitry Andric         summary = property(GetSummary, None, doc='''A read only property that returns the summary for this value as a string''')
6806c3fb27SDimitry Andric         description = property(GetObjectDescription, None, doc='''A read only property that returns the language-specific description of this value as a string''')
6906c3fb27SDimitry Andric         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.''')
7006c3fb27SDimitry Andric         location = property(GetLocation, None, doc='''A read only property that returns the location of this value as a string.''')
7106c3fb27SDimitry Andric         target = property(GetTarget, None, doc='''A read only property that returns the lldb.SBTarget that this value is associated with.''')
7206c3fb27SDimitry Andric         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.''')
7306c3fb27SDimitry Andric         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.''')
7406c3fb27SDimitry Andric         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.''')
7506c3fb27SDimitry Andric         num_children = property(GetNumChildren, None, doc='''A read only property that returns the number of child lldb.SBValues that this value has.''')
7606c3fb27SDimitry Andric         unsigned = property(GetValueAsUnsigned, None, doc='''A read only property that returns the value of this SBValue as an usigned integer.''')
7706c3fb27SDimitry Andric         signed = property(GetValueAsSigned, None, doc='''A read only property that returns the value of this SBValue as a signed integer.''')
7806c3fb27SDimitry Andric 
7906c3fb27SDimitry Andric         def get_expr_path(self):
8006c3fb27SDimitry Andric             s = SBStream()
8106c3fb27SDimitry Andric             self.GetExpressionPath (s)
8206c3fb27SDimitry Andric             return s.GetData()
8306c3fb27SDimitry Andric 
8406c3fb27SDimitry Andric         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.''')
8506c3fb27SDimitry Andric 
8606c3fb27SDimitry Andric         def synthetic_child_from_expression(self, name, expr, options=None):
8706c3fb27SDimitry Andric             if options is None: options = lldb.SBExpressionOptions()
8806c3fb27SDimitry Andric             child = self.CreateValueFromExpression(name, expr, options)
8906c3fb27SDimitry Andric             child.SetSyntheticChildrenGenerated(True)
9006c3fb27SDimitry Andric             return child
9106c3fb27SDimitry Andric 
9206c3fb27SDimitry Andric         def synthetic_child_from_data(self, name, data, type):
9306c3fb27SDimitry Andric             child = self.CreateValueFromData(name, data, type)
9406c3fb27SDimitry Andric             child.SetSyntheticChildrenGenerated(True)
9506c3fb27SDimitry Andric             return child
9606c3fb27SDimitry Andric 
9706c3fb27SDimitry Andric         def synthetic_child_from_address(self, name, addr, type):
9806c3fb27SDimitry Andric             child = self.CreateValueFromAddress(name, addr, type)
9906c3fb27SDimitry Andric             child.SetSyntheticChildrenGenerated(True)
10006c3fb27SDimitry Andric             return child
10106c3fb27SDimitry Andric 
10206c3fb27SDimitry Andric         def __eol_test(val):
10306c3fb27SDimitry Andric             """Default function for end of list test takes an SBValue object.
10406c3fb27SDimitry Andric 
10506c3fb27SDimitry Andric             Return True if val is invalid or it corresponds to a null pointer.
10606c3fb27SDimitry Andric             Otherwise, return False.
10706c3fb27SDimitry Andric             """
10806c3fb27SDimitry Andric             if not val or val.GetValueAsUnsigned() == 0:
10906c3fb27SDimitry Andric                 return True
11006c3fb27SDimitry Andric             else:
11106c3fb27SDimitry Andric                 return False
11206c3fb27SDimitry Andric 
11306c3fb27SDimitry Andric         # ==================================================
11406c3fb27SDimitry Andric         # Iterator for lldb.SBValue treated as a linked list
11506c3fb27SDimitry Andric         # ==================================================
11606c3fb27SDimitry Andric         def linked_list_iter(self, next_item_name, end_of_list_test=__eol_test):
11706c3fb27SDimitry Andric             """Generator adaptor to support iteration for SBValue as a linked list.
11806c3fb27SDimitry Andric 
11906c3fb27SDimitry Andric             linked_list_iter() is a special purpose iterator to treat the SBValue as
12006c3fb27SDimitry Andric             the head of a list data structure, where you specify the child member
12106c3fb27SDimitry Andric             name which points to the next item on the list and you specify the
12206c3fb27SDimitry Andric             end-of-list test function which takes an SBValue for an item and returns
12306c3fb27SDimitry Andric             True if EOL is reached and False if not.
12406c3fb27SDimitry Andric 
12506c3fb27SDimitry Andric             linked_list_iter() also detects infinite loop and bails out early.
12606c3fb27SDimitry Andric 
12706c3fb27SDimitry Andric             The end_of_list_test arg, if omitted, defaults to the __eol_test
12806c3fb27SDimitry Andric             function above.
12906c3fb27SDimitry Andric 
13006c3fb27SDimitry Andric             For example,
13106c3fb27SDimitry Andric 
13206c3fb27SDimitry Andric             # Get Frame #0.
13306c3fb27SDimitry Andric             ...
13406c3fb27SDimitry Andric 
13506c3fb27SDimitry Andric             # Get variable 'task_head'.
13606c3fb27SDimitry Andric             task_head = frame0.FindVariable('task_head')
13706c3fb27SDimitry Andric             ...
13806c3fb27SDimitry Andric 
13906c3fb27SDimitry Andric             for t in task_head.linked_list_iter('next'):
14006c3fb27SDimitry Andric                 print t
14106c3fb27SDimitry Andric             """
14206c3fb27SDimitry Andric             if end_of_list_test(self):
14306c3fb27SDimitry Andric                 return
14406c3fb27SDimitry Andric             item = self
14506c3fb27SDimitry Andric             visited = set()
14606c3fb27SDimitry Andric             try:
14706c3fb27SDimitry Andric                 while not end_of_list_test(item) and not item.GetValueAsUnsigned() in visited:
14806c3fb27SDimitry Andric                     visited.add(item.GetValueAsUnsigned())
14906c3fb27SDimitry Andric                     yield item
15006c3fb27SDimitry Andric                     # Prepare for the next iteration.
15106c3fb27SDimitry Andric                     item = item.GetChildMemberWithName(next_item_name)
15206c3fb27SDimitry Andric             except:
15306c3fb27SDimitry Andric                 # Exception occurred.  Stop the generator.
15406c3fb27SDimitry Andric                 pass
15506c3fb27SDimitry Andric 
15606c3fb27SDimitry Andric             return
15706c3fb27SDimitry Andric     %}
15806c3fb27SDimitry Andric #endif
15906c3fb27SDimitry Andric }
160