summaryrefslogtreecommitdiff
path: root/libstdc++-v3/python
diff options
context:
space:
mode:
authorredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2016-12-15 12:45:42 +0000
committerredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2016-12-15 12:45:42 +0000
commitac98398ddc2e5156dee3e820ba95116280b999c3 (patch)
treeae1599078d94ec2e2137bc68e7a9105f160f8870 /libstdc++-v3/python
parent543772ad7747d360be1a2a4dda4db06e18e6e00b (diff)
downloadgcc-ac98398ddc2e5156dee3e820ba95116280b999c3.tar.gz
Add GDB XMethods for shared_ptr and unique_ptr<T[]>
* python/libstdcxx/v6/xmethods.py (UniquePtrGetWorker.__init__): Use correct element type for unique_ptr<T[]>. (UniquePtrGetWorker._supports, UniquePtrDerefWorker._supports): New functions to disable unsupported operators for unique_ptr<T[]>. (UniquePtrSubscriptWorker): New worker for operator[]. (UniquePtrMethodsMatcher.__init__): Register UniquePtrSubscriptWorker. (UniquePtrMethodsMatcher.match): Call _supports on the chosen worker. (SharedPtrGetWorker, SharedPtrDerefWorker, SharedPtrSubscriptWorker) (SharedPtrUseCountWorker, SharedPtrUniqueWorker): New workers. (SharedPtrMethodsMatcher): New matcher for shared_ptr. (register_libstdcxx_xmethods): Register SharedPtrMethodsMatcher. * testsuite/libstdc++-xmethods/unique_ptr.cc: Test arrays. * testsuite/libstdc++-xmethods/shared_ptr.cc: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@243688 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/python')
-rw-r--r--libstdc++-v3/python/libstdcxx/v6/xmethods.py162
1 files changed, 160 insertions, 2 deletions
diff --git a/libstdc++-v3/python/libstdcxx/v6/xmethods.py b/libstdc++-v3/python/libstdcxx/v6/xmethods.py
index 045b6617637..1c9bf3ac0f4 100644
--- a/libstdc++-v3/python/libstdcxx/v6/xmethods.py
+++ b/libstdc++-v3/python/libstdcxx/v6/xmethods.py
@@ -565,8 +565,14 @@ class AssociativeContainerMethodsMatcher(gdb.xmethod.XMethodMatcher):
# Xmethods for std::unique_ptr
class UniquePtrGetWorker(gdb.xmethod.XMethodWorker):
+ "Implements std::unique_ptr<T>::get() and std::unique_ptr<T>::operator->()"
+
def __init__(self, elem_type):
- self._elem_type = elem_type
+ self._is_array = elem_type.code == gdb.TYPE_CODE_ARRAY
+ if self._is_array:
+ self._elem_type = elem_type.target()
+ else:
+ self._elem_type = elem_type
def get_arg_types(self):
return None
@@ -574,6 +580,10 @@ class UniquePtrGetWorker(gdb.xmethod.XMethodWorker):
def get_result_type(self, obj):
return self._elem_type.pointer()
+ def _supports(self, method_name):
+ "operator-> is not supported for unique_ptr<T[]>"
+ return method_name == 'get' or not self._is_array
+
def __call__(self, obj):
impl_type = obj.dereference().type.fields()[0].type.tag
if impl_type.startswith('std::__uniq_ptr_impl<'): # New implementation
@@ -583,15 +593,40 @@ class UniquePtrGetWorker(gdb.xmethod.XMethodWorker):
return None
class UniquePtrDerefWorker(UniquePtrGetWorker):
+ "Implements std::unique_ptr<T>::operator*()"
+
def __init__(self, elem_type):
UniquePtrGetWorker.__init__(self, elem_type)
def get_result_type(self, obj):
return self._elem_type
+ def _supports(self, method_name):
+ "operator* is not supported for unique_ptr<T[]>"
+ return not self._is_array
+
def __call__(self, obj):
return UniquePtrGetWorker.__call__(self, obj).dereference()
+class UniquePtrSubscriptWorker(UniquePtrGetWorker):
+ "Implements std::unique_ptr<T>::operator[](size_t)"
+
+ def __init__(self, elem_type):
+ UniquePtrGetWorker.__init__(self, elem_type)
+
+ def get_arg_types(self):
+ return get_std_size_type()
+
+ def get_result_type(self, obj, index):
+ return self._elem_type
+
+ def _supports(self, method_name):
+ "operator[] is only supported for unique_ptr<T[]>"
+ return self._is_array
+
+ def __call__(self, obj, index):
+ return UniquePtrGetWorker.__call__(self, obj)[index]
+
class UniquePtrMethodsMatcher(gdb.xmethod.XMethodMatcher):
def __init__(self):
gdb.xmethod.XMethodMatcher.__init__(self,
@@ -600,6 +635,7 @@ class UniquePtrMethodsMatcher(gdb.xmethod.XMethodMatcher):
'get': LibStdCxxXMethod('get', UniquePtrGetWorker),
'operator->': LibStdCxxXMethod('operator->', UniquePtrGetWorker),
'operator*': LibStdCxxXMethod('operator*', UniquePtrDerefWorker),
+ 'operator[]': LibStdCxxXMethod('operator[]', UniquePtrSubscriptWorker),
}
self.methods = [self._method_dict[m] for m in self._method_dict]
@@ -609,7 +645,128 @@ class UniquePtrMethodsMatcher(gdb.xmethod.XMethodMatcher):
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))
+ worker = method.worker_class(class_type.template_argument(0))
+ if worker._supports(method_name):
+ return worker
+ return None
+
+# Xmethods for std::shared_ptr
+
+class SharedPtrGetWorker(gdb.xmethod.XMethodWorker):
+ "Implements std::shared_ptr<T>::get() and std::shared_ptr<T>::operator->()"
+
+ def __init__(self, elem_type):
+ self._is_array = elem_type.code == gdb.TYPE_CODE_ARRAY
+ if self._is_array:
+ self._elem_type = elem_type.target()
+ else:
+ self._elem_type = elem_type
+
+ def get_arg_types(self):
+ return None
+
+ def get_result_type(self, obj):
+ return self._elem_type.pointer()
+
+ def _supports(self, method_name):
+ "operator-> is not supported for shared_ptr<T[]>"
+ return method_name == 'get' or not self._is_array
+
+ def __call__(self, obj):
+ return obj['_M_ptr']
+
+class SharedPtrDerefWorker(SharedPtrGetWorker):
+ "Implements std::shared_ptr<T>::operator*()"
+
+ def __init__(self, elem_type):
+ SharedPtrGetWorker.__init__(self, elem_type)
+
+ def get_result_type(self, obj):
+ return self._elem_type
+
+ def _supports(self, method_name):
+ "operator* is not supported for shared_ptr<T[]>"
+ return not self._is_array
+
+ def __call__(self, obj):
+ return SharedPtrGetWorker.__call__(self, obj).dereference()
+
+class SharedPtrSubscriptWorker(SharedPtrGetWorker):
+ "Implements std::shared_ptr<T>::operator[](size_t)"
+
+ def __init__(self, elem_type):
+ SharedPtrGetWorker.__init__(self, elem_type)
+
+ def get_arg_types(self):
+ return get_std_size_type()
+
+ def get_result_type(self, obj, index):
+ return self._elem_type
+
+ def _supports(self, method_name):
+ "operator[] is only supported for shared_ptr<T[]>"
+ return self._is_array
+
+ def __call__(self, obj, index):
+ # Check bounds if _elem_type is an array of known bound
+ m = re.match('.*\[(\d+)]$', str(self._elem_type))
+ if m and index >= int(m.group(1)):
+ raise IndexError('shared_ptr<%s> index "%d" should not be >= %d.' %
+ (self._elem_type, int(index), int(m.group(1))))
+ return SharedPtrGetWorker.__call__(self, obj)[index]
+
+class SharedPtrUseCountWorker(gdb.xmethod.XMethodWorker):
+ "Implements std::shared_ptr<T>::use_count()"
+
+ def __init__(self, elem_type):
+ SharedPtrUseCountWorker.__init__(self, elem_type)
+
+ def get_arg_types(self):
+ return None
+
+ def get_result_type(self, obj):
+ return gdb.lookup_type('long')
+
+ def __call__(self, obj):
+ refcounts = ['_M_refcount']['_M_pi']
+ return refcounts['_M_use_count'] if refcounts else 0
+
+class SharedPtrUniqueWorker(SharedPtrUseCountWorker):
+ "Implements std::shared_ptr<T>::unique()"
+
+ def __init__(self, elem_type):
+ SharedPtrUseCountWorker.__init__(self, elem_type)
+
+ def get_result_type(self, obj):
+ return gdb.lookup_type('bool')
+
+ def __call__(self, obj):
+ return SharedPtrUseCountWorker.__call__(self, obj) == 1
+
+class SharedPtrMethodsMatcher(gdb.xmethod.XMethodMatcher):
+ def __init__(self):
+ gdb.xmethod.XMethodMatcher.__init__(self,
+ matcher_name_prefix + 'shared_ptr')
+ self._method_dict = {
+ 'get': LibStdCxxXMethod('get', SharedPtrGetWorker),
+ 'operator->': LibStdCxxXMethod('operator->', SharedPtrGetWorker),
+ 'operator*': LibStdCxxXMethod('operator*', SharedPtrDerefWorker),
+ 'operator[]': LibStdCxxXMethod('operator[]', SharedPtrSubscriptWorker),
+ 'use_count': LibStdCxxXMethod('use_count', SharedPtrUseCountWorker),
+ 'unique': LibStdCxxXMethod('unique', SharedPtrUniqueWorker),
+ }
+ self.methods = [self._method_dict[m] for m in self._method_dict]
+
+ def match(self, class_type, method_name):
+ if not re.match('^std::shared_ptr<.*>$', class_type.tag):
+ return None
+ method = self._method_dict.get(method_name)
+ if method is None or not method.enabled:
+ return None
+ worker = method.worker_class(class_type.template_argument(0))
+ if worker._supports(method_name):
+ return worker
+ return None
def register_libstdcxx_xmethods(locus):
gdb.xmethod.register_xmethod_matcher(locus, ArrayMethodsMatcher())
@@ -634,3 +791,4 @@ def register_libstdcxx_xmethods(locus):
gdb.xmethod.register_xmethod_matcher(
locus, AssociativeContainerMethodsMatcher('unordered_multimap'))
gdb.xmethod.register_xmethod_matcher(locus, UniquePtrMethodsMatcher())
+ gdb.xmethod.register_xmethod_matcher(locus, SharedPtrMethodsMatcher())