diff options
Diffstat (limited to 'lldb/examples/synthetic/bitfield/example.py')
-rw-r--r-- | lldb/examples/synthetic/bitfield/example.py | 205 |
1 files changed, 114 insertions, 91 deletions
diff --git a/lldb/examples/synthetic/bitfield/example.py b/lldb/examples/synthetic/bitfield/example.py index 7995919a490..57bbf0f76ac 100644 --- a/lldb/examples/synthetic/bitfield/example.py +++ b/lldb/examples/synthetic/bitfield/example.py @@ -1,100 +1,123 @@ # Synthetic children provider example for class MaskedData # to use me: # command script import ./example.py --allow-reload -# type synthetic add MaskedData --python-class example.MaskedData_SyntheticChildrenProvider +# type synthetic add MaskedData --python-class +# example.MaskedData_SyntheticChildrenProvider + + class MaskedData_SyntheticChildrenProvider: - def __init__(self, valobj, dict): - self.valobj = valobj # remember the SBValue since you will not have another chance to get it :-) - def num_children(self): - # you could perform calculations involving the SBValue and/or its children to determine this value - # here, we have an hardcoded value - but since you have stored the SBValue you could use it to - # help figure out the correct thing to return here. if you return a number N, you should be prepared to - # answer questions about N children - return 4 + def __init__(self, valobj, dict): + # remember the SBValue since you will not have another chance to get it + # :-) + self.valobj = valobj + + def num_children(self): + # you could perform calculations involving the SBValue and/or its children to determine this value + # here, we have an hardcoded value - but since you have stored the SBValue you could use it to + # help figure out the correct thing to return here. if you return a number N, you should be prepared to + # answer questions about N children + return 4 - def has_children(self): - # we simply say True here because we know we have 4 children - # in general, you want to make this calculation as simple as possible - # and return True if in doubt (you can always return num_children == 0 later) - return True + def has_children(self): + # we simply say True here because we know we have 4 children + # in general, you want to make this calculation as simple as possible + # and return True if in doubt (you can always return num_children == 0 + # later) + return True - def get_child_index(self,name): - # given a name, return its index - # you can return None if you don't know the answer for a given name - if name == "value": - return 0 - # here, we are using a reserved C++ keyword as a child name - we could not do that in the source code - # but we are free to use the names we like best in the synthetic children provider class - # we are also not respecting the order of declaration in the C++ class itself - as long as - # we are consistent, we can do that freely - if name == "operator": - return 1 - if name == "mask": - return 2 - # this member does not exist in the original class - we will compute its value and show it to the user - # when returning synthetic children, there is no need to only stick to what already exists in memory - if name == "apply()": - return 3 - return None # no clue, just say none + def get_child_index(self, name): + # given a name, return its index + # you can return None if you don't know the answer for a given name + if name == "value": + return 0 + # here, we are using a reserved C++ keyword as a child name - we could not do that in the source code + # but we are free to use the names we like best in the synthetic children provider class + # we are also not respecting the order of declaration in the C++ class itself - as long as + # we are consistent, we can do that freely + if name == "operator": + return 1 + if name == "mask": + return 2 + # this member does not exist in the original class - we will compute its value and show it to the user + # when returning synthetic children, there is no need to only stick to + # what already exists in memory + if name == "apply()": + return 3 + return None # no clue, just say none - def get_child_at_index(self,index): - # precautionary measures - if index < 0: - return None - if index > self.num_children(): - return None - if self.valobj.IsValid() == False: - return None - if index == 0: - return self.valobj.GetChildMemberWithName("value") - if index == 1: - # fetch the value of the operator - op_chosen = self.valobj.GetChildMemberWithName("oper").GetValueAsUnsigned() - # if it is a known value, return a descriptive string for it - # we are not doing this in the most efficient possible way, but the code is very readable - # and easy to maintain - if you change the values on the C++ side, the same changes must be made here - if op_chosen == 0: - return self.valobj.CreateValueFromExpression("operator",'(const char*)"none"') - elif op_chosen == 1: - return self.valobj.CreateValueFromExpression("operator",'(const char*)"AND"') - elif op_chosen == 2: - return self.valobj.CreateValueFromExpression("operator",'(const char*)"OR"') - elif op_chosen == 3: - return self.valobj.CreateValueFromExpression("operator",'(const char*)"XOR"') - elif op_chosen == 4: - return self.valobj.CreateValueFromExpression("operator",'(const char*)"NAND"') - elif op_chosen == 5: - return self.valobj.CreateValueFromExpression("operator",'(const char*)"NOR"') - else: - return self.valobj.CreateValueFromExpression("operator",'(const char*)"unknown"') # something else - if index == 2: - return self.valobj.GetChildMemberWithName("mask") - if index == 3: - # for this, we must fetch all the other elements - # in an efficient implementation, we would be caching this data for efficiency - value = self.valobj.GetChildMemberWithName("value").GetValueAsUnsigned() - operator = self.valobj.GetChildMemberWithName("oper").GetValueAsUnsigned() - mask = self.valobj.GetChildMemberWithName("mask").GetValueAsUnsigned() - # compute the masked value according to the operator - if operator == 1: - value = value & mask - elif operator == 2: - value = value | mask - elif operator == 3: - value = value ^ mask - elif operator == 4: - value = ~(value & mask) - elif operator == 5: - value = ~(value | mask) - else: - pass - value &= 0xFFFFFFFF # make sure Python does not extend our values to 64-bits - # return it - again, not the most efficient possible way. we should actually be pushing the computed value - # into an SBData, and using the SBData to create an SBValue - this has the advantage of readability - return self.valobj.CreateValueFromExpression("apply()",'(uint32_t)(' + str(value) + ')') + def get_child_at_index(self, index): + # precautionary measures + if index < 0: + return None + if index > self.num_children(): + return None + if self.valobj.IsValid() == False: + return None + if index == 0: + return self.valobj.GetChildMemberWithName("value") + if index == 1: + # fetch the value of the operator + op_chosen = self.valobj.GetChildMemberWithName( + "oper").GetValueAsUnsigned() + # if it is a known value, return a descriptive string for it + # we are not doing this in the most efficient possible way, but the code is very readable + # and easy to maintain - if you change the values on the C++ side, + # the same changes must be made here + if op_chosen == 0: + return self.valobj.CreateValueFromExpression( + "operator", '(const char*)"none"') + elif op_chosen == 1: + return self.valobj.CreateValueFromExpression( + "operator", '(const char*)"AND"') + elif op_chosen == 2: + return self.valobj.CreateValueFromExpression( + "operator", '(const char*)"OR"') + elif op_chosen == 3: + return self.valobj.CreateValueFromExpression( + "operator", '(const char*)"XOR"') + elif op_chosen == 4: + return self.valobj.CreateValueFromExpression( + "operator", '(const char*)"NAND"') + elif op_chosen == 5: + return self.valobj.CreateValueFromExpression( + "operator", '(const char*)"NOR"') + else: + return self.valobj.CreateValueFromExpression( + "operator", '(const char*)"unknown"') # something else + if index == 2: + return self.valobj.GetChildMemberWithName("mask") + if index == 3: + # for this, we must fetch all the other elements + # in an efficient implementation, we would be caching this data for + # efficiency + value = self.valobj.GetChildMemberWithName( + "value").GetValueAsUnsigned() + operator = self.valobj.GetChildMemberWithName( + "oper").GetValueAsUnsigned() + mask = self.valobj.GetChildMemberWithName( + "mask").GetValueAsUnsigned() + # compute the masked value according to the operator + if operator == 1: + value = value & mask + elif operator == 2: + value = value | mask + elif operator == 3: + value = value ^ mask + elif operator == 4: + value = ~(value & mask) + elif operator == 5: + value = ~(value | mask) + else: + pass + value &= 0xFFFFFFFF # make sure Python does not extend our values to 64-bits + # return it - again, not the most efficient possible way. we should actually be pushing the computed value + # into an SBData, and using the SBData to create an SBValue - this + # has the advantage of readability + return self.valobj.CreateValueFromExpression( + "apply()", '(uint32_t)(' + str(value) + ')') - def update(self): - # we do not do anything special in update - but this would be the right place to lookup - # the data we use in get_child_at_index and cache it - pass + def update(self): + # we do not do anything special in update - but this would be the right place to lookup + # the data we use in get_child_at_index and cache it + pass |