diff options
author | Tom Tromey <tromey@redhat.com> | 2012-07-06 14:44:22 +0000 |
---|---|---|
committer | Tom Tromey <tromey@redhat.com> | 2012-07-06 14:44:22 +0000 |
commit | fcde5961ebacc85a85adcf858c751dc9c11f8d58 (patch) | |
tree | aa3300bf1a72493745909459933cefb0256899f8 /gdb/parse.c | |
parent | 1a7d0ce4eb4d724a3853500b45b379e746d7077a (diff) | |
download | gdb-fcde5961ebacc85a85adcf858c751dc9c11f8d58.zip gdb-fcde5961ebacc85a85adcf858c751dc9c11f8d58.tar.gz gdb-fcde5961ebacc85a85adcf858c751dc9c11f8d58.tar.bz2 |
* 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.
Diffstat (limited to 'gdb/parse.c')
-rw-r--r-- | gdb/parse.c | 107 |
1 files changed, 98 insertions, 9 deletions
diff --git a/gdb/parse.c b/gdb/parse.c index 83f7fec..b1ad832 100644 --- a/gdb/parse.c +++ b/gdb/parse.c @@ -1358,18 +1358,29 @@ 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 -check_type_stack_depth (void) +type_stack_reserve (struct type_stack *stack, int howmuch) { - if (type_stack.depth == type_stack.size) + if (stack->depth + howmuch >= stack->size) { - type_stack.size *= 2; - type_stack.elements - = xrealloc (type_stack.elements, - type_stack.size * sizeof (union type_stack_elt)); + 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) +{ + type_stack_reserve (&type_stack, 1); +} + /* A helper function for insert_type and insert_type_address_space. This does work of expanding the type stack and inserting the new element, ELEMENT, into the stack at location SLOT. */ @@ -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, |