/* Convert types from GDB to GCC

   Copyright (C) 2014-2018 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 "common/preprocessor.h"
#include "gdbtypes.h"
#include "compile-internal.h"
#include "compile-cplus.h"
#include "gdb_assert.h"
#include "symtab.h"
#include "source.h"
#include "cp-support.h"
#include "cp-abi.h"
#include "symtab.h"
#include "objfiles.h"
#include "block.h"
#include "gdbcmd.h"
#include "c-lang.h"
#include "compile-c.h" 		/* Included for c_get_range_decl_name
				   et al.  */
#include <algorithm>

/* Default compile flags for C++.  */

const char *compile_cplus_instance::m_default_cflags = "-std=gnu++11";

/* Flag to enable internal debugging.  */

static int debug_compile_cplus_types = 0;

/* Flag to enable internal scope switching debugging.  */

static int debug_compile_cplus_scopes = 0;

/* Forward declarations.  */

static gcc_type compile_cplus_convert_func (compile_cplus_instance *instance,
					    struct type *type,
					    bool strip_artificial);

/* See description in compile-cplus.h.  */

gdb::unique_xmalloc_ptr<char>
compile_cplus_instance::decl_name (const char *natural)
{
  if (natural == nullptr)
    return nullptr;

  char *name = cp_func_name (natural);
  if (name != nullptr)
    return gdb::unique_xmalloc_ptr<char> (name);

  return gdb::unique_xmalloc_ptr<char> (xstrdup (natural));
}

/* Get the access flag for the NUM'th field of TYPE.  */

static enum gcc_cp_symbol_kind
get_field_access_flag (const struct type *type, int num)
{
  if (TYPE_FIELD_PROTECTED (type, num))
    return GCC_CP_ACCESS_PROTECTED;
  else if (TYPE_FIELD_PRIVATE (type, num))
    return GCC_CP_ACCESS_PRIVATE;

  /* GDB assumes everything else is public.  */
  return GCC_CP_ACCESS_PUBLIC;
}

/* 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)
{
  gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT);

  /* If this type was not declared a class, everything is public.  */
  if (!TYPE_DECLARED_CLASS (type))
    return GCC_CP_ACCESS_PUBLIC;

  /* Otherwise, read accessibility from the fn_field.  */
  const struct fn_field *methods = TYPE_FN_FIELDLIST1 (type, fni);
  if (TYPE_FN_FIELD_PROTECTED (methods, num))
    return GCC_CP_ACCESS_PROTECTED;
  else if (TYPE_FN_FIELD_PRIVATE (methods, num))
    return GCC_CP_ACCESS_PRIVATE;
  else
    return GCC_CP_ACCESS_PUBLIC;
}

/* A useful debugging function to output the scope SCOPE to stdout.  */

static void __attribute__ ((used))
debug_print_scope (const compile_scope &scope)
{
  for (const auto &comp: scope)
    {
      const char *symbol = (comp.bsymbol.symbol != nullptr
			    ? SYMBOL_NATURAL_NAME (comp.bsymbol.symbol)
			    : "<none>");

      printf_unfiltered ("\tname = %s, symbol = %s\n", comp.name.c_str (),
			 symbol);
    }
}

/* See description in compile-cplus.h.  */

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

  if (type_name == nullptr)
    {
      /* An anonymous type.  We cannot really do much here.  We simply cannot
	 look up anonymous types easily/at all.  */
      return scope;
    }

  const char *p = type_name;
  std::string lookup_name;

  while (*p != '\0')
    {
      /* Create a string token of the first component of TYPE_NAME.  */
      int len = cp_find_first_component (p);
      std::string s (p, len);

      /* Advance past the last token.  */
      p += len;

      /* Look up the symbol and decide when to stop.  */
      if (!lookup_name.empty ())
	lookup_name += "::";
      lookup_name += s;

      /* Look up the resulting name.  */
      struct block_symbol bsymbol
	= lookup_symbol (lookup_name.c_str (), block, VAR_DOMAIN, nullptr);

      if (bsymbol.symbol != nullptr)
	{
	  scope_component comp = {s, bsymbol};

	  scope.push_back (comp);

	  if (TYPE_CODE (SYMBOL_TYPE (bsymbol.symbol)) != TYPE_CODE_NAMESPACE)
	    {
	      /* We're done.  */
	      break;
	    }
	}

      if (*p == ':')
	{
	  ++p;
	  if (*p == ':')
	    ++p;
	  else
	    {
	      /* This shouldn't happen since we are not attempting to
		 loop over user input.  This name is generated by GDB
		 from debug info.  */
	      internal_error (__FILE__, __LINE__,
			      _("malformed TYPE_NAME during parsing"));
	    }
	}
    }

  return scope;
}

/* Compare two scope_components for equality.  These are equal if the names
   of the two components' are the same.  */

bool
operator== (const scope_component &lhs, const scope_component &rhs)
{
  return lhs.name == rhs.name;
}

/* Compare two scope_components for inequality.  These are not equal if
   the two components' names are not equal.  */

bool
operator!= (const scope_component &lhs, const scope_component &rhs)
{
  return lhs.name != rhs.name;
}

/* Compare two compile_scopes for equality.  These are equal if they are both
   contain the same number of components and each component is equal.  */

bool
operator== (const compile_scope &lhs, const compile_scope &rhs)
{
  if (lhs.size () != rhs.size ())
    return false;

  for (int i = 0; i < lhs.size (); ++i)
    {
      if (lhs[i] != rhs[i])
	return false;
    }

  return true;
}

/* Compare two compile_scopes for inequality.  These are inequal if they
   contain unequal number of elements or if any of the components are not
   the same.  */

bool
operator!= (const compile_scope &lhs, const compile_scope &rhs)
{
  if (lhs.size () != rhs.size ())
    return true;

  for (int i = 0; i < lhs.size (); ++i)
    {
      if (lhs[i] != rhs[i])
	return true;
    }

  return false;
}

/* See description in compile-cplus.h.  */

void
compile_cplus_instance::enter_scope (compile_scope &&new_scope)
{
  bool must_push = m_scopes.empty () || m_scopes.back () != new_scope;

  new_scope.m_pushed = must_push;

  /* Save the new scope.  */
  m_scopes.push_back (std::move (new_scope));

  if (must_push)
    {
      if (debug_compile_cplus_scopes)
	{
	  fprintf_unfiltered (gdb_stdlog, "entering new scope %s\n",
			      host_address_to_string (&m_scopes.back ()));
	}

      /* Push the global namespace. */
      plugin ().push_namespace ("");

      /* Push all other namespaces.  Note that we do not push the last
	 scope_component -- that's the actual type we are converting.  */
      std::for_each
	(m_scopes.back ().begin (), m_scopes.back ().end () - 1,
	 [this] (const scope_component &comp)
	 {
	  gdb_assert (TYPE_CODE (SYMBOL_TYPE (comp.bsymbol.symbol))
		      == TYPE_CODE_NAMESPACE);

	  const char *ns = (comp.name == CP_ANONYMOUS_NAMESPACE_STR ? nullptr
			    : comp.name.c_str ());

	  this->plugin ().push_namespace (ns);
	 });
    }
  else
    {
      if (debug_compile_cplus_scopes)
	{
	  fprintf_unfiltered (gdb_stdlog, "staying in current scope -- "
			      "scopes are identical\n");
	}
    }
}

/* See description in compile-cplus.h.  */

void
compile_cplus_instance::leave_scope ()
{
  /* Get the current scope and remove it from the internal list of
     scopes.  */
  compile_scope current = m_scopes.back ();

  m_scopes.pop_back ();

  if (current.m_pushed)
    {
      if (debug_compile_cplus_scopes)
	{
	  fprintf_unfiltered (gdb_stdlog, "leaving scope %s\n",
			      host_address_to_string (&current));
	}

      /* Pop namespaces.  */
      std::for_each
	(current.begin (),current.end () - 1,
	 [this] (const scope_component &comp) {
	  gdb_assert (TYPE_CODE (SYMBOL_TYPE (comp.bsymbol.symbol))
		      == TYPE_CODE_NAMESPACE);
	  this->plugin ().pop_binding_level (comp.name.c_str ());
	});

      /* Pop global namespace.  */
      plugin ().pop_binding_level ("");
    }
  else
    {
      if (debug_compile_cplus_scopes)
	fprintf_unfiltered (gdb_stdlog,
			    "identical scopes -- not leaving scope\n");
    }
}

/* See description in compile-cplus.h.  */

compile_scope
compile_cplus_instance::new_scope (const char *type_name, struct type *type)
{
  /* Break the type name into components.  If TYPE was defined in some
     superclass, we do not process TYPE but process the enclosing type
     instead.  */
  compile_scope scope = type_name_to_scope (type_name, block ());

  if (!scope.empty ())
    {
      /* Get the name of the last component, which should be the
	 unqualified name of the type to process.  */
      scope_component &comp = scope.back ();

      if (!types_equal (type, SYMBOL_TYPE (comp.bsymbol.symbol))
	  && (m_scopes.empty ()
	      || (m_scopes.back ().back ().bsymbol.symbol
		  != comp.bsymbol.symbol)))
	{
	  /* The type is defined inside another class(es).  Convert that
	     type instead of defining this type.  */
	  convert_type (SYMBOL_TYPE (comp.bsymbol.symbol));

	  /* If the original type (passed in to us) is defined in a nested
	     class, the previous call will give us that type's gcc_type.
	     Upper layers are expecting to get the original type's
	     gcc_type!  */
	  get_cached_type (type, &scope.m_nested_type);
	  return scope;
	}
    }
  else
    {
      if (TYPE_NAME (type) == nullptr)
	{
	  /* Anonymous type  */

	  /* We don't have a qualified name for this to look up, but
	     we need a scope.  We have to assume, then, that it is the same
	     as the current scope, if any.  */
	  if (!m_scopes.empty ())
	    {
	      scope = m_scopes.back ();
	      scope.m_pushed = false;
	    }
	  else
	    scope.push_back (scope_component ());
	}
      else
	{
	  scope_component comp
	    = {
	        decl_name (TYPE_NAME (type)).get (),
		lookup_symbol (TYPE_NAME (type), block (), VAR_DOMAIN, nullptr)
	      };
	  scope.push_back (comp);
	}
    }

  /* There must be at least one component in the compile_scope.  */
  gdb_assert (scope.size () > 0);
  return scope;
}

/* See description in compile-cplus.h.  */

gcc_type
compile_cplus_instance::convert_reference_base
  (gcc_type base, enum gcc_cp_ref_qualifiers rquals)
{
  return this->plugin ().build_reference_type (base, rquals);
}

/* Convert a reference type to its gcc representation.  */

static gcc_type
compile_cplus_convert_reference (compile_cplus_instance *instance,
				 struct type *type)
{
  gcc_type target = instance->convert_type (TYPE_TARGET_TYPE (type));

  enum gcc_cp_ref_qualifiers quals = GCC_CP_REF_QUAL_NONE;
  switch (TYPE_CODE (type))
    {
    case TYPE_CODE_REF:
      quals = GCC_CP_REF_QUAL_LVALUE;
      break;
    case TYPE_CODE_RVALUE_REF:
      quals = GCC_CP_REF_QUAL_RVALUE;
      break;
    default:
      gdb_assert_not_reached ("unexpected type code for reference type");
    }

  return instance->convert_reference_base (target, quals);
}

/* See description in compile-cplus.h.  */

gcc_type
compile_cplus_instance::convert_pointer_base(gcc_type target)
{
  return plugin ().build_pointer_type (target);
}

/* Convert a pointer type to its gcc representation.  */

static gcc_type
compile_cplus_convert_pointer (compile_cplus_instance *instance,
			       struct type *type)
{
  gcc_type target = instance->convert_type (TYPE_TARGET_TYPE (type));

  return instance->convert_pointer_base (target);
}

/* Convert an array type to its gcc representation.  */

static gcc_type
compile_cplus_convert_array (compile_cplus_instance *instance,
			     struct type *type)
{
  struct type *range = TYPE_INDEX_TYPE (type);
  gcc_type element_type = instance->convert_type (TYPE_TARGET_TYPE (type));

  if (TYPE_LOW_BOUND_KIND (range) != PROP_CONST)
    {
      const char *s = _("array type with non-constant"
			" lower bound is not supported");

      return instance->plugin ().error (s);
    }

  if (TYPE_LOW_BOUND (range) != 0)
    {
      const char *s = _("cannot convert array type with "
			"non-zero lower bound to C");

      return instance->plugin ().error (s);
    }

  if (TYPE_HIGH_BOUND_KIND (range) == PROP_LOCEXPR
      || TYPE_HIGH_BOUND_KIND (range) == PROP_LOCLIST)
    {
      if (TYPE_VECTOR (type))
	{
	  const char *s = _("variably-sized vector type is not supported");

	  return instance->plugin ().error (s);
	}

      std::string upper_bound
	= c_get_range_decl_name (&TYPE_RANGE_DATA (range)->high);
      return instance->plugin ().build_vla_array_type (element_type,
					     upper_bound.c_str ());
    }
  else
    {
      LONGEST low_bound, high_bound, count;

      if (get_array_bounds (type, &low_bound, &high_bound) == 0)
	count = -1;
      else
	{
	  gdb_assert (low_bound == 0); /* Ensured above.  */
	  count = high_bound + 1;
	}

      if (TYPE_VECTOR (type))
	return instance->plugin ().build_vector_type (element_type, count);

      return instance->plugin ().build_array_type (element_type, count);
    }
}

/* Convert a typedef of TYPE.  If not GCC_CP_ACCESS_NONE, NESTED_ACCESS
   will define the accessibility of the typedef definition in its
   containing class.  */

static gcc_type
compile_cplus_convert_typedef (compile_cplus_instance *instance,
			       struct type *type,
			       enum gcc_cp_symbol_kind nested_access)
{
  compile_scope scope = instance->new_scope (TYPE_NAME (type), type);

  if (scope.nested_type () != GCC_TYPE_NONE)
    return scope.nested_type ();

  gdb::unique_xmalloc_ptr<char> name
    = compile_cplus_instance::decl_name (TYPE_NAME (type));

  /* Make sure the scope for this type has been pushed.  */
  instance->enter_scope (std::move (scope));

  /* Convert the typedef's real type.  */
  gcc_type typedef_type = instance->convert_type (check_typedef (type));

  instance->plugin ().build_decl ("typedef", name.get (),
				  GCC_CP_SYMBOL_TYPEDEF | nested_access,
			typedef_type, 0, 0, nullptr, 0);

  /* Completed this scope.  */
  instance->leave_scope ();
  return typedef_type;
}

/* Convert types defined in TYPE.  */

static void
compile_cplus_convert_type_defns (compile_cplus_instance *instance,
				  struct type *type)
{
  int i;
  enum gcc_cp_symbol_kind accessibility;

  /* Convert typedefs.  */
  for (i = 0; i < TYPE_TYPEDEF_FIELD_COUNT (type); ++i)
    {
      if (TYPE_TYPEDEF_FIELD_PROTECTED (type, i))
	accessibility = GCC_CP_ACCESS_PROTECTED;
      else if (TYPE_TYPEDEF_FIELD_PRIVATE (type, i))
	accessibility = GCC_CP_ACCESS_PRIVATE;
      else
	accessibility = GCC_CP_ACCESS_PUBLIC;
      instance->convert_type (TYPE_TYPEDEF_FIELD_TYPE (type, i), accessibility);
    }

  /* Convert nested types.  */
  for (i = 0; i < TYPE_NESTED_TYPES_COUNT (type); ++i)
    {
      if (TYPE_NESTED_TYPES_FIELD_PROTECTED (type, i))
	accessibility = GCC_CP_ACCESS_PROTECTED;
      else if (TYPE_NESTED_TYPES_FIELD_PRIVATE (type, i))
	accessibility = GCC_CP_ACCESS_PRIVATE;
      else
	accessibility = GCC_CP_ACCESS_PUBLIC;
      instance->convert_type (TYPE_NESTED_TYPES_FIELD_TYPE (type, i),
			      accessibility);
    }
}

/* Convert data members defined in TYPE, which should be struct/class/union
   with gcc_type COMP_TYPE.  */

static void
compile_cplus_convert_struct_or_union_members
  (compile_cplus_instance *instance, struct type *type, gcc_type comp_type)
{
  for (int i = TYPE_N_BASECLASSES (type); i < TYPE_NFIELDS (type); ++i)
    {
      const char *field_name = TYPE_FIELD_NAME (type, i);

      if (TYPE_FIELD_IGNORE (type, i)
	  || TYPE_FIELD_ARTIFICIAL (type, i))
	continue;

      /* GDB records unnamed/anonymous fields with empty string names.  */
      if (*field_name == '\0')
	field_name = nullptr;

      gcc_type field_type
	= instance->convert_type (TYPE_FIELD_TYPE (type, i));

      if (field_is_static (&TYPE_FIELD (type, i)))
	{
	  CORE_ADDR physaddr;

	  switch (TYPE_FIELD_LOC_KIND (type, i))
	    {
	    case FIELD_LOC_KIND_PHYSADDR:
	      {
		physaddr = TYPE_FIELD_STATIC_PHYSADDR (type, i);

		instance->plugin ().build_decl
		  ("field physaddr", field_name,
		   (GCC_CP_SYMBOL_VARIABLE | get_field_access_flag (type, i)),
		   field_type, nullptr, physaddr, nullptr, 0);
	      }
	      break;

	    case FIELD_LOC_KIND_PHYSNAME:
	      {
		const char *physname = TYPE_FIELD_STATIC_PHYSNAME (type, i);
		struct block_symbol sym
		  = lookup_symbol (physname, instance->block (),
				   VAR_DOMAIN, nullptr);

		if (sym.symbol == nullptr)
		  {
		    /* We didn't actually find the symbol.  There's little
		       we can do but ignore this member.  */
		    continue;
		  }
		const char *filename = symbol_symtab (sym.symbol)->filename;
		unsigned int line = SYMBOL_LINE (sym.symbol);

		physaddr = SYMBOL_VALUE_ADDRESS (sym.symbol);
		instance->plugin ().build_decl
		  ("field physname", field_name,
		   (GCC_CP_SYMBOL_VARIABLE| get_field_access_flag (type, i)),
		   field_type, nullptr, physaddr, filename, line);
	      }
	      break;

	    default:
	      gdb_assert_not_reached
		("unexpected static field location kind");
	    }
	}
      else
	{
	  unsigned long bitsize = TYPE_FIELD_BITSIZE (type, i);
	  enum gcc_cp_symbol_kind field_flags = GCC_CP_SYMBOL_FIELD
	    | get_field_access_flag (type, i);

	  if (bitsize == 0)
	    bitsize = 8 * TYPE_LENGTH (TYPE_FIELD_TYPE (type, i));

	  instance->plugin ().build_field
	    (field_name, field_type, field_flags, bitsize,
	     TYPE_FIELD_BITPOS (type, i));
	}
    }
}

/* Convert a method type to its gcc representation.  */

static gcc_type
compile_cplus_convert_method (compile_cplus_instance *instance,
			      struct type *parent_type,
			      struct type *method_type)
{
  /* Get the actual function type of the method, the corresponding class's
     type and corresponding qualifier flags.  */
  gcc_type func_type = compile_cplus_convert_func (instance, method_type, true);
  gcc_type class_type = instance->convert_type (parent_type);
  gcc_cp_qualifiers_flags quals = (enum gcc_cp_qualifiers) 0;

  if (TYPE_CONST (method_type))
    quals |= GCC_CP_QUALIFIER_CONST;
  if (TYPE_VOLATILE (method_type))
    quals |= GCC_CP_QUALIFIER_VOLATILE;
  if (TYPE_RESTRICT (method_type))
    quals |= GCC_CP_QUALIFIER_RESTRICT;

  /* Not yet implemented.  */
  gcc_cp_ref_qualifiers_flags rquals = GCC_CP_REF_QUAL_NONE;

  return instance->plugin ().build_method_type
    (class_type, func_type, quals, rquals);
}

/* Convert a member or method pointer represented by TYPE.  */

static gcc_type
compile_cplus_convert_memberptr (compile_cplus_instance *instance,
				 struct type *type)
{
  struct type *containing_class = TYPE_SELF_TYPE (type);

  if (containing_class == nullptr)
    return GCC_TYPE_NONE;

  gcc_type class_type = instance->convert_type (containing_class);
  gcc_type member_type
    = instance->convert_type (TYPE_TARGET_TYPE (type));

  return instance->plugin ().build_pointer_to_member_type
    (class_type, member_type);
}

/* Convert all methods defined in TYPE, which should be a class/struct/union
   with gcc_type CLASS_TYPE.  */

static void
compile_cplus_convert_struct_or_union_methods (compile_cplus_instance *instance,
					       struct type *type,
					       gcc_type class_type)
{
  for (int i = 0; i < TYPE_NFN_FIELDS (type); ++i)
    {
      struct fn_field *methods = TYPE_FN_FIELDLIST1 (type, i);
      gdb::unique_xmalloc_ptr<char> overloaded_name
	= compile_cplus_instance::decl_name (TYPE_FN_FIELDLIST_NAME (type, i));

      /* Loop through the fieldlist, adding decls to the compiler's
	 representation of the class.  */
      for (int j = 0; j < TYPE_FN_FIELDLIST_LENGTH (type, i); ++j)
	{
	  /* Skip artificial methods.  */
	  if (TYPE_FN_FIELD_ARTIFICIAL (methods, j))
	    continue;

	  gcc_cp_symbol_kind_flags sym_kind = GCC_CP_SYMBOL_FUNCTION;
	  gcc_type method_type;
	  struct block_symbol sym
	    = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (methods, j),
			     instance->block (), VAR_DOMAIN, nullptr);

	  if (sym.symbol == nullptr)
	    {
	      if (TYPE_FN_FIELD_VIRTUAL_P (methods, j))
		{
		  /* This is beyond hacky, and is really only a workaround for
		     detecting pure virtual methods.  */
		  method_type = compile_cplus_convert_method
		    (instance, type, TYPE_FN_FIELD_TYPE (methods, j));

		  instance->plugin ().build_decl
		    ("pure virtual method", overloaded_name.get (),
		     (sym_kind
		      | get_method_access_flag (type, i, j)
		      | GCC_CP_FLAG_VIRTUAL_FUNCTION
		      | GCC_CP_FLAG_PURE_VIRTUAL_FUNCTION),
		     method_type, nullptr, 0, nullptr, 0);
		  continue;
		}

	      /* This can happen if we have a DW_AT_declaration DIE
		 for the method, but no "definition"-type DIE (with
		 DW_AT_specification referencing the decl DIE), i.e.,
		 the compiler has probably optimized the method away.

		 In this case, all we can hope to do is issue a warning
		 to the user letting him know.  If the user has not actually
		 requested using this method, things should still work.  */
	      warning (_("Method %s appears to be optimized out.\n"
			 "All references to this method will be undefined."),
			 TYPE_FN_FIELD_PHYSNAME (methods, j));
	      continue;
	    }

	  const char *filename = symbol_symtab (sym.symbol)->filename;
	  unsigned int line = SYMBOL_LINE (sym.symbol);
	  CORE_ADDR address = BLOCK_START (SYMBOL_BLOCK_VALUE (sym.symbol));
	  const char *kind;

	  if (TYPE_FN_FIELD_STATIC_P (methods, j))
	    {
	      kind = "static method";
	      method_type = compile_cplus_convert_func
		(instance, TYPE_FN_FIELD_TYPE (methods, j), true);
	    }
	  else
	    {
	      kind = "method";
	      method_type = (compile_cplus_convert_method
			     (instance, type, TYPE_FN_FIELD_TYPE (methods, j)));
	    }

	  if (TYPE_FN_FIELD_VIRTUAL_P (methods, j))
	    sym_kind |= GCC_CP_FLAG_VIRTUAL_FUNCTION;

	  instance->plugin ().build_decl
	    (kind, overloaded_name.get (),
	     sym_kind | get_method_access_flag (type, i, j),
	     method_type, nullptr, address, filename, line);
	}
    }
}

/* Convert a struct or union type to its gcc representation.  If this type
   was defined in another type, NESTED_ACCESS should indicate the
   accessibility of this type.  */

static gcc_type
compile_cplus_convert_struct_or_union (compile_cplus_instance *instance,
				       struct type *type,
				       enum gcc_cp_symbol_kind nested_access)
{
  const char *filename = nullptr;
  unsigned short line = 0;

  /* Get the decl name of this type.  */
  gdb::unique_xmalloc_ptr<char> name
    = compile_cplus_instance::decl_name (TYPE_NAME (type));

  /* Create a new scope for TYPE.  */
  compile_scope scope = instance->new_scope (TYPE_NAME (type), type);

  if (scope.nested_type () != GCC_TYPE_NONE)
    {
      /* The type requested was actually defined inside another type,
	 such as a nested class definition.  Return that type.  */
      return scope.nested_type ();
    }

  /* Push all scopes.  */
  instance->enter_scope (std::move (scope));

  /* First we create the resulting type and enter it into our hash
     table.  This lets recursive types work.  */

  gcc_decl resuld;
  if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
    {
      const char *what = TYPE_DECLARED_CLASS (type) ? "struct" : "class";

      resuld = instance->plugin ().build_decl
	(what, name.get (), (GCC_CP_SYMBOL_CLASS | nested_access
			     | (TYPE_DECLARED_CLASS (type)
				? GCC_CP_FLAG_CLASS_NOFLAG
				: GCC_CP_FLAG_CLASS_IS_STRUCT)),
	 0, nullptr, 0, filename, line);
    }
  else
    {
      gdb_assert (TYPE_CODE (type) == TYPE_CODE_UNION);
      resuld = instance->plugin ().build_decl
	("union", name.get (), GCC_CP_SYMBOL_UNION | nested_access,
	 0, nullptr, 0, filename, line);
    }

  gcc_type result;
  if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
    {
      struct gcc_vbase_array bases;
      int num_baseclasses = TYPE_N_BASECLASSES (type);

      memset (&bases, 0, sizeof (bases));

      if (num_baseclasses > 0)
	{
	  bases.elements = XNEWVEC (gcc_type, num_baseclasses);
	  bases.flags = XNEWVEC (enum gcc_cp_symbol_kind, num_baseclasses);
	  bases.n_elements = num_baseclasses;
	  for (int i = 0; i < num_baseclasses; ++i)
	    {
	      struct type *base_type = TYPE_BASECLASS (type, i);

	      bases.flags[i] = GCC_CP_SYMBOL_BASECLASS
		| get_field_access_flag (type, i)
		| (BASETYPE_VIA_VIRTUAL (type, i)
		   ? GCC_CP_FLAG_BASECLASS_VIRTUAL
		   : GCC_CP_FLAG_BASECLASS_NOFLAG);
	      bases.elements[i] = instance->convert_type (base_type);
	    }
	}

      result = instance->plugin ().start_class_type
	(name.get (), resuld, &bases, filename, line);
      xfree (bases.flags);
      xfree (bases.elements);
    }
  else
    {
      gdb_assert (TYPE_CODE (type) == TYPE_CODE_UNION);
      result = instance->plugin ().start_class_type
	(name.get (), resuld, nullptr, filename, line);
    }

  instance->insert_type (type, result);

  /* Add definitions.  */
  compile_cplus_convert_type_defns (instance, type);

  /* Add methods.  */
  compile_cplus_convert_struct_or_union_methods (instance, type, result);

  /* Add members.  */
  compile_cplus_convert_struct_or_union_members (instance, type, result);

  /* All finished.  */
  instance->plugin ().finish_class_type (name.get (), TYPE_LENGTH (type));

  /* Pop all scopes.  */
  instance->leave_scope ();
  return result;
}

/* Convert an enum type to its gcc representation.  If this type
   was defined in another type, NESTED_ACCESS should indicate the
   accessibility of this type.*/

static gcc_type
compile_cplus_convert_enum (compile_cplus_instance *instance, struct type *type,
			    enum gcc_cp_symbol_kind nested_access)
{
  int scoped_enum_p = FALSE;

  /* Create a new scope for this type.  */
  compile_scope scope = instance->new_scope (TYPE_NAME (type), type);

  if (scope.nested_type () != GCC_TYPE_NONE)
    {
      /* The type requested was actually defined inside another type,
	 such as a nested class definition.  Return that type.  */
      return scope.nested_type ();
    }

  gdb::unique_xmalloc_ptr<char> name
    = compile_cplus_instance::decl_name (TYPE_NAME (type));

  /* Push all scopes.  */
  instance->enter_scope (std::move (scope));

  gcc_type int_type
    = instance->plugin ().get_int_type (TYPE_UNSIGNED (type),
					TYPE_LENGTH (type), nullptr);
  gcc_type result
    = instance->plugin ().start_enum_type (name.get (), int_type,
					   GCC_CP_SYMBOL_ENUM | nested_access
					   | (scoped_enum_p
					      ? GCC_CP_FLAG_ENUM_SCOPED
					      : GCC_CP_FLAG_ENUM_NOFLAG),
					   nullptr, 0);
  for (int i = 0; i < TYPE_NFIELDS (type); ++i)
    {
      gdb::unique_xmalloc_ptr<char> fname
	= compile_cplus_instance::decl_name (TYPE_FIELD_NAME (type, i));

      if (TYPE_FIELD_LOC_KIND (type, i) != FIELD_LOC_KIND_ENUMVAL
	  || fname == nullptr)
	continue;

      instance->plugin ().build_enum_constant (result, fname.get (),
					       TYPE_FIELD_ENUMVAL (type, i));
    }

  /* Finish enum definition and pop scopes.  */
  instance->plugin ().finish_enum_type (result);
  instance->leave_scope ();
  return result;
}

/* Convert a function type to its gcc representation.  This function does
   not deal with function templates.  */

static gcc_type
compile_cplus_convert_func (compile_cplus_instance *instance,
			    struct type *type, bool strip_artificial)
{
  int is_varargs = TYPE_VARARGS (type);
  struct type *target_type = TYPE_TARGET_TYPE (type);

  /* Functions with no debug info have no return type.  Ideally we'd
     want to fallback to the type of the cast just before the
     function, like GDB's built-in expression parser, but we don't
     have access to that type here.  For now, fallback to int, like
     GDB's parser used to do.  */
  if (target_type == nullptr)
    {
      if (TYPE_OBJFILE_OWNED (type))
	target_type = objfile_type (TYPE_OWNER (type).objfile)->builtin_int;
      else
	target_type = builtin_type (TYPE_OWNER (type).gdbarch)->builtin_int;
      warning (_("function has unknown return type; assuming int"));
    }

  /* This approach means we can't make self-referential function
     types.  Those are impossible in C, though.  */
  gcc_type return_type = instance->convert_type (target_type);

  struct gcc_type_array array =
    { TYPE_NFIELDS (type), XNEWVEC (gcc_type, TYPE_NFIELDS (type)) };
  int artificials = 0;
  for (int i = 0; i < TYPE_NFIELDS (type); ++i)
    {
      if (strip_artificial && TYPE_FIELD_ARTIFICIAL (type, i))
	{
	  --array.n_elements;
	  ++artificials;
	}
      else
	{
	  array.elements[i - artificials]
	    = instance->convert_type (TYPE_FIELD_TYPE (type, i));
	}
    }

  /* We omit setting the argument types to `void' to be a little flexible
     with some minsyms like printf (compile-cplus.exp has examples).  */
  gcc_type result = instance->plugin ().build_function_type
    (return_type, &array, is_varargs);
  xfree (array.elements);
  return result;
}

/* Convert an integer type to its gcc representation.  */

static gcc_type
compile_cplus_convert_int (compile_cplus_instance *instance, struct type *type)
{
  if (TYPE_NOSIGN (type))
    {
      gdb_assert (TYPE_LENGTH (type) == 1);
      return instance->plugin ().get_char_type ();
    }

  return instance->plugin ().get_int_type
    (TYPE_UNSIGNED (type), TYPE_LENGTH (type), TYPE_NAME (type));
}

/* Convert a floating-point type to its gcc representation.  */

static gcc_type
compile_cplus_convert_float (compile_cplus_instance *instance,
			     struct type *type)
{
  return instance->plugin ().get_float_type
    (TYPE_LENGTH (type), TYPE_NAME (type));
}

/* Convert the 'void' type to its gcc representation.  */

static gcc_type
compile_cplus_convert_void (compile_cplus_instance *instance, struct type *type)
{
  return instance->plugin ().get_void_type ();
}

/* Convert a boolean type to its gcc representation.  */

static gcc_type
compile_cplus_convert_bool (compile_cplus_instance *instance, struct type *type)
{
  return instance->plugin ().get_bool_type ();
}

/* See description in compile-cplus.h.  */

gcc_type
compile_cplus_instance::convert_qualified_base (gcc_type base,
						gcc_cp_qualifiers_flags quals)
{
  gcc_type result = base;

  if (quals != 0)
    result = plugin ().build_qualified_type (base, quals);

  return result;
}

/* See description in compile-cplus.h.  */

static gcc_type
compile_cplus_convert_qualified (compile_cplus_instance *instance,
				 struct type *type)
{
  struct type *unqual = make_unqualified_type (type);
  gcc_cp_qualifiers_flags quals = (enum gcc_cp_qualifiers) 0;
  gcc_type unqual_converted = instance->convert_type (unqual);

  if (TYPE_CONST (type))
    quals |= GCC_CP_QUALIFIER_CONST;
  if (TYPE_VOLATILE (type))
    quals |= GCC_CP_QUALIFIER_VOLATILE;
  if (TYPE_RESTRICT (type))
    quals |= GCC_CP_QUALIFIER_RESTRICT;

  return instance->convert_qualified_base (unqual_converted, quals);
}

/* Convert a complex type to its gcc representation.  */

static gcc_type
compile_cplus_convert_complex (compile_cplus_instance *instance,
			       struct type *type)
{
  gcc_type base = instance->convert_type (TYPE_TARGET_TYPE (type));

  return instance->plugin ().build_complex_type (base);
}

/* Convert a namespace of TYPE.  */

static gcc_type
compile_cplus_convert_namespace (compile_cplus_instance *instance,
				 struct type *type)
{
  compile_scope scope = instance->new_scope (TYPE_NAME (type), type);
  gdb::unique_xmalloc_ptr<char> name
    = compile_cplus_instance::decl_name (TYPE_NAME (type));

  /* Push scope.  */
  instance->enter_scope (std::move (scope));

  /* Convert this namespace.  */
  instance->plugin ().push_namespace (name.get ());
  instance->plugin ().pop_binding_level (name.get ());

  /* Pop scope.  */
  instance->leave_scope ();

  /* Namespaces are non-cacheable types.  */
  return GCC_TYPE_NONE;
}

/* A helper function which knows how to convert most types from their
   gdb representation to the corresponding gcc form.  This examines
   the TYPE and dispatches to the appropriate conversion function.  It
   returns the gcc type.

   If the type was defined in another type, NESTED_ACCESS should indicate the
   accessibility of this type.  */

static gcc_type
convert_type_cplus_basic (compile_cplus_instance *instance,
			  struct type *type,
			  enum gcc_cp_symbol_kind nested_access)
{
  /* If we are converting a qualified type, first convert the
     unqualified type and then apply the qualifiers.  */
  if ((TYPE_INSTANCE_FLAGS (type) & (TYPE_INSTANCE_FLAG_CONST
				     | TYPE_INSTANCE_FLAG_VOLATILE
				     | TYPE_INSTANCE_FLAG_RESTRICT)) != 0)
    return compile_cplus_convert_qualified (instance, type);

  switch (TYPE_CODE (type))
    {
    case TYPE_CODE_REF:
    case TYPE_CODE_RVALUE_REF:
      return compile_cplus_convert_reference (instance, type);

    case TYPE_CODE_PTR:
      return compile_cplus_convert_pointer (instance, type);

    case TYPE_CODE_ARRAY:
      return compile_cplus_convert_array (instance, type);

    case TYPE_CODE_STRUCT:
    case TYPE_CODE_UNION:
      return
	compile_cplus_convert_struct_or_union (instance, type, nested_access);

    case TYPE_CODE_ENUM:
      return compile_cplus_convert_enum (instance, type, nested_access);

    case TYPE_CODE_FUNC:
      return compile_cplus_convert_func (instance, type, false);

    case TYPE_CODE_METHOD:
      return
	compile_cplus_convert_method (instance, TYPE_SELF_TYPE (type), type);

    case TYPE_CODE_MEMBERPTR:
    case TYPE_CODE_METHODPTR:
      return compile_cplus_convert_memberptr (instance, type);
      break;

    case TYPE_CODE_INT:
      return compile_cplus_convert_int (instance, type);

    case TYPE_CODE_FLT:
      return compile_cplus_convert_float (instance, type);

    case TYPE_CODE_VOID:
      return compile_cplus_convert_void (instance, type);

    case TYPE_CODE_BOOL:
      return compile_cplus_convert_bool (instance, type);

    case TYPE_CODE_COMPLEX:
      return compile_cplus_convert_complex (instance, type);

    case TYPE_CODE_NAMESPACE:
      return compile_cplus_convert_namespace (instance, type);

    case TYPE_CODE_TYPEDEF:
      return compile_cplus_convert_typedef (instance, type, nested_access);

    default:
      break;
    }

  std::string s = string_printf (_("unhandled TYPE_CODE %d"),
				 TYPE_CODE (type));

  return instance->plugin ().error (s.c_str ());
}

gcc_type
compile_cplus_instance::convert_type (struct type *type,
				      enum gcc_cp_symbol_kind nested_access)
{
  /* Check if TYPE has already been converted.  */
  gcc_type result;
  if (get_cached_type (type, &result))
    return result;

  /* It is the first time this type has been seen -- convert it
     and cache it, if appropriate..  */
  result = convert_type_cplus_basic (this, type, nested_access);
  if (result != GCC_TYPE_NONE)
    insert_type (type, result);
  return result;
}

void
compile_cplus_instance::gcc_cplus_enter_scope
 (void *datum, struct gcc_cp_context *gcc_context)
{
}

void
compile_cplus_instance::gcc_cplus_leave_scope
  (void *datum, struct gcc_cp_context *gcc_context)
{
}



/* Plug-in forwards.  */

/* C++ plug-in wrapper.  */

/* A result printer for plug-in calls that return a gcc_type or
   gcc_decl.  */

static void
compile_cplus_debug_output_1 (ULONGEST arg)
{
  fprintf_unfiltered (gdb_stdlog, "%s", pulongest (arg));
}

static void
compile_cplus_debug_output_1 (const char *arg)
{
  if (arg == nullptr)
    fputs_unfiltered ("NULL", gdb_stdlog);
  else
    fputs_unfiltered (arg, gdb_stdlog);
}

static void
compile_cplus_debug_output ()
{
}

template <typename T>
static void
compile_cplus_debug_output_1 (const T *arg)
{
}

template <typename T, typename... Targs>
static void
compile_cplus_debug_output (T arg, Targs... Args)
{
  compile_cplus_debug_output_1 (arg);
  fputc_unfiltered (' ', gdb_stdlog);
  compile_cplus_debug_output (Args...);
}

#define FORWARD(OP,...) m_context->cp_ops->OP(m_context, ##__VA_ARGS__)
#define OUTPUT_DEBUG_RESULT(R)			  \
  if (debug_compile_cplus_types)		  \
    {						  \
      fputs_unfiltered (": ", gdb_stdlog);	  \
      compile_cplus_debug_output (R);		  \
      fputc_unfiltered ('\n', gdb_stdlog);	  \
    }						  \

#define GCC_METHOD0(R, N)			  \
  R gcc_cp_plugin::N () const			  \
  {						  \
    if (debug_compile_cplus_types)		  \
      compile_cplus_debug_output (STRINGIFY (N)); \
    auto result = FORWARD (N);			  \
    OUTPUT_DEBUG_RESULT (result);		  \
    return result;				  \
  }
#define GCC_METHOD1(R, N, A)				\
  R gcc_cp_plugin::N (A a) const			\
  {							\
    if (debug_compile_cplus_types)			\
      compile_cplus_debug_output (STRINGIFY (N), a);	\
    auto result = FORWARD (N, a);			\
    OUTPUT_DEBUG_RESULT (result);			\
    return result;					\
  }
#define GCC_METHOD2(R, N, A, B)				\
  R gcc_cp_plugin::N (A a, B b) const			\
  {							\
    if (debug_compile_cplus_types)			\
      compile_cplus_debug_output (STRINGIFY (N), a, b);	\
    auto result = FORWARD (N, a, b);			\
    OUTPUT_DEBUG_RESULT (result);			\
    return result;					\
  }
#define GCC_METHOD3(R, N, A, B, C) \
  R gcc_cp_plugin::N (A a, B b, C c) const			\
  {								\
    if (debug_compile_cplus_types)				\
      compile_cplus_debug_output (STRINGIFY (N), a, b, c);	\
    auto result = FORWARD (N, a, b, c);				\
    OUTPUT_DEBUG_RESULT (result);				\
    return result;						\
  }
#define GCC_METHOD4(R, N, A, B, C, D)				\
  R gcc_cp_plugin::N (A a, B b, C c, D d) const			\
  {								\
    if (debug_compile_cplus_types)				\
      compile_cplus_debug_output (STRINGIFY (N), a, b, c, d);	\
    auto result = FORWARD (N, a, b, c, d);			\
    OUTPUT_DEBUG_RESULT (result);				\
    return result;						\
  }
#define GCC_METHOD5(R, N, A, B, C, D, E)				\
  R gcc_cp_plugin::N (A a, B b, C c, D d, E e) const			\
  {									\
    if (debug_compile_cplus_types)					\
      compile_cplus_debug_output (STRINGIFY (N), a, b, c, d, e);	\
    auto result = FORWARD (N, a, b, c, d, e);				\
    OUTPUT_DEBUG_RESULT (result);					\
    return result;							\
  }
#define GCC_METHOD7(R, N, A, B, C, D, E, F, G)				\
  R gcc_cp_plugin::N (A a, B b, C c, D d, E e, F f, G g) const		\
  {									\
    if (debug_compile_cplus_types)					\
      compile_cplus_debug_output (STRINGIFY (N), a, b, c, d, e, f, g);	\
    auto result = FORWARD (N, a, b, c, d, e, f, g);			\
    OUTPUT_DEBUG_RESULT (result);					\
    return result;							\
  }

#include "gcc-cp-fe.def"

#undef GCC_METHOD0
#undef GCC_METHOD1
#undef GCC_METHOD2
#undef GCC_METHOD3
#undef GCC_METHOD4
#undef GCC_METHOD5
#undef GCC_METHOD7
#undef FORWARD
#undef OUTPUT_DEBUG_RESULT

gcc_expr
gcc_cp_plugin::build_decl (const char *debug_decltype, const char *name,
			   enum gcc_cp_symbol_kind sym_kind, gcc_type sym_type,
			   const char *substitution_name, gcc_address address,
			   const char *filename, unsigned int line_number)
{
  if (debug_compile_cplus_types)
    fprintf_unfiltered (gdb_stdlog, "<%s> ", debug_decltype);

  return build_decl (name, sym_kind, sym_type, substitution_name,
		     address, filename, line_number);
}

gcc_type
gcc_cp_plugin::start_class_type (const char *debug_name, gcc_decl typedecl,
				 const struct gcc_vbase_array *base_classes,
				 const char *filename, unsigned int line_number)
{
  if (debug_compile_cplus_types)
    fprintf_unfiltered (gdb_stdlog, "<%s> ", debug_name);

  return start_class_type (typedecl, base_classes, filename, line_number);
}

int
gcc_cp_plugin::finish_class_type (const char *debug_name,
				  unsigned long size_in_bytes)
{
  if (debug_compile_cplus_types)
    fprintf_unfiltered (gdb_stdlog, "<%s> ", debug_name);

  return finish_class_type (size_in_bytes);
}

int
gcc_cp_plugin::pop_binding_level (const char *debug_name)
{
  if (debug_compile_cplus_types)
    fprintf_unfiltered (gdb_stdlog, "<%s> ", debug_name);

  return pop_binding_level ();
}

void
_initialize_compile_cplus_types ()
{
  add_setshow_boolean_cmd ("compile-cplus-types", no_class,
			     &debug_compile_cplus_types, _("\
Set debugging of C++ compile type conversion."), _("\
Show debugging of C++ compile type conversion."), _("\
When enabled debugging messages are printed during C++ type conversion for\n\
the compile commands."),
			     nullptr,
			     nullptr,
			     &setdebuglist,
			     &showdebuglist);

  add_setshow_boolean_cmd ("compile-cplus-scopes", no_class,
			     &debug_compile_cplus_scopes, _("\
Set debugging of C++ compile scopes."), _("\
Show debugging of C++ compile scopes."), _("\
When enabled debugging messages are printed about definition scopes during\n\
C++ type conversion for the compile commands."),
			     nullptr,
			     nullptr,
			     &setdebuglist,
			     &showdebuglist);
}
