/* Header file for GDB compile C++ language support.
   Copyright (C) 2016-2021 Free Software Foundation, Inc.

   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 COMPILE_COMPILE_CPLUS_H
#define COMPILE_COMPILE_CPLUS_H

#include "gdbsupport/enum-flags.h"
#include "gcc-cp-plugin.h"
#include "symtab.h"

struct type;
struct block;

/* enum-flags wrapper  */
DEF_ENUM_FLAGS_TYPE (enum gcc_cp_qualifiers, gcc_cp_qualifiers_flags);
DEF_ENUM_FLAGS_TYPE (enum gcc_cp_ref_qualifiers, gcc_cp_ref_qualifiers_flags);
DEF_ENUM_FLAGS_TYPE (enum gcc_cp_symbol_kind, gcc_cp_symbol_kind_flags);

class compile_cplus_instance;

/* A single component of a type's scope.  Type names are broken into
   "components," a series of unqualified names comprising the type name,
   e.g., "namespace1", "namespace2", "myclass".  */

struct scope_component
{
  /* The unqualified name of this scope.  */
  std::string name;

  /* The block symbol for this type/scope.  */
  struct block_symbol bsymbol;
};

/* Comparison operators for scope_components.  */

bool operator== (const scope_component &lhs, const scope_component &rhs);
bool operator!= (const scope_component &lhs, const scope_component &rhs);


/* A single compiler scope used to define a type.

   A compile_scope is a list of scope_components, where all leading
   scope_components are namespaces, followed by a single non-namespace
   type component (the actual type we are converting).  */

class compile_scope : private std::vector<scope_component>
{
public:

  using std::vector<scope_component>::push_back;
  using std::vector<scope_component>::pop_back;
  using std::vector<scope_component>::back;
  using std::vector<scope_component>::empty;
  using std::vector<scope_component>::size;
  using std::vector<scope_component>::begin;
  using std::vector<scope_component>::end;
  using std::vector<scope_component>::operator[];

  compile_scope ()
    : m_nested_type (GCC_TYPE_NONE), m_pushed (false)
  {
  }

  /* Return the gcc_type of the type if it is a nested definition.
     Returns GCC_TYPE_NONE if this type was not nested.  */
  gcc_type nested_type ()
  {
    return m_nested_type;
  }

private:

  /* compile_cplus_instance is a friend class so that it can set the
     following private members when compile_scopes are created.  */
  friend compile_cplus_instance;

  /* If the type was actually a nested type, this will hold that nested
     type after the scope is pushed.  */
  gcc_type m_nested_type;

  /* If true, this scope was pushed to the compiler and all namespaces
     must be popped when leaving the scope.  */
  bool m_pushed;
};

/* Comparison operators for compile_scopes.  */

bool operator== (const compile_scope &lhs, const compile_scope &rhs);
bool operator!= (const compile_scope &lhs, const compile_scope &rhs);

/* Convert TYPENAME into a vector of namespace and top-most/super
   composite scopes.

   For example, for the input "Namespace::classB::classInner", the
   resultant vector will contain the tokens "Namespace" and
   "classB".  */

compile_scope type_name_to_scope (const char *type_name,
				  const struct block *block);

/* A callback suitable for use as the GCC C++ symbol oracle.  */

extern gcc_cp_oracle_function gcc_cplus_convert_symbol;

/* A callback suitable for use as the GCC C++ address oracle.  */

extern gcc_cp_symbol_address_function gcc_cplus_symbol_address;

/* A subclass of compile_instance that is specific to the C++ front
   end.  */

class compile_cplus_instance : public compile_instance
{
public:

  explicit compile_cplus_instance (struct gcc_cp_context *gcc_cp)
    : compile_instance (&gcc_cp->base, m_default_cflags),
      m_plugin (gcc_cp)
  {
    m_plugin.set_callbacks (gcc_cplus_convert_symbol,
			    gcc_cplus_symbol_address,
			    gcc_cplus_enter_scope, gcc_cplus_leave_scope,
			    this);
  }

  /* Convert a gdb type, TYPE, to a GCC type.

     If this type was defined in another type, NESTED_ACCESS should indicate
     the accessibility of this type (or GCC_CP_ACCESS_NONE if not a nested
     type).  GCC_CP_ACCESS_NONE is the default nested access.

     The new GCC type is returned.  */
  gcc_type convert_type
    (struct type *type,
     enum gcc_cp_symbol_kind nested_access = GCC_CP_ACCESS_NONE);

  /* Return a handle for the GCC plug-in.  */
  gcc_cp_plugin &plugin () { return m_plugin; }

  /* Factory method to create a new scope based on TYPE with name TYPE_NAME.
     [TYPE_NAME could be TYPE_NAME or SYMBOL_NATURAL_NAME.]

     If TYPE is a nested or local definition, nested_type () will return
     the gcc_type of the conversion.

     Otherwise, nested_type () is GCC_TYPE_NONE.  */
  compile_scope new_scope (const char *type_name, struct type *type);

  /* Enter the given NEW_SCOPE.  */
  void enter_scope (compile_scope &&scope);

  /* Leave the current scope.  */
  void leave_scope ();

  /* Add the qualifiers given by QUALS to BASE.  */
  gcc_type convert_qualified_base (gcc_type base,
				   gcc_cp_qualifiers_flags quals);

  /* Convert TARGET into a pointer type.  */
  gcc_type convert_pointer_base (gcc_type target);

  /* Convert BASE into a reference type.  RQUALS describes the reference.  */
  gcc_type convert_reference_base (gcc_type base,
				   enum gcc_cp_ref_qualifiers rquals);

  /* Return the declaration name of the symbol named NATURAL.
     This returns a name with no function arguments or template parameters,
     suitable for passing to the compiler plug-in.  */
  static gdb::unique_xmalloc_ptr<char> decl_name (const char *natural);

private:

  /* Callbacks suitable for use as the GCC C++ enter/leave scope requests.  */
  static gcc_cp_enter_leave_user_expr_scope_function gcc_cplus_enter_scope;
  static gcc_cp_enter_leave_user_expr_scope_function gcc_cplus_leave_scope;

  /* Default compiler flags for C++.  */
  static const char *m_default_cflags;

  /* The GCC plug-in.  */
  gcc_cp_plugin m_plugin;

  /* A list of scopes we are processing.  */
  std::vector<compile_scope> m_scopes;
};

/* Get the access flag for the NUM'th method of TYPE's FNI'th
   fieldlist.  */

enum gcc_cp_symbol_kind get_method_access_flag (const struct type *type,
						int fni, int num);

#endif /* COMPILE_COMPILE_CPLUS_H */
