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