lldbDataFormatters.py 3.7 KB

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