This is the mail archive of the gdb-patches@sourceware.org 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]

[Commit]: Allow field completion for pascal language


  As announced in my previous email,
as I didn't receive any comment on that RFC,
I checked the following in today.


Pierre Muller
GDB pascal language maintainer



>   I wrote this patch to get correct field completion
> for pascal language.
>   As pascal maintainer, I could have simply
> committed that change (I verified that it introduced
> no testsuite regression), but as
> I am not that familiar with the parser and completion
> code in general, I wanted to submit it for review first.
> 
>   I tried to adapt c-exp.y specific code using the
> COMPLETE token to p-exp.y.
>   The things are in fact a little easier in pascal
> as only '.' can be found before a union/struct field
> (named records, objects or classes in pascal language).
> 
>   If nobody has any remarks on that code,
> I plan to commit it in a few days, but I would
> of course welcome any comment.
> 
>   This modification is probably also doable in other language
> parsers... But I will not do that.
> 
> Pierre Muller
> GDB pascal language maintainer
> 
> 
> 
> 2011-01-12  Pierre Muller  <muller@ics.u-strasbg.fr>
> 
> 	* p-exp.y (intvar): New static variable, used to set CURRENT_TYPE
> 	for internal variables.
> 	(last_was_structop): New static variable.
> 	(COMPLETE): New token.
> 	(field_exp): New rule to group all '.' suffix handling.
> 	Add mark_struct_expression calls when approriate to be able
> 	to correctly find fields for completion.
> 	(yylex): Adapt to handle field completion and set INTVAR when
> 	required.
> 
> Index: src/gdb/p-exp.y
> ===================================================================
> RCS file: /cvs/src/src/gdb/p-exp.y,v
> retrieving revision 1.53
> diff -u -p -r1.53 p-exp.y
> --- src/gdb/p-exp.y	10 Jan 2011 20:38:49 -0000	1.53
> +++ src/gdb/p-exp.y	12 Jan 2011 14:33:45 -0000
> @@ -158,10 +158,12 @@ static int
>  parse_number (char *, int, int, YYSTYPE *);
> 
>  static struct type *current_type;
> +static struct internalvar *intvar;
>  static int leftdiv_is_integer;
>  static void push_current_type (void);
>  static void pop_current_type (void);
>  static int search_field;
> +
>  %}
> 
>  %type <voidval> exp exp1 type_exp start normal_start variable
> qualified_name
> @@ -184,6 +186,7 @@ static int search_field;
> 
>  %token <sval> STRING
>  %token <sval> FIELDNAME
> +%token <voidval> COMPLETE
>  %token <ssym> NAME /* BLOCKNAME defined below to give it higher
> precedence.
> */
>  %token <tsym> TYPENAME
>  %type <sval> name
> @@ -233,6 +236,7 @@ static int search_field;
>  %%
> 
>  start   :	{ current_type = NULL;
> +		  intvar = NULL;
>  		  search_field = 0;
>  		  leftdiv_is_integer = 0;
>  		}
> @@ -285,19 +289,56 @@ exp	:	DECREMENT  '(' exp ')'   %prec UNA
>  			{ write_exp_elt_opcode (UNOP_PREDECREMENT); }
>  	;
> 
> -exp	:	exp '.' { search_field = 1; }
> -		FIELDNAME
> -		/* name */
> +
> +field_exp	:	exp '.'	%prec UNARY
> +			{ search_field = 1; }
> +	;
> +
> +exp	:	field_exp FIELDNAME
>  			{ write_exp_elt_opcode (STRUCTOP_STRUCT);
> -			  write_exp_string ($4);
> +			  write_exp_string ($2);
>  			  write_exp_elt_opcode (STRUCTOP_STRUCT);
>  			  search_field = 0;
>  			  if (current_type)
> -			    { while (TYPE_CODE (current_type) ==
> TYPE_CODE_PTR)
> -				current_type = TYPE_TARGET_TYPE
> (current_type);
> +			    {
> +			      while (TYPE_CODE (current_type)
> +				     == TYPE_CODE_PTR)
> +				current_type =
> +				  TYPE_TARGET_TYPE (current_type);
>  			      current_type = lookup_struct_elt_type (
> -				current_type, $4.ptr, 0); };
> -			 } ;
> +				current_type, $2.ptr, 0);
> +			    }
> +			 }
> +	;
> +
> +exp	:	field_exp name
> +			{ mark_struct_expression ();
> +			  write_exp_elt_opcode (STRUCTOP_STRUCT);
> +			  write_exp_string ($2);
> +			  write_exp_elt_opcode (STRUCTOP_STRUCT);
> +			  search_field = 0;
> +			  if (current_type)
> +			    {
> +			      while (TYPE_CODE (current_type)
> +				     == TYPE_CODE_PTR)
> +				current_type =
> +				  TYPE_TARGET_TYPE (current_type);
> +			      current_type = lookup_struct_elt_type (
> +				current_type, $2.ptr, 0);
> +			    }
> +			}
> +	;
> +
> +exp	:	field_exp COMPLETE
> +			{ struct stoken s;
> +			  mark_struct_expression ();
> +			  write_exp_elt_opcode (STRUCTOP_STRUCT);
> +			  s.ptr = "";
> +			  s.length = 0;
> +			  write_exp_string (s);
> +			  write_exp_elt_opcode (STRUCTOP_STRUCT); }
> +	;
> +
>  exp	:	exp '['
>  			/* We need to save the current_type value.  */
>  			{ char *arrayname;
> @@ -516,8 +557,19 @@ exp	:	variable
>  	;
> 
>  exp	:	VARIABLE
> -			/* Already written by write_dollar_variable.  */
> -	;
> +			/* Already written by write_dollar_variable.
> +			   Handle current_type.  */
> + 			{  if (intvar) {
> + 			     struct value * val, * mark;
> +
> +			     mark = value_mark ();
> + 			     val = value_of_internalvar (parse_gdbarch,
> + 							 intvar);
> + 			     current_type = value_type (val);
> +			     value_release_to_mark (mark);
> + 			   }
> + 			}
> + 	;
> 
>  exp	:	SIZEOF '(' type ')'	%prec UNARY
>  			{ write_exp_elt_opcode (OP_LONG);
> @@ -1060,8 +1112,13 @@ static char * uptok (tokstart, namelen)
>    uptokstart[namelen]='\0';
>    return uptokstart;
>  }
> -/* Read one token, getting characters through lexptr.  */
> 
> +/* This is set if the previously-returned token was a structure
> +   operator  '.'.  This is used only when parsing to
> +   do field name completion.  */
> +static int last_was_structop;
> +
> +/* Read one token, getting characters through lexptr.  */
> 
>  static int
>  yylex ()
> @@ -1075,7 +1132,9 @@ yylex ()
>    int explen, tempbufindex;
>    static char *tempbuf;
>    static int tempbufsize;
> -
> +  int saw_structop = last_was_structop;
> +
> +  last_was_structop = 0;
>   retry:
> 
>    prev_lexptr = lexptr;
> @@ -1111,7 +1170,10 @@ yylex ()
>    switch (c = *tokstart)
>      {
>      case 0:
> -      return 0;
> +      if (saw_structop && search_field)
> +	return COMPLETE;
> +      else
> +       return 0;
> 
>      case ' ':
>      case '\t':
> @@ -1172,7 +1234,12 @@ yylex ()
>      case '.':
>        /* Might be a floating point number.  */
>        if (lexptr[1] < '0' || lexptr[1] > '9')
> -	goto symbol;		/* Nope, must be a symbol.  */
> +	{
> +	  if (in_parse_field)
> +	    last_was_structop = 1;
> +	  goto symbol;		/* Nope, must be a symbol.  */
> +	}
> +
>        /* FALL THRU into number case.  */
> 
>      case '0':
> @@ -1430,11 +1497,17 @@ yylex ()
> 
>    if (*tokstart == '$')
>      {
> +      char c;
>        /* $ is the normal prefix for pascal hexadecimal values
>          but this conflicts with the GDB use for debugger variables
>          so in expression to enter hexadecimal values
>          we still need to use C syntax with 0xff  */
>        write_dollar_variable (yylval.sval);
> +      c = tokstart[namelen];
> +      tokstart[namelen] = 0;
> +      intvar = lookup_only_internalvar (++tokstart);
> +      --tokstart;
> +      tokstart[namelen] = c;
>        free (uptokstart);
>        return VARIABLE;
>      }
> @@ -1454,7 +1527,7 @@ yylex ()
> 
>      if (search_field && current_type)
>        is_a_field = (lookup_struct_elt_type (current_type, tmp, 1) !=
> NULL);
> -    if (is_a_field)
> +    if (is_a_field || in_parse_field)
>        sym = NULL;
>      else
>        sym = lookup_symbol (tmp, expression_context_block,
> @@ -1469,7 +1542,7 @@ yylex ()
>           }
>         if (search_field && current_type)
>  	 is_a_field = (lookup_struct_elt_type (current_type, tmp, 1) !=
> NULL);
> -       if (is_a_field)
> +       if (is_a_field || in_parse_field)
>  	 sym = NULL;
>         else
>  	 sym = lookup_symbol (tmp, expression_context_block,
> @@ -1497,7 +1570,7 @@ yylex ()
>            }
>         if (search_field && current_type)
>  	 is_a_field = (lookup_struct_elt_type (current_type, tmp, 1) !=
> NULL);
> -       if (is_a_field)
> +       if (is_a_field || in_parse_field)
>  	 sym = NULL;
>         else
>  	 sym = lookup_symbol (tmp, expression_context_block,



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