mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-25 00:37:38 +00:00
* 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:
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,
|
||||
|
||||
Reference in New Issue
Block a user