OSDN Git Service

2009-06-09 Ghassan Shobaki <ghassan.shobaki@amd.com>
[pf3gnuchains/gcc-fork.git] / libiberty / cp-demangle.c
index 8ab5729..4f309ef 100644 (file)
@@ -719,8 +719,8 @@ cplus_demangle_fill_ctor (struct demangle_component *p,
 {
   if (p == NULL
       || name == NULL
-      || (kind < gnu_v3_complete_object_ctor
-         && kind > gnu_v3_complete_object_allocating_ctor))
+      || (int) kind < gnu_v3_complete_object_ctor
+      || (int) kind > gnu_v3_complete_object_allocating_ctor)
     return 0;
   p->type = DEMANGLE_COMPONENT_CTOR;
   p->u.s_ctor.kind = kind;
@@ -738,8 +738,8 @@ cplus_demangle_fill_dtor (struct demangle_component *p,
 {
   if (p == NULL
       || name == NULL
-      || (kind < gnu_v3_deleting_dtor
-         && kind > gnu_v3_base_object_dtor))
+      || (int) kind < gnu_v3_deleting_dtor
+      || (int) kind > gnu_v3_base_object_dtor)
     return 0;
   p->type = DEMANGLE_COMPONENT_DTOR;
   p->u.s_dtor.kind = kind;
@@ -964,6 +964,22 @@ d_make_template_param (struct d_info *di, long i)
   return p;
 }
 
+/* Add a new function parameter.  */
+
+static struct demangle_component *
+d_make_function_param (struct d_info *di, long i)
+{
+  struct demangle_component *p;
+
+  p = d_make_empty (di);
+  if (p != NULL)
+    {
+      p->type = DEMANGLE_COMPONENT_FUNCTION_PARAM;
+      p->u.s_number.number = i;
+    }
+  return p;
+}
+
 /* Add a new standard substitution component.  */
 
 static struct demangle_component *
@@ -989,7 +1005,11 @@ CP_STATIC_IF_GLIBCPP_V3
 struct demangle_component *
 cplus_demangle_mangled_name (struct d_info *di, int top_level)
 {
-  if (! d_check_char (di, '_'))
+  if (! d_check_char (di, '_')
+      /* Allow missing _ if not at toplevel to work around a
+        bug in G++ abi-version=2 mangling; see the comment in
+        write_template_arg.  */
+      && top_level)
     return NULL;
   if (! d_check_char (di, 'Z'))
     return NULL;
@@ -1481,6 +1501,8 @@ const struct demangle_operator_info cplus_demangle_operators[] =
   { "rs", NL (">>"),        2 },
   { "st", NL ("sizeof "),   1 },
   { "sz", NL ("sizeof "),   1 },
+  { "at", NL ("alignof "),   1 },
+  { "az", NL ("alignof "),   1 },
   { NULL, NULL, 0,          0 }
 };
 
@@ -2131,6 +2153,9 @@ cplus_demangle_type (struct d_info *di)
          peek = d_next_char (di);
          ret->u.s_fixed.sat = (peek == 's');
          break;
+
+       default:
+         return NULL;
        }
       break;
 
@@ -2561,12 +2586,31 @@ d_expression (struct d_info *di)
                            d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, name,
                                         d_template_args (di)));
     }
-  else if (peek == 's'
-          && (d_peek_next_char (di) == 'T' || d_peek_next_char (di) == 'R'))
+  else if (peek == 's' && d_peek_next_char (di) == 'p')
     {
-      /* Just demangle a parameter placeholder as its type.  */
       d_advance (di, 2);
-      return cplus_demangle_type (di);
+      return d_make_comp (di, DEMANGLE_COMPONENT_PACK_EXPANSION,
+                         d_expression (di), NULL);
+    }
+  else if (peek == 'f' && d_peek_next_char (di) == 'p')
+    {
+      /* Function parameter used in a late-specified return type.  */
+      int index;
+      d_advance (di, 2);
+      if (d_peek_char (di) == '_')
+       index = 1;
+      else
+       {
+         index = d_number (di);
+         if (index < 0)
+           return NULL;
+         index += 2;
+       }
+
+      if (! d_check_char (di, '_'))
+       return NULL;
+
+      return d_make_function_param (di, index);
     }
   else if (IS_DIGIT (peek))
     {
@@ -2618,7 +2662,8 @@ d_expression (struct d_info *di)
        case 1:
          {
            struct demangle_component *operand;
-           if (op->type == DEMANGLE_COMPONENT_CAST)
+           if (op->type == DEMANGLE_COMPONENT_CAST
+               && d_check_char (di, '_'))
              operand = d_exprlist (di);
            else
              operand = d_expression (di);
@@ -2675,7 +2720,9 @@ d_expr_primary (struct d_info *di)
 
   if (! d_check_char (di, 'L'))
     return NULL;
-  if (d_peek_char (di) == '_')
+  if (d_peek_char (di) == '_'
+      /* Workaround for G++ bug; see comment in write_template_arg.  */
+      || d_peek_char (di) == 'Z')
     ret = cplus_demangle_mangled_name (di, 0);
   else
     {
@@ -3203,6 +3250,7 @@ d_find_pack (struct d_print_info *dpi,
     case DEMANGLE_COMPONENT_BUILTIN_TYPE:
     case DEMANGLE_COMPONENT_SUB_STD:
     case DEMANGLE_COMPONENT_CHARACTER:
+    case DEMANGLE_COMPONENT_FUNCTION_PARAM:
       return NULL;
 
     case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
@@ -3243,7 +3291,8 @@ d_print_subexpr (struct d_print_info *dpi,
                 const struct demangle_component *dc)
 {
   int simple = 0;
-  if (dc->type == DEMANGLE_COMPONENT_NAME)
+  if (dc->type == DEMANGLE_COMPONENT_NAME
+      || dc->type == DEMANGLE_COMPONENT_FUNCTION_PARAM)
     simple = 1;
   if (!simple)
     d_append_char (dpi, '(');
@@ -3297,6 +3346,7 @@ d_print_comp (struct d_print_info *dpi,
           the right place for the type.  We also have to pass down
           any CV-qualifiers, which apply to the this parameter.  */
        hold_modifiers = dpi->modifiers;
+       dpi->modifiers = 0;
        i = 0;
        typed_name = d_left (dc);
        while (typed_name != NULL)
@@ -3970,10 +4020,20 @@ d_print_comp (struct d_print_info *dpi,
 
     case DEMANGLE_COMPONENT_PACK_EXPANSION:
       {
-       struct demangle_component *a = d_find_pack (dpi, d_left (dc));
-       int len = d_pack_length (a);
+       int len;
        int i;
+       struct demangle_component *a = d_find_pack (dpi, d_left (dc));
+       if (a == NULL)
+         {
+           /* d_find_pack won't find anything if the only packs involved
+              in this expansion are function parameter packs; in that
+              case, just print the pattern and "...".  */
+           d_print_subexpr (dpi, d_left (dc));
+           d_append_string (dpi, "...");
+           return;
+         }
 
+       len = d_pack_length (a);
        dc = d_left (dc);
        for (i = 0; i < len; ++i)
          {
@@ -3985,6 +4045,15 @@ d_print_comp (struct d_print_info *dpi,
       }
       return;
 
+    case DEMANGLE_COMPONENT_FUNCTION_PARAM:
+      {
+       char buf[25];
+       d_append_string (dpi, "parm#");
+       sprintf(buf,"%ld", dc->u.s_number.number);
+       d_append_string (dpi, buf);
+       return;
+      }
+
     default:
       d_print_error (dpi);
       return;