diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 955efbf16fc..c59c25453e1 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,11 @@ +2014-07-15 Jonathan Wakely + + * 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. + 2014-07-15 Tim Shen PR libstdc++/61720 diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py index 1fa08fbd572..ea34f222cdf 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 fbbb7728f98..b3989720abc 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; }