aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2014-07-15 13:00:18 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2014-07-15 13:00:18 +0100
commit6f440cceb403312f76a610b26cee52541e9cf3e7 (patch)
tree5464d3c9a5c218281fb459067905bd8df4505194 /libstdc++-v3
parent077aa95ec765641f315f5d3d032f43f2e31402d8 (diff)
downloadgcc-6f440cceb403312f76a610b26cee52541e9cf3e7.zip
gcc-6f440cceb403312f76a610b26cee52541e9cf3e7.tar.gz
gcc-6f440cceb403312f76a610b26cee52541e9cf3e7.tar.bz2
printers.py (SingleObjContainerPrinter): New base class for experimental::any and experimental::optional printers.
* python/libstdcxx/v6/printers.py (SingleObjContainerPrinter): New base class for experimental::any and experimental::optional printers. (StdExpAnyPrinter, StdExpOptionalPrinter, StdExpStringViewPrinter): New printers for Fundamentals TS types. * testsuite/libstdc++-prettyprinters/libfundts.cc: New. From-SVN: r212556
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog6
-rw-r--r--libstdc++-v3/python/libstdcxx/v6/printers.py131
-rw-r--r--libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc69
3 files changed, 204 insertions, 2 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index c59c254..32de882 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -6,6 +6,12 @@
and other class templates with default template arguments.
* testsuite/libstdc++-prettyprinters/whatis.cc: Test new recognizers.
+ * python/libstdcxx/v6/printers.py (SingleObjContainerPrinter): New
+ base class for experimental::any and experimental::optional printers.
+ (StdExpAnyPrinter, StdExpOptionalPrinter, StdExpStringViewPrinter):
+ New printers for Fundamentals TS types.
+ * testsuite/libstdc++-prettyprinters/libfundts.cc: New.
+
2014-07-15 Tim Shen <timshen@google.com>
PR libstdc++/61720
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index ea34f22..af41f1f 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -836,6 +836,126 @@ class StdForwardListPrinter:
return 'empty %s' % (self.typename)
return '%s' % (self.typename)
+class SingleObjContainerPrinter(object):
+ "Base class for printers of containers of single objects"
+
+ def __init__ (self, val, viz):
+ self.contained_value = val
+ self.visualizer = viz
+
+ def _recognize(self, type):
+ """Return TYPE as a string after applying type printers"""
+ return gdb.types.apply_type_recognizers(gdb.types.get_type_recognizers(),
+ type) or str(type)
+
+ class _contained:
+ def __init__ (self, val):
+ self.val = val
+
+ def __iter__ (self):
+ return self
+
+ def next (self):
+ if self.val is None:
+ raise StopIteration
+ retval = self.val
+ self.val = None
+ return ('[contained value]', retval)
+
+ def children (self):
+ if self.contained_value is None:
+ return self._contained (None)
+ if hasattr (self.visualizer, 'children'):
+ return self.visualizer.children ()
+ return self._contained (self.contained_value)
+
+ def display_hint (self):
+ # if contained value is a map we want to display in the same way
+ if hasattr (self.visualizer, 'children') and hasattr (self.visualizer, 'display_hint'):
+ return self.visualizer.display_hint ()
+ return None
+
+
+class StdExpAnyPrinter(SingleObjContainerPrinter):
+ "Print a std::experimental::any"
+
+ def __init__ (self, typename, val):
+ self.typename = 'std::experimental::any'
+ self.val = val
+ self.contained_type = None
+ contained_value = None
+ visualizer = None
+ mgr = self.val['_M_manager']
+ if mgr != 0:
+ func = gdb.block_for_pc(int(mgr.cast(gdb.lookup_type('intptr_t'))))
+ if not func:
+ raise ValueError("Invalid function pointer in std::experimental::any")
+ rx = r"""({0}::_Manager_\w+<.*>)::_S_manage\({0}::_Op, {0} const\*, {0}::_Arg\*\)""".format(typename)
+ m = re.match(rx, func.function.name)
+ if not m:
+ raise ValueError("Unknown manager function in std::experimental::any")
+
+ # FIXME need to expand 'std::string' so that gdb.lookup_type works
+ mgrname = re.sub("std::string(?!\w)", gdb.lookup_type('std::string').strip_typedefs().name, m.group(1))
+ mgrtype = gdb.lookup_type(mgrname)
+ self.contained_type = mgrtype.template_argument(0)
+ valptr = None
+ if '::_Manager_internal' in mgrname:
+ valptr = self.val['_M_storage']['_M_buffer'].address
+ elif '::_Manager_external' in mgrname:
+ valptr = self.val['_M_storage']['_M_ptr']
+ elif '::_Manager_alloc' in mgrname:
+ datatype = gdb.lookup_type(mgrname + '::_Data')
+ valptr = self.val['_M_storage']['_M_ptr'].cast(datatype.pointer())
+ valptr = valptr.dereference()['_M_data'].address
+ else:
+ raise ValueError("Unknown manager function in std::experimental::any")
+ contained_value = valptr.cast(self.contained_type.pointer()).dereference()
+ visualizer = gdb.default_visualizer(contained_value)
+ super(StdExpAnyPrinter, self).__init__ (contained_value, visualizer)
+
+ def to_string (self):
+ if self.contained_type is None:
+ return '%s [no contained value]' % self.typename
+ desc = "%s containing " % self.typename
+ if hasattr (self.visualizer, 'children'):
+ return desc + self.visualizer.to_string ()
+ valtype = self._recognize (self.contained_type)
+ return desc + valtype
+
+class StdExpOptionalPrinter(SingleObjContainerPrinter):
+ "Print a std::experimental::optional"
+
+ def __init__ (self, typename, val):
+ valtype = self._recognize (val.type.template_argument(0))
+ self.typename = "std::experimental::optional<%s>" % valtype
+ self.val = val
+ contained_value = val['_M_payload'] if self.val['_M_engaged'] else None
+ visualizer = gdb.default_visualizer (val['_M_payload'])
+ super (StdExpOptionalPrinter, self).__init__ (contained_value, visualizer)
+
+ def to_string (self):
+ if self.contained_value is None:
+ return self.typename + " [no contained value]"
+ if hasattr (self.visualizer, 'children'):
+ return self.typename + " containing " + self.visualizer.to_string ()
+ return self.typename
+
+class StdExpStringViewPrinter:
+ "Print a std::experimental::basic_string_view"
+
+ def __init__ (self, typename, val):
+ self.val = val
+
+ def to_string (self):
+ ptr = self.val['_M_str']
+ len = self.val['_M_len']
+ if hasattr (ptr, "lazy_string"):
+ return ptr.lazy_string (length = len)
+ return ptr.string (length = len)
+
+ def display_hint (self):
+ return 'string'
# A "regular expression" printer which conforms to the
# "SubPrettyPrinter" protocol from gdb.printing.
@@ -865,12 +985,12 @@ class Printer(object):
self.subprinters = []
self.lookup = {}
self.enabled = True
- self.compiled_rx = re.compile('^([a-zA-Z0-9_:]+)<.*>$')
+ self.compiled_rx = re.compile('^([a-zA-Z0-9_:]+)(<.*>)?$')
def add(self, name, function):
# A small sanity check.
# FIXME
- if not self.compiled_rx.match(name + '<>'):
+ if not self.compiled_rx.match(name):
raise ValueError('libstdc++ programming error: "%s" does not match' % name)
printer = RxPrinter(name, function)
self.subprinters.append(printer)
@@ -1214,6 +1334,13 @@ def build_libstdcxx_dictionary ():
libstdcxx_printer.add('std::__debug::forward_list',
StdForwardListPrinter)
+ # Library Fundamentals TS components
+ libstdcxx_printer.add_version('std::experimental::fundamentals_v1::',
+ 'any', StdExpAnyPrinter)
+ libstdcxx_printer.add_version('std::experimental::fundamentals_v1::',
+ 'optional', StdExpOptionalPrinter)
+ libstdcxx_printer.add_version('std::experimental::fundamentals_v1::',
+ 'basic_string_view', StdExpStringViewPrinter)
# Extensions.
libstdcxx_printer.add_version('__gnu_cxx::', 'slist', StdSlistPrinter)
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc
new file mode 100644
index 0000000..e2f99a1
--- /dev/null
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc
@@ -0,0 +1,69 @@
+// { dg-do run }
+// { dg-options "-g -O0 -std=gnu++14" }
+
+// Copyright (C) 2014 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 <experimental/any>
+#include <experimental/optional>
+#include <experimental/string_view>
+#include <string>
+#include <map>
+
+using std::experimental::any;
+using std::experimental::optional;
+using std::experimental::string_view;
+
+int
+main()
+{
+ string_view str = "string";
+// { dg-final { note-test str "\"string\"" } }
+
+ optional<int> o;
+// { dg-final { note-test o {std::experimental::optional<int> [no contained value]} } }
+ optional<bool> ob{false};
+// { dg-final { note-test ob {std::experimental::optional<bool> = {[contained value] = false}} } }
+ optional<int> oi{5};
+// { dg-final { note-test oi {std::experimental::optional<int> = {[contained value] = 5}} } }
+ optional<void*> op{nullptr};
+// { dg-final { note-test op {std::experimental::optional<void *> = {[contained value] = 0x0}} } }
+ optional<std::map<int, double>> om;
+ om = std::map<int, double>{ {1, 2.}, {3, 4.}, {5, 6.} };
+// { dg-final { note-test om {std::experimental::optional<std::map<int, double>> containing std::map with 3 elements = {[1] = 2, [3] = 4, [5] = 6}} } }
+ optional<std::string> os{ "stringy" };
+// { dg-final { note-test os {std::experimental::optional<std::string> = {[contained value] = "stringy"}} } }
+
+ any a;
+// { dg-final { note-test a {std::experimental::any [no contained value]} } }
+ any ab(false);
+// { dg-final { note-test ab {std::experimental::any containing bool = {[contained value] = false}} } }
+ any ai(6);
+// { dg-final { note-test ai {std::experimental::any containing int = {[contained value] = 6}} } }
+ any ap = (void*)nullptr;
+// { dg-final { note-test ap {std::experimental::any containing void * = {[contained value] = 0x0}} } }
+ any as = *os;
+// { dg-final { note-test as {std::experimental::any containing std::string = {[contained value] = "stringy"}} } }
+ any as2("stringiest");
+// { dg-final { regexp-test as2 {std::experimental::any containing const char \* = {\[contained value\] = 0x[[:xdigit:]]+ "stringiest"}} } }
+ any am = *om;
+// { dg-final { note-test am {std::experimental::any containing std::map with 3 elements = {[1] = 2, [3] = 4, [5] = 6}} } }
+
+ return 0; // Mark SPOT
+}
+
+// { dg-final { gdb-test SPOT } }