123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- /* Type stack for GDB parser.
- Copyright (C) 1986-2022 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 || 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<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;
- }
|