/* Objective-C language support routines for GDB, the GNU debugger.
- Copyright (C) 2002-2019 Free Software Foundation, Inc.
+ Copyright (C) 2002-2020 Free Software Foundation, Inc.
Contributed by Apple Computer, Inc.
Written by Michael Snyder.
CORE_ADDR imp;
};
-static const struct objfile_data *objc_objfile_data;
+static const struct objfile_key<unsigned int> objc_objfile_data;
/* Lookup a structure type named "struct NAME", visible in lexical
block BLOCK. If NOERR is nonzero, return zero if NAME is not
else
error (_("No struct type named %s."), name);
}
- if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_STRUCT)
+ if (SYMBOL_TYPE (sym)->code () != TYPE_CODE_STRUCT)
{
if (noerr)
return 0;
return NULL; /* Not an objc mangled name. */
}
-/* la_sniff_from_mangled_name for ObjC. */
-
-static int
-objc_sniff_from_mangled_name (const char *mangled, char **demangled)
-{
- *demangled = objc_demangle (mangled, 0);
- return *demangled != NULL;
-}
-
-/* Determine if we are currently in the Objective-C dispatch function.
- If so, get the address of the method function that the dispatcher
- would call and use that as the function to step into instead. Also
- skip over the trampoline for the function (if any). This is better
- for the user since they are only interested in stepping into the
- method function anyway. */
-static CORE_ADDR
-objc_skip_trampoline (struct frame_info *frame, CORE_ADDR stop_pc)
-{
- struct gdbarch *gdbarch = get_frame_arch (frame);
- CORE_ADDR real_stop_pc;
- CORE_ADDR method_stop_pc;
-
- real_stop_pc = gdbarch_skip_trampoline_code (gdbarch, frame, stop_pc);
-
- if (real_stop_pc != 0)
- find_objc_msgcall (real_stop_pc, &method_stop_pc);
- else
- find_objc_msgcall (stop_pc, &method_stop_pc);
-
- if (method_stop_pc)
- {
- real_stop_pc = gdbarch_skip_trampoline_code
- (gdbarch, frame, method_stop_pc);
- if (real_stop_pc == 0)
- real_stop_pc = method_stop_pc;
- }
-
- return real_stop_pc;
-}
-
/* Table mapping opcodes into strings for printing operators
and precedences of the operators. */
".m", NULL
};
-extern const struct language_defn objc_language_defn = {
+/* Constant data representing the Objective-C language. */
+
+extern const struct language_data objc_language_data =
+{
"objective-c", /* Language name */
"Objective-C",
language_objc,
c_printchar, /* Print a character constant */
c_printstr, /* Function to print string constant */
c_emit_char,
- c_print_type, /* Print a type using appropriate syntax */
c_print_typedef, /* Print a typedef using appropriate syntax */
- c_val_print, /* Print a value using appropriate syntax */
- c_value_print, /* Print a top-level value */
- default_read_var_value, /* la_read_var_value */
- objc_skip_trampoline, /* Language specific skip_trampoline */
"self", /* name_of_this */
false, /* la_store_sym_names_in_linkage_form_p */
- basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
- basic_lookup_transparent_type,/* lookup_transparent_type */
- objc_demangle, /* Language specific symbol demangler */
- objc_sniff_from_mangled_name,
- NULL, /* Language specific
- class_name_from_physname */
objc_op_print_tab, /* Expression operators for printing */
1, /* C-style arrays */
0, /* String lower bound */
- default_word_break_characters,
- default_collect_symbol_completion_matches,
- c_language_arch_info,
- default_print_array_index,
- default_pass_by_reference,
- default_get_string,
- c_watch_location_expression,
- NULL, /* la_get_symbol_name_matcher */
- iterate_over_symbols,
- default_search_name_hash,
&default_varobj_ops,
- NULL,
- NULL,
- LANG_MAGIC
+ c_is_string_type_p,
+ "{...}" /* la_struct_too_deep_ellipsis */
+};
+
+/* Class representing the Objective-C language. */
+
+class objc_language : public language_defn
+{
+public:
+ objc_language ()
+ : language_defn (language_objc, objc_language_data)
+ { /* Nothing. */ }
+
+ /* See language.h. */
+ void language_arch_info (struct gdbarch *gdbarch,
+ struct language_arch_info *lai) const override
+ {
+ c_language_arch_info (gdbarch, lai);
+ }
+
+ /* See language.h. */
+ bool sniff_from_mangled_name (const char *mangled,
+ char **demangled) const override
+ {
+ *demangled = objc_demangle (mangled, 0);
+ return *demangled != NULL;
+ }
+
+ /* See language.h. */
+
+ char *demangle (const char *mangled, int options) const override
+ {
+ return objc_demangle (mangled, options);
+ }
+
+ /* See language.h. */
+
+ void print_type (struct type *type, const char *varstring,
+ struct ui_file *stream, int show, int level,
+ const struct type_print_options *flags) const override
+ {
+ c_print_type (type, varstring, stream, show, level, flags);
+ }
+
+ /* See language.h. */
+
+ CORE_ADDR skip_trampoline (struct frame_info *frame,
+ CORE_ADDR stop_pc) const override
+ {
+ struct gdbarch *gdbarch = get_frame_arch (frame);
+ CORE_ADDR real_stop_pc;
+ CORE_ADDR method_stop_pc;
+
+ /* Determine if we are currently in the Objective-C dispatch function.
+ If so, get the address of the method function that the dispatcher
+ would call and use that as the function to step into instead. Also
+ skip over the trampoline for the function (if any). This is better
+ for the user since they are only interested in stepping into the
+ method function anyway. */
+
+ real_stop_pc = gdbarch_skip_trampoline_code (gdbarch, frame, stop_pc);
+
+ if (real_stop_pc != 0)
+ find_objc_msgcall (real_stop_pc, &method_stop_pc);
+ else
+ find_objc_msgcall (stop_pc, &method_stop_pc);
+
+ if (method_stop_pc)
+ {
+ real_stop_pc = gdbarch_skip_trampoline_code
+ (gdbarch, frame, method_stop_pc);
+ if (real_stop_pc == 0)
+ real_stop_pc = method_stop_pc;
+ }
+
+ return real_stop_pc;
+ }
};
+/* Single instance of the class representing the Objective-C language. */
+
+static objc_language objc_language_defn;
+
/*
* ObjC:
* Following functions help construct Objective-C message calls.
selname_chain = sel->next;
msglist_len = sel->msglist_len;
msglist_sel = sel->msglist_sel;
- selid = lookup_child_selector (parse_gdbarch (ps), p);
+ selid = lookup_child_selector (ps->gdbarch (), p);
if (!selid)
error (_("Can't find selector \"%s\""), p);
write_exp_elt_longcst (ps, selid);
{
const char *aname, *bname;
- aname = SYMBOL_PRINT_NAME (*(struct symbol **) a);
- bname = SYMBOL_PRINT_NAME (*(struct symbol **) b);
+ aname = (*(struct symbol **) a)->print_name ();
+ bname = (*(struct symbol **) b)->print_name ();
if (aname == NULL || bname == NULL)
error (_("internal: compare_selectors(1)"));
/* First time thru is JUST to get max length and count. */
for (objfile *objfile : current_program_space->objfiles ())
{
- for (minimal_symbol *msymbol : objfile_msymbols (objfile))
+ for (minimal_symbol *msymbol : objfile->msymbols ())
{
QUIT;
- name = MSYMBOL_NATURAL_NAME (msymbol);
+ name = msymbol->natural_name ();
if (name
&& (name[0] == '-' || name[0] == '+')
&& name[1] == '[') /* Got a method name. */
if (name == NULL)
{
complaint (_("Bad method name '%s'"),
- MSYMBOL_NATURAL_NAME (msymbol));
+ msymbol->natural_name ());
continue;
}
if (regexp == NULL || re_exec(++name) != 0)
matches = 0;
for (objfile *objfile : current_program_space->objfiles ())
{
- for (minimal_symbol *msymbol : objfile_msymbols (objfile))
+ for (minimal_symbol *msymbol : objfile->msymbols ())
{
QUIT;
- name = MSYMBOL_NATURAL_NAME (msymbol);
+ name = msymbol->natural_name ();
if (name &&
(name[0] == '-' || name[0] == '+') &&
name[1] == '[') /* Got a method name. */
char *p = asel;
QUIT;
- name = SYMBOL_NATURAL_NAME (sym_arr[ix]);
+ name = sym_arr[ix]->natural_name ();
name = strchr (name, ' ') + 1;
if (p[0] && specialcmp(name, p) == 0)
continue; /* Seen this one already (not unique). */
{
const char *aname, *bname;
- aname = SYMBOL_PRINT_NAME (*(struct symbol **) a);
- bname = SYMBOL_PRINT_NAME (*(struct symbol **) b);
+ aname = (*(struct symbol **) a)->print_name ();
+ bname = (*(struct symbol **) b)->print_name ();
if (aname == NULL || bname == NULL)
error (_("internal: compare_classes(1)"));
/* First time thru is JUST to get max length and count. */
for (objfile *objfile : current_program_space->objfiles ())
{
- for (minimal_symbol *msymbol : objfile_msymbols (objfile))
+ for (minimal_symbol *msymbol : objfile->msymbols ())
{
QUIT;
- name = MSYMBOL_NATURAL_NAME (msymbol);
+ name = msymbol->natural_name ();
if (name &&
(name[0] == '-' || name[0] == '+') &&
name[1] == '[') /* Got a method name. */
matches = 0;
for (objfile *objfile : current_program_space->objfiles ())
{
- for (minimal_symbol *msymbol : objfile_msymbols (objfile))
+ for (minimal_symbol *msymbol : objfile->msymbols ())
{
QUIT;
- name = MSYMBOL_NATURAL_NAME (msymbol);
+ name = msymbol->natural_name ();
if (name &&
(name[0] == '-' || name[0] == '+') &&
name[1] == '[') /* Got a method name. */
char *p = aclass;
QUIT;
- name = SYMBOL_NATURAL_NAME (sym_arr[ix]);
+ name = sym_arr[ix]->natural_name ();
name += 2;
if (p[0] && specialcmp(name, p) == 0)
continue; /* Seen this one already (not unique). */
unsigned int objfile_csym = 0;
- objc_csym = (unsigned int *) objfile_data (objfile, objc_objfile_data);
+ objc_csym = objc_objfile_data.get (objfile);
if (objc_csym != NULL && *objc_csym == 0)
/* There are no ObjC symbols in this objfile. Skip it entirely. */
continue;
- for (minimal_symbol *msymbol : objfile_msymbols (objfile))
+ for (minimal_symbol *msymbol : objfile->msymbols ())
{
QUIT;
/* Check the symbol name first as this can be done entirely without
sending any query to the target. */
- symname = MSYMBOL_NATURAL_NAME (msymbol);
+ symname = msymbol->natural_name ();
if (symname == NULL)
continue;
}
if (objc_csym == NULL)
- {
- objc_csym = XOBNEW (&objfile->objfile_obstack, unsigned int);
- *objc_csym = objfile_csym;
- set_objfile_data (objfile, objc_objfile_data, objc_csym);
- }
+ objc_csym = objc_objfile_data.emplace (objfile, objfile_csym);
else
/* Count of ObjC methods in this objfile should be constant. */
gdb_assert (*objc_csym == objfile_csym);
}
}
-/* Uniquify a VEC of strings. */
+/* Uniquify a vector of strings. */
static void
uniquify_strings (std::vector<const char *> *strings)
0).symbol;
if (sym != NULL)
- symbol_names->push_back (SYMBOL_NATURAL_NAME (sym));
+ symbol_names->push_back (sym->natural_name ());
else
{
struct bound_minimal_symbol msym
= lookup_minimal_symbol (selector, 0, 0);
if (msym.minsym != NULL)
- symbol_names->push_back (MSYMBOL_NATURAL_NAME (msym.minsym));
+ symbol_names->push_back (msym.minsym->natural_name ());
}
}
CORE_ADDR pc,
CORE_ADDR *new_pc)
{
- TRY
+ try
{
if (f (pc, new_pc) == 0)
return 1;
}
- CATCH (ex, RETURN_MASK_ALL)
+ catch (const gdb_exception &ex)
{
exception_fprintf (gdb_stderr, ex,
"Unable to determine target of "
"Objective-C method call (ignoring):\n");
}
- END_CATCH
return 0;
}
return 0;
}
+void _initialize_objc_language ();
void
-_initialize_objc_language (void)
+_initialize_objc_language ()
{
add_info ("selectors", info_selectors_command,
_("All Objective-C selectors, or those matching REGEXP."));
return 1;
return 0;
}
-
-void
-_initialize_objc_lang (void)
-{
- objc_objfile_data = register_objfile_data ();
-}