@@ -365,6 +365,66 @@ def make_pointer_union_printer(val):
365
365
string = 'llvm::PointerUnion containing %s' % pointer_type
366
366
return make_printer (string , [('pointer' , pointer .cast (pointer_type ))])
367
367
368
+ class IlistNodePrinter :
369
+ """Print an llvm::ilist_node object."""
370
+
371
+ def __init__ (self , val ):
372
+ impl_type = val .type .fields ()[0 ].type
373
+ base_type = impl_type .fields ()[0 ].type
374
+ derived_type = val .type .template_argument (0 )
375
+
376
+ def get_prev_and_sentinel (base ):
377
+ # One of Prev and PrevAndSentinel exists. Depending on #defines used to
378
+ # compile LLVM, the base_type's template argument is either true of false.
379
+ if base_type .template_argument (0 ):
380
+ return get_pointer_int_pair (base ['PrevAndSentinel' ])
381
+ return base ['Prev' ], None
382
+
383
+ # Casts a base_type pointer to the appropriate derived type.
384
+ def cast_pointer (pointer ):
385
+ sentinel = get_prev_and_sentinel (pointer .dereference ())[1 ]
386
+ pointer = pointer .cast (impl_type .pointer ())
387
+ if sentinel :
388
+ return pointer
389
+ return pointer .cast (derived_type .pointer ())
390
+
391
+ # Repeated cast becaue val.type's base_type is ambiguous when using tags.
392
+ base = val .cast (impl_type ).cast (base_type )
393
+ (prev , sentinel ) = get_prev_and_sentinel (base )
394
+ prev = prev .cast (base_type .pointer ())
395
+ self .prev = cast_pointer (prev )
396
+ self .next = cast_pointer (val ['Next' ])
397
+ self .sentinel = sentinel
398
+
399
+ def children (self ):
400
+ if self .sentinel :
401
+ yield 'sentinel' , 'yes'
402
+ yield 'prev' , self .prev
403
+ yield 'next' , self .next
404
+
405
+ class IlistPrinter :
406
+ """Print an llvm::simple_ilist or llvm::iplist object."""
407
+
408
+ def __init__ (self , val ):
409
+ self .node_type = val .type .template_argument (0 )
410
+ sentinel = val ['Sentinel' ]
411
+ # First field is common base type of sentinel and ilist_node.
412
+ base_type = sentinel .type .fields ()[0 ].type
413
+ self .sentinel = sentinel .address .cast (base_type .pointer ())
414
+
415
+ def _pointers (self ):
416
+ pointer = self .sentinel
417
+ while True :
418
+ pointer = pointer ['Next' ].cast (pointer .type )
419
+ if pointer == self .sentinel :
420
+ return
421
+ yield pointer .cast (self .node_type .pointer ())
422
+
423
+ def children (self ):
424
+ for k , v in enumerate (self ._pointers ()):
425
+ yield ('[%d]' % k , v .dereference ())
426
+
427
+
368
428
pp = gdb .printing .RegexpCollectionPrettyPrinter ("LLVMSupport" )
369
429
pp .add_printer ('llvm::SmallString' , '^llvm::SmallString<.*>$' , SmallStringPrinter )
370
430
pp .add_printer ('llvm::StringRef' , '^llvm::StringRef$' , StringRefPrinter )
@@ -376,4 +436,7 @@ def make_pointer_union_printer(val):
376
436
pp .add_printer ('llvm::Twine' , '^llvm::Twine$' , TwinePrinter )
377
437
pp .add_printer ('llvm::PointerIntPair' , '^llvm::PointerIntPair<.*>$' , make_pointer_int_pair_printer )
378
438
pp .add_printer ('llvm::PointerUnion' , '^llvm::PointerUnion<.*>$' , make_pointer_union_printer )
439
+ pp .add_printer ('llvm::ilist_node' , '^llvm::ilist_node<.*>$' , IlistNodePrinter )
440
+ pp .add_printer ('llvm::iplist' , '^llvm::iplist<.*>$' , IlistPrinter )
441
+ pp .add_printer ('llvm::simple_ilist' , '^llvm::simple_ilist<.*>$' , IlistPrinter )
379
442
gdb .printing .register_pretty_printer (gdb .current_objfile (), pp )
0 commit comments