diff mbox

Pretty printers for versioned namespace

Message ID e6b7da5e-1c1c-a5fc-0f80-4ee41a862a0d@gmail.com
State New
Headers show

Commit Message

François Dumont Dec. 14, 2016, 9:49 p.m. UTC
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

Comments

Jonathan Wakely Dec. 15, 2016, 11:04 a.m. UTC | #1
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.


The demangler has special handling for std::basic_string<char,
std::char_traits<char>, std::allocator<char>> to treat it as
std::string, because that's much more user-friendly. But when it sees
a different symbol, like foo::basic_string<bar>, or std::__7::... it
doesn't match and doesn't get special handling.

Being consistent doesn't matter, the point is to be user-friendly.

Users want to see std::string, not std::basic_string<char, ..., ...>.

Looking at all the ugly changes needed to the tests, I'm wondering if
we actually want to strip the __7:: namespace out of the typenames
displayed by printers. That would mean we don't need to change the
tests, but more importantly, it would mean the users see "std::vector"
not "std::__7::vector". The versioned namespace is an implementation
detail, not something they write explicitly in their code.

Your change makes the printer tests pass for the versioned namespace,
but does it make the printers useful for users? We want the printers
to be useful, not just pass our testsuite.


>>

>>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.


Ah yes, I forgot about the experimental one.

>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.


Looks good.

>I eventually use '__7' explicitely in some pretty printers tests 

>because '__\d+' was not working, don't know.


Yes, I also found that wasn't working. Presumably Tcl doesn't support
that syntax.

>Ok to commit once tests have completed ?
Jonathan Wakely Dec. 15, 2016, 2:37 p.m. UTC | #2
On 14/12/16 22:49 +0100, François Dumont wrote:
>@@ -1321,7 +1328,7 @@ def register_type_printers(obj):

>     if not _use_type_printing:

>         return

> 

>-    for pfx in ('', 'w'):

>+    for pfx in ('', 'w', vers_nsp, vers_nsp + 'w'):

>         add_one_type_printer(obj, 'basic_string', pfx + 'string')

>         add_one_type_printer(obj, 'basic_string_view', pfx + 'string_view')

>         add_one_type_printer(obj, 'basic_ios', pfx + 'ios')


Looking at this part again, can't we handle the std::__7:: cases
inside add_one_type_printer instead of here?

The "pfx" prefixes here are intended for names that are imilar, like
std::string and std::wstring. If we want to handle both with an
alternative namespace then the place to do that is where we prepend
the namespace, surely?

 def add_one_type_printer(obj, match, name):
     printer = FilteringTypePrinter(match, 'std::' + name)
     gdb.types.register_type_printer(obj, printer)
+    printer = FilteringTypePrinter(match, 'std::__7::' + name)
+    gdb.types.register_type_printer(obj, printer)

That will make the patch *much* smaller, and the logic is easier to
follow.

For the template type printers I think we just want to add (__7::)? to
the regular expressions. If we get a type like

  std::__7::vector<T, std::__7::allocator<T> >

Then I think we want to print that as std::vector<T>, without __7::.
Jonathan Wakely Dec. 15, 2016, 2:57 p.m. UTC | #3
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.
diff mbox

Patch

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)
@@ -485,7 +487,10 @@  class StdRbtreeIteratorPrinter:
     def __init__ (self, typename, val):
         self.val = val
         valtype = self.val.type.template_argument(0).strip_typedefs()
-        nodetype = gdb.lookup_type('std::_Rb_tree_node<' + str(valtype) + '>')
+        if typename.startswith('std::' + vers_nsp):
+            nodetype = gdb.lookup_type('std::' + vers_nsp + '_Rb_tree_node<' + str(valtype) + '>')
+        else:
+            nodetype = gdb.lookup_type('std::_Rb_tree_node<' + str(valtype) + '>')
         self.link_type = nodetype.strip_typedefs().pointer()
 
     def to_string (self):
@@ -937,7 +942,6 @@  class SingleObjContainerPrinter(object):
             return self.visualizer.display_hint ()
         return self.hint
 
-
 class StdExpAnyPrinter(SingleObjContainerPrinter):
     "Print a std::any or std::experimental::any"
 
@@ -957,8 +961,11 @@  class StdExpAnyPrinter(SingleObjContainerPrinter):
             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 '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))
+
             mgrtype = gdb.lookup_type(mgrname)
             self.contained_type = mgrtype.template_argument(0)
             valptr = None
@@ -1041,7 +1048,7 @@  class StdNodeHandlePrinter(SingleObjContainerPrinter):
     def __init__(self, typename, val):
         self.value_type = val.type.template_argument(1)
         nodetype = val.type.template_argument(2).template_argument(0)
-        self.is_rb_tree_node = nodetype.name.startswith('std::_Rb_tree_node')
+        self.is_rb_tree_node = re.match('^std::(' + vers_nsp + ')?_Rb_tree_node.*$', nodetype.name)
         self.is_map_node = val.type.template_argument(0) != self.value_type
         nodeptr = val['_M_ptr']
         if nodeptr:
@@ -1186,7 +1193,7 @@  class Printer(object):
     # Add a name using _GLIBCXX_BEGIN_NAMESPACE_VERSION.
     def add_version(self, base, name, function):
         self.add(base + name, function)
-        self.add(base + '__7::' + name, function)
+        self.add(base + vers_nsp + name, function)
 
     # Add a name using _GLIBCXX_BEGIN_NAMESPACE_CONTAINER.
     def add_container(self, base, name, function):
@@ -1321,7 +1328,7 @@  def register_type_printers(obj):
     if not _use_type_printing:
         return
 
-    for pfx in ('', 'w'):
+    for pfx in ('', 'w', vers_nsp, vers_nsp + 'w'):
         add_one_type_printer(obj, 'basic_string', pfx + 'string')
         add_one_type_printer(obj, 'basic_string_view', pfx + 'string_view')
         add_one_type_printer(obj, 'basic_ios', pfx + 'ios')
@@ -1352,70 +1359,70 @@  def register_type_printers(obj):
         add_one_type_printer(obj, 'regex_token_iterator',
                                  pfx + 'sregex_token_iterator')
 
-    # Note that we can't have a printer for std::wstreampos, because
-    # it shares the same underlying type as std::streampos.
-    add_one_type_printer(obj, 'fpos', 'streampos')
-    add_one_type_printer(obj, 'basic_string', 'u16string')
-    add_one_type_printer(obj, 'basic_string', 'u32string')
-
-    add_one_type_printer(obj, 'basic_string_view', 'u16string_view')
-    add_one_type_printer(obj, 'basic_string_view', 'u32string_view')
-
-    for dur in ('nanoseconds', 'microseconds', 'milliseconds',
-                'seconds', 'minutes', 'hours'):
-        add_one_type_printer(obj, 'duration', dur)
-
-    add_one_type_printer(obj, 'linear_congruential_engine', 'minstd_rand0')
-    add_one_type_printer(obj, 'linear_congruential_engine', 'minstd_rand')
-    add_one_type_printer(obj, 'mersenne_twister_engine', 'mt19937')
-    add_one_type_printer(obj, 'mersenne_twister_engine', 'mt19937_64')
-    add_one_type_printer(obj, 'subtract_with_carry_engine', 'ranlux24_base')
-    add_one_type_printer(obj, 'subtract_with_carry_engine', 'ranlux48_base')
-    add_one_type_printer(obj, 'discard_block_engine', 'ranlux24')
-    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<T>',
-            'unique_ptr<(.*), std::default_delete<\\1 ?> >',
-            'unique_ptr<{1}>')
-
-    add_one_template_type_printer(obj, 'deque<T>',
-            'deque<(.*), std::allocator<\\1 ?> >',
-            'deque<{1}>')
-    add_one_template_type_printer(obj, 'forward_list<T>',
-            'forward_list<(.*), std::allocator<\\1 ?> >',
-            'forward_list<{1}>')
-    add_one_template_type_printer(obj, 'list<T>',
-            'list<(.*), std::allocator<\\1 ?> >',
-            'list<{1}>')
-    add_one_template_type_printer(obj, 'vector<T>',
-            'vector<(.*), std::allocator<\\1 ?> >',
-            'vector<{1}>')
-    add_one_template_type_printer(obj, 'map<Key, T>',
-            'map<(.*), (.*), std::less<\\1 ?>, std::allocator<std::pair<\\1 const, \\2 ?> > >',
-            'map<{1}, {2}>')
-    add_one_template_type_printer(obj, 'multimap<Key, T>',
-            'multimap<(.*), (.*), std::less<\\1 ?>, std::allocator<std::pair<\\1 const, \\2 ?> > >',
-            'multimap<{1}, {2}>')
-    add_one_template_type_printer(obj, 'set<T>',
-            'set<(.*), std::less<\\1 ?>, std::allocator<\\1 ?> >',
-            'set<{1}>')
-    add_one_template_type_printer(obj, 'multiset<T>',
-            'multiset<(.*), std::less<\\1 ?>, std::allocator<\\1 ?> >',
-            'multiset<{1}>')
-    add_one_template_type_printer(obj, 'unordered_map<Key, T>',
-            'unordered_map<(.*), (.*), std::hash<\\1 ?>, std::equal_to<\\1 ?>, std::allocator<std::pair<\\1 const, \\2 ?> > >',
-            'unordered_map<{1}, {2}>')
-    add_one_template_type_printer(obj, 'unordered_multimap<Key, T>',
-            'unordered_multimap<(.*), (.*), std::hash<\\1 ?>, std::equal_to<\\1 ?>, std::allocator<std::pair<\\1 const, \\2 ?> > >',
-            'unordered_multimap<{1}, {2}>')
-    add_one_template_type_printer(obj, 'unordered_set<T>',
-            'unordered_set<(.*), std::hash<\\1 ?>, std::equal_to<\\1 ?>, std::allocator<\\1 ?> >',
-            'unordered_set<{1}>')
-    add_one_template_type_printer(obj, 'unordered_multiset<T>',
-            'unordered_multiset<(.*), std::hash<\\1 ?>, std::equal_to<\\1 ?>, std::allocator<\\1 ?> >',
-            'unordered_multiset<{1}>')
+    for vers in ('', vers_nsp):
+        # Note that we can't have a printer for std::wstreampos, because
+        # it shares the same underlying type as std::streampos.
+        add_one_type_printer(obj, 'fpos', vers + 'streampos')
+        add_one_type_printer(obj, 'basic_string', vers + 'u16string')
+        add_one_type_printer(obj, 'basic_string', vers + 'u32string')
+        add_one_type_printer(obj, 'basic_string_view', 'u16string_view')
+        add_one_type_printer(obj, 'basic_string_view', 'u32string_view')
+
+        for dur in ('nanoseconds', 'microseconds', 'milliseconds',
+                    'seconds', 'minutes', 'hours'):
+            add_one_type_printer(obj, 'duration', vers + dur)
+
+        add_one_type_printer(obj, 'linear_congruential_engine', vers + 'minstd_rand0')
+        add_one_type_printer(obj, 'linear_congruential_engine', vers + 'minstd_rand')
+        add_one_type_printer(obj, 'mersenne_twister_engine', vers + 'mt19937')
+        add_one_type_printer(obj, 'mersenne_twister_engine', vers + 'mt19937_64')
+        add_one_type_printer(obj, 'subtract_with_carry_engine', vers + 'ranlux24_base')
+        add_one_type_printer(obj, 'subtract_with_carry_engine', vers + 'ranlux48_base')
+        add_one_type_printer(obj, 'discard_block_engine', vers + 'ranlux24')
+        add_one_type_printer(obj, 'discard_block_engine', vers + 'ranlux48')
+        add_one_type_printer(obj, 'shuffle_order_engine', vers + 'knuth_b')
+
+        # Do not show defaulted template arguments in class templates
+        add_one_template_type_printer(obj, 'unique_ptr<T>',
+            '{0}unique_ptr<(.*), std::{0}default_delete<\\1 ?> >'.format(vers),
+            '%sunique_ptr<{1}>' % vers)
+
+        add_one_template_type_printer(obj, 'deque<T>',
+            '{0}deque<(.*), std::{0}allocator<\\1 ?> >'.format(vers),
+            '%sdeque<{1}>' % vers)
+        add_one_template_type_printer(obj, 'forward_list<T>',
+            '{0}forward_list<(.*), std::{0}allocator<\\1 ?> >'.format(vers),
+            '%sforward_list<{1}>' % vers)
+        add_one_template_type_printer(obj, 'list<T>',
+            '{0}list<(.*), std::{0}allocator<\\1 ?> >'.format(vers),
+            '%slist<{1}>' % vers)
+        add_one_template_type_printer(obj, 'vector<T>',
+            '{0}vector<(.*), std::{0}allocator<\\1 ?> >'.format(vers),
+            '%svector<{1}>' % vers)
+        add_one_template_type_printer(obj, 'map<Key, T>',
+            '{0}map<(.*), (.*), std::{0}less<\\1 ?>, std::{0}allocator<std::{0}pair<\\1 const, \\2 ?> > >'.format(vers),
+            '%smap<{1}, {2}>' % vers)
+        add_one_template_type_printer(obj, 'multimap<Key, T>',
+            '{0}multimap<(.*), (.*), std::{0}less<\\1 ?>, std::{0}allocator<std::{0}pair<\\1 const, \\2 ?> > >'.format(vers),
+            '%smultimap<{1}, {2}>' % vers)
+        add_one_template_type_printer(obj, 'set<T>',
+            '{0}set<(.*), std::{0}less<\\1 ?>, std::{0}allocator<\\1 ?> >'.format(vers),
+            '%sset<{1}>' % vers)
+        add_one_template_type_printer(obj, 'multiset<T>',
+            '{0}multiset<(.*), std::{0}less<\\1 ?>, std::{0}allocator<\\1 ?> >'.format(vers),
+            '%smultiset<{1}>' % vers)
+        add_one_template_type_printer(obj, 'unordered_map<Key, T>',
+            '{0}unordered_map<(.*), (.*), std::{0}hash<\\1 ?>, std::{0}equal_to<\\1 ?>, std::{0}allocator<std::{0}pair<\\1 const, \\2 ?> > >'.format(vers),
+            '%sunordered_map<{1}, {2}>' % vers)
+        add_one_template_type_printer(obj, 'unordered_multimap<Key, T>',
+            '{0}unordered_multimap<(.*), (.*), std::{0}hash<\\1 ?>, std::{0}equal_to<\\1 ?>, std::{0}allocator<std::{0}pair<\\1 const, \\2 ?> > >'.format(vers),
+            '%sunordered_multimap<{1}, {2}>' % vers)
+        add_one_template_type_printer(obj, 'unordered_set<T>',
+            '{0}unordered_set<(.*), std::{0}hash<\\1 ?>, std::{0}equal_to<\\1 ?>, std::{0}allocator<\\1 ?> >'.format(vers),
+            '%sunordered_set<{1}>' % vers)
+        add_one_template_type_printer(obj, 'unordered_multiset<T>',
+            '{0}unordered_multiset<(.*), std::{0}hash<\\1 ?>, std::{0}equal_to<\\1 ?>, std::{0}allocator<\\1 ?> >'.format(vers),
+            '%sunordered_multiset<{1}>' % vers)
 
     # strip the "fundamentals_v1" inline namespace from these types
     add_one_template_type_printer(obj, 'any<T>',
@@ -1449,7 +1456,7 @@  def build_libstdcxx_dictionary ():
     libstdcxx_printer = Printer("libstdc++-v6")
 
     # For _GLIBCXX_BEGIN_NAMESPACE_VERSION.
-    vers = '(__7::)?'
+    vers = '(' + vers_nsp + ')?'
     # For _GLIBCXX_BEGIN_NAMESPACE_CONTAINER.
     container = '(__cxx1998::' + vers + ')?'
 
diff --git a/libstdc++-v3/python/libstdcxx/v6/xmethods.py b/libstdc++-v3/python/libstdcxx/v6/xmethods.py
index 045b661..4d58663 100644
--- a/libstdc++-v3/python/libstdcxx/v6/xmethods.py
+++ b/libstdc++-v3/python/libstdcxx/v6/xmethods.py
@@ -148,7 +148,7 @@  class ArrayMethodsMatcher(gdb.xmethod.XMethodMatcher):
         self.methods = [self._method_dict[m] for m in self._method_dict]
 
     def match(self, class_type, method_name):
-        if not re.match('^std::array<.*>$', class_type.tag):
+        if not re.match('^std::(__\d+::)?array<.*>$', class_type.tag):
             return None
         method = self._method_dict.get(method_name)
         if method is None or not method.enabled:
@@ -265,7 +265,7 @@  class DequeMethodsMatcher(gdb.xmethod.XMethodMatcher):
         self.methods = [self._method_dict[m] for m in self._method_dict]
 
     def match(self, class_type, method_name):
-        if not re.match('^std::deque<.*>$', class_type.tag):
+        if not re.match('^std::(__\d+::)?deque<.*>$', class_type.tag):
             return None
         method = self._method_dict.get(method_name)
         if method is None or not method.enabled:
@@ -309,7 +309,7 @@  class ForwardListMethodsMatcher(gdb.xmethod.XMethodMatcher):
         self.methods = [self._method_dict[m] for m in self._method_dict]
 
     def match(self, class_type, method_name):
-        if not re.match('^std::forward_list<.*>$', class_type.tag):
+        if not re.match('^std::(__\d+::)?forward_list<.*>$', class_type.tag):
             return None
         method = self._method_dict.get(method_name)
         if method is None or not method.enabled:
@@ -390,7 +390,7 @@  class ListMethodsMatcher(gdb.xmethod.XMethodMatcher):
         self.methods = [self._method_dict[m] for m in self._method_dict]
 
     def match(self, class_type, method_name):
-        if not re.match('^std::(__cxx11::)?list<.*>$', class_type.tag):
+        if not re.match('^std::(__\d+::)?(__cxx11::)?list<.*>$', class_type.tag):
             return None
         method = self._method_dict.get(method_name)
         if method is None or not method.enabled:
@@ -505,7 +505,7 @@  class VectorMethodsMatcher(gdb.xmethod.XMethodMatcher):
         self.methods = [self._method_dict[m] for m in self._method_dict]
 
     def match(self, class_type, method_name):
-        if not re.match('^std::vector<.*>$', class_type.tag):
+        if not re.match('^std::(__\d+::)?vector<.*>$', class_type.tag):
             return None
         method = self._method_dict.get(method_name)
         if method is None or not method.enabled:
@@ -554,7 +554,7 @@  class AssociativeContainerMethodsMatcher(gdb.xmethod.XMethodMatcher):
         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):
+        if not re.match('^std::(__\d+::)?%s<.*>$' % self._name, class_type.tag):
             return None
         method = self._method_dict.get(method_name)
         if method is None or not method.enabled:
@@ -576,9 +576,9 @@  class UniquePtrGetWorker(gdb.xmethod.XMethodWorker):
 
     def __call__(self, obj):
         impl_type = obj.dereference().type.fields()[0].type.tag
-        if impl_type.startswith('std::__uniq_ptr_impl<'): # New implementation
+        if re.match('^std::(__\d+::)?__uniq_ptr_impl<.*>$', impl_type): # New implementation
             return obj['_M_t']['_M_t']['_M_head_impl']
-        elif impl_type.startswith('std::tuple<'):
+        elif re.match('^std::(__\d+::)?tuple<.*>$', impl_type):
             return obj['_M_t']['_M_head_impl']
         return None
 
@@ -604,7 +604,7 @@  class UniquePtrMethodsMatcher(gdb.xmethod.XMethodMatcher):
         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):
+        if not re.match('^std::(__\d+::)?unique_ptr<.*>$', class_type.tag):
             return None
         method = self._method_dict.get(method_name)
         if method is None or not method.enabled:
diff --git a/libstdc++-v3/testsuite/lib/gdb-test.exp b/libstdc++-v3/testsuite/lib/gdb-test.exp
index 3ebbf6b..5e1bdf7 100644
--- a/libstdc++-v3/testsuite/lib/gdb-test.exp
+++ b/libstdc++-v3/testsuite/lib/gdb-test.exp
@@ -74,6 +74,14 @@  proc whatis-test {var result} {
     lappend gdb_tests $var $result whatis
 }
 
+# A test of 'whatis'.  This tests a type rather than a variable through a
+# regular expression.
+proc whatis-regexp-test {var result} {
+    global gdb_tests
+
+    lappend gdb_tests $var $result whatis_regexp
+}
+
 # Utility for testing variable values using gdb, invoked via dg-final.
 # Tests all tests indicated by note-test and regexp-test.
 #
@@ -140,10 +148,15 @@  proc gdb-test { marker {selector {}} {load_xmethods 0} } {
 	incr count
 	set gdb_var($count) $var
 	set gdb_expected($count) $result
-	if {$kind == "whatis"} {
+	if {$kind == "whatis" || $kind == "whatis_regexp"} {
 	    if {$do_whatis_tests} {
 		set gdb_is_type($count) 1
 		set gdb_command($count) "whatis $var"
+		if {$kind == "whatis"} {
+		    set gdb_is_regexp($count) 0
+		} else {
+		    set gdb_is_regexp($count) 1
+		}
 	    } else {
 	        unsupported "$testname"
 	        close $fd
@@ -179,13 +192,13 @@  proc gdb-test { marker {selector {}} {load_xmethods 0} } {
 		if {$expect_out(1,string) != "type"} {
 		    error "gdb failure"
 		}
-		set match [expr {![string compare $first \
-				     $gdb_expected($test_counter)]}]
-	    } elseif {$gdb_is_regexp($test_counter)} {
+	    }
+
+	    if {$gdb_is_regexp($test_counter)} {
 		set match [regexp -- $gdb_expected($test_counter) $first]
 	    } else {
 		set match [expr {![string compare $first \
-				     $gdb_expected($test_counter)]}]
+				       $gdb_expected($test_counter)]}]
 	    }
 
 	    if {$match} {
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
index e02997a..2c2d07e 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
@@ -63,77 +63,77 @@  int
 main()
 {
   std::forward_list<int> efl;
-// { dg-final { note-test efl "empty std::forward_list" } }
+// { dg-final { regexp-test efl "empty std::(__7::)?forward_list" } }
 
   std::forward_list<int> &refl = efl;
-// { dg-final { note-test refl "empty std::forward_list" } }
+// { dg-final { regexp-test refl "empty std::(__7::)?forward_list" } }
 
   std::forward_list<int> fl;
   fl.push_front(2);
   fl.push_front(1);
-// { dg-final { note-test fl {std::forward_list = {[0] = 1, [1] = 2}} } }
+// { dg-final { regexp-test fl {std::(__7::)?forward_list = {\[0\] = 1, \[1\] = 2}} } }
 
   std::forward_list<int> &rfl = fl;
-// { dg-final { note-test rfl {std::forward_list = {[0] = 1, [1] = 2}} } }
+// { dg-final { regexp-test rfl {std::(__7::)?forward_list = {\[0\] = 1, \[1\] = 2}} } }
 
   std::unordered_map<int, std::string> eum;
-// { dg-final { note-test eum "std::unordered_map with 0 elements" } }
+// { dg-final { regexp-test eum "std::(__7::)?unordered_map with 0 elements" } }
   std::unordered_map<int, std::string> &reum = eum;
-// { dg-final { note-test reum "std::unordered_map with 0 elements" } }
+// { dg-final { regexp-test reum "std::(__7::)?unordered_map with 0 elements" } }
 
   std::unordered_multimap<int, std::string> eumm;
-// { dg-final { note-test eumm "std::unordered_multimap with 0 elements" } }
+// { dg-final { regexp-test eumm "std::(__7::)?unordered_multimap with 0 elements" } }
   std::unordered_multimap<int, std::string> &reumm = eumm;
-// { dg-final { note-test reumm "std::unordered_multimap with 0 elements" } }
+// { dg-final { regexp-test reumm "std::(__7::)?unordered_multimap with 0 elements" } }
 
   std::unordered_set<int> eus;
-// { dg-final { note-test eus "std::unordered_set with 0 elements" } }
+// { dg-final { regexp-test eus "std::(__7::)?unordered_set with 0 elements" } }
   std::unordered_set<int> &reus = eus;
-// { dg-final { note-test reus "std::unordered_set with 0 elements" } }
+// { dg-final { regexp-test reus "std::(__7::)?unordered_set with 0 elements" } }
 
   std::unordered_multiset<int> eums;
-// { dg-final { note-test eums "std::unordered_multiset with 0 elements" } }
+// { dg-final { regexp-test eums "std::(__7::)?unordered_multiset with 0 elements" } }
   std::unordered_multiset<int> &reums = eums;
-// { dg-final { note-test reums "std::unordered_multiset with 0 elements" } }
+// { dg-final { regexp-test reums "std::(__7::)?unordered_multiset with 0 elements" } }
 
   std::unordered_map<int, std::string> uom;
   uom[5] = "three";
   uom[3] = "seven";
-// { dg-final { note-test uom {std::unordered_map with 2 elements = {[3] = "seven", [5] = "three"}} } }
+// { dg-final { regexp-test uom {std::(__7::)?unordered_map with 2 elements = {\[3\] = "seven", \[5\] = "three"}} } }
 
   std::unordered_map<int, std::string> &ruom = uom;
-// { dg-final { note-test ruom {std::unordered_map with 2 elements = {[3] = "seven", [5] = "three"}} } }
+// { dg-final { regexp-test ruom {std::(__7::)?unordered_map with 2 elements = {\[3\] = "seven", \[5\] = "three"}} } }
 
   std::unordered_multimap<int, std::string> uomm;
   uomm.insert(std::pair<int, std::string> (5, "three"));
   uomm.insert(std::pair<int, std::string> (5, "seven"));
-// { dg-final { note-test uomm {std::unordered_multimap with 2 elements = {[5] = "seven", [5] = "three"}} } }
+// { dg-final { regexp-test uomm {std::(__7::)?unordered_multimap with 2 elements = {\[5\] = "seven", \[5\] = "three"}} } }
   std::unordered_multimap<int, std::string> &ruomm = uomm;
-// { dg-final { note-test ruomm {std::unordered_multimap with 2 elements = {[5] = "seven", [5] = "three"}} } }
+// { dg-final { regexp-test ruomm {std::(__7::)?unordered_multimap with 2 elements = {\[5\] = "seven", \[5\] = "three"}} } }
 
   std::unordered_set<int> uos;
   uos.insert(5);
-// { dg-final { note-test uos {std::unordered_set with 1 element = {[0] = 5}} } }
+// { dg-final { regexp-test uos {std::(__7::)?unordered_set with 1 element = {\[0\] = 5}} } }
   std::unordered_set<int> &ruos = uos;
-// { dg-final { note-test ruos {std::unordered_set with 1 element = {[0] = 5}} } }
+// { dg-final { regexp-test ruos {std::(__7::)?unordered_set with 1 element = {\[0\] = 5}} } }
 
   std::unordered_multiset<int> uoms;
   uoms.insert(5);
-// { dg-final { note-test uoms {std::unordered_multiset with 1 element = {[0] = 5}} } }
+// { dg-final { regexp-test uoms {std::(__7::)?unordered_multiset with 1 element = {\[0\] = 5}} } }
   std::unordered_multiset<int> &ruoms = uoms;
-// { dg-final { note-test ruoms {std::unordered_multiset with 1 element = {[0] = 5}} } }
+// { dg-final { regexp-test ruoms {std::(__7::)?unordered_multiset with 1 element = {\[0\] = 5}} } }
 
   std::unique_ptr<datum> uptr (new datum);
   uptr->s = "hi bob";
   uptr->i = 23;
-// { dg-final { regexp-test uptr {std::unique_ptr.datum. containing 0x.*} } }
+// { dg-final { regexp-test uptr {std::(__7::)?unique_ptr.datum. containing 0x.*} } }
   std::unique_ptr<datum> &ruptr = uptr;
-// { dg-final { regexp-test ruptr {std::unique_ptr.datum. containing 0x.*} } }
+// { dg-final { regexp-test ruptr {std::(__7::)?unique_ptr.datum. containing 0x.*} } }
 
   ExTuple tpl(6,7);
-// { dg-final { note-test tpl {std::tuple containing = {[1] = 6, [2] = 7}} } }  
+// { dg-final { regexp-test tpl {std::(__7::)?tuple containing = {\[1\] = 6, \[2\] = 7}} } }
   ExTuple &rtpl = tpl;
-// { dg-final { note-test rtpl {std::tuple containing = {[1] = 6, [2] = 7}} } }   
+// { dg-final { regexp-test rtpl {std::(__7::)?tuple containing = {\[1\] = 6, \[2\] = 7}} } }
   placeholder(""); // Mark SPOT
   use(efl);
   use(fl);
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc
index 69c16c1..bc72893 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc
@@ -44,48 +44,48 @@  main()
 // { dg-final { note-test str "\"string\"" } }
 
   optional<int> o;
-// { dg-final { note-test o {std::optional<int> [no contained value]} } }
+// { dg-final { regexp-test o {std::(__\d+::)?optional<int> \[no contained value\]} } }
   optional<bool> ob{false};
-// { dg-final { note-test ob {std::optional<bool> = {[contained value] = false}} } }
+// { dg-final { regexp-test ob {std::(__\d+::)?optional<bool> = {\[contained value\] = false}} } }
   optional<int> oi{5};
-// { dg-final { note-test oi {std::optional<int> = {[contained value] = 5}} } }
+// { dg-final { regexp-test oi {std::(__\d+::)?optional<int> = {\[contained value\] = 5}} } }
   optional<void*> op{nullptr};
-// { dg-final { note-test op {std::optional<void *> = {[contained value] = 0x0}} } }
+// { dg-final { regexp-test op {std::(__\d+::)?optional<void \*> = {\[contained value\] = 0x0}} } }
   optional<std::map<int, double>> om;
   om = std::map<int, double>{ {1, 2.}, {3, 4.}, {5, 6.} };
-// { dg-final { note-test om {std::optional<std::map<int, double>> containing std::map with 3 elements = {[1] = 2, [3] = 4, [5] = 6}} } }
+// { dg-final { regexp-test om {std::(__\d+::)?optional<std::(__\d+::)?map<int, double>> containing std::(__\d+::)?map with 3 elements = {\[1\] = 2, \[3\] = 4, \[5\] = 6}} } }
   optional<std::string> os{ "stringy" };
-// { dg-final { note-test os {std::optional<std::string> = {[contained value] = "stringy"}} } }
+// { dg-final { regexp-test os {std::(__\d+::)?optional<std::(__\d+::)?string> = {\[contained value\] = "stringy"}} } }
 
   any a;
-// { dg-final { note-test a {std::any [no contained value]} } }
+// { dg-final { regexp-test a {std::(__\d+::)?any \[no contained value\]} } }
   any ab(false);
-// { dg-final { note-test ab {std::any containing bool = {[contained value] = false}} } }
+// { dg-final { regexp-test ab {std::(__\d+::)?any containing bool = {\[contained value\] = false}} } }
   any ai(6);
-// { dg-final { note-test ai {std::any containing int = {[contained value] = 6}} } }
+// { dg-final { regexp-test ai {std::(__\d+::)?any containing int = {\[contained value\] = 6}} } }
   any ap = (void*)nullptr;
-// { dg-final { note-test ap {std::any containing void * = {[contained value] = 0x0}} } }
+// { dg-final { regexp-test ap {std::(__\d+::)?any containing void \* = {\[contained value\] = 0x0}} } }
   any as = *os;
-// { dg-final { note-test as {std::any containing std::string = {[contained value] = "stringy"}} } }
+// { dg-final { regexp-test as {std::(__\d+::)?any containing std::(__\d+::)?string = {\[contained value\] = "stringy"}} } }
   any as2("stringiest");
-// { dg-final { regexp-test as2 {std::any containing const char \* = {\[contained value\] = 0x[[:xdigit:]]+ "stringiest"}} } }
+// { dg-final { regexp-test as2 {std::(__\d+::)?any containing const char \* = {\[contained value\] = 0x[[:xdigit:]]+ "stringiest"}} } }
   any am = *om;
-// { dg-final { note-test am {std::any containing std::map with 3 elements = {[1] = 2, [3] = 4, [5] = 6}} } }
+// { dg-final { regexp-test am {std::(__\d+::)?any containing std::(__\d+::)?map with 3 elements = {\[1\] = 2, \[3\] = 4, \[5\] = 6}} } }
 
   struct S { operator int() { throw 42; }};
   variant<float, int, string_view> v0;
-// { dg-final { note-test v0 {std::variant<float, int, std::string_view> [index 0] = {0}} } }
+// { dg-final { regexp-test v0 {std::(__\d+::)?variant<float, int, std::(__\d+::)?string_view> \[index 0\] = {0}} } }
   variant<float, int, string_view> v1{ 0.5f };
-// { dg-final { note-test v1 {std::variant<float, int, std::string_view> [index 0] = {0.5}} } }
+// { dg-final { regexp-test v1 {std::(__\d+::)?variant<float, int, std::(__\d+::)?string_view> \[index 0\] = [{]0.5[}]} } }
   variant<float, int, string_view> v2;
   try {
     v2.emplace<1>(S());
   } catch (int) { }
-// { dg-final { note-test v2 {std::variant<float, int, std::string_view> [no contained value]} } }
+// { dg-final { regexp-test v2 {std::(__\d+::)?variant<float, int, std::(__\d+::)?string_view> \[no contained value\]} } }
   variant<float, int, string_view> v3{ 3 };
-// { dg-final { note-test v3 {std::variant<float, int, std::string_view> [index 1] = {3}} } }
+// { dg-final { regexp-test v3 {std::(__\d+::)?variant<float, int, std::(__\d+::)?string_view> \[index 1\] = [{]3[}]} } }
   variant<float, int, string_view> v4{ str };
-// { dg-final { note-test v4 {std::variant<float, int, std::string_view> [index 2] = {"string"}} } }
+// { dg-final { regexp-test v4 {std::(__\d+::)?variant<float, int, std::(__\d+::)?string_view> \[index 2\] = {"string"}} } }
 
   map<int, string_view> m{ {1, "one"} };
   map<int, string_view>::node_type n0;
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc
index 534c55f..774c708 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc
@@ -39,33 +39,33 @@  main()
 // { dg-final { note-test str "\"string\"" } }
 
   optional<int> o;
-// { dg-final { note-test o {std::experimental::optional<int> [no contained value]} } }
+// { dg-final { regexp-test o {std::experimental::(__\d+::)?optional<int> \[no contained value\]} } }
   optional<bool> ob{false};
-// { dg-final { note-test ob {std::experimental::optional<bool> = {[contained value] = false}} } }
+// { dg-final { regexp-test ob {std::experimental::(__\d+::)?optional<bool> = {\[contained value\] = false}} } }
   optional<int> oi{5};
-// { dg-final { note-test oi {std::experimental::optional<int> = {[contained value] = 5}} } }
+// { dg-final { regexp-test oi {std::experimental::(__\d+::)?optional<int> = {\[contained value\] = 5}} } }
   optional<void*> op{nullptr};
-// { dg-final { note-test op {std::experimental::optional<void *> = {[contained value] = 0x0}} } }
+// { dg-final { regexp-test op {std::experimental::(__\d+::)?optional<void \*> = {\[contained value\] = 0x0}} } }
   optional<std::map<int, double>> om;
   om = std::map<int, double>{ {1, 2.}, {3, 4.}, {5, 6.} };
-// { dg-final { note-test om {std::experimental::optional<std::map<int, double>> containing std::map with 3 elements = {[1] = 2, [3] = 4, [5] = 6}} } }
+// { dg-final { regexp-test om {std::experimental::(__\d+::)?optional<std::(__\d+::)?map<int, double>> containing std::(__\d+::)?map with 3 elements = {\[1\] = 2, \[3\] = 4, \[5\] = 6}} } }
   optional<std::string> os{ "stringy" };
-// { dg-final { note-test os {std::experimental::optional<std::string> = {[contained value] = "stringy"}} } }
+// { dg-final { regexp-test os {std::experimental::(__\d+::)?optional<std::(__\d+::)?string> = {\[contained value\] = "stringy"}} } }
 
   any a;
-// { dg-final { note-test a {std::experimental::any [no contained value]} } }
+// { dg-final { regexp-test a {std::experimental::(__\d+::)?any \[no contained value\]} } }
   any ab(false);
-// { dg-final { note-test ab {std::experimental::any containing bool = {[contained value] = false}} } }
+// { dg-final { regexp-test ab {std::experimental::(__\d+::)?any containing bool = {\[contained value\] = false}} } }
   any ai(6);
-// { dg-final { note-test ai {std::experimental::any containing int = {[contained value] = 6}} } }
+// { dg-final { regexp-test ai {std::experimental::(__\d+::)?any containing int = {\[contained value\] = 6}} } }
   any ap = (void*)nullptr;
-// { dg-final { note-test ap {std::experimental::any containing void * = {[contained value] = 0x0}} } }
+// { dg-final { regexp-test ap {std::experimental::(__\d+::)?any containing void \* = {\[contained value\] = 0x0}} } }
   any as = *os;
-// { dg-final { note-test as {std::experimental::any containing std::string = {[contained value] = "stringy"}} } }
+// { dg-final { regexp-test as {std::experimental::(__\d+::)?any containing std::(__\d+::)?string = {\[contained value\] = "stringy"}} } }
   any as2("stringiest");
-// { dg-final { regexp-test as2 {std::experimental::any containing const char \* = {\[contained value\] = 0x[[:xdigit:]]+ "stringiest"}} } }
+// { dg-final { regexp-test as2 {std::experimental::(__\d+::)?any containing const char \* = {\[contained value\] = 0x[[:xdigit:]]+ "stringiest"}} } }
   any am = *om;
-// { dg-final { note-test am {std::experimental::any containing std::map with 3 elements = {[1] = 2, [3] = 4, [5] = 6}} } }
+// { dg-final { regexp-test am {std::experimental::(__\d+::)?any containing std::(__\d+::)?map with 3 elements = {\[1\] = 2, \[3\] = 4, \[5\] = 6}} } }
 
   std::cout << "\n";
   return 0;			// Mark SPOT
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/shared_ptr.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/shared_ptr.cc
index 9528860..4e0e8c7 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/shared_ptr.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/shared_ptr.cc
@@ -49,25 +49,25 @@  main()
   typedef std::weak_ptr<int> weak;
 
   shared esp;
-// { dg-final { note-test esp "std::shared_ptr (empty) 0x0" } }
+// { dg-final { regexp-test esp {std::(__\d+::)?shared_ptr \(empty\) 0x0} } }
   weak ewp1;
-// { dg-final { note-test ewp1 "std::weak_ptr (empty) 0x0" } }
+// { dg-final { regexp-test ewp1 {std::(__\d+::)?weak_ptr \(empty\) 0x0} } }
   weak ewp2 = esp;
-// { dg-final { note-test ewp2 "std::weak_ptr (empty) 0x0" } }
+// { dg-final { regexp-test ewp2 {std::(__\d+::)?weak_ptr \(empty\) 0x0} } }
 
   shared sp1 = make(0x12345678);
   shared sp2 = sp1;
-// { dg-final { note-test sp1 "std::shared_ptr (count 2, weak 0) 0x12345678" } }
+// { dg-final { regexp-test sp1 {std::(__\d+::)?shared_ptr \(count 2, weak 0\) 0x12345678} } }
 
   shared sp3 = make(0x12344321);
   weak sp4 = sp3;
   weak wp1 = sp3;
-// { dg-final { note-test wp1 "std::weak_ptr (count 1, weak 2) 0x12344321" } }
+// { dg-final { regexp-test wp1 {std::(__\d+::)?weak_ptr \(count 1, weak 2\) 0x12344321} } }
 
   shared sp5 = make(0x56788765);
   weak wp2 = sp5;
   sp5.reset();
-// { dg-final { note-test wp2 "std::weak_ptr (expired, weak 1) 0x56788765" } }
+// { dg-final { regexp-test wp2 {std::(__\d+::)?weak_ptr \(expired, weak 1\) 0x56788765} } }
 
   placeholder(""); // Mark SPOT
   use(esp);
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc
index fb8e0d7..09bbbf4 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc
@@ -43,12 +43,12 @@  main()
   bs[0] = 1;
   bs[5] = 1;
   bs[7] = 1;
-// { dg-final { note-test bs {std::bitset = {[0] = 1, [5] = 1, [7] = 1}} } }
+// { dg-final { regexp-test bs {std::(__\d+::)?bitset = {\[0\] = 1, \[5\] = 1, \[7\] = 1}} } }
 
   std::deque<std::string> deq;
   deq.push_back("one");
   deq.push_back("two");
-// { dg-final { note-test deq {std::deque with 2 elements = {"one", "two"}} } }
+// { dg-final { regexp-test deq {std::(__\d+::)?deque with 2 elements = {"one", "two"}} } }
 
   std::deque<std::string>::iterator deqiter = deq.begin();
 // { dg-final { note-test deqiter {"one"} } }
@@ -56,7 +56,7 @@  main()
   std::list<std::string> lst;
   lst.push_back("one");
   lst.push_back("two");
-// { dg-final { note-test lst {std::list = {[0] = "one", [1] = "two"}} } }
+// { dg-final { regexp-test lst {std::(__\d+::)?list = {\[0\] = "one", \[1\] = "two"}} } }
 
   std::list<std::string>::iterator lstiter = lst.begin();
   tem = *lstiter;
@@ -68,7 +68,7 @@  main()
 
   std::map<std::string, int> mp;
   mp["zardoz"] = 23;
-// { dg-final { note-test mp {std::map with 1 element = {["zardoz"] = 23}} } }
+// { dg-final { regexp-test mp {std::(__\d+::)?map with 1 element = {\["zardoz"\] = 23}} } }
 
   std::map<std::string, int>::iterator mpiter = mp.begin();
 // { dg-final { note-test mpiter {{first = "zardoz", second = 23}} } }
@@ -78,12 +78,12 @@  main()
   intset.insert(2);
   intset.insert(3);
   const std::set<int> const_intset = intset;
-// { dg-final { note-test const_intset {std::set with 2 elements = {[0] = 2, [1] = 3}} } }
+// { dg-final { regexp-test const_intset {std::(__\d+::)?set with 2 elements = {\[0\] = 2, \[1\] = 3}} } }
 
   std::set<std::string> sp;
   sp.insert("clownfish");
   sp.insert("barrel");
-// { dg-final { note-test sp {std::set with 2 elements = {[0] = "barrel", [1] = "clownfish"}} } }
+// { dg-final { regexp-test sp {std::(__\d+::)?set with 2 elements = {\[0\] = "barrel", \[1\] = "clownfish"}} } }
 
   std::set<std::string>::const_iterator spciter = sp.begin();
 // { dg-final { note-test spciter {"barrel"} } }
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc
index 9e230e3..1e5d922 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc
@@ -43,12 +43,12 @@  main()
   bs[0] = 1;
   bs[5] = 1;
   bs[7] = 1;
-// { dg-final { note-test bs {std::bitset = {[0] = 1, [5] = 1, [7] = 1}} } }
+// { dg-final { regexp-test bs {std::(__\d+::)?bitset = {\[0\] = 1, \[5\] = 1, \[7\] = 1}} } }
 
   std::deque<std::string> deq;
   deq.push_back("one");
   deq.push_back("two");
-// { dg-final { note-test deq {std::deque with 2 elements = {"one", "two"}} } }
+// { dg-final { regexp-test deq {std::(__\d+::)?deque with 2 elements = {"one", "two"}} } }
 
   std::deque<std::string>::iterator deqiter = deq.begin();
 // { dg-final { note-test deqiter {"one"} } }
@@ -56,7 +56,7 @@  main()
   std::list<std::string> lst;
   lst.push_back("one");
   lst.push_back("two");
-// { dg-final { note-test lst {std::list = {[0] = "one", [1] = "two"}} } }
+// { dg-final { regexp-test lst {std::(__\d+::)?list = {\[0\] = "one", \[1\] = "two"}} } }
 
   std::list<std::string>::iterator lstiter = lst.begin();
   tem = *lstiter;
@@ -68,19 +68,19 @@  main()
 
   std::map<std::string, int> mp;
   mp["zardoz"] = 23;
-// { dg-final { note-test mp {std::map with 1 element = {["zardoz"] = 23}} } }
+// { dg-final { regexp-test mp {std::(__\d+::)?map with 1 element = {\["zardoz"\] = 23}} } }
 
   std::map<std::string, int>::iterator mpiter = mp.begin();
 // { dg-final { note-test mpiter {{first = "zardoz", second = 23}} } }
 
   // PR 67440
   const std::set<int> const_intset = {2, 3};
-// { dg-final { note-test const_intset {std::set with 2 elements = {[0] = 2, [1] = 3}} } }
+// { dg-final { regexp-test const_intset {std::(__\d+::)?set with 2 elements = {\[0\] = 2, \[1\] = 3}} } }
 
   std::set<std::string> sp;
   sp.insert("clownfish");
   sp.insert("barrel");
-// { dg-final { note-test sp {std::set with 2 elements = {[0] = "barrel", [1] = "clownfish"}} } }
+// { dg-final { regexp-test sp {std::(__\d+::)?set with 2 elements = {\[0\] = "barrel", \[1\] = "clownfish"}} } }
 
   std::set<std::string>::const_iterator spciter = sp.begin();
 // { dg-final { note-test spciter {"barrel"} } }
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/tr1.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/tr1.cc
index 609b1f0..0e18cd2 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/tr1.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/tr1.cc
@@ -51,31 +51,31 @@  int
 main()
 {
   std::tr1::unordered_map<int, std::string> eum;
-// { dg-final { note-test eum "std::tr1::unordered_map with 0 elements" } }
+// { dg-final { regexp-test eum "std::tr1::(__7::)?unordered_map with 0 elements" } }
   std::tr1::unordered_multimap<int, std::string> eumm;
-// { dg-final { note-test eumm "std::tr1::unordered_multimap with 0 elements" } }
+// { dg-final { regexp-test eumm "std::tr1::(__7::)?unordered_multimap with 0 elements" } }
   std::tr1::unordered_set<int> eus;
-// { dg-final { note-test eus "std::tr1::unordered_set with 0 elements" } }
+// { dg-final { regexp-test eus "std::tr1::(__7::)?unordered_set with 0 elements" } }
   std::tr1::unordered_multiset<int> eums;
-// { dg-final { note-test eums "std::tr1::unordered_multiset with 0 elements" } }
+// { dg-final { regexp-test eums "std::tr1::(__7::)?unordered_multiset with 0 elements" } }
 
   std::tr1::unordered_map<int, std::string> uom;
   uom[5] = "three";
   uom[3] = "seven";
-// { dg-final { note-test uom {std::tr1::unordered_map with 2 elements = {[3] = "seven", [5] = "three"}} } }
+// { dg-final { regexp-test uom {std::tr1::(__7::)?unordered_map with 2 elements = {\[3\] = "seven", \[5\] = "three"}} } }
 
   std::tr1::unordered_multimap<int, std::string> uomm;
   uomm.insert(std::pair<int, std::string> (5, "three"));
   uomm.insert(std::pair<int, std::string> (5, "seven"));
-// { dg-final { note-test uomm {std::tr1::unordered_multimap with 2 elements = {[5] = "three", [5] = "seven"}} } }
+// { dg-final { regexp-test uomm {std::tr1::(__7::)?unordered_multimap with 2 elements = {\[5\] = "three", \[5\] = "seven"}} } }
 
   std::tr1::unordered_set<int> uos;
   uos.insert(5);
-// { dg-final { note-test uos {std::tr1::unordered_set with 1 element = {[0] = 5}} } }
+// { dg-final { regexp-test uos {std::tr1::(__7::)?unordered_set with 1 element = {\[0\] = 5}} } }
 
   std::tr1::unordered_multiset<int> uoms;
   uoms.insert(5);
-// { dg-final { note-test uoms {std::tr1::unordered_multiset with 1 element = {[0] = 5}} } }
+// { dg-final { regexp-test uoms {std::tr1::(__7::)?unordered_multiset with 1 element = {\[0\] = 5}} } }
 
   placeholder(""); // Mark SPOT
   use(eum);
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/whatis.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/whatis.cc
index 3f79f92..f440692 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/whatis.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/whatis.cc
@@ -60,141 +60,141 @@  typedef std::basic_string<unsigned char> ustring;
 
 std::string *string_ptr;
 holder<std::string> string_holder;
-// { dg-final { whatis-test string_holder "holder<std::string>" } }
+// { dg-final { whatis-regexp-test string_holder "holder<std::(__7::)?string>" } }
 std::ios *ios_ptr;
 holder<std::ios> ios_holder;
-// { dg-final { whatis-test ios_holder "holder<std::ios>" } }
+// { dg-final { whatis-regexp-test ios_holder "holder<std::(__7::)?ios>" } }
 std::streambuf *streambuf_ptr;
 holder<std::streambuf> streambuf_holder;
-// { dg-final { whatis-test streambuf_holder "holder<std::streambuf>" } }
+// { dg-final { whatis-regexp-test streambuf_holder "holder<std::(__7::)?streambuf>" } }
 std::istream *istream_ptr;
 holder<std::istream> istream_holder;
-// { dg-final { whatis-test istream_holder "holder<std::istream>" } }
+// { dg-final { whatis-regexp-test istream_holder "holder<std::(__7::)?istream>" } }
 std::ostream *ostream_ptr;
 holder<std::ostream> ostream_holder;
-// { dg-final { whatis-test ostream_holder "holder<std::ostream>" } }
+// { dg-final { whatis-regexp-test ostream_holder "holder<std::(__7::)?ostream>" } }
 std::iostream *iostream_ptr;
 holder<std::iostream> iostream_holder;
-// { dg-final { whatis-test iostream_holder "holder<std::iostream>" } }
+// { dg-final { whatis-regexp-test iostream_holder "holder<std::(__7::)?iostream>" } }
 std::stringbuf *stringbuf_ptr;
 holder<std::stringbuf> stringbuf_holder;
-// { dg-final { whatis-test stringbuf_holder "holder<std::stringbuf>" } }
+// { dg-final { whatis-regexp-test stringbuf_holder "holder<std::(__7::)?stringbuf>" } }
 std::istringstream *istringstream_ptr;
 holder<std::istringstream> istringstream_holder;
-// { dg-final { whatis-test istringstream_holder "holder<std::istringstream>" } }
+// { dg-final { whatis-regexp-test istringstream_holder "holder<std::(__7::)?istringstream>" } }
 std::ostringstream *ostringstream_ptr;
 holder<std::ostringstream> ostringstream_holder;
-// { dg-final { whatis-test ostringstream_holder "holder<std::ostringstream>" } }
+// { dg-final { whatis-regexp-test ostringstream_holder "holder<std::(__7::)?ostringstream>" } }
 std::stringstream *stringstream_ptr;
 holder<std::stringstream> stringstream_holder;
-// { dg-final { whatis-test stringstream_holder "holder<std::stringstream>" } }
+// { dg-final { whatis-regexp-test stringstream_holder "holder<std::(__7::)?stringstream>" } }
 std::filebuf *filebuf_ptr;
 holder<std::filebuf> filebuf_holder;
-// { dg-final { whatis-test filebuf_holder "holder<std::filebuf>" } }
+// { dg-final { whatis-regexp-test filebuf_holder "holder<std::(__7::)?filebuf>" } }
 std::ifstream *ifstream_ptr;
 holder<std::ifstream> ifstream_holder;
-// { dg-final { whatis-test ifstream_holder "holder<std::ifstream>" } }
+// { dg-final { whatis-regexp-test ifstream_holder "holder<std::(__7::)?ifstream>" } }
 std::ofstream *ofstream_ptr;
 holder<std::ofstream> ofstream_holder;
-// { dg-final { whatis-test ofstream_holder "holder<std::ofstream>" } }
+// { dg-final { whatis-regexp-test ofstream_holder "holder<std::(__7::)?ofstream>" } }
 std::fstream *fstream_ptr;
 holder<std::fstream> fstream_holder;
-// { dg-final { whatis-test fstream_holder "holder<std::fstream>" } }
+// { dg-final { whatis-regexp-test fstream_holder "holder<std::(__7::)?fstream>" } }
 std::streampos *streampos_ptr;
 holder<std::streampos> streampos_holder;
-// { dg-final { whatis-test streampos_holder "holder<std::streampos>" } }
+// { dg-final { whatis-regexp-test streampos_holder "holder<std::(__7::)?streampos>" } }
 std::regex *regex_ptr;
 holder<std::regex> regex_holder;
-// { dg-final { whatis-test regex_holder "holder<std::regex>" } }
+// { dg-final { whatis-regexp-test regex_holder "holder<std::(__7::)?regex>" } }
 std::csub_match *csub_match_ptr;
 holder<std::csub_match> csub_match_holder;
-// { dg-final { whatis-test csub_match_holder "holder<std::csub_match>" } }
+// { dg-final { whatis-regexp-test csub_match_holder "holder<std::(__7::)?csub_match>" } }
 std::ssub_match *ssub_match_ptr;
 holder<std::ssub_match> ssub_match_holder;
-// { dg-final { whatis-test ssub_match_holder "holder<std::ssub_match>" } }
+// { dg-final { whatis-regexp-test ssub_match_holder "holder<std::(__7::)?ssub_match>" } }
 std::cmatch *cmatch_ptr;
 holder<std::cmatch> cmatch_holder;
-// { dg-final { whatis-test cmatch_holder "holder<std::cmatch>" } }
+// { dg-final { whatis-regexp-test cmatch_holder "holder<std::(__7::)?cmatch>" } }
 std::smatch *smatch_ptr;
 holder<std::smatch> smatch_holder;
-// { dg-final { whatis-test smatch_holder "holder<std::smatch>" } }
+// { dg-final { whatis-regexp-test smatch_holder "holder<std::(__7::)?smatch>" } }
 std::cregex_iterator *cregex_iterator_ptr;
 holder<std::cregex_iterator> cregex_iterator_holder;
-// { dg-final { whatis-test cregex_iterator_holder "holder<std::cregex_iterator>" } }
+// { dg-final { whatis-regexp-test cregex_iterator_holder "holder<std::(__7::)?cregex_iterator>" } }
 std::sregex_iterator *sregex_iterator_ptr;
 holder<std::sregex_iterator> sregex_iterator_holder;
-// { dg-final { whatis-test sregex_iterator_holder "holder<std::sregex_iterator>" } }
+// { dg-final { whatis-regexp-test sregex_iterator_holder "holder<std::(__7::)?sregex_iterator>" } }
 std::cregex_token_iterator *cregex_token_iterator_ptr;
 holder<std::cregex_token_iterator> cregex_token_iterator_holder;
-// { dg-final { whatis-test cregex_token_iterator_holder "holder<std::cregex_token_iterator>" } }
+// { dg-final { whatis-regexp-test cregex_token_iterator_holder "holder<std::(__7::)?cregex_token_iterator>" } }
 std::sregex_token_iterator *sregex_token_iterator_ptr;
 holder<std::sregex_token_iterator> sregex_token_iterator_holder;
-// { dg-final { whatis-test sregex_token_iterator_holder "holder<std::sregex_token_iterator>" } }
+// { dg-final { whatis-regexp-test sregex_token_iterator_holder "holder<std::(__7::)?sregex_token_iterator>" } }
 std::u16string *u16string_ptr;
 holder<std::u16string> u16string_holder;
-// { dg-final { whatis-test u16string_holder "holder<std::u16string>" } }
+// { dg-final { whatis-regexp-test u16string_holder "holder<std::(__7::)?u16string>" } }
 std::u32string *u32string_ptr;
 holder<std::u32string> u32string_holder;
-// { dg-final { whatis-test u32string_holder "holder<std::u32string>" } }
+// { dg-final { whatis-regexp-test u32string_holder "holder<std::(__7::)?u32string>" } }
 std::minstd_rand0 *minstd_rand0_ptr;
 holder<std::minstd_rand0> minstd_rand0_holder;
-// { dg-final { whatis-test minstd_rand0_holder "holder<std::minstd_rand0>" } }
+// { dg-final { whatis-regexp-test minstd_rand0_holder "holder<std::(__7::)?minstd_rand0>" } }
 std::minstd_rand *minstd_rand_ptr;
 holder<std::minstd_rand> minstd_rand_holder;
-// { dg-final { whatis-test minstd_rand_holder "holder<std::minstd_rand>" } }
+// { dg-final { whatis-regexp-test minstd_rand_holder "holder<std::(__7::)?minstd_rand>" } }
 std::mt19937 *mt19937_ptr;
 holder<std::mt19937> mt19937_holder;
-// { dg-final { whatis-test mt19937_holder "holder<std::mt19937>" } }
+// { dg-final { whatis-regexp-test mt19937_holder "holder<std::(__7::)?mt19937>" } }
 std::mt19937_64 *mt19937_64_ptr;
 holder<std::mt19937_64> mt19937_64_holder;
-// { dg-final { whatis-test mt19937_64_holder "holder<std::mt19937_64>" } }
+// { dg-final { whatis-regexp-test mt19937_64_holder "holder<std::(__7::)?mt19937_64>" } }
 std::ranlux24_base *ranlux24_base_ptr;
 holder<std::ranlux24_base> ranlux24_base_holder;
-// { dg-final { whatis-test ranlux24_base_holder "holder<std::ranlux24_base>" } }
+// { dg-final { whatis-regexp-test ranlux24_base_holder "holder<std::(__7::)?ranlux24_base>" } }
 std::ranlux48_base *ranlux48_base_ptr;
 holder<std::ranlux48_base> ranlux48_base_holder;
-// { dg-final { whatis-test ranlux48_base_holder "holder<std::ranlux48_base>" } }
+// { dg-final { whatis-regexp-test ranlux48_base_holder "holder<std::(__7::)?ranlux48_base>" } }
 std::ranlux24 *ranlux24_ptr;
 holder<std::ranlux24> ranlux24_holder;
-// { dg-final { whatis-test ranlux24_holder "holder<std::ranlux24>" } }
+// { dg-final { whatis-regexp-test ranlux24_holder "holder<std::(__7::)?ranlux24>" } }
 std::ranlux48 *ranlux48_ptr;
 holder<std::ranlux48> ranlux48_holder;
-// { dg-final { whatis-test ranlux48_holder "holder<std::ranlux48>" } }
+// { dg-final { whatis-regexp-test ranlux48_holder "holder<std::(__7::)?ranlux48>" } }
 std::knuth_b *knuth_b_ptr;
 holder<std::knuth_b> knuth_b_holder;
-// { dg-final { whatis-test knuth_b_holder "holder<std::knuth_b>" } }
+// { dg-final { whatis-regexp-test knuth_b_holder "holder<std::(__7::)?knuth_b>" } }
 
 ustring *ustring_ptr;
 holder<ustring> ustring_holder;
-// { dg-final { whatis-test ustring_holder "holder<std::basic_string<unsigned char, std::char_traits<unsigned char>, std::allocator<unsigned char> > >" } }
+// { dg-final { whatis-regexp-test ustring_holder "holder<std::(__7::)?basic_string<unsigned char, std::(__7::)?char_traits<unsigned char>, std::(__7::)?allocator<unsigned char> > >" } }
 
 std::basic_string<signed char> *sstring_ptr;
 holder< std::basic_string<signed char> > sstring_holder;
-// { dg-final { whatis-test sstring_holder "holder<std::basic_string<signed char, std::char_traits<signed char>, std::allocator<signed char> > >" } }
+// { dg-final { whatis-regexp-test sstring_holder "holder<std::(__7::)?basic_string<signed char, std::(__7::)?char_traits<signed char>, std::(__7::)?allocator<signed char> > >" } }
 
 std::vector<std::deque<std::unique_ptr<char>>> *seq1_ptr;
 holder< std::vector<std::deque<std::unique_ptr<char>>> > seq1_holder;
-// { dg-final { whatis-test seq1_holder "holder<std::vector<std::deque<std::unique_ptr<char>>> >" } }
+// { dg-final { whatis-regexp-test seq1_holder "holder<std::(__7::)?vector<std::(__7::)?deque<std::(__7::)?unique_ptr<char>>> >" } }
 
 std::list<std::forward_list<std::unique_ptr<char>>> *seq2_ptr;
 holder< std::list<std::forward_list<std::unique_ptr<char>>> > seq2_holder;
-// { dg-final { whatis-test seq2_holder "holder<std::list<std::forward_list<std::unique_ptr<char>>> >" } }
+// { dg-final { whatis-regexp-test seq2_holder "holder<std::(__7::)?list<std::(__7::)?forward_list<std::(__7::)?unique_ptr<char>>> >" } }
 
 std::map<int, std::set<int>> *assoc1_ptr;
 holder< std::map<int, std::set<int>> > assoc1_holder;
-// { dg-final { whatis-test assoc1_holder "holder<std::map<int, std::set<int>> >" } }
+// { dg-final { whatis-regexp-test assoc1_holder "holder<std::(__7::)?map<int, std::(__7::)?set<int>> >" } }
 
 std::multimap<int, std::multiset<int>> *assoc2_ptr;
 holder< std::multimap<int, std::multiset<int>> > assoc2_holder;
-// { dg-final { whatis-test assoc2_holder "holder<std::multimap<int, std::multiset<int>> >" } }
+// { dg-final { whatis-regexp-test assoc2_holder "holder<std::(__7::)?multimap<int, std::(__7::)?multiset<int>> >" } }
 
 std::unordered_map<int, std::unordered_set<int>> *unord1_ptr;
 holder< std::unordered_map<int, std::unordered_set<int>> > unord1_holder;
-// { dg-final { whatis-test unord1_holder "holder<std::unordered_map<int, std::unordered_set<int>> >" } }
+// { dg-final { whatis-regexp-test unord1_holder "holder<std::(__7::)?unordered_map<int, std::(__7::)?unordered_set<int>> >" } }
 
 std::unordered_multimap<int, std::unordered_multiset<int>> *unord2_ptr;
 holder< std::unordered_multimap<int, std::unordered_multiset<int>> > unord2_holder;
-// { dg-final { whatis-test unord2_holder "holder<std::unordered_multimap<int, std::unordered_multiset<int>> >" } }
+// { dg-final { whatis-regexp-test unord2_holder "holder<std::(__7::)?unordered_multimap<int, std::(__7::)?unordered_multiset<int>> >" } }
 
 
 int