1 # Pretty-printers for libstc++.
3 # Copyright (C) 2008-2013 Free Software Foundation, Inc.
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
22 # Try to use the new-style pretty-printing if available.
29 # Try to install type-printers.
30 _use_type_printing
= False
33 if hasattr(gdb
.types
, 'TypePrinter'):
34 _use_type_printing
= True
38 # Starting with the type ORIG, search for the member type NAME. This
39 # handles searching upward through superclasses. This is needed to
40 # work around http://sourceware.org/bugzilla/show_bug.cgi?id=13615.
41 def find_type(orig
, name
):
42 typ
= orig
.strip_typedefs()
44 search
= str(typ
) + '::' + name
46 return gdb
.lookup_type(search
)
49 # The type was not found, so try the superclass. We only need
50 # to check the first superclass, so we don't bother with
51 # anything fancier here.
52 field
= typ
.fields()[0]
53 if not field
.is_base_class
:
54 raise ValueError, "Cannot find type %s::%s" % (str(orig
), name
)
57 class SharedPointerPrinter
:
58 "Print a shared_ptr or weak_ptr"
60 def __init__ (self
, typename
, val
):
61 self
.typename
= typename
66 refcounts
= self
.val
['_M_refcount']['_M_pi']
68 usecount
= refcounts
['_M_use_count']
69 weakcount
= refcounts
['_M_weak_count']
71 state
= 'expired, weak %d' % weakcount
73 state
= 'count %d, weak %d' % (usecount
, weakcount
- 1)
74 return '%s (%s) %s' % (self
.typename
, state
, self
.val
['_M_ptr'])
76 class UniquePointerPrinter
:
79 def __init__ (self
, typename
, val
):
83 v
= self
.val
['_M_t']['_M_head_impl']
84 return ('std::unique_ptr<%s> containing %s' % (str(v
.type.target()),
91 def __init__(self
, nodetype
, head
):
92 self
.nodetype
= nodetype
93 self
.base
= head
['_M_next']
94 self
.head
= head
.address
101 if self
.base
== self
.head
:
103 elt
= self
.base
.cast(self
.nodetype
).dereference()
104 self
.base
= elt
['_M_next']
106 self
.count
= self
.count
+ 1
107 return ('[%d]' % count
, elt
['_M_data'])
109 def __init__(self
, typename
, val
):
110 self
.typename
= typename
114 nodetype
= find_type(self
.val
.type, '_Node')
115 nodetype
= nodetype
.strip_typedefs().pointer()
116 return self
._iterator
(nodetype
, self
.val
['_M_impl']['_M_node'])
119 if self
.val
['_M_impl']['_M_node'].address
== self
.val
['_M_impl']['_M_node']['_M_next']:
120 return 'empty %s' % (self
.typename
)
121 return '%s' % (self
.typename
)
123 class StdListIteratorPrinter
:
124 "Print std::list::iterator"
126 def __init__(self
, typename
, val
):
128 self
.typename
= typename
131 nodetype
= find_type(self
.val
.type, '_Node')
132 nodetype
= nodetype
.strip_typedefs().pointer()
133 return self
.val
['_M_node'].cast(nodetype
).dereference()['_M_data']
135 class StdSlistPrinter
:
136 "Print a __gnu_cxx::slist"
139 def __init__(self
, nodetype
, head
):
140 self
.nodetype
= nodetype
141 self
.base
= head
['_M_head']['_M_next']
150 elt
= self
.base
.cast(self
.nodetype
).dereference()
151 self
.base
= elt
['_M_next']
153 self
.count
= self
.count
+ 1
154 return ('[%d]' % count
, elt
['_M_data'])
156 def __init__(self
, typename
, val
):
160 nodetype
= find_type(self
.val
.type, '_Node')
161 nodetype
= nodetype
.strip_typedefs().pointer()
162 return self
._iterator
(nodetype
, self
.val
)
165 if self
.val
['_M_head']['_M_next'] == 0:
166 return 'empty __gnu_cxx::slist'
167 return '__gnu_cxx::slist'
169 class StdSlistIteratorPrinter
:
170 "Print __gnu_cxx::slist::iterator"
172 def __init__(self
, typename
, val
):
176 nodetype
= find_type(self
.val
.type, '_Node')
177 nodetype
= nodetype
.strip_typedefs().pointer()
178 return self
.val
['_M_node'].cast(nodetype
).dereference()['_M_data']
180 class StdVectorPrinter
:
181 "Print a std::vector"
184 def __init__ (self
, start
, finish
, bitvec
):
187 self
.item
= start
['_M_p']
188 self
.so
= start
['_M_offset']
189 self
.finish
= finish
['_M_p']
190 self
.fo
= finish
['_M_offset']
191 itype
= self
.item
.dereference().type
192 self
.isize
= 8 * itype
.sizeof
203 self
.count
= self
.count
+ 1
205 if self
.item
== self
.finish
and self
.so
>= self
.fo
:
207 elt
= self
.item
.dereference()
208 if elt
& (1 << self
.so
):
212 self
.so
= self
.so
+ 1
213 if self
.so
>= self
.isize
:
214 self
.item
= self
.item
+ 1
216 return ('[%d]' % count
, obit
)
218 if self
.item
== self
.finish
:
220 elt
= self
.item
.dereference()
221 self
.item
= self
.item
+ 1
222 return ('[%d]' % count
, elt
)
224 def __init__(self
, typename
, val
):
225 self
.typename
= typename
227 self
.is_bool
= val
.type.template_argument(0).code
== gdb
.TYPE_CODE_BOOL
230 return self
._iterator
(self
.val
['_M_impl']['_M_start'],
231 self
.val
['_M_impl']['_M_finish'],
235 start
= self
.val
['_M_impl']['_M_start']
236 finish
= self
.val
['_M_impl']['_M_finish']
237 end
= self
.val
['_M_impl']['_M_end_of_storage']
239 start
= self
.val
['_M_impl']['_M_start']['_M_p']
240 so
= self
.val
['_M_impl']['_M_start']['_M_offset']
241 finish
= self
.val
['_M_impl']['_M_finish']['_M_p']
242 fo
= self
.val
['_M_impl']['_M_finish']['_M_offset']
243 itype
= start
.dereference().type
244 bl
= 8 * itype
.sizeof
245 length
= (bl
- so
) + bl
* ((finish
- start
) - 1) + fo
246 capacity
= bl
* (end
- start
)
247 return ('%s<bool> of length %d, capacity %d'
248 % (self
.typename
, int (length
), int (capacity
)))
250 return ('%s of length %d, capacity %d'
251 % (self
.typename
, int (finish
- start
), int (end
- start
)))
253 def display_hint(self
):
256 class StdVectorIteratorPrinter
:
257 "Print std::vector::iterator"
259 def __init__(self
, typename
, val
):
263 return self
.val
['_M_current'].dereference()
265 class StdTuplePrinter
:
269 def __init__ (self
, head
):
272 # Set the base class as the initial head of the
274 nodes
= self
.head
.type.fields ()
276 # Set the actual head to the first pair.
277 self
.head
= self
.head
.cast (nodes
[0].type)
278 elif len (nodes
) != 0:
279 raise ValueError, "Top of tuple tree does not consist of a single node."
286 nodes
= self
.head
.type.fields ()
287 # Check for further recursions in the inheritance tree.
290 # Check that this iteration has an expected structure.
292 raise ValueError, "Cannot parse more than 2 nodes in a tuple tree."
294 # - Left node is the next recursion parent.
295 # - Right node is the actual class contained in the tuple.
297 # Process right node.
298 impl
= self
.head
.cast (nodes
[1].type)
300 # Process left node and set it as head.
301 self
.head
= self
.head
.cast (nodes
[0].type)
302 self
.count
= self
.count
+ 1
304 # Finally, check the implementation. If it is
305 # wrapped in _M_head_impl return that, otherwise return
307 fields
= impl
.type.fields ()
308 if len (fields
) < 1 or fields
[0].name
!= "_M_head_impl":
309 return ('[%d]' % self
.count
, impl
)
311 return ('[%d]' % self
.count
, impl
['_M_head_impl'])
313 def __init__ (self
, typename
, val
):
314 self
.typename
= typename
318 return self
._iterator
(self
.val
)
320 def to_string (self
):
321 if len (self
.val
.type.fields ()) == 0:
322 return 'empty %s' % (self
.typename
)
323 return '%s containing' % (self
.typename
)
325 class StdStackOrQueuePrinter
:
326 "Print a std::stack or std::queue"
328 def __init__ (self
, typename
, val
):
329 self
.typename
= typename
330 self
.visualizer
= gdb
.default_visualizer(val
['c'])
333 return self
.visualizer
.children()
335 def to_string (self
):
336 return '%s wrapping: %s' % (self
.typename
,
337 self
.visualizer
.to_string())
339 def display_hint (self
):
340 if hasattr (self
.visualizer
, 'display_hint'):
341 return self
.visualizer
.display_hint ()
344 class RbtreeIterator
:
345 def __init__(self
, rbtree
):
346 self
.size
= rbtree
['_M_t']['_M_impl']['_M_node_count']
347 self
.node
= rbtree
['_M_t']['_M_impl']['_M_header']['_M_left']
354 return int (self
.size
)
357 if self
.count
== self
.size
:
360 self
.count
= self
.count
+ 1
361 if self
.count
< self
.size
:
362 # Compute the next node.
364 if node
.dereference()['_M_right']:
365 node
= node
.dereference()['_M_right']
366 while node
.dereference()['_M_left']:
367 node
= node
.dereference()['_M_left']
369 parent
= node
.dereference()['_M_parent']
370 while node
== parent
.dereference()['_M_right']:
372 parent
= parent
.dereference()['_M_parent']
373 if node
.dereference()['_M_right'] != parent
:
378 # This is a pretty printer for std::_Rb_tree_iterator (which is
379 # std::map::iterator), and has nothing to do with the RbtreeIterator
381 class StdRbtreeIteratorPrinter
:
382 "Print std::map::iterator"
384 def __init__ (self
, typename
, val
):
387 def to_string (self
):
388 typename
= str(self
.val
.type.strip_typedefs()) + '::_Link_type'
389 nodetype
= gdb
.lookup_type(typename
).strip_typedefs()
390 return self
.val
.cast(nodetype
).dereference()['_M_value_field']
392 class StdDebugIteratorPrinter
:
393 "Print a debug enabled version of an iterator"
395 def __init__ (self
, typename
, val
):
398 # Just strip away the encapsulating __gnu_debug::_Safe_iterator
399 # and return the wrapped iterator value.
400 def to_string (self
):
401 itype
= self
.val
.type.template_argument(0)
402 return self
.val
['_M_current'].cast(itype
)
405 "Print a std::map or std::multimap"
407 # Turn an RbtreeIterator into a pretty-print iterator.
409 def __init__(self
, rbiter
, type):
418 if self
.count
% 2 == 0:
419 n
= self
.rbiter
.next()
420 n
= n
.cast(self
.type).dereference()['_M_value_field']
424 item
= self
.pair
['second']
425 result
= ('[%d]' % self
.count
, item
)
426 self
.count
= self
.count
+ 1
429 def __init__ (self
, typename
, val
):
430 self
.typename
= typename
433 def to_string (self
):
434 return '%s with %d elements' % (self
.typename
,
435 len (RbtreeIterator (self
.val
)))
438 rep_type
= find_type(self
.val
.type, '_Rep_type')
439 node
= find_type(rep_type
, '_Link_type')
440 node
= node
.strip_typedefs()
441 return self
._iter
(RbtreeIterator (self
.val
), node
)
443 def display_hint (self
):
447 "Print a std::set or std::multiset"
449 # Turn an RbtreeIterator into a pretty-print iterator.
451 def __init__(self
, rbiter
, type):
460 item
= self
.rbiter
.next()
461 item
= item
.cast(self
.type).dereference()['_M_value_field']
462 # FIXME: this is weird ... what to do?
463 # Maybe a 'set' display hint?
464 result
= ('[%d]' % self
.count
, item
)
465 self
.count
= self
.count
+ 1
468 def __init__ (self
, typename
, val
):
469 self
.typename
= typename
472 def to_string (self
):
473 return '%s with %d elements' % (self
.typename
,
474 len (RbtreeIterator (self
.val
)))
477 rep_type
= find_type(self
.val
.type, '_Rep_type')
478 node
= find_type(rep_type
, '_Link_type')
479 node
= node
.strip_typedefs()
480 return self
._iter
(RbtreeIterator (self
.val
), node
)
482 class StdBitsetPrinter
:
483 "Print a std::bitset"
485 def __init__(self
, typename
, val
):
486 self
.typename
= typename
489 def to_string (self
):
490 # If template_argument handled values, we could print the
491 # size. Or we could use a regexp on the type.
492 return '%s' % (self
.typename
)
495 words
= self
.val
['_M_w']
498 # The _M_w member can be either an unsigned long, or an
499 # array. This depends on the template specialization used.
500 # If it is a single long, convert to a single element list.
501 if wtype
.code
== gdb
.TYPE_CODE_ARRAY
:
502 tsize
= wtype
.target ().sizeof
507 nwords
= wtype
.sizeof
/ tsize
515 # Another spot where we could use 'set'?
516 result
.append(('[%d]' % (byte
* tsize
* 8 + bit
), 1))
522 class StdDequePrinter
:
526 def __init__(self
, node
, start
, end
, last
, buffer_size
):
531 self
.buffer_size
= buffer_size
538 if self
.p
== self
.last
:
541 result
= ('[%d]' % self
.count
, self
.p
.dereference())
542 self
.count
= self
.count
+ 1
544 # Advance the 'cur' pointer.
546 if self
.p
== self
.end
:
547 # If we got to the end of this bucket, move to the
549 self
.node
= self
.node
+ 1
550 self
.p
= self
.node
[0]
551 self
.end
= self
.p
+ self
.buffer_size
555 def __init__(self
, typename
, val
):
556 self
.typename
= typename
558 self
.elttype
= val
.type.template_argument(0)
559 size
= self
.elttype
.sizeof
561 self
.buffer_size
= int (512 / size
)
566 start
= self
.val
['_M_impl']['_M_start']
567 end
= self
.val
['_M_impl']['_M_finish']
569 delta_n
= end
['_M_node'] - start
['_M_node'] - 1
570 delta_s
= start
['_M_last'] - start
['_M_cur']
571 delta_e
= end
['_M_cur'] - end
['_M_first']
573 size
= self
.buffer_size
* delta_n
+ delta_s
+ delta_e
575 return '%s with %d elements' % (self
.typename
, long (size
))
578 start
= self
.val
['_M_impl']['_M_start']
579 end
= self
.val
['_M_impl']['_M_finish']
580 return self
._iter
(start
['_M_node'], start
['_M_cur'], start
['_M_last'],
581 end
['_M_cur'], self
.buffer_size
)
583 def display_hint (self
):
586 class StdDequeIteratorPrinter
:
587 "Print std::deque::iterator"
589 def __init__(self
, typename
, val
):
593 return self
.val
['_M_cur'].dereference()
595 class StdStringPrinter
:
596 "Print a std::basic_string of some kind"
598 def __init__(self
, typename
, val
):
602 # Make sure &string works, too.
604 if type.code
== gdb
.TYPE_CODE_REF
:
605 type = type.target ()
607 # Calculate the length of the string so that to_string returns
608 # the string according to length, not according to first null
610 ptr
= self
.val
['_M_dataplus']['_M_p']
611 realtype
= type.unqualified ().strip_typedefs ()
612 reptype
= gdb
.lookup_type (str (realtype
) + '::_Rep').pointer ()
613 header
= ptr
.cast(reptype
) - 1
614 len = header
.dereference ()['_M_length']
615 if hasattr(ptr
, "lazy_string"):
616 return ptr
.lazy_string (length
= len)
617 return ptr
.string (length
= len)
619 def display_hint (self
):
622 class Tr1HashtableIterator
:
623 def __init__ (self
, hash):
624 self
.buckets
= hash['_M_buckets']
626 self
.bucket_count
= hash['_M_bucket_count']
627 self
.node_type
= find_type(hash.type, '_Node').pointer()
629 while self
.bucket
!= self
.bucket_count
:
630 self
.node
= self
.buckets
[self
.bucket
]
633 self
.bucket
= self
.bucket
+ 1
641 node
= self
.node
.cast(self
.node_type
)
642 result
= node
.dereference()['_M_v']
643 self
.node
= node
.dereference()['_M_next'];
645 self
.bucket
= self
.bucket
+ 1
646 while self
.bucket
!= self
.bucket_count
:
647 self
.node
= self
.buckets
[self
.bucket
]
650 self
.bucket
= self
.bucket
+ 1
653 class StdHashtableIterator
:
654 def __init__(self
, hash):
655 self
.node
= hash['_M_before_begin']['_M_nxt']
656 self
.node_type
= find_type(hash.type, '__node_type').pointer()
664 elt
= self
.node
.cast(self
.node_type
).dereference()
665 self
.node
= elt
['_M_nxt']
666 valptr
= elt
['_M_storage'].address
667 valptr
= valptr
.cast(elt
.type.template_argument(0).pointer())
668 return valptr
.dereference()
670 class Tr1UnorderedSetPrinter
:
671 "Print a tr1::unordered_set"
673 def __init__ (self
, typename
, val
):
674 self
.typename
= typename
677 def hashtable (self
):
678 if self
.typename
.startswith('std::tr1'):
680 return self
.val
['_M_h']
682 def to_string (self
):
683 return '%s with %d elements' % (self
.typename
, self
.hashtable()['_M_element_count'])
686 def format_count (i
):
690 counter
= itertools
.imap (self
.format_count
, itertools
.count())
691 if self
.typename
.startswith('std::tr1'):
692 return itertools
.izip (counter
, Tr1HashtableIterator (self
.hashtable()))
693 return itertools
.izip (counter
, StdHashtableIterator (self
.hashtable()))
695 class Tr1UnorderedMapPrinter
:
696 "Print a tr1::unordered_map"
698 def __init__ (self
, typename
, val
):
699 self
.typename
= typename
702 def hashtable (self
):
703 if self
.typename
.startswith('std::tr1'):
705 return self
.val
['_M_h']
707 def to_string (self
):
708 return '%s with %d elements' % (self
.typename
, self
.hashtable()['_M_element_count'])
717 def format_one (elt
):
718 return (elt
['first'], elt
['second'])
721 def format_count (i
):
725 counter
= itertools
.imap (self
.format_count
, itertools
.count())
726 # Map over the hash table and flatten the result.
727 if self
.typename
.startswith('std::tr1'):
728 data
= self
.flatten (itertools
.imap (self
.format_one
, Tr1HashtableIterator (self
.hashtable())))
729 # Zip the two iterators together.
730 return itertools
.izip (counter
, data
)
731 data
= self
.flatten (itertools
.imap (self
.format_one
, StdHashtableIterator (self
.hashtable())))
732 # Zip the two iterators together.
733 return itertools
.izip (counter
, data
)
736 def display_hint (self
):
739 class StdForwardListPrinter
:
740 "Print a std::forward_list"
743 def __init__(self
, nodetype
, head
):
744 self
.nodetype
= nodetype
745 self
.base
= head
['_M_next']
754 elt
= self
.base
.cast(self
.nodetype
).dereference()
755 self
.base
= elt
['_M_next']
757 self
.count
= self
.count
+ 1
758 valptr
= elt
['_M_storage'].address
759 valptr
= valptr
.cast(elt
.type.template_argument(0).pointer())
760 return ('[%d]' % count
, valptr
.dereference())
762 def __init__(self
, typename
, val
):
764 self
.typename
= typename
767 nodetype
= find_type(self
.val
.type, '_Node')
768 nodetype
= nodetype
.strip_typedefs().pointer()
769 return self
._iterator
(nodetype
, self
.val
['_M_impl']['_M_head'])
772 if self
.val
['_M_impl']['_M_head']['_M_next'] == 0:
773 return 'empty %s' % (self
.typename
)
774 return '%s' % (self
.typename
)
777 # A "regular expression" printer which conforms to the
778 # "SubPrettyPrinter" protocol from gdb.printing.
779 class RxPrinter(object):
780 def __init__(self
, name
, function
):
781 super(RxPrinter
, self
).__init
__()
783 self
.function
= function
786 def invoke(self
, value
):
789 return self
.function(self
.name
, value
)
791 # A pretty-printer that conforms to the "PrettyPrinter" protocol from
792 # gdb.printing. It can also be used directly as an old-style printer.
793 class Printer(object):
794 def __init__(self
, name
):
795 super(Printer
, self
).__init
__()
797 self
.subprinters
= []
800 self
.compiled_rx
= re
.compile('^([a-zA-Z0-9_:]+)<.*>$')
802 def add(self
, name
, function
):
803 # A small sanity check.
805 if not self
.compiled_rx
.match(name
+ '<>'):
806 raise ValueError, 'libstdc++ programming error: "%s" does not match' % name
807 printer
= RxPrinter(name
, function
)
808 self
.subprinters
.append(printer
)
809 self
.lookup
[name
] = printer
811 # Add a name using _GLIBCXX_BEGIN_NAMESPACE_VERSION.
812 def add_version(self
, base
, name
, function
):
813 self
.add(base
+ name
, function
)
814 self
.add(base
+ '__7::' + name
, function
)
816 # Add a name using _GLIBCXX_BEGIN_NAMESPACE_CONTAINER.
817 def add_container(self
, base
, name
, function
):
818 self
.add_version(base
, name
, function
)
819 self
.add_version(base
+ '__cxx1998::', name
, function
)
822 def get_basic_type(type):
823 # If it points to a reference, get the reference.
824 if type.code
== gdb
.TYPE_CODE_REF
:
825 type = type.target ()
827 # Get the unqualified type, stripped of typedefs.
828 type = type.unqualified ().strip_typedefs ()
832 def __call__(self
, val
):
833 typename
= self
.get_basic_type(val
.type)
837 # All the types we match are template types, so we can use a
839 match
= self
.compiled_rx
.match(typename
)
843 basename
= match
.group(1)
844 if basename
in self
.lookup
:
845 return self
.lookup
[basename
].invoke(val
)
847 # Cannot find a pretty printer. Return None.
850 libstdcxx_printer
= None
852 class FilteringTypePrinter(object):
853 def __init__(self
, match
, name
):
858 class _recognizer(object):
859 def __init__(self
, match
, name
):
864 def recognize(self
, type_obj
):
865 if type_obj
.tag
is None:
868 if self
.type_obj
is None:
869 if not self
.match
in type_obj
.tag
:
870 # Filter didn't match.
873 self
.type_obj
= gdb
.lookup_type(self
.name
).strip_typedefs()
876 if self
.type_obj
== type_obj
:
880 def instantiate(self
):
881 return self
._recognizer
(self
.match
, self
.name
)
883 def add_one_type_printer(obj
, match
, name
):
884 printer
= FilteringTypePrinter(match
, 'std::' + name
)
885 gdb
.types
.register_type_printer(obj
, printer
)
887 def register_type_printers(obj
):
888 global _use_type_printing
890 if not _use_type_printing
:
893 for pfx
in ('', 'w'):
894 add_one_type_printer(obj
, 'basic_string', pfx
+ 'string')
895 add_one_type_printer(obj
, 'basic_ios', pfx
+ 'ios')
896 add_one_type_printer(obj
, 'basic_streambuf', pfx
+ 'streambuf')
897 add_one_type_printer(obj
, 'basic_istream', pfx
+ 'istream')
898 add_one_type_printer(obj
, 'basic_ostream', pfx
+ 'ostream')
899 add_one_type_printer(obj
, 'basic_iostream', pfx
+ 'iostream')
900 add_one_type_printer(obj
, 'basic_stringbuf', pfx
+ 'stringbuf')
901 add_one_type_printer(obj
, 'basic_istringstream',
902 pfx
+ 'istringstream')
903 add_one_type_printer(obj
, 'basic_ostringstream',
904 pfx
+ 'ostringstream')
905 add_one_type_printer(obj
, 'basic_stringstream',
906 pfx
+ 'stringstream')
907 add_one_type_printer(obj
, 'basic_filebuf', pfx
+ 'filebuf')
908 add_one_type_printer(obj
, 'basic_ifstream', pfx
+ 'ifstream')
909 add_one_type_printer(obj
, 'basic_ofstream', pfx
+ 'ofstream')
910 add_one_type_printer(obj
, 'basic_fstream', pfx
+ 'fstream')
911 add_one_type_printer(obj
, 'basic_regex', pfx
+ 'regex')
912 add_one_type_printer(obj
, 'sub_match', pfx
+ 'csub_match')
913 add_one_type_printer(obj
, 'sub_match', pfx
+ 'ssub_match')
914 add_one_type_printer(obj
, 'match_results', pfx
+ 'cmatch')
915 add_one_type_printer(obj
, 'match_results', pfx
+ 'smatch')
916 add_one_type_printer(obj
, 'regex_iterator', pfx
+ 'cregex_iterator')
917 add_one_type_printer(obj
, 'regex_iterator', pfx
+ 'sregex_iterator')
918 add_one_type_printer(obj
, 'regex_token_iterator',
919 pfx
+ 'cregex_token_iterator')
920 add_one_type_printer(obj
, 'regex_token_iterator',
921 pfx
+ 'sregex_token_iterator')
923 # Note that we can't have a printer for std::wstreampos, because
924 # it shares the same underlying type as std::streampos.
925 add_one_type_printer(obj
, 'fpos', 'streampos')
926 add_one_type_printer(obj
, 'basic_string', 'u16string')
927 add_one_type_printer(obj
, 'basic_string', 'u32string')
929 for dur
in ('nanoseconds', 'microseconds', 'milliseconds',
930 'seconds', 'minutes', 'hours'):
931 add_one_type_printer(obj
, 'duration', dur
)
933 add_one_type_printer(obj
, 'linear_congruential_engine', 'minstd_rand0')
934 add_one_type_printer(obj
, 'linear_congruential_engine', 'minstd_rand')
935 add_one_type_printer(obj
, 'mersenne_twister_engine', 'mt19937')
936 add_one_type_printer(obj
, 'mersenne_twister_engine', 'mt19937_64')
937 add_one_type_printer(obj
, 'subtract_with_carry_engine', 'ranlux24_base')
938 add_one_type_printer(obj
, 'subtract_with_carry_engine', 'ranlux48_base')
939 add_one_type_printer(obj
, 'discard_block_engine', 'ranlux24')
940 add_one_type_printer(obj
, 'discard_block_engine', 'ranlux48')
941 add_one_type_printer(obj
, 'shuffle_order_engine', 'knuth_b')
943 def register_libstdcxx_printers (obj
):
944 "Register libstdc++ pretty-printers with objfile Obj."
947 global libstdcxx_printer
950 gdb
.printing
.register_pretty_printer(obj
, libstdcxx_printer
)
954 obj
.pretty_printers
.append(libstdcxx_printer
)
956 register_type_printers(obj
)
958 def build_libstdcxx_dictionary ():
959 global libstdcxx_printer
961 libstdcxx_printer
= Printer("libstdc++-v6")
963 # For _GLIBCXX_BEGIN_NAMESPACE_VERSION.
965 # For _GLIBCXX_BEGIN_NAMESPACE_CONTAINER.
966 container
= '(__cxx1998::' + vers
+ ')?'
968 # libstdc++ objects requiring pretty-printing.
970 # http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01847.html
971 libstdcxx_printer
.add_version('std::', 'basic_string', StdStringPrinter
)
972 libstdcxx_printer
.add_container('std::', 'bitset', StdBitsetPrinter
)
973 libstdcxx_printer
.add_container('std::', 'deque', StdDequePrinter
)
974 libstdcxx_printer
.add_container('std::', 'list', StdListPrinter
)
975 libstdcxx_printer
.add_container('std::', 'map', StdMapPrinter
)
976 libstdcxx_printer
.add_container('std::', 'multimap', StdMapPrinter
)
977 libstdcxx_printer
.add_container('std::', 'multiset', StdSetPrinter
)
978 libstdcxx_printer
.add_version('std::', 'priority_queue',
979 StdStackOrQueuePrinter
)
980 libstdcxx_printer
.add_version('std::', 'queue', StdStackOrQueuePrinter
)
981 libstdcxx_printer
.add_version('std::', 'tuple', StdTuplePrinter
)
982 libstdcxx_printer
.add_container('std::', 'set', StdSetPrinter
)
983 libstdcxx_printer
.add_version('std::', 'stack', StdStackOrQueuePrinter
)
984 libstdcxx_printer
.add_version('std::', 'unique_ptr', UniquePointerPrinter
)
985 libstdcxx_printer
.add_container('std::', 'vector', StdVectorPrinter
)
988 # Printer registrations for classes compiled with -D_GLIBCXX_DEBUG.
989 libstdcxx_printer
.add('std::__debug::bitset', StdBitsetPrinter
)
990 libstdcxx_printer
.add('std::__debug::deque', StdDequePrinter
)
991 libstdcxx_printer
.add('std::__debug::list', StdListPrinter
)
992 libstdcxx_printer
.add('std::__debug::map', StdMapPrinter
)
993 libstdcxx_printer
.add('std::__debug::multimap', StdMapPrinter
)
994 libstdcxx_printer
.add('std::__debug::multiset', StdSetPrinter
)
995 libstdcxx_printer
.add('std::__debug::priority_queue',
996 StdStackOrQueuePrinter
)
997 libstdcxx_printer
.add('std::__debug::queue', StdStackOrQueuePrinter
)
998 libstdcxx_printer
.add('std::__debug::set', StdSetPrinter
)
999 libstdcxx_printer
.add('std::__debug::stack', StdStackOrQueuePrinter
)
1000 libstdcxx_printer
.add('std::__debug::unique_ptr', UniquePointerPrinter
)
1001 libstdcxx_printer
.add('std::__debug::vector', StdVectorPrinter
)
1003 # These are the TR1 and C++0x printers.
1004 # For array - the default GDB pretty-printer seems reasonable.
1005 libstdcxx_printer
.add_version('std::', 'shared_ptr', SharedPointerPrinter
)
1006 libstdcxx_printer
.add_version('std::', 'weak_ptr', SharedPointerPrinter
)
1007 libstdcxx_printer
.add_container('std::', 'unordered_map',
1008 Tr1UnorderedMapPrinter
)
1009 libstdcxx_printer
.add_container('std::', 'unordered_set',
1010 Tr1UnorderedSetPrinter
)
1011 libstdcxx_printer
.add_container('std::', 'unordered_multimap',
1012 Tr1UnorderedMapPrinter
)
1013 libstdcxx_printer
.add_container('std::', 'unordered_multiset',
1014 Tr1UnorderedSetPrinter
)
1015 libstdcxx_printer
.add_container('std::', 'forward_list',
1016 StdForwardListPrinter
)
1018 libstdcxx_printer
.add_version('std::tr1::', 'shared_ptr', SharedPointerPrinter
)
1019 libstdcxx_printer
.add_version('std::tr1::', 'weak_ptr', SharedPointerPrinter
)
1020 libstdcxx_printer
.add_version('std::tr1::', 'unordered_map',
1021 Tr1UnorderedMapPrinter
)
1022 libstdcxx_printer
.add_version('std::tr1::', 'unordered_set',
1023 Tr1UnorderedSetPrinter
)
1024 libstdcxx_printer
.add_version('std::tr1::', 'unordered_multimap',
1025 Tr1UnorderedMapPrinter
)
1026 libstdcxx_printer
.add_version('std::tr1::', 'unordered_multiset',
1027 Tr1UnorderedSetPrinter
)
1029 # These are the C++0x printer registrations for -D_GLIBCXX_DEBUG cases.
1030 # The tr1 namespace printers do not seem to have any debug
1031 # equivalents, so do no register them.
1032 libstdcxx_printer
.add('std::__debug::unordered_map',
1033 Tr1UnorderedMapPrinter
)
1034 libstdcxx_printer
.add('std::__debug::unordered_set',
1035 Tr1UnorderedSetPrinter
)
1036 libstdcxx_printer
.add('std::__debug::unordered_multimap',
1037 Tr1UnorderedMapPrinter
)
1038 libstdcxx_printer
.add('std::__debug::unordered_multiset',
1039 Tr1UnorderedSetPrinter
)
1040 libstdcxx_printer
.add('std::__debug::forward_list',
1041 StdForwardListPrinter
)
1045 libstdcxx_printer
.add_version('__gnu_cxx::', 'slist', StdSlistPrinter
)
1048 # These shouldn't be necessary, if GDB "print *i" worked.
1049 # But it often doesn't, so here they are.
1050 libstdcxx_printer
.add_container('std::', '_List_iterator',
1051 StdListIteratorPrinter
)
1052 libstdcxx_printer
.add_container('std::', '_List_const_iterator',
1053 StdListIteratorPrinter
)
1054 libstdcxx_printer
.add_version('std::', '_Rb_tree_iterator',
1055 StdRbtreeIteratorPrinter
)
1056 libstdcxx_printer
.add_version('std::', '_Rb_tree_const_iterator',
1057 StdRbtreeIteratorPrinter
)
1058 libstdcxx_printer
.add_container('std::', '_Deque_iterator',
1059 StdDequeIteratorPrinter
)
1060 libstdcxx_printer
.add_container('std::', '_Deque_const_iterator',
1061 StdDequeIteratorPrinter
)
1062 libstdcxx_printer
.add_version('__gnu_cxx::', '__normal_iterator',
1063 StdVectorIteratorPrinter
)
1064 libstdcxx_printer
.add_version('__gnu_cxx::', '_Slist_iterator',
1065 StdSlistIteratorPrinter
)
1067 # Debug (compiled with -D_GLIBCXX_DEBUG) printer
1068 # registrations. The Rb_tree debug iterator when unwrapped
1069 # from the encapsulating __gnu_debug::_Safe_iterator does not
1070 # have the __norm namespace. Just use the existing printer
1071 # registration for that.
1072 libstdcxx_printer
.add('__gnu_debug::_Safe_iterator',
1073 StdDebugIteratorPrinter
)
1074 libstdcxx_printer
.add('std::__norm::_List_iterator',
1075 StdListIteratorPrinter
)
1076 libstdcxx_printer
.add('std::__norm::_List_const_iterator',
1077 StdListIteratorPrinter
)
1078 libstdcxx_printer
.add('std::__norm::_Deque_const_iterator',
1079 StdDequeIteratorPrinter
)
1080 libstdcxx_printer
.add('std::__norm::_Deque_iterator',
1081 StdDequeIteratorPrinter
)
1083 build_libstdcxx_dictionary ()