re PR libstdc++/65839 (xmethods need updating once gdb decides how to fix 18285)
authorDoug Evans <dje@google.com>
Wed, 29 Apr 2015 22:50:31 +0000 (22:50 +0000)
committerDoug Evans <devans@gcc.gnu.org>
Wed, 29 Apr 2015 22:50:31 +0000 (22:50 +0000)
PR libstdc++/65839
* python/libstdcxx/v6/xmethods.py (get_bool_type): New function.
Replace all lookups of "bool" with this.
(get_std_size_type): New function.  Replace all lookups of std::size_t
with this.
(*Worker): New method get_result_type.
(DequeWorkerBase.__init__): New arg val_type.  All callers updated.
(ListWorkerBase.__init__): New arg val_type.  All callers updated.
(UniquePtrGetWorker.__init__): New arg elem_type.  All callers updated.
Delete setting of name, enabled.
(UniquePtrDerefWorker.__init__): New arg elem_type.  All callers
updated.  Delete setting of name.
(UniquePtrMethodsMatcher): Rewrite for consistency with all other
libstdc++ xmethod matchers.
* testsuite/libstdc++-xmethods/array.cc: Add whatis tests.
* testsuite/libstdc++-xmethods/associative-containers.cc: Ditto.
* testsuite/libstdc++-xmethods/deque.cc: Ditto.
* testsuite/libstdc++-xmethods/forwardlist.cc: Ditto.
* testsuite/libstdc++-xmethods/list.cc: Ditto.
* testsuite/libstdc++-xmethods/unique_ptr.cc: Ditto.
* testsuite/libstdc++-xmethods/vector.cc: Ditto.

From-SVN: r222599

libstdc++-v3/ChangeLog
libstdc++-v3/python/libstdcxx/v6/xmethods.py
libstdc++-v3/testsuite/libstdc++-xmethods/array.cc
libstdc++-v3/testsuite/libstdc++-xmethods/associative-containers.cc
libstdc++-v3/testsuite/libstdc++-xmethods/deque.cc
libstdc++-v3/testsuite/libstdc++-xmethods/forwardlist.cc
libstdc++-v3/testsuite/libstdc++-xmethods/list.cc
libstdc++-v3/testsuite/libstdc++-xmethods/unique_ptr.cc
libstdc++-v3/testsuite/libstdc++-xmethods/vector.cc

index ca9ca6af123eecf6e254079a4014032a1f117ff7..5b509f79cf24a0b0d30c7ca33b8922fd580feac7 100644 (file)
@@ -1,3 +1,27 @@
+2015-04-29  Doug Evans  <dje@google.com>
+
+       PR libstdc++/65839
+       * python/libstdcxx/v6/xmethods.py (get_bool_type): New function.
+       Replace all lookups of "bool" with this.
+       (get_std_size_type): New function.  Replace all lookups of std::size_t
+       with this.
+       (*Worker): New method get_result_type.
+       (DequeWorkerBase.__init__): New arg val_type.  All callers updated.
+       (ListWorkerBase.__init__): New arg val_type.  All callers updated.
+       (UniquePtrGetWorker.__init__): New arg elem_type.  All callers updated.
+       Delete setting of name, enabled.
+       (UniquePtrDerefWorker.__init__): New arg elem_type.  All callers
+       updated.  Delete setting of name.
+       (UniquePtrMethodsMatcher): Rewrite for consistency with all other
+       libstdc++ xmethod matchers.
+       * testsuite/libstdc++-xmethods/array.cc: Add whatis tests.
+       * testsuite/libstdc++-xmethods/associative-containers.cc: Ditto.
+       * testsuite/libstdc++-xmethods/deque.cc: Ditto.
+       * testsuite/libstdc++-xmethods/forwardlist.cc: Ditto.
+       * testsuite/libstdc++-xmethods/list.cc: Ditto.
+       * testsuite/libstdc++-xmethods/unique_ptr.cc: Ditto.
+       * testsuite/libstdc++-xmethods/vector.cc: Ditto.
+
 2015-04-29  Doug Evans  <dje@google.com>
 
        Use consistent naming for value type attributes.
index e4e920a3e5c0d00a93a108c5493e47a9f772f4b0..6db0e163e9835d3f7bd239147b4791c67353bd6c 100644 (file)
@@ -21,6 +21,12 @@ import re
 
 matcher_name_prefix = 'libstdc++::'
 
+def get_bool_type():
+    return gdb.lookup_type('bool')
+
+def get_std_size_type():
+    return gdb.lookup_type('std::size_t')
+
 class LibStdCxxXMethod(gdb.xmethod.XMethod):
     def __init__(self, name, worker_class):
         gdb.xmethod.XMethod.__init__(self, name)
@@ -44,6 +50,9 @@ class ArraySizeWorker(ArrayWorkerBase):
     def get_arg_types(self):
         return None
 
+    def get_result_type(self, obj):
+        return get_std_size_type()
+
     def __call__(self, obj):
         return self._size
 
@@ -54,6 +63,9 @@ class ArrayEmptyWorker(ArrayWorkerBase):
     def get_arg_types(self):
         return None
 
+    def get_result_type(self, obj):
+        return get_bool_type()
+
     def __call__(self, obj):
         return (int(self._size) == 0)
 
@@ -64,6 +76,9 @@ class ArrayFrontWorker(ArrayWorkerBase):
     def get_arg_types(self):
         return None
 
+    def get_result_type(self, obj):
+        return self._val_type
+
     def __call__(self, obj):
         if int(self._size) > 0:
             return obj['_M_elems'][0]
@@ -77,6 +92,9 @@ class ArrayBackWorker(ArrayWorkerBase):
     def get_arg_types(self):
         return None
 
+    def get_result_type(self, obj):
+        return self._val_type
+
     def __call__(self, obj):
         if int(self._size) > 0:
             return obj['_M_elems'][self._size - 1]
@@ -88,7 +106,10 @@ class ArrayAtWorker(ArrayWorkerBase):
         ArrayWorkerBase.__init__(self, val_type, size)
 
     def get_arg_types(self):
-        return gdb.lookup_type('std::size_t')
+        return get_std_size_type()
+
+    def get_result_type(self, obj, index):
+        return self._val_type
 
     def __call__(self, obj, index):
         if int(index) >= int(self._size):
@@ -101,7 +122,10 @@ class ArraySubscriptWorker(ArrayWorkerBase):
         ArrayWorkerBase.__init__(self, val_type, size)
 
     def get_arg_types(self):
-        return gdb.lookup_type('std::size_t')
+        return get_std_size_type()
+
+    def get_result_type(self, obj, index):
+        return self._val_type
 
     def __call__(self, obj, index):
         if int(self._size) > 0:
@@ -140,6 +164,7 @@ class ArrayMethodsMatcher(gdb.xmethod.XMethodMatcher):
 
 class DequeWorkerBase(gdb.xmethod.XMethodWorker):
     def __init__(self, val_type):
+        self._val_type = val_type
         self._bufsize = (512 / val_type.sizeof) or 1
 
     def size(self, obj):
@@ -158,6 +183,9 @@ class DequeEmptyWorker(DequeWorkerBase):
     def get_arg_types(self):
         return None
 
+    def get_result_type(self, obj):
+        return get_bool_type()
+
     def __call__(self, obj):
         return (obj['_M_impl']['_M_start']['_M_cur'] ==
                 obj['_M_impl']['_M_finish']['_M_cur'])
@@ -166,6 +194,9 @@ class DequeSizeWorker(DequeWorkerBase):
     def get_arg_types(self):
         return None
 
+    def get_result_type(self, obj):
+        return get_std_size_type()
+
     def __call__(self, obj):
         return self.size(obj)
 
@@ -173,6 +204,9 @@ class DequeFrontWorker(DequeWorkerBase):
     def get_arg_types(self):
         return None
 
+    def get_result_type(self, obj):
+        return self._val_type
+
     def __call__(self, obj):
         return obj['_M_impl']['_M_start']['_M_cur'][0]
 
@@ -180,6 +214,9 @@ class DequeBackWorker(DequeWorkerBase):
     def get_arg_types(self):
         return None
 
+    def get_result_type(self, obj):
+        return self._val_type
+
     def __call__(self, obj):
         if (obj['_M_impl']['_M_finish']['_M_cur'] ==
             obj['_M_impl']['_M_finish']['_M_first']):
@@ -190,14 +227,20 @@ class DequeBackWorker(DequeWorkerBase):
 
 class DequeSubscriptWorker(DequeWorkerBase):
     def get_arg_types(self):
-        return gdb.lookup_type('std::size_t')
+        return get_std_size_type()
+
+    def get_result_type(self, obj, subscript):
+        return self._val_type
 
     def __call__(self, obj, subscript):
         return self.index(obj, subscript)
 
 class DequeAtWorker(DequeWorkerBase):
     def get_arg_types(self):
-        return gdb.lookup_type('std::size_t')
+        return get_std_size_type()
+
+    def get_result_type(self, obj, index):
+        return self._val_type
 
     def __call__(self, obj, index):
         deque_size = int(self.size(obj))
@@ -240,10 +283,16 @@ class ForwardListWorkerBase(gdb.xmethod.XMethodMatcher):
         return None
 
 class ForwardListEmptyWorker(ForwardListWorkerBase):
+    def get_result_type(self, obj):
+        return get_bool_type()
+
     def __call__(self, obj):
         return obj['_M_impl']['_M_head']['_M_next'] == 0
 
 class ForwardListFrontWorker(ForwardListWorkerBase):
+    def get_result_type(self, obj):
+        return self._val_type
+
     def __call__(self, obj):
         node = obj['_M_impl']['_M_head']['_M_next'].cast(self._node_type)
         val_address = node['_M_storage']['_M_storage'].address
@@ -272,13 +321,17 @@ class ForwardListMethodsMatcher(gdb.xmethod.XMethodMatcher):
 # Xmethods for std::list
 
 class ListWorkerBase(gdb.xmethod.XMethodWorker):
-    def __init__(self, node_type):
+    def __init__(self, val_type, node_type):
+        self._val_type = val_type
         self._node_type = node_type
 
     def get_arg_types(self):
         return None
 
 class ListEmptyWorker(ListWorkerBase):
+    def get_result_type(self, obj):
+        return get_bool_type()
+
     def __call__(self, obj):
         base_node = obj['_M_impl']['_M_node']
         if base_node['_M_next'] == base_node.address:
@@ -287,6 +340,9 @@ class ListEmptyWorker(ListWorkerBase):
             return False
 
 class ListSizeWorker(ListWorkerBase):
+    def get_result_type(self, obj):
+        return get_std_size_type()
+
     def __call__(self, obj):
         begin_node = obj['_M_impl']['_M_node']['_M_next']
         end_node = obj['_M_impl']['_M_node'].address
@@ -297,11 +353,17 @@ class ListSizeWorker(ListWorkerBase):
         return size
 
 class ListFrontWorker(ListWorkerBase):
+    def get_result_type(self, obj):
+        return self._val_type
+
     def __call__(self, obj):
         node = obj['_M_impl']['_M_node']['_M_next'].cast(self._node_type)
         return node['_M_data']
 
 class ListBackWorker(ListWorkerBase):
+    def get_result_type(self, obj):
+        return self._val_type
+
     def __call__(self, obj):
         prev_node = obj['_M_impl']['_M_node']['_M_prev'].cast(self._node_type)
         return prev_node['_M_data']
@@ -324,8 +386,9 @@ class ListMethodsMatcher(gdb.xmethod.XMethodMatcher):
         method = self._method_dict.get(method_name)
         if method is None or not method.enabled:
             return None
+        val_type = class_type.template_argument(0)
         node_type = gdb.lookup_type(str(class_type) + '::_Node').pointer()
-        return method.worker_class(node_type)
+        return method.worker_class(val_type, node_type)
 
 # Xmethods for std::vector
 
@@ -357,6 +420,9 @@ class VectorEmptyWorker(VectorWorkerBase):
     def get_arg_types(self):
         return None
 
+    def get_result_type(self, obj):
+        return get_bool_type()
+
     def __call__(self, obj):
         return int(self.size(obj)) == 0
 
@@ -364,6 +430,9 @@ class VectorSizeWorker(VectorWorkerBase):
     def get_arg_types(self):
         return None
 
+    def get_result_type(self, obj):
+        return get_std_size_type()
+
     def __call__(self, obj):
         return self.size(obj)
 
@@ -371,6 +440,9 @@ class VectorFrontWorker(VectorWorkerBase):
     def get_arg_types(self):
         return None
 
+    def get_result_type(self, obj):
+        return self._val_type
+
     def __call__(self, obj):
         return self.get(obj, 0)
 
@@ -378,12 +450,18 @@ class VectorBackWorker(VectorWorkerBase):
     def get_arg_types(self):
         return None
 
+    def get_result_type(self, obj):
+        return self._val_type
+
     def __call__(self, obj):
         return self.get(obj, int(self.size(obj)) - 1)
 
 class VectorAtWorker(VectorWorkerBase):
     def get_arg_types(self):
-        return gdb.lookup_type('std::size_t')
+        return get_std_size_type()
+
+    def get_result_type(self, obj, index):
+        return self._val_type
 
     def __call__(self, obj, index):
         size = int(self.size(obj))
@@ -394,7 +472,10 @@ class VectorAtWorker(VectorWorkerBase):
 
 class VectorSubscriptWorker(VectorWorkerBase):
     def get_arg_types(self):
-        return gdb.lookup_type('std::size_t')
+        return get_std_size_type()
+
+    def get_result_type(self, obj, subscript):
+        return self._val_type
 
     def __call__(self, obj, subscript):
         return self.get(obj, int(subscript))
@@ -438,10 +519,16 @@ class AssociativeContainerWorkerBase(gdb.xmethod.XMethodWorker):
         return None
 
 class AssociativeContainerEmptyWorker(AssociativeContainerWorkerBase):
+    def get_result_type(self, obj):
+        return get_bool_type()
+
     def __call__(self, obj):
         return int(self.node_count(obj)) == 0
 
 class AssociativeContainerSizeWorker(AssociativeContainerWorkerBase):
+    def get_result_type(self, obj):
+        return get_std_size_type()
+
     def __call__(self, obj):
         return self.node_count(obj)
 
@@ -469,20 +556,24 @@ class AssociativeContainerMethodsMatcher(gdb.xmethod.XMethodMatcher):
 # Xmethods for std::unique_ptr
 
 class UniquePtrGetWorker(gdb.xmethod.XMethodWorker):
-    def __init__(self):
-        self.name = 'get'
-        self.enabled = True
+    def __init__(self, elem_type):
+        self._elem_type = elem_type
 
     def get_arg_types(self):
         return None
 
+    def get_result_type(self, obj):
+        return self._elem_type.pointer()
+
     def __call__(self, obj):
         return obj['_M_t']['_M_head_impl']
 
 class UniquePtrDerefWorker(UniquePtrGetWorker):
-    def __init__(self):
-        UniquePtrGetWorker.__init__(self)
-        self.name = 'operator*'
+    def __init__(self, elem_type):
+        UniquePtrGetWorker.__init__(self, elem_type)
+
+    def get_result_type(self, obj):
+        return self._elem_type
 
     def __call__(self, obj):
         return UniquePtrGetWorker.__call__(self, obj).dereference()
@@ -491,17 +582,19 @@ class UniquePtrMethodsMatcher(gdb.xmethod.XMethodMatcher):
     def __init__(self):
         gdb.xmethod.XMethodMatcher.__init__(self,
                                             matcher_name_prefix + 'unique_ptr')
-        self._get_worker = UniquePtrGetWorker()
-        self._deref_worker = UniquePtrDerefWorker()
-        self.methods = [self._get_worker, self._deref_worker]
+        self._method_dict = {
+            'get': LibStdCxxXMethod('get', UniquePtrGetWorker),
+            'operator*': LibStdCxxXMethod('operator*', UniquePtrDerefWorker),
+        }
+        self.methods = [self._method_dict[m] for m in self._method_dict]
 
     def match(self, class_type, method_name):
         if not re.match('^std::unique_ptr<.*>$', class_type.tag):
             return None
-        if method_name == 'operator*' and self._deref_worker.enabled:
-            return self._deref_worker
-        elif method_name == 'get' and self._get_worker.enabled:
-            return self._get_worker
+        method = self._method_dict.get(method_name)
+        if method is None or not method.enabled:
+            return None
+        return method.worker_class(class_type.template_argument(0))
 \f
 def register_libstdcxx_xmethods(locus):
     gdb.xmethod.register_xmethod_matcher(locus, ArrayMethodsMatcher())
index 0b314e42945b7882be894eb0acc3a11ce3b06c95..dfe61467485af51036b8a949cbcf788d338159d7 100644 (file)
@@ -40,6 +40,13 @@ main ()
 // { dg-final { note-test a\[4\] 104 } }
 // { dg-final { note-test a\[9\] 109 } }
 
+// { dg-final { whatis-test a.size() std::size_t } }
+// { dg-final { whatis-test a.empty() bool } }
+// { dg-final { whatis-test a.front() int } }
+// { dg-final { whatis-test a.back() int } }
+// { dg-final { whatis-test a.at(5) int } }
+// { dg-final { whatis-test a\[0\] int } }
+
   return 0;  // Mark SPOT
 }
 
index fae61ae80113dc4111739fad06fae417fbf584da..2f04b240f4e6517cb5f94f5634eb4c36f3101fd4 100644 (file)
@@ -73,6 +73,9 @@ main ()
 // { dg-final { note-test umm.empty() false } }
 // { dg-final { note-test umm1.empty() true } }
 
+// { dg-final { whatis-test s.size() std::size_t } }
+// { dg-final { whatis-test s.empty() bool } }
+
   return 0;  // Mark SPOT
 }
 
index e40898e1658411dd26a83c403e42da00c29be244..5890dd858c1b83cde882238fef03213ec6fef8c0 100644 (file)
@@ -61,6 +61,12 @@ main ()
 // { dg-final { note-test q3\[q3_size/2\]==(300+q3_size/2) true } }
 // { dg-final { note-test q3\[q3_size-1]==(300+q3_size-1) true } }
 
+// { dg-final { whatis-test q0.empty() bool } }
+// { dg-final { whatis-test q0.size() std::size_t } }
+// { dg-final { whatis-test q1.front() int } }
+// { dg-final { whatis-test q1.back() int } }
+// { dg-final { whatis-test q3\[0\] int } }
+
   return 0;  // Mark SPOT
 }
 
index 224bbd3c93e29bc2cbf807119f254d4ef81fcca9..2e8b7ac0eb4fc6be923c26142dd3221a0c63c43b 100644 (file)
@@ -34,6 +34,9 @@ main ()
 // { dg-final { note-test l1.empty() false } }
 // { dg-final { note-test l1.front() 11011 } }
 
+// { dg-final { whatis-test l1.empty() bool } }
+// { dg-final { whatis-test l1.front() int } }
+
   return 0;  // Mark SPOT
 }
 
index 9f716f7db53f98580ccfb583d9387ad51571ae75..050f75b807eb288eca761c00387ed391c9b24a38 100644 (file)
@@ -38,6 +38,10 @@ main ()
 // { dg-final { note-test l1.front() 123 } }
 // { dg-final { note-test l1.back() 789 } }
 
+// { dg-final { whatis-test l1.empty() bool } }
+// { dg-final { whatis-test l1.size() std::size_t } }
+// { dg-final { whatis-test l1.front() int } }
+// { dg-final { whatis-test l1.back() int } }
 
   return 0;  // Mark SPOT
 }
index cd6d2e8f0c0b0a3dd1a0c27ff47b956e5cab854d..5d59b551f52bce619c69fc2f1265dce25cd4e646 100644 (file)
@@ -30,6 +30,9 @@ main ()
 // { dg-final { note-test *p 10 } }
 // { dg-final { regexp-test p.get() 0x.* } }
 
+// { dg-final { whatis-test *p int } }
+// { dg-final { whatis-test p.get() "int \*" } }
+
   return 0;  // Mark SPOT
 }
 
index 6f258bcb9f213d00ff14f3b7a08d3e9352c55c22..896728696e0c0b711012cd7a4f46fd905117d048 100644 (file)
@@ -83,6 +83,19 @@ main ()
 // { dg-final { note-test bv3.at(63) true } }
 // { dg-final { note-test bv3.at(64) false } }
 
+// { dg-final { whatis-test v0.empty() bool } }
+// { dg-final { whatis-test v0.size() std::size_t } }
+// { dg-final { whatis-test v1.front() int } }
+// { dg-final { whatis-test v1.back() int } }
+// { dg-final { whatis-test v1\[0\] int } }
+// { dg-final { whatis-test v1.at(1) int } }
+// { dg-final { whatis-test bv0.empty() bool } }
+// { dg-final { whatis-test bv0.size() std::size_t } }
+// { dg-final { whatis-test bv1.front() bool } }
+// { dg-final { whatis-test bv1.back() bool } }
+// { dg-final { whatis-test bv1\[0\] bool } }
+// { dg-final { whatis-test bv1.at(1) bool } }
+
   return 0;  // Mark SPOT
 }