This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFA] Add ObjC recognition to linespec.c [5/5]


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  <fedor@gnu.org>
> 
>         * 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.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]