Skip to content

Commit 4c3320c

Browse files
authored
Merge improved gdb pretty-printer for newer libstdc++
This fixes some issues due to gdb behavior changes. Related PR: #1114
2 parents 3f9321a + bcb2c37 commit 4c3320c

1 file changed

Lines changed: 54 additions & 16 deletions

File tree

dev_tools/scripts/gdb-ginkgo.py

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
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
5556
def 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

67111
def 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

90128
class GkoArrayPrinter:

0 commit comments

Comments
 (0)