gdb/cp-support.c - gdb
Global variables defined
Functions defined
Macros defined
Source code
- #include "defs.h"
- #include "cp-support.h"
- #include "demangle.h"
- #include "gdbcmd.h"
- #include "dictionary.h"
- #include "objfiles.h"
- #include "frame.h"
- #include "symtab.h"
- #include "block.h"
- #include "complaints.h"
- #include "gdbtypes.h"
- #include "expression.h"
- #include "value.h"
- #include "cp-abi.h"
- #include <signal.h>
- #include "safe-ctype.h"
- #define d_left(dc) (dc)->u.s_binary.left
- #define d_right(dc) (dc)->u.s_binary.right
- static unsigned int cp_find_first_component_aux (const char *name,
- int permissive);
- static void demangled_name_complaint (const char *name);
- static int sym_return_val_size = -1;
- static int sym_return_val_index;
- static struct symbol **sym_return_val;
- static void overload_list_add_symbol (struct symbol *sym,
- const char *oload_name);
- static void make_symbol_overload_list_using (const char *func_name,
- const char *namespace);
- static void make_symbol_overload_list_qualified (const char *func_name);
- struct cmd_list_element *maint_cplus_cmd_list = NULL;
- static void maint_cplus_command (char *arg, int from_tty);
- static void first_component_command (char *arg, int from_tty);
- static const char * const ignore_typedefs[] =
- {
- "std::istream", "std::iostream", "std::ostream", "std::string"
- };
- static void
- replace_typedefs (struct demangle_parse_info *info,
- struct demangle_component *ret_comp,
- canonicalization_ftype *finder,
- void *data);
- static char *
- copy_string_to_obstack (struct obstack *obstack, const char *string,
- long *len)
- {
- *len = strlen (string);
- return obstack_copy (obstack, string, *len);
- }
- static void
- do_demangled_name_parse_free_cleanup (void *data)
- {
- struct demangle_parse_info *info = (struct demangle_parse_info *) data;
- cp_demangled_name_parse_free (info);
- }
- struct cleanup *
- make_cleanup_cp_demangled_name_parse_free (struct demangle_parse_info *info)
- {
- return make_cleanup (do_demangled_name_parse_free_cleanup, info);
- }
- static int
- cp_already_canonical (const char *string)
- {
-
- if (!ISIDST (string[0]))
- return 0;
-
- if (string[0] == 'u' && strcmp (&string[1], "nsigned") == 0)
- return 0;
- else if (string[0] == 's' && strcmp (&string[1], "igned") == 0)
- return 0;
-
- while (ISIDNUM (string[1]))
- string++;
- if (string[1] == '\0')
- return 1;
- else
- return 0;
- }
- 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;
- volatile struct gdb_exception except;
-
- 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';
-
- for (i = 0; i < ARRAY_SIZE (ignore_typedefs); ++i)
- {
- if (strcmp (name, ignore_typedefs[i]) == 0)
- return 0;
- }
- sym = NULL;
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- sym = lookup_symbol (name, 0, VAR_DOMAIN, 0);
- }
- if (except.reason >= 0 && 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 (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;
-
- type = check_typedef (otype);
-
- 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;
-
- while (TYPE_TARGET_TYPE (last) != NULL
- && (TYPE_CODE (TYPE_TARGET_TYPE (last))
- == TYPE_CODE_TYPEDEF))
- last = TYPE_TARGET_TYPE (last);
-
- if (type == otype)
- return 0;
- else
-
- type = last;
- }
- buf = mem_fileopen ();
- TRY_CATCH (except, RETURN_MASK_ERROR)
- {
- type_print (type, "", buf, -1);
- }
-
- if (except.reason < 0)
- {
- ui_file_delete (buf);
- return 0;
- }
- name = ui_file_obsavestring (buf, &info->obstack, &len);
- ui_file_delete (buf);
-
- i = cp_demangled_name_to_comp (name, NULL);
- if (i != NULL)
- {
-
- cp_merge_demangle_parse_infos (info, ret_comp, i);
-
- if (!is_anon)
- replace_typedefs (info, ret_comp, finder, data);
- }
- else
- {
-
- char *canon = cp_canonicalize_string_no_typedefs (name);
- if (canon != NULL)
- {
-
- 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;
- }
- }
- return 0;
- }
- static void
- replace_typedefs_qualified_name (struct demangle_parse_info *info,
- struct demangle_component *ret_comp,
- canonicalization_ftype *finder,
- void *data)
- {
- long len;
- char *name;
- struct ui_file *buf = mem_fileopen ();
- struct demangle_component *comp = ret_comp;
-
- while (comp->type == DEMANGLE_COMPONENT_QUAL_NAME)
- {
- if (d_left (comp)->type == DEMANGLE_COMPONENT_NAME)
- {
- struct demangle_component new;
- ui_file_write (buf, d_left (comp)->u.s_name.s,
- d_left (comp)->u.s_name.len);
- name = ui_file_obsavestring (buf, &info->obstack, &len);
- new.type = DEMANGLE_COMPONENT_NAME;
- new.u.s_name.s = name;
- new.u.s_name.len = len;
- if (inspect_type (info, &new, finder, data))
- {
- char *n, *s;
- long slen;
-
- ui_file_rewind (buf);
- n = cp_comp_to_string (&new, 100);
- if (n == NULL)
- {
-
- ui_file_delete (buf);
- return;
- }
- s = copy_string_to_obstack (&info->obstack, n, &slen);
- xfree (n);
- d_left (ret_comp)->type = DEMANGLE_COMPONENT_NAME;
- d_left (ret_comp)->u.s_name.s = s;
- d_left (ret_comp)->u.s_name.len = slen;
- d_right (ret_comp) = d_right (comp);
- comp = ret_comp;
- continue;
- }
- }
- else
- {
-
- replace_typedefs (info, d_left (comp), finder, data);
- name = cp_comp_to_string (d_left (comp), 100);
- if (name == NULL)
- {
-
- ui_file_delete (buf);
- return;
- }
- fputs_unfiltered (name, buf);
- xfree (name);
- }
- ui_file_write (buf, "::", 2);
- comp = d_right (comp);
- }
-
- if (comp->type == DEMANGLE_COMPONENT_NAME)
- {
- ui_file_write (buf, comp->u.s_name.s, comp->u.s_name.len);
- name = ui_file_obsavestring (buf, &info->obstack, &len);
-
- 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, finder, data);
- }
- else
- replace_typedefs (info, comp, finder, data);
- ui_file_delete (buf);
- }
- static void
- check_cv_qualifiers (struct demangle_component *ret_comp)
- {
- while (d_left (ret_comp) != NULL
- && (d_left (ret_comp)->type == DEMANGLE_COMPONENT_CONST
- || d_left (ret_comp)->type == DEMANGLE_COMPONENT_VOLATILE))
- {
- d_left (ret_comp) = d_left (d_left (ret_comp));
- }
- }
- static void
- replace_typedefs (struct demangle_parse_info *info,
- 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:
- check_cv_qualifiers (ret_comp);
-
- case DEMANGLE_COMPONENT_FUNCTION_TYPE:
- case DEMANGLE_COMPONENT_TEMPLATE:
- case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
- case DEMANGLE_COMPONENT_TYPED_NAME:
- 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, finder, data);
- break;
- case DEMANGLE_COMPONENT_QUAL_NAME:
- 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), finder, data);
- break;
- case DEMANGLE_COMPONENT_CONST:
- case DEMANGLE_COMPONENT_RESTRICT:
- case DEMANGLE_COMPONENT_VOLATILE:
- case DEMANGLE_COMPONENT_VOLATILE_THIS:
- case DEMANGLE_COMPONENT_CONST_THIS:
- case DEMANGLE_COMPONENT_RESTRICT_THIS:
- case DEMANGLE_COMPONENT_POINTER:
- case DEMANGLE_COMPONENT_REFERENCE:
- replace_typedefs (info, d_left (ret_comp), finder, data);
- break;
- default:
- break;
- }
- }
- }
- char *
- cp_canonicalize_string_full (const char *string,
- canonicalization_ftype *finder,
- void *data)
- {
- char *ret;
- unsigned int estimated_len;
- struct demangle_parse_info *info;
- ret = NULL;
- estimated_len = strlen (string) * 2;
- info = cp_demangled_name_to_comp (string, NULL);
- if (info != NULL)
- {
-
- replace_typedefs (info, info->tree, finder, data);
-
- ret = cp_comp_to_string (info->tree, estimated_len);
- gdb_assert (ret != NULL);
-
- cp_demangled_name_parse_free (info);
-
- if (strcmp (string, ret) == 0)
- {
- xfree (ret);
- return NULL;
- }
- }
- return ret;
- }
- char *
- cp_canonicalize_string_no_typedefs (const char *string)
- {
- return cp_canonicalize_string_full (string, NULL, NULL);
- }
- char *
- cp_canonicalize_string (const char *string)
- {
- struct demangle_parse_info *info;
- unsigned int estimated_len;
- char *ret;
- if (cp_already_canonical (string))
- return NULL;
- info = cp_demangled_name_to_comp (string, NULL);
- if (info == NULL)
- return NULL;
- estimated_len = strlen (string) * 2;
- ret = cp_comp_to_string (info->tree, estimated_len);
- cp_demangled_name_parse_free (info);
- if (ret == NULL)
- {
- warning (_("internal error: string \"%s\" failed to be canonicalized"),
- string);
- return NULL;
- }
- if (strcmp (string, ret) == 0)
- {
- xfree (ret);
- return NULL;
- }
- return ret;
- }
- static struct demangle_parse_info *
- mangled_name_to_comp (const char *mangled_name, int options,
- void **memory, char **demangled_p)
- {
- char *demangled_name;
- struct demangle_parse_info *info;
-
- if (mangled_name[0] == '_' && mangled_name[1] == 'Z')
- {
- struct demangle_component *ret;
- ret = cplus_demangle_v3_components (mangled_name,
- options, memory);
- if (ret)
- {
- info = cp_new_demangle_parse_info ();
- info->tree = ret;
- *demangled_p = NULL;
- return info;
- }
- }
-
- demangled_name = gdb_demangle (mangled_name, options);
- if (demangled_name == NULL)
- return NULL;
-
- info = cp_demangled_name_to_comp (demangled_name, NULL);
- if (info == NULL)
- {
- xfree (demangled_name);
- return NULL;
- }
- *demangled_p = demangled_name;
- return info;
- }
- char *
- cp_class_name_from_physname (const char *physname)
- {
- void *storage = NULL;
- char *demangled_name = NULL, *ret;
- struct demangle_component *ret_comp, *prev_comp, *cur_comp;
- struct demangle_parse_info *info;
- int done;
- info = mangled_name_to_comp (physname, DMGL_ANSI,
- &storage, &demangled_name);
- if (info == NULL)
- return NULL;
- done = 0;
- ret_comp = info->tree;
-
- 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;
- }
-
- if (ret_comp->type == DEMANGLE_COMPONENT_TYPED_NAME)
- ret_comp = d_left (ret_comp);
-
- if (ret_comp->type == DEMANGLE_COMPONENT_TEMPLATE)
- ret_comp = d_left (ret_comp);
-
- done = 0;
- prev_comp = NULL;
- cur_comp = ret_comp;
- while (!done)
- switch (cur_comp->type)
- {
- case DEMANGLE_COMPONENT_QUAL_NAME:
- case DEMANGLE_COMPONENT_LOCAL_NAME:
- prev_comp = cur_comp;
- cur_comp = d_right (cur_comp);
- break;
- case DEMANGLE_COMPONENT_TEMPLATE:
- case DEMANGLE_COMPONENT_NAME:
- case DEMANGLE_COMPONENT_CTOR:
- case DEMANGLE_COMPONENT_DTOR:
- case DEMANGLE_COMPONENT_OPERATOR:
- case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
- done = 1;
- break;
- default:
- done = 1;
- cur_comp = NULL;
- break;
- }
- ret = NULL;
- if (cur_comp != NULL && prev_comp != NULL)
- {
-
- *prev_comp = *d_left (prev_comp);
-
- ret = cp_comp_to_string (ret_comp, 10);
- }
- xfree (storage);
- xfree (demangled_name);
- cp_demangled_name_parse_free (info);
- return ret;
- }
- static struct demangle_component *
- unqualified_name_from_comp (struct demangle_component *comp)
- {
- struct demangle_component *ret_comp = comp, *last_template;
- int done;
- done = 0;
- last_template = NULL;
- while (!done)
- switch (ret_comp->type)
- {
- case DEMANGLE_COMPONENT_QUAL_NAME:
- case DEMANGLE_COMPONENT_LOCAL_NAME:
- ret_comp = d_right (ret_comp);
- break;
- case DEMANGLE_COMPONENT_TYPED_NAME:
- ret_comp = d_left (ret_comp);
- break;
- case DEMANGLE_COMPONENT_TEMPLATE:
- gdb_assert (last_template == NULL);
- last_template = ret_comp;
- ret_comp = d_left (ret_comp);
- break;
- 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;
- case DEMANGLE_COMPONENT_NAME:
- case DEMANGLE_COMPONENT_CTOR:
- case DEMANGLE_COMPONENT_DTOR:
- case DEMANGLE_COMPONENT_OPERATOR:
- case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
- done = 1;
- break;
- default:
- return NULL;
- break;
- }
- if (last_template)
- {
- d_left (last_template) = ret_comp;
- return last_template;
- }
- return ret_comp;
- }
- char *
- method_name_from_physname (const char *physname)
- {
- void *storage = NULL;
- char *demangled_name = NULL, *ret;
- struct demangle_component *ret_comp;
- struct demangle_parse_info *info;
- info = mangled_name_to_comp (physname, DMGL_ANSI,
- &storage, &demangled_name);
- if (info == NULL)
- return NULL;
- ret_comp = unqualified_name_from_comp (info->tree);
- ret = NULL;
- if (ret_comp != NULL)
-
- ret = cp_comp_to_string (ret_comp, 10);
- xfree (storage);
- xfree (demangled_name);
- cp_demangled_name_parse_free (info);
- return ret;
- }
- char *
- cp_func_name (const char *full_name)
- {
- char *ret;
- struct demangle_component *ret_comp;
- struct demangle_parse_info *info;
- info = cp_demangled_name_to_comp (full_name, NULL);
- if (!info)
- return NULL;
- ret_comp = unqualified_name_from_comp (info->tree);
- ret = NULL;
- if (ret_comp != NULL)
- ret = cp_comp_to_string (ret_comp, 10);
- cp_demangled_name_parse_free (info);
- return ret;
- }
- char *
- cp_remove_params (const char *demangled_name)
- {
- int done = 0;
- struct demangle_component *ret_comp;
- struct demangle_parse_info *info;
- char *ret = NULL;
- if (demangled_name == NULL)
- return NULL;
- info = cp_demangled_name_to_comp (demangled_name, NULL);
- if (info == NULL)
- return NULL;
-
- ret_comp = info->tree;
- 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;
- }
-
- if (ret_comp->type == DEMANGLE_COMPONENT_TYPED_NAME)
- ret = cp_comp_to_string (d_left (ret_comp), 10);
- cp_demangled_name_parse_free (info);
- return ret;
- }
- FIXME
- unsigned int
- cp_find_first_component (const char *name)
- {
- return cp_find_first_component_aux (name, 0);
- }
- #define LENGTH_OF_OPERATOR 8
- static unsigned int
- cp_find_first_component_aux (const char *name, int permissive)
- {
- unsigned int index = 0;
-
- int operator_possible = 1;
- for (;; ++index)
- {
- switch (name[index])
- {
- case '<':
-
- index += 1;
- for (index += cp_find_first_component_aux (name + index, 1);
- name[index] != '>';
- index += cp_find_first_component_aux (name + index, 1))
- {
- if (name[index] != ':')
- {
- demangled_name_complaint (name);
- return strlen (name);
- }
- index += 2;
- }
- operator_possible = 1;
- break;
- case '(':
-
- index += 1;
- for (index += cp_find_first_component_aux (name + index, 1);
- name[index] != ')';
- index += cp_find_first_component_aux (name + index, 1))
- {
- if (name[index] != ':')
- {
- demangled_name_complaint (name);
- return strlen (name);
- }
- index += 2;
- }
- operator_possible = 1;
- break;
- case '>':
- case ')':
- if (permissive)
- return index;
- else
- {
- demangled_name_complaint (name);
- return strlen (name);
- }
- case '\0':
- case ':':
- return index;
- case 'o':
-
- if (operator_possible
- && strncmp (name + index, "operator",
- LENGTH_OF_OPERATOR) == 0)
- {
- index += LENGTH_OF_OPERATOR;
- while (ISSPACE(name[index]))
- ++index;
- switch (name[index])
- {
-
- case '<':
- if (name[index + 1] == '<')
- index += 1;
- else
- index += 0;
- break;
- case '>':
- case '-':
- if (name[index + 1] == '>')
- index += 1;
- else
- index += 0;
- break;
- case '(':
- index += 1;
- break;
- default:
- index += 0;
- break;
- }
- }
- operator_possible = 0;
- break;
- case ' ':
- case ',':
- case '.':
- case '&':
- case '*':
-
- operator_possible = 1;
- break;
- default:
- operator_possible = 0;
- break;
- }
- }
- }
- static void
- demangled_name_complaint (const char *name)
- {
- complaint (&symfile_complaints,
- "unexpected demangled name '%s'", name);
- }
- unsigned int
- cp_entire_prefix_len (const char *name)
- {
- unsigned int current_len = cp_find_first_component (name);
- unsigned int previous_len = 0;
- while (name[current_len] != '\0')
- {
- gdb_assert (name[current_len] == ':');
- previous_len = current_len;
-
- current_len += 2;
- current_len += cp_find_first_component (name + current_len);
- }
- return previous_len;
- }
- static void
- overload_list_add_symbol (struct symbol *sym,
- const char *oload_name)
- {
- int newsize;
- int i;
- char *sym_name;
-
- if (SYMBOL_TYPE (sym) == NULL)
- return;
-
- for (i = 0; i < sym_return_val_index; ++i)
- if (strcmp (SYMBOL_LINKAGE_NAME (sym),
- SYMBOL_LINKAGE_NAME (sym_return_val[i])) == 0)
- return;
-
- sym_name = cp_remove_params (SYMBOL_NATURAL_NAME (sym));
- if (!sym_name)
- return;
-
- if (strcmp (sym_name, oload_name) != 0)
- {
- xfree (sym_name);
- return;
- }
- xfree (sym_name);
-
- if (sym_return_val_index + 3 > sym_return_val_size)
- {
- newsize = (sym_return_val_size *= 2) * sizeof (struct symbol *);
- sym_return_val = (struct symbol **)
- xrealloc ((char *) sym_return_val, newsize);
- }
- sym_return_val[sym_return_val_index++] = sym;
- sym_return_val[sym_return_val_index] = NULL;
- }
- struct symbol **
- make_symbol_overload_list (const char *func_name,
- const char *namespace)
- {
- struct cleanup *old_cleanups;
- const char *name;
- sym_return_val_size = 100;
- sym_return_val_index = 0;
- sym_return_val = xmalloc ((sym_return_val_size + 1) *
- sizeof (struct symbol *));
- sym_return_val[0] = NULL;
- old_cleanups = make_cleanup (xfree, sym_return_val);
- make_symbol_overload_list_using (func_name, namespace);
- if (namespace[0] == '\0')
- name = func_name;
- else
- {
- char *concatenated_name
- = alloca (strlen (namespace) + 2 + strlen (func_name) + 1);
- strcpy (concatenated_name, namespace);
- strcat (concatenated_name, "::");
- strcat (concatenated_name, func_name);
- name = concatenated_name;
- }
- make_symbol_overload_list_qualified (name);
- discard_cleanups (old_cleanups);
- return sym_return_val;
- }
- static void
- make_symbol_overload_list_block (const char *name,
- const struct block *block)
- {
- struct block_iterator iter;
- struct symbol *sym;
- ALL_BLOCK_SYMBOLS_WITH_NAME (block, name, iter, sym)
- overload_list_add_symbol (sym, name);
- }
- static void
- make_symbol_overload_list_namespace (const char *func_name,
- const char *namespace)
- {
- const char *name;
- const struct block *block = NULL;
- if (namespace[0] == '\0')
- name = func_name;
- else
- {
- char *concatenated_name
- = alloca (strlen (namespace) + 2 + strlen (func_name) + 1);
- strcpy (concatenated_name, namespace);
- strcat (concatenated_name, "::");
- strcat (concatenated_name, func_name);
- name = concatenated_name;
- }
-
- block = block_static_block (get_selected_block (0));
- if (block)
- make_symbol_overload_list_block (name, block);
-
- block = block_global_block (block);
- if (block)
- make_symbol_overload_list_block (name, block);
- }
- static void
- make_symbol_overload_list_adl_namespace (struct type *type,
- const char *func_name)
- {
- char *namespace;
- const char *type_name;
- int i, prefix_len;
- while (TYPE_CODE (type) == TYPE_CODE_PTR
- || TYPE_CODE (type) == TYPE_CODE_REF
- || TYPE_CODE (type) == TYPE_CODE_ARRAY
- || TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
- {
- if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
- type = check_typedef(type);
- else
- type = TYPE_TARGET_TYPE (type);
- }
- type_name = TYPE_NAME (type);
- if (type_name == NULL)
- return;
- prefix_len = cp_entire_prefix_len (type_name);
- if (prefix_len != 0)
- {
- namespace = alloca (prefix_len + 1);
- strncpy (namespace, type_name, prefix_len);
- namespace[prefix_len] = '\0';
- make_symbol_overload_list_namespace (func_name, namespace);
- }
-
- if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
- for (i = 0; i < TYPE_N_BASECLASSES (type); i++)
- {
- if (BASETYPE_VIA_PUBLIC (type, i))
- make_symbol_overload_list_adl_namespace (TYPE_BASECLASS (type,
- i),
- func_name);
- }
- }
- struct symbol **
- make_symbol_overload_list_adl (struct type **arg_types, int nargs,
- const char *func_name)
- {
- int i;
- gdb_assert (sym_return_val_size != -1);
- for (i = 1; i <= nargs; i++)
- make_symbol_overload_list_adl_namespace (arg_types[i - 1],
- func_name);
- return sym_return_val;
- }
- static void
- reset_directive_searched (void *data)
- {
- struct using_direct *direct = data;
- direct->searched = 0;
- }
- static void
- make_symbol_overload_list_using (const char *func_name,
- const char *namespace)
- {
- struct using_direct *current;
- const struct block *block;
-
- for (block = get_selected_block (0);
- block != NULL;
- block = BLOCK_SUPERBLOCK (block))
- for (current = block_using (block);
- current != NULL;
- current = current->next)
- {
-
- if (current->searched)
- continue;
-
- if (current->alias != NULL || current->declaration != NULL)
- continue;
- if (strcmp (namespace, current->import_dest) == 0)
- {
-
- struct cleanup *old_chain;
- current->searched = 1;
- old_chain = make_cleanup (reset_directive_searched,
- current);
- make_symbol_overload_list_using (func_name,
- current->import_src);
- current->searched = 0;
- discard_cleanups (old_chain);
- }
- }
-
- make_symbol_overload_list_namespace (func_name, namespace);
- }
- static void
- make_symbol_overload_list_qualified (const char *func_name)
- {
- struct compunit_symtab *cust;
- struct objfile *objfile;
- const struct block *b, *surrounding_static_block = 0;
-
- ALL_OBJFILES (objfile)
- {
- if (objfile->sf)
- objfile->sf->qf->expand_symtabs_for_function (objfile, func_name);
- }
-
- for (b = get_selected_block (0); b != NULL; b = BLOCK_SUPERBLOCK (b))
- make_symbol_overload_list_block (func_name, b);
- surrounding_static_block = block_static_block (get_selected_block (0));
-
- ALL_COMPUNITS (objfile, cust)
- {
- QUIT;
- b = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), GLOBAL_BLOCK);
- make_symbol_overload_list_block (func_name, b);
- }
- ALL_COMPUNITS (objfile, cust)
- {
- QUIT;
- b = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), STATIC_BLOCK);
-
- if (b == surrounding_static_block)
- continue;
- make_symbol_overload_list_block (func_name, b);
- }
- }
- struct type *
- cp_lookup_rtti_type (const char *name, struct block *block)
- {
- struct symbol * rtti_sym;
- struct type * rtti_type;
- rtti_sym = lookup_symbol (name, block, STRUCT_DOMAIN, NULL);
- if (rtti_sym == NULL)
- {
- warning (_("RTTI symbol not found for class '%s'"), name);
- return NULL;
- }
- if (SYMBOL_CLASS (rtti_sym) != LOC_TYPEDEF)
- {
- warning (_("RTTI symbol for class '%s' is not a type"), name);
- return NULL;
- }
- rtti_type = SYMBOL_TYPE (rtti_sym);
- switch (TYPE_CODE (rtti_type))
- {
- case TYPE_CODE_STRUCT:
- break;
- case TYPE_CODE_NAMESPACE:
-
- warning (_("RTTI symbol for class '%s' is a namespace"), name);
- return NULL;
- default:
- warning (_("RTTI symbol for class '%s' has bad type"), name);
- return NULL;
- }
- return rtti_type;
- }
- #ifdef HAVE_WORKING_FORK
- static int catch_demangler_crashes = 1;
- static SIGJMP_BUF gdb_demangle_jmp_buf;
- static int gdb_demangle_attempt_core_dump = 1;
- static void
- gdb_demangle_signal_handler (int signo)
- {
- if (gdb_demangle_attempt_core_dump)
- {
- if (fork () == 0)
- dump_core ();
- gdb_demangle_attempt_core_dump = 0;
- }
- SIGLONGJMP (gdb_demangle_jmp_buf, signo);
- }
- #endif
- char *
- gdb_demangle (const char *name, int options)
- {
- char *result = NULL;
- int crash_signal = 0;
- #ifdef HAVE_WORKING_FORK
- #if defined (HAVE_SIGACTION) && defined (SA_RESTART)
- struct sigaction sa, old_sa;
- #else
- void (*ofunc) ();
- #endif
- static int core_dump_allowed = -1;
- if (core_dump_allowed == -1)
- {
- core_dump_allowed = can_dump_core (LIMIT_CUR);
- if (!core_dump_allowed)
- gdb_demangle_attempt_core_dump = 0;
- }
- if (catch_demangler_crashes)
- {
- #if defined (HAVE_SIGACTION) && defined (SA_RESTART)
- sa.sa_handler = gdb_demangle_signal_handler;
- sigemptyset (&sa.sa_mask);
- #ifdef HAVE_SIGALTSTACK
- sa.sa_flags = SA_ONSTACK;
- #else
- sa.sa_flags = 0;
- #endif
- sigaction (SIGSEGV, &sa, &old_sa);
- #else
- ofunc = (void (*)()) signal (SIGSEGV, gdb_demangle_signal_handler);
- #endif
- crash_signal = SIGSETJMP (gdb_demangle_jmp_buf);
- }
- #endif
- if (crash_signal == 0)
- result = bfd_demangle (NULL, name, options);
- #ifdef HAVE_WORKING_FORK
- if (catch_demangler_crashes)
- {
- #if defined (HAVE_SIGACTION) && defined (SA_RESTART)
- sigaction (SIGSEGV, &old_sa, NULL);
- #else
- signal (SIGSEGV, ofunc);
- #endif
- if (crash_signal != 0)
- {
- static int error_reported = 0;
- if (!error_reported)
- {
- char *short_msg, *long_msg;
- struct cleanup *back_to;
- short_msg = xstrprintf (_("unable to demangle '%s' "
- "(demangler failed with signal %d)"),
- name, crash_signal);
- back_to = make_cleanup (xfree, short_msg);
- long_msg = xstrprintf ("%s:%d: %s: %s", __FILE__, __LINE__,
- "demangler-warning", short_msg);
- make_cleanup (xfree, long_msg);
- target_terminal_ours ();
- begin_line ();
- if (core_dump_allowed)
- fprintf_unfiltered (gdb_stderr,
- _("%s\nAttempting to dump core.\n"),
- long_msg);
- else
- warn_cant_dump_core (long_msg);
- demangler_warning (__FILE__, __LINE__, "%s", short_msg);
- do_cleanups (back_to);
- error_reported = 1;
- }
- result = NULL;
- }
- }
- #endif
- return result;
- }
- static void
- maint_cplus_command (char *arg, int from_tty)
- {
- printf_unfiltered (_("\"maintenance cplus\" must be followed "
- "by the name of a command.\n"));
- help_list (maint_cplus_cmd_list,
- "maintenance cplus ",
- all_commands, gdb_stdout);
- }
- static void
- first_component_command (char *arg, int from_tty)
- {
- int len;
- char *prefix;
- if (!arg)
- return;
- len = cp_find_first_component (arg);
- prefix = alloca (len + 1);
- memcpy (prefix, arg, len);
- prefix[len] = '\0';
- printf_unfiltered ("%s\n", prefix);
- }
- extern initialize_file_ftype _initialize_cp_support;
- static void
- info_vtbl_command (char *arg, int from_tty)
- {
- struct value *value;
- value = parse_and_eval (arg);
- cplus_print_vtable (value);
- }
- void
- _initialize_cp_support (void)
- {
- add_prefix_cmd ("cplus", class_maintenance,
- maint_cplus_command,
- _("C++ maintenance commands."),
- &maint_cplus_cmd_list,
- "maintenance cplus ",
- 0, &maintenancelist);
- add_alias_cmd ("cp", "cplus",
- class_maintenance, 1,
- &maintenancelist);
- add_cmd ("first_component",
- class_maintenance,
- first_component_command,
- _("Print the first class/namespace component of NAME."),
- &maint_cplus_cmd_list);
- add_info ("vtbl", info_vtbl_command,
- _("Show the virtual function table for a C++ object.\n\
- Usage: info vtbl EXPRESSION\n\
- Evaluate EXPRESSION and display the virtual function table for the\n\
- resulting object."));
- #ifdef HAVE_WORKING_FORK
- add_setshow_boolean_cmd ("catch-demangler-crashes", class_maintenance,
- &catch_demangler_crashes, _("\
- Set whether to attempt to catch demangler crashes."), _("\
- Show whether to attempt to catch demangler crashes."), _("\
- If enabled GDB will attempt to catch demangler crashes and\n\
- display the offending symbol."),
- NULL,
- NULL,
- &maintenance_set_cmdlist,
- &maintenance_show_cmdlist);
- #endif
- }