From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 31199 invoked by alias); 4 Jan 2003 01:32:59 -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 31192 invoked from network); 4 Jan 2003 01:32:58 -0000 Received: from unknown (HELO mx1.redhat.com) (66.187.233.31) by 209.249.29.67 with SMTP; 4 Jan 2003 01:32:58 -0000 Received: from int-mx2.corp.redhat.com (nat-pool-rdu-dmz.redhat.com [172.16.52.200]) by mx1.redhat.com (8.11.6/8.11.6) with ESMTP id h0415OB21180 for ; Fri, 3 Jan 2003 20:05:25 -0500 Received: from potter.sfbay.redhat.com (potter.sfbay.redhat.com [172.16.27.15]) by int-mx2.corp.redhat.com (8.11.6/8.11.6) with ESMTP id h041Wjn30511; Fri, 3 Jan 2003 20:32:45 -0500 Received: from redhat.com (reddwarf.sfbay.redhat.com [172.16.24.50]) by potter.sfbay.redhat.com (8.11.6/8.11.6) with ESMTP id h041Win08577; Fri, 3 Jan 2003 17:32:44 -0800 Message-ID: <3E1639BC.42723FC6@redhat.com> Date: Sat, 04 Jan 2003 01:32:00 -0000 From: Michael Snyder Organization: Red Hat, Inc. X-Accept-Language: en MIME-Version: 1.0 To: Adam Fedor CC: GDB Patches Subject: Re: [RFA] Add ObjC recognition to linespec.c [5/5] References: <3E161D25.7070106@doc.com> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-SW-Source: 2003-01/txt/msg00136.txt.bz2 Adam Fedor wrote: > > 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... > > ------------------------------------------------------------------------------- > 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); > + I presume this will go away when you can include objc-lang.h. > /* 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); > + I like this -- presumably it keeps a lot of the new code out of poor old decrepit decode_line_1. > 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; > + } Was this meant to be an if? It seems to be a naked block. I'd feel better if there was an if around it, eg. is there a simple way to test for a selector name? Do I remember that they begin with a unique prefix such as '@'? > + > /* 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, ""); > + } OK, except didn't we decide that "skip_quoted_chars" needs a better name? One that identifies it with objc? > 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. */