#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/ADT/ilist.h"
#include "llvm/Support/Error.h"
int Array[] = {1, 2, 3};
llvm::PointerIntPair<int *, 1> PointerIntPair(IntPtr, 1);
llvm::PointerUnion<float *, int *> PointerUnion(IntPtr);
+using IlistTag = llvm::ilist_tag<struct A>;
+using SimpleIlistTag = llvm::ilist_tag<struct B>;
+struct IlistNode : llvm::ilist_node<IlistNode, IlistTag>,
+ llvm::ilist_node<IlistNode, SimpleIlistTag> {
+ int Value;
+};
+auto Ilist = [] {
+ llvm::ilist<IlistNode, IlistTag> Result;
+ for (int I : {13, 14, 15}) {
+ Result.push_back(new IlistNode);
+ Result.back().Value = I;
+ }
+ return Result;
+}();
+auto SimpleIlist = []() {
+ llvm::simple_ilist<IlistNode, SimpleIlistTag> Result;
+ for (auto &Node : Ilist)
+ Result.push_front(Node);
+ return Result;
+}();
+
int main() { return 0; }
# CHECK: llvm::PointerUnion containing int * = {pointer = 0xabc}
p PointerUnion
-
+# Switch to print pretty adds newlines to the following statements.
+set print pretty
+
+# CHECK: {
+# CHECK: [0] = {
+# CHECK: <llvm::ilist_node<IlistNode, llvm::ilist_tag<A> >> = {
+# CHECK: prev = [[Ilist_Sentinel:0x.*]] <Ilist>,
+# CHECK: next = [[Node_14:0x.*]]
+# CHECK: },
+# CHECK: <llvm::ilist_node<IlistNode, llvm::ilist_tag<B> >> = {
+# CHECK: prev = [[Node_14]],
+# CHECK: next = [[SimpleIlist_Sentinel:0x.*]] <SimpleIlist>
+# CHECK: },
+# CHECK: members of IlistNode:
+# CHECK: Value = 13
+# CHECK: },
+# CHECK: [1] = {
+# CHECK: <llvm::ilist_node<IlistNode, llvm::ilist_tag<A> >> = {
+# CHECK: prev = [[Node_13:0x.*]],
+# CHECK: next = [[Node_15:0x.*]]
+# CHECK: },
+# CHECK: <llvm::ilist_node<IlistNode, llvm::ilist_tag<B> >> = {
+# CHECK: prev = [[Node_15]],
+# CHECK: next = [[Node_13]]
+# CHECK: },
+# CHECK: members of IlistNode:
+# CHECK: Value = 14
+# CHECK: },
+# CHECK: [2] = {
+# CHECK: <llvm::ilist_node<IlistNode, llvm::ilist_tag<A> >> = {
+# CHECK: prev = [[Node_14]],
+# CHECK: next = [[Ilist_Sentinel]] <Ilist>
+# CHECK: },
+# CHECK: <llvm::ilist_node<IlistNode, llvm::ilist_tag<B> >> = {
+# CHECK: prev = [[SimpleIlist_Sentinel]] <SimpleIlist>,
+# CHECK: next = [[Node_14]]
+# CHECK: },
+# CHECK: members of IlistNode:
+# CHECK: Value = 15
+# CHECK: }
+# CHECK: }
+p Ilist
+
+# CHECK: {
+# CHECK: [0] = {
+# CHECK: <llvm::ilist_node<IlistNode, llvm::ilist_tag<A> >> = {
+# CHECK: prev = [[Node_14]],
+# CHECK: next = [[Ilist_Sentinel]] <Ilist>
+# CHECK: },
+# CHECK: <llvm::ilist_node<IlistNode, llvm::ilist_tag<B> >> = {
+# CHECK: prev = [[SimpleIlist_Sentinel]] <SimpleIlist>,
+# CHECK: next = [[Node_14]]
+# CHECK: },
+# CHECK: members of IlistNode:
+# CHECK: Value = 15
+# CHECK: },
+# CHECK: [1] = {
+# CHECK: <llvm::ilist_node<IlistNode, llvm::ilist_tag<A> >> = {
+# CHECK: prev = [[Node_13]],
+# CHECK: next = [[Node_15]]
+# CHECK: },
+# CHECK: <llvm::ilist_node<IlistNode, llvm::ilist_tag<B> >> = {
+# CHECK: prev = [[Node_15]],
+# CHECK: next = [[Node_13]]
+# CHECK: },
+# CHECK: members of IlistNode:
+# CHECK: Value = 14
+# CHECK: },
+# CHECK: [2] = {
+# CHECK: <llvm::ilist_node<IlistNode, llvm::ilist_tag<A> >> = {
+# CHECK: prev = [[Ilist_Sentinel]] <Ilist>,
+# CHECK: next = [[Node_14]]
+# CHECK: },
+# CHECK: <llvm::ilist_node<IlistNode, llvm::ilist_tag<B> >> = {
+# CHECK: prev = [[Node_14]],
+# CHECK: next = [[SimpleIlist_Sentinel]] <SimpleIlist>
+# CHECK: },
+# CHECK: members of IlistNode:
+# CHECK: Value = 13
+# CHECK: }
+# CHECK: }
+p SimpleIlist
string = 'llvm::PointerUnion containing %s' % pointer_type
return make_printer(string, [('pointer', pointer.cast(pointer_type))])
+class IlistNodePrinter:
+ """Print an llvm::ilist_node object."""
+
+ def __init__(self, val):
+ impl_type = val.type.fields()[0].type
+ base_type = impl_type.fields()[0].type
+ derived_type = val.type.template_argument(0)
+
+ def get_prev_and_sentinel(base):
+ # One of Prev and PrevAndSentinel exists. Depending on #defines used to
+ # compile LLVM, the base_type's template argument is either true of false.
+ if base_type.template_argument(0):
+ return get_pointer_int_pair(base['PrevAndSentinel'])
+ return base['Prev'], None
+
+ # Casts a base_type pointer to the appropriate derived type.
+ def cast_pointer(pointer):
+ sentinel = get_prev_and_sentinel(pointer.dereference())[1]
+ pointer = pointer.cast(impl_type.pointer())
+ if sentinel:
+ return pointer
+ return pointer.cast(derived_type.pointer())
+
+ # Repeated cast becaue val.type's base_type is ambiguous when using tags.
+ base = val.cast(impl_type).cast(base_type)
+ (prev, sentinel) = get_prev_and_sentinel(base)
+ prev = prev.cast(base_type.pointer())
+ self.prev = cast_pointer(prev)
+ self.next = cast_pointer(val['Next'])
+ self.sentinel = sentinel
+
+ def children(self):
+ if self.sentinel:
+ yield 'sentinel', 'yes'
+ yield 'prev', self.prev
+ yield 'next', self.next
+
+class IlistPrinter:
+ """Print an llvm::simple_ilist or llvm::iplist object."""
+
+ def __init__(self, val):
+ self.node_type = val.type.template_argument(0)
+ sentinel = val['Sentinel']
+ # First field is common base type of sentinel and ilist_node.
+ base_type = sentinel.type.fields()[0].type
+ self.sentinel = sentinel.address.cast(base_type.pointer())
+
+ def _pointers(self):
+ pointer = self.sentinel
+ while True:
+ pointer = pointer['Next'].cast(pointer.type)
+ if pointer == self.sentinel:
+ return
+ yield pointer.cast(self.node_type.pointer())
+
+ def children(self):
+ for k, v in enumerate(self._pointers()):
+ yield ('[%d]' % k, v.dereference())
+
+
pp = gdb.printing.RegexpCollectionPrettyPrinter("LLVMSupport")
pp.add_printer('llvm::SmallString', '^llvm::SmallString<.*>$', SmallStringPrinter)
pp.add_printer('llvm::StringRef', '^llvm::StringRef$', StringRefPrinter)
pp.add_printer('llvm::Twine', '^llvm::Twine$', TwinePrinter)
pp.add_printer('llvm::PointerIntPair', '^llvm::PointerIntPair<.*>$', make_pointer_int_pair_printer)
pp.add_printer('llvm::PointerUnion', '^llvm::PointerUnion<.*>$', make_pointer_union_printer)
+pp.add_printer('llvm::ilist_node', '^llvm::ilist_node<.*>$', IlistNodePrinter)
+pp.add_printer('llvm::iplist', '^llvm::iplist<.*>$', IlistPrinter)
+pp.add_printer('llvm::simple_ilist', '^llvm::simple_ilist<.*>$', IlistPrinter)
gdb.printing.register_pretty_printer(gdb.current_objfile(), pp)