From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12644 invoked by alias); 3 Jan 2003 23:31:04 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 12598 invoked from network); 3 Jan 2003 23:31:03 -0000 Received: from unknown (63.119.183.65) by 209.249.29.67 with QMTP; 3 Jan 2003 23:31:03 -0000 Received: (qmail 26553 invoked from network); 3 Jan 2003 23:29:06 -0000 Received: from cpe-24-221-209-215.co.sprintbbd.net (HELO doc.com) (24.221.209.215) by external1 with SMTP; 3 Jan 2003 23:29:06 -0000 Message-ID: <3E161D25.7070106@doc.com> Date: Fri, 03 Jan 2003 23:31:00 -0000 From: Adam Fedor User-Agent: Mozilla/5.0 (X11; U; Linux ppc; en-US; rv:1.1) Gecko/20020905 X-Accept-Language: en-us, en MIME-Version: 1.0 To: GDB Patches Subject: [RFA] Add ObjC recognition to linespec.c [5/5] Content-Type: multipart/mixed; boundary="------------030006050406060706070707" X-SW-Source: 2003-01/txt/msg00121.txt.bz2 This is a multi-part message in MIME format. --------------030006050406060706070707 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Content-length: 265 I know that linespec has been changing a lot lately, and I'm not sure if it's finished changing yet. So this is my attempt to insert ObjC handling into linespec. Actually Klee Dienes really did most of these changes, and I probably bastardized those as well... --------------030006050406060706070707 Content-Type: text/plain; name="objc23.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="objc23.patch" Content-length: 6732 2003-01-03 Adam Fedor * linespec.c (decode_objc): New function to decode ObjC calls (decode_line_1): Check for ObjC calls (using decode_objc) Index: linespec.c =================================================================== RCS file: /cvs/src/src/gdb/linespec.c,v retrieving revision 1.32 diff -u -p -r1.32 linespec.c --- linespec.c 19 Dec 2002 18:56:14 -0000 1.32 +++ linespec.c 3 Jan 2003 22:56:54 -0000 @@ -37,6 +37,11 @@ extern char *operator_chars (char *, char **); +/* From objc-lang.h. Included here to avoid conflict with other prototypes */ +extern char *find_imps (struct symtab *symtab, struct block *block, + char *method, struct symbol **syms, unsigned int *nsym, + unsigned int *ndebug); + /* Prototypes for local functions */ static void initialize_defaults (struct symtab **default_symtab, @@ -48,6 +53,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, @@ -568,6 +579,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; init_sal (&val); /* initialize to zeroes */ @@ -596,6 +608,24 @@ decode_line_1 (char **argptr, int funfir p = locate_first_half (argptr, &is_quote_enclosed); + /* Check if this is an Objective-C method. */ + if (*p && (p[0] == ':') && (strchr ("+-", p[1]) != NULL) + && (p[2] == '[')) + { + is_objc_method = 1; + paren_pointer = NULL; /* Probably just a category name. Ignore it */ + } + + /* Is it 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) @@ -669,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; @@ -952,6 +990,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 */ @@ -993,6 +1038,98 @@ locate_first_half (char **argptr, int *i } + +struct symtabs_and_lines +decode_objc (char **argptr, int funfirstline, struct symtab *file_symtab, + char ***canonical, char *saved_arg) +{ + /* 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 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 -- user must choose one or more */ + return decode_line_2 (sym_arr, i2, funfirstline, canonical); + //return select_symbols (sym_arr, i1, 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. */ --------------030006050406060706070707--