lldbDataFormatters.py 5.2 KB

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