/* Type stack for GDB parser.

   Copyright (C) 1986-2020 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/>.  */

#ifndef TYPE_STACK_H
#define TYPE_STACK_H

#include "gdbtypes.h"
#include <vector>

struct type;
struct expr_builder;

/* For parsing of complicated types.
   An array should be preceded in the list by the size of the array.  */
enum type_pieces
  {
    tp_end = -1, 
    tp_pointer, 
    tp_reference, 
    tp_rvalue_reference,
    tp_array, 
    tp_function,
    tp_function_with_arguments,
    tp_const, 
    tp_volatile, 
    tp_space_identifier,
    tp_type_stack,
    tp_kind
  };

/* The stack can contain either an enum type_pieces or an int.  */
union type_stack_elt
  {
    enum type_pieces piece;
    int int_val;
    struct type_stack *stack_val;
    std::vector<struct type *> *typelist_val;
  };

/* The type stack is an instance of this structure.  */

struct type_stack
{
public:

  type_stack () = default;

  DISABLE_COPY_AND_ASSIGN (type_stack);

  type_stack *create ()
  {
    type_stack *result = new type_stack ();
    result->m_elements = std::move (m_elements);
    return result;
  }

  /* 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 (enum type_pieces tp);

  void push (enum type_pieces tp)
  {
    type_stack_elt elt;
    elt.piece = tp;
    m_elements.push_back (elt);
  }

  void push (int n)
  {
    type_stack_elt elt;
    elt.int_val = n;
    m_elements.push_back (elt);
  }

  /* Push the type stack STACK as an element on this type stack.  */

  void push (struct type_stack *stack)
  {
    type_stack_elt elt;
    elt.stack_val = stack;
    m_elements.push_back (elt);
    push (tp_type_stack);
  }

  /* 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 (std::vector<struct type *> *list)
  {
    type_stack_elt elt;
    elt.typelist_val = list;
    m_elements.push_back (elt);
    push (tp_function_with_arguments);
  }

  enum type_pieces pop ()
  {
    if (m_elements.empty ())
      return tp_end;
    type_stack_elt elt = m_elements.back ();
    m_elements.pop_back ();
    return elt.piece;
  }

  int pop_int ()
  {
    if (m_elements.empty ())
      {
	/* "Can't happen".  */
	return 0;
      }
    type_stack_elt elt = m_elements.back ();
    m_elements.pop_back ();
    return elt.int_val;
  }

  std::vector<struct type *> *pop_typelist ()
  {
    gdb_assert (!m_elements.empty ());
    type_stack_elt elt = m_elements.back ();
    m_elements.pop_back ();
    return elt.typelist_val;
  }

  /* Pop a type_stack element.  */

  struct type_stack *pop_type_stack ()
  {
    gdb_assert (!m_elements.empty ());
    type_stack_elt elt = m_elements.back ();
    m_elements.pop_back ();
    return elt.stack_val;
  }

  /* 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 (struct expr_builder *pstate, const char *string);

  /* Append the elements of the type stack FROM to the type stack
     THIS.  Always returns THIS.  */

  struct type_stack *append (struct type_stack *from)
  {
    m_elements.insert (m_elements.end (), from->m_elements.begin (),
		       from->m_elements.end ());
    return this;
  }

  /* 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 ();

  /* 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);

private:

  /* 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.  */

  void insert_into (int slot, union type_stack_elt element)
  {
    gdb_assert (slot <= m_elements.size ());
    m_elements.insert (m_elements.begin () + slot, element);
  }


  /* Elements on the stack.  */
  std::vector<union type_stack_elt> m_elements;
};

#endif /* TYPE_STACK_H */
