1010#
1111# Based on the pretty-printers for libstdc++.
1212
13- # Copyright (C) 2008-2020 Free Software Foundation, Inc.
13+ # Copyright (C) 2008-2021 Free Software Foundation, Inc.
1414#
1515# This program is free software; you can redistribute it and/or modify
1616# it under the terms of the GNU General Public License as published by
@@ -51,7 +51,8 @@ def next(self):
5151
5252_versioned_namespace = '__8::'
5353
54-
54+ # new version adapted from https://gcc.gnu.org/pipermail/gcc-cvs/2021-November/356230.html
55+ # necessary due to empty class optimization
5556def is_specialization_of (x , template_name ):
5657 "Test if a type is a given template instantiation."
5758 global _versioned_namespace
@@ -63,28 +64,65 @@ def is_specialization_of(x, template_name):
6364 expr = '^std::{}<.*>$' .format (template_name )
6465 return re .match (expr , x ) is not None
6566
67+ def get_template_arg_list (type_obj ):
68+ "Return a type's template arguments as a list"
69+ n = 0
70+ template_args = []
71+ while True :
72+ try :
73+ template_args .append (type_obj .template_argument (n ))
74+ except :
75+ return template_args
76+ n += 1
77+
78+ def _tuple_impl_get (val ):
79+ "Return the tuple element stored in a _Tuple_impl<N, T> base class."
80+ bases = val .type .fields ()
81+ if not bases [- 1 ].is_base_class :
82+ raise ValueError ("Unsupported implementation for std::tuple: %s" % str (val .type ))
83+ # Get the _Head_base<N, T> base class:
84+ head_base = val .cast (bases [- 1 ].type )
85+ fields = head_base .type .fields ()
86+ if len (fields ) == 0 :
87+ raise ValueError ("Unsupported implementation for std::tuple: %s" % str (val .type ))
88+ if fields [0 ].name == '_M_head_impl' :
89+ # The tuple element is the _Head_base::_M_head_impl data member.
90+ return head_base ['_M_head_impl' ]
91+ elif fields [0 ].is_base_class :
92+ # The tuple element is an empty base class of _Head_base.
93+ # Cast to that empty base class.
94+ return head_base .cast (fields [0 ].type )
95+ else :
96+ raise ValueError ("Unsupported implementation for std::tuple: %s" % str (val .type ))
97+
98+ def tuple_get (n , val ):
99+ "Return the result of std::get<n>(val) on a std::tuple"
100+ tuple_size = len (get_template_arg_list (val .type ))
101+ if n > tuple_size :
102+ raise ValueError ("Out of range index for std::get<N> on std::tuple" )
103+ # Get the first _Tuple_impl<0, T...> base class:
104+ node = val .cast (val .type .fields ()[0 ].type )
105+ while n > 0 :
106+ # Descend through the base classes until the Nth one.
107+ node = node .cast (node .type .fields ()[0 ].type )
108+ n -= 1
109+ return _tuple_impl_get (node )
66110
67111def get_unique_ptr_data_ptr (val ):
68- impl_type = val .type .fields ()[0 ].type .tag
112+ "Return the result of val.get() on a std::unique_ptr"
113+ # std::unique_ptr<T, D> contains a std::tuple<D::pointer, D>,
114+ # either as a direct data member _M_t (the old implementation)
115+ # or within a data member of type __uniq_ptr_data.
116+ impl_type = val .type .fields ()[0 ].type .strip_typedefs ()
69117 # Check for new implementations first:
70118 if is_specialization_of (impl_type , '__uniq_ptr_data' ) \
71- or is_specialization_of (impl_type , '__uniq_ptr_impl' ):
119+ or is_specialization_of (impl_type , '__uniq_ptr_impl' ):
72120 tuple_member = val ['_M_t' ]['_M_t' ]
73121 elif is_specialization_of (impl_type , 'tuple' ):
74122 tuple_member = val ['_M_t' ]
75123 else :
76- raise ValueError (
77- "Unsupported unique_ptr impl: {}" .format (impl_type ))
78- tuple_impl_type = tuple_member .type .fields ()[0 ].type # _Tuple_impl
79- tuple_head_type = tuple_impl_type .fields ()[1 ].type # _Head_base
80- head_field = tuple_head_type .fields ()[0 ]
81- if head_field .name == '_M_head_impl' :
82- return tuple_member ['_M_head_impl' ]
83- elif head_field .is_base_class :
84- return tuple_member .cast (head_field .type )
85- else :
86- raise ValueError (
87- "Unsupported tuple impl in unique_ptr: {}" .format (impl_type ))
124+ raise ValueError ("Unsupported implementation for unique_ptr: %s" % str (impl_type ))
125+ return tuple_get (0 , tuple_member )
88126
89127
90128class GkoArrayPrinter :
0 commit comments