/* Convert types from GDB to GCC

   Copyright (C) 2014-2021 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */


#include "defs.h"
#include "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)
{
  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_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, VAR_DOMAIN, nullptr);

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

	  scope.push_back (comp);

	  if (SYMBOL_TYPE (bsymbol.symbol)->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 (__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 (SYMBOL_TYPE (comp.bsymbol.symbol)->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)
	{
	  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 (SYMBOL_TYPE (comp.bsymbol.symbol)->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)
	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 () == 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 (), 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 ())
    {
    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 ();
  gcc_type element_type = instance->convert_type (TYPE_TARGET_TYPE (type));

  if (range->bounds ()->low.kind () != PROP_CONST)
    {
      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_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 (i).type ());

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

	  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 = 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 (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).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 = 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)).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 short 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 (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)
{
  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 (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->num_fields (); ++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->has_varargs ();
  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->is_objfile_owned ())
	target_type = objfile_type (type->objfile_owner ())->builtin_int;
      else
	target_type = builtin_type (type->arch_owner ())->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 = { type->num_fields (), elements.data () };
  int artificials = 0;
  for (int i = 0; i < type->num_fields (); ++i)
    {
      if (strip_artificial && TYPE_FIELD_ARTIFICIAL (type, i))
	{
	  --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 (type) == 1);
      return instance->plugin ().get_char_type ();
    }

  return instance->plugin ().get_int_type
    (type->is_unsigned (), TYPE_LENGTH (type), 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), 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 (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)
{
  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 ();
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);
}
