1 # Pretty-printers for libstc++.
3 # Copyright (C) 2008, 2009, 2010 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 class StdPointerPrinter
:
23 "Print a smart pointer of some kind"
25 def __init__ (self
, typename
, val
):
26 self
.typename
= typename
30 if self
.val
['_M_refcount']['_M_pi'] == 0:
31 return '%s (empty) %s' % (self
.typename
, self
.val
['_M_ptr'])
32 return '%s (count %d) %s' % (self
.typename
,
33 self
.val
['_M_refcount']['_M_pi']['_M_use_count'],
36 class UniquePointerPrinter
:
39 def __init__ (self
, val
):
43 return self
.val
['_M_t']
49 def __init__(self
, nodetype
, head
):
50 self
.nodetype
= nodetype
51 self
.base
= head
['_M_next']
52 self
.head
= head
.address
59 if self
.base
== self
.head
:
61 elt
= self
.base
.cast(self
.nodetype
).dereference()
62 self
.base
= elt
['_M_next']
64 self
.count
= self
.count
+ 1
65 return ('[%d]' % count
, elt
['_M_data'])
67 def __init__(self
, typename
, val
):
68 self
.typename
= typename
72 itype
= self
.val
.type.template_argument(0)
73 # If the inferior program is compiled with -D_GLIBCXX_DEBUG
74 # some of the internal implementation details change.
75 if self
.typename
== "std::list":
76 nodetype
= gdb
.lookup_type('std::_List_node<%s>' % itype
).pointer()
77 elif self
.typename
== "std::__debug::list":
78 nodetype
= gdb
.lookup_type('std::__norm::_List_node<%s>' % itype
).pointer()
80 raise ValueError, "Cannot cast list node for list printer."
81 return self
._iterator
(nodetype
, self
.val
['_M_impl']['_M_node'])
84 if self
.val
['_M_impl']['_M_node'].address
== self
.val
['_M_impl']['_M_node']['_M_next']:
85 return 'empty %s' % (self
.typename
)
86 return '%s' % (self
.typename
)
88 class StdListIteratorPrinter
:
89 "Print std::list::iterator"
91 def __init__(self
, typename
, val
):
93 self
.typename
= typename
96 itype
= self
.val
.type.template_argument(0)
97 # If the inferior program is compiled with -D_GLIBCXX_DEBUG
98 # some of the internal implementation details change.
99 if self
.typename
== "std::_List_iterator" or self
.typename
== "std::_List_const_iterator":
100 nodetype
= gdb
.lookup_type('std::_List_node<%s>' % itype
).pointer()
101 elif self
.typename
== "std::__norm::_List_iterator" or self
.typename
== "std::__norm::_List_const_iterator":
102 nodetype
= gdb
.lookup_type('std::__norm::_List_node<%s>' % itype
).pointer()
104 raise ValueError, "Cannot cast list node for list iterator printer."
105 return self
.val
['_M_node'].cast(nodetype
).dereference()['_M_data']
107 class StdSlistPrinter
:
108 "Print a __gnu_cxx::slist"
111 def __init__(self
, nodetype
, head
):
112 self
.nodetype
= nodetype
113 self
.base
= head
['_M_head']['_M_next']
122 elt
= self
.base
.cast(self
.nodetype
).dereference()
123 self
.base
= elt
['_M_next']
125 self
.count
= self
.count
+ 1
126 return ('[%d]' % count
, elt
['_M_data'])
128 def __init__(self
, val
):
132 itype
= self
.val
.type.template_argument(0)
133 nodetype
= gdb
.lookup_type('__gnu_cxx::_Slist_node<%s>' % itype
).pointer()
134 return self
._iterator
(nodetype
, self
.val
)
137 if self
.val
['_M_head']['_M_next'] == 0:
138 return 'empty __gnu_cxx::slist'
139 return '__gnu_cxx::slist'
141 class StdSlistIteratorPrinter
:
142 "Print __gnu_cxx::slist::iterator"
144 def __init__(self
, val
):
148 itype
= self
.val
.type.template_argument(0)
149 nodetype
= gdb
.lookup_type('__gnu_cxx::_Slist_node<%s>' % itype
).pointer()
150 return self
.val
['_M_node'].cast(nodetype
).dereference()['_M_data']
152 class StdVectorPrinter
:
153 "Print a std::vector"
156 def __init__ (self
, start
, finish
, bitvec
):
159 self
.item
= start
['_M_p']
160 self
.so
= start
['_M_offset']
161 self
.finish
= finish
['_M_p']
162 self
.fo
= finish
['_M_offset']
163 itype
= self
.item
.dereference().type
164 self
.isize
= 8 * itype
.sizeof
175 self
.count
= self
.count
+ 1
177 if self
.item
== self
.finish
and self
.so
>= self
.fo
:
179 elt
= self
.item
.dereference()
180 if elt
& (1 << self
.so
):
184 self
.so
= self
.so
+ 1
185 if self
.so
>= self
.isize
:
186 self
.item
= self
.item
+ 1
188 return ('[%d]' % count
, obit
)
190 if self
.item
== self
.finish
:
192 elt
= self
.item
.dereference()
193 self
.item
= self
.item
+ 1
194 return ('[%d]' % count
, elt
)
196 def __init__(self
, typename
, val
):
197 self
.typename
= typename
199 self
.is_bool
= val
.type.template_argument(0).code
== gdb
.TYPE_CODE_BOOL
202 return self
._iterator
(self
.val
['_M_impl']['_M_start'],
203 self
.val
['_M_impl']['_M_finish'],
207 start
= self
.val
['_M_impl']['_M_start']
208 finish
= self
.val
['_M_impl']['_M_finish']
209 end
= self
.val
['_M_impl']['_M_end_of_storage']
211 start
= self
.val
['_M_impl']['_M_start']['_M_p']
212 so
= self
.val
['_M_impl']['_M_start']['_M_offset']
213 finish
= self
.val
['_M_impl']['_M_finish']['_M_p']
214 fo
= self
.val
['_M_impl']['_M_finish']['_M_offset']
215 itype
= start
.dereference().type
216 bl
= 8 * itype
.sizeof
217 length
= (bl
- so
) + bl
* ((finish
- start
) - 1) + fo
218 capacity
= bl
* (end
- start
)
219 return ('%s<bool> of length %d, capacity %d'
220 % (self
.typename
, int (length
), int (capacity
)))
222 return ('%s of length %d, capacity %d'
223 % (self
.typename
, int (finish
- start
), int (end
- start
)))
225 def display_hint(self
):
228 class StdVectorIteratorPrinter
:
229 "Print std::vector::iterator"
231 def __init__(self
, val
):
235 return self
.val
['_M_current'].dereference()
237 class StdTuplePrinter
:
241 def __init__ (self
, head
):
244 # Set the base class as the initial head of the
246 nodes
= self
.head
.type.fields ()
248 raise ValueError, "Top of tuple tree does not consist of a single node."
250 # Set the actual head to the first pair.
251 self
.head
= self
.head
.cast (nodes
[0].type)
258 nodes
= self
.head
.type.fields ()
259 # Check for further recursions in the inheritance tree.
262 # Check that this iteration has an expected structure.
264 raise ValueError, "Cannot parse more than 2 nodes in a tuple tree."
266 # - Left node is the next recursion parent.
267 # - Right node is the actual class contained in the tuple.
269 # Process right node.
270 impl
= self
.head
.cast (nodes
[1].type)
272 # Process left node and set it as head.
273 self
.head
= self
.head
.cast (nodes
[0].type)
274 self
.count
= self
.count
+ 1
276 # Finally, check the implementation. If it is
277 # wrapped in _M_head_impl return that, otherwise return
279 fields
= impl
.type.fields ()
280 if len (fields
) < 1 or fields
[0].name
!= "_M_head_impl":
281 return ('[%d]' % self
.count
, impl
)
283 return ('[%d]' % self
.count
, impl
['_M_head_impl'])
285 def __init__ (self
, typename
, val
):
286 self
.typename
= typename
290 return self
._iterator
(self
.val
)
292 def to_string (self
):
293 return '%s containing' % (self
.typename
)
295 class StdStackOrQueuePrinter
:
296 "Print a std::stack or std::queue"
298 def __init__ (self
, typename
, val
):
299 self
.typename
= typename
300 self
.visualizer
= gdb
.default_visualizer(val
['c'])
303 return self
.visualizer
.children()
305 def to_string (self
):
306 return '%s wrapping: %s' % (self
.typename
,
307 self
.visualizer
.to_string())
309 def display_hint (self
):
310 if hasattr (self
.visualizer
, 'display_hint'):
311 return self
.visualizer
.display_hint ()
314 class RbtreeIterator
:
315 def __init__(self
, rbtree
):
316 self
.size
= rbtree
['_M_t']['_M_impl']['_M_node_count']
317 self
.node
= rbtree
['_M_t']['_M_impl']['_M_header']['_M_left']
324 return int (self
.size
)
327 if self
.count
== self
.size
:
330 self
.count
= self
.count
+ 1
331 if self
.count
< self
.size
:
332 # Compute the next node.
334 if node
.dereference()['_M_right']:
335 node
= node
.dereference()['_M_right']
336 while node
.dereference()['_M_left']:
337 node
= node
.dereference()['_M_left']
339 parent
= node
.dereference()['_M_parent']
340 while node
== parent
.dereference()['_M_right']:
342 parent
= parent
.dereference()['_M_parent']
343 if node
.dereference()['_M_right'] != parent
:
348 # This is a pretty printer for std::_Rb_tree_iterator (which is
349 # std::map::iterator), and has nothing to do with the RbtreeIterator
351 class StdRbtreeIteratorPrinter
:
352 "Print std::map::iterator"
354 def __init__ (self
, val
):
357 def to_string (self
):
358 valuetype
= self
.val
.type.template_argument(0)
359 nodetype
= gdb
.lookup_type('std::_Rb_tree_node < %s >' % valuetype
)
360 nodetype
= nodetype
.pointer()
361 return self
.val
.cast(nodetype
).dereference()['_M_value_field']
363 class StdDebugIteratorPrinter
:
364 "Print a debug enabled version of an iterator"
366 def __init__ (self
, val
):
369 # Just strip away the encapsulating __gnu_debug::_Safe_iterator
370 # and return the wrapped iterator value.
371 def to_string (self
):
372 itype
= self
.val
.type.template_argument(0)
373 return self
.val
['_M_current'].cast(itype
)
376 "Print a std::map or std::multimap"
378 # Turn an RbtreeIterator into a pretty-print iterator.
380 def __init__(self
, rbiter
, type):
389 if self
.count
% 2 == 0:
390 n
= self
.rbiter
.next()
391 n
= n
.cast(self
.type).dereference()['_M_value_field']
395 item
= self
.pair
['second']
396 result
= ('[%d]' % self
.count
, item
)
397 self
.count
= self
.count
+ 1
400 def __init__ (self
, typename
, val
):
401 self
.typename
= typename
404 def to_string (self
):
405 return '%s with %d elements' % (self
.typename
,
406 len (RbtreeIterator (self
.val
)))
409 keytype
= self
.val
.type.template_argument(0).const()
410 valuetype
= self
.val
.type.template_argument(1)
411 nodetype
= gdb
.lookup_type('std::_Rb_tree_node< std::pair< %s, %s > >' % (keytype
, valuetype
))
412 nodetype
= nodetype
.pointer()
413 return self
._iter
(RbtreeIterator (self
.val
), nodetype
)
415 def display_hint (self
):
419 "Print a std::set or std::multiset"
421 # Turn an RbtreeIterator into a pretty-print iterator.
423 def __init__(self
, rbiter
, type):
432 item
= self
.rbiter
.next()
433 item
= item
.cast(self
.type).dereference()['_M_value_field']
434 # FIXME: this is weird ... what to do?
435 # Maybe a 'set' display hint?
436 result
= ('[%d]' % self
.count
, item
)
437 self
.count
= self
.count
+ 1
440 def __init__ (self
, typename
, val
):
441 self
.typename
= typename
444 def to_string (self
):
445 return '%s with %d elements' % (self
.typename
,
446 len (RbtreeIterator (self
.val
)))
449 keytype
= self
.val
.type.template_argument(0)
450 nodetype
= gdb
.lookup_type('std::_Rb_tree_node< %s >' % keytype
).pointer()
451 return self
._iter
(RbtreeIterator (self
.val
), nodetype
)
453 class StdBitsetPrinter
:
454 "Print a std::bitset"
456 def __init__(self
, typename
, val
):
457 self
.typename
= typename
460 def to_string (self
):
461 # If template_argument handled values, we could print the
462 # size. Or we could use a regexp on the type.
463 return '%s' % (self
.typename
)
466 words
= self
.val
['_M_w']
469 # The _M_w member can be either an unsigned long, or an
470 # array. This depends on the template specialization used.
471 # If it is a single long, convert to a single element list.
472 if wtype
.code
== gdb
.TYPE_CODE_ARRAY
:
473 tsize
= wtype
.target ().sizeof
478 nwords
= wtype
.sizeof
/ tsize
486 # Another spot where we could use 'set'?
487 result
.append(('[%d]' % (byte
* tsize
* 8 + bit
), 1))
493 class StdDequePrinter
:
497 def __init__(self
, node
, start
, end
, last
, buffer_size
):
502 self
.buffer_size
= buffer_size
509 if self
.p
== self
.last
:
512 result
= ('[%d]' % self
.count
, self
.p
.dereference())
513 self
.count
= self
.count
+ 1
515 # Advance the 'cur' pointer.
517 if self
.p
== self
.end
:
518 # If we got to the end of this bucket, move to the
520 self
.node
= self
.node
+ 1
521 self
.p
= self
.node
[0]
522 self
.end
= self
.p
+ self
.buffer_size
526 def __init__(self
, typename
, val
):
527 self
.typename
= typename
529 self
.elttype
= val
.type.template_argument(0)
530 size
= self
.elttype
.sizeof
532 self
.buffer_size
= int (512 / size
)
537 start
= self
.val
['_M_impl']['_M_start']
538 end
= self
.val
['_M_impl']['_M_finish']
540 delta_n
= end
['_M_node'] - start
['_M_node'] - 1
541 delta_s
= start
['_M_last'] - start
['_M_cur']
542 delta_e
= end
['_M_cur'] - end
['_M_first']
544 size
= self
.buffer_size
* delta_n
+ delta_s
+ delta_e
546 return '%s with %d elements' % (self
.typename
, long (size
))
549 start
= self
.val
['_M_impl']['_M_start']
550 end
= self
.val
['_M_impl']['_M_finish']
551 return self
._iter
(start
['_M_node'], start
['_M_cur'], start
['_M_last'],
552 end
['_M_cur'], self
.buffer_size
)
554 def display_hint (self
):
557 class StdDequeIteratorPrinter
:
558 "Print std::deque::iterator"
560 def __init__(self
, val
):
564 return self
.val
['_M_cur'].dereference()
566 class StdStringPrinter
:
567 "Print a std::basic_string of some kind"
569 def __init__(self
, val
):
573 # Make sure &string works, too.
575 if type.code
== gdb
.TYPE_CODE_REF
:
576 type = type.target ()
578 # Calculate the length of the string so that to_string returns
579 # the string according to length, not according to first null
581 ptr
= self
.val
['_M_dataplus']['_M_p']
582 realtype
= type.unqualified ().strip_typedefs ()
583 reptype
= gdb
.lookup_type (str (realtype
) + '::_Rep').pointer ()
584 header
= ptr
.cast(reptype
) - 1
585 len = header
.dereference ()['_M_length']
586 if hasattr(ptr
, "lazy_string"):
587 return ptr
.lazy_string (length
= len)
588 return ptr
.string (length
= len)
590 def display_hint (self
):
593 class Tr1HashtableIterator
:
594 def __init__ (self
, hash):
596 self
.n_buckets
= hash['_M_element_count']
597 if self
.n_buckets
== 0:
600 self
.bucket
= hash['_M_buckets']
601 self
.node
= self
.bucket
[0]
608 # If we advanced off the end of the chain, move to the next
610 while self
.node
== 0:
611 self
.bucket
= self
.bucket
+ 1
612 self
.node
= self
.bucket
[0]
614 # If we advanced off the end of the bucket array, then
616 if self
.count
== self
.n_buckets
:
619 self
.count
= self
.count
+ 1
624 result
= self
.node
.dereference()['_M_v']
625 self
.node
= self
.node
.dereference()['_M_next']
629 class Tr1UnorderedSetPrinter
:
630 "Print a tr1::unordered_set"
632 def __init__ (self
, typename
, val
):
633 self
.typename
= typename
636 def to_string (self
):
637 return '%s with %d elements' % (self
.typename
, self
.val
['_M_element_count'])
640 def format_count (i
):
644 counter
= itertools
.imap (self
.format_count
, itertools
.count())
645 return itertools
.izip (counter
, Tr1HashtableIterator (self
.val
))
647 class Tr1UnorderedMapPrinter
:
648 "Print a tr1::unordered_map"
650 def __init__ (self
, typename
, val
):
651 self
.typename
= typename
654 def to_string (self
):
655 return '%s with %d elements' % (self
.typename
, self
.val
['_M_element_count'])
664 def format_one (elt
):
665 return (elt
['first'], elt
['second'])
668 def format_count (i
):
672 counter
= itertools
.imap (self
.format_count
, itertools
.count())
673 # Map over the hash table and flatten the result.
674 data
= self
.flatten (itertools
.imap (self
.format_one
, Tr1HashtableIterator (self
.val
)))
675 # Zip the two iterators together.
676 return itertools
.izip (counter
, data
)
678 def display_hint (self
):
681 def register_libstdcxx_printers (obj
):
682 "Register libstdc++ pretty-printers with objfile Obj."
687 obj
.pretty_printers
.append (lookup_function
)
689 def lookup_function (val
):
690 "Look-up and return a pretty-printer that can print val."
695 # If it points to a reference, get the reference.
696 if type.code
== gdb
.TYPE_CODE_REF
:
697 type = type.target ()
699 # Get the unqualified type, stripped of typedefs.
700 type = type.unqualified ().strip_typedefs ()
707 # Iterate over local dictionary of types to determine
708 # if a printer is registered for that type. Return an
709 # instantiation of the printer if found.
710 for function
in pretty_printers_dict
:
711 if function
.search (typename
):
712 return pretty_printers_dict
[function
] (val
)
714 # Cannot find a pretty printer. Return None.
717 def build_libstdcxx_dictionary ():
718 # libstdc++ objects requiring pretty-printing.
720 # http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01847.html
721 pretty_printers_dict
[re
.compile('^std::basic_string<.*>$')] = lambda val
: StdStringPrinter(val
)
722 pretty_printers_dict
[re
.compile('^std::bitset<.*>$')] = lambda val
: StdBitsetPrinter("std::bitset", val
)
723 pretty_printers_dict
[re
.compile('^std::deque<.*>$')] = lambda val
: StdDequePrinter("std::deque", val
)
724 pretty_printers_dict
[re
.compile('^std::list<.*>$')] = lambda val
: StdListPrinter("std::list", val
)
725 pretty_printers_dict
[re
.compile('^std::map<.*>$')] = lambda val
: StdMapPrinter("std::map", val
)
726 pretty_printers_dict
[re
.compile('^std::multimap<.*>$')] = lambda val
: StdMapPrinter("std::multimap", val
)
727 pretty_printers_dict
[re
.compile('^std::multiset<.*>$')] = lambda val
: StdSetPrinter("std::multiset", val
)
728 pretty_printers_dict
[re
.compile('^std::priority_queue<.*>$')] = lambda val
: StdStackOrQueuePrinter("std::priority_queue", val
)
729 pretty_printers_dict
[re
.compile('^std::queue<.*>$')] = lambda val
: StdStackOrQueuePrinter("std::queue", val
)
730 pretty_printers_dict
[re
.compile('^std::tuple<.*>$')] = lambda val
: StdTuplePrinter("std::tuple", val
)
731 pretty_printers_dict
[re
.compile('^std::set<.*>$')] = lambda val
: StdSetPrinter("std::set", val
)
732 pretty_printers_dict
[re
.compile('^std::stack<.*>$')] = lambda val
: StdStackOrQueuePrinter("std::stack", val
)
733 pretty_printers_dict
[re
.compile('^std::unique_ptr<.*>$')] = UniquePointerPrinter
734 pretty_printers_dict
[re
.compile('^std::vector<.*>$')] = lambda val
: StdVectorPrinter("std::vector", val
)
737 # Printer registrations for classes compiled with -D_GLIBCXX_DEBUG.
738 pretty_printers_dict
[re
.compile('^std::__debug::bitset<.*>$')] = lambda val
: StdBitsetPrinter("std::__debug::bitset", val
)
739 pretty_printers_dict
[re
.compile('^std::__debug::deque<.*>$')] = lambda val
: StdDequePrinter("std::__debug::deque", val
)
740 pretty_printers_dict
[re
.compile('^std::__debug::list<.*>$')] = lambda val
: StdListPrinter("std::__debug::list", val
)
741 pretty_printers_dict
[re
.compile('^std::__debug::map<.*>$')] = lambda val
: StdMapPrinter("std::__debug::map", val
)
742 pretty_printers_dict
[re
.compile('^std::__debug::multimap<.*>$')] = lambda val
: StdMapPrinter("std::__debug::multimap", val
)
743 pretty_printers_dict
[re
.compile('^std::__debug::multiset<.*>$')] = lambda val
: StdSetPrinter("std::__debug::multiset", val
)
744 pretty_printers_dict
[re
.compile('^std::__debug::priority_queue<.*>$')] = lambda val
: StdStackOrQueuePrinter("std::__debug::priority_queue", val
)
745 pretty_printers_dict
[re
.compile('^std::__debug::queue<.*>$')] = lambda val
: StdStackOrQueuePrinter("std::__debug::queue", val
)
746 pretty_printers_dict
[re
.compile('^std::__debug::set<.*>$')] = lambda val
: StdSetPrinter("std::__debug::set", val
)
747 pretty_printers_dict
[re
.compile('^std::__debug::stack<.*>$')] = lambda val
: StdStackOrQueuePrinter("std::__debug::stack", val
)
748 pretty_printers_dict
[re
.compile('^std::__debug::unique_ptr<.*>$')] = UniquePointerPrinter
749 pretty_printers_dict
[re
.compile('^std::__debug::vector<.*>$')] = lambda val
: StdVectorPrinter("std::__debug::vector", val
)
751 # These are the TR1 and C++0x printers.
752 # For array - the default GDB pretty-printer seems reasonable.
753 pretty_printers_dict
[re
.compile('^std::shared_ptr<.*>$')] = lambda val
: StdPointerPrinter ('std::shared_ptr', val
)
754 pretty_printers_dict
[re
.compile('^std::weak_ptr<.*>$')] = lambda val
: StdPointerPrinter ('std::weak_ptr', val
)
755 pretty_printers_dict
[re
.compile('^std::unordered_map<.*>$')] = lambda val
: Tr1UnorderedMapPrinter ('std::unordered_map', val
)
756 pretty_printers_dict
[re
.compile('^std::unordered_set<.*>$')] = lambda val
: Tr1UnorderedSetPrinter ('std::unordered_set', val
)
757 pretty_printers_dict
[re
.compile('^std::unordered_multimap<.*>$')] = lambda val
: Tr1UnorderedMapPrinter ('std::unordered_multimap', val
)
758 pretty_printers_dict
[re
.compile('^std::unordered_multiset<.*>$')] = lambda val
: Tr1UnorderedSetPrinter ('std::unordered_multiset', val
)
760 pretty_printers_dict
[re
.compile('^std::tr1::shared_ptr<.*>$')] = lambda val
: StdPointerPrinter ('std::tr1::shared_ptr', val
)
761 pretty_printers_dict
[re
.compile('^std::tr1::weak_ptr<.*>$')] = lambda val
: StdPointerPrinter ('std::tr1::weak_ptr', val
)
762 pretty_printers_dict
[re
.compile('^std::tr1::unordered_map<.*>$')] = lambda val
: Tr1UnorderedMapPrinter ('std::tr1::unordered_map', val
)
763 pretty_printers_dict
[re
.compile('^std::tr1::unordered_set<.*>$')] = lambda val
: Tr1UnorderedSetPrinter ('std::tr1::unordered_set', val
)
764 pretty_printers_dict
[re
.compile('^std::tr1::unordered_multimap<.*>$')] = lambda val
: Tr1UnorderedMapPrinter ('std::tr1::unordered_multimap', val
)
765 pretty_printers_dict
[re
.compile('^std::tr1::unordered_multiset<.*>$')] = lambda val
: Tr1UnorderedSetPrinter ('std::tr1::unordered_multiset', val
)
767 # These are the C++0x printer registrations for -D_GLIBCXX_DEBUG cases.
768 # The tr1 namespace printers do not seem to have any debug
769 # equivalents, so do no register them.
770 pretty_printers_dict
[re
.compile('^std::__debug::unordered_map<.*>$')] = lambda val
: Tr1UnorderedMapPrinter ('std::__debug::unordered_map', val
)
771 pretty_printers_dict
[re
.compile('^std::__debug::unordered_set<.*>$')] = lambda val
: Tr1UnorderedSetPrinter ('std::__debug::unordered_set', val
)
772 pretty_printers_dict
[re
.compile('^std::__debug::unordered_multimap<.*>$')] = lambda val
: Tr1UnorderedMapPrinter ('std::__debug::unordered_multimap', val
)
773 pretty_printers_dict
[re
.compile('^std::__debug::unordered_multiset<.*>$')] = lambda val
: Tr1UnorderedSetPrinter ('std::__debug:unordered_multiset', val
)
777 pretty_printers_dict
[re
.compile('^__gnu_cxx::slist<.*>$')] = StdSlistPrinter
780 # These shouldn't be necessary, if GDB "print *i" worked.
781 # But it often doesn't, so here they are.
782 pretty_printers_dict
[re
.compile('^std::_List_iterator<.*>$')] = lambda val
: StdListIteratorPrinter("std::_List_iterator",val
)
783 pretty_printers_dict
[re
.compile('^std::_List_const_iterator<.*>$')] = lambda val
: StdListIteratorPrinter("std::_List_const_iterator",val
)
784 pretty_printers_dict
[re
.compile('^std::_Rb_tree_iterator<.*>$')] = lambda val
: StdRbtreeIteratorPrinter(val
)
785 pretty_printers_dict
[re
.compile('^std::_Rb_tree_const_iterator<.*>$')] = lambda val
: StdRbtreeIteratorPrinter(val
)
786 pretty_printers_dict
[re
.compile('^std::_Deque_iterator<.*>$')] = lambda val
: StdDequeIteratorPrinter(val
)
787 pretty_printers_dict
[re
.compile('^std::_Deque_const_iterator<.*>$')] = lambda val
: StdDequeIteratorPrinter(val
)
788 pretty_printers_dict
[re
.compile('^__gnu_cxx::__normal_iterator<.*>$')] = lambda val
: StdVectorIteratorPrinter(val
)
789 pretty_printers_dict
[re
.compile('^__gnu_cxx::_Slist_iterator<.*>$')] = lambda val
: StdSlistIteratorPrinter(val
)
791 # Debug (compiled with -D_GLIBCXX_DEBUG) printer registrations.
792 # The Rb_tree debug iterator when unwrapped from the encapsulating __gnu_debug::_Safe_iterator
793 # does not have the __norm namespace. Just use the existing printer registration for that.
794 pretty_printers_dict
[re
.compile('^__gnu_debug::_Safe_iterator<.*>$')] = lambda val
: StdDebugIteratorPrinter(val
)
795 pretty_printers_dict
[re
.compile('^std::__norm::_List_iterator<.*>$')] = lambda val
: StdListIteratorPrinter ("std::__norm::_List_iterator",val
)
796 pretty_printers_dict
[re
.compile('^std::__norm::_List_const_iterator<.*>$')] = lambda val
: StdListIteratorPrinter ("std::__norm::_List_const_iterator",val
)
797 pretty_printers_dict
[re
.compile('^std::__norm::_Deque_const_iterator<.*>$')] = lambda val
: StdDequeIteratorPrinter(val
)
798 pretty_printers_dict
[re
.compile('^std::__norm::_Deque_iterator<.*>$')] = lambda val
: StdDequeIteratorPrinter(val
)
800 pretty_printers_dict
= {}
802 build_libstdcxx_dictionary ()