summaryrefslogtreecommitdiff
path: root/gdb/type-stack.c
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2019-03-31 13:43:54 -0600
committerTom Tromey <tom@tromey.com>2019-04-04 19:55:11 -0600
commitdac43e327d002107f6bc9481749de039f410df73 (patch)
treee3f3ae3d7b892d2a68e271127e5b53cf75e2c0d0 /gdb/type-stack.c
parent2a61252965c91540133bece7deb92eb22e3cf929 (diff)
downloadbinutils-gdb-dac43e327d002107f6bc9481749de039f410df73.tar.gz
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/type-stack.c')
-rw-r--r--gdb/type-stack.c209
1 files changed, 209 insertions, 0 deletions
diff --git a/gdb/type-stack.c b/gdb/type-stack.c
new file mode 100644
index 00000000000..cb0c147d307
--- /dev/null
+++ b/gdb/type-stack.c
@@ -0,0 +1,209 @@
+/* Type stack for GDB parser.
+
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "type-stack.h"
+
+#include "gdbtypes.h"
+#include "parser-defs.h"
+
+/* See type-stack.h. */
+
+void
+type_stack::insert (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 (!m_elements.empty () && (tp == tp_const || tp == tp_volatile))
+ slot = 1;
+ else
+ slot = 0;
+
+ element.piece = tp;
+ insert_into (slot, element);
+}
+
+/* See type-stack.h. */
+
+void
+type_stack::insert (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 (!m_elements.empty ())
+ slot = 1;
+ else
+ slot = 0;
+
+ element.piece = tp_space_identifier;
+ insert_into (slot, element);
+ element.int_val = address_space_name_to_int (pstate->gdbarch (),
+ string);
+ insert_into (slot, element);
+}
+
+/* See type-stack.h. */
+
+type_instance_flags
+type_stack::follow_type_instance_flags ()
+{
+ type_instance_flags flags = 0;
+
+ for (;;)
+ switch (pop ())
+ {
+ 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");
+ }
+}
+
+/* See type-stack.h. */
+
+struct type *
+type_stack::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 ())
+ {
+ 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_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_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 ();
+ follow_type = stack->follow_types (follow_type);
+ }
+ break;
+ default:
+ gdb_assert_not_reached ("unrecognized tp_ value in follow_types");
+ }
+ return follow_type;
+}