public inbox for gcc-cvs@sourceware.org help / color / mirror / Atom feed
From: Jonathan Wakely <redi@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc r12-8286] libstdc++: Add pretty printer for std::atomic Date: Wed, 27 Apr 2022 14:53:06 +0000 (GMT) [thread overview] Message-ID: <20220427145306.22F90385842B@sourceware.org> (raw) https://gcc.gnu.org/g:a849584587c317e47f7581df2181efabb948d08f commit r12-8286-ga849584587c317e47f7581df2181efabb948d08f Author: Jonathan Wakely <jwakely@redhat.com> Date: Wed Apr 27 14:29:34 2022 +0100 libstdc++: Add pretty printer for std::atomic For the atomic specializations for shared_ptr and weak_ptr we can reuse the existing SharedPointerPrinter, with a small tweak. libstdc++-v3/ChangeLog: * python/libstdcxx/v6/printers.py (SharedPointerPrinter): Add support for atomic<shared_ptr<T>> and atomic<weak_ptr<T>>. (StdAtomicPrinter): New printer. (build_libstdcxx_dictionary): Register new printer. * testsuite/libstdc++-prettyprinters/cxx11.cc: Test std::atomic. * testsuite/libstdc++-prettyprinters/cxx20.cc: Test atomic smart pointers. Diff: --- libstdc++-v3/python/libstdcxx/v6/printers.py | 53 ++++++++++++++++++++-- .../testsuite/libstdc++-prettyprinters/cxx11.cc | 10 ++++ .../testsuite/libstdc++-prettyprinters/cxx20.cc | 9 ++++ 3 files changed, 69 insertions(+), 3 deletions(-) diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py index c31134bcdd2..0bd793c0897 100644 --- a/libstdc++-v3/python/libstdcxx/v6/printers.py +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py @@ -218,7 +218,7 @@ class SmartPtrIterator(Iterator): return ('get()', val) class SharedPointerPrinter: - "Print a shared_ptr or weak_ptr" + "Print a shared_ptr, weak_ptr, atomic<shared_ptr>, or atomic<weak_ptr>" def __init__ (self, typename, val): self.typename = strip_versioned_namespace(typename) @@ -228,9 +228,21 @@ class SharedPointerPrinter: def children (self): return SmartPtrIterator(self.pointer) + # Return the _Sp_counted_base<>* that holds the refcounts. + def _get_refcounts (self): + if self.typename == 'std::atomic': + # A tagged pointer is stored as uintptr_t. + ptr_val = self.val['_M_refcount']['_M_val']['_M_i'] + ptr_val = ptr_val - (ptr_val % 2) # clear lock bit + ptr_type = find_type(self.val['_M_refcount'].type, 'pointer') + return ptr_val.cast(ptr_type) + return self.val['_M_refcount']['_M_pi'] + def to_string (self): state = 'empty' - refcounts = self.val['_M_refcount']['_M_pi'] + refcounts = self._get_refcounts() + targ = self.val.type.template_argument(0) + if refcounts != 0: usecount = refcounts['_M_use_count'] weakcount = refcounts['_M_weak_count'] @@ -238,7 +250,7 @@ class SharedPointerPrinter: state = 'expired, weak count %d' % weakcount else: state = 'use count %d, weak count %d' % (usecount, weakcount - 1) - return '%s<%s> (%s)' % (self.typename, str(self.val.type.template_argument(0)), state) + return '%s<%s> (%s)' % (self.typename, str(targ), state) def _tuple_impl_get(val): "Return the tuple element stored in a _Tuple_impl<N, T> base class." @@ -1708,6 +1720,40 @@ class StdInitializerListPrinter: def display_hint(self): return 'array' +class StdAtomicPrinter: + "Print a std:atomic" + + def __init__(self, typename, val): + self.typename = typename + self.val = val + self.shptr_printer = None + self.value_type = self.val.type.template_argument(0) + if self.value_type.tag is not None: + typ = strip_versioned_namespace(self.value_type.tag) + if typ.startswith('std::shared_ptr<') or typ.startswith('std::weak_ptr<'): + impl = val['_M_impl'] + self.shptr_printer = SharedPointerPrinter(typename, impl) + self.children = self._shptr_children + + def _shptr_children(self): + return SmartPtrIterator(self.shptr_printer.pointer) + + def to_string(self): + if self.shptr_printer is not None: + return self.shptr_printer.to_string() + + if self.value_type.code == gdb.TYPE_CODE_INT: + val = self.val['_M_i'] + elif self.value_type.code == gdb.TYPE_CODE_FLT: + val = self.val['_M_fp'] + elif self.value_type.code == gdb.TYPE_CODE_PTR: + val = self.val['_M_b']['_M_p'] + elif self.value_type.code == gdb.TYPE_CODE_BOOL: + val = self.val['_M_base']['_M_i'] + else: + val = self.val['_M_i'] + return '%s<%s> = { %s }' % (self.typename, str(self.value_type), val) + # A "regular expression" printer which conforms to the # "SubPrettyPrinter" protocol from gdb.printing. class RxPrinter(object): @@ -2175,6 +2221,7 @@ def build_libstdcxx_dictionary (): libstdcxx_printer.add_version('std::', 'initializer_list', StdInitializerListPrinter) + libstdcxx_printer.add_version('std::', 'atomic', StdAtomicPrinter) # std::regex components libstdcxx_printer.add_version('std::__detail::', '_State', diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc index 621d13bd062..f97640a0189 100644 --- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc +++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc @@ -26,6 +26,7 @@ #include <iostream> #include <future> #include <initializer_list> +#include <atomic> #include "../util/testsuite_allocator.h" // NullablePointer typedef std::tuple<int, int> ExTuple; @@ -197,6 +198,15 @@ main() std::initializer_list<int> il = {3, 4}; // { dg-final { note-test il {std::initializer_list of length 2 = {3, 4}} } } + std::atomic<int> ai{100}; + // { dg-final { note-test ai {std::atomic<int> = { 100 }} } } + long l{}; + std::atomic<long*> ap{&l}; + // { dg-final { regexp-test ap {std::atomic.long \*. = { 0x.* }} } } + struct Value { int i, j; }; + std::atomic<Value> av{{8, 9}}; + // { dg-final { note-test av {std::atomic<Value> = { {i = 8, j = 9} }} } } + placeholder(""); // Mark SPOT use(efl); use(fl); diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx20.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx20.cc index 76023df93fa..f027d0eae38 100644 --- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx20.cc +++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx20.cc @@ -21,6 +21,7 @@ #include <array> #include <compare> #include <iostream> +#include <memory> #include <span> struct X @@ -65,6 +66,14 @@ main() static_assert(s2.extent == std::size_t(2)); // { dg-final { note-test s2 {std::span of length 2 = {3, 4}} } } + std::atomic<std::shared_ptr<int>> spe; +// { dg-final { note-test spe {std::atomic<std::shared_ptr<int>> (empty) = {get() = 0x0}} } } + std::atomic<std::shared_ptr<int>> sp1 = std::make_shared<int>(1); + std::atomic<std::shared_ptr<int>> sp2 = sp1.load(); + std::atomic<std::weak_ptr<int>> wp{sp2.load()}; +// { dg-final { regexp-test sp1 {std::atomic.std::shared_ptr.int.. \(use count 2, weak count 1\) = {get\(\) = 0x.*}} } } +// { dg-final { regexp-test wp {std::atomic.std::weak_ptr.int.. \(use count 2, weak count 1\) = {get\(\) = 0x.*}} } } + std::cout << "\n"; return 0; // Mark SPOT }
reply other threads:[~2022-04-27 14:53 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20220427145306.22F90385842B@sourceware.org \ --to=redi@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ --cc=libstdc++-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).