* 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.
This commit is contained in:
parent
e870b9ca1b
commit
a5a44b5381
@ -1,3 +1,15 @@
|
|||||||
|
2011-01-17 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.
|
||||||
|
|
||||||
2011-01-14 Yao Qi <yao@codesourcery.com>
|
2011-01-14 Yao Qi <yao@codesourcery.com>
|
||||||
|
|
||||||
* arm-tdep.c (arm_register_reggroup_p): FPS register is in
|
* arm-tdep.c (arm_register_reggroup_p): FPS register is in
|
||||||
|
98
gdb/p-exp.y
98
gdb/p-exp.y
@ -158,6 +158,7 @@ static int
|
|||||||
parse_number (char *, int, int, YYSTYPE *);
|
parse_number (char *, int, int, YYSTYPE *);
|
||||||
|
|
||||||
static struct type *current_type;
|
static struct type *current_type;
|
||||||
|
static struct internalvar *intvar;
|
||||||
static int leftdiv_is_integer;
|
static int leftdiv_is_integer;
|
||||||
static void push_current_type (void);
|
static void push_current_type (void);
|
||||||
static void pop_current_type (void);
|
static void pop_current_type (void);
|
||||||
@ -184,6 +185,7 @@ static int search_field;
|
|||||||
|
|
||||||
%token <sval> STRING
|
%token <sval> STRING
|
||||||
%token <sval> FIELDNAME
|
%token <sval> FIELDNAME
|
||||||
|
%token <voidval> COMPLETE
|
||||||
%token <ssym> NAME /* BLOCKNAME defined below to give it higher precedence. */
|
%token <ssym> NAME /* BLOCKNAME defined below to give it higher precedence. */
|
||||||
%token <tsym> TYPENAME
|
%token <tsym> TYPENAME
|
||||||
%type <sval> name
|
%type <sval> name
|
||||||
@ -233,6 +235,7 @@ static int search_field;
|
|||||||
%%
|
%%
|
||||||
|
|
||||||
start : { current_type = NULL;
|
start : { current_type = NULL;
|
||||||
|
intvar = NULL;
|
||||||
search_field = 0;
|
search_field = 0;
|
||||||
leftdiv_is_integer = 0;
|
leftdiv_is_integer = 0;
|
||||||
}
|
}
|
||||||
@ -285,19 +288,56 @@ exp : DECREMENT '(' exp ')' %prec UNARY
|
|||||||
{ write_exp_elt_opcode (UNOP_PREDECREMENT); }
|
{ write_exp_elt_opcode (UNOP_PREDECREMENT); }
|
||||||
;
|
;
|
||||||
|
|
||||||
exp : exp '.' { search_field = 1; }
|
|
||||||
FIELDNAME
|
field_exp : exp '.' %prec UNARY
|
||||||
/* name */
|
{ search_field = 1; }
|
||||||
|
;
|
||||||
|
|
||||||
|
exp : field_exp FIELDNAME
|
||||||
{ write_exp_elt_opcode (STRUCTOP_STRUCT);
|
{ write_exp_elt_opcode (STRUCTOP_STRUCT);
|
||||||
write_exp_string ($4);
|
write_exp_string ($2);
|
||||||
write_exp_elt_opcode (STRUCTOP_STRUCT);
|
write_exp_elt_opcode (STRUCTOP_STRUCT);
|
||||||
search_field = 0;
|
search_field = 0;
|
||||||
if (current_type)
|
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 = 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 '['
|
exp : exp '['
|
||||||
/* We need to save the current_type value. */
|
/* We need to save the current_type value. */
|
||||||
{ char *arrayname;
|
{ char *arrayname;
|
||||||
@ -516,7 +556,18 @@ exp : variable
|
|||||||
;
|
;
|
||||||
|
|
||||||
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
|
exp : SIZEOF '(' type ')' %prec UNARY
|
||||||
@ -1060,8 +1111,13 @@ static char * uptok (tokstart, namelen)
|
|||||||
uptokstart[namelen]='\0';
|
uptokstart[namelen]='\0';
|
||||||
return uptokstart;
|
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
|
static int
|
||||||
yylex ()
|
yylex ()
|
||||||
@ -1075,7 +1131,9 @@ yylex ()
|
|||||||
int explen, tempbufindex;
|
int explen, tempbufindex;
|
||||||
static char *tempbuf;
|
static char *tempbuf;
|
||||||
static int tempbufsize;
|
static int tempbufsize;
|
||||||
|
int saw_structop = last_was_structop;
|
||||||
|
|
||||||
|
last_was_structop = 0;
|
||||||
retry:
|
retry:
|
||||||
|
|
||||||
prev_lexptr = lexptr;
|
prev_lexptr = lexptr;
|
||||||
@ -1111,6 +1169,9 @@ yylex ()
|
|||||||
switch (c = *tokstart)
|
switch (c = *tokstart)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
if (saw_structop && search_field)
|
||||||
|
return COMPLETE;
|
||||||
|
else
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case ' ':
|
case ' ':
|
||||||
@ -1172,7 +1233,12 @@ yylex ()
|
|||||||
case '.':
|
case '.':
|
||||||
/* Might be a floating point number. */
|
/* Might be a floating point number. */
|
||||||
if (lexptr[1] < '0' || lexptr[1] > '9')
|
if (lexptr[1] < '0' || lexptr[1] > '9')
|
||||||
|
{
|
||||||
|
if (in_parse_field)
|
||||||
|
last_was_structop = 1;
|
||||||
goto symbol; /* Nope, must be a symbol. */
|
goto symbol; /* Nope, must be a symbol. */
|
||||||
|
}
|
||||||
|
|
||||||
/* FALL THRU into number case. */
|
/* FALL THRU into number case. */
|
||||||
|
|
||||||
case '0':
|
case '0':
|
||||||
@ -1430,11 +1496,17 @@ yylex ()
|
|||||||
|
|
||||||
if (*tokstart == '$')
|
if (*tokstart == '$')
|
||||||
{
|
{
|
||||||
|
char c;
|
||||||
/* $ is the normal prefix for pascal hexadecimal values
|
/* $ is the normal prefix for pascal hexadecimal values
|
||||||
but this conflicts with the GDB use for debugger variables
|
but this conflicts with the GDB use for debugger variables
|
||||||
so in expression to enter hexadecimal values
|
so in expression to enter hexadecimal values
|
||||||
we still need to use C syntax with 0xff */
|
we still need to use C syntax with 0xff */
|
||||||
write_dollar_variable (yylval.sval);
|
write_dollar_variable (yylval.sval);
|
||||||
|
c = tokstart[namelen];
|
||||||
|
tokstart[namelen] = 0;
|
||||||
|
intvar = lookup_only_internalvar (++tokstart);
|
||||||
|
--tokstart;
|
||||||
|
tokstart[namelen] = c;
|
||||||
free (uptokstart);
|
free (uptokstart);
|
||||||
return VARIABLE;
|
return VARIABLE;
|
||||||
}
|
}
|
||||||
@ -1454,7 +1526,7 @@ yylex ()
|
|||||||
|
|
||||||
if (search_field && current_type)
|
if (search_field && current_type)
|
||||||
is_a_field = (lookup_struct_elt_type (current_type, tmp, 1) != NULL);
|
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;
|
sym = NULL;
|
||||||
else
|
else
|
||||||
sym = lookup_symbol (tmp, expression_context_block,
|
sym = lookup_symbol (tmp, expression_context_block,
|
||||||
@ -1469,7 +1541,7 @@ yylex ()
|
|||||||
}
|
}
|
||||||
if (search_field && current_type)
|
if (search_field && current_type)
|
||||||
is_a_field = (lookup_struct_elt_type (current_type, tmp, 1) != NULL);
|
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;
|
sym = NULL;
|
||||||
else
|
else
|
||||||
sym = lookup_symbol (tmp, expression_context_block,
|
sym = lookup_symbol (tmp, expression_context_block,
|
||||||
@ -1497,7 +1569,7 @@ yylex ()
|
|||||||
}
|
}
|
||||||
if (search_field && current_type)
|
if (search_field && current_type)
|
||||||
is_a_field = (lookup_struct_elt_type (current_type, tmp, 1) != NULL);
|
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;
|
sym = NULL;
|
||||||
else
|
else
|
||||||
sym = lookup_symbol (tmp, expression_context_block,
|
sym = lookup_symbol (tmp, expression_context_block,
|
||||||
|
Loading…
Reference in New Issue
Block a user