diff options
author | Tom Tromey <tom@tromey.com> | 2019-03-31 13:43:54 -0600 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2019-04-04 19:55:11 -0600 |
commit | dac43e327d002107f6bc9481749de039f410df73 (patch) | |
tree | e3f3ae3d7b892d2a68e271127e5b53cf75e2c0d0 /gdb/parse.c | |
parent | 2a61252965c91540133bece7deb92eb22e3cf929 (diff) | |
download | gdb-dac43e327d002107f6bc9481749de039f410df73.zip gdb-dac43e327d002107f6bc9481749de039f410df73.tar.gz gdb-dac43e327d002107f6bc9481749de039f410df73.tar.bz2 |
Move type stack handling to a new class
This introduces a new "type_stack" class, and moves all the parser
type stack handling to this class. Parsers that wish to use this
facility must now instantiate this class somehow. I chose this
approach because a minority of the existing parsers require this.
gdb/ChangeLog
2019-04-04 Tom Tromey <tom@tromey.com>
* type-stack.h: New file.
* type-stack.c: New file.
* parser-defs.h (enum type_pieces, union type_stack_elt): Move to
type-stack.h.
(insert_into_type_stack, insert_type, push_type, push_type_int)
(insert_type_address_space, pop_type, pop_type_int)
(pop_typelist, pop_type_stack, append_type_stack)
(push_type_stack, get_type_stack, push_typelist)
(follow_type_instance_flags, follow_types): Don't declare.
* parse.c (type_stack): Remove global.
(parse_exp_in_context): Update.
(insert_into_type_stack, insert_type, push_type, push_type_int)
(insert_type_address_space, pop_type, pop_type_int)
(pop_typelist, pop_type_stack, append_type_stack)
(push_type_stack, get_type_stack, push_typelist)
(follow_type_instance_flags, follow_types): Remove (moved to
type-stack.c).
* f-exp.y (type_stack): New global.
Update rules.
(push_kind_type, f_parse): Update.
* d-exp.y (type_stack): New global.
Update rules.
(d_parse): Update.
* c-exp.y (struct c_parse_state) <type_stack>: New member.
Update rules.
* Makefile.in (COMMON_SFILES): Add type-stack.c.
(HFILES_NO_SRCDIR): Add type-stack.h.
Diffstat (limited to 'gdb/parse.c')
-rw-r--r-- | gdb/parse.c | 333 |
1 files changed, 0 insertions, 333 deletions
diff --git a/gdb/parse.c b/gdb/parse.c index 7984a32..89a29f0 100644 --- a/gdb/parse.c +++ b/gdb/parse.c @@ -67,7 +67,6 @@ const struct exp_descriptor exp_descriptor_standard = /* Global variables declared in parser-defs.h (and commented there). */ innermost_block_tracker innermost_block; -static struct type_stack type_stack; static unsigned int expressiondebug = 0; @@ -1073,7 +1072,6 @@ parse_exp_in_context (const char **stringptr, CORE_ADDR pc, const struct language_defn *lang = NULL; int subexp; - type_stack.elements.clear (); innermost_block.reset (tracker_types); if (*stringptr == 0 || **stringptr == 0) @@ -1287,337 +1285,6 @@ parse_float (const char *p, int len, return target_float_from_string (data, type, std::string (p, len)); } -/* Stuff for maintaining a stack of types. Currently just used by C, but - probably useful for any language which declares its types "backwards". */ - -/* 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. */ - -static void -insert_into_type_stack (int slot, union type_stack_elt element) -{ - gdb_assert (slot <= type_stack.elements.size ()); - type_stack.elements.insert (type_stack.elements.begin () + slot, element); -} - -/* Insert a new type, TP, at the bottom of the type stack. If TP is - tp_pointer, tp_reference or tp_rvalue_reference, it is inserted at the - bottom. If TP is a qualifier, it is inserted at slot 1 (just above a - previous tp_pointer) if there is anything on the stack, or simply pushed - if the stack is empty. Other values for TP are invalid. */ - -void -insert_type (enum type_pieces tp) -{ - union type_stack_elt element; - int slot; - - gdb_assert (tp == tp_pointer || tp == tp_reference - || tp == tp_rvalue_reference || tp == tp_const - || tp == tp_volatile); - - /* If there is anything on the stack (we know it will be a - tp_pointer), insert the qualifier above it. Otherwise, simply - push this on the top of the stack. */ - if (!type_stack.elements.empty () && (tp == tp_const || tp == tp_volatile)) - slot = 1; - else - slot = 0; - - element.piece = tp; - insert_into_type_stack (slot, element); -} - -void -push_type (enum type_pieces tp) -{ - type_stack_elt elt; - elt.piece = tp; - type_stack.elements.push_back (elt); -} - -void -push_type_int (int n) -{ - type_stack_elt elt; - elt.int_val = n; - type_stack.elements.push_back (elt); -} - -/* Insert a tp_space_identifier and the corresponding address space - value into the stack. STRING is the name of an address space, as - recognized by address_space_name_to_int. If the stack is empty, - the new elements are simply pushed. If the stack is not empty, - this function assumes that the first item on the stack is a - tp_pointer, and the new values are inserted above the first - item. */ - -void -insert_type_address_space (struct expr_builder *pstate, char *string) -{ - union type_stack_elt element; - int slot; - - /* If there is anything on the stack (we know it will be a - tp_pointer), insert the address space qualifier above it. - Otherwise, simply push this on the top of the stack. */ - if (!type_stack.elements.empty ()) - slot = 1; - else - slot = 0; - - element.piece = tp_space_identifier; - insert_into_type_stack (slot, element); - element.int_val = address_space_name_to_int (pstate->gdbarch (), - string); - insert_into_type_stack (slot, element); -} - -enum type_pieces -pop_type (void) -{ - if (!type_stack.elements.empty ()) - { - type_stack_elt elt = type_stack.elements.back (); - type_stack.elements.pop_back (); - return elt.piece; - } - return tp_end; -} - -int -pop_type_int (void) -{ - if (!type_stack.elements.empty ()) - { - type_stack_elt elt = type_stack.elements.back (); - type_stack.elements.pop_back (); - return elt.int_val; - } - /* "Can't happen". */ - return 0; -} - -/* Pop a type list element from the global type stack. */ - -static std::vector<struct type *> * -pop_typelist (void) -{ - gdb_assert (!type_stack.elements.empty ()); - type_stack_elt elt = type_stack.elements.back (); - type_stack.elements.pop_back (); - return elt.typelist_val; -} - -/* Pop a type_stack element from the global type stack. */ - -static struct type_stack * -pop_type_stack (void) -{ - gdb_assert (!type_stack.elements.empty ()); - type_stack_elt elt = type_stack.elements.back (); - type_stack.elements.pop_back (); - return elt.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) -{ - to->elements.insert (to->elements.end (), from->elements.begin (), - from->elements.end ()); - return to; -} - -/* Push the type stack STACK as an element on the global type stack. */ - -void -push_type_stack (struct type_stack *stack) -{ - type_stack_elt elt; - elt.stack_val = stack; - type_stack.elements.push_back (elt); - 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 delete. */ - -struct type_stack * -get_type_stack (void) -{ - struct type_stack *result = new struct type_stack (std::move (type_stack)); - type_stack.elements.clear (); - return result; -} - -/* Push a function type with arguments onto the global type stack. - LIST holds the argument types. If the final item in LIST is NULL, - then the function will be varargs. */ - -void -push_typelist (std::vector<struct type *> *list) -{ - type_stack_elt elt; - elt.typelist_val = list; - type_stack.elements.push_back (elt); - push_type (tp_function_with_arguments); -} - -/* Pop the type stack and return a type_instance_flags that - corresponds the const/volatile qualifiers on the stack. This is - called by the C++ parser when parsing methods types, and as such no - other kind of type in the type stack is expected. */ - -type_instance_flags -follow_type_instance_flags () -{ - type_instance_flags flags = 0; - - for (;;) - switch (pop_type ()) - { - case tp_end: - return flags; - case tp_const: - flags |= TYPE_INSTANCE_FLAG_CONST; - break; - case tp_volatile: - flags |= TYPE_INSTANCE_FLAG_VOLATILE; - break; - default: - gdb_assert_not_reached ("unrecognized tp_ value in follow_types"); - } -} - - -/* 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 (struct type *follow_type) -{ - int done = 0; - int make_const = 0; - int make_volatile = 0; - int make_addr_space = 0; - int array_size; - - while (!done) - switch (pop_type ()) - { - case tp_end: - done = 1; - if (make_const) - follow_type = make_cv_type (make_const, - TYPE_VOLATILE (follow_type), - follow_type, 0); - if (make_volatile) - follow_type = make_cv_type (TYPE_CONST (follow_type), - make_volatile, - follow_type, 0); - if (make_addr_space) - follow_type = make_type_with_address_space (follow_type, - make_addr_space); - make_const = make_volatile = 0; - make_addr_space = 0; - break; - case tp_const: - make_const = 1; - break; - case tp_volatile: - make_volatile = 1; - break; - case tp_space_identifier: - make_addr_space = pop_type_int (); - break; - case tp_pointer: - follow_type = lookup_pointer_type (follow_type); - if (make_const) - follow_type = make_cv_type (make_const, - TYPE_VOLATILE (follow_type), - follow_type, 0); - if (make_volatile) - follow_type = make_cv_type (TYPE_CONST (follow_type), - make_volatile, - follow_type, 0); - if (make_addr_space) - follow_type = make_type_with_address_space (follow_type, - make_addr_space); - make_const = make_volatile = 0; - make_addr_space = 0; - break; - case tp_reference: - follow_type = lookup_lvalue_reference_type (follow_type); - goto process_reference; - case tp_rvalue_reference: - follow_type = lookup_rvalue_reference_type (follow_type); - process_reference: - if (make_const) - follow_type = make_cv_type (make_const, - TYPE_VOLATILE (follow_type), - follow_type, 0); - if (make_volatile) - follow_type = make_cv_type (TYPE_CONST (follow_type), - make_volatile, - follow_type, 0); - if (make_addr_space) - follow_type = make_type_with_address_space (follow_type, - make_addr_space); - make_const = make_volatile = 0; - make_addr_space = 0; - break; - case tp_array: - array_size = pop_type_int (); - /* FIXME-type-allocation: need a way to free this type when we are - done with it. */ - follow_type = - lookup_array_range_type (follow_type, - 0, array_size >= 0 ? array_size - 1 : 0); - if (array_size < 0) - TYPE_HIGH_BOUND_KIND (TYPE_INDEX_TYPE (follow_type)) - = PROP_UNDEFINED; - break; - case tp_function: - /* FIXME-type-allocation: need a way to free this type when we are - done with it. */ - follow_type = lookup_function_type (follow_type); - break; - - case tp_function_with_arguments: - { - std::vector<struct type *> *args = pop_typelist (); - - follow_type - = lookup_function_type_with_arguments (follow_type, - args->size (), - args->data ()); - } - 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.elements.empty ()); - - type_stack = save; - } - break; - default: - gdb_assert_not_reached ("unrecognized tp_ value in follow_types"); - } - return follow_type; -} - /* This function avoids direct calls to fprintf in the parser generated debug code. */ void |