@@ -365,6 +365,66 @@ def make_pointer_union_printer(val):
365365 string = 'llvm::PointerUnion containing %s' % pointer_type
366366 return make_printer (string , [('pointer' , pointer .cast (pointer_type ))])
367367
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+
368428pp = gdb .printing .RegexpCollectionPrettyPrinter ("LLVMSupport" )
369429pp .add_printer ('llvm::SmallString' , '^llvm::SmallString<.*>$' , SmallStringPrinter )
370430pp .add_printer ('llvm::StringRef' , '^llvm::StringRef$' , StringRefPrinter )
@@ -376,4 +436,7 @@ def make_pointer_union_printer(val):
376436pp .add_printer ('llvm::Twine' , '^llvm::Twine$' , TwinePrinter )
377437pp .add_printer ('llvm::PointerIntPair' , '^llvm::PointerIntPair<.*>$' , make_pointer_int_pair_printer )
378438pp .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 )
379442gdb .printing .register_pretty_printer (gdb .current_objfile (), pp )
0 commit comments