1,5 → 1,5 |
/* Demangler for g++ V3 ABI. |
Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 |
Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2014 |
Free Software Foundation, Inc. |
Written by Ian Lance Taylor <ian@wasabisystems.com>. |
|
275,6 → 275,41 |
int allocation_failure; |
}; |
|
/* Stack of components, innermost first, used to avoid loops. */ |
|
struct d_component_stack |
{ |
/* This component. */ |
const struct demangle_component *dc; |
/* This component's parent. */ |
const struct d_component_stack *parent; |
}; |
|
/* A demangle component and some scope captured when it was first |
traversed. */ |
|
struct d_saved_scope |
{ |
/* The component whose scope this is. */ |
const struct demangle_component *container; |
/* The list of templates, if any, that was current when this |
scope was captured. */ |
struct d_print_template *templates; |
}; |
|
/* Checkpoint structure to allow backtracking. This holds copies |
of the fields of struct d_info that need to be restored |
if a trial parse needs to be backtracked over. */ |
|
struct d_info_checkpoint |
{ |
const char *n; |
int next_comp; |
int next_sub; |
int did_subs; |
int expansion; |
}; |
|
enum { D_PRINT_BUFFER_LENGTH = 256 }; |
struct d_print_info |
{ |
302,6 → 337,22 |
int pack_index; |
/* Number of d_print_flush calls so far. */ |
unsigned long int flush_count; |
/* Stack of components, innermost first, used to avoid loops. */ |
const struct d_component_stack *component_stack; |
/* Array of saved scopes for evaluating substitutions. */ |
struct d_saved_scope *saved_scopes; |
/* Index of the next unused saved scope in the above array. */ |
int next_saved_scope; |
/* Number of saved scopes in the above array. */ |
int num_saved_scopes; |
/* Array of templates for saving into scopes. */ |
struct d_print_template *copy_templates; |
/* Index of the next unused copy template in the above array. */ |
int next_copy_template; |
/* Number of copy templates in the above array. */ |
int num_copy_templates; |
/* The nearest enclosing template, if any. */ |
const struct demangle_component *current_template; |
}; |
|
#ifdef CP_DEMANGLE_DEBUG |
428,6 → 479,10 |
|
static struct demangle_component *d_substitution (struct d_info *, int); |
|
static void d_checkpoint (struct d_info *, struct d_info_checkpoint *); |
|
static void d_backtrack (struct d_info *, struct d_info_checkpoint *); |
|
static void d_growable_string_init (struct d_growable_string *, size_t); |
|
static inline void |
440,7 → 495,8 |
d_growable_string_callback_adapter (const char *, size_t, void *); |
|
static void |
d_print_init (struct d_print_info *, demangle_callbackref, void *); |
d_print_init (struct d_print_info *, demangle_callbackref, void *, |
const struct demangle_component *); |
|
static inline void d_print_error (struct d_print_info *); |
|
519,6 → 575,9 |
case DEMANGLE_COMPONENT_TEMPLATE_PARAM: |
printf ("template parameter %ld\n", dc->u.s_number.number); |
return; |
case DEMANGLE_COMPONENT_FUNCTION_PARAM: |
printf ("function parameter %ld\n", dc->u.s_number.number); |
return; |
case DEMANGLE_COMPONENT_CTOR: |
printf ("constructor %d\n", (int) dc->u.s_ctor.kind); |
d_dump (dc->u.s_ctor.name, indent + 2); |
654,7 → 713,9 |
printf ("pointer to member type\n"); |
break; |
case DEMANGLE_COMPONENT_FIXED_TYPE: |
printf ("fixed-point type\n"); |
printf ("fixed-point type, accum? %d, sat? %d\n", |
dc->u.s_fixed.accum, dc->u.s_fixed.sat); |
d_dump (dc->u.s_fixed.length, indent + 2) |
break; |
case DEMANGLE_COMPONENT_ARGLIST: |
printf ("argument list\n"); |
704,6 → 765,9 |
case DEMANGLE_COMPONENT_CHARACTER: |
printf ("character '%c'\n", dc->u.s_character.character); |
return; |
case DEMANGLE_COMPONENT_NUMBER: |
printf ("number %ld\n", dc->u.s_number.number); |
return; |
case DEMANGLE_COMPONENT_DECLTYPE: |
printf ("decltype\n"); |
break; |
1238,7 → 1302,12 |
static struct demangle_component * |
d_abi_tags (struct d_info *di, struct demangle_component *dc) |
{ |
struct demangle_component *hold_last_name; |
char peek; |
|
/* Preserve the last name, so the ABI tag doesn't clobber it. */ |
hold_last_name = di->last_name; |
|
while (peek = d_peek_char (di), |
peek == 'B') |
{ |
1247,6 → 1316,9 |
tag = d_source_name (di); |
dc = d_make_comp (di, DEMANGLE_COMPONENT_TAGGED_NAME, dc, tag); |
} |
|
di->last_name = hold_last_name; |
|
return dc; |
} |
|
1276,7 → 1348,6 |
case 'Z': |
return d_local_name (di); |
|
case 'L': |
case 'U': |
return d_unqualified_name (di); |
|
1323,6 → 1394,7 |
return dc; |
} |
|
case 'L': |
default: |
dc = d_unqualified_name (di); |
if (d_peek_char (di) == 'I') |
1718,8 → 1790,15 |
if (c1 == 'v' && IS_DIGIT (c2)) |
return d_make_extended_operator (di, c2 - '0', d_source_name (di)); |
else if (c1 == 'c' && c2 == 'v') |
return d_make_comp (di, DEMANGLE_COMPONENT_CAST, |
cplus_demangle_type (di), NULL); |
{ |
struct demangle_component *type; |
int was_conversion = di->is_conversion; |
|
di->is_conversion = ! di->is_expression; |
type = cplus_demangle_type (di); |
di->is_conversion = was_conversion; |
return d_make_comp (di, DEMANGLE_COMPONENT_CAST, type, NULL); |
} |
else |
{ |
/* LOW is the inclusive lower bound. */ |
2065,6 → 2144,9 |
case '3': |
kind = gnu_v3_complete_object_allocating_ctor; |
break; |
case '4': |
kind = gnu_v3_unified_ctor; |
break; |
case '5': |
kind = gnu_v3_object_ctor_group; |
break; |
2090,6 → 2172,10 |
case '2': |
kind = gnu_v3_base_object_dtor; |
break; |
/* digit '3' is not used */ |
case '4': |
kind = gnu_v3_unified_dtor; |
break; |
case '5': |
kind = gnu_v3_object_dtor_group; |
break; |
2268,14 → 2354,62 |
ret = d_template_param (di); |
if (d_peek_char (di) == 'I') |
{ |
/* This is <template-template-param> <template-args>. The |
<template-template-param> part is a substitution |
/* This may be <template-template-param> <template-args>. |
If this is the type for a conversion operator, we can |
have a <template-template-param> here only by following |
a derivation like this: |
|
<nested-name> |
-> <template-prefix> <template-args> |
-> <prefix> <template-unqualified-name> <template-args> |
-> <unqualified-name> <template-unqualified-name> <template-args> |
-> <source-name> <template-unqualified-name> <template-args> |
-> <source-name> <operator-name> <template-args> |
-> <source-name> cv <type> <template-args> |
-> <source-name> cv <template-template-param> <template-args> <template-args> |
|
where the <template-args> is followed by another. |
Otherwise, we must have a derivation like this: |
|
<nested-name> |
-> <template-prefix> <template-args> |
-> <prefix> <template-unqualified-name> <template-args> |
-> <unqualified-name> <template-unqualified-name> <template-args> |
-> <source-name> <template-unqualified-name> <template-args> |
-> <source-name> <operator-name> <template-args> |
-> <source-name> cv <type> <template-args> |
-> <source-name> cv <template-param> <template-args> |
|
where we need to leave the <template-args> to be processed |
by d_prefix (following the <template-prefix>). |
|
The <template-template-param> part is a substitution |
candidate. */ |
if (! di->is_conversion) |
{ |
if (! d_add_substitution (di, ret)) |
return NULL; |
ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret, |
d_template_args (di)); |
} |
else |
{ |
struct demangle_component *args; |
struct d_info_checkpoint checkpoint; |
|
d_checkpoint (di, &checkpoint); |
args = d_template_args (di); |
if (d_peek_char (di) == 'I') |
{ |
if (! d_add_substitution (di, ret)) |
return NULL; |
ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret, |
args); |
} |
else |
d_backtrack (di, &checkpoint); |
} |
} |
break; |
|
case 'S': |
2344,6 → 2478,9 |
case 'U': |
d_advance (di, 1); |
ret = d_source_name (di); |
if (d_peek_char (di) == 'I') |
ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret, |
d_template_args (di)); |
ret = d_make_comp (di, DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL, |
cplus_demangle_type (di), ret); |
break; |
2960,8 → 3097,8 |
::= <expr-primary> |
*/ |
|
static struct demangle_component * |
d_expression (struct d_info *di) |
static inline struct demangle_component * |
d_expression_1 (struct d_info *di) |
{ |
char peek; |
|
2989,7 → 3126,7 |
{ |
d_advance (di, 2); |
return d_make_comp (di, DEMANGLE_COMPONENT_PACK_EXPANSION, |
d_expression (di), NULL); |
d_expression_1 (di), NULL); |
} |
else if (peek == 'f' && d_peek_next_char (di) == 'p') |
{ |
3094,7 → 3231,7 |
&& d_check_char (di, '_')) |
operand = d_exprlist (di, 'E'); |
else |
operand = d_expression (di); |
operand = d_expression_1 (di); |
|
if (suffix) |
/* Indicate the suffix variant for d_print_comp. */ |
3114,7 → 3251,7 |
if (op_is_new_cast (op)) |
left = cplus_demangle_type (di); |
else |
left = d_expression (di); |
left = d_expression_1 (di); |
if (!strcmp (code, "cl")) |
right = d_exprlist (di, 'E'); |
else if (!strcmp (code, "dt") || !strcmp (code, "pt")) |
3125,7 → 3262,7 |
right, d_template_args (di)); |
} |
else |
right = d_expression (di); |
right = d_expression_1 (di); |
|
return d_make_comp (di, DEMANGLE_COMPONENT_BINARY, op, |
d_make_comp (di, |
3141,9 → 3278,9 |
if (!strcmp (code, "qu")) |
{ |
/* ?: expression. */ |
first = d_expression (di); |
second = d_expression (di); |
third = d_expression (di); |
first = d_expression_1 (di); |
second = d_expression_1 (di); |
third = d_expression_1 (di); |
} |
else if (code[0] == 'n') |
{ |
3167,7 → 3304,7 |
else if (d_peek_char (di) == 'i' |
&& d_peek_next_char (di) == 'l') |
/* initializer-list. */ |
third = d_expression (di); |
third = d_expression_1 (di); |
else |
return NULL; |
} |
3187,6 → 3324,18 |
} |
} |
|
static struct demangle_component * |
d_expression (struct d_info *di) |
{ |
struct demangle_component *ret; |
int was_expression = di->is_expression; |
|
di->is_expression = 1; |
ret = d_expression_1 (di); |
di->is_expression = was_expression; |
return ret; |
} |
|
/* <expr-primary> ::= L <type> <(value) number> E |
::= L <type> <(value) float> E |
::= L <mangled-name> E |
3549,6 → 3698,7 |
{ |
const char *s; |
int len; |
struct demangle_component *c; |
|
if (p->set_last_name != NULL) |
di->last_name = d_make_sub (di, p->set_last_name, |
3564,14 → 3714,42 |
len = p->simple_len; |
} |
di->expansion += len; |
return d_make_sub (di, s, len); |
c = d_make_sub (di, s, len); |
if (d_peek_char (di) == 'B') |
{ |
/* If there are ABI tags on the abbreviation, it becomes |
a substitution candidate. */ |
c = d_abi_tags (di, c); |
d_add_substitution (di, c); |
} |
return c; |
} |
} |
|
return NULL; |
} |
} |
|
static void |
d_checkpoint (struct d_info *di, struct d_info_checkpoint *checkpoint) |
{ |
checkpoint->n = di->n; |
checkpoint->next_comp = di->next_comp; |
checkpoint->next_sub = di->next_sub; |
checkpoint->did_subs = di->did_subs; |
checkpoint->expansion = di->expansion; |
} |
|
static void |
d_backtrack (struct d_info *di, struct d_info_checkpoint *checkpoint) |
{ |
di->n = checkpoint->n; |
di->next_comp = checkpoint->next_comp; |
di->next_sub = checkpoint->next_sub; |
di->did_subs = checkpoint->did_subs; |
di->expansion = checkpoint->expansion; |
} |
|
/* Initialize a growable string. */ |
|
static void |
3648,11 → 3826,145 |
d_growable_string_append_buffer (dgs, s, l); |
} |
|
/* Walk the tree, counting the number of templates encountered, and |
the number of times a scope might be saved. These counts will be |
used to allocate data structures for d_print_comp, so the logic |
here must mirror the logic d_print_comp will use. It is not |
important that the resulting numbers are exact, so long as they |
are larger than the actual numbers encountered. */ |
|
static void |
d_count_templates_scopes (int *num_templates, int *num_scopes, |
const struct demangle_component *dc) |
{ |
if (dc == NULL) |
return; |
|
switch (dc->type) |
{ |
case DEMANGLE_COMPONENT_NAME: |
case DEMANGLE_COMPONENT_TEMPLATE_PARAM: |
case DEMANGLE_COMPONENT_FUNCTION_PARAM: |
case DEMANGLE_COMPONENT_SUB_STD: |
case DEMANGLE_COMPONENT_BUILTIN_TYPE: |
case DEMANGLE_COMPONENT_OPERATOR: |
case DEMANGLE_COMPONENT_CHARACTER: |
case DEMANGLE_COMPONENT_NUMBER: |
case DEMANGLE_COMPONENT_UNNAMED_TYPE: |
break; |
|
case DEMANGLE_COMPONENT_TEMPLATE: |
(*num_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)++; |
goto recurse_left_right; |
|
case DEMANGLE_COMPONENT_QUAL_NAME: |
case DEMANGLE_COMPONENT_LOCAL_NAME: |
case DEMANGLE_COMPONENT_TYPED_NAME: |
case DEMANGLE_COMPONENT_VTABLE: |
case DEMANGLE_COMPONENT_VTT: |
case DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE: |
case DEMANGLE_COMPONENT_TYPEINFO: |
case DEMANGLE_COMPONENT_TYPEINFO_NAME: |
case DEMANGLE_COMPONENT_TYPEINFO_FN: |
case DEMANGLE_COMPONENT_THUNK: |
case DEMANGLE_COMPONENT_VIRTUAL_THUNK: |
case DEMANGLE_COMPONENT_COVARIANT_THUNK: |
case DEMANGLE_COMPONENT_JAVA_CLASS: |
case DEMANGLE_COMPONENT_GUARD: |
case DEMANGLE_COMPONENT_TLS_INIT: |
case DEMANGLE_COMPONENT_TLS_WRAPPER: |
case DEMANGLE_COMPONENT_REFTEMP: |
case DEMANGLE_COMPONENT_HIDDEN_ALIAS: |
case DEMANGLE_COMPONENT_RESTRICT: |
case DEMANGLE_COMPONENT_VOLATILE: |
case DEMANGLE_COMPONENT_CONST: |
case DEMANGLE_COMPONENT_RESTRICT_THIS: |
case DEMANGLE_COMPONENT_VOLATILE_THIS: |
case DEMANGLE_COMPONENT_CONST_THIS: |
case DEMANGLE_COMPONENT_REFERENCE_THIS: |
case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS: |
case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL: |
case DEMANGLE_COMPONENT_POINTER: |
case DEMANGLE_COMPONENT_COMPLEX: |
case DEMANGLE_COMPONENT_IMAGINARY: |
case DEMANGLE_COMPONENT_VENDOR_TYPE: |
case DEMANGLE_COMPONENT_FUNCTION_TYPE: |
case DEMANGLE_COMPONENT_ARRAY_TYPE: |
case DEMANGLE_COMPONENT_PTRMEM_TYPE: |
case DEMANGLE_COMPONENT_VECTOR_TYPE: |
case DEMANGLE_COMPONENT_ARGLIST: |
case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST: |
case DEMANGLE_COMPONENT_INITIALIZER_LIST: |
case DEMANGLE_COMPONENT_CAST: |
case DEMANGLE_COMPONENT_NULLARY: |
case DEMANGLE_COMPONENT_UNARY: |
case DEMANGLE_COMPONENT_BINARY: |
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_JAVA_RESOURCE: |
case DEMANGLE_COMPONENT_COMPOUND_NAME: |
case DEMANGLE_COMPONENT_DECLTYPE: |
case DEMANGLE_COMPONENT_TRANSACTION_CLONE: |
case DEMANGLE_COMPONENT_NONTRANSACTION_CLONE: |
case DEMANGLE_COMPONENT_PACK_EXPANSION: |
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)); |
break; |
|
case DEMANGLE_COMPONENT_CTOR: |
d_count_templates_scopes (num_templates, num_scopes, |
dc->u.s_ctor.name); |
break; |
|
case DEMANGLE_COMPONENT_DTOR: |
d_count_templates_scopes (num_templates, num_scopes, |
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); |
break; |
|
case DEMANGLE_COMPONENT_FIXED_TYPE: |
d_count_templates_scopes (num_templates, num_scopes, |
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)); |
break; |
|
case DEMANGLE_COMPONENT_LAMBDA: |
case DEMANGLE_COMPONENT_DEFAULT_ARG: |
d_count_templates_scopes (num_templates, num_scopes, |
dc->u.s_unary_num.sub); |
break; |
} |
} |
|
/* Initialize a print information structure. */ |
|
static void |
d_print_init (struct d_print_info *dpi, demangle_callbackref callback, |
void *opaque) |
void *opaque, const struct demangle_component *dc) |
{ |
dpi->len = 0; |
dpi->last_char = '\0'; |
3665,6 → 3977,22 |
dpi->opaque = opaque; |
|
dpi->demangle_failure = 0; |
|
dpi->component_stack = NULL; |
|
dpi->saved_scopes = NULL; |
dpi->next_saved_scope = 0; |
dpi->num_saved_scopes = 0; |
|
dpi->copy_templates = NULL; |
dpi->next_copy_template = 0; |
dpi->num_copy_templates = 0; |
|
d_count_templates_scopes (&dpi->num_copy_templates, |
&dpi->num_saved_scopes, dc); |
dpi->num_copy_templates *= dpi->num_saved_scopes; |
|
dpi->current_template = NULL; |
} |
|
/* Indicate that an error occurred during printing, and test for error. */ |
3750,9 → 4078,24 |
{ |
struct d_print_info dpi; |
|
d_print_init (&dpi, callback, opaque); |
d_print_init (&dpi, callback, opaque, dc); |
|
{ |
#ifdef CP_DYNAMIC_ARRAYS |
__extension__ struct d_saved_scope scopes[dpi.num_saved_scopes]; |
__extension__ struct d_print_template temps[dpi.num_copy_templates]; |
|
dpi.saved_scopes = scopes; |
dpi.copy_templates = temps; |
#else |
dpi.saved_scopes = alloca (dpi.num_saved_scopes |
* sizeof (*dpi.saved_scopes)); |
dpi.copy_templates = alloca (dpi.num_copy_templates |
* sizeof (*dpi.copy_templates)); |
#endif |
|
d_print_comp (&dpi, options, dc); |
} |
|
d_print_flush (&dpi); |
|
3913,10 → 4256,66 |
d_append_char (dpi, ')'); |
} |
|
/* Save the current scope. */ |
|
static void |
d_save_scope (struct d_print_info *dpi, |
const struct demangle_component *container) |
{ |
struct d_saved_scope *scope; |
struct d_print_template *src, **link; |
|
if (dpi->next_saved_scope >= dpi->num_saved_scopes) |
{ |
d_print_error (dpi); |
return; |
} |
scope = &dpi->saved_scopes[dpi->next_saved_scope]; |
dpi->next_saved_scope++; |
|
scope->container = container; |
link = &scope->templates; |
|
for (src = dpi->templates; src != NULL; src = src->next) |
{ |
struct d_print_template *dst; |
|
if (dpi->next_copy_template >= dpi->num_copy_templates) |
{ |
d_print_error (dpi); |
return; |
} |
dst = &dpi->copy_templates[dpi->next_copy_template]; |
dpi->next_copy_template++; |
|
dst->template_decl = src->template_decl; |
*link = dst; |
link = &dst->next; |
} |
|
*link = NULL; |
} |
|
/* Attempt to locate a previously saved scope. Returns NULL if no |
corresponding saved scope was found. */ |
|
static struct d_saved_scope * |
d_get_saved_scope (struct d_print_info *dpi, |
const struct demangle_component *container) |
{ |
int i; |
|
for (i = 0; i < dpi->next_saved_scope; i++) |
if (dpi->saved_scopes[i].container == container) |
return &dpi->saved_scopes[i]; |
|
return NULL; |
} |
|
/* Subroutine to handle components. */ |
|
static void |
d_print_comp (struct d_print_info *dpi, int options, |
d_print_comp_inner (struct d_print_info *dpi, int options, |
const struct demangle_component *dc) |
{ |
/* Magic variable to let reference smashing skip over the next modifier |
3923,6 → 4322,13 |
without needing to modify *dc. */ |
const struct demangle_component *mod_inner = NULL; |
|
/* Variable used to store the current templates while a previously |
captured scope is used. */ |
struct d_print_template *saved_templates; |
|
/* Nonzero if templates have been stored in the above variable. */ |
int need_template_restore = 0; |
|
if (dc == NULL) |
{ |
d_print_error (dpi); |
4085,7 → 4491,13 |
{ |
struct d_print_mod *hold_dpm; |
struct demangle_component *dcl; |
const struct demangle_component *hold_current; |
|
/* This template may need to be referenced by a cast operator |
contained in its subtree. */ |
hold_current = dpi->current_template; |
dpi->current_template = dc; |
|
/* Don't push modifiers into a template definition. Doing so |
could give the wrong definition for a template argument. |
Instead, treat the template essentially as a name. */ |
4121,6 → 4533,7 |
} |
|
dpi->modifiers = hold_dpm; |
dpi->current_template = hold_current; |
|
return; |
} |
4291,12 → 4704,56 |
const struct demangle_component *sub = d_left (dc); |
if (sub->type == DEMANGLE_COMPONENT_TEMPLATE_PARAM) |
{ |
struct demangle_component *a = d_lookup_template_argument (dpi, sub); |
struct d_saved_scope *scope = d_get_saved_scope (dpi, sub); |
struct demangle_component *a; |
|
if (scope == NULL) |
{ |
/* This is the first time SUB has been traversed. |
We need to capture the current templates so |
they can be restored if SUB is reentered as a |
substitution. */ |
d_save_scope (dpi, sub); |
if (d_print_saw_error (dpi)) |
return; |
} |
else |
{ |
const struct d_component_stack *dcse; |
int found_self_or_parent = 0; |
|
/* This traversal is reentering SUB as a substition. |
If we are not beneath SUB or DC in the tree then we |
need to restore SUB's template stack temporarily. */ |
for (dcse = dpi->component_stack; dcse != NULL; |
dcse = dcse->parent) |
{ |
if (dcse->dc == sub |
|| (dcse->dc == dc |
&& dcse != dpi->component_stack)) |
{ |
found_self_or_parent = 1; |
break; |
} |
} |
|
if (!found_self_or_parent) |
{ |
saved_templates = dpi->templates; |
dpi->templates = scope->templates; |
need_template_restore = 1; |
} |
} |
|
a = d_lookup_template_argument (dpi, sub); |
if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST) |
a = d_index_template_argument (a, dpi->pack_index); |
|
if (a == NULL) |
{ |
if (need_template_restore) |
dpi->templates = saved_templates; |
|
d_print_error (dpi); |
return; |
} |
4344,6 → 4801,9 |
|
dpi->modifiers = dpm.next; |
|
if (need_template_restore) |
dpi->templates = saved_templates; |
|
return; |
} |
|
4921,6 → 5381,21 |
} |
} |
|
static void |
d_print_comp (struct d_print_info *dpi, int options, |
const struct demangle_component *dc) |
{ |
struct d_component_stack self; |
|
self.dc = dc; |
self.parent = dpi->component_stack; |
dpi->component_stack = &self; |
|
d_print_comp_inner (dpi, options, dc); |
|
dpi->component_stack = self.parent; |
} |
|
/* Print a Java dentifier. For Java we try to handle encoded extended |
Unicode characters. The C++ ABI doesn't mention Unicode encoding, |
so we don't it for C++. Characters are encoded as |
5289,27 → 5764,31 |
d_print_cast (struct d_print_info *dpi, int options, |
const struct demangle_component *dc) |
{ |
if (d_left (dc)->type != DEMANGLE_COMPONENT_TEMPLATE) |
d_print_comp (dpi, options, d_left (dc)); |
else |
{ |
struct d_print_mod *hold_dpm; |
struct d_print_template dpt; |
|
/* It appears that for a templated cast operator, we need to put |
the template parameters in scope for the operator name, but |
not for the parameters. The effect is that we need to handle |
the template printing here. */ |
|
hold_dpm = dpi->modifiers; |
dpi->modifiers = NULL; |
|
/* For a cast operator, we need the template parameters from |
the enclosing template in scope for processing the type. */ |
if (dpi->current_template != NULL) |
{ |
dpt.next = dpi->templates; |
dpi->templates = &dpt; |
dpt.template_decl = d_left (dc); |
dpt.template_decl = dpi->current_template; |
} |
|
if (d_left (dc)->type != DEMANGLE_COMPONENT_TEMPLATE) |
{ |
d_print_comp (dpi, options, d_left (dc)); |
if (dpi->current_template != NULL) |
dpi->templates = dpt.next; |
} |
else |
{ |
d_print_comp (dpi, options, d_left (d_left (dc))); |
|
/* For a templated cast operator, we need to remove the template |
parameters from scope after printing the operator name, |
so we need to handle the template printing here. */ |
if (dpi->current_template != NULL) |
dpi->templates = dpt.next; |
|
if (d_last_char (dpi) == '<') |
5321,8 → 5800,6 |
if (d_last_char (dpi) == '>') |
d_append_char (dpi, ' '); |
d_append_char (dpi, '>'); |
|
dpi->modifiers = hold_dpm; |
} |
} |
|
5355,6 → 5832,8 |
di->last_name = NULL; |
|
di->expansion = 0; |
di->is_expression = 0; |
di->is_conversion = 0; |
} |
|
/* Internal implementation for the demangler. If MANGLED is a g++ v3 ABI |
5425,6 → 5904,8 |
NULL); |
d_advance (&di, strlen (d_str (&di))); |
break; |
default: |
abort (); /* We have listed all the cases. */ |
} |
|
/* If DMGL_PARAMS is set, then if we didn't consume the entire |