/* Type stack for GDB parser. Copyright (C) 1986-2023 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 . */ #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 || tp == tp_restrict || tp == tp_atomic); /* 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 || tp == tp_restrict)) slot = 1; else slot = 0; element.piece = tp; insert_into (slot, element); } /* See type-stack.h. */ void type_stack::insert (struct expr_builder *pstate, const 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_type_instance_flags (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; case tp_atomic: flags |= TYPE_INSTANCE_FLAG_ATOMIC; break; case tp_restrict: flags |= TYPE_INSTANCE_FLAG_RESTRICT; 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; type_instance_flags make_addr_space = 0; bool make_restrict = false; bool make_atomic = false; int array_size; while (!done) switch (pop ()) { case tp_end: done = 1; goto process_qualifiers; break; case tp_const: make_const = 1; break; case tp_volatile: make_volatile = 1; break; case tp_space_identifier: make_addr_space = (enum type_instance_flag_value) pop_int (); break; case tp_atomic: make_atomic = true; break; case tp_restrict: make_restrict = true; break; case tp_pointer: follow_type = lookup_pointer_type (follow_type); goto process_qualifiers; case tp_reference: follow_type = lookup_lvalue_reference_type (follow_type); goto process_qualifiers; case tp_rvalue_reference: follow_type = lookup_rvalue_reference_type (follow_type); process_qualifiers: 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); if (make_restrict) follow_type = make_restrict_type (follow_type); if (make_atomic) follow_type = make_atomic_type (follow_type); make_const = make_volatile = 0; make_addr_space = 0; make_restrict = make_atomic = false; 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) follow_type->bounds ()->high.set_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 *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; }