From patchwork Mon Jul 14 14:21:59 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 369641 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id DA8771400AA for ; Tue, 15 Jul 2014 00:22:28 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:mime-version:content-type; q=dns; s=default; b=ynEKy7jnA7NuUxTLlCtE8XCsj3sYZnFuhRtynjP01yrU+UDJDB wsDnEL/GC+wisMc3D6tNaKU8RpDV/ds3JPm4MdAVD1W7Z2fLzJ3MiKG6yLfQVGfW RK6Q74Wf+oNO+FVHMBJVIMW07pyGFsL4tPEUq55LMOZwqZy98xH2DGQ0c= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:mime-version:content-type; s= default; bh=nSMO7tAMvj7ji8bx6AwbhGe9M1E=; b=tmPErPApMgD3p0yaQx8R 6XsvENGg7OrqxtiNMQfbhdFThuV52QQXzPaLx/MGJTF4NKMwAv5SZHKCH1Zyotl3 anle002LeszXkW5oFzumXVOfUc4ZdHqQj//4y30I32gg8aVS5TPTRaKEiCefHf3s ZraFguzu1z+Wu7lGkinYwPQ= Received: (qmail 15628 invoked by alias); 14 Jul 2014 14:22:09 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 15604 invoked by uid 89); 14 Jul 2014 14:22:08 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 X-Spam-User: qpsmtpd, 2 recipients X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Mon, 14 Jul 2014 14:22:03 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s6EEM1px029367 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 14 Jul 2014 10:22:01 -0400 Received: from localhost (ovpn-116-72.ams2.redhat.com [10.36.116.72]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s6EELx61009753; Mon, 14 Jul 2014 10:22:00 -0400 Date: Mon, 14 Jul 2014 15:21:59 +0100 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Cc: tromey@redhat.com, pmuldoon@redhat.com Subject: [patch] Add libstdc++ type printers for class templates Message-ID: <20140714142159.GF4871@redhat.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) This defines a new style of Python type printer that recognizes templates and can be used to omit default template arguments from the typename GDB prints, e.g. showing std::vector> as simply std::vector. Additionally, T will get processed by the type recognizers so if it's a standard typedef or template it will also get displayed in its abbreviated form. e.g. with current trunk: Breakpoint 1, main () at p.cc:45 45 std::vector>> nested; (gdb) whatis nested type = std::vector >, std::allocator > > >, std::allocator >, std::allocator > > > > > and with this patch: (gdb) whatis nested type = std::vector>> N.B. I am not printing spaces between the closing angle brackets. If people prefer I can put them in, or only do it for C++11 types, so that copying and pasting types from GDB will always work (if you're copying a C++11 type then you must be planning to use it with a C++11 compiler, which will handle >> without spaces). This passes the python testsuite but I'll wait for comments before committing, in case my use of the GDB API or Python can be improved by anyone. commit 538e6eddc52681d9b3ca8fb5d97f194492ee68da Author: Jonathan Wakely Date: Thu Jul 10 20:31:11 2014 +0100 * python/libstdcxx/v6/printers.py (TemplateTypePrinter): Add type printer for class templates. (register_type_printers): Use TemplateTypePrinter for containers and other class templates with default template arguments. * testsuite/libstdc++-prettyprinters/whatis.cc: Test new recognizers. diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py index 1fa08fb..ea34f22 100644 --- a/libstdc++-v3/python/libstdcxx/v6/printers.py +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py @@ -922,6 +922,57 @@ class Printer(object): libstdcxx_printer = None +class TemplateTypePrinter(object): + """A type printer for class templates. + + Recognizes type names that match a regular expression. + Replaces them with a formatted string which can use replacement field + {N} to refer to the \N subgroup of the regex match. + Type printers are recusively applied to the subgroups. + + This allows recognizing e.g. "std::vector<(.*), std::allocator<\\1> >" + and replacing it with "std::vector<{1}>", omitting the template argument + that uses the default type. + """ + + def __init__(self, name, pattern, subst): + self.name = name + self.pattern = re.compile(pattern) + self.subst = subst + self.enabled = True + + class _recognizer(object): + def __init__(self, pattern, subst): + self.pattern = pattern + self.subst = subst + self.type_obj = None + + def recognize(self, type_obj): + if type_obj.tag is None: + return None + + m = self.pattern.match(type_obj.tag) + if m: + subs = list(m.groups()) + for i, sub in enumerate(subs): + if ('{%d}' % (i+1)) in self.subst: + # apply recognizers to subgroup + rep = gdb.types.apply_type_recognizers( + gdb.types.get_type_recognizers(), + gdb.lookup_type(sub)) + if rep: + subs[i] = rep + subs = [None] + subs + return self.subst.format(*subs) + return None + + def instantiate(self): + return self._recognizer(self.pattern, self.subst) + +def add_one_template_type_printer(obj, name, match, subst): + printer = TemplateTypePrinter(name, '^std::' + match + '$', 'std::' + subst) + gdb.types.register_type_printer(obj, printer) + class FilteringTypePrinter(object): def __init__(self, match, name): self.match = match @@ -1013,6 +1064,56 @@ def register_type_printers(obj): add_one_type_printer(obj, 'discard_block_engine', 'ranlux48') add_one_type_printer(obj, 'shuffle_order_engine', 'knuth_b') + # Do not show defaulted template arguments in class templates + add_one_template_type_printer(obj, 'unique_ptr', + 'unique_ptr<(.*), std::default_delete<\\1 ?> >', + 'unique_ptr<{1}>') + + add_one_template_type_printer(obj, 'deque', + 'deque<(.*), std::allocator<\\1 ?> >', + 'deque<{1}>') + add_one_template_type_printer(obj, 'forward_list', + 'forward_list<(.*), std::allocator<\\1 ?> >', + 'forward_list<{1}>') + add_one_template_type_printer(obj, 'list', + 'list<(.*), std::allocator<\\1 ?> >', + 'list<{1}>') + add_one_template_type_printer(obj, 'vector', + 'vector<(.*), std::allocator<\\1 ?> >', + 'vector<{1}>') + add_one_template_type_printer(obj, 'map', + 'map<(.*), (.*), std::less<\\1 ?>, std::allocator > >', + 'map<{1}, {2}>') + add_one_template_type_printer(obj, 'multimap', + 'multimap<(.*), (.*), std::less<\\1 ?>, std::allocator > >', + 'multimap<{1}, {2}>') + add_one_template_type_printer(obj, 'set', + 'set<(.*), std::less<\\1 ?>, std::allocator<\\1 ?> >', + 'set<{1}>') + add_one_template_type_printer(obj, 'multiset', + 'multiset<(.*), std::less<\\1 ?>, std::allocator<\\1 ?> >', + 'multiset<{1}>') + add_one_template_type_printer(obj, 'unordered_map', + 'unordered_map<(.*), (.*), std::hash<\\1 ?>, std::equal_to<\\1 ?>, std::allocator > >', + 'unordered_map<{1}, {2}>') + add_one_template_type_printer(obj, 'unordered_multimap', + 'unordered_multimap<(.*), (.*), std::hash<\\1 ?>, std::equal_to<\\1 ?>, std::allocator > >', + 'unordered_multimap<{1}, {2}>') + add_one_template_type_printer(obj, 'unordered_set', + 'unordered_set<(.*), std::hash<\\1 ?>, std::equal_to<\\1 ?>, std::allocator<\\1 ?> >', + 'unordered_set<{1}>') + add_one_template_type_printer(obj, 'unordered_multiset', + 'unordered_multiset<(.*), std::hash<\\1 ?>, std::equal_to<\\1 ?>, std::allocator<\\1 ?> >', + 'unordered_multiset<{1}>') + + # strip the "fundamentals_v1" inline namespace from these types + add_one_template_type_printer(obj, 'optional', + 'experimental::fundamentals_v1::optional<(.*)>', + 'experimental::optional<\\1>') + add_one_template_type_printer(obj, 'basic_string_view', + 'experimental::fundamentals_v1::basic_string_view<(.*), std::char_traits<\\1> >', + 'experimental::basic_string_view<\\1>') + def register_libstdcxx_printers (obj): "Register libstdc++ pretty-printers with objfile Obj." diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/whatis.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/whatis.cc index fbbb772..b398972 100644 --- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/whatis.cc +++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/whatis.cc @@ -21,6 +21,15 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include template void @@ -159,6 +168,31 @@ std::basic_string *sstring_ptr; holder< std::basic_string > sstring_holder; // { dg-final { whatis-test sstring_holder "holder, std::allocator > >" } } +std::vector>> *seq1_ptr; +holder< std::vector>> > seq1_holder; +// { dg-final { whatis-test seq1_holder "holder>> >" } } + +std::list>> *seq2_ptr; +holder< std::list>> > seq2_holder; +// { dg-final { whatis-test seq2_holder "holder>> >" } } + +std::map> *assoc1_ptr; +holder< std::map> > assoc1_holder; +// { dg-final { whatis-test assoc1_holder "holder> >" } } + +std::multimap> *assoc2_ptr; +holder< std::multimap> > assoc2_holder; +// { dg-final { whatis-test assoc2_holder "holder> >" } } + +std::unordered_map> *unord1_ptr; +holder< std::unordered_map> > unord1_holder; +// { dg-final { whatis-test unord1_holder "holder> >" } } + +std::unordered_multimap> *unord2_ptr; +holder< std::unordered_multimap> > unord2_holder; +// { dg-final { whatis-test unord2_holder "holder> >" } } + + int main() { @@ -236,6 +270,18 @@ main() placeholder(&ustring_holder); placeholder(&sstring_ptr); placeholder(&sstring_holder); + placeholder(&seq1_ptr); + placeholder(&seq1_holder); + placeholder(&seq2_ptr); + placeholder(&seq2_holder); + placeholder(&assoc1_ptr); + placeholder(&assoc1_holder); + placeholder(&assoc2_ptr); + placeholder(&assoc2_holder); + placeholder(&unord1_ptr); + placeholder(&unord1_holder); + placeholder(&unord2_ptr); + placeholder(&unord2_holder); return 0; }