/* Objective-C language support routines for GDB, the GNU debugger.
- Copyright 2002, 2003 Free Software Foundation, Inc.
+ Copyright 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Apple Computer, Inc.
Written by Michael Snyder.
#include "gdb_regex.h"
#include "regcache.h"
#include "block.h"
+#include "infcall.h"
+#include "valprint.h"
+#include "gdb_assert.h"
#include <ctype.h>
CORE_ADDR imp;
};
-/* Complaints about ObjC classes, selectors, etc. */
-
-#if (!defined __GNUC__ || __GNUC__ < 2 || __GNUC_MINOR__ < (defined __cplusplus ? 6 : 4))
-#define __CHECK_FUNCTION ((__const char *) 0)
-#else
-#define __CHECK_FUNCTION __PRETTY_FUNCTION__
-#endif
-
-#define CHECK(expression) \
- ((void) ((expression) ? 0 : gdb_check (#expression, __FILE__, __LINE__, \
- __CHECK_FUNCTION)))
-
-#define CHECK_FATAL(expression) \
- ((void) ((expression) ? 0 : gdb_check_fatal (#expression, __FILE__, \
- __LINE__, __CHECK_FUNCTION)))
-
-static void
-gdb_check (const char *str, const char *file,
- unsigned int line, const char *func)
-{
- error ("assertion failure on line %u of \"%s\" in function \"%s\": %s\n",
- line, file, func, str);
-}
-
-static void
-gdb_check_fatal (const char *str, const char *file,
- unsigned int line, const char *func)
-{
- internal_error (file, line,
- "assertion failure in function \"%s\": %s\n", func, str);
-}
-
/* Lookup a structure type named "struct NAME", visible in lexical
block BLOCK. If NOERR is nonzero, return zero if NAME is not
suitably defined. */
struct symbol *
lookup_struct_typedef (char *name, struct block *block, int noerr)
{
- register struct symbol *sym;
+ struct symbol *sym;
- sym = lookup_symbol (name, block, STRUCT_NAMESPACE, 0,
+ sym = lookup_symbol (name, block, STRUCT_DOMAIN, 0,
(struct symtab **) NULL);
if (sym == NULL)
1, &classval));
}
-int
+CORE_ADDR
lookup_child_selector (char *selname)
{
struct value * function, *selstring;
if (!target_has_execution)
return 0; /* Can't call into inferior to create NSString. */
- if (!(sym = lookup_struct_typedef("NSString", 0, 1)) &&
- !(sym = lookup_struct_typedef("NXString", 0, 1)))
+ sym = lookup_struct_typedef("NSString", 0, 1);
+ if (sym == NULL)
+ sym = lookup_struct_typedef("NXString", 0, 1);
+ if (sym == NULL)
type = lookup_pointer_type(builtin_type_void);
else
type = lookup_pointer_type(SYMBOL_TYPE (sym));
for printing characters and strings is language specific. */
static void
-objc_emit_char (register int c, struct ui_file *stream, int quoter)
+objc_emit_char (int c, struct ui_file *stream, int quoter)
{
c &= 0xFF; /* Avoid sign bit follies. */
objc_printstr (struct ui_file *stream, char *string,
unsigned int length, int width, int force_ellipses)
{
- register unsigned int i;
+ unsigned int i;
unsigned int things_printed = 0;
int in_quotes = 0;
int need_comma = 0;
- extern int inspect_it;
- extern int repeat_count_threshold;
- extern int print_max;
/* If the string was not truncated due to `set print elements', and
the last byte of it is a null, we don't print that, in
static struct type *
objc_create_fundamental_type (struct objfile *objfile, int typeid)
{
- register struct type *type = NULL;
+ struct type *type = NULL;
switch (typeid)
{
{"sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0},
{"++", UNOP_PREINCREMENT, PREC_PREFIX, 0},
{"--", UNOP_PREDECREMENT, PREC_PREFIX, 0},
- {NULL, 0, 0, 0}
+ {NULL, OP_NULL, PREC_NULL, 0}
};
struct type ** const (objc_builtin_types[]) =
range_check_off,
type_check_off,
case_sensitive_on,
+ &exp_descriptor_standard,
objc_parse,
objc_error,
- evaluate_subexp_standard,
+ null_post_parser,
objc_printchar, /* Print a character constant */
objc_printstr, /* Function to print string constant */
objc_emit_char,
c_val_print, /* Print a value using appropriate syntax */
c_value_print, /* Print a top-level value */
objc_skip_trampoline, /* Language specific skip_trampoline */
+ value_of_this, /* value_of_this */
+ basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
+ basic_lookup_transparent_type,/* lookup_transparent_type */
objc_demangle, /* Language specific symbol demangler */
+ NULL, /* Language specific class_name_from_physname */
{"", "", "", ""}, /* Binary format info */
{"0%lo", "0", "o", ""}, /* Octal format info */
{"%ld", "", "d", ""}, /* Decimal format info */
1, /* C-style arrays */
0, /* String lower bound */
&builtin_type_char, /* Type of string elements */
+ default_word_break_characters,
+ NULL, /* FIXME: la_language_arch_info. */
LANG_MAGIC
};
void
start_msglist(void)
{
- register struct selname *new =
+ struct selname *new =
(struct selname *) xmalloc (sizeof (struct selname));
new->next = selname_chain;
int
end_msglist(void)
{
- register int val = msglist_len;
- register struct selname *sel = selname_chain;
- register char *p = msglist_sel;
- int selid;
+ int val = msglist_len;
+ struct selname *sel = selname_chain;
+ char *p = msglist_sel;
+ CORE_ADDR selid;
selname_chain = sel->next;
msglist_len = sel->msglist_len;
* Used for qsorting lists of objc methods (either by class or selector).
*/
-int specialcmp(char *a, char *b)
+static int
+specialcmp (char *a, char *b)
{
while (*a && *a != ' ' && *a != ']' && *b && *b != ' ' && *b != ']')
{
}
if (regexp != NULL)
- if (0 != (val = re_comp (myregexp)))
- error ("Invalid regexp (%s): %s", val, regexp);
+ {
+ val = re_comp (myregexp);
+ if (val != 0)
+ error ("Invalid regexp (%s): %s", val, regexp);
+ }
/* First time thru is JUST to get max length and count. */
ALL_MSYMBOLS (objfile, msymbol)
{
QUIT;
- name = SYMBOL_DEMANGLED_NAME (msymbol);
- if (name == NULL)
- name = DEPRECATED_SYMBOL_NAME (msymbol);
+ name = SYMBOL_NATURAL_NAME (msymbol);
if (name &&
(name[0] == '-' || name[0] == '+') &&
name[1] == '[') /* Got a method name. */
ALL_MSYMBOLS (objfile, msymbol)
{
QUIT;
- name = SYMBOL_DEMANGLED_NAME (msymbol);
- if (name == NULL)
- name = DEPRECATED_SYMBOL_NAME (msymbol);
+ name = SYMBOL_NATURAL_NAME (msymbol);
if (name &&
(name[0] == '-' || name[0] == '+') &&
name[1] == '[') /* Got a method name. */
char *p = asel;
QUIT;
- name = SYMBOL_DEMANGLED_NAME (sym_arr[ix]);
- if (name == NULL)
- name = DEPRECATED_SYMBOL_NAME (sym_arr[ix]);
+ name = SYMBOL_NATURAL_NAME (sym_arr[ix]);
name = strchr (name, ' ') + 1;
if (p[0] && specialcmp(name, p) == 0)
continue; /* Seen this one already (not unique). */
}
if (regexp != NULL)
- if (0 != (val = re_comp (myregexp)))
- error ("Invalid regexp (%s): %s", val, regexp);
+ {
+ val = re_comp (myregexp);
+ if (val != 0)
+ error ("Invalid regexp (%s): %s", val, regexp);
+ }
/* First time thru is JUST to get max length and count. */
ALL_MSYMBOLS (objfile, msymbol)
{
QUIT;
- name = SYMBOL_DEMANGLED_NAME (msymbol);
- if (name == NULL)
- name = DEPRECATED_SYMBOL_NAME (msymbol);
+ name = SYMBOL_NATURAL_NAME (msymbol);
if (name &&
(name[0] == '-' || name[0] == '+') &&
name[1] == '[') /* Got a method name. */
ALL_MSYMBOLS (objfile, msymbol)
{
QUIT;
- name = SYMBOL_DEMANGLED_NAME (msymbol);
- if (name == NULL)
- name = DEPRECATED_SYMBOL_NAME (msymbol);
+ name = SYMBOL_NATURAL_NAME (msymbol);
if (name &&
(name[0] == '-' || name[0] == '+') &&
name[1] == '[') /* Got a method name. */
char *p = aclass;
QUIT;
- name = SYMBOL_DEMANGLED_NAME (sym_arr[ix]);
- if (name == NULL)
- name = DEPRECATED_SYMBOL_NAME (sym_arr[ix]);
+ name = SYMBOL_NATURAL_NAME (sym_arr[ix]);
name += 2;
if (p[0] && specialcmp(name, p) == 0)
continue; /* Seen this one already (not unique). */
char *nselector = NULL;
- CHECK (selector != NULL);
+ gdb_assert (selector != NULL);
s1 = method;
char *ncategory = NULL;
char *nselector = NULL;
- CHECK (type != NULL);
- CHECK (class != NULL);
- CHECK (category != NULL);
- CHECK (selector != NULL);
+ gdb_assert (type != NULL);
+ gdb_assert (class != NULL);
+ gdb_assert (category != NULL);
+ gdb_assert (selector != NULL);
s1 = method;
static char *tmp = NULL;
static unsigned int tmplen = 0;
- CHECK (nsym != NULL);
- CHECK (ndebug != NULL);
+ gdb_assert (nsym != NULL);
+ gdb_assert (ndebug != NULL);
if (symtab)
block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK);
/* Not in the specified symtab. */
continue;
- symname = SYMBOL_DEMANGLED_NAME (msymbol);
- if (symname == NULL)
- symname = DEPRECATED_SYMBOL_NAME (msymbol);
+ symname = SYMBOL_NATURAL_NAME (msymbol);
if (symname == NULL)
continue;
sym = find_pc_function (SYMBOL_VALUE_ADDRESS (msymbol));
if (sym != NULL)
{
- const char *newsymname = SYMBOL_DEMANGLED_NAME (sym);
+ const char *newsymname = SYMBOL_NATURAL_NAME (sym);
- if (newsymname == NULL)
- newsymname = DEPRECATED_SYMBOL_NAME (sym);
if (strcmp (symname, newsymname) == 0)
{
/* Found a high-level method sym: swap it into the
char *buf = NULL;
char *tmp = NULL;
- CHECK (nsym != NULL);
- CHECK (ndebug != NULL);
+ gdb_assert (nsym != NULL);
+ gdb_assert (ndebug != NULL);
if (nsym != NULL)
*nsym = 0;
if (tmp == NULL) {
- struct symtab *sym_symtab = NULL;
struct symbol *sym = NULL;
struct minimal_symbol *msym = NULL;
if (tmp == NULL)
return NULL;
- sym = lookup_symbol (selector, block, VAR_NAMESPACE, 0, &sym_symtab);
+ sym = lookup_symbol (selector, block, VAR_DOMAIN, 0, NULL);
if (sym != NULL)
{
if (syms)
return method + (tmp - buf);
}
-void
+static void
print_object_command (char *args, int from_tty)
{
struct value *object, *function, *description;
{
struct expression *expr = parse_expression (args);
- register struct cleanup *old_chain =
+ struct cleanup *old_chain =
make_cleanup (free_current_contents, &expr);
int pc = 0;
- object = expr->language_defn->evaluate_exp (builtin_type_void_data_ptr,
- expr, &pc, EVAL_NORMAL);
+ object = expr->language_defn->la_exp_desc->evaluate_exp
+ (builtin_type_void_data_ptr, expr, &pc, EVAL_NORMAL);
do_cleanups (old_chain);
}
* case the functions have moved for some reason.
*/
-void
+static void
find_objc_msgsend (void)
{
unsigned int i;
CORE_ADDR *new_pc;
};
-int
+static int
find_objc_msgcall_submethod_helper (void * arg)
{
struct objc_submethod_helper_data *s =
return 0;
}
-int
+static int
find_objc_msgcall_submethod (int (*f) (CORE_ADDR, CORE_ADDR *),
CORE_ADDR pc,
CORE_ADDR *new_pc)
unsigned int i;
find_objc_msgsend ();
- if (new_pc != NULL) { *new_pc = 0; }
+ if (new_pc != NULL)
+ {
+ *new_pc = 0;
+ }
for (i = 0; i < nmethcalls; i++)
if ((pc >= methcalls[i].begin) && (pc < methcalls[i].end))
return 0;
}
+extern initialize_file_ftype _initialize_objc_language; /* -Wmissing-prototypes */
+
void
_initialize_objc_language (void)
{
add_com_alias ("po", "print-object", class_vars, 1);
}
-#if defined (__powerpc__) || defined (__ppc__)
-static unsigned long FETCH_ARGUMENT (int i)
-{
- return read_register (3 + i);
-}
-#elif defined (__i386__)
-static unsigned long FETCH_ARGUMENT (int i)
-{
- CORE_ADDR stack = read_register (SP_REGNUM);
- return read_memory_unsigned_integer (stack + (4 * (i + 1)), 4);
-}
-#elif defined (__sparc__)
-static unsigned long FETCH_ARGUMENT (int i)
-{
- return read_register (O0_REGNUM + i);
-}
-#elif defined (__hppa__) || defined (__hppa)
-static unsigned long FETCH_ARGUMENT (int i)
-{
- return read_register (R0_REGNUM + 26 - i);
-}
-#else
-#error unknown architecture
-#endif
-
-#if defined (__hppa__) || defined (__hppa)
-static CORE_ADDR CONVERT_FUNCPTR (CORE_ADDR pc)
-{
- if (pc & 0x2)
- pc = (CORE_ADDR) read_memory_integer (pc & ~0x3, 4);
-
- return pc;
-}
-#else
-static CORE_ADDR CONVERT_FUNCPTR (CORE_ADDR pc)
-{
- return pc;
-}
-#endif
-
static void
read_objc_method (CORE_ADDR addr, struct objc_method *method)
{
read_objc_methlist_method (CORE_ADDR addr, unsigned long num,
struct objc_method *method)
{
- CHECK_FATAL (num < read_objc_methlist_nmethods (addr));
+ gdb_assert (num < read_objc_methlist_nmethods (addr));
read_objc_method (addr + 8 + (12 * num), method);
}
class->protocols = read_memory_unsigned_integer (addr + 36, 4);
}
-CORE_ADDR
+static CORE_ADDR
find_implementation_from_class (CORE_ADDR class, CORE_ADDR sel)
{
CORE_ADDR subclass = class;
#endif
if (meth_str.name == sel)
- return CONVERT_FUNCPTR (meth_str.imp);
+ /* FIXME: hppa arch was doing a pointer dereference
+ here. There needs to be a better way to do that. */
+ return meth_str.imp;
}
mlistnum++;
}
return 0;
}
-CORE_ADDR
+static CORE_ADDR
find_implementation (CORE_ADDR object, CORE_ADDR sel)
{
struct objc_object ostr;
return find_implementation_from_class (ostr.isa, sel);
}
+#define OBJC_FETCH_POINTER_ARGUMENT(argi) \
+ FETCH_POINTER_ARGUMENT (get_current_frame (), argi, builtin_type_void_func_ptr)
+
static int
resolve_msgsend (CORE_ADDR pc, CORE_ADDR *new_pc)
{
CORE_ADDR sel;
CORE_ADDR res;
- object = FETCH_ARGUMENT (0);
- sel = FETCH_ARGUMENT (1);
+ object = OBJC_FETCH_POINTER_ARGUMENT (0);
+ sel = OBJC_FETCH_POINTER_ARGUMENT (1);
res = find_implementation (object, sel);
if (new_pc != 0)
CORE_ADDR sel;
CORE_ADDR res;
- object = FETCH_ARGUMENT (1);
- sel = FETCH_ARGUMENT (2);
+ object = OBJC_FETCH_POINTER_ARGUMENT (1);
+ sel = OBJC_FETCH_POINTER_ARGUMENT (2);
res = find_implementation (object, sel);
if (new_pc != 0)
CORE_ADDR sel;
CORE_ADDR res;
- super = FETCH_ARGUMENT (0);
- sel = FETCH_ARGUMENT (1);
+ super = OBJC_FETCH_POINTER_ARGUMENT (0);
+ sel = OBJC_FETCH_POINTER_ARGUMENT (1);
read_objc_super (super, &sstr);
if (sstr.class == 0)
CORE_ADDR sel;
CORE_ADDR res;
- super = FETCH_ARGUMENT (1);
- sel = FETCH_ARGUMENT (2);
+ super = OBJC_FETCH_POINTER_ARGUMENT (1);
+ sel = OBJC_FETCH_POINTER_ARGUMENT (2);
read_objc_super (super, &sstr);
if (sstr.class == 0)