2012-01-08 Jonathan Wakely <jwakely....@gmail.com> * python/libstdcxx/v6/printers.py (StdForwardListPrinter): Add. * testsuite/libstdc++-prettyprinters/cxx11.cc: New.
Tested 'make check RUNTESTFLAGS=prettyprinters.exp' and committed to trunk The test also checks some of the other C++11 containers' printers but could be improved to give better coverage.
Index: python/libstdcxx/v6/printers.py =================================================================== --- python/libstdcxx/v6/printers.py (revision 182988) +++ python/libstdcxx/v6/printers.py (working copy) @@ -687,6 +687,49 @@ class Tr1UnorderedMapPrinter: def display_hint (self): return 'map' +class StdForwardListPrinter: + "Print a std::forward_list" + + class _iterator: + def __init__(self, nodetype, head): + self.nodetype = nodetype + self.base = head['_M_next'] + self.count = 0 + + def __iter__(self): + return self + + def next(self): + if self.base == 0: + raise StopIteration + elt = self.base.cast(self.nodetype).dereference() + self.base = elt['_M_next'] + count = self.count + self.count = self.count + 1 + return ('[%d]' % count, elt['_M_value']) + + def __init__(self, typename, val): + self.val = val + self.typename = typename + + def children(self): + itype = self.val.type.template_argument(0) + # If the inferior program is compiled with -D_GLIBCXX_DEBUG + # some of the internal implementation details change. + if self.typename == "std::forward_list": + nodetype = gdb.lookup_type('std::_Fwd_list_node<%s>' % itype).pointer() + elif self.typename == "std::__debug::list": + nodetype = gdb.lookup_type('std::__norm::_Fwd_list_node<%s>' % itype).pointer() + else: + raise ValueError, "Cannot cast forward_list node for forward_list printer." + return self._iterator(nodetype, self.val['_M_impl']['_M_head']) + + def to_string(self): + if self.val['_M_impl']['_M_head']['_M_next'] == 0: + return 'empty %s' % (self.typename) + return '%s' % (self.typename) + + # A "regular expression" printer which conforms to the # "SubPrettyPrinter" protocol from gdb.printing. class RxPrinter(object): @@ -812,6 +855,7 @@ def build_libstdcxx_dictionary (): libstdcxx_printer.add('std::unordered_set', Tr1UnorderedSetPrinter) libstdcxx_printer.add('std::unordered_multimap', Tr1UnorderedMapPrinter) libstdcxx_printer.add('std::unordered_multiset', Tr1UnorderedSetPrinter) + libstdcxx_printer.add('std::forward_list', StdForwardListPrinter) libstdcxx_printer.add('std::tr1::shared_ptr', StdPointerPrinter) libstdcxx_printer.add('std::tr1::weak_ptr', StdPointerPrinter) @@ -833,6 +877,8 @@ def build_libstdcxx_dictionary (): Tr1UnorderedMapPrinter) libstdcxx_printer.add('std::__debug::unordered_multiset', Tr1UnorderedSetPrinter) + libstdcxx_printer.add('std::__debug::forward_list', + StdForwardListPrinter) # Extensions. Index: testsuite/libstdc++-prettyprinters/cxx11.cc =================================================================== --- testsuite/libstdc++-prettyprinters/cxx11.cc (revision 0) +++ testsuite/libstdc++-prettyprinters/cxx11.cc (revision 0) @@ -0,0 +1,82 @@ +// { dg-do run } +// { dg-options "-std=gnu++11 -g" } + +// Copyright (C) 2011 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <forward_list> +#include <unordered_map> +#include <unordered_set> +#include <string> +#include <iostream> + +template<class T> +void +placeholder(const T &s) +{ + std::cout << s; +} + +template<class T, class S> +void +placeholder(const std::pair<T,S> &s) +{ + std::cout << s.first; +} + +template<class T> +void +use(const T &container) +{ + for (typename T::const_iterator i = container.begin(); + i != container.end(); + ++i) + placeholder(*i); +} + +int +main() +{ + std::forward_list<int> efl; +// { dg-final { note-test efl "empty std::forward_list" } } + + std::forward_list<int> fl; + fl.push_front(2); + fl.push_front(1); +// { dg-final { note-test fl {std::forward_list = {[0] = 1, [1] = 2}} } } + + std::unordered_map<int, std::string> eum; +// { dg-final { note-test eum "std::unordered_map with 0 elements" } } + std::unordered_multimap<int, std::string> eumm; +// { dg-final { note-test eumm "std::unordered_multimap with 0 elements" } } + std::unordered_set<int> eus; +// { dg-final { note-test eus "std::unordered_set with 0 elements" } } + std::unordered_multiset<int> eums; +// { dg-final { note-test eums "std::unordered_multiset with 0 elements" } } + + placeholder(""); // Mark SPOT + use(efl); + use(fl); + use(eum); + use(eumm); + use(eus); + use(eums); + + return 0; +} + +// { dg-final { gdb-test SPOT } }