|  | """ | 
|  | LLDB Formatters for LLVM data types. | 
|  |  | 
|  | Load into LLDB with 'command script import /path/to/lldbDataFormatters.py' | 
|  | """ | 
|  |  | 
|  | def __lldb_init_module(debugger, internal_dict): | 
|  | debugger.HandleCommand('type category define -e llvm -l c++') | 
|  | debugger.HandleCommand('type synthetic add -w llvm ' | 
|  | '-l lldbDataFormatters.SmallVectorSynthProvider ' | 
|  | '-x "^llvm::SmallVectorImpl<.+>$"') | 
|  | debugger.HandleCommand('type synthetic add -w llvm ' | 
|  | '-l lldbDataFormatters.SmallVectorSynthProvider ' | 
|  | '-x "^llvm::SmallVector<.+,.+>$"') | 
|  | debugger.HandleCommand('type synthetic add -w llvm ' | 
|  | '-l lldbDataFormatters.ArrayRefSynthProvider ' | 
|  | '-x "^llvm::ArrayRef<.+>$"') | 
|  | debugger.HandleCommand('type summary add -w llvm ' | 
|  | '-F lldbDataFormatters.OptionalSummaryProvider ' | 
|  | '-x "^llvm::Optional<.+>$"') | 
|  |  | 
|  | # Pretty printer for llvm::SmallVector/llvm::SmallVectorImpl | 
|  | class SmallVectorSynthProvider: | 
|  | def __init__(self, valobj, dict): | 
|  | self.valobj = valobj; | 
|  | self.update() # initialize this provider | 
|  |  | 
|  | def num_children(self): | 
|  | begin = self.begin.GetValueAsUnsigned(0) | 
|  | end = self.end.GetValueAsUnsigned(0) | 
|  | return (end - begin)/self.type_size | 
|  |  | 
|  | def get_child_index(self, name): | 
|  | try: | 
|  | return int(name.lstrip('[').rstrip(']')) | 
|  | except: | 
|  | return -1; | 
|  |  | 
|  | def get_child_at_index(self, index): | 
|  | # Do bounds checking. | 
|  | if index < 0: | 
|  | return None | 
|  | if index >= self.num_children(): | 
|  | return None; | 
|  |  | 
|  | offset = index * self.type_size | 
|  | return self.begin.CreateChildAtOffset('['+str(index)+']', | 
|  | offset, self.data_type) | 
|  |  | 
|  | def update(self): | 
|  | self.begin = self.valobj.GetChildMemberWithName('BeginX') | 
|  | self.end = self.valobj.GetChildMemberWithName('EndX') | 
|  | the_type = self.valobj.GetType() | 
|  | # If this is a reference type we have to dereference it to get to the | 
|  | # template parameter. | 
|  | if the_type.IsReferenceType(): | 
|  | the_type = the_type.GetDereferencedType() | 
|  |  | 
|  | self.data_type = the_type.GetTemplateArgumentType(0) | 
|  | self.type_size = self.data_type.GetByteSize() | 
|  | assert self.type_size != 0 | 
|  |  | 
|  | class ArrayRefSynthProvider: | 
|  | """ Provider for llvm::ArrayRef """ | 
|  | def __init__(self, valobj, dict): | 
|  | self.valobj = valobj; | 
|  | self.update() # initialize this provider | 
|  |  | 
|  | def num_children(self): | 
|  | return self.length | 
|  |  | 
|  | def get_child_index(self, name): | 
|  | try: | 
|  | return int(name.lstrip('[').rstrip(']')) | 
|  | except: | 
|  | return -1; | 
|  |  | 
|  | def get_child_at_index(self, index): | 
|  | if index < 0 or index >= self.num_children(): | 
|  | return None; | 
|  | offset = index * self.type_size | 
|  | return self.data.CreateChildAtOffset('[' + str(index) + ']', | 
|  | offset, self.data_type) | 
|  |  | 
|  | def update(self): | 
|  | self.data = self.valobj.GetChildMemberWithName('Data') | 
|  | length_obj = self.valobj.GetChildMemberWithName('Length') | 
|  | self.length = length_obj.GetValueAsUnsigned(0) | 
|  | self.data_type = self.data.GetType().GetPointeeType() | 
|  | self.type_size = self.data_type.GetByteSize() | 
|  | assert self.type_size != 0 | 
|  |  | 
|  | def OptionalSummaryProvider(valobj, internal_dict): | 
|  | storage = valobj.GetChildMemberWithName('Storage') | 
|  | if not storage: | 
|  | storage = valobj | 
|  |  | 
|  | failure = 2 | 
|  | hasVal = storage.GetChildMemberWithName('hasVal').GetValueAsUnsigned(failure) | 
|  | if hasVal == failure: | 
|  | return '<could not read llvm::Optional>' | 
|  |  | 
|  | if hasVal == 0: | 
|  | return 'None' | 
|  |  | 
|  | underlying_type = storage.GetType().GetTemplateArgumentType(0) | 
|  | storage = storage.GetChildMemberWithName('storage') | 
|  | return str(storage.Cast(underlying_type)) |