OSDN Git Service

* python/libstdcxx/v6/printers.py (StdForwardListPrinter): Add.
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / python / libstdcxx / v6 / printers.py
1 # Pretty-printers for libstc++.
2
3 # Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4
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.
9 #
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.
14 #
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/>.
17
18 import gdb
19 import itertools
20 import re
21
22 # Try to use the new-style pretty-printing if available.
23 _use_gdb_pp = True
24 try:
25     import gdb.printing
26 except ImportError:
27     _use_gdb_pp = False
28
29 class StdPointerPrinter:
30     "Print a smart pointer of some kind"
31
32     def __init__ (self, typename, val):
33         self.typename = typename
34         self.val = val
35
36     def to_string (self):
37         if self.val['_M_refcount']['_M_pi'] == 0:
38             return '%s (empty) %s' % (self.typename, self.val['_M_ptr'])
39         return '%s (count %d) %s' % (self.typename,
40                                      self.val['_M_refcount']['_M_pi']['_M_use_count'],
41                                      self.val['_M_ptr'])
42
43 class UniquePointerPrinter:
44     "Print a unique_ptr"
45
46     def __init__ (self, typename, val):
47         self.val = val
48
49     def to_string (self):
50         return self.val['_M_t']
51
52 class StdListPrinter:
53     "Print a std::list"
54
55     class _iterator:
56         def __init__(self, nodetype, head):
57             self.nodetype = nodetype
58             self.base = head['_M_next']
59             self.head = head.address
60             self.count = 0
61
62         def __iter__(self):
63             return self
64
65         def next(self):
66             if self.base == self.head:
67                 raise StopIteration
68             elt = self.base.cast(self.nodetype).dereference()
69             self.base = elt['_M_next']
70             count = self.count
71             self.count = self.count + 1
72             return ('[%d]' % count, elt['_M_data'])
73
74     def __init__(self, typename, val):
75         self.typename = typename
76         self.val = val
77
78     def children(self):
79         itype = self.val.type.template_argument(0)
80         # If the inferior program is compiled with -D_GLIBCXX_DEBUG
81         # some of the internal implementation details change.
82         if self.typename == "std::list":
83             nodetype = gdb.lookup_type('std::_List_node<%s>' % itype).pointer()
84         elif self.typename == "std::__debug::list":
85             nodetype = gdb.lookup_type('std::__norm::_List_node<%s>' % itype).pointer()
86         else:
87             raise ValueError, "Cannot cast list node for list printer."
88         return self._iterator(nodetype, self.val['_M_impl']['_M_node'])
89
90     def to_string(self):
91         if self.val['_M_impl']['_M_node'].address == self.val['_M_impl']['_M_node']['_M_next']:
92             return 'empty %s' % (self.typename)
93         return '%s' % (self.typename)
94
95 class StdListIteratorPrinter:
96     "Print std::list::iterator"
97
98     def __init__(self, typename, val):
99         self.val = val
100         self.typename = typename
101
102     def to_string(self):
103         itype = self.val.type.template_argument(0)
104         # If the inferior program is compiled with -D_GLIBCXX_DEBUG
105         # some of the internal implementation details change.
106         if self.typename == "std::_List_iterator" or self.typename == "std::_List_const_iterator":
107             nodetype = gdb.lookup_type('std::_List_node<%s>' % itype).pointer()
108         elif self.typename == "std::__norm::_List_iterator" or self.typename == "std::__norm::_List_const_iterator":
109             nodetype = gdb.lookup_type('std::__norm::_List_node<%s>' % itype).pointer()
110         else:
111             raise ValueError, "Cannot cast list node for list iterator printer."
112         return self.val['_M_node'].cast(nodetype).dereference()['_M_data']
113
114 class StdSlistPrinter:
115     "Print a __gnu_cxx::slist"
116
117     class _iterator:
118         def __init__(self, nodetype, head):
119             self.nodetype = nodetype
120             self.base = head['_M_head']['_M_next']
121             self.count = 0
122
123         def __iter__(self):
124             return self
125
126         def next(self):
127             if self.base == 0:
128                 raise StopIteration
129             elt = self.base.cast(self.nodetype).dereference()
130             self.base = elt['_M_next']
131             count = self.count
132             self.count = self.count + 1
133             return ('[%d]' % count, elt['_M_data'])
134
135     def __init__(self, typename, val):
136         self.val = val
137
138     def children(self):
139         itype = self.val.type.template_argument(0)
140         nodetype = gdb.lookup_type('__gnu_cxx::_Slist_node<%s>' % itype).pointer()
141         return self._iterator(nodetype, self.val)
142
143     def to_string(self):
144         if self.val['_M_head']['_M_next'] == 0:
145             return 'empty __gnu_cxx::slist'
146         return '__gnu_cxx::slist'
147
148 class StdSlistIteratorPrinter:
149     "Print __gnu_cxx::slist::iterator"
150
151     def __init__(self, typename, val):
152         self.val = val
153
154     def to_string(self):
155         itype = self.val.type.template_argument(0)
156         nodetype = gdb.lookup_type('__gnu_cxx::_Slist_node<%s>' % itype).pointer()
157         return self.val['_M_node'].cast(nodetype).dereference()['_M_data']
158
159 class StdVectorPrinter:
160     "Print a std::vector"
161
162     class _iterator:
163         def __init__ (self, start, finish, bitvec):
164             self.bitvec = bitvec
165             if bitvec:
166                 self.item   = start['_M_p']
167                 self.so     = start['_M_offset']
168                 self.finish = finish['_M_p']
169                 self.fo     = finish['_M_offset']
170                 itype = self.item.dereference().type
171                 self.isize = 8 * itype.sizeof
172             else:
173                 self.item = start
174                 self.finish = finish
175             self.count = 0
176
177         def __iter__(self):
178             return self
179
180         def next(self):
181             count = self.count
182             self.count = self.count + 1
183             if self.bitvec:
184                 if self.item == self.finish and self.so >= self.fo:
185                     raise StopIteration
186                 elt = self.item.dereference()
187                 if elt & (1 << self.so):
188                     obit = 1
189                 else:
190                     obit = 0
191                 self.so = self.so + 1
192                 if self.so >= self.isize:
193                     self.item = self.item + 1
194                     self.so = 0
195                 return ('[%d]' % count, obit)
196             else:
197                 if self.item == self.finish:
198                     raise StopIteration
199                 elt = self.item.dereference()
200                 self.item = self.item + 1
201                 return ('[%d]' % count, elt)
202
203     def __init__(self, typename, val):
204         self.typename = typename
205         self.val = val
206         self.is_bool = val.type.template_argument(0).code  == gdb.TYPE_CODE_BOOL
207
208     def children(self):
209         return self._iterator(self.val['_M_impl']['_M_start'],
210                               self.val['_M_impl']['_M_finish'],
211                               self.is_bool)
212
213     def to_string(self):
214         start = self.val['_M_impl']['_M_start']
215         finish = self.val['_M_impl']['_M_finish']
216         end = self.val['_M_impl']['_M_end_of_storage']
217         if self.is_bool:
218             start = self.val['_M_impl']['_M_start']['_M_p']
219             so    = self.val['_M_impl']['_M_start']['_M_offset']
220             finish = self.val['_M_impl']['_M_finish']['_M_p']
221             fo     = self.val['_M_impl']['_M_finish']['_M_offset']
222             itype = start.dereference().type
223             bl = 8 * itype.sizeof
224             length   = (bl - so) + bl * ((finish - start) - 1) + fo
225             capacity = bl * (end - start)
226             return ('%s<bool> of length %d, capacity %d'
227                     % (self.typename, int (length), int (capacity)))
228         else:
229             return ('%s of length %d, capacity %d'
230                     % (self.typename, int (finish - start), int (end - start)))
231
232     def display_hint(self):
233         return 'array'
234
235 class StdVectorIteratorPrinter:
236     "Print std::vector::iterator"
237
238     def __init__(self, typename, val):
239         self.val = val
240
241     def to_string(self):
242         return self.val['_M_current'].dereference()
243
244 class StdTuplePrinter:
245     "Print a std::tuple"
246
247     class _iterator:
248         def __init__ (self, head):
249             self.head = head
250
251             # Set the base class as the initial head of the
252             # tuple.
253             nodes = self.head.type.fields ()
254             if len (nodes) == 1:
255                 # Set the actual head to the first pair.
256                 self.head  = self.head.cast (nodes[0].type)
257             elif len (nodes) != 0:
258                 raise ValueError, "Top of tuple tree does not consist of a single node."
259             self.count = 0
260
261         def __iter__ (self):
262             return self
263
264         def next (self):
265             nodes = self.head.type.fields ()
266             # Check for further recursions in the inheritance tree.
267             if len (nodes) == 0:
268                 raise StopIteration
269             # Check that this iteration has an expected structure.
270             if len (nodes) != 2:
271                 raise ValueError, "Cannot parse more than 2 nodes in a tuple tree."
272
273             # - Left node is the next recursion parent.
274             # - Right node is the actual class contained in the tuple.
275
276             # Process right node.
277             impl = self.head.cast (nodes[1].type)
278
279             # Process left node and set it as head.
280             self.head  = self.head.cast (nodes[0].type)
281             self.count = self.count + 1
282
283             # Finally, check the implementation.  If it is
284             # wrapped in _M_head_impl return that, otherwise return
285             # the value "as is".
286             fields = impl.type.fields ()
287             if len (fields) < 1 or fields[0].name != "_M_head_impl":
288                 return ('[%d]' % self.count, impl)
289             else:
290                 return ('[%d]' % self.count, impl['_M_head_impl'])
291
292     def __init__ (self, typename, val):
293         self.typename = typename
294         self.val = val;
295
296     def children (self):
297         return self._iterator (self.val)
298
299     def to_string (self):
300         if len (self.val.type.fields ()) == 0:
301             return 'empty %s' % (self.typename)
302         return '%s containing' % (self.typename)
303
304 class StdStackOrQueuePrinter:
305     "Print a std::stack or std::queue"
306
307     def __init__ (self, typename, val):
308         self.typename = typename
309         self.visualizer = gdb.default_visualizer(val['c'])
310
311     def children (self):
312         return self.visualizer.children()
313
314     def to_string (self):
315         return '%s wrapping: %s' % (self.typename,
316                                     self.visualizer.to_string())
317
318     def display_hint (self):
319         if hasattr (self.visualizer, 'display_hint'):
320             return self.visualizer.display_hint ()
321         return None
322
323 class RbtreeIterator:
324     def __init__(self, rbtree):
325         self.size = rbtree['_M_t']['_M_impl']['_M_node_count']
326         self.node = rbtree['_M_t']['_M_impl']['_M_header']['_M_left']
327         self.count = 0
328
329     def __iter__(self):
330         return self
331
332     def __len__(self):
333         return int (self.size)
334
335     def next(self):
336         if self.count == self.size:
337             raise StopIteration
338         result = self.node
339         self.count = self.count + 1
340         if self.count < self.size:
341             # Compute the next node.
342             node = self.node
343             if node.dereference()['_M_right']:
344                 node = node.dereference()['_M_right']
345                 while node.dereference()['_M_left']:
346                     node = node.dereference()['_M_left']
347             else:
348                 parent = node.dereference()['_M_parent']
349                 while node == parent.dereference()['_M_right']:
350                     node = parent
351                     parent = parent.dereference()['_M_parent']
352                 if node.dereference()['_M_right'] != parent:
353                     node = parent
354             self.node = node
355         return result
356
357 # This is a pretty printer for std::_Rb_tree_iterator (which is
358 # std::map::iterator), and has nothing to do with the RbtreeIterator
359 # class above.
360 class StdRbtreeIteratorPrinter:
361     "Print std::map::iterator"
362
363     def __init__ (self, typename, val):
364         self.val = val
365
366     def to_string (self):
367         valuetype = self.val.type.template_argument(0)
368         nodetype = gdb.lookup_type('std::_Rb_tree_node < %s >' % valuetype)
369         nodetype = nodetype.pointer()
370         return self.val.cast(nodetype).dereference()['_M_value_field']
371
372 class StdDebugIteratorPrinter:
373     "Print a debug enabled version of an iterator"
374
375     def __init__ (self, typename, val):
376         self.val = val
377
378     # Just strip away the encapsulating __gnu_debug::_Safe_iterator
379     # and return the wrapped iterator value.
380     def to_string (self):
381         itype = self.val.type.template_argument(0)
382         return self.val['_M_current'].cast(itype)
383
384 class StdMapPrinter:
385     "Print a std::map or std::multimap"
386
387     # Turn an RbtreeIterator into a pretty-print iterator.
388     class _iter:
389         def __init__(self, rbiter, type):
390             self.rbiter = rbiter
391             self.count = 0
392             self.type = type
393
394         def __iter__(self):
395             return self
396
397         def next(self):
398             if self.count % 2 == 0:
399                 n = self.rbiter.next()
400                 n = n.cast(self.type).dereference()['_M_value_field']
401                 self.pair = n
402                 item = n['first']
403             else:
404                 item = self.pair['second']
405             result = ('[%d]' % self.count, item)
406             self.count = self.count + 1
407             return result
408
409     def __init__ (self, typename, val):
410         self.typename = typename
411         self.val = val
412
413     def to_string (self):
414         return '%s with %d elements' % (self.typename,
415                                         len (RbtreeIterator (self.val)))
416
417     def children (self):
418         keytype = self.val.type.template_argument(0).const()
419         valuetype = self.val.type.template_argument(1)
420         nodetype = gdb.lookup_type('std::_Rb_tree_node< std::pair< %s, %s > >' % (keytype, valuetype))
421         nodetype = nodetype.pointer()
422         return self._iter (RbtreeIterator (self.val), nodetype)
423
424     def display_hint (self):
425         return 'map'
426
427 class StdSetPrinter:
428     "Print a std::set or std::multiset"
429
430     # Turn an RbtreeIterator into a pretty-print iterator.
431     class _iter:
432         def __init__(self, rbiter, type):
433             self.rbiter = rbiter
434             self.count = 0
435             self.type = type
436
437         def __iter__(self):
438             return self
439
440         def next(self):
441             item = self.rbiter.next()
442             item = item.cast(self.type).dereference()['_M_value_field']
443             # FIXME: this is weird ... what to do?
444             # Maybe a 'set' display hint?
445             result = ('[%d]' % self.count, item)
446             self.count = self.count + 1
447             return result
448
449     def __init__ (self, typename, val):
450         self.typename = typename
451         self.val = val
452
453     def to_string (self):
454         return '%s with %d elements' % (self.typename,
455                                         len (RbtreeIterator (self.val)))
456
457     def children (self):
458         keytype = self.val.type.template_argument(0)
459         nodetype = gdb.lookup_type('std::_Rb_tree_node< %s >' % keytype).pointer()
460         return self._iter (RbtreeIterator (self.val), nodetype)
461
462 class StdBitsetPrinter:
463     "Print a std::bitset"
464
465     def __init__(self, typename, val):
466         self.typename = typename
467         self.val = val
468
469     def to_string (self):
470         # If template_argument handled values, we could print the
471         # size.  Or we could use a regexp on the type.
472         return '%s' % (self.typename)
473
474     def children (self):
475         words = self.val['_M_w']
476         wtype = words.type
477
478         # The _M_w member can be either an unsigned long, or an
479         # array.  This depends on the template specialization used.
480         # If it is a single long, convert to a single element list.
481         if wtype.code == gdb.TYPE_CODE_ARRAY:
482             tsize = wtype.target ().sizeof
483         else:
484             words = [words]
485             tsize = wtype.sizeof 
486
487         nwords = wtype.sizeof / tsize
488         result = []
489         byte = 0
490         while byte < nwords:
491             w = words[byte]
492             bit = 0
493             while w != 0:
494                 if (w & 1) != 0:
495                     # Another spot where we could use 'set'?
496                     result.append(('[%d]' % (byte * tsize * 8 + bit), 1))
497                 bit = bit + 1
498                 w = w >> 1
499             byte = byte + 1
500         return result
501
502 class StdDequePrinter:
503     "Print a std::deque"
504
505     class _iter:
506         def __init__(self, node, start, end, last, buffer_size):
507             self.node = node
508             self.p = start
509             self.end = end
510             self.last = last
511             self.buffer_size = buffer_size
512             self.count = 0
513
514         def __iter__(self):
515             return self
516
517         def next(self):
518             if self.p == self.last:
519                 raise StopIteration
520
521             result = ('[%d]' % self.count, self.p.dereference())
522             self.count = self.count + 1
523
524             # Advance the 'cur' pointer.
525             self.p = self.p + 1
526             if self.p == self.end:
527                 # If we got to the end of this bucket, move to the
528                 # next bucket.
529                 self.node = self.node + 1
530                 self.p = self.node[0]
531                 self.end = self.p + self.buffer_size
532
533             return result
534
535     def __init__(self, typename, val):
536         self.typename = typename
537         self.val = val
538         self.elttype = val.type.template_argument(0)
539         size = self.elttype.sizeof
540         if size < 512:
541             self.buffer_size = int (512 / size)
542         else:
543             self.buffer_size = 1
544
545     def to_string(self):
546         start = self.val['_M_impl']['_M_start']
547         end = self.val['_M_impl']['_M_finish']
548
549         delta_n = end['_M_node'] - start['_M_node'] - 1
550         delta_s = start['_M_last'] - start['_M_cur']
551         delta_e = end['_M_cur'] - end['_M_first']
552
553         size = self.buffer_size * delta_n + delta_s + delta_e
554
555         return '%s with %d elements' % (self.typename, long (size))
556
557     def children(self):
558         start = self.val['_M_impl']['_M_start']
559         end = self.val['_M_impl']['_M_finish']
560         return self._iter(start['_M_node'], start['_M_cur'], start['_M_last'],
561                           end['_M_cur'], self.buffer_size)
562
563     def display_hint (self):
564         return 'array'
565
566 class StdDequeIteratorPrinter:
567     "Print std::deque::iterator"
568
569     def __init__(self, typename, val):
570         self.val = val
571
572     def to_string(self):
573         return self.val['_M_cur'].dereference()
574
575 class StdStringPrinter:
576     "Print a std::basic_string of some kind"
577
578     def __init__(self, typename, val):
579         self.val = val
580
581     def to_string(self):
582         # Make sure &string works, too.
583         type = self.val.type
584         if type.code == gdb.TYPE_CODE_REF:
585             type = type.target ()
586
587         # Calculate the length of the string so that to_string returns
588         # the string according to length, not according to first null
589         # encountered.
590         ptr = self.val ['_M_dataplus']['_M_p']
591         realtype = type.unqualified ().strip_typedefs ()
592         reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer ()
593         header = ptr.cast(reptype) - 1
594         len = header.dereference ()['_M_length']
595         if hasattr(ptr, "lazy_string"):
596             return ptr.lazy_string (length = len)
597         return ptr.string (length = len)
598
599     def display_hint (self):
600         return 'string'
601
602 class Tr1HashtableIterator:
603     def __init__ (self, hash):
604         self.count = 0
605         self.n_buckets = hash['_M_element_count']
606         if self.n_buckets == 0:
607             self.node = False
608         else:
609             self.bucket = hash['_M_buckets']
610             self.node = self.bucket[0]
611             self.update ()
612
613     def __iter__ (self):
614         return self
615
616     def update (self):
617         # If we advanced off the end of the chain, move to the next
618         # bucket.
619         while self.node == 0:
620             self.bucket = self.bucket + 1
621             self.node = self.bucket[0]
622
623        # If we advanced off the end of the bucket array, then
624        # we're done.
625         if self.count == self.n_buckets:
626             self.node = False
627         else:
628             self.count = self.count + 1
629
630     def next (self):
631         if not self.node:
632             raise StopIteration
633         result = self.node.dereference()['_M_v']
634         self.node = self.node.dereference()['_M_next']
635         self.update ()
636         return result
637
638 class Tr1UnorderedSetPrinter:
639     "Print a tr1::unordered_set"
640
641     def __init__ (self, typename, val):
642         self.typename = typename
643         self.val = val
644
645     def to_string (self):
646         return '%s with %d elements' % (self.typename, self.val['_M_element_count'])
647
648     @staticmethod
649     def format_count (i):
650         return '[%d]' % i
651
652     def children (self):
653         counter = itertools.imap (self.format_count, itertools.count())
654         return itertools.izip (counter, Tr1HashtableIterator (self.val))
655
656 class Tr1UnorderedMapPrinter:
657     "Print a tr1::unordered_map"
658
659     def __init__ (self, typename, val):
660         self.typename = typename
661         self.val = val
662
663     def to_string (self):
664         return '%s with %d elements' % (self.typename, self.val['_M_element_count'])
665
666     @staticmethod
667     def flatten (list):
668         for elt in list:
669             for i in elt:
670                 yield i
671
672     @staticmethod
673     def format_one (elt):
674         return (elt['first'], elt['second'])
675
676     @staticmethod
677     def format_count (i):
678         return '[%d]' % i
679
680     def children (self):
681         counter = itertools.imap (self.format_count, itertools.count())
682         # Map over the hash table and flatten the result.
683         data = self.flatten (itertools.imap (self.format_one, Tr1HashtableIterator (self.val)))
684         # Zip the two iterators together.
685         return itertools.izip (counter, data)
686
687     def display_hint (self):
688         return 'map'
689
690 class StdForwardListPrinter:
691     "Print a std::forward_list"
692
693     class _iterator:
694         def __init__(self, nodetype, head):
695             self.nodetype = nodetype
696             self.base = head['_M_next']
697             self.count = 0
698
699         def __iter__(self):
700             return self
701
702         def next(self):
703             if self.base == 0:
704                 raise StopIteration
705             elt = self.base.cast(self.nodetype).dereference()
706             self.base = elt['_M_next']
707             count = self.count
708             self.count = self.count + 1
709             return ('[%d]' % count, elt['_M_value'])
710
711     def __init__(self, typename, val):
712         self.val = val
713         self.typename = typename
714
715     def children(self):
716         itype = self.val.type.template_argument(0)
717         # If the inferior program is compiled with -D_GLIBCXX_DEBUG
718         # some of the internal implementation details change.
719         if self.typename == "std::forward_list":
720             nodetype = gdb.lookup_type('std::_Fwd_list_node<%s>' % itype).pointer()
721         elif self.typename == "std::__debug::list":
722             nodetype = gdb.lookup_type('std::__norm::_Fwd_list_node<%s>' % itype).pointer()
723         else:
724             raise ValueError, "Cannot cast forward_list node for forward_list printer."
725         return self._iterator(nodetype, self.val['_M_impl']['_M_head'])
726
727     def to_string(self):
728         if self.val['_M_impl']['_M_head']['_M_next'] == 0:
729             return 'empty %s' % (self.typename)
730         return '%s' % (self.typename)
731
732
733 # A "regular expression" printer which conforms to the
734 # "SubPrettyPrinter" protocol from gdb.printing.
735 class RxPrinter(object):
736     def __init__(self, name, function):
737         super(RxPrinter, self).__init__()
738         self.name = name
739         self.function = function
740         self.enabled = True
741
742     def invoke(self, value):
743         if not self.enabled:
744             return None
745         return self.function(self.name, value)
746
747 # A pretty-printer that conforms to the "PrettyPrinter" protocol from
748 # gdb.printing.  It can also be used directly as an old-style printer.
749 class Printer(object):
750     def __init__(self, name):
751         super(Printer, self).__init__()
752         self.name = name
753         self.subprinters = []
754         self.lookup = {}
755         self.enabled = True
756         self.compiled_rx = re.compile('^([a-zA-Z0-9_:]+)<.*>$')
757
758     def add(self, name, function):
759         # A small sanity check.
760         # FIXME
761         if not self.compiled_rx.match(name + '<>'):
762             raise ValueError, 'libstdc++ programming error: "%s" does not match' % name
763         printer = RxPrinter(name, function)
764         self.subprinters.append(printer)
765         self.lookup[name] = printer
766
767     @staticmethod
768     def get_basic_type(type):
769         # If it points to a reference, get the reference.
770         if type.code == gdb.TYPE_CODE_REF:
771             type = type.target ()
772
773         # Get the unqualified type, stripped of typedefs.
774         type = type.unqualified ().strip_typedefs ()
775
776         return type.tag
777
778     def __call__(self, val):
779         typename = self.get_basic_type(val.type)
780         if not typename:
781             return None
782
783         # All the types we match are template types, so we can use a
784         # dictionary.
785         match = self.compiled_rx.match(typename)
786         if not match:
787             return None
788
789         basename = match.group(1)
790         if basename in self.lookup:
791             return self.lookup[basename].invoke(val)
792
793         # Cannot find a pretty printer.  Return None.
794         return None
795
796 libstdcxx_printer = None
797
798 def register_libstdcxx_printers (obj):
799     "Register libstdc++ pretty-printers with objfile Obj."
800
801     global _use_gdb_pp
802     global libstdcxx_printer
803
804     if _use_gdb_pp:
805         gdb.printing.register_pretty_printer(obj, libstdcxx_printer)
806     else:
807         if obj is None:
808             obj = gdb
809         obj.pretty_printers.append(libstdcxx_printer)
810
811 def build_libstdcxx_dictionary ():
812     global libstdcxx_printer
813
814     libstdcxx_printer = Printer("libstdc++-v6")
815
816     # libstdc++ objects requiring pretty-printing.
817     # In order from:
818     # http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01847.html
819     libstdcxx_printer.add('std::basic_string', StdStringPrinter)
820     libstdcxx_printer.add('std::bitset', StdBitsetPrinter)
821     libstdcxx_printer.add('std::deque', StdDequePrinter)
822     libstdcxx_printer.add('std::list', StdListPrinter)
823     libstdcxx_printer.add('std::map', StdMapPrinter)
824     libstdcxx_printer.add('std::multimap', StdMapPrinter)
825     libstdcxx_printer.add('std::multiset', StdSetPrinter)
826     libstdcxx_printer.add('std::priority_queue', StdStackOrQueuePrinter)
827     libstdcxx_printer.add('std::queue', StdStackOrQueuePrinter)
828     libstdcxx_printer.add('std::tuple', StdTuplePrinter)
829     libstdcxx_printer.add('std::set', StdSetPrinter)
830     libstdcxx_printer.add('std::stack', StdStackOrQueuePrinter)
831     libstdcxx_printer.add('std::unique_ptr', UniquePointerPrinter)
832     libstdcxx_printer.add('std::vector', StdVectorPrinter)
833     # vector<bool>
834
835     # Printer registrations for classes compiled with -D_GLIBCXX_DEBUG.
836     libstdcxx_printer.add('std::__debug::bitset', StdBitsetPrinter)
837     libstdcxx_printer.add('std::__debug::deque', StdDequePrinter)
838     libstdcxx_printer.add('std::__debug::list', StdListPrinter)
839     libstdcxx_printer.add('std::__debug::map', StdMapPrinter)
840     libstdcxx_printer.add('std::__debug::multimap', StdMapPrinter)
841     libstdcxx_printer.add('std::__debug::multiset', StdSetPrinter)
842     libstdcxx_printer.add('std::__debug::priority_queue',
843                           StdStackOrQueuePrinter)
844     libstdcxx_printer.add('std::__debug::queue', StdStackOrQueuePrinter)
845     libstdcxx_printer.add('std::__debug::set', StdSetPrinter)
846     libstdcxx_printer.add('std::__debug::stack', StdStackOrQueuePrinter)
847     libstdcxx_printer.add('std::__debug::unique_ptr', UniquePointerPrinter)
848     libstdcxx_printer.add('std::__debug::vector', StdVectorPrinter)
849
850     # These are the TR1 and C++0x printers.
851     # For array - the default GDB pretty-printer seems reasonable.
852     libstdcxx_printer.add('std::shared_ptr', StdPointerPrinter)
853     libstdcxx_printer.add('std::weak_ptr', StdPointerPrinter)
854     libstdcxx_printer.add('std::unordered_map', Tr1UnorderedMapPrinter)
855     libstdcxx_printer.add('std::unordered_set', Tr1UnorderedSetPrinter)
856     libstdcxx_printer.add('std::unordered_multimap', Tr1UnorderedMapPrinter)
857     libstdcxx_printer.add('std::unordered_multiset', Tr1UnorderedSetPrinter)
858     libstdcxx_printer.add('std::forward_list', StdForwardListPrinter)
859
860     libstdcxx_printer.add('std::tr1::shared_ptr', StdPointerPrinter)
861     libstdcxx_printer.add('std::tr1::weak_ptr', StdPointerPrinter)
862     libstdcxx_printer.add('std::tr1::unordered_map', Tr1UnorderedMapPrinter)
863     libstdcxx_printer.add('std::tr1::unordered_set', Tr1UnorderedSetPrinter)
864     libstdcxx_printer.add('std::tr1::unordered_multimap',
865                           Tr1UnorderedMapPrinter)
866     libstdcxx_printer.add('std::tr1::unordered_multiset',
867                           Tr1UnorderedSetPrinter)
868
869     # These are the C++0x printer registrations for -D_GLIBCXX_DEBUG cases.
870     # The tr1 namespace printers do not seem to have any debug
871     # equivalents, so do no register them.
872     libstdcxx_printer.add('std::__debug::unordered_map',
873                           Tr1UnorderedMapPrinter)
874     libstdcxx_printer.add('std::__debug::unordered_set',
875                           Tr1UnorderedSetPrinter)
876     libstdcxx_printer.add('std::__debug::unordered_multimap',
877                           Tr1UnorderedMapPrinter)
878     libstdcxx_printer.add('std::__debug::unordered_multiset',
879                           Tr1UnorderedSetPrinter)
880     libstdcxx_printer.add('std::__debug::forward_list',
881                           StdForwardListPrinter)
882
883
884     # Extensions.
885     libstdcxx_printer.add('__gnu_cxx::slist', StdSlistPrinter)
886
887     if True:
888         # These shouldn't be necessary, if GDB "print *i" worked.
889         # But it often doesn't, so here they are.
890         libstdcxx_printer.add('std::_List_iterator', StdListIteratorPrinter)
891         libstdcxx_printer.add('std::_List_const_iterator',
892                               StdListIteratorPrinter)
893         libstdcxx_printer.add('std::_Rb_tree_iterator',
894                               StdRbtreeIteratorPrinter)
895         libstdcxx_printer.add('std::_Rb_tree_const_iterator',
896                               StdRbtreeIteratorPrinter)
897         libstdcxx_printer.add('std::_Deque_iterator', StdDequeIteratorPrinter)
898         libstdcxx_printer.add('std::_Deque_const_iterator',
899                               StdDequeIteratorPrinter)
900         libstdcxx_printer.add('__gnu_cxx::__normal_iterator',
901                               StdVectorIteratorPrinter)
902         libstdcxx_printer.add('__gnu_cxx::_Slist_iterator',
903                               StdSlistIteratorPrinter)
904
905         # Debug (compiled with -D_GLIBCXX_DEBUG) printer
906         # registrations.  The Rb_tree debug iterator when unwrapped
907         # from the encapsulating __gnu_debug::_Safe_iterator does not
908         # have the __norm namespace. Just use the existing printer
909         # registration for that.
910         libstdcxx_printer.add('__gnu_debug::_Safe_iterator',
911                               StdDebugIteratorPrinter)
912         libstdcxx_printer.add('std::__norm::_List_iterator',
913                               StdListIteratorPrinter)
914         libstdcxx_printer.add('std::__norm::_List_const_iterator',
915                               StdListIteratorPrinter)
916         libstdcxx_printer.add('std::__norm::_Deque_const_iterator',
917                               StdDequeIteratorPrinter)
918         libstdcxx_printer.add('std::__norm::_Deque_iterator',
919                               StdDequeIteratorPrinter)
920
921 build_libstdcxx_dictionary ()