static void
replace_typedefs (struct demangle_parse_info *info,
- struct demangle_component *ret_comp);
+ struct demangle_component *ret_comp,
+ canonicalization_ftype *finder,
+ void *data);
/* A convenience function to copy STRING into OBSTACK, returning a pointer
to the newly allocated string and saving the number of bytes saved in LEN.
static int
inspect_type (struct demangle_parse_info *info,
- struct demangle_component *ret_comp)
+ struct demangle_component *ret_comp,
+ canonicalization_ftype *finder,
+ void *data)
{
int i;
char *name;
{
struct type *otype = SYMBOL_TYPE (sym);
+ if (finder != NULL)
+ {
+ const char *new_name = (*finder) (otype, data);
+
+ if (new_name != NULL)
+ {
+ ret_comp->u.s_name.s = new_name;
+ ret_comp->u.s_name.len = strlen (new_name);
+ return 1;
+ }
+
+ return 0;
+ }
+
/* If the type is a typedef, replace it. */
if (TYPE_CODE (otype) == TYPE_CODE_TYPEDEF)
{
if the type is anonymous (that would lead to infinite
looping). */
if (!is_anon)
- replace_typedefs (info, ret_comp);
+ replace_typedefs (info, ret_comp, finder, data);
}
else
{
static void
replace_typedefs_qualified_name (struct demangle_parse_info *info,
- struct demangle_component *ret_comp)
+ struct demangle_component *ret_comp,
+ canonicalization_ftype *finder,
+ void *data)
{
long len;
char *name;
new.type = DEMANGLE_COMPONENT_NAME;
new.u.s_name.s = name;
new.u.s_name.len = len;
- if (inspect_type (info, &new))
+ if (inspect_type (info, &new, finder, data))
{
char *n, *s;
long slen;
/* The current node is not a name, so simply replace any
typedefs in it. Then print it to the stream to continue
checking for more typedefs in the tree. */
- replace_typedefs (info, d_left (comp));
+ replace_typedefs (info, d_left (comp), finder, data);
name = cp_comp_to_string (d_left (comp), 100);
if (name == NULL)
{
fputs_unfiltered (name, buf);
xfree (name);
}
+
ui_file_write (buf, "::", 2);
comp = d_right (comp);
}
ret_comp->type = DEMANGLE_COMPONENT_NAME;
ret_comp->u.s_name.s = name;
ret_comp->u.s_name.len = len;
- inspect_type (info, ret_comp);
+ inspect_type (info, ret_comp, finder, data);
}
else
- replace_typedefs (info, comp);
+ replace_typedefs (info, comp, finder, data);
ui_file_delete (buf);
}
static void
replace_typedefs (struct demangle_parse_info *info,
- struct demangle_component *ret_comp)
+ struct demangle_component *ret_comp,
+ canonicalization_ftype *finder,
+ void *data)
{
if (ret_comp)
{
+ if (finder != NULL
+ && (ret_comp->type == DEMANGLE_COMPONENT_NAME
+ || ret_comp->type == DEMANGLE_COMPONENT_QUAL_NAME
+ || ret_comp->type == DEMANGLE_COMPONENT_TEMPLATE
+ || ret_comp->type == DEMANGLE_COMPONENT_BUILTIN_TYPE))
+ {
+ char *local_name = cp_comp_to_string (ret_comp, 10);
+
+ if (local_name != NULL)
+ {
+ struct symbol *sym;
+ volatile struct gdb_exception except;
+
+ sym = NULL;
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ sym = lookup_symbol (local_name, 0, VAR_DOMAIN, 0);
+ }
+ xfree (local_name);
+
+ if (except.reason >= 0 && sym != NULL)
+ {
+ struct type *otype = SYMBOL_TYPE (sym);
+ const char *new_name = (*finder) (otype, data);
+
+ if (new_name != NULL)
+ {
+ ret_comp->type = DEMANGLE_COMPONENT_NAME;
+ ret_comp->u.s_name.s = new_name;
+ ret_comp->u.s_name.len = strlen (new_name);
+ return;
+ }
+ }
+ }
+ }
+
switch (ret_comp->type)
{
case DEMANGLE_COMPONENT_ARGLIST:
case DEMANGLE_COMPONENT_TEMPLATE:
case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
case DEMANGLE_COMPONENT_TYPED_NAME:
- replace_typedefs (info, d_left (ret_comp));
- replace_typedefs (info, d_right (ret_comp));
+ replace_typedefs (info, d_left (ret_comp), finder, data);
+ replace_typedefs (info, d_right (ret_comp), finder, data);
break;
case DEMANGLE_COMPONENT_NAME:
- inspect_type (info, ret_comp);
+ inspect_type (info, ret_comp, finder, data);
break;
case DEMANGLE_COMPONENT_QUAL_NAME:
- replace_typedefs_qualified_name (info, ret_comp);
+ replace_typedefs_qualified_name (info, ret_comp, finder, data);
break;
case DEMANGLE_COMPONENT_LOCAL_NAME:
case DEMANGLE_COMPONENT_CTOR:
case DEMANGLE_COMPONENT_ARRAY_TYPE:
case DEMANGLE_COMPONENT_PTRMEM_TYPE:
- replace_typedefs (info, d_right (ret_comp));
+ replace_typedefs (info, d_right (ret_comp), finder, data);
break;
case DEMANGLE_COMPONENT_CONST:
case DEMANGLE_COMPONENT_RESTRICT_THIS:
case DEMANGLE_COMPONENT_POINTER:
case DEMANGLE_COMPONENT_REFERENCE:
- replace_typedefs (info, d_left (ret_comp));
+ replace_typedefs (info, d_left (ret_comp), finder, data);
break;
default:
/* Parse STRING and convert it to canonical form, resolving any typedefs.
If parsing fails, or if STRING is already canonical, return NULL.
Otherwise return the canonical form. The return value is allocated via
- xmalloc. */
+ xmalloc. If FINDER is not NULL, then type components are passed to
+ FINDER to be looked up. DATA is passed verbatim to FINDER. */
char *
-cp_canonicalize_string_no_typedefs (const char *string)
+cp_canonicalize_string_full (const char *string,
+ canonicalization_ftype *finder,
+ void *data)
{
char *ret;
unsigned int estimated_len;
if (info != NULL)
{
/* Replace all the typedefs in the tree. */
- replace_typedefs (info, info->tree);
+ replace_typedefs (info, info->tree, finder, data);
/* Convert the tree back into a string. */
ret = cp_comp_to_string (info->tree, estimated_len);
return ret;
}
+/* Like cp_canonicalize_string_full, but always passes NULL for
+ FINDER. */
+
+char *
+cp_canonicalize_string_no_typedefs (const char *string)
+{
+ return cp_canonicalize_string_full (string, NULL, NULL);
+}
+
/* Parse STRING and convert it to canonical form. If parsing fails,
or if STRING is already canonical, return NULL. Otherwise return
the canonical form. The return value is allocated via xmalloc. */