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 debugger.HandleCommand('type summary add -w llvm ' 22 '-F lldbDataFormatters.SmallStringSummaryProvider ' 23 '-x "^llvm::SmallString<.+>$"') 24 25# Pretty printer for llvm::SmallVector/llvm::SmallVectorImpl 26class SmallVectorSynthProvider: 27 def __init__(self, valobj, dict): 28 self.valobj = valobj; 29 self.update() # initialize this provider 30 31 def num_children(self): 32 return self.size.GetValueAsUnsigned(0) 33 34 def get_child_index(self, name): 35 try: 36 return int(name.lstrip('[').rstrip(']')) 37 except: 38 return -1; 39 40 def get_child_at_index(self, index): 41 # Do bounds checking. 42 if index < 0: 43 return None 44 if index >= self.num_children(): 45 return None; 46 47 offset = index * self.type_size 48 return self.begin.CreateChildAtOffset('['+str(index)+']', 49 offset, self.data_type) 50 51 def update(self): 52 self.begin = self.valobj.GetChildMemberWithName('BeginX') 53 self.size = self.valobj.GetChildMemberWithName('Size') 54 the_type = self.valobj.GetType() 55 # If this is a reference type we have to dereference it to get to the 56 # template parameter. 57 if the_type.IsReferenceType(): 58 the_type = the_type.GetDereferencedType() 59 60 self.data_type = the_type.GetTemplateArgumentType(0) 61 self.type_size = self.data_type.GetByteSize() 62 assert self.type_size != 0 63 64class ArrayRefSynthProvider: 65 """ Provider for llvm::ArrayRef """ 66 def __init__(self, valobj, dict): 67 self.valobj = valobj; 68 self.update() # initialize this provider 69 70 def num_children(self): 71 return self.length 72 73 def get_child_index(self, name): 74 try: 75 return int(name.lstrip('[').rstrip(']')) 76 except: 77 return -1; 78 79 def get_child_at_index(self, index): 80 if index < 0 or index >= self.num_children(): 81 return None; 82 offset = index * self.type_size 83 return self.data.CreateChildAtOffset('[' + str(index) + ']', 84 offset, self.data_type) 85 86 def update(self): 87 self.data = self.valobj.GetChildMemberWithName('Data') 88 length_obj = self.valobj.GetChildMemberWithName('Length') 89 self.length = length_obj.GetValueAsUnsigned(0) 90 self.data_type = self.data.GetType().GetPointeeType() 91 self.type_size = self.data_type.GetByteSize() 92 assert self.type_size != 0 93 94def OptionalSummaryProvider(valobj, internal_dict): 95 storage = valobj.GetChildMemberWithName('Storage') 96 if not storage: 97 storage = valobj 98 99 failure = 2 100 hasVal = storage.GetChildMemberWithName('hasVal').GetValueAsUnsigned(failure) 101 if hasVal == failure: 102 return '<could not read llvm::Optional>' 103 104 if hasVal == 0: 105 return 'None' 106 107 underlying_type = storage.GetType().GetTemplateArgumentType(0) 108 storage = storage.GetChildMemberWithName('storage') 109 return str(storage.Cast(underlying_type)) 110 111def SmallStringSummaryProvider(valobj, internal_dict): 112 num_elements = valobj.GetNumChildren() 113 res = "\"" 114 for i in range(0, num_elements): 115 res += valobj.GetChildAtIndex(i).GetValue().strip("'") 116 res += "\"" 117 return res 118