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