[Frontend] Remove unused includes (NFC) (#116927)
[llvm-project.git] / llvm / utils / gdb-scripts / prettyprinters.py
blobc78491529182b9e50472f869506af51420a385d1
1 from __future__ import print_function
2 import struct
3 import sys
5 import gdb.printing
6 import gdb.types
9 class Iterator:
10 def __iter__(self):
11 return self
13 if sys.version_info.major == 2:
15 def next(self):
16 return self.__next__()
18 def children(self):
19 return self
22 class SmallStringPrinter:
23 """Print an llvm::SmallString object."""
25 def __init__(self, val):
26 self.val = val
28 def to_string(self):
29 data = self.val["BeginX"].cast(gdb.lookup_type("char").pointer())
30 length = self.val["Size"]
31 return data.lazy_string(length=length)
33 def display_hint(self):
34 return "string"
37 class StringRefPrinter:
38 """Print an llvm::StringRef object."""
40 def __init__(self, val):
41 self.val = val
43 def to_string(self):
44 data = self.val["Data"]
45 length = self.val["Length"]
46 return data.lazy_string(length=length)
48 def display_hint(self):
49 return "string"
52 class SmallVectorPrinter(Iterator):
53 """Print an llvm::SmallVector object."""
55 def __init__(self, val):
56 self.val = val
57 t = val.type.template_argument(0).pointer()
58 self.begin = val["BeginX"].cast(t)
59 self.size = val["Size"]
60 self.i = 0
62 def __next__(self):
63 if self.i == self.size:
64 raise StopIteration
65 ret = "[{}]".format(self.i), (self.begin + self.i).dereference()
66 self.i += 1
67 return ret
69 def to_string(self):
70 return "llvm::SmallVector of Size {}, Capacity {}".format(
71 self.size, self.val["Capacity"]
74 def display_hint(self):
75 return "array"
78 class ArrayRefPrinter:
79 """Print an llvm::ArrayRef object."""
81 class _iterator:
82 def __init__(self, begin, end):
83 self.cur = begin
84 self.end = end
85 self.count = 0
87 def __iter__(self):
88 return self
90 def __next__(self):
91 if self.cur == self.end:
92 raise StopIteration
93 count = self.count
94 self.count = self.count + 1
95 cur = self.cur
96 self.cur = self.cur + 1
97 return "[%d]" % count, cur.dereference()
99 if sys.version_info.major == 2:
100 next = __next__
102 def __init__(self, val):
103 self.val = val
105 def children(self):
106 data = self.val["Data"]
107 return self._iterator(data, data + self.val["Length"])
109 def to_string(self):
110 return "llvm::ArrayRef of length %d" % (self.val["Length"])
112 def display_hint(self):
113 return "array"
116 class ExpectedPrinter(Iterator):
117 """Print an llvm::Expected object."""
119 def __init__(self, val):
120 self.val = val
122 def __next__(self):
123 val = self.val
124 if val is None:
125 raise StopIteration
126 self.val = None
127 if val["HasError"]:
128 return (
129 "error",
130 val["ErrorStorage"]
131 .address.cast(gdb.lookup_type("llvm::ErrorInfoBase").pointer())
132 .dereference(),
134 return (
135 "value",
136 val["TStorage"]
137 .address.cast(val.type.template_argument(0).pointer())
138 .dereference(),
141 def to_string(self):
142 return "llvm::Expected{}".format(" is error" if self.val["HasError"] else "")
145 class OptionalPrinter(Iterator):
146 """Print an llvm::Optional object."""
148 def __init__(self, val):
149 self.val = val
151 def __next__(self):
152 val = self.val
153 if val is None:
154 raise StopIteration
155 self.val = None
156 if not val["Storage"]["hasVal"]:
157 raise StopIteration
158 return ("value", val["Storage"]["val"])
160 def to_string(self):
161 return "llvm::Optional{}".format(
162 "" if self.val["Storage"]["hasVal"] else " is not initialized"
166 class DenseMapPrinter:
167 "Print a DenseMap"
169 class _iterator:
170 def __init__(self, key_info_t, begin, end):
171 self.key_info_t = key_info_t
172 self.cur = begin
173 self.end = end
174 self.advancePastEmptyBuckets()
175 self.first = True
177 def __iter__(self):
178 return self
180 def advancePastEmptyBuckets(self):
181 # disabled until the comments below can be addressed
182 # keeping as notes/posterity/hints for future contributors
183 return
184 n = self.key_info_t.name
185 is_equal = gdb.parse_and_eval(n + "::isEqual")
186 empty = gdb.parse_and_eval(n + "::getEmptyKey()")
187 tombstone = gdb.parse_and_eval(n + "::getTombstoneKey()")
188 # the following is invalid, GDB fails with:
189 # Python Exception <class 'gdb.error'> Attempt to take address of value
190 # not located in memory.
191 # because isEqual took parameter (for the unsigned long key I was testing)
192 # by const ref, and GDB
193 # It's also not entirely general - we should be accessing the "getFirst()"
194 # member function, not the 'first' member variable, but I've yet to figure
195 # out how to find/call member functions (especially (const) overloaded
196 # ones) on a gdb.Value.
197 while self.cur != self.end and (
198 is_equal(self.cur.dereference()["first"], empty)
199 or is_equal(self.cur.dereference()["first"], tombstone)
201 self.cur = self.cur + 1
203 def __next__(self):
204 if self.cur == self.end:
205 raise StopIteration
206 cur = self.cur
207 v = cur.dereference()["first" if self.first else "second"]
208 if not self.first:
209 self.cur = self.cur + 1
210 self.advancePastEmptyBuckets()
211 self.first = True
212 else:
213 self.first = False
214 return "x", v
216 if sys.version_info.major == 2:
217 next = __next__
219 def __init__(self, val):
220 self.val = val
222 def children(self):
223 t = self.val.type.template_argument(3).pointer()
224 begin = self.val["Buckets"].cast(t)
225 end = (begin + self.val["NumBuckets"]).cast(t)
226 return self._iterator(self.val.type.template_argument(2), begin, end)
228 def to_string(self):
229 return "llvm::DenseMap with %d elements" % (self.val["NumEntries"])
231 def display_hint(self):
232 return "map"
235 class StringMapPrinter:
236 "Print a StringMap"
238 def __init__(self, val):
239 self.val = val
241 def children(self):
242 it = self.val["TheTable"]
243 end = it + self.val["NumBuckets"]
244 value_ty = self.val.type.template_argument(0)
245 entry_base_ty = gdb.lookup_type("llvm::StringMapEntryBase")
246 tombstone = gdb.parse_and_eval("llvm::StringMapImpl::TombstoneIntVal")
248 while it != end:
249 it_deref = it.dereference()
250 if it_deref == 0 or it_deref == tombstone:
251 it = it + 1
252 continue
254 entry_ptr = it_deref.cast(entry_base_ty.pointer())
255 entry = entry_ptr.dereference()
257 str_len = entry["keyLength"]
258 value_ptr = (entry_ptr + 1).cast(value_ty.pointer())
259 str_data = (entry_ptr + 1).cast(gdb.lookup_type("uintptr_t")) + max(
260 value_ty.sizeof, entry_base_ty.alignof
262 str_data = str_data.cast(gdb.lookup_type("char").const().pointer())
263 string_ref = gdb.Value(
264 struct.pack("PN", int(str_data), int(str_len)),
265 gdb.lookup_type("llvm::StringRef"),
267 yield "key", string_ref
269 value = value_ptr.dereference()
270 yield "value", value
272 it = it + 1
274 def to_string(self):
275 return "llvm::StringMap with %d elements" % (self.val["NumItems"])
277 def display_hint(self):
278 return "map"
281 class TwinePrinter:
282 "Print a Twine"
284 def __init__(self, val):
285 self._val = val
287 def display_hint(self):
288 return "string"
290 def string_from_pretty_printer_lookup(self, val):
291 """Lookup the default pretty-printer for val and use it.
293 If no pretty-printer is defined for the type of val, print an error and
294 return a placeholder string."""
296 pp = gdb.default_visualizer(val)
297 if pp:
298 s = pp.to_string()
300 # The pretty-printer may return a LazyString instead of an actual Python
301 # string. Convert it to a Python string. However, GDB doesn't seem to
302 # register the LazyString type, so we can't check
303 # "type(s) == gdb.LazyString".
304 if "LazyString" in type(s).__name__:
305 s = s.value().string()
307 else:
308 print(
310 "No pretty printer for {} found. The resulting Twine "
311 + "representation will be incomplete."
312 ).format(val.type.name)
314 s = "(missing {})".format(val.type.name)
316 return s
318 def is_twine_kind(self, kind, expected):
319 if not kind.endswith(expected):
320 return False
321 # apparently some GDB versions add the NodeKind:: namespace
322 # (happens for me on GDB 7.11)
323 return kind in (
324 "llvm::Twine::" + expected,
325 "llvm::Twine::NodeKind::" + expected,
328 def string_from_child(self, child, kind):
329 """Return the string representation of the Twine::Child child."""
331 if self.is_twine_kind(kind, "EmptyKind") or self.is_twine_kind(
332 kind, "NullKind"
334 return ""
336 if self.is_twine_kind(kind, "TwineKind"):
337 return self.string_from_twine_object(child["twine"].dereference())
339 if self.is_twine_kind(kind, "CStringKind"):
340 return child["cString"].string()
342 if self.is_twine_kind(kind, "StdStringKind"):
343 val = child["stdString"].dereference()
344 return self.string_from_pretty_printer_lookup(val)
346 if self.is_twine_kind(kind, "PtrAndLengthKind"):
347 val = child["ptrAndLength"]
348 data = val["ptr"]
349 length = val["length"]
350 return data.string(length=length)
352 if self.is_twine_kind(kind, "CharKind"):
353 return chr(child["character"])
355 if self.is_twine_kind(kind, "DecUIKind"):
356 return str(child["decUI"])
358 if self.is_twine_kind(kind, "DecIKind"):
359 return str(child["decI"])
361 if self.is_twine_kind(kind, "DecULKind"):
362 return str(child["decUL"].dereference())
364 if self.is_twine_kind(kind, "DecLKind"):
365 return str(child["decL"].dereference())
367 if self.is_twine_kind(kind, "DecULLKind"):
368 return str(child["decULL"].dereference())
370 if self.is_twine_kind(kind, "DecLLKind"):
371 return str(child["decLL"].dereference())
373 if self.is_twine_kind(kind, "UHexKind"):
374 val = child["uHex"].dereference()
375 return hex(int(val))
377 print(
379 "Unhandled NodeKind {} in Twine pretty-printer. The result will be "
380 "incomplete."
381 ).format(kind)
384 return "(unhandled {})".format(kind)
386 def string_from_twine_object(self, twine):
387 """Return the string representation of the Twine object twine."""
389 lhs = twine["LHS"]
390 rhs = twine["RHS"]
392 lhs_kind = str(twine["LHSKind"])
393 rhs_kind = str(twine["RHSKind"])
395 lhs_str = self.string_from_child(lhs, lhs_kind)
396 rhs_str = self.string_from_child(rhs, rhs_kind)
398 return lhs_str + rhs_str
400 def to_string(self):
401 return self.string_from_twine_object(self._val)
403 def display_hint(self):
404 return "string"
407 def get_pointer_int_pair(val):
408 """Get tuple from llvm::PointerIntPair."""
409 info_name = val.type.template_argument(4).strip_typedefs().name
410 # Note: this throws a gdb.error if the info type is not used (by means of a
411 # call to getPointer() or similar) in the current translation unit.
412 enum_type = gdb.lookup_type(info_name + "::MaskAndShiftConstants")
413 enum_dict = gdb.types.make_enum_dict(enum_type)
414 ptr_mask = enum_dict[info_name + "::PointerBitMask"]
415 int_shift = enum_dict[info_name + "::IntShift"]
416 int_mask = enum_dict[info_name + "::IntMask"]
417 pair_union = val["Value"]
418 value_type = pair_union.type.template_argument(0)
419 value_type_ptr = value_type.pointer()
420 pair_union = pair_union.address.cast(value_type_ptr).dereference()
421 pair_union = pair_union.cast(gdb.lookup_type("intptr_t"))
422 pointer = pair_union & ptr_mask
423 pointer = pointer.cast(value_type)
424 value = (pair_union >> int_shift) & int_mask
425 return (pointer, value)
428 class PointerIntPairPrinter:
429 """Print a PointerIntPair."""
431 def __init__(self, pointer, value):
432 self.pointer = pointer
433 self.value = value
435 def children(self):
436 yield ("pointer", self.pointer)
437 yield ("value", self.value)
439 def to_string(self):
440 return "(%s, %s)" % (self.pointer.type, self.value.type)
443 def make_pointer_int_pair_printer(val):
444 """Factory for an llvm::PointerIntPair printer."""
445 try:
446 pointer, value = get_pointer_int_pair(val)
447 except gdb.error:
448 return None # If PointerIntPair cannot be analyzed, print as raw value.
449 pointer_type = val.type.template_argument(0)
450 value_type = val.type.template_argument(2)
451 return PointerIntPairPrinter(pointer.cast(pointer_type), value.cast(value_type))
454 class PointerUnionPrinter:
455 """Print a PointerUnion."""
457 def __init__(self, pointer):
458 self.pointer = pointer
460 def children(self):
461 yield ("pointer", self.pointer)
463 def to_string(self):
464 return "Containing %s" % self.pointer.type
467 def make_pointer_union_printer(val):
468 """Factory for an llvm::PointerUnion printer."""
469 try:
470 pointer, value = get_pointer_int_pair(val["Val"])
471 except gdb.error:
472 return None # If PointerIntPair cannot be analyzed, print as raw value.
473 pointer_type = val.type.template_argument(int(value))
474 return PointerUnionPrinter(pointer.cast(pointer_type))
477 class IlistNodePrinter:
478 """Print an llvm::ilist_node object."""
480 def __init__(self, val):
481 impl_type = val.type.fields()[0].type
482 base_type = impl_type.fields()[0].type
483 derived_type = val.type.template_argument(0)
485 def get_prev_and_sentinel(base):
486 # One of Prev and PrevAndSentinel exists. Depending on #defines used to
487 # compile LLVM, the base_type's template argument is either true of false.
488 if base_type.template_argument(0):
489 return get_pointer_int_pair(base["PrevAndSentinel"])
490 return base["Prev"], None
492 # Casts a base_type pointer to the appropriate derived type.
493 def cast_pointer(pointer):
494 sentinel = get_prev_and_sentinel(pointer.dereference())[1]
495 pointer = pointer.cast(impl_type.pointer())
496 if sentinel:
497 return pointer
498 return pointer.cast(derived_type.pointer())
500 # Repeated cast becaue val.type's base_type is ambiguous when using tags.
501 base = val.cast(impl_type).cast(base_type)
502 (prev, sentinel) = get_prev_and_sentinel(base)
503 prev = prev.cast(base_type.pointer())
504 self.prev = cast_pointer(prev)
505 self.next = cast_pointer(val["Next"])
506 self.sentinel = sentinel
508 def children(self):
509 if self.sentinel:
510 yield "sentinel", "yes"
511 yield "prev", self.prev
512 yield "next", self.next
515 class IlistPrinter:
516 """Print an llvm::simple_ilist or llvm::iplist object."""
518 def __init__(self, val):
519 self.node_type = val.type.template_argument(0)
520 sentinel = val["Sentinel"]
521 # First field is common base type of sentinel and ilist_node.
522 base_type = sentinel.type.fields()[0].type
523 self.sentinel = sentinel.address.cast(base_type.pointer())
525 def _pointers(self):
526 pointer = self.sentinel
527 while True:
528 pointer = pointer["Next"].cast(pointer.type)
529 if pointer == self.sentinel:
530 return
531 yield pointer.cast(self.node_type.pointer())
533 def children(self):
534 for k, v in enumerate(self._pointers()):
535 yield ("[%d]" % k, v.dereference())
538 pp = gdb.printing.RegexpCollectionPrettyPrinter("LLVMSupport")
539 pp.add_printer("llvm::SmallString", "^llvm::SmallString<.*>$", SmallStringPrinter)
540 pp.add_printer("llvm::StringRef", "^llvm::StringRef$", StringRefPrinter)
541 pp.add_printer(
542 "llvm::SmallVectorImpl", "^llvm::SmallVector(Impl)?<.*>$", SmallVectorPrinter
544 pp.add_printer("llvm::ArrayRef", "^llvm::(Mutable)?ArrayRef<.*>$", ArrayRefPrinter)
545 pp.add_printer("llvm::Expected", "^llvm::Expected<.*>$", ExpectedPrinter)
546 pp.add_printer("llvm::Optional", "^llvm::Optional<.*>$", OptionalPrinter)
547 pp.add_printer("llvm::DenseMap", "^llvm::DenseMap<.*>$", DenseMapPrinter)
548 pp.add_printer("llvm::StringMap", "^llvm::StringMap<.*>$", StringMapPrinter)
549 pp.add_printer("llvm::Twine", "^llvm::Twine$", TwinePrinter)
550 pp.add_printer(
551 "llvm::PointerIntPair", "^llvm::PointerIntPair<.*>$", make_pointer_int_pair_printer
553 pp.add_printer(
554 "llvm::PointerUnion", "^llvm::PointerUnion<.*>$", make_pointer_union_printer
556 pp.add_printer("llvm::ilist_node", "^llvm::ilist_node<.*>$", IlistNodePrinter)
557 pp.add_printer("llvm::iplist", "^llvm::iplist<.*>$", IlistPrinter)
558 pp.add_printer("llvm::simple_ilist", "^llvm::simple_ilist<.*>$", IlistPrinter)
559 gdb.printing.register_pretty_printer(gdb.current_objfile(), pp)