OSDN Git Service

merge from gcc
[pf3gnuchains/pf3gnuchains4x.git] / libiberty / cp-demangle.c
index 0f1166b..2dfd67c 100644 (file)
@@ -648,9 +648,15 @@ d_dump (struct demangle_component *dc, int indent)
     case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
       printf ("template argument list\n");
       break;
+    case DEMANGLE_COMPONENT_INITIALIZER_LIST:
+      printf ("initializer list\n");
+      break;
     case DEMANGLE_COMPONENT_CAST:
       printf ("cast\n");
       break;
+    case DEMANGLE_COMPONENT_NULLARY:
+      printf ("nullary operator\n");
+      break;
     case DEMANGLE_COMPONENT_UNARY:
       printf ("unary operator\n");
       break;
@@ -806,7 +812,6 @@ d_make_comp (struct d_info *di, enum demangle_component_type type,
     case DEMANGLE_COMPONENT_BINARY_ARGS:
     case DEMANGLE_COMPONENT_TRINARY:
     case DEMANGLE_COMPONENT_TRINARY_ARG1:
-    case DEMANGLE_COMPONENT_TRINARY_ARG2:
     case DEMANGLE_COMPONENT_LITERAL:
     case DEMANGLE_COMPONENT_LITERAL_NEG:
     case DEMANGLE_COMPONENT_COMPOUND_NAME:
@@ -843,6 +848,8 @@ d_make_comp (struct d_info *di, enum demangle_component_type type,
     case DEMANGLE_COMPONENT_PACK_EXPANSION:
     case DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS:
     case DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS:
+    case DEMANGLE_COMPONENT_NULLARY:
+    case DEMANGLE_COMPONENT_TRINARY_ARG2:
       if (left == NULL)
        return NULL;
       break;
@@ -850,6 +857,7 @@ d_make_comp (struct d_info *di, enum demangle_component_type type,
       /* This needs a right parameter, but the left parameter can be
         empty.  */
     case DEMANGLE_COMPONENT_ARRAY_TYPE:
+    case DEMANGLE_COMPONENT_INITIALIZER_LIST:
       if (right == NULL)
        return NULL;
       break;
@@ -1554,7 +1562,8 @@ d_identifier (struct d_info *di, int len)
 /* operator_name ::= many different two character encodings.
                  ::= cv <type>
                  ::= v <digit> <source-name>
-*/
+
+   This list is sorted for binary search.  */
 
 #define NL(s) s, (sizeof s) - 1
 
@@ -1566,19 +1575,23 @@ const struct demangle_operator_info cplus_demangle_operators[] =
   { "aa", NL ("&&"),        2 },
   { "ad", NL ("&"),         1 },
   { "an", NL ("&"),         2 },
+  { "at", NL ("alignof "),   1 },
+  { "az", NL ("alignof "),   1 },
   { "cl", NL ("()"),        2 },
   { "cm", NL (","),         2 },
   { "co", NL ("~"),         1 },
   { "dV", NL ("/="),        2 },
-  { "da", NL ("delete[]"),  1 },
+  { "da", NL ("delete[] "), 1 },
   { "de", NL ("*"),         1 },
-  { "dl", NL ("delete"),    1 },
+  { "dl", NL ("delete "),   1 },
+  { "ds", NL (".*"),        2 },
   { "dt", NL ("."),         2 },
   { "dv", NL ("/"),         2 },
   { "eO", NL ("^="),        2 },
   { "eo", NL ("^"),         2 },
   { "eq", NL ("=="),        2 },
   { "ge", NL (">="),        2 },
+  { "gs", NL ("::"),       1 },
   { "gt", NL (">"),         2 },
   { "ix", NL ("[]"),        2 },
   { "lS", NL ("<<="),       2 },
@@ -1590,11 +1603,11 @@ const struct demangle_operator_info cplus_demangle_operators[] =
   { "mi", NL ("-"),         2 },
   { "ml", NL ("*"),         2 },
   { "mm", NL ("--"),        1 },
-  { "na", NL ("new[]"),     1 },
+  { "na", NL ("new[]"),     3 },
   { "ne", NL ("!="),        2 },
   { "ng", NL ("-"),         1 },
   { "nt", NL ("!"),         1 },
-  { "nw", NL ("new"),       1 },
+  { "nw", NL ("new"),       3 },
   { "oR", NL ("|="),        2 },
   { "oo", NL ("||"),        2 },
   { "or", NL ("|"),         2 },
@@ -1611,8 +1624,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 },
+  { "tr", NL ("throw"),     0 },
+  { "tw", NL ("throw "),    1 },
   { NULL, NULL, 0,          0 }
 };
 
@@ -2242,12 +2255,14 @@ cplus_demangle_type (struct d_info *di)
                             d_expression (di), NULL);
          if (ret && d_next_char (di) != 'E')
            ret = NULL;
+         can_subst = 1;
          break;
          
        case 'p':
          /* Pack expansion.  */
          ret = d_make_comp (di, DEMANGLE_COMPONENT_PACK_EXPANSION,
                             cplus_demangle_type (di), NULL);
+         can_subst = 1;
          break;
          
        case 'f':
@@ -2298,6 +2313,7 @@ cplus_demangle_type (struct d_info *di)
 
        case 'v':
          ret = d_vector_type (di);
+         can_subst = 1;
          break;
 
         case 'n':
@@ -2675,8 +2691,10 @@ d_template_args (struct d_info *di)
      constructor or destructor.  */
   hold_last_name = di->last_name;
 
-  if (! d_check_char (di, 'I'))
+  if (d_peek_char (di) != 'I'
+      && d_peek_char (di) != 'J')
     return NULL;
+  d_advance (di, 1);
 
   if (d_peek_char (di) == 'E')
     {
@@ -2735,6 +2753,7 @@ d_template_arg (struct d_info *di)
       return d_expr_primary (di);
 
     case 'I':
+    case 'J':
       /* An argument pack.  */
       return d_template_args (di);
 
@@ -2743,15 +2762,16 @@ d_template_arg (struct d_info *di)
     }
 }
 
-/* Subroutine of <expression> ::= cl <expression>+ E */
+/* Parse a sequence of expressions until we hit the terminator
+   character.  */
 
 static struct demangle_component *
-d_exprlist (struct d_info *di)
+d_exprlist (struct d_info *di, char terminator)
 {
   struct demangle_component *list = NULL;
   struct demangle_component **p = &list;
 
-  if (d_peek_char (di) == 'E')
+  if (d_peek_char (di) == terminator)
     {
       d_advance (di, 1);
       return d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, NULL, NULL);
@@ -2768,7 +2788,7 @@ d_exprlist (struct d_info *di)
        return NULL;
       p = &d_right (*p);
 
-      if (d_peek_char (di) == 'E')
+      if (d_peek_char (di) == terminator)
        {
          d_advance (di, 1);
          break;
@@ -2859,9 +2879,21 @@ d_expression (struct d_info *di)
       else
        return name;
     }
+  else if ((peek == 'i' || peek == 't')
+          && d_peek_next_char (di) == 'l')
+    {
+      /* Brace-enclosed initializer list, untyped or typed.  */
+      struct demangle_component *type = NULL;
+      if (peek == 't')
+       type = cplus_demangle_type (di);
+      d_advance (di, 2);
+      return d_make_comp (di, DEMANGLE_COMPONENT_INITIALIZER_LIST,
+                         type, d_exprlist (di, 'E'));
+    }
   else
     {
       struct demangle_component *op;
+      const char *code = NULL;
       int args;
 
       op = d_operator_name (di);
@@ -2869,12 +2901,13 @@ d_expression (struct d_info *di)
        return NULL;
 
       if (op->type == DEMANGLE_COMPONENT_OPERATOR)
-       di->expansion += op->u.s_operator.op->len - 2;
-
-      if (op->type == DEMANGLE_COMPONENT_OPERATOR
-         && strcmp (op->u.s_operator.op->code, "st") == 0)
-       return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
-                           cplus_demangle_type (di));
+       {
+         code = op->u.s_operator.op->code;
+         di->expansion += op->u.s_operator.op->len - 2;
+         if (strcmp (code, "st") == 0)
+           return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
+                               cplus_demangle_type (di));
+       }
 
       switch (op->type)
        {
@@ -2893,26 +2926,43 @@ d_expression (struct d_info *di)
 
       switch (args)
        {
+       case 0:
+         return d_make_comp (di, DEMANGLE_COMPONENT_NULLARY, op, NULL);
+
        case 1:
          {
            struct demangle_component *operand;
+           int suffix = 0;
+
+           if (code && (code[0] == 'p' || code[0] == 'm')
+               && code[1] == code[0])
+             /* pp_ and mm_ are the prefix variants.  */
+             suffix = !d_check_char (di, '_');
+
            if (op->type == DEMANGLE_COMPONENT_CAST
                && d_check_char (di, '_'))
-             operand = d_exprlist (di);
+             operand = d_exprlist (di, 'E');
            else
              operand = d_expression (di);
-           return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
-                               operand);
+
+           if (suffix)
+             /* Indicate the suffix variant for d_print_comp.  */
+             return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
+                                 d_make_comp (di,
+                                              DEMANGLE_COMPONENT_BINARY_ARGS,
+                                              operand, operand));
+           else
+             return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
+                                 operand);
          }
        case 2:
          {
            struct demangle_component *left;
            struct demangle_component *right;
-           const char *code = op->u.s_operator.op->code;
 
            left = d_expression (di);
            if (!strcmp (code, "cl"))
-             right = d_exprlist (di);
+             right = d_exprlist (di, 'E');
            else if (!strcmp (code, "dt") || !strcmp (code, "pt"))
              {
                right = d_unqualified_name (di);
@@ -2932,17 +2982,50 @@ d_expression (struct d_info *di)
          {
            struct demangle_component *first;
            struct demangle_component *second;
+           struct demangle_component *third;
 
-           first = d_expression (di);
-           second = d_expression (di);
+           if (!strcmp (code, "qu"))
+             {
+               /* ?: expression.  */
+               first = d_expression (di);
+               second = d_expression (di);
+               third = d_expression (di);
+             }
+           else if (code[0] == 'n')
+             {
+               /* new-expression.  */
+               if (code[1] != 'w' && code[1] != 'a')
+                 return NULL;
+               first = d_exprlist (di, '_');
+               second = cplus_demangle_type (di);
+               if (d_peek_char (di) == 'E')
+                 {
+                   d_advance (di, 1);
+                   third = NULL;
+                 }
+               else if (d_peek_char (di) == 'p'
+                        && d_peek_next_char (di) == 'i')
+                 {
+                   /* Parenthesized initializer.  */
+                   d_advance (di, 2);
+                   third = d_exprlist (di, 'E');
+                 }
+               else if (d_peek_char (di) == 'i'
+                        && d_peek_next_char (di) == 'l')
+                 /* initializer-list.  */
+                 third = d_expression (di);
+               else
+                 return NULL;
+             }
+           else
+             return NULL;
            return d_make_comp (di, DEMANGLE_COMPONENT_TRINARY, op,
                                d_make_comp (di,
                                             DEMANGLE_COMPONENT_TRINARY_ARG1,
                                             first,
                                             d_make_comp (di,
                                                          DEMANGLE_COMPONENT_TRINARY_ARG2,
-                                                         second,
-                                                         d_expression (di))));
+                                                         second, third)));
          }
        default:
          return NULL;
@@ -3662,6 +3745,8 @@ d_print_subexpr (struct d_print_info *dpi, int options,
 {
   int simple = 0;
   if (dc->type == DEMANGLE_COMPONENT_NAME
+      || dc->type == DEMANGLE_COMPONENT_QUAL_NAME
+      || dc->type == DEMANGLE_COMPONENT_INITIALIZER_LIST
       || dc->type == DEMANGLE_COMPONENT_FUNCTION_PARAM)
     simple = 1;
   if (!simple)
@@ -4257,6 +4342,19 @@ d_print_comp (struct d_print_info *dpi, int options,
        }
       return;
 
+    case DEMANGLE_COMPONENT_INITIALIZER_LIST:
+      {
+       struct demangle_component *type = d_left (dc);
+       struct demangle_component *list = d_right (dc);
+
+       if (type)
+         d_print_comp (dpi, options, type);
+       d_append_char (dpi, '{');
+       d_print_comp (dpi, options, list);
+       d_append_char (dpi, '}');
+      }
+      return;
+
     case DEMANGLE_COMPONENT_OPERATOR:
       {
        char c;
@@ -4280,55 +4378,59 @@ d_print_comp (struct d_print_info *dpi, int options,
       d_print_cast (dpi, options, dc);
       return;
 
+    case DEMANGLE_COMPONENT_NULLARY:
+      d_print_expr_op (dpi, options, d_left (dc));
+      return;
+
     case DEMANGLE_COMPONENT_UNARY:
-      if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR
-         && d_left (dc)->u.s_operator.op->len == 1
-         && d_left (dc)->u.s_operator.op->name[0] == '&'
-         && d_right (dc)->type == DEMANGLE_COMPONENT_TYPED_NAME
-         && d_left (d_right (dc))->type == DEMANGLE_COMPONENT_QUAL_NAME
-         && d_right (d_right (dc))->type == DEMANGLE_COMPONENT_FUNCTION_TYPE)
-       {
-         /* Address of a function (therefore in an expression context) must
-            have its argument list suppressed.
-
-            unary operator ... dc
-              operator & ... d_left (dc)
-              typed name ... d_right (dc)
-                qualified name ... d_left (d_right (dc))
-                  <names>
-                function type ... d_right (d_right (dc))
-                  argument list
-                    <arguments>  */
-
-         d_print_expr_op (dpi, options, d_left (dc));
-         d_print_comp (dpi, options, d_left (d_right (dc)));
-         return;
-       }
-      else if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR
-              && d_left (dc)->u.s_operator.op->len == 1
-              && d_left (dc)->u.s_operator.op->name[0] == '&'
-              && d_right (dc)->type == DEMANGLE_COMPONENT_QUAL_NAME)
-       {
-         /* Keep also already processed variant without the argument list.
+      {
+       struct demangle_component *op = d_left (dc);
+       struct demangle_component *operand = d_right (dc);
+       const char *code = NULL;
 
-            unary operator ... dc
-              operator & ... d_left (dc)
-              qualified name ... d_right (dc)
-                <names>  */
+       if (op->type == DEMANGLE_COMPONENT_OPERATOR)
+         {
+           code = op->u.s_operator.op->code;
+           if (!strcmp (code, "ad"))
+             {
+               /* Don't print the argument list for the address of a
+                  function.  */
+               if (operand->type == DEMANGLE_COMPONENT_TYPED_NAME
+                   && d_left (operand)->type == DEMANGLE_COMPONENT_QUAL_NAME
+                   && d_right (operand)->type == DEMANGLE_COMPONENT_FUNCTION_TYPE)
+                 operand = d_left (operand);
+             }
+           if (operand->type == DEMANGLE_COMPONENT_BINARY_ARGS)
+             {
+               /* This indicates a suffix operator.  */
+               operand = d_left (operand);
+               d_print_subexpr (dpi, options, operand);
+               d_print_expr_op (dpi, options, op);
+               return;
+             }
+         }
 
-         d_print_expr_op (dpi, options, d_left (dc));
-         d_print_comp (dpi, options, d_right (dc));
-         return;
-       }
-      else if (d_left (dc)->type != DEMANGLE_COMPONENT_CAST)
-       d_print_expr_op (dpi, options, d_left (dc));
-      else
-       {
-         d_append_char (dpi, '(');
-         d_print_cast (dpi, options, d_left (dc));
-         d_append_char (dpi, ')');
-       }
-      d_print_subexpr (dpi, options, d_right (dc));
+       if (op->type != DEMANGLE_COMPONENT_CAST)
+         d_print_expr_op (dpi, options, op);
+       else
+         {
+           d_append_char (dpi, '(');
+           d_print_cast (dpi, options, op);
+           d_append_char (dpi, ')');
+         }
+       if (code && !strcmp (code, "gs"))
+         /* Avoid parens after '::'.  */
+         d_print_comp (dpi, options, operand);
+       else if (code && !strcmp (code, "st"))
+         /* Always print parens for sizeof (type).  */
+         {
+           d_append_char (dpi, '(');
+           d_print_comp (dpi, options, operand);
+           d_append_char (dpi, ')');
+         }
+       else
+         d_print_subexpr (dpi, options, operand);
+      }
       return;
 
     case DEMANGLE_COMPONENT_BINARY:
@@ -4393,11 +4495,33 @@ d_print_comp (struct d_print_info *dpi, int options,
          d_print_error (dpi);
          return;
        }
-      d_print_subexpr (dpi, options, d_left (d_right (dc)));
-      d_print_expr_op (dpi, options, d_left (dc));
-      d_print_subexpr (dpi, options, d_left (d_right (d_right (dc))));
-      d_append_string (dpi, " : ");
-      d_print_subexpr (dpi, options, d_right (d_right (d_right (dc))));
+      {
+       struct demangle_component *op = d_left (dc);
+       struct demangle_component *first = d_left (d_right (dc));
+       struct demangle_component *second = d_left (d_right (d_right (dc)));
+       struct demangle_component *third = d_right (d_right (d_right (dc)));
+
+       if (!strcmp (op->u.s_operator.op->code, "qu"))
+         {
+           d_print_subexpr (dpi, options, first);
+           d_print_expr_op (dpi, options, op);
+           d_print_subexpr (dpi, options, second);
+           d_append_string (dpi, " : ");
+           d_print_subexpr (dpi, options, third);
+         }
+       else
+         {
+           d_append_string (dpi, "new ");
+           if (d_left (first) != NULL)
+             {
+               d_print_subexpr (dpi, options, first);
+               d_append_char (dpi, ' ');
+             }
+           d_print_comp (dpi, options, second);
+           if (third)
+             d_print_subexpr (dpi, options, third);
+         }
+      }
       return;
 
     case DEMANGLE_COMPONENT_TRINARY_ARG1: