* parse.c, parser-defs.h (follow_types): New function.
* c-exp.y (ptype : typebase abs_decl): Use it. * c-exp.y (ptype): Add support for type qualifiers after the typebase. The typebase rule already has support for them before the typebase. * Makefile.in: Change the expected number of shift/reduce conflicts to 6. This is OK--the 2 new conflicts are basically the same as one of the old ones.
This commit is contained in:
parent
cf4d863151
commit
f843c95fc3
65
gdb/c-exp.y
65
gdb/c-exp.y
|
@ -722,48 +722,23 @@ variable: name_not_typename
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
/* shift/reduce conflict: "typebase ." and the token is '('. (Shows up
|
||||||
|
twice, once where qualified_name is a possibility and once where
|
||||||
|
it is not). */
|
||||||
|
/* shift/reduce conflict: "typebase CONST_KEYWORD ." and the token is '('. */
|
||||||
|
/* shift/reduce conflict: "typebase VOLATILE_KEYWORD ." and the token is
|
||||||
|
'('. */
|
||||||
ptype : typebase
|
ptype : typebase
|
||||||
|
/* "const" and "volatile" are curently ignored. A type qualifier
|
||||||
|
before the type is currently handled in the typebase rule. */
|
||||||
|
| typebase CONST_KEYWORD
|
||||||
|
| typebase VOLATILE_KEYWORD
|
||||||
| typebase abs_decl
|
| typebase abs_decl
|
||||||
{
|
{ $$ = follow_types ($1); }
|
||||||
/* This is where the interesting stuff happens. */
|
| typebase CONST_KEYWORD abs_decl
|
||||||
int done = 0;
|
{ $$ = follow_types ($1); }
|
||||||
int array_size;
|
| typebase VOLATILE_KEYWORD abs_decl
|
||||||
struct type *follow_type = $1;
|
{ $$ = follow_types ($1); }
|
||||||
struct type *range_type;
|
|
||||||
|
|
||||||
while (!done)
|
|
||||||
switch (pop_type ())
|
|
||||||
{
|
|
||||||
case tp_end:
|
|
||||||
done = 1;
|
|
||||||
break;
|
|
||||||
case tp_pointer:
|
|
||||||
follow_type = lookup_pointer_type (follow_type);
|
|
||||||
break;
|
|
||||||
case tp_reference:
|
|
||||||
follow_type = lookup_reference_type (follow_type);
|
|
||||||
break;
|
|
||||||
case tp_array:
|
|
||||||
array_size = pop_type_int ();
|
|
||||||
if (array_size != -1)
|
|
||||||
{
|
|
||||||
range_type =
|
|
||||||
create_range_type ((struct type *) NULL,
|
|
||||||
builtin_type_int, 0,
|
|
||||||
array_size - 1);
|
|
||||||
follow_type =
|
|
||||||
create_array_type ((struct type *) NULL,
|
|
||||||
follow_type, range_type);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
follow_type = lookup_pointer_type (follow_type);
|
|
||||||
break;
|
|
||||||
case tp_function:
|
|
||||||
follow_type = lookup_function_type (follow_type);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
$$ = follow_type;
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
abs_decl: '*'
|
abs_decl: '*'
|
||||||
|
@ -790,6 +765,10 @@ direct_abs_decl: '(' abs_decl ')'
|
||||||
push_type (tp_array);
|
push_type (tp_array);
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* shift/reduce conflict. "direct_abs_decl . func_mod", and the token
|
||||||
|
is '('. */
|
||||||
|
|
||||||
| direct_abs_decl func_mod
|
| direct_abs_decl func_mod
|
||||||
{ push_type (tp_function); }
|
{ push_type (tp_function); }
|
||||||
| func_mod
|
| func_mod
|
||||||
|
@ -808,6 +787,8 @@ func_mod: '(' ')'
|
||||||
{ free ((PTR)$2); $$ = 0; }
|
{ free ((PTR)$2); $$ = 0; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
/* shift/reduce conflict: "type '(' typebase COLONCOLON '*' ')' ." and the
|
||||||
|
token is '('. */
|
||||||
type : ptype
|
type : ptype
|
||||||
| typebase COLONCOLON '*'
|
| typebase COLONCOLON '*'
|
||||||
{ $$ = lookup_member_type (builtin_type_int, $1); }
|
{ $$ = lookup_member_type (builtin_type_int, $1); }
|
||||||
|
@ -871,7 +852,9 @@ typebase /* Implements (approximately): (type-qualifier)* type-specifier */
|
||||||
{ $$ = lookup_template_type(copy_name($2), $4,
|
{ $$ = lookup_template_type(copy_name($2), $4,
|
||||||
expression_context_block);
|
expression_context_block);
|
||||||
}
|
}
|
||||||
/* "const" and "volatile" are curently ignored. */
|
/* "const" and "volatile" are curently ignored. A type qualifier
|
||||||
|
after the type is handled in the ptype rule. I think these could
|
||||||
|
be too. */
|
||||||
| CONST_KEYWORD typebase { $$ = $2; }
|
| CONST_KEYWORD typebase { $$ = $2; }
|
||||||
| VOLATILE_KEYWORD typebase { $$ = $2; }
|
| VOLATILE_KEYWORD typebase { $$ = $2; }
|
||||||
;
|
;
|
||||||
|
|
47
gdb/parse.c
47
gdb/parse.c
|
@ -726,6 +726,9 @@ parse_expression (string)
|
||||||
error ("Junk after end of expression.");
|
error ("Junk after end of expression.");
|
||||||
return exp;
|
return exp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Stuff for maintaining a stack of types. Currently just used by C, but
|
||||||
|
probably useful for any language which declares its types "backwards". */
|
||||||
|
|
||||||
void
|
void
|
||||||
push_type (tp)
|
push_type (tp)
|
||||||
|
@ -770,6 +773,50 @@ pop_type_int ()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Pop the type stack and return the type which corresponds to FOLLOW_TYPE
|
||||||
|
as modified by all the stuff on the stack. */
|
||||||
|
struct type *
|
||||||
|
follow_types (follow_type)
|
||||||
|
struct type *follow_type;
|
||||||
|
{
|
||||||
|
int done = 0;
|
||||||
|
int array_size;
|
||||||
|
struct type *range_type;
|
||||||
|
|
||||||
|
while (!done)
|
||||||
|
switch (pop_type ())
|
||||||
|
{
|
||||||
|
case tp_end:
|
||||||
|
done = 1;
|
||||||
|
break;
|
||||||
|
case tp_pointer:
|
||||||
|
follow_type = lookup_pointer_type (follow_type);
|
||||||
|
break;
|
||||||
|
case tp_reference:
|
||||||
|
follow_type = lookup_reference_type (follow_type);
|
||||||
|
break;
|
||||||
|
case tp_array:
|
||||||
|
array_size = pop_type_int ();
|
||||||
|
if (array_size != -1)
|
||||||
|
{
|
||||||
|
range_type =
|
||||||
|
create_range_type ((struct type *) NULL,
|
||||||
|
builtin_type_int, 0,
|
||||||
|
array_size - 1);
|
||||||
|
follow_type =
|
||||||
|
create_array_type ((struct type *) NULL,
|
||||||
|
follow_type, range_type);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
follow_type = lookup_pointer_type (follow_type);
|
||||||
|
break;
|
||||||
|
case tp_function:
|
||||||
|
follow_type = lookup_function_type (follow_type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return follow_type;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_initialize_parse ()
|
_initialize_parse ()
|
||||||
{
|
{
|
||||||
|
|
|
@ -133,6 +133,8 @@ pop_type PARAMS ((void));
|
||||||
extern int
|
extern int
|
||||||
pop_type_int PARAMS ((void));
|
pop_type_int PARAMS ((void));
|
||||||
|
|
||||||
|
extern struct type *follow_types PARAMS ((struct type *));
|
||||||
|
|
||||||
/* During parsing of a C expression, the pointer to the next character
|
/* During parsing of a C expression, the pointer to the next character
|
||||||
is in this variable. */
|
is in this variable. */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue