gdb/testsuite: add some logging in Term::_check_box
[deliverable/binutils-gdb.git] / libiberty / cp-demangle.c
index 3f2a097e7f2075e5750e40a31ce46589d4ab83d5..d3e798455cc6a3a21f19314a76af26b189c44a3e 100644 (file)
@@ -1,5 +1,5 @@
 /* Demangler for g++ V3 ABI.
-   Copyright (C) 2003-2018 Free Software Foundation, Inc.
+   Copyright (C) 2003-2021 Free Software Foundation, Inc.
    Written by Ian Lance Taylor <ian@wasabisystems.com>.
 
    This file is part of the libiberty library, which is part of GCC.
@@ -192,9 +192,9 @@ static void d_init_info (const char *, int, size_t, struct d_info *);
 #else
 #ifdef __STDC__
 #ifdef __STDC_VERSION__
-#if __STDC_VERSION__ >= 199901L
+#if __STDC_VERSION__ >= 199901L && !__STDC_NO_VLA__
 #define CP_DYNAMIC_ARRAYS
-#endif /* __STDC__VERSION >= 199901L */
+#endif /* __STDC_VERSION__ >= 199901L && !__STDC_NO_VLA__ */
 #endif /* defined (__STDC_VERSION__) */
 #endif /* defined (__STDC__) */
 #endif /* ! defined (__GNUC__) */
@@ -429,7 +429,7 @@ static struct demangle_component *d_name (struct d_info *);
 
 static struct demangle_component *d_nested_name (struct d_info *);
 
-static struct demangle_component *d_prefix (struct d_info *);
+static struct demangle_component *d_prefix (struct d_info *, int);
 
 static struct demangle_component *d_unqualified_name (struct d_info *);
 
@@ -517,7 +517,7 @@ d_growable_string_callback_adapter (const char *, size_t, void *);
 
 static void
 d_print_init (struct d_print_info *, demangle_callbackref, void *,
-             const struct demangle_component *);
+             struct demangle_component *);
 
 static inline void d_print_error (struct d_print_info *);
 
@@ -625,6 +625,9 @@ d_dump (struct demangle_component *dc, int indent)
     case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
       printf ("template parameter %ld\n", dc->u.s_number.number);
       return;
+    case DEMANGLE_COMPONENT_TPARM_OBJ:
+      printf ("template parameter object\n");
+      break;
     case DEMANGLE_COMPONENT_FUNCTION_PARAM:
       printf ("function parameter %ld\n", dc->u.s_number.number);
       return;
@@ -858,9 +861,10 @@ CP_STATIC_IF_GLIBCPP_V3
 int
 cplus_demangle_fill_name (struct demangle_component *p, const char *s, int len)
 {
-  if (p == NULL || s == NULL || len == 0)
+  if (p == NULL || s == NULL || len <= 0)
     return 0;
   p->d_printing = 0;
+  p->d_counting = 0;
   p->type = DEMANGLE_COMPONENT_NAME;
   p->u.s_name.s = s;
   p->u.s_name.len = len;
@@ -877,6 +881,7 @@ cplus_demangle_fill_extended_operator (struct demangle_component *p, int args,
   if (p == NULL || args < 0 || name == NULL)
     return 0;
   p->d_printing = 0;
+  p->d_counting = 0;
   p->type = DEMANGLE_COMPONENT_EXTENDED_OPERATOR;
   p->u.s_extended_operator.args = args;
   p->u.s_extended_operator.name = name;
@@ -897,6 +902,7 @@ cplus_demangle_fill_ctor (struct demangle_component *p,
       || (int) kind > gnu_v3_object_ctor_group)
     return 0;
   p->d_printing = 0;
+  p->d_counting = 0;
   p->type = DEMANGLE_COMPONENT_CTOR;
   p->u.s_ctor.kind = kind;
   p->u.s_ctor.name = name;
@@ -917,6 +923,7 @@ cplus_demangle_fill_dtor (struct demangle_component *p,
       || (int) kind > gnu_v3_object_dtor_group)
     return 0;
   p->d_printing = 0;
+  p->d_counting = 0;
   p->type = DEMANGLE_COMPONENT_DTOR;
   p->u.s_dtor.kind = kind;
   p->u.s_dtor.name = name;
@@ -934,6 +941,7 @@ d_make_empty (struct d_info *di)
     return NULL;
   p = &di->comps[di->next_comp];
   p->d_printing = 0;
+  p->d_counting = 0;
   ++di->next_comp;
   return p;
 }
@@ -1007,6 +1015,7 @@ d_make_comp (struct d_info *di, enum demangle_component_type type,
     case DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS:
     case DEMANGLE_COMPONENT_NULLARY:
     case DEMANGLE_COMPONENT_TRINARY_ARG2:
+    case DEMANGLE_COMPONENT_TPARM_OBJ:
       if (left == NULL)
        return NULL;
       break;
@@ -1326,8 +1335,14 @@ d_encoding (struct d_info *di, int top_level)
             really apply here; this happens when parsing a class
             which is local to a function.  */
          if (dc->type == DEMANGLE_COMPONENT_LOCAL_NAME)
-           while (is_fnqual_component_type (d_right (dc)->type))
-             d_right (dc) = d_left (d_right (dc));
+           {
+             while (d_right (dc) != NULL
+                    && is_fnqual_component_type (d_right (dc)->type))
+               d_right (dc) = d_left (d_right (dc));
+
+             if (d_right (dc) == NULL)
+               dc = NULL;
+           }
        }
       else
        {
@@ -1495,7 +1510,7 @@ d_nested_name (struct d_info *di)
      once we have something to attach it to.  */
   rqual = d_ref_qualifier (di, NULL);
 
-  *pret = d_prefix (di);
+  *pret = d_prefix (di, 1);
   if (*pret == NULL)
     return NULL;
 
@@ -1521,10 +1536,12 @@ d_nested_name (struct d_info *di)
    <template-prefix> ::= <prefix> <(template) unqualified-name>
                      ::= <template-param>
                      ::= <substitution>
-*/
+
+   SUBST is true if we should add substitutions (as normal), false
+   if not (in an unresolved-name).  */
 
 static struct demangle_component *
-d_prefix (struct d_info *di)
+d_prefix (struct d_info *di, int subst)
 {
   struct demangle_component *ret = NULL;
 
@@ -1590,7 +1607,7 @@ d_prefix (struct d_info *di)
       else
        ret = d_make_comp (di, comb_type, ret, dc);
 
-      if (peek != 'S' && d_peek_char (di) != 'E')
+      if (peek != 'S' && d_peek_char (di) != 'E' && subst)
        {
          if (! d_add_substitution (di, ret))
            return NULL;
@@ -1617,9 +1634,15 @@ d_unqualified_name (struct d_info *di)
     ret = d_source_name (di);
   else if (IS_LOWER (peek))
     {
+      int was_expr = di->is_expression;
       if (peek == 'o' && d_peek_next_char (di) == 'n')
-       d_advance (di, 2);
+       {
+         d_advance (di, 2);
+         /* Treat cv as naming a conversion operator.  */
+         di->is_expression = 0;
+       }
       ret = d_operator_name (di);
+      di->is_expression = was_expr;
       if (ret != NULL && ret->type == DEMANGLE_COMPONENT_OPERATOR)
        {
          di->expansion += sizeof "operator" + ret->u.s_operator.op->len - 2;
@@ -1707,7 +1730,7 @@ d_number (struct d_info *di)
        }
       if (ret > ((INT_MAX - (peek - '0')) / 10))
         return -1;
-      ret = ret * 10 + peek - '0';
+      ret = ret * 10 + (peek - '0');
       d_advance (di, 1);
       peek = d_peek_char (di);
     }
@@ -1787,19 +1810,23 @@ const struct demangle_operator_info cplus_demangle_operators[] =
   { "ad", NL ("&"),         1 },
   { "an", NL ("&"),         2 },
   { "at", NL ("alignof "),   1 },
+  { "aw", NL ("co_await "), 1 },
   { "az", NL ("alignof "),   1 },
   { "cc", NL ("const_cast"), 2 },
   { "cl", NL ("()"),        2 },
   { "cm", NL (","),         2 },
   { "co", NL ("~"),         1 },
   { "dV", NL ("/="),        2 },
+  { "dX", NL ("[...]="),     3 }, /* [expr...expr] = expr */
   { "da", NL ("delete[] "), 1 },
   { "dc", NL ("dynamic_cast"), 2 },
   { "de", NL ("*"),         1 },
+  { "di", NL ("="),         2 }, /* .name = expr */
   { "dl", NL ("delete "),   1 },
   { "ds", NL (".*"),        2 },
   { "dt", NL ("."),         2 },
   { "dv", NL ("/"),         2 },
+  { "dx", NL ("]="),        2 }, /* [expr] = expr */
   { "eO", NL ("^="),        2 },
   { "eo", NL ("^"),         2 },
   { "eq", NL ("=="),        2 },
@@ -1844,6 +1871,7 @@ const struct demangle_operator_info cplus_demangle_operators[] =
   { "sP", NL ("sizeof..."), 1 },
   { "sZ", NL ("sizeof..."), 1 },
   { "sc", NL ("static_cast"), 2 },
+  { "ss", NL ("<=>"),       2 },
   { "st", NL ("sizeof "),   1 },
   { "sz", NL ("sizeof "),   1 },
   { "tr", NL ("throw"),     0 },
@@ -2007,6 +2035,7 @@ d_java_resource (struct d_info *di)
                   ::= TT <type>
                   ::= TI <type>
                   ::= TS <type>
+                 ::= TA <template-arg>
                   ::= GV <(object) name>
                   ::= T <call-offset> <(base) encoding>
                   ::= Tc <call-offset> <call-offset> <(base) encoding>
@@ -2099,6 +2128,10 @@ d_special_name (struct d_info *di)
          return d_make_comp (di, DEMANGLE_COMPONENT_TLS_WRAPPER,
                              d_name (di), NULL);
 
+       case 'A':
+         return d_make_comp (di, DEMANGLE_COMPONENT_TPARM_OBJ,
+                             d_template_arg (di), NULL);
+
        default:
          return NULL;
        }
@@ -2355,9 +2388,10 @@ cplus_demangle_builtin_types[D_BUILTIN_TYPE_COUNT] =
   /* 27 */ { NL ("decimal64"), NL ("decimal64"),       D_PRINT_DEFAULT },
   /* 28 */ { NL ("decimal128"),        NL ("decimal128"),      D_PRINT_DEFAULT },
   /* 29 */ { NL ("half"),      NL ("half"),            D_PRINT_FLOAT },
-  /* 30 */ { NL ("char16_t"),  NL ("char16_t"),        D_PRINT_DEFAULT },
-  /* 31 */ { NL ("char32_t"),  NL ("char32_t"),        D_PRINT_DEFAULT },
-  /* 32 */ { NL ("decltype(nullptr)"), NL ("decltype(nullptr)"),
+  /* 30 */ { NL ("char8_t"),   NL ("char8_t"),         D_PRINT_DEFAULT },
+  /* 31 */ { NL ("char16_t"),  NL ("char16_t"),        D_PRINT_DEFAULT },
+  /* 32 */ { NL ("char32_t"),  NL ("char32_t"),        D_PRINT_DEFAULT },
+  /* 33 */ { NL ("decltype(nullptr)"), NL ("decltype(nullptr)"),
             D_PRINT_DEFAULT },
 };
 
@@ -2645,14 +2679,19 @@ cplus_demangle_type (struct d_info *di)
          ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[29]);
          di->expansion += ret->u.s_builtin.type->len;
          break;
+       case 'u':
+         /* char8_t */
+         ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[30]);
+         di->expansion += ret->u.s_builtin.type->len;
+         break;
        case 's':
          /* char16_t */
-         ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[30]);
+         ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[31]);
          di->expansion += ret->u.s_builtin.type->len;
          break;
        case 'i':
          /* char32_t */
-         ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[31]);
+         ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[32]);
          di->expansion += ret->u.s_builtin.type->len;
          break;
 
@@ -2678,7 +2717,7 @@ cplus_demangle_type (struct d_info *di)
 
         case 'n':
           /* decltype(nullptr) */
-         ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[32]);
+         ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[33]);
          di->expansion += ret->u.s_builtin.type->len;
          break;
 
@@ -2843,21 +2882,35 @@ d_ref_qualifier (struct d_info *di, struct demangle_component *sub)
 static struct demangle_component *
 d_function_type (struct d_info *di)
 {
-  struct demangle_component *ret;
+  struct demangle_component *ret = NULL;
 
-  if (! d_check_char (di, 'F'))
-    return NULL;
-  if (d_peek_char (di) == 'Y')
+  if ((di->options & DMGL_NO_RECURSE_LIMIT) == 0)
     {
-      /* Function has C linkage.  We don't print this information.
-        FIXME: We should print it in verbose mode.  */
-      d_advance (di, 1);
+      if (di->recursion_level > DEMANGLE_RECURSION_LIMIT)
+       /* FIXME: There ought to be a way to report
+          that the recursion limit has been reached.  */
+       return NULL;
+
+      di->recursion_level ++;
     }
-  ret = d_bare_function_type (di, 1);
-  ret = d_ref_qualifier (di, ret);
 
-  if (! d_check_char (di, 'E'))
-    return NULL;
+  if (d_check_char (di, 'F'))
+    {
+      if (d_peek_char (di) == 'Y')
+       {
+         /* Function has C linkage.  We don't print this information.
+            FIXME: We should print it in verbose mode.  */
+         d_advance (di, 1);
+       }
+      ret = d_bare_function_type (di, 1);
+      ret = d_ref_qualifier (di, ret);
+      
+      if (! d_check_char (di, 'E'))
+       ret = NULL;
+    }
+
+  if ((di->options & DMGL_NO_RECURSE_LIMIT) == 0)
+    di->recursion_level --;
   return ret;
 }
 
@@ -3240,18 +3293,68 @@ op_is_new_cast (struct demangle_component *op)
              || code[0] == 'c' || code[0] == 'r'));
 }
 
+/*   <unresolved-name> ::= [gs] <base-unresolved-name> # x or (with "gs") ::x
+       ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x
+       # T::N::x /decltype(p)::N::x
+       ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
+       # A::x, N::y, A<T>::z; "gs" means leading "::"
+       ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
+
+     "gs" is handled elsewhere, as a unary operator.  */
+
+static struct demangle_component *
+d_unresolved_name (struct d_info *di)
+{
+  struct demangle_component *type;
+  struct demangle_component *name;
+  char peek;
+
+  /* Consume the "sr".  */
+  d_advance (di, 2);
+
+  peek = d_peek_char (di);
+  if (di->unresolved_name_state
+      && (IS_DIGIT (peek)
+         || IS_LOWER (peek)
+         || peek == 'C'
+         || peek == 'U'
+         || peek == 'L'))
+    {
+      /* The third production is ambiguous with the old unresolved-name syntax
+        of <type> <base-unresolved-name>; in the old mangling, A::x was mangled
+        as sr1A1x, now sr1AE1x.  So we first try to demangle using the new
+        mangling, then with the old if that fails.  */
+      di->unresolved_name_state = -1;
+      type = d_prefix (di, 0);
+      if (d_peek_char (di) == 'E')
+       d_advance (di, 1);
+    }
+  else
+    type = cplus_demangle_type (di);
+  name = d_unqualified_name (di);
+  if (d_peek_char (di) == 'I')
+    name = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, name,
+                       d_template_args (di));
+  return d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME, type, name);
+}
+
 /* <expression> ::= <(unary) operator-name> <expression>
                 ::= <(binary) operator-name> <expression> <expression>
                 ::= <(trinary) operator-name> <expression> <expression> <expression>
                ::= cl <expression>+ E
                 ::= st <type>
                 ::= <template-param>
-                ::= sr <type> <unqualified-name>
-                ::= sr <type> <unqualified-name> <template-args>
+               ::= <unresolved-name>
                 ::= <expr-primary>
+
+  <braced-expression> ::= <expression>
+                     ::= di <field source-name> <braced-expression>    # .name = expr
+                     ::= dx <index expression> <braced-expression>     # [expr] = expr
+                     ::= dX <range begin expression> <range end expression> <braced-expression>
+                                                                       # [expr ... expr] = expr
 */
 
-static inline struct demangle_component *
+static struct demangle_component *
 d_expression_1 (struct d_info *di)
 {
   char peek;
@@ -3262,20 +3365,7 @@ d_expression_1 (struct d_info *di)
   else if (peek == 'T')
     return d_template_param (di);
   else if (peek == 's' && d_peek_next_char (di) == 'r')
-    {
-      struct demangle_component *type;
-      struct demangle_component *name;
-
-      d_advance (di, 2);
-      type = cplus_demangle_type (di);
-      name = d_unqualified_name (di);
-      if (d_peek_char (di) != 'I')
-       return d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME, type, name);
-      else
-       return d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME, type,
-                           d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, name,
-                                        d_template_args (di)));
-    }
+    return d_unresolved_name (di);
   else if (peek == 's' && d_peek_next_char (di) == 'p')
     {
       d_advance (di, 2);
@@ -3327,11 +3417,11 @@ d_expression_1 (struct d_info *di)
     {
       /* Brace-enclosed initializer list, untyped or typed.  */
       struct demangle_component *type = NULL;
+      d_advance (di, 2);
       if (peek == 't')
        type = cplus_demangle_type (di);
-      if (!d_peek_next_char (di))
+      if (!d_peek_char (di) || !d_peek_next_char (di))
        return NULL;
-      d_advance (di, 2);
       return d_make_comp (di, DEMANGLE_COMPONENT_INITIALIZER_LIST,
                          type, d_exprlist (di, 'E'));
     }
@@ -3411,16 +3501,30 @@ d_expression_1 (struct d_info *di)
            else if (code[0] == 'f')
              /* fold-expression.  */
              left = d_operator_name (di);
+           else if (!strcmp (code, "di"))
+             left = d_unqualified_name (di);
            else
              left = d_expression_1 (di);
            if (!strcmp (code, "cl"))
              right = d_exprlist (di, 'E');
            else if (!strcmp (code, "dt") || !strcmp (code, "pt"))
              {
-               right = d_unqualified_name (di);
-               if (d_peek_char (di) == 'I')
-                 right = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE,
-                                      right, d_template_args (di));
+               peek = d_peek_char (di);
+               /* These codes start a qualified name.  */
+               if ((peek == 'g' && d_peek_next_char (di) == 's')
+                   || (peek == 's' && d_peek_next_char (di) == 'r'))
+                 right = d_expression_1 (di);
+               else
+                 {
+                   /* Otherwise it's an unqualified name.  We use
+                      d_unqualified_name rather than d_expression_1 here for
+                      old mangled names that didn't add 'on' before operator
+                      names.  */
+                   right = d_unqualified_name (di);
+                   if (d_peek_char (di) == 'I')
+                     right = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE,
+                                          right, d_template_args (di));
+                 }
              }
            else
              right = d_expression_1 (di);
@@ -3438,7 +3542,8 @@ d_expression_1 (struct d_info *di)
 
            if (code == NULL)
              return NULL;
-           else if (!strcmp (code, "qu"))
+           else if (!strcmp (code, "qu")
+                    || !strcmp (code, "dX"))
              {
                /* ?: expression.  */
                first = d_expression_1 (di);
@@ -3542,6 +3647,17 @@ d_expr_primary (struct d_info *di)
          && type->u.s_builtin.type->print != D_PRINT_DEFAULT)
        di->expansion -= type->u.s_builtin.type->len;
 
+      if (type->type == DEMANGLE_COMPONENT_BUILTIN_TYPE
+         && strcmp (type->u.s_builtin.type->name,
+                    cplus_demangle_builtin_types[33].name) == 0)
+       {
+         if (d_peek_char (di) == 'E')
+           {
+             d_advance (di, 1);
+             return type;
+           }
+       }
+
       /* Rather than try to interpret the literal value, we just
         collect it as a string.  Note that it's possible to have a
         floating point literal here.  The ABI specifies that the
@@ -3711,9 +3827,6 @@ d_lambda (struct d_info *di)
       ret->u.s_unary_num.num = num;
     }
 
-  if (! d_add_substitution (di, ret))
-    return NULL;
-
   return ret;
 }
 
@@ -4032,12 +4145,14 @@ d_growable_string_callback_adapter (const char *s, size_t l, void *opaque)
    are larger than the actual numbers encountered.  */
 
 static void
-d_count_templates_scopes (int *num_templates, int *num_scopes,
-                         const struct demangle_component *dc)
+d_count_templates_scopes (struct d_print_info *dpi,
+                         struct demangle_component *dc)
 {
-  if (dc == NULL)
+  if (dc == NULL || dc->d_counting > 1 || dpi->recursion > MAX_RECURSION_COUNT)
     return;
 
+  ++ dc->d_counting;
+
   switch (dc->type)
     {
     case DEMANGLE_COMPONENT_NAME:
@@ -4052,13 +4167,13 @@ d_count_templates_scopes (int *num_templates, int *num_scopes,
       break;
 
     case DEMANGLE_COMPONENT_TEMPLATE:
-      (*num_templates)++;
+      dpi->num_copy_templates++;
       goto recurse_left_right;
 
     case DEMANGLE_COMPONENT_REFERENCE:
     case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
       if (d_left (dc)->type == DEMANGLE_COMPONENT_TEMPLATE_PARAM)
-       (*num_scopes)++;
+       dpi->num_saved_scopes++;
       goto recurse_left_right;
 
     case DEMANGLE_COMPONENT_QUAL_NAME:
@@ -4101,6 +4216,7 @@ d_count_templates_scopes (int *num_templates, int *num_scopes,
     case DEMANGLE_COMPONENT_VECTOR_TYPE:
     case DEMANGLE_COMPONENT_ARGLIST:
     case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
+    case DEMANGLE_COMPONENT_TPARM_OBJ:
     case DEMANGLE_COMPONENT_INITIALIZER_LIST:
     case DEMANGLE_COMPONENT_CAST:
     case DEMANGLE_COMPONENT_CONVERSION:
@@ -4122,42 +4238,42 @@ d_count_templates_scopes (int *num_templates, int *num_scopes,
     case DEMANGLE_COMPONENT_TAGGED_NAME:
     case DEMANGLE_COMPONENT_CLONE:
     recurse_left_right:
-      d_count_templates_scopes (num_templates, num_scopes,
-                               d_left (dc));
-      d_count_templates_scopes (num_templates, num_scopes,
-                               d_right (dc));
+      /* PR 89394 - Check for too much recursion.  */
+      if (dpi->recursion > DEMANGLE_RECURSION_LIMIT)
+       /* FIXME: There ought to be a way to report to the
+          user that the recursion limit has been reached.  */
+       return;
+
+      ++ dpi->recursion;
+      d_count_templates_scopes (dpi, d_left (dc));
+      d_count_templates_scopes (dpi, d_right (dc));
+      -- dpi->recursion;
       break;
 
     case DEMANGLE_COMPONENT_CTOR:
-      d_count_templates_scopes (num_templates, num_scopes,
-                               dc->u.s_ctor.name);
+      d_count_templates_scopes (dpi, dc->u.s_ctor.name);
       break;
 
     case DEMANGLE_COMPONENT_DTOR:
-      d_count_templates_scopes (num_templates, num_scopes,
-                               dc->u.s_dtor.name);
+      d_count_templates_scopes (dpi, dc->u.s_dtor.name);
       break;
 
     case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
-      d_count_templates_scopes (num_templates, num_scopes,
-                               dc->u.s_extended_operator.name);
+      d_count_templates_scopes (dpi, dc->u.s_extended_operator.name);
       break;
 
     case DEMANGLE_COMPONENT_FIXED_TYPE:
-      d_count_templates_scopes (num_templates, num_scopes,
-                                dc->u.s_fixed.length);
+      d_count_templates_scopes (dpi, dc->u.s_fixed.length);
       break;
 
     case DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS:
     case DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS:
-      d_count_templates_scopes (num_templates, num_scopes,
-                               d_left (dc));
+      d_count_templates_scopes (dpi, d_left (dc));
       break;
 
     case DEMANGLE_COMPONENT_LAMBDA:
     case DEMANGLE_COMPONENT_DEFAULT_ARG:
-      d_count_templates_scopes (num_templates, num_scopes,
-                               dc->u.s_unary_num.sub);
+      d_count_templates_scopes (dpi, dc->u.s_unary_num.sub);
       break;
     }
 }
@@ -4166,7 +4282,7 @@ d_count_templates_scopes (int *num_templates, int *num_scopes,
 
 static void
 d_print_init (struct d_print_info *dpi, demangle_callbackref callback,
-             void *opaque, const struct demangle_component *dc)
+             void *opaque, struct demangle_component *dc)
 {
   dpi->len = 0;
   dpi->last_char = '\0';
@@ -4192,8 +4308,12 @@ d_print_init (struct d_print_info *dpi, demangle_callbackref callback,
   dpi->next_copy_template = 0;
   dpi->num_copy_templates = 0;
 
-  d_count_templates_scopes (&dpi->num_copy_templates,
-                           &dpi->num_saved_scopes, dc);
+  d_count_templates_scopes (dpi, dc);
+  /* If we did not reach the recursion limit, then reset the
+     current recursion value back to 0, so that we can print
+     the templates.  */
+  if (dpi->recursion < DEMANGLE_RECURSION_LIMIT)
+    dpi->recursion = 0;
   dpi->num_copy_templates *= dpi->num_saved_scopes;
 
   dpi->current_template = NULL;
@@ -4615,6 +4735,64 @@ d_maybe_print_fold_expression (struct d_print_info *dpi, int options,
   return 1;
 }
 
+/* True iff DC represents a C99-style designated initializer.  */
+
+static int
+is_designated_init (struct demangle_component *dc)
+{
+  if (dc->type != DEMANGLE_COMPONENT_BINARY
+      && dc->type != DEMANGLE_COMPONENT_TRINARY)
+    return 0;
+
+  struct demangle_component *op = d_left (dc);
+  const char *code = op->u.s_operator.op->code;
+  return (code[0] == 'd'
+         && (code[1] == 'i' || code[1] == 'x' || code[1] == 'X'));
+}
+
+/* If DC represents a C99-style designated initializer, print it and return
+   true; otherwise, return false.  */
+
+static int
+d_maybe_print_designated_init (struct d_print_info *dpi, int options,
+                              struct demangle_component *dc)
+{
+  if (!is_designated_init (dc))
+    return 0;
+
+  const char *code = d_left (dc)->u.s_operator.op->code;
+
+  struct demangle_component *operands = d_right (dc);
+  struct demangle_component *op1 = d_left (operands);
+  struct demangle_component *op2 = d_right (operands);
+
+  if (code[1] == 'i')
+    d_append_char (dpi, '.');
+  else
+    d_append_char (dpi, '[');
+
+  d_print_comp (dpi, options, op1);
+  if (code[1] == 'X')
+    {
+      d_append_string (dpi, " ... ");
+      d_print_comp (dpi, options, d_left (op2));
+      op2 = d_right (op2);
+    }
+  if (code[1] != 'i')
+    d_append_char (dpi, ']');
+  if (is_designated_init (op2))
+    {
+      /* Don't put '=' or '(' between chained designators.  */
+      d_print_comp (dpi, options, op2);
+    }
+  else
+    {
+      d_append_char (dpi, '=');
+      d_print_subexpr (dpi, options, op2);
+    }
+  return 1;
+}
+
 /* Subroutine to handle components.  */
 
 static void
@@ -4727,12 +4905,8 @@ d_print_comp_inner (struct d_print_info *dpi, int options,
            typed_name = d_right (typed_name);
            if (typed_name->type == DEMANGLE_COMPONENT_DEFAULT_ARG)
              typed_name = typed_name->u.s_unary_num.sub;
-           if (typed_name == NULL)
-             {
-               d_print_error (dpi);
-               return;
-             }
-           while (is_fnqual_component_type (typed_name->type))
+           while (typed_name != NULL
+                  && is_fnqual_component_type (typed_name->type))
              {
                if (i >= sizeof adpm / sizeof adpm[0])
                  {
@@ -4751,6 +4925,11 @@ d_print_comp_inner (struct d_print_info *dpi, int options,
 
                typed_name = d_left (typed_name);
              }
+           if (typed_name == NULL)
+             {
+               d_print_error (dpi);
+               return;
+             }
          }
 
        /* If typed_name is a template, then it applies to the
@@ -4872,6 +5051,11 @@ d_print_comp_inner (struct d_print_info *dpi, int options,
        }
       return;
 
+    case DEMANGLE_COMPONENT_TPARM_OBJ:
+      d_append_string (dpi, "template parameter object for ");
+      d_print_comp (dpi, options, d_left (dc));
+      return;
+
     case DEMANGLE_COMPONENT_CTOR:
       d_print_comp (dpi, options, dc->u.s_ctor.name);
       return;
@@ -5325,9 +5509,18 @@ d_print_comp_inner (struct d_print_info *dpi, int options,
       }
 
     case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
-      d_append_string (dpi, "operator ");
-      d_print_comp (dpi, options, dc->u.s_extended_operator.name);
-      return;
+      {
+       struct demangle_component *name = dc->u.s_extended_operator.name;
+       if (name->type == DEMANGLE_COMPONENT_NAME
+           && !strncmp (name->u.s_name.s, "__alignof__", name->u.s_name.len))
+         d_print_comp (dpi, options, dc->u.s_extended_operator.name);
+       else
+         {
+           d_append_string (dpi, "operator ");
+           d_print_comp (dpi, options, dc->u.s_extended_operator.name);
+         }
+       return;
+      }
 
     case DEMANGLE_COMPONENT_CONVERSION:
       d_append_string (dpi, "operator ");
@@ -5392,8 +5585,14 @@ d_print_comp_inner (struct d_print_info *dpi, int options,
        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).  */
+       else if ((code && !strcmp (code, "st"))
+                || (op->type == DEMANGLE_COMPONENT_EXTENDED_OPERATOR
+                    && (op->u.s_extended_operator.name->type
+                        == DEMANGLE_COMPONENT_NAME)
+                    && !strncmp (op->u.s_extended_operator.name->u.s_name.s,
+                                 "__alignof__",
+                                 op->u.s_extended_operator.name->u.s_name.len)))
+         /* Always print parens for sizeof (type) and __alignof__.  */
          {
            d_append_char (dpi, '(');
            d_print_comp (dpi, options, operand);
@@ -5425,6 +5624,9 @@ d_print_comp_inner (struct d_print_info *dpi, int options,
       if (d_maybe_print_fold_expression (dpi, options, dc))
        return;
 
+      if (d_maybe_print_designated_init (dpi, options, dc))
+       return;
+
       /* We wrap an expression which uses the greater-than operator in
         an extra layer of parens so that it does not get confused
         with the '>' which ends the template parameters.  */
@@ -5482,6 +5684,8 @@ d_print_comp_inner (struct d_print_info *dpi, int options,
        }
       if (d_maybe_print_fold_expression (dpi, options, dc))
        return;
+      if (d_maybe_print_designated_init (dpi, options, dc))
+       return;
       {
        struct demangle_component *op = d_left (dc);
        struct demangle_component *first = d_left (d_right (dc));
@@ -5931,10 +6135,10 @@ d_print_mod (struct d_print_info *dpi, int options,
       d_append_string (dpi, "&&");
       return;
     case DEMANGLE_COMPONENT_COMPLEX:
-      d_append_string (dpi, "complex ");
+      d_append_string (dpi, " _Complex");
       return;
     case DEMANGLE_COMPONENT_IMAGINARY:
-      d_append_string (dpi, "imaginary ");
+      d_append_string (dpi, " _Imaginary");
       return;
     case DEMANGLE_COMPONENT_PTRMEM_TYPE:
       if (d_last_char (dpi) != '(')
@@ -6172,13 +6376,13 @@ cplus_demangle_init_info (const char *mangled, int options, size_t len,
 
   di->n = mangled;
 
-  /* We can not need more components than twice the number of chars in
+  /* We cannot need more components than twice the number of chars in
      the mangled string.  Most components correspond directly to
      chars, but the ARGLIST types are exceptions.  */
   di->num_comps = 2 * len;
   di->next_comp = 0;
 
-  /* Similarly, we can not need more substitutions than there are
+  /* Similarly, we cannot need more substitutions than there are
      chars in the mangled string.  */
   di->num_subs = len;
   di->next_sub = 0;
@@ -6188,6 +6392,7 @@ cplus_demangle_init_info (const char *mangled, int options, size_t len,
   di->expansion = 0;
   di->is_expression = 0;
   di->is_conversion = 0;
+  di->recursion_level = 0;
 }
 
 /* Internal implementation for the demangler.  If MANGLED is a g++ v3 ABI
@@ -6225,8 +6430,25 @@ d_demangle_callback (const char *mangled, int options,
       type = DCT_TYPE;
     }
 
+  di.unresolved_name_state = 1;
+
+ again:
   cplus_demangle_init_info (mangled, options, strlen (mangled), &di);
 
+  /* PR 87675 - Check for a mangled string that is so long
+     that we do not have enough stack space to demangle it.  */
+  if (((options & DMGL_NO_RECURSE_LIMIT) == 0)
+      /* This check is a bit arbitrary, since what we really want to do is to
+        compare the sizes of the di.comps and di.subs arrays against the
+        amount of stack space remaining.  But there is no portable way to do
+        this, so instead we use the recursion limit as a guide to the maximum
+        size of the arrays.  */
+      && (unsigned long) di.num_comps > DEMANGLE_RECURSION_LIMIT)
+    {
+      /* FIXME: We need a way to indicate that a stack limit has been reached.  */
+      return 0;
+    }
+
   {
 #ifdef CP_DYNAMIC_ARRAYS
     __extension__ struct demangle_component comps[di.num_comps];
@@ -6269,6 +6491,13 @@ d_demangle_callback (const char *mangled, int options,
     if (((options & DMGL_PARAMS) != 0) && d_peek_char (&di) != '\0')
       dc = NULL;
 
+    /* See discussion in d_unresolved_name.  */
+    if (dc == NULL && di.unresolved_name_state == -1)
+      {
+       di.unresolved_name_state = 0;
+       goto again;
+      }
+
 #ifdef CP_DEMANGLE_DEBUG
     d_dump (dc, 0);
 #endif
This page took 0.035785 seconds and 4 git commands to generate.