Fix for PR c++/13447:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 19 Dec 2003 21:14:35 +0000 (21:14 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 19 Dec 2003 21:14:35 +0000 (21:14 +0000)
* cp-demangle.c (enum d_comp_type): Add D_COMP_LOCAL_NAME.
(d_dump, d_make_comp): Handle D_COMP_LOCAL_NAME.
(is_ctor_dtor_or_conversion): Handle D_COMP_LOCAL_NAME like
D_COMP_QUAL_NAME.
(is_ctor_or_dtor): Likewise.
(d_local_name): Use D_COMP_LOCAL_NAME rather than
D_COMP_QUAL_NAME.
(d_print_comp) [D_COMP_LOCAL_NAME]: New.
(d_prinT_comp) [D_COMP_TYPED_NAME]: If the left tree is
D_COMP_LOCAL_NAME, pull any qualifiers off its right subtree.
(d_print_mod_list): Handle D_COMP_LOCAL_NAME.
* testsuite/demangle-expected: Add two test cases.

* cp-demangle.c (d_print_function_type): Clear the global modifier
list when printing the modifiers, not just when printing the
function parameters.
* testsuite/demangle-expected: Add two test cases.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@74850 138bc75d-0d04-0410-961f-82ee72b054a4

libiberty/ChangeLog
libiberty/cp-demangle.c
libiberty/testsuite/demangle-expected

index 0a027a0..695c450 100644 (file)
@@ -1,3 +1,24 @@
+2003-12-19  Ian Lance Taylor  <ian@wasabisystems.com>
+
+       Fix for PR c++/13447:
+       * cp-demangle.c (enum d_comp_type): Add D_COMP_LOCAL_NAME.
+       (d_dump, d_make_comp): Handle D_COMP_LOCAL_NAME.
+       (is_ctor_dtor_or_conversion): Handle D_COMP_LOCAL_NAME like
+       D_COMP_QUAL_NAME.
+       (is_ctor_or_dtor): Likewise.
+       (d_local_name): Use D_COMP_LOCAL_NAME rather than
+       D_COMP_QUAL_NAME.
+       (d_print_comp) [D_COMP_LOCAL_NAME]: New.
+       (d_prinT_comp) [D_COMP_TYPED_NAME]: If the left tree is
+       D_COMP_LOCAL_NAME, pull any qualifiers off its right subtree.
+       (d_print_mod_list): Handle D_COMP_LOCAL_NAME.
+       * testsuite/demangle-expected: Add two test cases.
+
+       * cp-demangle.c (d_print_function_type): Clear the global modifier
+       list when printing the modifiers, not just when printing the
+       function parameters.
+       * testsuite/demangle-expected: Add two test cases.
+
 2003-12-15  Ian Lance Taylor  <ian@wasabisystems.com>
 
        * cp-demangle.c (d_print_function_type): Print the function
index f6c0543..27e09df 100644 (file)
@@ -166,6 +166,8 @@ enum d_comp_type
   D_COMP_NAME,
   /* A qualified name.  */
   D_COMP_QUAL_NAME,
+  /* A local name.  */
+  D_COMP_LOCAL_NAME,
   /* A typed name.  */
   D_COMP_TYPED_NAME,
   /* A template.  */
@@ -585,6 +587,9 @@ d_dump (dc, indent)
     case D_COMP_QUAL_NAME:
       printf ("qualified name\n");
       break;
+    case D_COMP_LOCAL_NAME:
+      printf ("local name\n");
+      break;
     case D_COMP_TYPED_NAME:
       printf ("typed name\n");
       break;
@@ -748,6 +753,7 @@ d_make_comp (di, type, left, right)
     {
       /* These types require two parameters.  */
     case D_COMP_QUAL_NAME:
+    case D_COMP_LOCAL_NAME:
     case D_COMP_TYPED_NAME:
     case D_COMP_TEMPLATE:
     case D_COMP_VENDOR_TYPE_QUAL:
@@ -1025,6 +1031,7 @@ is_ctor_dtor_or_conversion (dc)
     default:
       return 0;
     case D_COMP_QUAL_NAME:
+    case D_COMP_LOCAL_NAME:
       return is_ctor_dtor_or_conversion (d_right (dc));
     case D_COMP_CTOR:
     case D_COMP_DTOR:
@@ -2332,7 +2339,7 @@ d_local_name (di)
       d_advance (di, 1);
       if (! d_discriminator (di))
        return NULL;
-      return d_make_comp (di, D_COMP_QUAL_NAME, function,
+      return d_make_comp (di, D_COMP_LOCAL_NAME, function,
                          d_make_name (di, "string literal",
                                       sizeof "string literal" - 1));
     }
@@ -2343,7 +2350,7 @@ d_local_name (di)
       name = d_name (di);
       if (! d_discriminator (di))
        return NULL;
-      return d_make_comp (di, D_COMP_QUAL_NAME, function, name);
+      return d_make_comp (di, D_COMP_LOCAL_NAME, function, name);
     }
 }
 
@@ -2641,6 +2648,7 @@ d_print_comp (dpi, dc)
       return;
 
     case D_COMP_QUAL_NAME:
+    case D_COMP_LOCAL_NAME:
       d_print_comp (dpi, d_left (dc));
       d_append_string (dpi, (dpi->options & DMGL_JAVA) == 0 ? "::" : ".");
       d_print_comp (dpi, d_right (dc));
@@ -2692,6 +2700,38 @@ d_print_comp (dpi, dc)
            dpt.template = typed_name;
          }
 
+       /* If typed_name is a D_COMP_LOCAL_NAME, then there may be
+          CV-qualifiers on its right argument which really apply
+          here; this happens when parsing a class which is local to a
+          function.  */
+       if (typed_name->type == D_COMP_LOCAL_NAME)
+         {
+           struct d_comp *local_name;
+
+           local_name = d_right (typed_name);
+           while (local_name->type == D_COMP_RESTRICT_THIS
+                  || local_name->type == D_COMP_VOLATILE_THIS
+                  || local_name->type == D_COMP_CONST_THIS)
+             {
+               if (i >= sizeof adpm / sizeof adpm[0])
+                 {
+                   d_print_error (dpi);
+                   return;
+                 }
+
+               adpm[i] = adpm[i - 1];
+               adpm[i].next = &adpm[i - 1];
+               dpi->modifiers = &adpm[i];
+
+               adpm[i - 1].mod = local_name;
+               adpm[i - 1].printed = 0;
+               adpm[i - 1].templates = dpi->templates;
+               ++i;
+
+               local_name = d_left (local_name);
+             }
+         }
+
        d_print_comp (dpi, d_right (dc));
 
        if (typed_name->type == D_COMP_TEMPLATE)
@@ -3260,6 +3300,34 @@ d_print_mod_list (dpi, mods, suffix)
       dpi->templates = hold_dpt;
       return;
     }
+  else if (mods->mod->type == D_COMP_LOCAL_NAME)
+    {
+      struct d_print_mod *hold_modifiers;
+      struct d_comp *dc;
+
+      /* When this is on the modifier stack, we have pulled any
+        qualifiers off the right argument already.  Otherwise, we
+        print it as usual, but don't let the left argument see any
+        modifiers.  */
+
+      hold_modifiers = dpi->modifiers;
+      dpi->modifiers = NULL;
+      d_print_comp (dpi, d_left (mods->mod));
+      dpi->modifiers = hold_modifiers;
+
+      d_append_string (dpi, (dpi->options & DMGL_JAVA) == 0 ? "::" : ".");
+
+      dc = d_right (mods->mod);
+      while (dc->type == D_COMP_RESTRICT_THIS
+            || dc->type == D_COMP_VOLATILE_THIS
+            || dc->type == D_COMP_CONST_THIS)
+       dc = d_left (dc);
+
+      d_print_comp (dpi, dc);
+
+      dpi->templates = hold_dpt;
+      return;
+    }
 
   d_print_mod (dpi, mods->mod);
 
@@ -3335,6 +3403,7 @@ d_print_function_type (dpi, dc, mods)
   int need_paren;
   int saw_mod;
   struct d_print_mod *p;
+  struct d_print_mod *hold_modifiers;
 
   need_paren = 0;
   saw_mod = 0;
@@ -3388,6 +3457,9 @@ d_print_function_type (dpi, dc, mods)
       d_append_char (dpi, '(');
     }
 
+  hold_modifiers = dpi->modifiers;
+  dpi->modifiers = NULL;
+
   d_print_mod_list (dpi, mods, 0);
 
   if (need_paren)
@@ -3396,18 +3468,13 @@ d_print_function_type (dpi, dc, mods)
   d_append_char (dpi, '(');
 
   if (d_right (dc) != NULL)
-    {
-      struct d_print_mod *hold_modifiers;
-
-      hold_modifiers = dpi->modifiers;
-      dpi->modifiers = NULL;
-      d_print_comp (dpi, d_right (dc));
-      dpi->modifiers = hold_modifiers;
-    }
+    d_print_comp (dpi, d_right (dc));
 
   d_append_char (dpi, ')');
 
   d_print_mod_list (dpi, mods, 1);
+
+  dpi->modifiers = hold_modifiers;
 }
 
 /* Print an array type, except for the element type.  */
@@ -3857,6 +3924,7 @@ is_ctor_or_dtor (mangled, ctor_kind, dtor_kind)
          dc = d_left (dc);
          break;
        case D_COMP_QUAL_NAME:
+       case D_COMP_LOCAL_NAME:
          dc = d_right (dc);
          break;
        case D_COMP_CTOR:
index 7452338..8bae90e 100644 (file)
@@ -2921,6 +2921,27 @@ std::basic_iostream<char, std::char_traits<char> >::~basic_iostream()
 _ZNK15nsBaseHashtableI15nsUint32HashKey8nsCOMPtrI4IFooEPS2_E13EnumerateReadEPF15PLDHashOperatorRKjS4_PvES9_
 nsBaseHashtable<nsUint32HashKey, nsCOMPtr<IFoo>, IFoo*>::EnumerateRead(PLDHashOperator (*)(unsigned int const&, IFoo*, void*), void*) const
 #
+# Another member function qualifier test case, when the member function
+# returns a pointer to function.
+--format=gnu-v3
+_ZNK1C1fIiEEPFivEv
+int (*C::f<int>() const)()
+#
+# Another case where we got member function qualifiers wrong.
+--format=gnu-v3
+_ZZ3BBdI3FooEvvENK3Fob3FabEv
+void BBd<Foo>()::Fob::Fab() const
+#
+# The same idea one level deeper.
+--format=gnu-v3
+_ZZZ3BBdI3FooEvvENK3Fob3FabEvENK3Gob3GabEv
+void BBd<Foo>()::Fob::Fab() const::Gob::Gab() const
+#
+# Yet another member function qualifier problem.
+--format=gnu-v3
+_ZNK5boost6spirit5matchI13rcs_deltatextEcvMNS0_4impl5dummyEFvvEEv
+boost::spirit::match<rcs_deltatext>::operator void (boost::spirit::impl::dummy::*)()() const
+#
 # This caused an infinite loop.
 #
 # This is generated by an EDG compiler (kcc 4.0).  To demangle it