Home | History | Annotate | Download | only in utils
      1 """
      2 LLDB Formatters for LLVM data types.
      3 
      4 Load into LLDB with 'command script import /path/to/lldbDataFormatters.py'
      5 """
      6 
      7 def __lldb_init_module(debugger, internal_dict):
      8     debugger.HandleCommand('type category define -e llvm -l c++')
      9     debugger.HandleCommand('type synthetic add -w llvm '
     10                            '-l lldbDataFormatters.SmallVectorSynthProvider '
     11                            '-x "^llvm::SmallVectorImpl<.+>$"')
     12     debugger.HandleCommand('type synthetic add -w llvm '
     13                            '-l lldbDataFormatters.SmallVectorSynthProvider '
     14                            '-x "^llvm::SmallVector<.+,.+>$"')
     15     debugger.HandleCommand('type synthetic add -w llvm '
     16                            '-l lldbDataFormatters.ArrayRefSynthProvider '
     17                            '-x "^llvm::ArrayRef<.+>$"')
     18     debugger.HandleCommand('type summary add -w llvm '
     19                            '-F lldbDataFormatters.OptionalSummaryProvider '
     20                            '-x "^llvm::Optional<.+>$"')
     21 
     22 # Pretty printer for llvm::SmallVector/llvm::SmallVectorImpl
     23 class SmallVectorSynthProvider:
     24     def __init__(self, valobj, dict):
     25         self.valobj = valobj;
     26         self.update() # initialize this provider
     27 
     28     def num_children(self):
     29         begin = self.begin.GetValueAsUnsigned(0)
     30         end = self.end.GetValueAsUnsigned(0)
     31         return (end - begin)/self.type_size
     32 
     33     def get_child_index(self, name):
     34         try:
     35             return int(name.lstrip('[').rstrip(']'))
     36         except:
     37             return -1;
     38 
     39     def get_child_at_index(self, index):
     40         # Do bounds checking.
     41         if index < 0:
     42             return None
     43         if index >= self.num_children():
     44             return None;
     45 
     46         offset = index * self.type_size
     47         return self.begin.CreateChildAtOffset('['+str(index)+']',
     48                                               offset, self.data_type)
     49 
     50     def update(self):
     51         self.begin = self.valobj.GetChildMemberWithName('BeginX')
     52         self.end = self.valobj.GetChildMemberWithName('EndX')
     53         the_type = self.valobj.GetType()
     54         # If this is a reference type we have to dereference it to get to the
     55         # template parameter.
     56         if the_type.IsReferenceType():
     57             the_type = the_type.GetDereferencedType()
     58 
     59         self.data_type = the_type.GetTemplateArgumentType(0)
     60         self.type_size = self.data_type.GetByteSize()
     61         assert self.type_size != 0
     62 
     63 class ArrayRefSynthProvider:
     64     """ Provider for llvm::ArrayRef """
     65     def __init__(self, valobj, dict):
     66         self.valobj = valobj;
     67         self.update() # initialize this provider
     68 
     69     def num_children(self):
     70         return self.length
     71 
     72     def get_child_index(self, name):
     73         try:
     74             return int(name.lstrip('[').rstrip(']'))
     75         except:
     76             return -1;
     77 
     78     def get_child_at_index(self, index):
     79         if index < 0 or index >= self.num_children():
     80             return None;
     81         offset = index * self.type_size
     82         return self.data.CreateChildAtOffset('[' + str(index) + ']',
     83                                              offset, self.data_type)
     84 
     85     def update(self):
     86         self.data = self.valobj.GetChildMemberWithName('Data')
     87         length_obj = self.valobj.GetChildMemberWithName('Length')
     88         self.length = length_obj.GetValueAsUnsigned(0)
     89         self.data_type = self.data.GetType().GetPointeeType()
     90         self.type_size = self.data_type.GetByteSize()
     91         assert self.type_size != 0
     92 
     93 def OptionalSummaryProvider(valobj, internal_dict):
     94     if not valobj.GetChildMemberWithName('hasVal').GetValueAsUnsigned(0):
     95         return 'None'
     96     underlying_type = valobj.GetType().GetTemplateArgumentType(0)
     97     storage = valobj.GetChildMemberWithName('storage')
     98     return str(storage.Cast(underlying_type))
     99