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;
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;
::= TT <type>
::= TI <type>
::= TS <type>
+ ::= TA <template-arg>
::= GV <(object) name>
::= T <call-offset> <(base) encoding>
::= Tc <call-offset> <call-offset> <(base) encoding>
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;
}
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;
}
{
/* 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))
return NULL;
- d_advance (di, 2);
return d_make_comp (di, DEMANGLE_COMPONENT_INITIALIZER_LIST,
type, d_exprlist (di, 'E'));
}
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:
}
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;
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
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];