1""" 2LLDB Formatters for LLVM data types. 3 4Load into LLDB with 'command script import /path/to/lldbDataFormatters.py' 5""" 6 7def __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 23class SmallVectorSynthProvider: 24 def __init__(self, valobj, dict): 25 self.valobj = valobj; 26 self.update() # initialize this provider 27 28 def num_children(self): 29 return self.size.GetValueAsUnsigned(0) 30 31 def get_child_index(self, name): 32 try: 33 return int(name.lstrip('[').rstrip(']')) 34 except: 35 return -1; 36 37 def get_child_at_index(self, index): 38 # Do bounds checking. 39 if index < 0: 40 return None 41 if index >= self.num_children(): 42 return None; 43 44 offset = index * self.type_size 45 return self.begin.CreateChildAtOffset('['+str(index)+']', 46 offset, self.data_type) 47 48 def update(self): 49 self.begin = self.valobj.GetChildMemberWithName('BeginX') 50 self.size = self.valobj.GetChildMemberWithName('Size') 51 the_type = self.valobj.GetType() 52 # If this is a reference type we have to dereference it to get to the 53 # template parameter. 54 if the_type.IsReferenceType(): 55 the_type = the_type.GetDereferencedType() 56 57 self.data_type = the_type.GetTemplateArgumentType(0) 58 self.type_size = self.data_type.GetByteSize() 59 assert self.type_size != 0 60 61class ArrayRefSynthProvider: 62 """ Provider for llvm::ArrayRef """ 63 def __init__(self, valobj, dict): 64 self.valobj = valobj; 65 self.update() # initialize this provider 66 67 def num_children(self): 68 return self.length 69 70 def get_child_index(self, name): 71 try: 72 return int(name.lstrip('[').rstrip(']')) 73 except: 74 return -1; 75 76 def get_child_at_index(self, index): 77 if index < 0 or index >= self.num_children(): 78 return None; 79 offset = index * self.type_size 80 return self.data.CreateChildAtOffset('[' + str(index) + ']', 81 offset, self.data_type) 82 83 def update(self): 84 self.data = self.valobj.GetChildMemberWithName('Data') 85 length_obj = self.valobj.GetChildMemberWithName('Length') 86 self.length = length_obj.GetValueAsUnsigned(0) 87 self.data_type = self.data.GetType().GetPointeeType() 88 self.type_size = self.data_type.GetByteSize() 89 assert self.type_size != 0 90 91def OptionalSummaryProvider(valobj, internal_dict): 92 storage = valobj.GetChildMemberWithName('Storage') 93 if not storage: 94 storage = valobj 95 96 failure = 2 97 hasVal = storage.GetChildMemberWithName('hasVal').GetValueAsUnsigned(failure) 98 if hasVal == failure: 99 return '<could not read llvm::Optional>' 100 101 if hasVal == 0: 102 return 'None' 103 104 underlying_type = storage.GetType().GetTemplateArgumentType(0) 105 storage = storage.GetChildMemberWithName('storage') 106 return str(storage.Cast(underlying_type)) 107