char * cp_canonicalize_string (const char *string) { struct demangle_component *ret_comp; unsigned int estimated_len; char *ret; if (cp_already_canonical (string)) return NULL; ret_comp = cp_demangled_name_to_comp (string, NULL); if (ret_comp == NULL) return NULL; estimated_len = strlen (string) * 2; ret = cp_comp_to_string (ret_comp, estimated_len); if (strcmp (string, ret) == 0) { xfree (ret); return NULL; } return ret; }
char * cp_func_name (const char *full_name) { char *ret; struct demangle_component *ret_comp; ret_comp = cp_demangled_name_to_comp (full_name, NULL); if (!ret_comp) return NULL; ret_comp = unqualified_name_from_comp (ret_comp); ret = NULL; if (ret_comp != NULL) ret = cp_comp_to_string (ret_comp, 10); return ret; }
char * cp_remove_params (const char *demangled_name) { int done = 0; struct demangle_component *ret_comp; char *ret = NULL; if (demangled_name == NULL) return NULL; ret_comp = cp_demangled_name_to_comp (demangled_name, NULL); if (ret_comp == NULL) return NULL; /* First strip off any qualifiers, if we have a function or method. */ while (!done) switch (ret_comp->type) { case DEMANGLE_COMPONENT_CONST: case DEMANGLE_COMPONENT_RESTRICT: case DEMANGLE_COMPONENT_VOLATILE: case DEMANGLE_COMPONENT_CONST_THIS: case DEMANGLE_COMPONENT_RESTRICT_THIS: case DEMANGLE_COMPONENT_VOLATILE_THIS: case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL: ret_comp = d_left (ret_comp); break; default: done = 1; break; } /* What we have now should be a function. Return its name. */ if (ret_comp->type == DEMANGLE_COMPONENT_TYPED_NAME) ret = cp_comp_to_string (d_left (ret_comp), 10); return ret; }
static struct demangle_component * mangled_name_to_comp (const char *mangled_name, int options, void **memory, char **demangled_p) { struct demangle_component *ret; char *demangled_name; /* If it looks like a v3 mangled name, then try to go directly to trees. */ if (mangled_name[0] == '_' && mangled_name[1] == 'Z') { ret = cplus_demangle_v3_components (mangled_name, options, memory); if (ret) { *demangled_p = NULL; return ret; } } /* If it doesn't, or if that failed, then try to demangle the name. */ demangled_name = cplus_demangle (mangled_name, options); if (demangled_name == NULL) return NULL; /* If we could demangle the name, parse it to build the component tree. */ ret = cp_demangled_name_to_comp (demangled_name, NULL); if (ret == NULL) { xfree (demangled_name); return NULL; } *demangled_p = demangled_name; return ret; }
static int inspect_type (struct demangle_parse_info *info, struct demangle_component *ret_comp, canonicalization_ftype *finder, void *data) { int i; char *name; struct symbol *sym; /* Copy the symbol's name from RET_COMP and look it up in the symbol table. */ name = (char *) alloca (ret_comp->u.s_name.len + 1); memcpy (name, ret_comp->u.s_name.s, ret_comp->u.s_name.len); name[ret_comp->u.s_name.len] = '\0'; /* Ignore any typedefs that should not be substituted. */ for (i = 0; i < ARRAY_SIZE (ignore_typedefs); ++i) { if (strcmp (name, ignore_typedefs[i]) == 0) return 0; } sym = NULL; TRY { sym = lookup_symbol (name, 0, VAR_DOMAIN, 0); } CATCH (except, RETURN_MASK_ALL) { return 0; } END_CATCH if (sym != NULL) { 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 or namespace alias, replace it. */ if (TYPE_CODE (otype) == TYPE_CODE_TYPEDEF || TYPE_CODE (otype) == TYPE_CODE_NAMESPACE) { long len; int is_anon; struct type *type; struct demangle_parse_info *i; struct ui_file *buf; /* Get the real type of the typedef. */ type = check_typedef (otype); /* If the symbol is a namespace and its type name is no different than the name we looked up, this symbol is not a namespace alias and does not need to be substituted. */ if (TYPE_CODE (otype) == TYPE_CODE_NAMESPACE && strcmp (TYPE_NAME (type), name) == 0) return 0; is_anon = (TYPE_TAG_NAME (type) == NULL && (TYPE_CODE (type) == TYPE_CODE_ENUM || TYPE_CODE (type) == TYPE_CODE_STRUCT || TYPE_CODE (type) == TYPE_CODE_UNION)); if (is_anon) { struct type *last = otype; /* Find the last typedef for the type. */ while (TYPE_TARGET_TYPE (last) != NULL && (TYPE_CODE (TYPE_TARGET_TYPE (last)) == TYPE_CODE_TYPEDEF)) last = TYPE_TARGET_TYPE (last); /* If there is only one typedef for this anonymous type, do not substitute it. */ if (type == otype) return 0; else /* Use the last typedef seen as the type for this anonymous type. */ type = last; } buf = mem_fileopen (); TRY { type_print (type, "", buf, -1); } /* If type_print threw an exception, there is little point in continuing, so just bow out gracefully. */ CATCH (except, RETURN_MASK_ERROR) { ui_file_delete (buf); return 0; } END_CATCH name = ui_file_obsavestring (buf, &info->obstack, &len); ui_file_delete (buf); /* Turn the result into a new tree. Note that this tree will contain pointers into NAME, so NAME cannot be free'd until all typedef conversion is done and the final result is converted into a string. */ i = cp_demangled_name_to_comp (name, NULL); if (i != NULL) { /* Merge the two trees. */ cp_merge_demangle_parse_infos (info, ret_comp, i); /* Replace any newly introduced typedefs -- but not if the type is anonymous (that would lead to infinite looping). */ if (!is_anon) replace_typedefs (info, ret_comp, finder, data); } else { /* This shouldn't happen unless the type printer has output something that the name parser cannot grok. Nonetheless, an ounce of prevention... Canonicalize the name again, and store it in the current node (RET_COMP). */ char *canon = cp_canonicalize_string_no_typedefs (name); if (canon != NULL) { /* Copy the canonicalization into the obstack and free CANON. */ name = copy_string_to_obstack (&info->obstack, canon, &len); xfree (canon); } ret_comp->u.s_name.s = name; ret_comp->u.s_name.len = len; } return 1; }