* c-exp.y (%union) <type_stack>: New field.

(abs_decl, direct_abs_decl): Use <type_stack> type.  Update.
	(ptr_operator_ts): New production.
	(ptype): Update.
	* parse.c (type_stack_reserve): New function.
	(check_type_stack_depth): Use it.
	(pop_type_stack, append_type_stack, push_type_stack)
	(get_type_stack, type_stack_cleanup): New functions.
	(follow_types): Handle tp_type_stack.
	(_initialize_parse): Simplify initialization.
	* parser-defs.h (enum type_pieces) <tp_type_stack>: New
	constant.
	(union type_stack_elt) <stack_val>: New field.
	(get_type_stack, append_type_stack, push_type_stack)
	(type_stack_cleanup): Declare.
testsuite
	* gdb.base/whatis.exp: Add tests.
This commit is contained in:
Tom Tromey 2012-07-06 14:44:22 +00:00
parent 1a7d0ce4eb
commit fcde5961eb
6 changed files with 178 additions and 16 deletions

View File

@ -1,3 +1,21 @@
2012-07-06 Tom Tromey <tromey@redhat.com>
* c-exp.y (%union) <type_stack>: New field.
(abs_decl, direct_abs_decl): Use <type_stack> type. Update.
(ptr_operator_ts): New production.
(ptype): Update.
* parse.c (type_stack_reserve): New function.
(check_type_stack_depth): Use it.
(pop_type_stack, append_type_stack, push_type_stack)
(get_type_stack, type_stack_cleanup): New functions.
(follow_types): Handle tp_type_stack.
(_initialize_parse): Simplify initialization.
* parser-defs.h (enum type_pieces) <tp_type_stack>: New
constant.
(union type_stack_elt) <stack_val>: New field.
(get_type_stack, append_type_stack, push_type_stack)
(type_stack_cleanup): Declare.
2012-07-06 Tom Tromey <tromey@redhat.com>
* parser-defs.h (type_stack, type_stack_size, type_stack_depth):

View File

@ -157,6 +157,8 @@ void yyerror (char *);
struct stoken_vector svec;
struct type **tvec;
int *ivec;
struct type_stack *type_stack;
}
%{
@ -176,6 +178,8 @@ static struct stoken operator_stoken (const char *);
%type <lval> array_mod
%type <tval> conversion_type_id
%type <type_stack> ptr_operator_ts abs_decl direct_abs_decl
%token <typed_val_int> INT
%token <typed_val_float> FLOAT
%token <typed_val_decfloat> DECFLOAT
@ -963,27 +967,48 @@ ptr_operator:
{ insert_type (tp_reference); }
;
abs_decl: ptr_operator direct_abs_decl
| ptr_operator
ptr_operator_ts: ptr_operator
{
$$ = get_type_stack ();
/* This cleanup is eventually run by
c_parse. */
make_cleanup (type_stack_cleanup, $$);
}
;
abs_decl: ptr_operator_ts direct_abs_decl
{ $$ = append_type_stack ($2, $1); }
| ptr_operator_ts
| direct_abs_decl
;
direct_abs_decl: '(' abs_decl ')'
{ $$ = $2; }
| direct_abs_decl array_mod
{
push_type_stack ($1);
push_type_int ($2);
push_type (tp_array);
$$ = get_type_stack ();
}
| array_mod
{
push_type_int ($1);
push_type (tp_array);
$$ = get_type_stack ();
}
| direct_abs_decl func_mod
{ push_type (tp_function); }
{
push_type_stack ($1);
push_type (tp_function);
$$ = get_type_stack ();
}
| func_mod
{ push_type (tp_function); }
{
push_type (tp_function);
$$ = get_type_stack ();
}
;
array_mod: '[' ']'
@ -1206,7 +1231,10 @@ nonempty_typelist
ptype : typebase
| ptype abs_decl
{ $$ = follow_types ($1); }
{
push_type_stack ($2);
$$ = follow_types ($1);
}
;
conversion_type_id: typebase conversion_declarator

View File

@ -1358,16 +1358,27 @@ parse_c_float (struct gdbarch *gdbarch, const char *p, int len,
/* Stuff for maintaining a stack of types. Currently just used by C, but
probably useful for any language which declares its types "backwards". */
/* Ensure that there are HOWMUCH open slots on the type stack STACK. */
static void
type_stack_reserve (struct type_stack *stack, int howmuch)
{
if (stack->depth + howmuch >= stack->size)
{
stack->size *= 2;
if (stack->size < howmuch)
stack->size = howmuch;
stack->elements = xrealloc (stack->elements,
stack->size * sizeof (union type_stack_elt));
}
}
/* Ensure that there is a single open slot in the global type stack. */
static void
check_type_stack_depth (void)
{
if (type_stack.depth == type_stack.size)
{
type_stack.size *= 2;
type_stack.elements
= xrealloc (type_stack.elements,
type_stack.size * sizeof (union type_stack_elt));
}
type_stack_reserve (&type_stack, 1);
}
/* A helper function for insert_type and insert_type_address_space.
@ -1472,6 +1483,68 @@ pop_type_int (void)
return 0;
}
/* Pop a type_stack element from the global type stack. */
static struct type_stack *
pop_type_stack (void)
{
gdb_assert (type_stack.depth);
return type_stack.elements[--type_stack.depth].stack_val;
}
/* Append the elements of the type stack FROM to the type stack TO.
Always returns TO. */
struct type_stack *
append_type_stack (struct type_stack *to, struct type_stack *from)
{
type_stack_reserve (to, from->depth);
memcpy (&to->elements[to->depth], &from->elements[0],
from->depth * sizeof (union type_stack_elt));
to->depth += from->depth;
return to;
}
/* Push the type stack STACK as an element on the global type stack. */
void
push_type_stack (struct type_stack *stack)
{
check_type_stack_depth ();
type_stack.elements[type_stack.depth++].stack_val = stack;
push_type (tp_type_stack);
}
/* Copy the global type stack into a newly allocated type stack and
return it. The global stack is cleared. The returned type stack
must be freed with type_stack_cleanup. */
struct type_stack *
get_type_stack (void)
{
struct type_stack *result = XNEW (struct type_stack);
*result = type_stack;
type_stack.depth = 0;
type_stack.size = 0;
type_stack.elements = NULL;
return result;
}
/* A cleanup function that destroys a single type stack. */
void
type_stack_cleanup (void *arg)
{
struct type_stack *stack = arg;
xfree (stack->elements);
xfree (stack);
}
/* Pop the type stack and return the type which corresponds to FOLLOW_TYPE
as modified by all the stuff on the stack. */
struct type *
@ -1558,6 +1631,23 @@ follow_types (struct type *follow_type)
done with it. */
follow_type = lookup_function_type (follow_type);
break;
case tp_type_stack:
{
struct type_stack *stack = pop_type_stack ();
/* Sort of ugly, but not really much worse than the
alternatives. */
struct type_stack save = type_stack;
type_stack = *stack;
follow_type = follow_types (follow_type);
gdb_assert (type_stack.depth == 0);
type_stack = save;
}
break;
default:
gdb_assert_not_reached ("unrecognized tp_ value in follow_types");
}
return follow_type;
}
@ -1725,10 +1815,9 @@ exp_uses_objfile (struct expression *exp, struct objfile *objfile)
void
_initialize_parse (void)
{
type_stack.size = 80;
type_stack.size = 0;
type_stack.depth = 0;
type_stack.elements = xmalloc (type_stack.size
* sizeof (union type_stack_elt));
type_stack.elements = NULL;
add_setshow_zinteger_cmd ("expression", class_maintenance,
&expressiondebug,

View File

@ -119,13 +119,15 @@ enum type_pieces
tp_function,
tp_const,
tp_volatile,
tp_space_identifier
tp_space_identifier,
tp_type_stack
};
/* The stack can contain either an enum type_pieces or an int. */
union type_stack_elt
{
enum type_pieces piece;
int int_val;
struct type_stack *stack_val;
};
/* The type stack is an instance of this structure. */
@ -214,6 +216,15 @@ extern enum type_pieces pop_type (void);
extern int pop_type_int (void);
extern struct type_stack *get_type_stack (void);
extern struct type_stack *append_type_stack (struct type_stack *to,
struct type_stack *from);
extern void push_type_stack (struct type_stack *stack);
extern void type_stack_cleanup (void *arg);
extern int length_of_subexp (struct expression *, int);
extern int dump_subexp (struct expression *, struct ui_file *, int);

View File

@ -1,3 +1,7 @@
2012-07-06 Tom Tromey <tromey@redhat.com>
* gdb.base/whatis.exp: Add tests.
2012-07-04 Jan Kratochvil <jan.kratochvil@redhat.com>
PR 12649

View File

@ -479,3 +479,15 @@ gdb_test "whatis void (** const)()" \
gdb_test "whatis void (* const *)()" \
"type = void \\(\\* const \\*\\)\\(\\)" \
"whatis applied to pointer to const pointer to function"
gdb_test "whatis int *(*)()" \
"type = int \\*\\(\\*\\)\\(\\)" \
"whatis applied to pointer to function returning pointer to int"
gdb_test "whatis int *(**)()" \
"type = int \\*\\(\\*\\*\\)\\(\\)" \
"whatis applied to pointer to pointer to function returning pointer to int"
gdb_test "whatis char (*(*)())\[23\]" \
"type = char \\(\\*\\(\\*\\)\\(\\)\\)\\\[23\\\]" \
"whatis applied to pointer to function returning pointer to array"