cpp-d1064d
[cross.git] / i686-linux-gnu-4.7 / usr / share / gcc-8 / python / libstdcxx / v6 / printers.py
1 # Pretty-printers for libstdc++.
2
3 # Copyright (C) 2008-2018 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 import sys
22
23 ### Python 2 + Python 3 compatibility code
24
25 # Resources about compatibility:
26 #
27 #  * <http://pythonhosted.org/six/>: Documentation of the "six" module
28
29 # FIXME: The handling of e.g. std::basic_string (at least on char)
30 # probably needs updating to work with Python 3's new string rules.
31 #
32 # In particular, Python 3 has a separate type (called byte) for
33 # bytestrings, and a special b"" syntax for the byte literals; the old
34 # str() type has been redefined to always store Unicode text.
35 #
36 # We probably can't do much about this until this GDB PR is addressed:
37 # <https://sourceware.org/bugzilla/show_bug.cgi?id=17138>
38
39 if sys.version_info[0] > 2:
40     ### Python 3 stuff
41     Iterator = object
42     # Python 3 folds these into the normal functions.
43     imap = map
44     izip = zip
45     # Also, int subsumes long
46     long = int
47 else:
48     ### Python 2 stuff
49     class Iterator:
50         """Compatibility mixin for iterators
51
52         Instead of writing next() methods for iterators, write
53         __next__() methods and use this mixin to make them work in
54         Python 2 as well as Python 3.
55
56         Idea stolen from the "six" documentation:
57         <http://pythonhosted.org/six/#six.Iterator>
58         """
59
60         def next(self):
61             return self.__next__()
62
63     # In Python 2, we still need these from itertools
64     from itertools import imap, izip
65
66 # Try to use the new-style pretty-printing if available.
67 _use_gdb_pp = True
68 try:
69     import gdb.printing
70 except ImportError:
71     _use_gdb_pp = False
72
73 # Try to install type-printers.
74 _use_type_printing = False
75 try:
76     import gdb.types
77     if hasattr(gdb.types, 'TypePrinter'):
78         _use_type_printing = True
79 except ImportError:
80     pass
81
82 # Starting with the type ORIG, search for the member type NAME.  This
83 # handles searching upward through superclasses.  This is needed to
84 # work around http://sourceware.org/bugzilla/show_bug.cgi?id=13615.
85 def find_type(orig, name):
86     typ = orig.strip_typedefs()
87     while True:
88         # Strip cv-qualifiers.  PR 67440.
89         search = '%s::%s' % (typ.unqualified(), name)
90         try:
91             return gdb.lookup_type(search)
92         except RuntimeError:
93             pass
94         # The type was not found, so try the superclass.  We only need
95         # to check the first superclass, so we don't bother with
96         # anything fancier here.
97         field = typ.fields()[0]
98         if not field.is_base_class:
99             raise ValueError("Cannot find type %s::%s" % (str(orig), name))
100         typ = field.type
101
102 _versioned_namespace = '__8::'
103
104 def is_specialization_of(type, template_name):
105     "Test if a type is a given template instantiation."
106     global _versioned_namespace
107     if _versioned_namespace:
108         return re.match('^std::(%s)?%s<.*>$' % (_versioned_namespace, template_name), type) is not None
109     return re.match('^std::%s<.*>$' % template_name, type) is not None
110
111 def strip_versioned_namespace(typename):
112     global _versioned_namespace
113     if _versioned_namespace:
114         return typename.replace(_versioned_namespace, '')
115     return typename
116
117 def strip_inline_namespaces(type_str):
118     "Remove known inline namespaces from the canonical name of a type."
119     type_str = strip_versioned_namespace(type_str)
120     type_str = type_str.replace('std::__cxx11::', 'std::')
121     expt_ns = 'std::experimental::'
122     for lfts_ns in ('fundamentals_v1', 'fundamentals_v2'):
123         type_str = type_str.replace(expt_ns+lfts_ns+'::', expt_ns)
124     fs_ns = expt_ns + 'filesystem::'
125     type_str = type_str.replace(fs_ns+'v1::', fs_ns)
126     return type_str
127
128 def get_template_arg_list(type_obj):
129     "Return a type's template arguments as a list"
130     n = 0
131     template_args = []
132     while True:
133         try:
134             template_args.append(type_obj.template_argument(n))
135         except:
136             return template_args
137         n += 1
138
139 class SmartPtrIterator(Iterator):
140     "An iterator for smart pointer types with a single 'child' value"
141
142     def __init__(self, val):
143         self.val = val
144
145     def __iter__(self):
146         return self
147
148     def __next__(self):
149         if self.val is None:
150             raise StopIteration
151         self.val, val = None, self.val
152         return ('get()', val)
153
154 class SharedPointerPrinter:
155     "Print a shared_ptr or weak_ptr"
156
157     def __init__ (self, typename, val):
158         self.typename = strip_versioned_namespace(typename)
159         self.val = val
160         self.pointer = val['_M_ptr']
161
162     def children (self):
163         return SmartPtrIterator(self.pointer)
164
165     def to_string (self):
166         state = 'empty'
167         refcounts = self.val['_M_refcount']['_M_pi']
168         if refcounts != 0:
169             usecount = refcounts['_M_use_count']
170             weakcount = refcounts['_M_weak_count']
171             if usecount == 0:
172                 state = 'expired, weak count %d' % weakcount
173             else:
174                 state = 'use count %d, weak count %d' % (usecount, weakcount - 1)
175         return '%s<%s> (%s)' % (self.typename, str(self.val.type.template_argument(0)), state)
176
177 class UniquePointerPrinter:
178     "Print a unique_ptr"
179
180     def __init__ (self, typename, val):
181         self.val = val
182         impl_type = val.type.fields()[0].type.tag
183         if is_specialization_of(impl_type, '__uniq_ptr_impl'): # New implementation
184             self.pointer = val['_M_t']['_M_t']['_M_head_impl']
185         elif is_specialization_of(impl_type, 'tuple'):
186             self.pointer = val['_M_t']['_M_head_impl']
187         else:
188             raise ValueError("Unsupported implementation for unique_ptr: %s" % impl_type)
189
190     def children (self):
191         return SmartPtrIterator(self.pointer)
192
193     def to_string (self):
194         return ('std::unique_ptr<%s>' % (str(self.val.type.template_argument(0))))
195
196 def get_value_from_aligned_membuf(buf, valtype):
197     """Returns the value held in a __gnu_cxx::__aligned_membuf."""
198     return buf['_M_storage'].address.cast(valtype.pointer()).dereference()
199
200 def get_value_from_list_node(node):
201     """Returns the value held in an _List_node<_Val>"""
202     try:
203         member = node.type.fields()[1].name
204         if member == '_M_data':
205             # C++03 implementation, node contains the value as a member
206             return node['_M_data']
207         elif member == '_M_storage':
208             # C++11 implementation, node stores value in __aligned_membuf
209             valtype = node.type.template_argument(0)
210             return get_value_from_aligned_membuf(node['_M_storage'], valtype)
211     except:
212         pass
213     raise ValueError("Unsupported implementation for %s" % str(node.type))
214
215 class StdListPrinter:
216     "Print a std::list"
217
218     class _iterator(Iterator):
219         def __init__(self, nodetype, head):
220             self.nodetype = nodetype
221             self.base = head['_M_next']
222             self.head = head.address
223             self.count = 0
224
225         def __iter__(self):
226             return self
227
228         def __next__(self):
229             if self.base == self.head:
230                 raise StopIteration
231             elt = self.base.cast(self.nodetype).dereference()
232             self.base = elt['_M_next']
233             count = self.count
234             self.count = self.count + 1
235             val = get_value_from_list_node(elt)
236             return ('[%d]' % count, val)
237
238     def __init__(self, typename, val):
239         self.typename = strip_versioned_namespace(typename)
240         self.val = val
241
242     def children(self):
243         nodetype = find_type(self.val.type, '_Node')
244         nodetype = nodetype.strip_typedefs().pointer()
245         return self._iterator(nodetype, self.val['_M_impl']['_M_node'])
246
247     def to_string(self):
248         if self.val['_M_impl']['_M_node'].address == self.val['_M_impl']['_M_node']['_M_next']:
249             return 'empty %s' % (self.typename)
250         return '%s' % (self.typename)
251
252 class NodeIteratorPrinter:
253     def __init__(self, typename, val, contname):
254         self.val = val
255         self.typename = typename
256         self.contname = contname
257
258     def to_string(self):
259         if not self.val['_M_node']:
260             return 'non-dereferenceable iterator for std::%s' % (self.contname)
261         nodetype = find_type(self.val.type, '_Node')
262         nodetype = nodetype.strip_typedefs().pointer()
263         node = self.val['_M_node'].cast(nodetype).dereference()
264         return str(get_value_from_list_node(node))
265
266 class StdListIteratorPrinter(NodeIteratorPrinter):
267     "Print std::list::iterator"
268
269     def __init__(self, typename, val):
270         NodeIteratorPrinter.__init__(self, typename, val, 'list')
271
272 class StdFwdListIteratorPrinter(NodeIteratorPrinter):
273     "Print std::forward_list::iterator"
274
275     def __init__(self, typename, val):
276         NodeIteratorPrinter.__init__(self, typename, val, 'forward_list')
277
278 class StdSlistPrinter:
279     "Print a __gnu_cxx::slist"
280
281     class _iterator(Iterator):
282         def __init__(self, nodetype, head):
283             self.nodetype = nodetype
284             self.base = head['_M_head']['_M_next']
285             self.count = 0
286
287         def __iter__(self):
288             return self
289
290         def __next__(self):
291             if self.base == 0:
292                 raise StopIteration
293             elt = self.base.cast(self.nodetype).dereference()
294             self.base = elt['_M_next']
295             count = self.count
296             self.count = self.count + 1
297             return ('[%d]' % count, elt['_M_data'])
298
299     def __init__(self, typename, val):
300         self.val = val
301
302     def children(self):
303         nodetype = find_type(self.val.type, '_Node')
304         nodetype = nodetype.strip_typedefs().pointer()
305         return self._iterator(nodetype, self.val)
306
307     def to_string(self):
308         if self.val['_M_head']['_M_next'] == 0:
309             return 'empty __gnu_cxx::slist'
310         return '__gnu_cxx::slist'
311
312 class StdSlistIteratorPrinter:
313     "Print __gnu_cxx::slist::iterator"
314
315     def __init__(self, typename, val):
316         self.val = val
317
318     def to_string(self):
319         if not self.val['_M_node']:
320             return 'non-dereferenceable iterator for __gnu_cxx::slist'
321         nodetype = find_type(self.val.type, '_Node')
322         nodetype = nodetype.strip_typedefs().pointer()
323         return str(self.val['_M_node'].cast(nodetype).dereference()['_M_data'])
324
325 class StdVectorPrinter:
326     "Print a std::vector"
327
328     class _iterator(Iterator):
329         def __init__ (self, start, finish, bitvec):
330             self.bitvec = bitvec
331             if bitvec:
332                 self.item   = start['_M_p']
333                 self.so     = start['_M_offset']
334                 self.finish = finish['_M_p']
335                 self.fo     = finish['_M_offset']
336                 itype = self.item.dereference().type
337                 self.isize = 8 * itype.sizeof
338             else:
339                 self.item = start
340                 self.finish = finish
341             self.count = 0
342
343         def __iter__(self):
344             return self
345
346         def __next__(self):
347             count = self.count
348             self.count = self.count + 1
349             if self.bitvec:
350                 if self.item == self.finish and self.so >= self.fo:
351                     raise StopIteration
352                 elt = self.item.dereference()
353                 if elt & (1 << self.so):
354                     obit = 1
355                 else:
356                     obit = 0
357                 self.so = self.so + 1
358                 if self.so >= self.isize:
359                     self.item = self.item + 1
360                     self.so = 0
361                 return ('[%d]' % count, obit)
362             else:
363                 if self.item == self.finish:
364                     raise StopIteration
365                 elt = self.item.dereference()
366                 self.item = self.item + 1
367                 return ('[%d]' % count, elt)
368
369     def __init__(self, typename, val):
370         self.typename = strip_versioned_namespace(typename)
371         self.val = val
372         self.is_bool = val.type.template_argument(0).code  == gdb.TYPE_CODE_BOOL
373
374     def children(self):
375         return self._iterator(self.val['_M_impl']['_M_start'],
376                               self.val['_M_impl']['_M_finish'],
377                               self.is_bool)
378
379     def to_string(self):
380         start = self.val['_M_impl']['_M_start']
381         finish = self.val['_M_impl']['_M_finish']
382         end = self.val['_M_impl']['_M_end_of_storage']
383         if self.is_bool:
384             start = self.val['_M_impl']['_M_start']['_M_p']
385             so    = self.val['_M_impl']['_M_start']['_M_offset']
386             finish = self.val['_M_impl']['_M_finish']['_M_p']
387             fo     = self.val['_M_impl']['_M_finish']['_M_offset']
388             itype = start.dereference().type
389             bl = 8 * itype.sizeof
390             length   = (bl - so) + bl * ((finish - start) - 1) + fo
391             capacity = bl * (end - start)
392             return ('%s<bool> of length %d, capacity %d'
393                     % (self.typename, int (length), int (capacity)))
394         else:
395             return ('%s of length %d, capacity %d'
396                     % (self.typename, int (finish - start), int (end - start)))
397
398     def display_hint(self):
399         return 'array'
400
401 class StdVectorIteratorPrinter:
402     "Print std::vector::iterator"
403
404     def __init__(self, typename, val):
405         self.val = val
406
407     def to_string(self):
408         if not self.val['_M_current']:
409             return 'non-dereferenceable iterator for std::vector'
410         return str(self.val['_M_current'].dereference())
411
412 class StdTuplePrinter:
413     "Print a std::tuple"
414
415     class _iterator(Iterator):
416         def __init__ (self, head):
417             self.head = head
418
419             # Set the base class as the initial head of the
420             # tuple.
421             nodes = self.head.type.fields ()
422             if len (nodes) == 1:
423                 # Set the actual head to the first pair.
424                 self.head  = self.head.cast (nodes[0].type)
425             elif len (nodes) != 0:
426                 raise ValueError("Top of tuple tree does not consist of a single node.")
427             self.count = 0
428
429         def __iter__ (self):
430             return self
431
432         def __next__ (self):
433             # Check for further recursions in the inheritance tree.
434             # For a GCC 5+ tuple self.head is None after visiting all nodes:
435             if not self.head:
436                 raise StopIteration
437             nodes = self.head.type.fields ()
438             # For a GCC 4.x tuple there is a final node with no fields:
439             if len (nodes) == 0:
440                 raise StopIteration
441             # Check that this iteration has an expected structure.
442             if len (nodes) > 2:
443                 raise ValueError("Cannot parse more than 2 nodes in a tuple tree.")
444
445             if len (nodes) == 1:
446                 # This is the last node of a GCC 5+ std::tuple.
447                 impl = self.head.cast (nodes[0].type)
448                 self.head = None
449             else:
450                 # Either a node before the last node, or the last node of
451                 # a GCC 4.x tuple (which has an empty parent).
452
453                 # - Left node is the next recursion parent.
454                 # - Right node is the actual class contained in the tuple.
455
456                 # Process right node.
457                 impl = self.head.cast (nodes[1].type)
458
459                 # Process left node and set it as head.
460                 self.head  = self.head.cast (nodes[0].type)
461
462             self.count = self.count + 1
463
464             # Finally, check the implementation.  If it is
465             # wrapped in _M_head_impl return that, otherwise return
466             # the value "as is".
467             fields = impl.type.fields ()
468             if len (fields) < 1 or fields[0].name != "_M_head_impl":
469                 return ('[%d]' % self.count, impl)
470             else:
471                 return ('[%d]' % self.count, impl['_M_head_impl'])
472
473     def __init__ (self, typename, val):
474         self.typename = strip_versioned_namespace(typename)
475         self.val = val;
476
477     def children (self):
478         return self._iterator (self.val)
479
480     def to_string (self):
481         if len (self.val.type.fields ()) == 0:
482             return 'empty %s' % (self.typename)
483         return '%s containing' % (self.typename)
484
485 class StdStackOrQueuePrinter:
486     "Print a std::stack or std::queue"
487
488     def __init__ (self, typename, val):
489         self.typename = strip_versioned_namespace(typename)
490         self.visualizer = gdb.default_visualizer(val['c'])
491
492     def children (self):
493         return self.visualizer.children()
494
495     def to_string (self):
496         return '%s wrapping: %s' % (self.typename,
497                                     self.visualizer.to_string())
498
499     def display_hint (self):
500         if hasattr (self.visualizer, 'display_hint'):
501             return self.visualizer.display_hint ()
502         return None
503
504 class RbtreeIterator(Iterator):
505     """
506     Turn an RB-tree-based container (std::map, std::set etc.) into
507     a Python iterable object.
508     """
509
510     def __init__(self, rbtree):
511         self.size = rbtree['_M_t']['_M_impl']['_M_node_count']
512         self.node = rbtree['_M_t']['_M_impl']['_M_header']['_M_left']
513         self.count = 0
514
515     def __iter__(self):
516         return self
517
518     def __len__(self):
519         return int (self.size)
520
521     def __next__(self):
522         if self.count == self.size:
523             raise StopIteration
524         result = self.node
525         self.count = self.count + 1
526         if self.count < self.size:
527             # Compute the next node.
528             node = self.node
529             if node.dereference()['_M_right']:
530                 node = node.dereference()['_M_right']
531                 while node.dereference()['_M_left']:
532                     node = node.dereference()['_M_left']
533             else:
534                 parent = node.dereference()['_M_parent']
535                 while node == parent.dereference()['_M_right']:
536                     node = parent
537                     parent = parent.dereference()['_M_parent']
538                 if node.dereference()['_M_right'] != parent:
539                     node = parent
540             self.node = node
541         return result
542
543 def get_value_from_Rb_tree_node(node):
544     """Returns the value held in an _Rb_tree_node<_Val>"""
545     try:
546         member = node.type.fields()[1].name
547         if member == '_M_value_field':
548             # C++03 implementation, node contains the value as a member
549             return node['_M_value_field']
550         elif member == '_M_storage':
551             # C++11 implementation, node stores value in __aligned_membuf
552             valtype = node.type.template_argument(0)
553             return get_value_from_aligned_membuf(node['_M_storage'], valtype)
554     except:
555         pass
556     raise ValueError("Unsupported implementation for %s" % str(node.type))
557
558 # This is a pretty printer for std::_Rb_tree_iterator (which is
559 # std::map::iterator), and has nothing to do with the RbtreeIterator
560 # class above.
561 class StdRbtreeIteratorPrinter:
562     "Print std::map::iterator, std::set::iterator, etc."
563
564     def __init__ (self, typename, val):
565         self.val = val
566         valtype = self.val.type.template_argument(0).strip_typedefs()
567         nodetype = '_Rb_tree_node<' + str(valtype) + '>'
568         if _versioned_namespace and typename.startswith('std::' + _versioned_namespace):
569             nodetype = _versioned_namespace + nodetype
570         nodetype = gdb.lookup_type('std::' + nodetype)
571         self.link_type = nodetype.strip_typedefs().pointer()
572
573     def to_string (self):
574         if not self.val['_M_node']:
575             return 'non-dereferenceable iterator for associative container'
576         node = self.val['_M_node'].cast(self.link_type).dereference()
577         return str(get_value_from_Rb_tree_node(node))
578
579 class StdDebugIteratorPrinter:
580     "Print a debug enabled version of an iterator"
581
582     def __init__ (self, typename, val):
583         self.val = val
584
585     # Just strip away the encapsulating __gnu_debug::_Safe_iterator
586     # and return the wrapped iterator value.
587     def to_string (self):
588         base_type = gdb.lookup_type('__gnu_debug::_Safe_iterator_base')
589         itype = self.val.type.template_argument(0)
590         safe_seq = self.val.cast(base_type)['_M_sequence']
591         if not safe_seq:
592             return str(self.val.cast(itype))
593         if self.val['_M_version'] != safe_seq['_M_version']:
594             return "invalid iterator"
595         return str(self.val.cast(itype))
596
597 def num_elements(num):
598     """Return either "1 element" or "N elements" depending on the argument."""
599     return '1 element' if num == 1 else '%d elements' % num
600
601 class StdMapPrinter:
602     "Print a std::map or std::multimap"
603
604     # Turn an RbtreeIterator into a pretty-print iterator.
605     class _iter(Iterator):
606         def __init__(self, rbiter, type):
607             self.rbiter = rbiter
608             self.count = 0
609             self.type = type
610
611         def __iter__(self):
612             return self
613
614         def __next__(self):
615             if self.count % 2 == 0:
616                 n = next(self.rbiter)
617                 n = n.cast(self.type).dereference()
618                 n = get_value_from_Rb_tree_node(n)
619                 self.pair = n
620                 item = n['first']
621             else:
622                 item = self.pair['second']
623             result = ('[%d]' % self.count, item)
624             self.count = self.count + 1
625             return result
626
627     def __init__ (self, typename, val):
628         self.typename = strip_versioned_namespace(typename)
629         self.val = val
630
631     def to_string (self):
632         return '%s with %s' % (self.typename,
633                                num_elements(len(RbtreeIterator (self.val))))
634
635     def children (self):
636         rep_type = find_type(self.val.type, '_Rep_type')
637         node = find_type(rep_type, '_Link_type')
638         node = node.strip_typedefs()
639         return self._iter (RbtreeIterator (self.val), node)
640
641     def display_hint (self):
642         return 'map'
643
644 class StdSetPrinter:
645     "Print a std::set or std::multiset"
646
647     # Turn an RbtreeIterator into a pretty-print iterator.
648     class _iter(Iterator):
649         def __init__(self, rbiter, type):
650             self.rbiter = rbiter
651             self.count = 0
652             self.type = type
653
654         def __iter__(self):
655             return self
656
657         def __next__(self):
658             item = next(self.rbiter)
659             item = item.cast(self.type).dereference()
660             item = get_value_from_Rb_tree_node(item)
661             # FIXME: this is weird ... what to do?
662             # Maybe a 'set' display hint?
663             result = ('[%d]' % self.count, item)
664             self.count = self.count + 1
665             return result
666
667     def __init__ (self, typename, val):
668         self.typename = strip_versioned_namespace(typename)
669         self.val = val
670
671     def to_string (self):
672         return '%s with %s' % (self.typename,
673                                num_elements(len(RbtreeIterator (self.val))))
674
675     def children (self):
676         rep_type = find_type(self.val.type, '_Rep_type')
677         node = find_type(rep_type, '_Link_type')
678         node = node.strip_typedefs()
679         return self._iter (RbtreeIterator (self.val), node)
680
681 class StdBitsetPrinter:
682     "Print a std::bitset"
683
684     def __init__(self, typename, val):
685         self.typename = strip_versioned_namespace(typename)
686         self.val = val
687
688     def to_string (self):
689         # If template_argument handled values, we could print the
690         # size.  Or we could use a regexp on the type.
691         return '%s' % (self.typename)
692
693     def children (self):
694         try:
695             # An empty bitset may not have any members which will
696             # result in an exception being thrown.
697             words = self.val['_M_w']
698         except:
699             return []
700
701         wtype = words.type
702
703         # The _M_w member can be either an unsigned long, or an
704         # array.  This depends on the template specialization used.
705         # If it is a single long, convert to a single element list.
706         if wtype.code == gdb.TYPE_CODE_ARRAY:
707             tsize = wtype.target ().sizeof
708         else:
709             words = [words]
710             tsize = wtype.sizeof
711
712         nwords = wtype.sizeof / tsize
713         result = []
714         byte = 0
715         while byte < nwords:
716             w = words[byte]
717             bit = 0
718             while w != 0:
719                 if (w & 1) != 0:
720                     # Another spot where we could use 'set'?
721                     result.append(('[%d]' % (byte * tsize * 8 + bit), 1))
722                 bit = bit + 1
723                 w = w >> 1
724             byte = byte + 1
725         return result
726
727 class StdDequePrinter:
728     "Print a std::deque"
729
730     class _iter(Iterator):
731         def __init__(self, node, start, end, last, buffer_size):
732             self.node = node
733             self.p = start
734             self.end = end
735             self.last = last
736             self.buffer_size = buffer_size
737             self.count = 0
738
739         def __iter__(self):
740             return self
741
742         def __next__(self):
743             if self.p == self.last:
744                 raise StopIteration
745
746             result = ('[%d]' % self.count, self.p.dereference())
747             self.count = self.count + 1
748
749             # Advance the 'cur' pointer.
750             self.p = self.p + 1
751             if self.p == self.end:
752                 # If we got to the end of this bucket, move to the
753                 # next bucket.
754                 self.node = self.node + 1
755                 self.p = self.node[0]
756                 self.end = self.p + self.buffer_size
757
758             return result
759
760     def __init__(self, typename, val):
761         self.typename = strip_versioned_namespace(typename)
762         self.val = val
763         self.elttype = val.type.template_argument(0)
764         size = self.elttype.sizeof
765         if size < 512:
766             self.buffer_size = int (512 / size)
767         else:
768             self.buffer_size = 1
769
770     def to_string(self):
771         start = self.val['_M_impl']['_M_start']
772         end = self.val['_M_impl']['_M_finish']
773
774         delta_n = end['_M_node'] - start['_M_node'] - 1
775         delta_s = start['_M_last'] - start['_M_cur']
776         delta_e = end['_M_cur'] - end['_M_first']
777
778         size = self.buffer_size * delta_n + delta_s + delta_e
779
780         return '%s with %s' % (self.typename, num_elements(long(size)))
781
782     def children(self):
783         start = self.val['_M_impl']['_M_start']
784         end = self.val['_M_impl']['_M_finish']
785         return self._iter(start['_M_node'], start['_M_cur'], start['_M_last'],
786                           end['_M_cur'], self.buffer_size)
787
788     def display_hint (self):
789         return 'array'
790
791 class StdDequeIteratorPrinter:
792     "Print std::deque::iterator"
793
794     def __init__(self, typename, val):
795         self.val = val
796
797     def to_string(self):
798         if not self.val['_M_cur']:
799             return 'non-dereferenceable iterator for std::deque'
800         return str(self.val['_M_cur'].dereference())
801
802 class StdStringPrinter:
803     "Print a std::basic_string of some kind"
804
805     def __init__(self, typename, val):
806         self.val = val
807         self.new_string = typename.find("::__cxx11::basic_string") != -1
808
809     def to_string(self):
810         # Make sure &string works, too.
811         type = self.val.type
812         if type.code == gdb.TYPE_CODE_REF:
813             type = type.target ()
814
815         # Calculate the length of the string so that to_string returns
816         # the string according to length, not according to first null
817         # encountered.
818         ptr = self.val ['_M_dataplus']['_M_p']
819         if self.new_string:
820             length = self.val['_M_string_length']
821             # https://sourceware.org/bugzilla/show_bug.cgi?id=17728
822             ptr = ptr.cast(ptr.type.strip_typedefs())
823         else:
824             realtype = type.unqualified ().strip_typedefs ()
825             reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer ()
826             header = ptr.cast(reptype) - 1
827             length = header.dereference ()['_M_length']
828         if hasattr(ptr, "lazy_string"):
829             return ptr.lazy_string (length = length)
830         return ptr.string (length = length)
831
832     def display_hint (self):
833         return 'string'
834
835 class Tr1HashtableIterator(Iterator):
836     def __init__ (self, hash):
837         self.buckets = hash['_M_buckets']
838         self.bucket = 0
839         self.bucket_count = hash['_M_bucket_count']
840         self.node_type = find_type(hash.type, '_Node').pointer()
841         self.node = 0
842         while self.bucket != self.bucket_count:
843             self.node = self.buckets[self.bucket]
844             if self.node:
845                 break
846             self.bucket = self.bucket + 1
847
848     def __iter__ (self):
849         return self
850
851     def __next__ (self):
852         if self.node == 0:
853             raise StopIteration
854         node = self.node.cast(self.node_type)
855         result = node.dereference()['_M_v']
856         self.node = node.dereference()['_M_next'];
857         if self.node == 0:
858             self.bucket = self.bucket + 1
859             while self.bucket != self.bucket_count:
860                 self.node = self.buckets[self.bucket]
861                 if self.node:
862                     break
863                 self.bucket = self.bucket + 1
864         return result
865
866 class StdHashtableIterator(Iterator):
867     def __init__(self, hash):
868         self.node = hash['_M_before_begin']['_M_nxt']
869         self.node_type = find_type(hash.type, '__node_type').pointer()
870
871     def __iter__(self):
872         return self
873
874     def __next__(self):
875         if self.node == 0:
876             raise StopIteration
877         elt = self.node.cast(self.node_type).dereference()
878         self.node = elt['_M_nxt']
879         valptr = elt['_M_storage'].address
880         valptr = valptr.cast(elt.type.template_argument(0).pointer())
881         return valptr.dereference()
882
883 class Tr1UnorderedSetPrinter:
884     "Print a tr1::unordered_set"
885
886     def __init__ (self, typename, val):
887         self.typename = strip_versioned_namespace(typename)
888         self.val = val
889
890     def hashtable (self):
891         if self.typename.startswith('std::tr1'):
892             return self.val
893         return self.val['_M_h']
894
895     def to_string (self):
896         count = self.hashtable()['_M_element_count']
897         return '%s with %s' % (self.typename, num_elements(count))
898
899     @staticmethod
900     def format_count (i):
901         return '[%d]' % i
902
903     def children (self):
904         counter = imap (self.format_count, itertools.count())
905         if self.typename.startswith('std::tr1'):
906             return izip (counter, Tr1HashtableIterator (self.hashtable()))
907         return izip (counter, StdHashtableIterator (self.hashtable()))
908
909 class Tr1UnorderedMapPrinter:
910     "Print a tr1::unordered_map"
911
912     def __init__ (self, typename, val):
913         self.typename = strip_versioned_namespace(typename)
914         self.val = val
915
916     def hashtable (self):
917         if self.typename.startswith('std::tr1'):
918             return self.val
919         return self.val['_M_h']
920
921     def to_string (self):
922         count = self.hashtable()['_M_element_count']
923         return '%s with %s' % (self.typename, num_elements(count))
924
925     @staticmethod
926     def flatten (list):
927         for elt in list:
928             for i in elt:
929                 yield i
930
931     @staticmethod
932     def format_one (elt):
933         return (elt['first'], elt['second'])
934
935     @staticmethod
936     def format_count (i):
937         return '[%d]' % i
938
939     def children (self):
940         counter = imap (self.format_count, itertools.count())
941         # Map over the hash table and flatten the result.
942         if self.typename.startswith('std::tr1'):
943             data = self.flatten (imap (self.format_one, Tr1HashtableIterator (self.hashtable())))
944             # Zip the two iterators together.
945             return izip (counter, data)
946         data = self.flatten (imap (self.format_one, StdHashtableIterator (self.hashtable())))
947         # Zip the two iterators together.
948         return izip (counter, data)
949
950     def display_hint (self):
951         return 'map'
952
953 class StdForwardListPrinter:
954     "Print a std::forward_list"
955
956     class _iterator(Iterator):
957         def __init__(self, nodetype, head):
958             self.nodetype = nodetype
959             self.base = head['_M_next']
960             self.count = 0
961
962         def __iter__(self):
963             return self
964
965         def __next__(self):
966             if self.base == 0:
967                 raise StopIteration
968             elt = self.base.cast(self.nodetype).dereference()
969             self.base = elt['_M_next']
970             count = self.count
971             self.count = self.count + 1
972             valptr = elt['_M_storage'].address
973             valptr = valptr.cast(elt.type.template_argument(0).pointer())
974             return ('[%d]' % count, valptr.dereference())
975
976     def __init__(self, typename, val):
977         self.val = val
978         self.typename = strip_versioned_namespace(typename)
979
980     def children(self):
981         nodetype = find_type(self.val.type, '_Node')
982         nodetype = nodetype.strip_typedefs().pointer()
983         return self._iterator(nodetype, self.val['_M_impl']['_M_head'])
984
985     def to_string(self):
986         if self.val['_M_impl']['_M_head']['_M_next'] == 0:
987             return 'empty %s' % self.typename
988         return '%s' % self.typename
989
990 class SingleObjContainerPrinter(object):
991     "Base class for printers of containers of single objects"
992
993     def __init__ (self, val, viz, hint = None):
994         self.contained_value = val
995         self.visualizer = viz
996         self.hint = hint
997
998     def _recognize(self, type):
999         """Return TYPE as a string after applying type printers"""
1000         global _use_type_printing
1001         if not _use_type_printing:
1002             return str(type)
1003         return gdb.types.apply_type_recognizers(gdb.types.get_type_recognizers(),
1004                                                 type) or str(type)
1005
1006     class _contained(Iterator):
1007         def __init__ (self, val):
1008             self.val = val
1009
1010         def __iter__ (self):
1011             return self
1012
1013         def __next__(self):
1014             if self.val is None:
1015                 raise StopIteration
1016             retval = self.val
1017             self.val = None
1018             return ('[contained value]', retval)
1019
1020     def children (self):
1021         if self.contained_value is None:
1022             return self._contained (None)
1023         if hasattr (self.visualizer, 'children'):
1024             return self.visualizer.children ()
1025         return self._contained (self.contained_value)
1026
1027     def display_hint (self):
1028         # if contained value is a map we want to display in the same way
1029         if hasattr (self.visualizer, 'children') and hasattr (self.visualizer, 'display_hint'):
1030             return self.visualizer.display_hint ()
1031         return self.hint
1032
1033 class StdExpAnyPrinter(SingleObjContainerPrinter):
1034     "Print a std::any or std::experimental::any"
1035
1036     def __init__ (self, typename, val):
1037         self.typename = strip_versioned_namespace(typename)
1038         self.typename = re.sub('^std::experimental::fundamentals_v\d::', 'std::experimental::', self.typename, 1)
1039         self.val = val
1040         self.contained_type = None
1041         contained_value = None
1042         visualizer = None
1043         mgr = self.val['_M_manager']
1044         if mgr != 0:
1045             func = gdb.block_for_pc(int(mgr.cast(gdb.lookup_type('intptr_t'))))
1046             if not func:
1047                 raise ValueError("Invalid function pointer in %s" % self.typename)
1048             rx = r"""({0}::_Manager_\w+<.*>)::_S_manage""".format(typename)
1049             m = re.match(rx, func.function.name)
1050             if not m:
1051                 raise ValueError("Unknown manager function in %s" % self.typename)
1052
1053             mgrname = m.group(1)
1054             # FIXME need to expand 'std::string' so that gdb.lookup_type works
1055             if 'std::string' in mgrname:
1056                 mgrname = re.sub("std::string(?!\w)", str(gdb.lookup_type('std::string').strip_typedefs()), m.group(1))
1057
1058             mgrtype = gdb.lookup_type(mgrname)
1059             self.contained_type = mgrtype.template_argument(0)
1060             valptr = None
1061             if '::_Manager_internal' in mgrname:
1062                 valptr = self.val['_M_storage']['_M_buffer'].address
1063             elif '::_Manager_external' in mgrname:
1064                 valptr = self.val['_M_storage']['_M_ptr']
1065             else:
1066                 raise ValueError("Unknown manager function in %s" % self.typename)
1067             contained_value = valptr.cast(self.contained_type.pointer()).dereference()
1068             visualizer = gdb.default_visualizer(contained_value)
1069         super(StdExpAnyPrinter, self).__init__ (contained_value, visualizer)
1070
1071     def to_string (self):
1072         if self.contained_type is None:
1073             return '%s [no contained value]' % self.typename
1074         desc = "%s containing " % self.typename
1075         if hasattr (self.visualizer, 'children'):
1076             return desc + self.visualizer.to_string ()
1077         valtype = self._recognize (self.contained_type)
1078         return desc + strip_versioned_namespace(str(valtype))
1079
1080 class StdExpOptionalPrinter(SingleObjContainerPrinter):
1081     "Print a std::optional or std::experimental::optional"
1082
1083     def __init__ (self, typename, val):
1084         valtype = self._recognize (val.type.template_argument(0))
1085         self.typename = strip_versioned_namespace(typename)
1086         self.typename = re.sub('^std::(experimental::|)(fundamentals_v\d::|)(.*)', r'std::\1\3<%s>' % valtype, self.typename, 1)
1087         if not self.typename.startswith('std::experimental'):
1088             val = val['_M_payload']
1089         self.val = val
1090         contained_value = val['_M_payload'] if self.val['_M_engaged'] else None
1091         visualizer = gdb.default_visualizer (val['_M_payload'])
1092         super (StdExpOptionalPrinter, self).__init__ (contained_value, visualizer)
1093
1094     def to_string (self):
1095         if self.contained_value is None:
1096             return "%s [no contained value]" % self.typename
1097         if hasattr (self.visualizer, 'children'):
1098             return "%s containing %s" % (self.typename,
1099                                          self.visualizer.to_string())
1100         return self.typename
1101
1102 class StdVariantPrinter(SingleObjContainerPrinter):
1103     "Print a std::variant"
1104
1105     def __init__(self, typename, val):
1106         alternatives = get_template_arg_list(val.type)
1107         self.typename = strip_versioned_namespace(typename)
1108         self.typename = "%s<%s>" % (self.typename, ', '.join([self._recognize(alt) for alt in alternatives]))
1109         self.index = val['_M_index']
1110         if self.index >= len(alternatives):
1111             self.contained_type = None
1112             contained_value = None
1113             visualizer = None
1114         else:
1115             self.contained_type = alternatives[int(self.index)]
1116             addr = val['_M_u']['_M_first']['_M_storage'].address
1117             contained_value = addr.cast(self.contained_type.pointer()).dereference()
1118             visualizer = gdb.default_visualizer(contained_value)
1119         super (StdVariantPrinter, self).__init__(contained_value, visualizer, 'array')
1120
1121     def to_string(self):
1122         if self.contained_value is None:
1123             return "%s [no contained value]" % self.typename
1124         if hasattr(self.visualizer, 'children'):
1125             return "%s [index %d] containing %s" % (self.typename, self.index,
1126                                                     self.visualizer.to_string())
1127         return "%s [index %d]" % (self.typename, self.index)
1128
1129 class StdNodeHandlePrinter(SingleObjContainerPrinter):
1130     "Print a container node handle"
1131
1132     def __init__(self, typename, val):
1133         self.value_type = val.type.template_argument(1)
1134         nodetype = val.type.template_argument(2).template_argument(0)
1135         self.is_rb_tree_node = is_specialization_of(nodetype.name, '_Rb_tree_node')
1136         self.is_map_node = val.type.template_argument(0) != self.value_type
1137         nodeptr = val['_M_ptr']
1138         if nodeptr:
1139             if self.is_rb_tree_node:
1140                 contained_value = get_value_from_Rb_tree_node(nodeptr.dereference())
1141             else:
1142                 contained_value = get_value_from_aligned_membuf(nodeptr['_M_storage'],
1143                                                                 self.value_type)
1144             visualizer = gdb.default_visualizer(contained_value)
1145         else:
1146             contained_value = None
1147             visualizer = None
1148         optalloc = val['_M_alloc']
1149         self.alloc = optalloc['_M_payload'] if optalloc['_M_engaged'] else None
1150         super(StdNodeHandlePrinter, self).__init__(contained_value, visualizer,
1151                                                    'array')
1152
1153     def to_string(self):
1154         desc = 'node handle for '
1155         if not self.is_rb_tree_node:
1156             desc += 'unordered '
1157         if self.is_map_node:
1158             desc += 'map';
1159         else:
1160             desc += 'set';
1161
1162         if self.contained_value:
1163             desc += ' with element'
1164             if hasattr(self.visualizer, 'children'):
1165                 return "%s = %s" % (desc, self.visualizer.to_string())
1166             return desc
1167         else:
1168             return 'empty %s' % desc
1169
1170 class StdExpStringViewPrinter:
1171     "Print a std::basic_string_view or std::experimental::basic_string_view"
1172
1173     def __init__ (self, typename, val):
1174         self.val = val
1175
1176     def to_string (self):
1177         ptr = self.val['_M_str']
1178         len = self.val['_M_len']
1179         if hasattr (ptr, "lazy_string"):
1180             return ptr.lazy_string (length = len)
1181         return ptr.string (length = len)
1182
1183     def display_hint (self):
1184         return 'string'
1185
1186 class StdExpPathPrinter:
1187     "Print a std::experimental::filesystem::path"
1188
1189     def __init__ (self, typename, val):
1190         self.val = val
1191         start = self.val['_M_cmpts']['_M_impl']['_M_start']
1192         finish = self.val['_M_cmpts']['_M_impl']['_M_finish']
1193         self.num_cmpts = int (finish - start)
1194
1195     def _path_type(self):
1196         t = str(self.val['_M_type'])
1197         if t[-9:] == '_Root_dir':
1198             return "root-directory"
1199         if t[-10:] == '_Root_name':
1200             return "root-name"
1201         return None
1202
1203     def to_string (self):
1204         path = "%s" % self.val ['_M_pathname']
1205         if self.num_cmpts == 0:
1206             t = self._path_type()
1207             if t:
1208                 path = '%s [%s]' % (path, t)
1209         return "filesystem::path %s" % path
1210
1211     class _iterator(Iterator):
1212         def __init__(self, cmpts):
1213             self.item = cmpts['_M_impl']['_M_start']
1214             self.finish = cmpts['_M_impl']['_M_finish']
1215             self.count = 0
1216
1217         def __iter__(self):
1218             return self
1219
1220         def __next__(self):
1221             if self.item == self.finish:
1222                 raise StopIteration
1223             item = self.item.dereference()
1224             count = self.count
1225             self.count = self.count + 1
1226             self.item = self.item + 1
1227             path = item['_M_pathname']
1228             t = StdExpPathPrinter(item.type.name, item)._path_type()
1229             if not t:
1230                 t = count
1231             return ('[%s]' % t, path)
1232
1233     def children(self):
1234         return self._iterator(self.val['_M_cmpts'])
1235
1236
1237 class StdPairPrinter:
1238     "Print a std::pair object, with 'first' and 'second' as children"
1239
1240     def __init__(self, typename, val):
1241         self.val = val
1242
1243     class _iter(Iterator):
1244         "An iterator for std::pair types. Returns 'first' then 'second'."
1245
1246         def __init__(self, val):
1247             self.val = val
1248             self.which = 'first'
1249
1250         def __iter__(self):
1251             return self
1252
1253         def __next__(self):
1254             if self.which is None:
1255                 raise StopIteration
1256             which = self.which
1257             if which == 'first':
1258                 self.which = 'second'
1259             else:
1260                 self.which = None
1261             return (which, self.val[which])
1262
1263     def children(self):
1264         return self._iter(self.val)
1265
1266     def to_string(self):
1267         return None
1268
1269
1270 # A "regular expression" printer which conforms to the
1271 # "SubPrettyPrinter" protocol from gdb.printing.
1272 class RxPrinter(object):
1273     def __init__(self, name, function):
1274         super(RxPrinter, self).__init__()
1275         self.name = name
1276         self.function = function
1277         self.enabled = True
1278
1279     def invoke(self, value):
1280         if not self.enabled:
1281             return None
1282
1283         if value.type.code == gdb.TYPE_CODE_REF:
1284             if hasattr(gdb.Value,"referenced_value"):
1285                 value = value.referenced_value()
1286
1287         return self.function(self.name, value)
1288
1289 # A pretty-printer that conforms to the "PrettyPrinter" protocol from
1290 # gdb.printing.  It can also be used directly as an old-style printer.
1291 class Printer(object):
1292     def __init__(self, name):
1293         super(Printer, self).__init__()
1294         self.name = name
1295         self.subprinters = []
1296         self.lookup = {}
1297         self.enabled = True
1298         self.compiled_rx = re.compile('^([a-zA-Z0-9_:]+)(<.*>)?$')
1299
1300     def add(self, name, function):
1301         # A small sanity check.
1302         # FIXME
1303         if not self.compiled_rx.match(name):
1304             raise ValueError('libstdc++ programming error: "%s" does not match' % name)
1305         printer = RxPrinter(name, function)
1306         self.subprinters.append(printer)
1307         self.lookup[name] = printer
1308
1309     # Add a name using _GLIBCXX_BEGIN_NAMESPACE_VERSION.
1310     def add_version(self, base, name, function):
1311         self.add(base + name, function)
1312         if _versioned_namespace:
1313             vbase = re.sub('^(std|__gnu_cxx)::', r'\g<0>%s' % _versioned_namespace, base)
1314             self.add(vbase + name, function)
1315
1316     # Add a name using _GLIBCXX_BEGIN_NAMESPACE_CONTAINER.
1317     def add_container(self, base, name, function):
1318         self.add_version(base, name, function)
1319         self.add_version(base + '__cxx1998::', name, function)
1320
1321     @staticmethod
1322     def get_basic_type(type):
1323         # If it points to a reference, get the reference.
1324         if type.code == gdb.TYPE_CODE_REF:
1325             type = type.target ()
1326
1327         # Get the unqualified type, stripped of typedefs.
1328         type = type.unqualified ().strip_typedefs ()
1329
1330         return type.tag
1331
1332     def __call__(self, val):
1333         typename = self.get_basic_type(val.type)
1334         if not typename:
1335             return None
1336
1337         # All the types we match are template types, so we can use a
1338         # dictionary.
1339         match = self.compiled_rx.match(typename)
1340         if not match:
1341             return None
1342
1343         basename = match.group(1)
1344
1345         if val.type.code == gdb.TYPE_CODE_REF:
1346             if hasattr(gdb.Value,"referenced_value"):
1347                 val = val.referenced_value()
1348
1349         if basename in self.lookup:
1350             return self.lookup[basename].invoke(val)
1351
1352         # Cannot find a pretty printer.  Return None.
1353         return None
1354
1355 libstdcxx_printer = None
1356
1357 class TemplateTypePrinter(object):
1358     r"""
1359     A type printer for class templates with default template arguments.
1360
1361     Recognizes specializations of class templates and prints them without
1362     any template arguments that use a default template argument.
1363     Type printers are recursively applied to the template arguments.
1364
1365     e.g. replace "std::vector<T, std::allocator<T> >" with "std::vector<T>".
1366     """
1367
1368     def __init__(self, name, defargs):
1369         self.name = name
1370         self.defargs = defargs
1371         self.enabled = True
1372
1373     class _recognizer(object):
1374         "The recognizer class for TemplateTypePrinter."
1375
1376         def __init__(self, name, defargs):
1377             self.name = name
1378             self.defargs = defargs
1379             # self.type_obj = None
1380
1381         def recognize(self, type_obj):
1382             """
1383             If type_obj is a specialization of self.name that uses all the
1384             default template arguments for the class template, then return
1385             a string representation of the type without default arguments.
1386             Otherwise, return None.
1387             """
1388
1389             if type_obj.tag is None:
1390                 return None
1391
1392             if not type_obj.tag.startswith(self.name):
1393                 return None
1394
1395             template_args = get_template_arg_list(type_obj)
1396             displayed_args = []
1397             require_defaulted = False
1398             for n in range(len(template_args)):
1399                 # The actual template argument in the type:
1400                 targ = template_args[n]
1401                 # The default template argument for the class template:
1402                 defarg = self.defargs.get(n)
1403                 if defarg is not None:
1404                     # Substitute other template arguments into the default:
1405                     defarg = defarg.format(*template_args)
1406                     # Fail to recognize the type (by returning None)
1407                     # unless the actual argument is the same as the default.
1408                     try:
1409                         if targ != gdb.lookup_type(defarg):
1410                             return None
1411                     except gdb.error:
1412                         # Type lookup failed, just use string comparison:
1413                         if targ.tag != defarg:
1414                             return None
1415                     # All subsequent args must have defaults:
1416                     require_defaulted = True
1417                 elif require_defaulted:
1418                     return None
1419                 else:
1420                     # Recursively apply recognizers to the template argument
1421                     # and add it to the arguments that will be displayed:
1422                     displayed_args.append(self._recognize_subtype(targ))
1423
1424             # This assumes no class templates in the nested-name-specifier:
1425             template_name = type_obj.tag[0:type_obj.tag.find('<')]
1426             template_name = strip_inline_namespaces(template_name)
1427
1428             return template_name + '<' + ', '.join(displayed_args) + '>'
1429
1430         def _recognize_subtype(self, type_obj):
1431             """Convert a gdb.Type to a string by applying recognizers,
1432             or if that fails then simply converting to a string."""
1433
1434             if type_obj.code == gdb.TYPE_CODE_PTR:
1435                 return self._recognize_subtype(type_obj.target()) + '*'
1436             if type_obj.code == gdb.TYPE_CODE_ARRAY:
1437                 type_str = self._recognize_subtype(type_obj.target())
1438                 if str(type_obj.strip_typedefs()).endswith('[]'):
1439                     return type_str + '[]' # array of unknown bound
1440                 return "%s[%d]" % (type_str, type_obj.range()[1] + 1)
1441             if type_obj.code == gdb.TYPE_CODE_REF:
1442                 return self._recognize_subtype(type_obj.target()) + '&'
1443             if hasattr(gdb, 'TYPE_CODE_RVALUE_REF'):
1444                 if type_obj.code == gdb.TYPE_CODE_RVALUE_REF:
1445                     return self._recognize_subtype(type_obj.target()) + '&&'
1446
1447             type_str = gdb.types.apply_type_recognizers(
1448                     gdb.types.get_type_recognizers(), type_obj)
1449             if type_str:
1450                 return type_str
1451             return str(type_obj)
1452
1453     def instantiate(self):
1454         "Return a recognizer object for this type printer."
1455         return self._recognizer(self.name, self.defargs)
1456
1457 def add_one_template_type_printer(obj, name, defargs):
1458     r"""
1459     Add a type printer for a class template with default template arguments.
1460
1461     Args:
1462         name (str): The template-name of the class template.
1463         defargs (dict int:string) The default template arguments.
1464
1465     Types in defargs can refer to the Nth template-argument using {N}
1466     (with zero-based indices).
1467
1468     e.g. 'unordered_map' has these defargs:
1469     { 2: 'std::hash<{0}>',
1470       3: 'std::equal_to<{0}>',
1471       4: 'std::allocator<std::pair<const {0}, {1}> >' }
1472
1473     """
1474     printer = TemplateTypePrinter('std::'+name, defargs)
1475     gdb.types.register_type_printer(obj, printer)
1476     if _versioned_namespace:
1477         # Add second type printer for same type in versioned namespace:
1478         ns = 'std::' + _versioned_namespace
1479         # PR 86112 Cannot use dict comprehension here:
1480         defargs = dict((n, d.replace('std::', ns)) for (n,d) in defargs.items())
1481         printer = TemplateTypePrinter(ns+name, defargs)
1482         gdb.types.register_type_printer(obj, printer)
1483
1484 class FilteringTypePrinter(object):
1485     r"""
1486     A type printer that uses typedef names for common template specializations.
1487
1488     Args:
1489         match (str): The class template to recognize.
1490         name (str): The typedef-name that will be used instead.
1491
1492     Checks if a specialization of the class template 'match' is the same type
1493     as the typedef 'name', and prints it as 'name' instead.
1494
1495     e.g. if an instantiation of std::basic_istream<C, T> is the same type as
1496     std::istream then print it as std::istream.
1497     """
1498
1499     def __init__(self, match, name):
1500         self.match = match
1501         self.name = name
1502         self.enabled = True
1503
1504     class _recognizer(object):
1505         "The recognizer class for TemplateTypePrinter."
1506
1507         def __init__(self, match, name):
1508             self.match = match
1509             self.name = name
1510             self.type_obj = None
1511
1512         def recognize(self, type_obj):
1513             """
1514             If type_obj starts with self.match and is the same type as
1515             self.name then return self.name, otherwise None.
1516             """
1517             if type_obj.tag is None:
1518                 return None
1519
1520             if self.type_obj is None:
1521                 if not type_obj.tag.startswith(self.match):
1522                     # Filter didn't match.
1523                     return None
1524                 try:
1525                     self.type_obj = gdb.lookup_type(self.name).strip_typedefs()
1526                 except:
1527                     pass
1528             if self.type_obj == type_obj:
1529                 return strip_inline_namespaces(self.name)
1530             return None
1531
1532     def instantiate(self):
1533         "Return a recognizer object for this type printer."
1534         return self._recognizer(self.match, self.name)
1535
1536 def add_one_type_printer(obj, match, name):
1537     printer = FilteringTypePrinter('std::' + match, 'std::' + name)
1538     gdb.types.register_type_printer(obj, printer)
1539     if _versioned_namespace:
1540         ns = 'std::' + _versioned_namespace
1541         printer = FilteringTypePrinter(ns + match, ns + name)
1542         gdb.types.register_type_printer(obj, printer)
1543
1544 def register_type_printers(obj):
1545     global _use_type_printing
1546
1547     if not _use_type_printing:
1548         return
1549
1550     # Add type printers for typedefs std::string, std::wstring etc.
1551     for ch in ('', 'w', 'u16', 'u32'):
1552         add_one_type_printer(obj, 'basic_string', ch + 'string')
1553         add_one_type_printer(obj, '__cxx11::basic_string',
1554                              '__cxx11::' + ch + 'string')
1555         add_one_type_printer(obj, 'basic_string_view', ch + 'string_view')
1556
1557     # Add type printers for typedefs std::istream, std::wistream etc.
1558     for ch in ('', 'w'):
1559         for x in ('ios', 'streambuf', 'istream', 'ostream', 'iostream',
1560                   'filebuf', 'ifstream', 'ofstream', 'fstream'):
1561             add_one_type_printer(obj, 'basic_' + x, ch + x)
1562         for x in ('stringbuf', 'istringstream', 'ostringstream',
1563                   'stringstream'):
1564             add_one_type_printer(obj, 'basic_' + x, ch + x)
1565             # <sstream> types are in __cxx11 namespace, but typedefs aren'x:
1566             add_one_type_printer(obj, '__cxx11::basic_' + x, ch + x)
1567
1568     # Add type printers for typedefs regex, wregex, cmatch, wcmatch etc.
1569     for abi in ('', '__cxx11::'):
1570         for ch in ('', 'w'):
1571             add_one_type_printer(obj, abi + 'basic_regex', abi + ch + 'regex')
1572         for ch in ('c', 's', 'wc', 'ws'):
1573             add_one_type_printer(obj, abi + 'match_results', abi + ch + 'match')
1574             for x in ('sub_match', 'regex_iterator', 'regex_token_iterator'):
1575                 add_one_type_printer(obj, abi + x, abi + ch + x)
1576
1577     # Note that we can't have a printer for std::wstreampos, because
1578     # it is the same type as std::streampos.
1579     add_one_type_printer(obj, 'fpos', 'streampos')
1580
1581     # Add type printers for <chrono> typedefs.
1582     for dur in ('nanoseconds', 'microseconds', 'milliseconds',
1583                 'seconds', 'minutes', 'hours'):
1584         add_one_type_printer(obj, 'duration', dur)
1585
1586     # Add type printers for <random> typedefs.
1587     add_one_type_printer(obj, 'linear_congruential_engine', 'minstd_rand0')
1588     add_one_type_printer(obj, 'linear_congruential_engine', 'minstd_rand')
1589     add_one_type_printer(obj, 'mersenne_twister_engine', 'mt19937')
1590     add_one_type_printer(obj, 'mersenne_twister_engine', 'mt19937_64')
1591     add_one_type_printer(obj, 'subtract_with_carry_engine', 'ranlux24_base')
1592     add_one_type_printer(obj, 'subtract_with_carry_engine', 'ranlux48_base')
1593     add_one_type_printer(obj, 'discard_block_engine', 'ranlux24')
1594     add_one_type_printer(obj, 'discard_block_engine', 'ranlux48')
1595     add_one_type_printer(obj, 'shuffle_order_engine', 'knuth_b')
1596
1597     # Add type printers for experimental::basic_string_view typedefs.
1598     ns = 'experimental::fundamentals_v1::'
1599     for ch in ('', 'w', 'u16', 'u32'):
1600         add_one_type_printer(obj, ns + 'basic_string_view',
1601                              ns + ch + 'string_view')
1602
1603     # Do not show defaulted template arguments in class templates.
1604     add_one_template_type_printer(obj, 'unique_ptr',
1605             { 1: 'std::default_delete<{0}>' })
1606     add_one_template_type_printer(obj, 'deque', { 1: 'std::allocator<{0}>'})
1607     add_one_template_type_printer(obj, 'forward_list', { 1: 'std::allocator<{0}>'})
1608     add_one_template_type_printer(obj, 'list', { 1: 'std::allocator<{0}>'})
1609     add_one_template_type_printer(obj, '__cxx11::list', { 1: 'std::allocator<{0}>'})
1610     add_one_template_type_printer(obj, 'vector', { 1: 'std::allocator<{0}>'})
1611     add_one_template_type_printer(obj, 'map',
1612             { 2: 'std::less<{0}>',
1613               3: 'std::allocator<std::pair<{0} const, {1}>>' })
1614     add_one_template_type_printer(obj, 'multimap',
1615             { 2: 'std::less<{0}>',
1616               3: 'std::allocator<std::pair<{0} const, {1}>>' })
1617     add_one_template_type_printer(obj, 'set',
1618             { 1: 'std::less<{0}>', 2: 'std::allocator<{0}>' })
1619     add_one_template_type_printer(obj, 'multiset',
1620             { 1: 'std::less<{0}>', 2: 'std::allocator<{0}>' })
1621     add_one_template_type_printer(obj, 'unordered_map',
1622             { 2: 'std::hash<{0}>',
1623               3: 'std::equal_to<{0}>',
1624               4: 'std::allocator<std::pair<{0} const, {1}>>'})
1625     add_one_template_type_printer(obj, 'unordered_multimap',
1626             { 2: 'std::hash<{0}>',
1627               3: 'std::equal_to<{0}>',
1628               4: 'std::allocator<std::pair<{0} const, {1}>>'})
1629     add_one_template_type_printer(obj, 'unordered_set',
1630             { 1: 'std::hash<{0}>',
1631               2: 'std::equal_to<{0}>',
1632               3: 'std::allocator<{0}>'})
1633     add_one_template_type_printer(obj, 'unordered_multiset',
1634             { 1: 'std::hash<{0}>',
1635               2: 'std::equal_to<{0}>',
1636               3: 'std::allocator<{0}>'})
1637
1638 def register_libstdcxx_printers (obj):
1639     "Register libstdc++ pretty-printers with objfile Obj."
1640
1641     global _use_gdb_pp
1642     global libstdcxx_printer
1643
1644     if _use_gdb_pp:
1645         gdb.printing.register_pretty_printer(obj, libstdcxx_printer)
1646     else:
1647         if obj is None:
1648             obj = gdb
1649         obj.pretty_printers.append(libstdcxx_printer)
1650
1651     register_type_printers(obj)
1652
1653 def build_libstdcxx_dictionary ():
1654     global libstdcxx_printer
1655
1656     libstdcxx_printer = Printer("libstdc++-v6")
1657
1658     # libstdc++ objects requiring pretty-printing.
1659     # In order from:
1660     # http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01847.html
1661     libstdcxx_printer.add_version('std::', 'basic_string', StdStringPrinter)
1662     libstdcxx_printer.add_version('std::__cxx11::', 'basic_string', StdStringPrinter)
1663     libstdcxx_printer.add_container('std::', 'bitset', StdBitsetPrinter)
1664     libstdcxx_printer.add_container('std::', 'deque', StdDequePrinter)
1665     libstdcxx_printer.add_container('std::', 'list', StdListPrinter)
1666     libstdcxx_printer.add_container('std::__cxx11::', 'list', StdListPrinter)
1667     libstdcxx_printer.add_container('std::', 'map', StdMapPrinter)
1668     libstdcxx_printer.add_container('std::', 'multimap', StdMapPrinter)
1669     libstdcxx_printer.add_container('std::', 'multiset', StdSetPrinter)
1670     libstdcxx_printer.add_version('std::', 'pair', StdPairPrinter)
1671     libstdcxx_printer.add_version('std::', 'priority_queue',
1672                                   StdStackOrQueuePrinter)
1673     libstdcxx_printer.add_version('std::', 'queue', StdStackOrQueuePrinter)
1674     libstdcxx_printer.add_version('std::', 'tuple', StdTuplePrinter)
1675     libstdcxx_printer.add_container('std::', 'set', StdSetPrinter)
1676     libstdcxx_printer.add_version('std::', 'stack', StdStackOrQueuePrinter)
1677     libstdcxx_printer.add_version('std::', 'unique_ptr', UniquePointerPrinter)
1678     libstdcxx_printer.add_container('std::', 'vector', StdVectorPrinter)
1679     # vector<bool>
1680
1681     # Printer registrations for classes compiled with -D_GLIBCXX_DEBUG.
1682     libstdcxx_printer.add('std::__debug::bitset', StdBitsetPrinter)
1683     libstdcxx_printer.add('std::__debug::deque', StdDequePrinter)
1684     libstdcxx_printer.add('std::__debug::list', StdListPrinter)
1685     libstdcxx_printer.add('std::__debug::map', StdMapPrinter)
1686     libstdcxx_printer.add('std::__debug::multimap', StdMapPrinter)
1687     libstdcxx_printer.add('std::__debug::multiset', StdSetPrinter)
1688     libstdcxx_printer.add('std::__debug::priority_queue',
1689                           StdStackOrQueuePrinter)
1690     libstdcxx_printer.add('std::__debug::queue', StdStackOrQueuePrinter)
1691     libstdcxx_printer.add('std::__debug::set', StdSetPrinter)
1692     libstdcxx_printer.add('std::__debug::stack', StdStackOrQueuePrinter)
1693     libstdcxx_printer.add('std::__debug::unique_ptr', UniquePointerPrinter)
1694     libstdcxx_printer.add('std::__debug::vector', StdVectorPrinter)
1695
1696     # These are the TR1 and C++11 printers.
1697     # For array - the default GDB pretty-printer seems reasonable.
1698     libstdcxx_printer.add_version('std::', 'shared_ptr', SharedPointerPrinter)
1699     libstdcxx_printer.add_version('std::', 'weak_ptr', SharedPointerPrinter)
1700     libstdcxx_printer.add_container('std::', 'unordered_map',
1701                                     Tr1UnorderedMapPrinter)
1702     libstdcxx_printer.add_container('std::', 'unordered_set',
1703                                     Tr1UnorderedSetPrinter)
1704     libstdcxx_printer.add_container('std::', 'unordered_multimap',
1705                                     Tr1UnorderedMapPrinter)
1706     libstdcxx_printer.add_container('std::', 'unordered_multiset',
1707                                     Tr1UnorderedSetPrinter)
1708     libstdcxx_printer.add_container('std::', 'forward_list',
1709                                     StdForwardListPrinter)
1710
1711     libstdcxx_printer.add_version('std::tr1::', 'shared_ptr', SharedPointerPrinter)
1712     libstdcxx_printer.add_version('std::tr1::', 'weak_ptr', SharedPointerPrinter)
1713     libstdcxx_printer.add_version('std::tr1::', 'unordered_map',
1714                                   Tr1UnorderedMapPrinter)
1715     libstdcxx_printer.add_version('std::tr1::', 'unordered_set',
1716                                   Tr1UnorderedSetPrinter)
1717     libstdcxx_printer.add_version('std::tr1::', 'unordered_multimap',
1718                                   Tr1UnorderedMapPrinter)
1719     libstdcxx_printer.add_version('std::tr1::', 'unordered_multiset',
1720                                   Tr1UnorderedSetPrinter)
1721
1722     # These are the C++11 printer registrations for -D_GLIBCXX_DEBUG cases.
1723     # The tr1 namespace containers do not have any debug equivalents,
1724     # so do not register printers for them.
1725     libstdcxx_printer.add('std::__debug::unordered_map',
1726                           Tr1UnorderedMapPrinter)
1727     libstdcxx_printer.add('std::__debug::unordered_set',
1728                           Tr1UnorderedSetPrinter)
1729     libstdcxx_printer.add('std::__debug::unordered_multimap',
1730                           Tr1UnorderedMapPrinter)
1731     libstdcxx_printer.add('std::__debug::unordered_multiset',
1732                           Tr1UnorderedSetPrinter)
1733     libstdcxx_printer.add('std::__debug::forward_list',
1734                           StdForwardListPrinter)
1735
1736     # Library Fundamentals TS components
1737     libstdcxx_printer.add_version('std::experimental::fundamentals_v1::',
1738                                   'any', StdExpAnyPrinter)
1739     libstdcxx_printer.add_version('std::experimental::fundamentals_v1::',
1740                                   'optional', StdExpOptionalPrinter)
1741     libstdcxx_printer.add_version('std::experimental::fundamentals_v1::',
1742                                   'basic_string_view', StdExpStringViewPrinter)
1743     # Filesystem TS components
1744     libstdcxx_printer.add_version('std::experimental::filesystem::v1::',
1745                                   'path', StdExpPathPrinter)
1746     libstdcxx_printer.add_version('std::experimental::filesystem::v1::__cxx11::',
1747                                   'path', StdExpPathPrinter)
1748     libstdcxx_printer.add_version('std::filesystem::',
1749                                   'path', StdExpPathPrinter)
1750     libstdcxx_printer.add_version('std::filesystem::__cxx11::',
1751                                   'path', StdExpPathPrinter)
1752
1753     # C++17 components
1754     libstdcxx_printer.add_version('std::',
1755                                   'any', StdExpAnyPrinter)
1756     libstdcxx_printer.add_version('std::',
1757                                   'optional', StdExpOptionalPrinter)
1758     libstdcxx_printer.add_version('std::',
1759                                   'basic_string_view', StdExpStringViewPrinter)
1760     libstdcxx_printer.add_version('std::',
1761                                   'variant', StdVariantPrinter)
1762     libstdcxx_printer.add_version('std::',
1763                                   '_Node_handle', StdNodeHandlePrinter)
1764
1765     # Extensions.
1766     libstdcxx_printer.add_version('__gnu_cxx::', 'slist', StdSlistPrinter)
1767
1768     if True:
1769         # These shouldn't be necessary, if GDB "print *i" worked.
1770         # But it often doesn't, so here they are.
1771         libstdcxx_printer.add_container('std::', '_List_iterator',
1772                                         StdListIteratorPrinter)
1773         libstdcxx_printer.add_container('std::', '_List_const_iterator',
1774                                         StdListIteratorPrinter)
1775         libstdcxx_printer.add_version('std::', '_Rb_tree_iterator',
1776                                       StdRbtreeIteratorPrinter)
1777         libstdcxx_printer.add_version('std::', '_Rb_tree_const_iterator',
1778                                       StdRbtreeIteratorPrinter)
1779         libstdcxx_printer.add_container('std::', '_Deque_iterator',
1780                                         StdDequeIteratorPrinter)
1781         libstdcxx_printer.add_container('std::', '_Deque_const_iterator',
1782                                         StdDequeIteratorPrinter)
1783         libstdcxx_printer.add_version('__gnu_cxx::', '__normal_iterator',
1784                                       StdVectorIteratorPrinter)
1785         libstdcxx_printer.add_version('__gnu_cxx::', '_Slist_iterator',
1786                                       StdSlistIteratorPrinter)
1787         libstdcxx_printer.add_container('std::', '_Fwd_list_iterator',
1788                                         StdFwdListIteratorPrinter)
1789         libstdcxx_printer.add_container('std::', '_Fwd_list_const_iterator',
1790                                         StdFwdListIteratorPrinter)
1791
1792         # Debug (compiled with -D_GLIBCXX_DEBUG) printer
1793         # registrations.
1794         libstdcxx_printer.add('__gnu_debug::_Safe_iterator',
1795                               StdDebugIteratorPrinter)
1796
1797 build_libstdcxx_dictionary ()