/* Convert types from GDB to GCC

   Copyright (C) 2014-2024 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 "gdbsupport/preprocessor.h"
#include "gdbtypes.h"
#include "compile-internal.h"
#include "compile-cplus.h"
#include "gdbsupport/gdb_assert.h"
#include "symtab.h"
#include "source.h"
#include "cp-support.h"
#include "cp-abi.h"
#include "objfiles.h"
#include "block.h"
#include "gdbcmd.h"
#include "c-lang.h"
#include "compile-c.h"
#include <algorithm>

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

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

/* Flag to enable internal debugging.  */

static bool debug_compile_cplus_types = false;

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

static bool debug_compile_cplus_scopes = false;

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

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

  return make_unique_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)
{
  field &fld = type->field (num);
  if (fld.is_protected ())
    return GCC_CP_ACCESS_PROTECTED;
  else if (fld.is_private ())
    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_CODE_STRUCT);

  /* If this type was not declared a class, everything is public.  */
  if (!type->is_declared_class ())
    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
			    ? comp.bsymbol.symbol->natural_name ()
			    : "<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, SEARCH_VFT, nullptr);

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

	  scope.push_back (comp);

	  if (bsymbol.symbol->type ()->code () != 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 (_("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)
	{
	  gdb_printf (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 (comp.bsymbol.symbol->type ()->code ()
		      == 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)
	{
	  gdb_printf (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)
	{
	  gdb_printf (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 (comp.bsymbol.symbol->type ()->code ()
		      == 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)
	gdb_printf (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, comp.bsymbol.symbol->type ())
	  && (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 (comp.bsymbol.symbol->type ());

	  /* 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 () == 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 ()).get (),
		lookup_symbol (type->name (), block (), SEARCH_VFT, 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 ());

  enum gcc_cp_ref_qualifiers quals = GCC_CP_REF_QUAL_NONE;
  switch (type->code ())
    {
    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 ());

  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 ();
  gcc_type element_type = instance->convert_type (type->target_type ());

  if (!range->bounds ()->low.is_constant ())
    {
      const char *s = _("array type with non-constant"
			" lower bound is not supported");

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

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

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

  if (range->bounds ()->high.kind () == PROP_LOCEXPR
      || range->bounds ()->high.kind () == PROP_LOCLIST)
    {
      if (type->is_vector ())
	{
	  const char *s = _("variably-sized vector type is not supported");

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

      std::string upper_bound
	= c_get_range_decl_name (&range->bounds ()->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))
	count = -1;
      else
	{
	  gdb_assert (low_bound == 0); /* Ensured above.  */
	  count = high_bound + 1;
	}

      if (type->is_vector ())
	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);

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

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

  /* 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->num_fields (); ++i)
    {
      const char *field_name = type->field (i).name ();

      if (type->field (i).is_ignored ()
	  || type->field (i).is_artificial ())
	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 (i).type ());

      if (type->field (i).is_static ())
	{
	  CORE_ADDR physaddr;

	  switch (type->field (i).loc_kind ())
	    {
	    case FIELD_LOC_KIND_PHYSADDR:
	      {
		physaddr = type->field (i).loc_physaddr ();

		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 (i).loc_physname ();
		struct block_symbol sym
		  = lookup_symbol (physname, instance->block (),
				   SEARCH_VFT, 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 = sym.symbol->symtab ()->filename;
		unsigned int line = sym.symbol->line ();

		physaddr = sym.symbol->value_address ();
		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 (i).bitsize ();
	  enum gcc_cp_symbol_kind field_flags = GCC_CP_SYMBOL_FIELD
	    | get_field_access_flag (type, i);

	  if (bitsize == 0)
	    bitsize = 8 * type->field (i).type ()->length ();

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

/* 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 = 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.raw (), rquals.raw ());
}

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

  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 (), SEARCH_VFT, 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).raw (),
		     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 = sym.symbol->symtab ()->filename;
	  unsigned int line = sym.symbol->line ();
	  CORE_ADDR address = sym.symbol->value_block()->start ();
	  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)).raw (),
	     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 int line = 0;

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

  /* Create a new scope for TYPE.  */
  compile_scope scope = instance->new_scope (type->name (), 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_CODE_STRUCT)
    {
      const char *what = type->is_declared_class () ? "class" : "struct";

      resuld = instance->plugin ().build_decl
	(what, name.get (), (GCC_CP_SYMBOL_CLASS | nested_access
			     | (type->is_declared_class ()
				? GCC_CP_FLAG_CLASS_NOFLAG
				: GCC_CP_FLAG_CLASS_IS_STRUCT)),
	 0, nullptr, 0, filename, line);
    }
  else
    {
      gdb_assert (type->code () == 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_CODE_STRUCT)
    {
      int num_baseclasses = TYPE_N_BASECLASSES (type);
      std::vector<gcc_type> elements (num_baseclasses);
      std::vector<enum gcc_cp_symbol_kind> flags (num_baseclasses);

      struct gcc_vbase_array bases {};
      bases.elements = elements.data ();
      bases.flags = flags.data ();
      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);
    }
  else
    {
      gdb_assert (type->code () == 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 ());

  /* 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)
{
  bool scoped_enum_p = false;

  /* Create a new scope for this type.  */
  compile_scope scope = instance->new_scope (type->name (), 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 ());

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

  gcc_type int_type
    = instance->plugin ().get_int_type (type->is_unsigned (),
					type->length (), 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->num_fields (); ++i)
    {
      gdb::unique_xmalloc_ptr<char> fname
	= compile_cplus_instance::decl_name (type->field (i).name ());

      if (type->field (i).loc_kind () != FIELD_LOC_KIND_ENUMVAL
	  || fname == nullptr)
	continue;

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

  /* 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->has_varargs ();
  struct type *target_type = type->target_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)
    {
      target_type = builtin_type (type->arch ())->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);

  std::vector<gcc_type> elements (type->num_fields ());
  struct gcc_type_array array = { (int) type->num_fields (), elements.data () };
  int artificials = 0;
  for (int i = 0; i < type->num_fields (); ++i)
    {
      if (strip_artificial && type->field (i).is_artificial ())
	{
	  --array.n_elements;
	  ++artificials;
	}
      else
	{
	  array.elements[i - artificials]
	    = instance->convert_type (type->field (i).type ());
	}
    }

  /* 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);
  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->has_no_signedness ())
    {
      gdb_assert (type->length () == 1);
      return instance->plugin ().get_char_type ();
    }

  return instance->plugin ().get_int_type
    (type->is_unsigned (), type->length (), type->name ());
}

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

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

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

  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);
  gdb::unique_xmalloc_ptr<char> name
    = compile_cplus_instance::decl_name (type->name ());

  /* 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_INSTANCE_FLAG_CONST
				  | TYPE_INSTANCE_FLAG_VOLATILE
				  | TYPE_INSTANCE_FLAG_RESTRICT)) != 0)
    return compile_cplus_convert_qualified (instance, type);

  switch (type->code ())
    {
    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 ());

  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)
{
  gdb_printf (gdb_stdlog, "%s", pulongest (arg));
}

static void
compile_cplus_debug_output_1 (const char *arg)
{
  if (arg == nullptr)
    gdb_puts ("NULL", gdb_stdlog);
  else
    gdb_puts (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);
  gdb_putc (' ', 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)		  \
    {						  \
      gdb_puts (": ", gdb_stdlog);		  \
      compile_cplus_debug_output (R);		  \
      gdb_putc ('\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)
    gdb_printf (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)
    gdb_printf (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)
    gdb_printf (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)
    gdb_printf (gdb_stdlog, "<%s> ", debug_name);

  return pop_binding_level ();
}

void _initialize_compile_cplus_types ();
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);
}
