Pretty printers for versioned namespace

Jonathan Wakely jwakely@redhat.com
Thu Dec 15 14:57:00 GMT 2016


On 14/12/16 22:49 +0100, François Dumont wrote:
>On 09/12/2016 16:18, Jonathan Wakely wrote:
>>
>>>But I don't know how to fix this so for the moment I just adapt it 
>>>to correctly handle std::__7::string.
>>
>>But that's not correct. Please try to understand the point I'm making:
>>The name "std::__7::string" does not appear in a symbol name.
>Ok, the only point I don't get yet is why std::string is a symbol but 
>std::__7::string is not. It seems inconsistent.
>
>>
>>This works for me:
>>
>>@@ -946,9 +950,10 @@ class StdExpAnyPrinter(SingleObjContainerPrinter):
>>            m = re.match(rx, func.function.name)
>>            if not m:
>>                raise ValueError("Unknown manager function in %s" % 
>>self.typename)
>>-
>>-            # FIXME need to expand 'std::string' so that 
>>gdb.lookup_type works
>>-            mgrname = re.sub("std::string(?!\w)", 
>>str(gdb.lookup_type('std::string').strip_typedefs()), m.group(1))
>>+            mgrname = m.group(1)
>>+            if not typename.startswith('std::' + vers_nsp):
>>+                # FIXME need to expand 'std::string' so that 
>>gdb.lookup_type works
>>+                mgrname = re.sub("std::string(?!\w)", 
>>str(gdb.lookup_type('std::string').strip_typedefs()), mgrname)
>>
>I think it doesn't work in all situations as this code is also used 
>for std::experimental::any so typename doesn't start with std::__7:: 
>but there is still no std::string symbol.
>
>So I propose:
>
>            mgrname = m.group(1)
>            if 'std::string' in mgrname:
>                # FIXME need to expand 'std::string' so that 
>gdb.lookup_type works
>                mgrname = re.sub("std::string(?!\w)", 
>str(gdb.lookup_type('std::string').strip_typedefs()), m.group(1))
>
>as you will see in attach patch.
>
>I eventually use '__7' explicitely in some pretty printers tests 
>because '__\d+' was not working, don't know.
>
>Ok to commit once tests have completed ?
>
>François
>

>diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
>index 3a111d7..9aba69a 100644
>--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
>+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
>@@ -36,6 +36,8 @@ import sys
> # We probably can't do much about this until this GDB PR is addressed:
> # <https://sourceware.org/bugzilla/show_bug.cgi?id=17138>
> 
>+vers_nsp = '__7::'
>+
> if sys.version_info[0] > 2:
>     ### Python 3 stuff
>     Iterator = object
>@@ -127,9 +129,9 @@ class UniquePointerPrinter:
> 
>     def to_string (self):
>         impl_type = self.val.type.fields()[0].type.tag
>-        if impl_type.startswith('std::__uniq_ptr_impl<'): # New implementation
>+        if re.match('^std::(' + vers_nsp + ')?__uniq_ptr_impl<.*>$', impl_type): # New implementation
>             v = self.val['_M_t']['_M_t']['_M_head_impl']
>-        elif impl_type.startswith('std::tuple<'):
>+        elif re.match('^std::(' + vers_nsp + ')?tuple<.*>$', impl_type):
>             v = self.val['_M_t']['_M_head_impl']
>         else:
>             raise ValueError("Unsupported implementation for unique_ptr: %s" % self.val.type.fields()[0].type.tag)

And we could avoid three re.match expressions with complicated regular
expressions by creating a helper function to do the "startswith"
checks:

def is_specialization_of(type, template_name):
    return re.match('^std::(%s)?%s<.*>$' % (vers_nsp, template_name), type) is not None

Then replace impl_type.startswith('std::__uniq_ptr_impl<') with
is_specialization_of(impl_type, '__uniq_ptr_impl')

And replace impl_type.startswith('std::tuple<') with
is_specialization_of(impl_type, 'tuple')

And replace nodetype.name.startswith('std::_Rb_tree_node') with
is_specialization_of(nodetype.name, '_Rb_tree_node')

That makes the code much easier to read.



More information about the Libstdc++ mailing list