diff --git a/libstdc++-v3/python/libstdcxx/v6/xmethods.py b/libstdc++-v3/python/libstdcxx/v6/xmethods.py index 6af1c95..2198411 100644 --- a/libstdc++-v3/python/libstdcxx/v6/xmethods.py +++ b/libstdc++-v3/python/libstdcxx/v6/xmethods.py @@ -422,6 +422,50 @@ class VectorMethodsMatcher(gdb.xmethod.XMethodMatcher): return None return method.worker_class(class_type.template_argument(0)) +# Xmethods for associative containers + +class AssociativeContainerWorkerBase(gdb.xmethod.XMethodWorker): + def __init__(self, unordered): + self._unordered = unordered + + def node_count(self, obj): + if self._unordered: + return obj['_M_h']['_M_element_count'] + else: + return obj['_M_t']['_M_impl']['_M_node_count'] + + def get_arg_types(self): + return None + +class AssociativeContainerEmptyWorker(AssociativeContainerWorkerBase): + def __call__(self, obj): + return int(self.node_count(obj)) == 0 + +class AssociativeContainerSizeWorker(AssociativeContainerWorkerBase): + def __call__(self, obj): + return self.node_count(obj) + +class AssociativeContainerMethodsMatcher(gdb.xmethod.XMethodMatcher): + def __init__(self, name): + gdb.xmethod.XMethodMatcher.__init__(self, + matcher_name_prefix + name) + self._name = name + self._method_dict = { + 'size': LibStdCxxXMethod('size', AssociativeContainerSizeWorker), + 'empty': LibStdCxxXMethod('empty', + AssociativeContainerEmptyWorker), + } + self.methods = [self._method_dict[m] for m in self._method_dict] + + def match(self, class_type, method_name): + if not re.match('^std::%s<.*>$' % self._name, class_type.tag): + return None + method = self._method_dict.get(method_name) + if method is None or not method.enabled: + return None + unordered = 'unordered' in self._name + return method.worker_class(unordered) + # Xmethods for std::unique_ptr class UniquePtrGetWorker(gdb.xmethod.XMethodWorker): @@ -465,4 +509,20 @@ def register_libstdcxx_xmethods(locus): gdb.xmethod.register_xmethod_matcher(locus, DequeMethodsMatcher()) gdb.xmethod.register_xmethod_matcher(locus, ListMethodsMatcher()) gdb.xmethod.register_xmethod_matcher(locus, VectorMethodsMatcher()) + gdb.xmethod.register_xmethod_matcher( + locus, AssociativeContainerMethodsMatcher('set')) + gdb.xmethod.register_xmethod_matcher( + locus, AssociativeContainerMethodsMatcher('map')) + gdb.xmethod.register_xmethod_matcher( + locus, AssociativeContainerMethodsMatcher('multiset')) + gdb.xmethod.register_xmethod_matcher( + locus, AssociativeContainerMethodsMatcher('multimap')) + gdb.xmethod.register_xmethod_matcher( + locus, AssociativeContainerMethodsMatcher('unordered_set')) + gdb.xmethod.register_xmethod_matcher( + locus, AssociativeContainerMethodsMatcher('unordered_map')) + gdb.xmethod.register_xmethod_matcher( + locus, AssociativeContainerMethodsMatcher('unordered_multiset')) + gdb.xmethod.register_xmethod_matcher( + locus, AssociativeContainerMethodsMatcher('unordered_multimap')) gdb.xmethod.register_xmethod_matcher(locus, UniquePtrMethodsMatcher()) diff --git a/libstdc++-v3/testsuite/libstdc++-xmethods/associative-containers.cc b/libstdc++-v3/testsuite/libstdc++-xmethods/associative-containers.cc new file mode 100644 index 0000000..7949f22 --- /dev/null +++ b/libstdc++-v3/testsuite/libstdc++-xmethods/associative-containers.cc @@ -0,0 +1,79 @@ +// { dg-do run } +// { dg-options "-std=gnu++11 -g -O0" } + +// 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 +// . + +#include +#include +#include +#include + +int +main () +{ + std::set s, s1; + std::multiset ms, ms1; + std::unordered_set us, us1; + std::unordered_multiset ums, ums1; + std::map m, m1; + std::multimap mm, mm1; + std::unordered_map um, um1; + std::unordered_multimap umm, umm1; + + for (int i = 0; i < 100; i++) + { + s.insert (i % 5); + ms.insert (i % 5); + us.insert (i % 7); + ums.insert (i % 7); + + m.insert(std::pair ('a' + i % 5, i)); + mm.insert(std::pair ('a' + i % 5, i)); + um.insert(std::pair ('a' + i % 7, i)); + umm.insert(std::pair ('a' + i % 7, i)); + } + +// { dg-final { note-test s.size() 5 } } +// { dg-final { note-test s.empty() false } } +// { dg-final { note-test s1.empty() true } } +// { dg-final { note-test ms.size() 100 } } +// { dg-final { note-test ms.empty() false } } +// { dg-final { note-test ms1.empty() true } } +// { dg-final { note-test us.size() 7 } } +// { dg-final { note-test us.empty() false } } +// { dg-final { note-test us1.empty() true } } +// { dg-final { note-test ums.size() 100 } } +// { dg-final { note-test ums.empty() false } } +// { dg-final { note-test ums1.empty() true } } +// { dg-final { note-test m.size() 5 } } +// { dg-final { note-test m.empty() false } } +// { dg-final { note-test m1.empty() true } } +// { dg-final { note-test mm.size() 100 } } +// { dg-final { note-test mm.empty() false } } +// { dg-final { note-test mm1.empty() true } } +// { dg-final { note-test um.size() 7 } } +// { dg-final { note-test um.empty() false } } +// { dg-final { note-test um1.empty() true } } +// { dg-final { note-test umm.size() 100 } } +// { dg-final { note-test umm.empty() false } } +// { dg-final { note-test umm1.empty() true } } + + return 0; // Mark SPOT +} + +// { dg-final { gdb-test SPOT {} 1 } }