/* Type stack for GDB parser.

   Copyright (C) 1986-2021 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;
}
