2003-01-03 Adam Fedor * Makefile (linespec.o): Add $(objc_lang_h) * linespec.c (decode_objc): New function to decode ObjC calls (decode_line_1): Check for ObjC calls (using decode_objc) Index: Makefile.in =================================================================== RCS file: /cvs/src/src/gdb/Makefile.in,v retrieving revision 1.311 diff -u -p -r1.311 Makefile.in --- Makefile.in 9 Jan 2003 18:03:35 -0000 1.311 @@ -1831,7 +1833,7 @@ lin-lwp.o: lin-lwp.c $(defs_h) $(gdb_ass $(gdbthread_h) $(inferior_h) $(target_h) $(regcache_h) $(gdbcmd_h) linespec.o: linespec.c $(defs_h) $(symtab_h) $(frame_h) $(command_h) \ $(symfile_h) $(objfiles_h) $(demangle_h) $(value_h) $(completer_h) \ - $(cp_abi_h) $(source_h) $(parser_defs_h) + $(cp_abi_h) $(source_h) $(parser_defs_h) $(objc_lang_h) linux-proc.o: linux-proc.c $(defs_h) $(inferior_h) $(regcache_h) \ $(gregset_h) $(gdbcore_h) $(gdbthread_h) $(elf_bfd_h) \ $(cli_decode_h) $(gdb_string_h) Index: linespec.c =================================================================== RCS file: /cvs/src/src/gdb/linespec.c,v retrieving revision 1.36 diff -u -p -r1.36 linespec.c --- linespec.c 11 Jan 2003 01:01:04 -0000 1.36 +++ linespec.c 11 Jan 2003 04:36:07 -0000 @@ -32,6 +32,7 @@ #include "completer.h" #include "cp-abi.h" #include "parser-defs.h" +#include "objc-lang.h" /* We share this one with symtab.c, but it is not exported widely. */ @@ -48,6 +49,12 @@ static struct symtabs_and_lines decode_i static char *locate_first_half (char **argptr, int *is_quote_enclosed); +static struct symtabs_and_lines decode_objc (char **argptr, + int funfirstline, + struct symtab *file_symtab, + char ***canonical, + char *saved_arg); + static struct symtabs_and_lines decode_compound (char **argptr, int funfirstline, char ***canonical, @@ -573,6 +580,7 @@ decode_line_1 (char **argptr, int funfir int is_quoted; /* Is part of *ARGPTR is enclosed in double quotes? */ int is_quote_enclosed; + int is_objc_method = 0; char *saved_arg = *argptr; /* Defaults have defaults. */ @@ -599,6 +607,25 @@ decode_line_1 (char **argptr, int funfir p = locate_first_half (argptr, &is_quote_enclosed); + /* Check if this is an Objective-C method (anything that starts with + a '+' or '-' and a '['). */ + if (*p && (p[0] == ':') && (strchr ("+-", p[1]) != NULL) + && (p[2] == '[')) + { + is_objc_method = 1; + paren_pointer = NULL; /* Just a category name. Ignore it. */ + } + + /* Check if the symbol could be an Objective-C selector. */ + + { + struct symtabs_and_lines values; + values = decode_objc (argptr, funfirstline, NULL, + canonical, saved_arg); + if (values.sals != NULL) + return values; + } + /* Does it look like there actually were two parts? */ if ((p[0] == ':' || p[0] == '.') && paren_pointer == NULL) @@ -672,13 +699,21 @@ decode_line_1 (char **argptr, int funfir Find the next token (everything up to end or next whitespace). */ if (**argptr == '$') /* May be a convenience variable */ - p = skip_quoted (*argptr + (((*argptr)[1] == '$') ? 2 : 1)); /* One or two $ chars possible */ + { + /* One or two $ chars possible */ + p = skip_quoted (*argptr + (((*argptr)[1] == '$') ? 2 : 1)); + } else if (is_quoted) { p = skip_quoted (*argptr); if (p[-1] != '\'') error ("Unmatched single quote."); } + else if (is_objc_method) + { + /* allow word separators in method names for Obj-C */ + p = skip_quoted_chars (*argptr, NULL, ""); + } else if (paren_pointer != NULL) { p = paren_pointer + 1; @@ -881,6 +916,13 @@ locate_first_half (char **argptr, int *i error ("malformed template specification in command"); p = temp_end; } + /* Check for a colon and a plus or minus and a [ (which + indicates an Objective-C method) */ + if (*p && (p[0] == ':') && (strchr ("+-", p[1]) != NULL) + && (p[2] == '[')) + { + break; + } /* Check for the end of the first half of the linespec. End of line, a tab, a double colon or the last single colon, or a space. But if enclosed in double quotes we do not break on enclosed spaces */ @@ -922,6 +964,95 @@ locate_first_half (char **argptr, int *i } + +/* Here's where we recognise an Objective-C Selector. An Objective C + selector may be implemented by more than one class, therefore it + may represent more than one method/function. This gives us a + situation somewhat analogous to C++ overloading. If there's more + than one method that could represent the selector, then use some of + the existing C++ code to let the user choose one. */ + +struct symtabs_and_lines +decode_objc (char **argptr, int funfirstline, struct symtab *file_symtab, + char ***canonical, char *saved_arg) +{ + struct symtabs_and_lines values; + struct symbol **sym_arr = NULL; + struct symbol *sym = NULL; + char *copy = NULL; + struct block *block = NULL; + int i1 = 0; + int i2 = 0; + + values.sals = NULL; + values.nelts = 0; + + if (file_symtab != NULL) + block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (file_symtab), STATIC_BLOCK); + else + block = get_selected_block (0); + + copy = find_imps (file_symtab, block, *argptr, NULL, &i1, &i2); + + if (i1 > 0) + { + sym_arr = (struct symbol **) alloca ((i1 + 1) * sizeof (struct symbol *)); + sym_arr[i1] = 0; + + copy = find_imps (file_symtab, block, *argptr, sym_arr, &i1, &i2); + *argptr = copy; + } + + /* i1 now represents the TOTAL number of matches found. + i2 represents how many HIGH-LEVEL (struct symbol) matches, + which will come first in the sym_arr array. Any low-level + (minimal_symbol) matches will follow those. */ + + if (i1 == 1) + { + if (i2 > 0) + { + /* Already a struct symbol. */ + sym = sym_arr[0]; + } + else + { + sym = find_pc_function (SYMBOL_VALUE_ADDRESS (sym_arr[0])); + if ((sym != NULL) && strcmp (SYMBOL_NAME (sym_arr[0]), SYMBOL_NAME (sym)) != 0) + { + warning ("debugging symbol \"%s\" does not match selector; ignoring", SYMBOL_NAME (sym)); + sym = NULL; + } + } + + values.sals = (struct symtab_and_line *) xmalloc (sizeof (struct symtab_and_line)); + values.nelts = 1; + + if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK) + { + /* Canonicalize this, so it remains resolved for dylib loads. */ + values.sals[0] = find_function_start_sal (sym, funfirstline); + build_canonical_line_spec (values.sals, SYMBOL_SOURCE_NAME (sym), canonical); + } + else + { + /* The only match was a non-debuggable symbol. */ + values.sals[0].symtab = 0; + values.sals[0].line = 0; + values.sals[0].end = 0; + values.sals[0].pc = SYMBOL_VALUE_ADDRESS (sym_arr[0]); + } + return values; + } + + if (i1 > 1) + { + /* More than one match. The user must choose one or more. */ + return decode_line_2 (sym_arr, i2, funfirstline, canonical); + } + + return values; +} /* This handles C++ and Java compound data structures. P should point at the first component separator, i.e. double-colon or period. */