From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 79FFD3857430 for ; Wed, 27 Apr 2022 14:53:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 79FFD3857430 Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-390-nDLM2ptFPUGLAQs3vthUuA-1; Wed, 27 Apr 2022 10:53:24 -0400 X-MC-Unique: nDLM2ptFPUGLAQs3vthUuA-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.rdu2.redhat.com [10.11.54.8]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 0F2F43C10AA4; Wed, 27 Apr 2022 14:53:24 +0000 (UTC) Received: from localhost (unknown [10.33.36.192]) by smtp.corp.redhat.com (Postfix) with ESMTP id C8874C52C86; Wed, 27 Apr 2022 14:53:23 +0000 (UTC) From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed] libstdc++: Add pretty printer for std::atomic Date: Wed, 27 Apr 2022 15:53:23 +0100 Message-Id: <20220427145323.2221521-1-jwakely@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.85 on 10.11.54.8 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-13.0 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_NONE, TXREP, T_FILL_THIS_FORM_SHORT autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libstdc++@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++ mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 27 Apr 2022 14:53:28 -0000 Tested x86_64-linux, pushed to trunk. -- >8 -- 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> and atomic>. (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. --- libstdc++-v3/python/libstdcxx/v6/printers.py | 53 +++++++++++++++++-- .../libstdc++-prettyprinters/cxx11.cc | 10 ++++ .../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, or atomic" 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 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 #include #include +#include #include "../util/testsuite_allocator.h" // NullablePointer typedef std::tuple ExTuple; @@ -197,6 +198,15 @@ main() std::initializer_list il = {3, 4}; // { dg-final { note-test il {std::initializer_list of length 2 = {3, 4}} } } + std::atomic ai{100}; + // { dg-final { note-test ai {std::atomic = { 100 }} } } + long l{}; + std::atomic ap{&l}; + // { dg-final { regexp-test ap {std::atomic.long \*. = { 0x.* }} } } + struct Value { int i, j; }; + std::atomic av{{8, 9}}; + // { dg-final { note-test av {std::atomic = { {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 #include #include +#include #include 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> spe; +// { dg-final { note-test spe {std::atomic> (empty) = {get() = 0x0}} } } + std::atomic> sp1 = std::make_shared(1); + std::atomic> sp2 = sp1.load(); + std::atomic> 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 } -- 2.34.1