* 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:
parent
1a7d0ce4eb
commit
fcde5961eb
|
@ -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):
|
||||
|
|
38
gdb/c-exp.y
38
gdb/c-exp.y
|
@ -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
|
||||
|
|
109
gdb/parse.c
109
gdb/parse.c
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue