/* Support routines for manipulating internal types for GDB.

   Copyright (C) 1992-2024 Free Software Foundation, Inc.

   Contributed by Cygnus Support, using pieces from other GDB modules.

   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 "bfd.h"
#include "symtab.h"
#include "symfile.h"
#include "objfiles.h"
#include "gdbtypes.h"
#include "expression.h"
#include "language.h"
#include "target.h"
#include "value.h"
#include "demangle.h"
#include "complaints.h"
#include "gdbcmd.h"
#include "cp-abi.h"
#include "hashtab.h"
#include "cp-support.h"
#include "bcache.h"
#include "dwarf2/loc.h"
#include "dwarf2/read.h"
#include "gdbcore.h"
#include "floatformat.h"
#include "f-lang.h"
#include <algorithm>
#include "gmp-utils.h"
#include "rust-lang.h"
#include "ada-lang.h"

/* The value of an invalid conversion badness.  */
#define INVALID_CONVERSION 100

static struct dynamic_prop_list *
copy_dynamic_prop_list (struct obstack *, struct dynamic_prop_list *);

/* Initialize BADNESS constants.  */

const struct rank LENGTH_MISMATCH_BADNESS = {INVALID_CONVERSION,0};

const struct rank TOO_FEW_PARAMS_BADNESS = {INVALID_CONVERSION,0};
const struct rank INCOMPATIBLE_TYPE_BADNESS = {INVALID_CONVERSION,0};

const struct rank EXACT_MATCH_BADNESS = {0,0};

const struct rank INTEGER_PROMOTION_BADNESS = {1,0};
const struct rank FLOAT_PROMOTION_BADNESS = {1,0};
const struct rank BASE_PTR_CONVERSION_BADNESS = {1,0};
const struct rank CV_CONVERSION_BADNESS = {1, 0};
const struct rank INTEGER_CONVERSION_BADNESS = {2,0};
const struct rank FLOAT_CONVERSION_BADNESS = {2,0};
const struct rank INT_FLOAT_CONVERSION_BADNESS = {2,0};
const struct rank VOID_PTR_CONVERSION_BADNESS = {2,0};
const struct rank BOOL_CONVERSION_BADNESS = {3,0};
const struct rank BASE_CONVERSION_BADNESS = {2,0};
const struct rank REFERENCE_CONVERSION_BADNESS = {2,0};
const struct rank REFERENCE_SEE_THROUGH_BADNESS = {0,1};
const struct rank NULL_POINTER_CONVERSION_BADNESS = {2,0};
const struct rank NS_POINTER_CONVERSION_BADNESS = {10,0};
const struct rank NS_INTEGER_POINTER_CONVERSION_BADNESS = {3,0};
const struct rank VARARG_BADNESS = {4, 0};

/* Floatformat pairs.  */
const struct floatformat *floatformats_ieee_half[BFD_ENDIAN_UNKNOWN] = {
  &floatformat_ieee_half_big,
  &floatformat_ieee_half_little
};
const struct floatformat *floatformats_ieee_single[BFD_ENDIAN_UNKNOWN] = {
  &floatformat_ieee_single_big,
  &floatformat_ieee_single_little
};
const struct floatformat *floatformats_ieee_double[BFD_ENDIAN_UNKNOWN] = {
  &floatformat_ieee_double_big,
  &floatformat_ieee_double_little
};
const struct floatformat *floatformats_ieee_quad[BFD_ENDIAN_UNKNOWN] = {
  &floatformat_ieee_quad_big,
  &floatformat_ieee_quad_little
};
const struct floatformat *floatformats_ieee_double_littlebyte_bigword[BFD_ENDIAN_UNKNOWN] = {
  &floatformat_ieee_double_big,
  &floatformat_ieee_double_littlebyte_bigword
};
const struct floatformat *floatformats_i387_ext[BFD_ENDIAN_UNKNOWN] = {
  &floatformat_i387_ext,
  &floatformat_i387_ext
};
const struct floatformat *floatformats_m68881_ext[BFD_ENDIAN_UNKNOWN] = {
  &floatformat_m68881_ext,
  &floatformat_m68881_ext
};
const struct floatformat *floatformats_arm_ext[BFD_ENDIAN_UNKNOWN] = {
  &floatformat_arm_ext_big,
  &floatformat_arm_ext_littlebyte_bigword
};
const struct floatformat *floatformats_ia64_spill[BFD_ENDIAN_UNKNOWN] = {
  &floatformat_ia64_spill_big,
  &floatformat_ia64_spill_little
};
const struct floatformat *floatformats_vax_f[BFD_ENDIAN_UNKNOWN] = {
  &floatformat_vax_f,
  &floatformat_vax_f
};
const struct floatformat *floatformats_vax_d[BFD_ENDIAN_UNKNOWN] = {
  &floatformat_vax_d,
  &floatformat_vax_d
};
const struct floatformat *floatformats_ibm_long_double[BFD_ENDIAN_UNKNOWN] = {
  &floatformat_ibm_long_double_big,
  &floatformat_ibm_long_double_little
};
const struct floatformat *floatformats_bfloat16[BFD_ENDIAN_UNKNOWN] = {
  &floatformat_bfloat16_big,
  &floatformat_bfloat16_little
};

/* Should opaque types be resolved?  */

static bool opaque_type_resolution = true;

/* See gdbtypes.h.  */

unsigned int overload_debug = 0;

/* A flag to enable strict type checking.  */

static bool strict_type_checking = true;

/* A function to show whether opaque types are resolved.  */

static void
show_opaque_type_resolution (struct ui_file *file, int from_tty,
			     struct cmd_list_element *c, 
			     const char *value)
{
  gdb_printf (file, _("Resolution of opaque struct/class/union types "
		      "(if set before loading symbols) is %s.\n"),
	      value);
}

/* A function to show whether C++ overload debugging is enabled.  */

static void
show_overload_debug (struct ui_file *file, int from_tty,
		     struct cmd_list_element *c, const char *value)
{
  gdb_printf (file, _("Debugging of C++ overloading is %s.\n"), 
	      value);
}

/* A function to show the status of strict type checking.  */

static void
show_strict_type_checking (struct ui_file *file, int from_tty,
			   struct cmd_list_element *c, const char *value)
{
  gdb_printf (file, _("Strict type checking is %s.\n"), value);
}


/* Helper function to initialize a newly allocated type.  Set type code
   to CODE and initialize the type-specific fields accordingly.  */

static void
set_type_code (struct type *type, enum type_code code)
{
  type->set_code (code);

  switch (code)
    {
      case TYPE_CODE_STRUCT:
      case TYPE_CODE_UNION:
      case TYPE_CODE_NAMESPACE:
	INIT_CPLUS_SPECIFIC (type);
	break;
      case TYPE_CODE_FLT:
	TYPE_SPECIFIC_FIELD (type) = TYPE_SPECIFIC_FLOATFORMAT;
	break;
      case TYPE_CODE_FUNC:
	INIT_FUNC_SPECIFIC (type);
	break;
      case TYPE_CODE_FIXED_POINT:
	INIT_FIXED_POINT_SPECIFIC (type);
	break;
    }
}

/* See gdbtypes.h.  */

type *
type_allocator::new_type ()
{
  if (m_smash)
    return m_data.type;

  obstack *obstack = (m_is_objfile
		      ? &m_data.objfile->objfile_obstack
		      : gdbarch_obstack (m_data.gdbarch));

  /* Alloc the structure and start off with all fields zeroed.  */
  struct type *type = OBSTACK_ZALLOC (obstack, struct type);
  TYPE_MAIN_TYPE (type) = OBSTACK_ZALLOC (obstack, struct main_type);
  TYPE_MAIN_TYPE (type)->m_lang = m_lang;

  if (m_is_objfile)
    {
      OBJSTAT (m_data.objfile, n_types++);
      type->set_owner (m_data.objfile);
    }
  else
    type->set_owner (m_data.gdbarch);

  /* Initialize the fields that might not be zero.  */
  type->set_code (TYPE_CODE_UNDEF);
  TYPE_CHAIN (type) = type;	/* Chain back to itself.  */

  return type;
}

/* See gdbtypes.h.  */

type *
type_allocator::new_type (enum type_code code, int bit, const char *name)
{
  struct type *type = new_type ();
  set_type_code (type, code);
  gdb_assert ((bit % TARGET_CHAR_BIT) == 0);
  type->set_length (bit / TARGET_CHAR_BIT);

  if (name != nullptr)
    {
      obstack *obstack = (m_is_objfile
			  ? &m_data.objfile->objfile_obstack
			  : gdbarch_obstack (m_data.gdbarch));
      type->set_name (obstack_strdup (obstack, name));
    }

  return type;
}

/* See gdbtypes.h.  */

gdbarch *
type_allocator::arch ()
{
  if (m_smash)
    return m_data.type->arch ();
  if (m_is_objfile)
    return m_data.objfile->arch ();
  return m_data.gdbarch;
}

/* See gdbtypes.h.  */

gdbarch *
type::arch () const
{
  struct gdbarch *arch;

  if (this->is_objfile_owned ())
    arch = this->objfile_owner ()->arch ();
  else
    arch = this->arch_owner ();

  /* The ARCH can be NULL if TYPE is associated with neither an objfile nor
     a gdbarch, however, this is very rare, and even then, in most cases
     that type::arch is called, we assume that a non-NULL value is
     returned.  */
  gdb_assert (arch != nullptr);
  return arch;
}

/* See gdbtypes.h.  */

struct type *
get_target_type (struct type *type)
{
  if (type != NULL)
    {
      type = type->target_type ();
      if (type != NULL)
	type = check_typedef (type);
    }

  return type;
}

/* See gdbtypes.h.  */

unsigned int
type_length_units (struct type *type)
{
  int unit_size = gdbarch_addressable_memory_unit_size (type->arch ());

  return type->length () / unit_size;
}

/* Alloc a new type instance structure, fill it with some defaults,
   and point it at OLDTYPE.  Allocate the new type instance from the
   same place as OLDTYPE.  */

static struct type *
alloc_type_instance (struct type *oldtype)
{
  struct type *type;

  /* Allocate the structure.  */

  if (!oldtype->is_objfile_owned ())
    type = GDBARCH_OBSTACK_ZALLOC (oldtype->arch_owner (), struct type);
  else
    type = OBSTACK_ZALLOC (&oldtype->objfile_owner ()->objfile_obstack,
			   struct type);

  TYPE_MAIN_TYPE (type) = TYPE_MAIN_TYPE (oldtype);

  TYPE_CHAIN (type) = type;	/* Chain back to itself for now.  */

  return type;
}

/* Clear all remnants of the previous type at TYPE, in preparation for
   replacing it with something else.  Preserve owner information.  */

static void
smash_type (struct type *type)
{
  bool objfile_owned = type->is_objfile_owned ();
  objfile *objfile = type->objfile_owner ();
  gdbarch *arch = type->arch_owner ();

  memset (TYPE_MAIN_TYPE (type), 0, sizeof (struct main_type));

  /* Restore owner information.  */
  if (objfile_owned)
    type->set_owner (objfile);
  else
    type->set_owner (arch);

  /* For now, delete the rings.  */
  TYPE_CHAIN (type) = type;

  /* For now, leave the pointer/reference types alone.  */
}

/* Lookup a pointer to a type TYPE.  TYPEPTR, if nonzero, points
   to a pointer to memory where the pointer type should be stored.
   If *TYPEPTR is zero, update it to point to the pointer type we return.
   We allocate new memory if needed.  */

struct type *
make_pointer_type (struct type *type, struct type **typeptr)
{
  struct type *ntype;	/* New type */
  struct type *chain;

  ntype = TYPE_POINTER_TYPE (type);

  if (ntype)
    {
      if (typeptr == 0)
	return ntype;		/* Don't care about alloc, 
				   and have new type.  */
      else if (*typeptr == 0)
	{
	  *typeptr = ntype;	/* Tracking alloc, and have new type.  */
	  return ntype;
	}
    }

  if (typeptr == 0 || *typeptr == 0)	/* We'll need to allocate one.  */
    {
      ntype = type_allocator (type).new_type ();
      if (typeptr)
	*typeptr = ntype;
    }
  else			/* We have storage, but need to reset it.  */
    {
      ntype = *typeptr;
      chain = TYPE_CHAIN (ntype);
      smash_type (ntype);
      TYPE_CHAIN (ntype) = chain;
    }

  ntype->set_target_type (type);
  TYPE_POINTER_TYPE (type) = ntype;

  /* FIXME!  Assumes the machine has only one representation for pointers!  */

  ntype->set_length (gdbarch_ptr_bit (type->arch ()) / TARGET_CHAR_BIT);
  ntype->set_code (TYPE_CODE_PTR);

  /* Mark pointers as unsigned.  The target converts between pointers
     and addresses (CORE_ADDRs) using gdbarch_pointer_to_address and
     gdbarch_address_to_pointer.  */
  ntype->set_is_unsigned (true);

  /* Update the length of all the other variants of this type.  */
  chain = TYPE_CHAIN (ntype);
  while (chain != ntype)
    {
      chain->set_length (ntype->length ());
      chain = TYPE_CHAIN (chain);
    }

  return ntype;
}

/* Given a type TYPE, return a type of pointers to that type.
   May need to construct such a type if this is the first use.  */

struct type *
lookup_pointer_type (struct type *type)
{
  return make_pointer_type (type, (struct type **) 0);
}

/* Lookup a C++ `reference' to a type TYPE.  TYPEPTR, if nonzero,
   points to a pointer to memory where the reference type should be
   stored.  If *TYPEPTR is zero, update it to point to the reference
   type we return.  We allocate new memory if needed. REFCODE denotes
   the kind of reference type to lookup (lvalue or rvalue reference).  */

struct type *
make_reference_type (struct type *type, struct type **typeptr,
		      enum type_code refcode)
{
  struct type *ntype;	/* New type */
  struct type **reftype;
  struct type *chain;

  gdb_assert (refcode == TYPE_CODE_REF || refcode == TYPE_CODE_RVALUE_REF);

  ntype = (refcode == TYPE_CODE_REF ? TYPE_REFERENCE_TYPE (type)
	   : TYPE_RVALUE_REFERENCE_TYPE (type));

  if (ntype)
    {
      if (typeptr == 0)
	return ntype;		/* Don't care about alloc, 
				   and have new type.  */
      else if (*typeptr == 0)
	{
	  *typeptr = ntype;	/* Tracking alloc, and have new type.  */
	  return ntype;
	}
    }

  if (typeptr == 0 || *typeptr == 0)	/* We'll need to allocate one.  */
    {
      ntype = type_allocator (type).new_type ();
      if (typeptr)
	*typeptr = ntype;
    }
  else			/* We have storage, but need to reset it.  */
    {
      ntype = *typeptr;
      chain = TYPE_CHAIN (ntype);
      smash_type (ntype);
      TYPE_CHAIN (ntype) = chain;
    }

  ntype->set_target_type (type);
  reftype = (refcode == TYPE_CODE_REF ? &TYPE_REFERENCE_TYPE (type)
	     : &TYPE_RVALUE_REFERENCE_TYPE (type));

  *reftype = ntype;

  /* FIXME!  Assume the machine has only one representation for
     references, and that it matches the (only) representation for
     pointers!  */

  ntype->set_length (gdbarch_ptr_bit (type->arch ()) / TARGET_CHAR_BIT);
  ntype->set_code (refcode);

  *reftype = ntype;

  /* Update the length of all the other variants of this type.  */
  chain = TYPE_CHAIN (ntype);
  while (chain != ntype)
    {
      chain->set_length (ntype->length ());
      chain = TYPE_CHAIN (chain);
    }

  return ntype;
}

/* Same as above, but caller doesn't care about memory allocation
   details.  */

struct type *
lookup_reference_type (struct type *type, enum type_code refcode)
{
  return make_reference_type (type, (struct type **) 0, refcode);
}

/* Lookup the lvalue reference type for the type TYPE.  */

struct type *
lookup_lvalue_reference_type (struct type *type)
{
  return lookup_reference_type (type, TYPE_CODE_REF);
}

/* Lookup the rvalue reference type for the type TYPE.  */

struct type *
lookup_rvalue_reference_type (struct type *type)
{
  return lookup_reference_type (type, TYPE_CODE_RVALUE_REF);
}

/* Lookup a function type that returns type TYPE.  TYPEPTR, if
   nonzero, points to a pointer to memory where the function type
   should be stored.  If *TYPEPTR is zero, update it to point to the
   function type we return.  We allocate new memory if needed.  */

struct type *
make_function_type (struct type *type, struct type **typeptr)
{
  struct type *ntype;	/* New type */

  if (typeptr == 0 || *typeptr == 0)	/* We'll need to allocate one.  */
    {
      ntype = type_allocator (type).new_type ();
      if (typeptr)
	*typeptr = ntype;
    }
  else			/* We have storage, but need to reset it.  */
    {
      ntype = *typeptr;
      smash_type (ntype);
    }

  ntype->set_target_type (type);

  ntype->set_length (1);
  ntype->set_code (TYPE_CODE_FUNC);

  INIT_FUNC_SPECIFIC (ntype);

  return ntype;
}

/* Given a type TYPE, return a type of functions that return that type.
   May need to construct such a type if this is the first use.  */

struct type *
lookup_function_type (struct type *type)
{
  return make_function_type (type, (struct type **) 0);
}

/* Given a type TYPE and argument types, return the appropriate
   function type.  If the final type in PARAM_TYPES is NULL, make a
   varargs function.  */

struct type *
lookup_function_type_with_arguments (struct type *type,
				     int nparams,
				     struct type **param_types)
{
  struct type *fn = make_function_type (type, (struct type **) 0);
  int i;

  if (nparams > 0)
    {
      if (param_types[nparams - 1] == NULL)
	{
	  --nparams;
	  fn->set_has_varargs (true);
	}
      else if (check_typedef (param_types[nparams - 1])->code ()
	       == TYPE_CODE_VOID)
	{
	  --nparams;
	  /* Caller should have ensured this.  */
	  gdb_assert (nparams == 0);
	  fn->set_is_prototyped (true);
	}
      else
	fn->set_is_prototyped (true);
    }

  fn->alloc_fields (nparams);
  for (i = 0; i < nparams; ++i)
    fn->field (i).set_type (param_types[i]);

  return fn;
}

/* Identify address space identifier by name -- return a
   type_instance_flags.  */

type_instance_flags
address_space_name_to_type_instance_flags (struct gdbarch *gdbarch,
					   const char *space_identifier)
{
  type_instance_flags type_flags;

  /* Check for known address space delimiters.  */
  if (!strcmp (space_identifier, "code"))
    return TYPE_INSTANCE_FLAG_CODE_SPACE;
  else if (!strcmp (space_identifier, "data"))
    return TYPE_INSTANCE_FLAG_DATA_SPACE;
  else if (gdbarch_address_class_name_to_type_flags_p (gdbarch)
	   && gdbarch_address_class_name_to_type_flags (gdbarch,
							space_identifier,
							&type_flags))
    return type_flags;
  else
    error (_("Unknown address space specifier: \"%s\""), space_identifier);
}

/* Identify address space identifier by type_instance_flags and return
   the string version of the adress space name.  */

const char *
address_space_type_instance_flags_to_name (struct gdbarch *gdbarch,
					   type_instance_flags space_flag)
{
  if (space_flag & TYPE_INSTANCE_FLAG_CODE_SPACE)
    return "code";
  else if (space_flag & TYPE_INSTANCE_FLAG_DATA_SPACE)
    return "data";
  else if ((space_flag & TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL)
	   && gdbarch_address_class_type_flags_to_name_p (gdbarch))
    return gdbarch_address_class_type_flags_to_name (gdbarch, space_flag);
  else
    return NULL;
}

/* Create a new type with instance flags NEW_FLAGS, based on TYPE.

   If STORAGE is non-NULL, create the new type instance there.
   STORAGE must be in the same obstack as TYPE.  */

static struct type *
make_qualified_type (struct type *type, type_instance_flags new_flags,
		     struct type *storage)
{
  struct type *ntype;

  ntype = type;
  do
    {
      if (ntype->instance_flags () == new_flags)
	return ntype;
      ntype = TYPE_CHAIN (ntype);
    }
  while (ntype != type);

  /* Create a new type instance.  */
  if (storage == NULL)
    ntype = alloc_type_instance (type);
  else
    {
      /* If STORAGE was provided, it had better be in the same objfile
	 as TYPE.  Otherwise, we can't link it into TYPE's cv chain:
	 if one objfile is freed and the other kept, we'd have
	 dangling pointers.  */
      gdb_assert (type->objfile_owner () == storage->objfile_owner ());

      ntype = storage;
      TYPE_MAIN_TYPE (ntype) = TYPE_MAIN_TYPE (type);
      TYPE_CHAIN (ntype) = ntype;
    }

  /* Pointers or references to the original type are not relevant to
     the new type.  */
  TYPE_POINTER_TYPE (ntype) = (struct type *) 0;
  TYPE_REFERENCE_TYPE (ntype) = (struct type *) 0;

  /* Chain the new qualified type to the old type.  */
  TYPE_CHAIN (ntype) = TYPE_CHAIN (type);
  TYPE_CHAIN (type) = ntype;

  /* Now set the instance flags and return the new type.  */
  ntype->set_instance_flags (new_flags);

  /* Set length of new type to that of the original type.  */
  ntype->set_length (type->length ());

  return ntype;
}

/* Make an address-space-delimited variant of a type -- a type that
   is identical to the one supplied except that it has an address
   space attribute attached to it (such as "code" or "data").

   The space attributes "code" and "data" are for Harvard
   architectures.  The address space attributes are for architectures
   which have alternately sized pointers or pointers with alternate
   representations.  */

struct type *
make_type_with_address_space (struct type *type,
			      type_instance_flags space_flag)
{
  type_instance_flags new_flags = ((type->instance_flags ()
				    & ~(TYPE_INSTANCE_FLAG_CODE_SPACE
					| TYPE_INSTANCE_FLAG_DATA_SPACE
					| TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL))
				   | space_flag);

  return make_qualified_type (type, new_flags, NULL);
}

/* Make a "c-v" variant of a type -- a type that is identical to the
   one supplied except that it may have const or volatile attributes
   CNST is a flag for setting the const attribute
   VOLTL is a flag for setting the volatile attribute
   TYPE is the base type whose variant we are creating.

   If TYPEPTR and *TYPEPTR are non-zero, then *TYPEPTR points to
   storage to hold the new qualified type; *TYPEPTR and TYPE must be
   in the same objfile.  Otherwise, allocate fresh memory for the new
   type whereever TYPE lives.  If TYPEPTR is non-zero, set it to the
   new type we construct.  */

struct type *
make_cv_type (int cnst, int voltl, 
	      struct type *type, 
	      struct type **typeptr)
{
  struct type *ntype;	/* New type */

  type_instance_flags new_flags = (type->instance_flags ()
				   & ~(TYPE_INSTANCE_FLAG_CONST
				       | TYPE_INSTANCE_FLAG_VOLATILE));

  if (cnst)
    new_flags |= TYPE_INSTANCE_FLAG_CONST;

  if (voltl)
    new_flags |= TYPE_INSTANCE_FLAG_VOLATILE;

  if (typeptr && *typeptr != NULL)
    {
      /* TYPE and *TYPEPTR must be in the same objfile.  We can't have
	 a C-V variant chain that threads across objfiles: if one
	 objfile gets freed, then the other has a broken C-V chain.

	 This code used to try to copy over the main type from TYPE to
	 *TYPEPTR if they were in different objfiles, but that's
	 wrong, too: TYPE may have a field list or member function
	 lists, which refer to types of their own, etc. etc.  The
	 whole shebang would need to be copied over recursively; you
	 can't have inter-objfile pointers.  The only thing to do is
	 to leave stub types as stub types, and look them up afresh by
	 name each time you encounter them.  */
      gdb_assert ((*typeptr)->objfile_owner () == type->objfile_owner ());
    }
  
  ntype = make_qualified_type (type, new_flags, 
			       typeptr ? *typeptr : NULL);

  if (typeptr != NULL)
    *typeptr = ntype;

  return ntype;
}

/* Make a 'restrict'-qualified version of TYPE.  */

struct type *
make_restrict_type (struct type *type)
{
  return make_qualified_type (type,
			      (type->instance_flags ()
			       | TYPE_INSTANCE_FLAG_RESTRICT),
			      NULL);
}

/* Make a type without const, volatile, or restrict.  */

struct type *
make_unqualified_type (struct type *type)
{
  return make_qualified_type (type,
			      (type->instance_flags ()
			       & ~(TYPE_INSTANCE_FLAG_CONST
				   | TYPE_INSTANCE_FLAG_VOLATILE
				   | TYPE_INSTANCE_FLAG_RESTRICT)),
			      NULL);
}

/* Make a '_Atomic'-qualified version of TYPE.  */

struct type *
make_atomic_type (struct type *type)
{
  return make_qualified_type (type,
			      (type->instance_flags ()
			       | TYPE_INSTANCE_FLAG_ATOMIC),
			      NULL);
}

/* Replace the contents of ntype with the type *type.  This changes the
   contents, rather than the pointer for TYPE_MAIN_TYPE (ntype); thus
   the changes are propogated to all types in the TYPE_CHAIN.

   In order to build recursive types, it's inevitable that we'll need
   to update types in place --- but this sort of indiscriminate
   smashing is ugly, and needs to be replaced with something more
   controlled.  TYPE_MAIN_TYPE is a step in this direction; it's not
   clear if more steps are needed.  */

void
replace_type (struct type *ntype, struct type *type)
{
  struct type *chain;

  /* These two types had better be in the same objfile.  Otherwise,
     the assignment of one type's main type structure to the other
     will produce a type with references to objects (names; field
     lists; etc.) allocated on an objfile other than its own.  */
  gdb_assert (ntype->objfile_owner () == type->objfile_owner ());

  *TYPE_MAIN_TYPE (ntype) = *TYPE_MAIN_TYPE (type);

  /* The type length is not a part of the main type.  Update it for
     each type on the variant chain.  */
  chain = ntype;
  do
    {
      /* Assert that this element of the chain has no address-class bits
	 set in its flags.  Such type variants might have type lengths
	 which are supposed to be different from the non-address-class
	 variants.  This assertion shouldn't ever be triggered because
	 symbol readers which do construct address-class variants don't
	 call replace_type().  */
      gdb_assert (TYPE_ADDRESS_CLASS_ALL (chain) == 0);

      chain->set_length (type->length ());
      chain = TYPE_CHAIN (chain);
    }
  while (ntype != chain);

  /* Assert that the two types have equivalent instance qualifiers.
     This should be true for at least all of our debug readers.  */
  gdb_assert (ntype->instance_flags () == type->instance_flags ());
}

/* Implement direct support for MEMBER_TYPE in GNU C++.
   May need to construct such a type if this is the first use.
   The TYPE is the type of the member.  The DOMAIN is the type
   of the aggregate that the member belongs to.  */

struct type *
lookup_memberptr_type (struct type *type, struct type *domain)
{
  struct type *mtype;

  mtype = type_allocator (type).new_type ();
  smash_to_memberptr_type (mtype, domain, type);
  return mtype;
}

/* Return a pointer-to-method type, for a method of type TO_TYPE.  */

struct type *
lookup_methodptr_type (struct type *to_type)
{
  struct type *mtype;

  mtype = type_allocator (to_type).new_type ();
  smash_to_methodptr_type (mtype, to_type);
  return mtype;
}

/* See gdbtypes.h.  */

bool
operator== (const dynamic_prop &l, const dynamic_prop &r)
{
  if (l.kind () != r.kind ())
    return false;

  switch (l.kind ())
    {
    case PROP_UNDEFINED:
      return true;
    case PROP_CONST:
      return l.const_val () == r.const_val ();
    case PROP_ADDR_OFFSET:
    case PROP_LOCEXPR:
    case PROP_LOCLIST:
      return l.baton () == r.baton ();
    case PROP_VARIANT_PARTS:
      return l.variant_parts () == r.variant_parts ();
    case PROP_TYPE:
      return l.original_type () == r.original_type ();
    }

  gdb_assert_not_reached ("unhandled dynamic_prop kind");
}

/* See gdbtypes.h.  */

bool
operator== (const range_bounds &l, const range_bounds &r)
{
#define FIELD_EQ(FIELD) (l.FIELD == r.FIELD)

  return (FIELD_EQ (low)
	  && FIELD_EQ (high)
	  && FIELD_EQ (flag_upper_bound_is_count)
	  && FIELD_EQ (flag_bound_evaluated)
	  && FIELD_EQ (bias));

#undef FIELD_EQ
}

/* See gdbtypes.h.  */

struct type *
create_range_type (type_allocator &alloc, struct type *index_type,
		   const struct dynamic_prop *low_bound,
		   const struct dynamic_prop *high_bound,
		   LONGEST bias)
{
  /* The INDEX_TYPE should be a type capable of holding the upper and lower
     bounds, as such a zero sized, or void type makes no sense.  */
  gdb_assert (index_type->code () != TYPE_CODE_VOID);
  gdb_assert (index_type->length () > 0);

  struct type *result_type = alloc.new_type ();
  result_type->set_code (TYPE_CODE_RANGE);
  result_type->set_target_type (index_type);
  if (index_type->is_stub ())
    result_type->set_target_is_stub (true);
  else
    result_type->set_length (check_typedef (index_type)->length ());

  range_bounds *bounds
    = (struct range_bounds *) TYPE_ZALLOC (result_type, sizeof (range_bounds));
  bounds->low = *low_bound;
  bounds->high = *high_bound;
  bounds->bias = bias;
  bounds->stride.set_const_val (0);

  result_type->set_bounds (bounds);

  if (index_type->code () == TYPE_CODE_FIXED_POINT)
    result_type->set_is_unsigned (index_type->is_unsigned ());
  else if (index_type->is_unsigned ())
    {
      /* If the underlying type is unsigned, then the range
	 necessarily is.  */
      result_type->set_is_unsigned (true);
    }
  /* Otherwise, the signed-ness of a range type can't simply be copied
     from the underlying type.  Consider a case where the underlying
     type is 'int', but the range type can hold 0..65535, and where
     the range is further specified to fit into 16 bits.  In this
     case, if we copy the underlying type's sign, then reading some
     range values will cause an unwanted sign extension.  So, we have
     some heuristics here instead.  */
  else if (low_bound->is_constant () && low_bound->const_val () >= 0)
    {
      result_type->set_is_unsigned (true);
      /* Ada allows the declaration of range types whose upper bound is
	 less than the lower bound, so checking the lower bound is not
	 enough.  Make sure we do not mark a range type whose upper bound
	 is negative as unsigned.  */
      if (high_bound->is_constant () && high_bound->const_val () < 0)
	result_type->set_is_unsigned (false);
    }

  result_type->set_endianity_is_not_default
    (index_type->endianity_is_not_default ());

  return result_type;
}

/* See gdbtypes.h.  */

struct type *
create_range_type_with_stride (type_allocator &alloc,
			       struct type *index_type,
			       const struct dynamic_prop *low_bound,
			       const struct dynamic_prop *high_bound,
			       LONGEST bias,
			       const struct dynamic_prop *stride,
			       bool byte_stride_p)
{
  struct type *result_type = create_range_type (alloc, index_type, low_bound,
						high_bound, bias);

  gdb_assert (stride != nullptr);
  result_type->bounds ()->stride = *stride;
  result_type->bounds ()->flag_is_byte_stride = byte_stride_p;

  return result_type;
}

/* See gdbtypes.h.  */

struct type *
create_static_range_type (type_allocator &alloc, struct type *index_type,
			  LONGEST low_bound, LONGEST high_bound)
{
  struct dynamic_prop low, high;

  low.set_const_val (low_bound);
  high.set_const_val (high_bound);

  struct type *result_type = create_range_type (alloc, index_type,
						&low, &high, 0);

  return result_type;
}

/* Predicate tests whether BOUNDS are static.  Returns 1 if all bounds values
   are static, otherwise returns 0.  */

static bool
has_static_range (const struct range_bounds *bounds)
{
  /* If the range doesn't have a defined stride then its stride field will
     be initialized to the constant 0.  */
  return (bounds->low.is_constant ()
	  && bounds->high.is_constant ()
	  && bounds->stride.is_constant ());
}

/* See gdbtypes.h.  */

std::optional<LONGEST>
get_discrete_low_bound (struct type *type)
{
  type = check_typedef (type);
  switch (type->code ())
    {
    case TYPE_CODE_RANGE:
      {
	/* This function only works for ranges with a constant low bound.  */
	if (!type->bounds ()->low.is_constant ())
	  return {};

	LONGEST low = type->bounds ()->low.const_val ();

	if (type->target_type ()->code () == TYPE_CODE_ENUM)
	  {
	    std::optional<LONGEST> low_pos
	      = discrete_position (type->target_type (), low);

	    if (low_pos.has_value ())
	      low = *low_pos;
	  }

	return low;
      }

    case TYPE_CODE_ENUM:
      {
	if (type->num_fields () > 0)
	  {
	    /* The enums may not be sorted by value, so search all
	       entries.  */
	    LONGEST low = type->field (0).loc_enumval ();

	    for (int i = 0; i < type->num_fields (); i++)
	      {
		if (type->field (i).loc_enumval () < low)
		  low = type->field (i).loc_enumval ();
	      }

	    return low;
	  }
	else
	  return 0;
      }

    case TYPE_CODE_BOOL:
      return 0;

    case TYPE_CODE_INT:
      if (type->length () > sizeof (LONGEST))	/* Too big */
	return {};

      if (!type->is_unsigned ())
	return -(1 << (type->length () * TARGET_CHAR_BIT - 1));

      [[fallthrough]];
    case TYPE_CODE_CHAR:
      return 0;

    default:
      return {};
    }
}

/* See gdbtypes.h.  */

std::optional<LONGEST>
get_discrete_high_bound (struct type *type)
{
  type = check_typedef (type);
  switch (type->code ())
    {
    case TYPE_CODE_RANGE:
      {
	/* This function only works for ranges with a constant high bound.  */
	if (!type->bounds ()->high.is_constant ())
	  return {};

	LONGEST high = type->bounds ()->high.const_val ();

	if (type->target_type ()->code () == TYPE_CODE_ENUM)
	  {
	    std::optional<LONGEST> high_pos
	      = discrete_position (type->target_type (), high);

	    if (high_pos.has_value ())
	      high = *high_pos;
	  }

	return high;
      }

    case TYPE_CODE_ENUM:
      {
	if (type->num_fields () > 0)
	  {
	    /* The enums may not be sorted by value, so search all
	       entries.  */
	    LONGEST high = type->field (0).loc_enumval ();

	    for (int i = 0; i < type->num_fields (); i++)
	      {
		if (type->field (i).loc_enumval () > high)
		  high = type->field (i).loc_enumval ();
	      }

	    return high;
	  }
	else
	  return -1;
      }

    case TYPE_CODE_BOOL:
      return 1;

    case TYPE_CODE_INT:
      if (type->length () > sizeof (LONGEST))	/* Too big */
	return {};

      if (!type->is_unsigned ())
	{
	  LONGEST low = -(1 << (type->length () * TARGET_CHAR_BIT - 1));
	  return -low - 1;
	}

      [[fallthrough]];
    case TYPE_CODE_CHAR:
      {
	/* This round-about calculation is to avoid shifting by
	   type->length () * TARGET_CHAR_BIT, which will not work
	   if type->length () == sizeof (LONGEST).  */
	LONGEST high = 1 << (type->length () * TARGET_CHAR_BIT - 1);
	return (high - 1) | high;
      }

    default:
      return {};
    }
}

/* See gdbtypes.h.  */

bool
get_discrete_bounds (struct type *type, LONGEST *lowp, LONGEST *highp)
{
  std::optional<LONGEST> low = get_discrete_low_bound (type);
  if (!low.has_value ())
    return false;

  std::optional<LONGEST> high = get_discrete_high_bound (type);
  if (!high.has_value ())
    return false;

  *lowp = *low;
  *highp = *high;

  return true;
}

/* See gdbtypes.h  */

bool
get_array_bounds (struct type *type, LONGEST *low_bound, LONGEST *high_bound)
{
  struct type *index = type->index_type ();
  LONGEST low = 0;
  LONGEST high = 0;

  if (index == NULL)
    return false;

  if (!get_discrete_bounds (index, &low, &high))
    return false;

  if (low_bound)
    *low_bound = low;

  if (high_bound)
    *high_bound = high;

  return true;
}

/* Assuming that TYPE is a discrete type and VAL is a valid integer
   representation of a value of this type, save the corresponding
   position number in POS.

   Its differs from VAL only in the case of enumeration types.  In
   this case, the position number of the value of the first listed
   enumeration literal is zero; the position number of the value of
   each subsequent enumeration literal is one more than that of its
   predecessor in the list.

   Return 1 if the operation was successful.  Return zero otherwise,
   in which case the value of POS is unmodified.
*/

std::optional<LONGEST>
discrete_position (struct type *type, LONGEST val)
{
  if (type->code () == TYPE_CODE_RANGE)
    type = type->target_type ();

  if (type->code () == TYPE_CODE_ENUM)
    {
      int i;

      for (i = 0; i < type->num_fields (); i += 1)
	{
	  if (val == type->field (i).loc_enumval ())
	    return i;
	}

      /* Invalid enumeration value.  */
      return {};
    }
  else
    return val;
}

/* If the array TYPE has static bounds calculate and update its
   size, then return true.  Otherwise return false and leave TYPE
   unchanged.  */

static bool
update_static_array_size (struct type *type)
{
  gdb_assert (type->code () == TYPE_CODE_ARRAY);

  struct type *range_type = type->index_type ();

  if (type->dyn_prop (DYN_PROP_BYTE_STRIDE) == nullptr
      && has_static_range (range_type->bounds ())
      && (!type_not_associated (type)
	  && !type_not_allocated (type)))
    {
      LONGEST low_bound, high_bound;
      int stride;
      struct type *element_type;

      stride = type->bit_stride ();

      if (!get_discrete_bounds (range_type, &low_bound, &high_bound))
	low_bound = high_bound = 0;

      element_type = check_typedef (type->target_type ());
      /* Be careful when setting the array length.  Ada arrays can be
	 empty arrays with the high_bound being smaller than the low_bound.
	 In such cases, the array length should be zero.  */
      if (high_bound < low_bound)
	type->set_length (0);
      else if (stride != 0)
	{
	  /* Ensure that the type length is always positive, even in the
	     case where (for example in Fortran) we have a negative
	     stride.  It is possible to have a single element array with a
	     negative stride in Fortran (this doesn't mean anything
	     special, it's still just a single element array) so do
	     consider that case when touching this code.  */
	  LONGEST element_count = std::abs (high_bound - low_bound + 1);
	  type->set_length (((std::abs (stride) * element_count) + 7) / 8);
	}
      else
	type->set_length (element_type->length ()
			  * (high_bound - low_bound + 1));

      /* If this array's element is itself an array with a bit stride,
	 then we want to update this array's bit stride to reflect the
	 size of the sub-array.  Otherwise, we'll end up using the
	 wrong size when trying to find elements of the outer
	 array.  */
      if (element_type->code () == TYPE_CODE_ARRAY
	  && (stride != 0 || element_type->is_multi_dimensional ())
	  && element_type->length () != 0
	  && element_type->field (0).bitsize () != 0
	  && get_array_bounds (element_type, &low_bound, &high_bound)
	  && high_bound >= low_bound)
	type->field (0).set_bitsize
	  ((high_bound - low_bound + 1)
	   * element_type->field (0).bitsize ());

      return true;
    }

  return false;
}

/* See gdbtypes.h.  */

struct type *
create_array_type_with_stride (type_allocator &alloc,
			       struct type *element_type,
			       struct type *range_type,
			       struct dynamic_prop *byte_stride_prop,
			       unsigned int bit_stride)
{
  if (byte_stride_prop != nullptr && byte_stride_prop->is_constant ())
    {
      /* The byte stride is actually not dynamic.  Pretend we were
	 called with bit_stride set instead of byte_stride_prop.
	 This will give us the same result type, while avoiding
	 the need to handle this as a special case.  */
      bit_stride = byte_stride_prop->const_val () * 8;
      byte_stride_prop = NULL;
    }

  struct type *result_type = alloc.new_type ();

  result_type->set_code (TYPE_CODE_ARRAY);
  result_type->set_target_type (element_type);

  result_type->alloc_fields (1);
  result_type->set_index_type (range_type);
  if (byte_stride_prop != NULL)
    result_type->add_dyn_prop (DYN_PROP_BYTE_STRIDE, *byte_stride_prop);
  else if (bit_stride > 0)
    result_type->field (0).set_bitsize (bit_stride);

  if (!update_static_array_size (result_type))
    {
      /* This type is dynamic and its length needs to be computed
	 on demand.  In the meantime, avoid leaving the TYPE_LENGTH
	 undefined by setting it to zero.  Although we are not expected
	 to trust TYPE_LENGTH in this case, setting the size to zero
	 allows us to avoid allocating objects of random sizes in case
	 we accidently do.  */
      result_type->set_length (0);
    }

  /* TYPE_TARGET_STUB will take care of zero length arrays.  */
  if (result_type->length () == 0)
    result_type->set_target_is_stub (true);

  return result_type;
}

/* See gdbtypes.h.  */

struct type *
create_array_type (type_allocator &alloc,
		   struct type *element_type,
		   struct type *range_type)
{
  return create_array_type_with_stride (alloc, element_type,
					range_type, NULL, 0);
}

struct type *
lookup_array_range_type (struct type *element_type,
			 LONGEST low_bound, LONGEST high_bound)
{
  struct type *index_type;
  struct type *range_type;

  type_allocator alloc (element_type);
  index_type = builtin_type (element_type->arch ())->builtin_int;

  range_type = create_static_range_type (alloc, index_type,
					 low_bound, high_bound);

  return create_array_type (alloc, element_type, range_type);
}

/* See gdbtypes.h.  */

struct type *
create_string_type (type_allocator &alloc,
		    struct type *string_char_type,
		    struct type *range_type)
{
  struct type *result_type = create_array_type (alloc,
						string_char_type,
						range_type);
  result_type->set_code (TYPE_CODE_STRING);
  return result_type;
}

struct type *
lookup_string_range_type (struct type *string_char_type,
			  LONGEST low_bound, LONGEST high_bound)
{
  struct type *result_type;

  result_type = lookup_array_range_type (string_char_type,
					 low_bound, high_bound);
  result_type->set_code (TYPE_CODE_STRING);
  return result_type;
}

struct type *
create_set_type (type_allocator &alloc, struct type *domain_type)
{
  struct type *result_type = alloc.new_type ();

  result_type->set_code (TYPE_CODE_SET);
  result_type->alloc_fields (1);

  if (!domain_type->is_stub ())
    {
      LONGEST low_bound, high_bound, bit_length;

      if (!get_discrete_bounds (domain_type, &low_bound, &high_bound))
	low_bound = high_bound = 0;

      bit_length = high_bound - low_bound + 1;
      result_type->set_length ((bit_length + TARGET_CHAR_BIT - 1)
			       / TARGET_CHAR_BIT);
      if (low_bound >= 0)
	result_type->set_is_unsigned (true);
    }
  result_type->field (0).set_type (domain_type);

  return result_type;
}

/* Convert ARRAY_TYPE to a vector type.  This may modify ARRAY_TYPE
   and any array types nested inside it.  */

void
make_vector_type (struct type *array_type)
{
  struct type *inner_array, *elt_type;

  /* Find the innermost array type, in case the array is
     multi-dimensional.  */
  inner_array = array_type;
  while (inner_array->target_type ()->code () == TYPE_CODE_ARRAY)
    inner_array = inner_array->target_type ();

  elt_type = inner_array->target_type ();
  if (elt_type->code () == TYPE_CODE_INT)
    {
      type_instance_flags flags
	= elt_type->instance_flags () | TYPE_INSTANCE_FLAG_NOTTEXT;
      elt_type = make_qualified_type (elt_type, flags, NULL);
      inner_array->set_target_type (elt_type);
    }

  array_type->set_is_vector (true);
}

struct type *
init_vector_type (struct type *elt_type, int n)
{
  struct type *array_type;

  array_type = lookup_array_range_type (elt_type, 0, n - 1);
  make_vector_type (array_type);
  return array_type;
}

/* Internal routine called by TYPE_SELF_TYPE to return the type that TYPE
   belongs to.  In c++ this is the class of "this", but TYPE_THIS_TYPE is too
   confusing.  "self" is a common enough replacement for "this".
   TYPE must be one of TYPE_CODE_METHODPTR, TYPE_CODE_MEMBERPTR, or
   TYPE_CODE_METHOD.  */

struct type *
internal_type_self_type (struct type *type)
{
  switch (type->code ())
    {
    case TYPE_CODE_METHODPTR:
    case TYPE_CODE_MEMBERPTR:
      if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NONE)
	return NULL;
      gdb_assert (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_SELF_TYPE);
      return TYPE_MAIN_TYPE (type)->type_specific.self_type;
    case TYPE_CODE_METHOD:
      if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NONE)
	return NULL;
      gdb_assert (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_FUNC);
      return TYPE_MAIN_TYPE (type)->type_specific.func_stuff->self_type;
    default:
      gdb_assert_not_reached ("bad type");
    }
}

/* Set the type of the class that TYPE belongs to.
   In c++ this is the class of "this".
   TYPE must be one of TYPE_CODE_METHODPTR, TYPE_CODE_MEMBERPTR, or
   TYPE_CODE_METHOD.  */

void
set_type_self_type (struct type *type, struct type *self_type)
{
  switch (type->code ())
    {
    case TYPE_CODE_METHODPTR:
    case TYPE_CODE_MEMBERPTR:
      if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NONE)
	TYPE_SPECIFIC_FIELD (type) = TYPE_SPECIFIC_SELF_TYPE;
      gdb_assert (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_SELF_TYPE);
      TYPE_MAIN_TYPE (type)->type_specific.self_type = self_type;
      break;
    case TYPE_CODE_METHOD:
      if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NONE)
	INIT_FUNC_SPECIFIC (type);
      gdb_assert (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_FUNC);
      TYPE_MAIN_TYPE (type)->type_specific.func_stuff->self_type = self_type;
      break;
    default:
      gdb_assert_not_reached ("bad type");
    }
}

/* Smash TYPE to be a type of pointers to members of SELF_TYPE with type
   TO_TYPE.  A member pointer is a wierd thing -- it amounts to a
   typed offset into a struct, e.g. "an int at offset 8".  A MEMBER
   TYPE doesn't include the offset (that's the value of the MEMBER
   itself), but does include the structure type into which it points
   (for some reason).

   When "smashing" the type, we preserve the objfile that the old type
   pointed to, since we aren't changing where the type is actually
   allocated.  */

void
smash_to_memberptr_type (struct type *type, struct type *self_type,
			 struct type *to_type)
{
  smash_type (type);
  type->set_code (TYPE_CODE_MEMBERPTR);
  type->set_target_type (to_type);
  set_type_self_type (type, self_type);
  /* Assume that a data member pointer is the same size as a normal
     pointer.  */
  type->set_length (gdbarch_ptr_bit (to_type->arch ()) / TARGET_CHAR_BIT);
}

/* Smash TYPE to be a type of pointer to methods type TO_TYPE.

   When "smashing" the type, we preserve the objfile that the old type
   pointed to, since we aren't changing where the type is actually
   allocated.  */

void
smash_to_methodptr_type (struct type *type, struct type *to_type)
{
  smash_type (type);
  type->set_code (TYPE_CODE_METHODPTR);
  type->set_target_type (to_type);
  set_type_self_type (type, TYPE_SELF_TYPE (to_type));
  type->set_length (cplus_method_ptr_size (to_type));
}

/* Smash TYPE to be a type of method of SELF_TYPE with type TO_TYPE.
   METHOD just means `function that gets an extra "this" argument'.

   When "smashing" the type, we preserve the objfile that the old type
   pointed to, since we aren't changing where the type is actually
   allocated.  */

void
smash_to_method_type (struct type *type, struct type *self_type,
		      struct type *to_type, struct field *args,
		      int nargs, int varargs)
{
  smash_type (type);
  type->set_code (TYPE_CODE_METHOD);
  type->set_target_type (to_type);
  set_type_self_type (type, self_type);
  type->set_fields (args);
  type->set_num_fields (nargs);

  if (varargs)
    type->set_has_varargs (true);

  /* In practice, this is never needed.  */
  type->set_length (1);
}

/* A wrapper of TYPE_NAME which calls error if the type is anonymous.
   Since GCC PR debug/47510 DWARF provides associated information to detect the
   anonymous class linkage name from its typedef.

   Parameter TYPE should not yet have CHECK_TYPEDEF applied, this function will
   apply it itself.  */

const char *
type_name_or_error (struct type *type)
{
  struct type *saved_type = type;
  const char *name;
  struct objfile *objfile;

  type = check_typedef (type);

  name = type->name ();
  if (name != NULL)
    return name;

  name = saved_type->name ();
  objfile = saved_type->objfile_owner ();
  error (_("Invalid anonymous type %s [in module %s], GCC PR debug/47510 bug?"),
	 name ? name : "<anonymous>",
	 objfile ? objfile_name (objfile) : "<arch>");
}

/* See gdbtypes.h.  */

struct type *
lookup_typename (const struct language_defn *language,
		 const char *name,
		 const struct block *block, int noerr)
{
  struct symbol *sym;

  sym = lookup_symbol_in_language (name, block, SEARCH_TYPE_DOMAIN,
				   language->la_language, NULL).symbol;
  if (sym != nullptr)
    {
      struct type *type = sym->type ();
      /* Ensure the length of TYPE is valid.  */
      check_typedef (type);
      return type;
    }

  if (noerr)
    return NULL;
  error (_("No type named %s."), name);
}

struct type *
lookup_unsigned_typename (const struct language_defn *language,
			  const char *name)
{
  std::string uns;
  uns.reserve (strlen (name) + strlen ("unsigned "));
  uns = "unsigned ";
  uns += name;

  return lookup_typename (language, uns.c_str (), NULL, 0);
}

struct type *
lookup_signed_typename (const struct language_defn *language, const char *name)
{
  /* In C and C++, "char" and "signed char" are distinct types.  */
  if (streq (name, "char"))
    name = "signed char";
  return lookup_typename (language, name, NULL, 0);
}

/* Lookup a structure type named "struct NAME",
   visible in lexical block BLOCK.  */

struct type *
lookup_struct (const char *name, const struct block *block)
{
  struct symbol *sym;

  sym = lookup_symbol (name, block, SEARCH_STRUCT_DOMAIN, 0).symbol;

  if (sym == NULL)
    {
      error (_("No struct type named %s."), name);
    }
  if (sym->type ()->code () != TYPE_CODE_STRUCT)
    {
      error (_("This context has class, union or enum %s, not a struct."),
	     name);
    }
  return (sym->type ());
}

/* Lookup a union type named "union NAME",
   visible in lexical block BLOCK.  */

struct type *
lookup_union (const char *name, const struct block *block)
{
  struct symbol *sym;
  struct type *t;

  sym = lookup_symbol (name, block, SEARCH_STRUCT_DOMAIN, 0).symbol;

  if (sym == NULL)
    error (_("No union type named %s."), name);

  t = sym->type ();

  if (t->code () == TYPE_CODE_UNION)
    return t;

  /* If we get here, it's not a union.  */
  error (_("This context has class, struct or enum %s, not a union."), 
	 name);
}

/* Lookup an enum type named "enum NAME",
   visible in lexical block BLOCK.  */

struct type *
lookup_enum (const char *name, const struct block *block)
{
  struct symbol *sym;

  sym = lookup_symbol (name, block, SEARCH_STRUCT_DOMAIN, 0).symbol;
  if (sym == NULL)
    {
      error (_("No enum type named %s."), name);
    }
  if (sym->type ()->code () != TYPE_CODE_ENUM)
    {
      error (_("This context has class, struct or union %s, not an enum."), 
	     name);
    }
  return (sym->type ());
}

/* Lookup a template type named "template NAME<TYPE>",
   visible in lexical block BLOCK.  */

struct type *
lookup_template_type (const char *name, struct type *type, 
		      const struct block *block)
{
  std::string nam;
  nam.reserve (strlen (name) + strlen (type->name ()) + strlen ("< >"));
  nam = name;
  nam += "<";
  nam += type->name ();
  nam += " >"; /* FIXME, extra space still introduced in gcc?  */

  symbol *sym = lookup_symbol (nam.c_str (), block,
			       SEARCH_STRUCT_DOMAIN, 0).symbol;

  if (sym == NULL)
    {
      error (_("No template type named %s."), name);
    }
  if (sym->type ()->code () != TYPE_CODE_STRUCT)
    {
      error (_("This context has class, union or enum %s, not a struct."),
	     name);
    }
  return (sym->type ());
}

/* See gdbtypes.h.  */

struct_elt
lookup_struct_elt (struct type *type, const char *name, int noerr)
{
  int i;

  for (;;)
    {
      type = check_typedef (type);
      if (type->code () != TYPE_CODE_PTR
	  && type->code () != TYPE_CODE_REF)
	break;
      type = type->target_type ();
    }

  if (type->code () != TYPE_CODE_STRUCT
      && type->code () != TYPE_CODE_UNION)
    {
      std::string type_name = type_to_string (type);
      error (_("Type %s is not a structure or union type."),
	     type_name.c_str ());
    }

  for (i = type->num_fields () - 1; i >= TYPE_N_BASECLASSES (type); i--)
    {
      const char *t_field_name = type->field (i).name ();

      if (t_field_name && (strcmp_iw (t_field_name, name) == 0))
	{
	  return {&type->field (i), type->field (i).loc_bitpos ()};
	}
      else if (!t_field_name || *t_field_name == '\0')
	{
	  struct_elt elt
	    = lookup_struct_elt (type->field (i).type (), name, 1);
	  if (elt.field != NULL)
	    {
	      elt.offset += type->field (i).loc_bitpos ();
	      return elt;
	    }
	}
    }

  /* OK, it's not in this class.  Recursively check the baseclasses.  */
  for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
    {
      struct_elt elt = lookup_struct_elt (TYPE_BASECLASS (type, i), name, 1);
      if (elt.field != NULL)
	return elt;
    }

  if (noerr)
    return {nullptr, 0};

  std::string type_name = type_to_string (type);
  error (_("Type %s has no component named %s."), type_name.c_str (), name);
}

/* See gdbtypes.h.  */

struct type *
lookup_struct_elt_type (struct type *type, const char *name, int noerr)
{
  struct_elt elt = lookup_struct_elt (type, name, noerr);
  if (elt.field != NULL)
    return elt.field->type ();
  else
    return NULL;
}

/* Return the largest number representable by unsigned integer type TYPE.  */

ULONGEST
get_unsigned_type_max (struct type *type)
{
  unsigned int n;

  type = check_typedef (type);
  gdb_assert (type->code () == TYPE_CODE_INT && type->is_unsigned ());
  gdb_assert (type->length () <= sizeof (ULONGEST));

  /* Written this way to avoid overflow.  */
  n = type->length () * TARGET_CHAR_BIT;
  return ((((ULONGEST) 1 << (n - 1)) - 1) << 1) | 1;
}

/* Store in *MIN, *MAX the smallest and largest numbers representable by
   signed integer type TYPE.  */

void
get_signed_type_minmax (struct type *type, LONGEST *min, LONGEST *max)
{
  unsigned int n;

  type = check_typedef (type);
  gdb_assert (type->code () == TYPE_CODE_INT && !type->is_unsigned ());
  gdb_assert (type->length () <= sizeof (LONGEST));

  n = type->length () * TARGET_CHAR_BIT;
  *min = -((ULONGEST) 1 << (n - 1));
  *max = ((ULONGEST) 1 << (n - 1)) - 1;
}

/* Return the largest value representable by pointer type TYPE. */

CORE_ADDR
get_pointer_type_max (struct type *type)
{
  unsigned int n;

  type = check_typedef (type);
  gdb_assert (type->code () == TYPE_CODE_PTR);
  gdb_assert (type->length () <= sizeof (CORE_ADDR));

  n = type->length () * TARGET_CHAR_BIT;
  return ((((CORE_ADDR) 1 << (n - 1)) - 1) << 1) | 1;
}

/* Internal routine called by TYPE_VPTR_FIELDNO to return the value of
   cplus_stuff.vptr_fieldno.

   cplus_stuff is initialized to cplus_struct_default which does not
   set vptr_fieldno to -1 for portability reasons (IWBN to use C99
   designated initializers).  We cope with that here.  */

int
internal_type_vptr_fieldno (struct type *type)
{
  type = check_typedef (type);
  gdb_assert (type->code () == TYPE_CODE_STRUCT
	      || type->code () == TYPE_CODE_UNION);
  if (!HAVE_CPLUS_STRUCT (type))
    return -1;
  return TYPE_RAW_CPLUS_SPECIFIC (type)->vptr_fieldno;
}

/* Set the value of cplus_stuff.vptr_fieldno.  */

void
set_type_vptr_fieldno (struct type *type, int fieldno)
{
  type = check_typedef (type);
  gdb_assert (type->code () == TYPE_CODE_STRUCT
	      || type->code () == TYPE_CODE_UNION);
  if (!HAVE_CPLUS_STRUCT (type))
    ALLOCATE_CPLUS_STRUCT_TYPE (type);
  TYPE_RAW_CPLUS_SPECIFIC (type)->vptr_fieldno = fieldno;
}

/* Internal routine called by TYPE_VPTR_BASETYPE to return the value of
   cplus_stuff.vptr_basetype.  */

struct type *
internal_type_vptr_basetype (struct type *type)
{
  type = check_typedef (type);
  gdb_assert (type->code () == TYPE_CODE_STRUCT
	      || type->code () == TYPE_CODE_UNION);
  gdb_assert (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_CPLUS_STUFF);
  return TYPE_RAW_CPLUS_SPECIFIC (type)->vptr_basetype;
}

/* Set the value of cplus_stuff.vptr_basetype.  */

void
set_type_vptr_basetype (struct type *type, struct type *basetype)
{
  type = check_typedef (type);
  gdb_assert (type->code () == TYPE_CODE_STRUCT
	      || type->code () == TYPE_CODE_UNION);
  if (!HAVE_CPLUS_STRUCT (type))
    ALLOCATE_CPLUS_STRUCT_TYPE (type);
  TYPE_RAW_CPLUS_SPECIFIC (type)->vptr_basetype = basetype;
}

/* Lookup the vptr basetype/fieldno values for TYPE.
   If found store vptr_basetype in *BASETYPEP if non-NULL, and return
   vptr_fieldno.  Also, if found and basetype is from the same objfile,
   cache the results.
   If not found, return -1 and ignore BASETYPEP.
   Callers should be aware that in some cases (for example,
   the type or one of its baseclasses is a stub type and we are
   debugging a .o file, or the compiler uses DWARF-2 and is not GCC),
   this function will not be able to find the
   virtual function table pointer, and vptr_fieldno will remain -1 and
   vptr_basetype will remain NULL or incomplete.  */

int
get_vptr_fieldno (struct type *type, struct type **basetypep)
{
  type = check_typedef (type);

  if (TYPE_VPTR_FIELDNO (type) < 0)
    {
      int i;

      /* We must start at zero in case the first (and only) baseclass
	 is virtual (and hence we cannot share the table pointer).  */
      for (i = 0; i < TYPE_N_BASECLASSES (type); i++)
	{
	  struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i));
	  int fieldno;
	  struct type *basetype;

	  fieldno = get_vptr_fieldno (baseclass, &basetype);
	  if (fieldno >= 0)
	    {
	      /* If the type comes from a different objfile we can't cache
		 it, it may have a different lifetime.  PR 2384 */
	      if (type->objfile_owner () == basetype->objfile_owner ())
		{
		  set_type_vptr_fieldno (type, fieldno);
		  set_type_vptr_basetype (type, basetype);
		}
	      if (basetypep)
		*basetypep = basetype;
	      return fieldno;
	    }
	}

      /* Not found.  */
      return -1;
    }
  else
    {
      if (basetypep)
	*basetypep = TYPE_VPTR_BASETYPE (type);
      return TYPE_VPTR_FIELDNO (type);
    }
}

static void
stub_noname_complaint (void)
{
  complaint (_("stub type has NULL name"));
}

/* Return nonzero if TYPE has a DYN_PROP_BYTE_STRIDE dynamic property
   attached to it, and that property has a non-constant value.  */

static int
array_type_has_dynamic_stride (struct type *type)
{
  struct dynamic_prop *prop = type->dyn_prop (DYN_PROP_BYTE_STRIDE);

  return prop != nullptr && prop->is_constant ();
}

/* Worker for is_dynamic_type.  */

static bool
is_dynamic_type_internal (struct type *type, bool top_level)
{
  type = check_typedef (type);

  /* We only want to recognize references and pointers at the outermost
     level.  */
  if (top_level && type->is_pointer_or_reference ())
    type = check_typedef (type->target_type ());

  /* Types that have a dynamic TYPE_DATA_LOCATION are considered
     dynamic, even if the type itself is statically defined.
     From a user's point of view, this may appear counter-intuitive;
     but it makes sense in this context, because the point is to determine
     whether any part of the type needs to be resolved before it can
     be exploited.  */
  if (TYPE_DATA_LOCATION (type) != NULL
      && (TYPE_DATA_LOCATION_KIND (type) == PROP_LOCEXPR
	  || TYPE_DATA_LOCATION_KIND (type) == PROP_LOCLIST))
    return true;

  if (TYPE_ASSOCIATED_PROP (type))
    return true;

  if (TYPE_ALLOCATED_PROP (type))
    return true;

  struct dynamic_prop *prop = type->dyn_prop (DYN_PROP_VARIANT_PARTS);
  if (prop != nullptr && prop->kind () != PROP_TYPE)
    return true;

  if (TYPE_HAS_DYNAMIC_LENGTH (type))
    return true;

  switch (type->code ())
    {
    case TYPE_CODE_RANGE:
      {
	/* A range type is obviously dynamic if it has at least one
	   dynamic bound.  But also consider the range type to be
	   dynamic when its subtype is dynamic, even if the bounds
	   of the range type are static.  It allows us to assume that
	   the subtype of a static range type is also static.  */
	return (!has_static_range (type->bounds ())
		|| is_dynamic_type_internal (type->target_type (), false));
      }

    case TYPE_CODE_STRING:
      /* Strings are very much like an array of characters, and can be
	 treated as one here.  */
    case TYPE_CODE_ARRAY:
      {
	gdb_assert (type->num_fields () == 1);

	/* The array is dynamic if either the bounds are dynamic...  */
	if (is_dynamic_type_internal (type->index_type (), false))
	  return true;
	/* ... or the elements it contains have a dynamic contents...  */
	if (is_dynamic_type_internal (type->target_type (), false))
	  return true;
	/* ... or if it has a dynamic stride...  */
	if (array_type_has_dynamic_stride (type))
	  return true;
	return false;
      }

    case TYPE_CODE_STRUCT:
    case TYPE_CODE_UNION:
      {
	int i;

	bool is_cplus = HAVE_CPLUS_STRUCT (type);

	for (i = 0; i < type->num_fields (); ++i)
	  {
	    /* Static fields can be ignored here.  */
	    if (type->field (i).is_static ())
	      continue;
	    /* If the field has dynamic type, then so does TYPE.  */
	    if (is_dynamic_type_internal (type->field (i).type (), false))
	      return true;
	    /* If the field is at a fixed offset, then it is not
	       dynamic.  */
	    if (type->field (i).loc_kind () != FIELD_LOC_KIND_DWARF_BLOCK)
	      continue;
	    /* Do not consider C++ virtual base types to be dynamic
	       due to the field's offset being dynamic; these are
	       handled via other means.  */
	    if (is_cplus && BASETYPE_VIA_VIRTUAL (type, i))
	      continue;
	    return true;
	  }
      }
      break;
    }

  return false;
}

/* See gdbtypes.h.  */

bool
is_dynamic_type (struct type *type)
{
  return is_dynamic_type_internal (type, true);
}

static struct type *resolve_dynamic_type_internal
  (struct type *type, struct property_addr_info *addr_stack,
   const frame_info_ptr &frame, bool top_level);

/* Given a dynamic range type (dyn_range_type) and a stack of
   struct property_addr_info elements, return a static version
   of that type.

   When RESOLVE_P is true then the returned static range is created by
   actually evaluating any dynamic properties within the range type, while
   when RESOLVE_P is false the returned static range has all of the bounds
   and stride information set to undefined.  The RESOLVE_P set to false
   case will be used when evaluating a dynamic array that is not
   allocated, or not associated, i.e. the bounds information might not be
   initialized yet.

   RANK is the array rank for which we are resolving this range, and is a
   zero based count.  The rank should never be negative.
*/

static struct type *
resolve_dynamic_range (struct type *dyn_range_type,
		       struct property_addr_info *addr_stack,
		       const frame_info_ptr &frame,
		       int rank, bool resolve_p = true)
{
  CORE_ADDR value;
  struct type *static_range_type, *static_target_type;
  struct dynamic_prop low_bound, high_bound, stride;

  gdb_assert (dyn_range_type->code () == TYPE_CODE_RANGE);
  gdb_assert (rank >= 0);

  const struct dynamic_prop *prop = &dyn_range_type->bounds ()->low;
  if (resolve_p)
    {
      if (dwarf2_evaluate_property (prop, frame, addr_stack, &value,
				    { (CORE_ADDR) rank }))
	low_bound.set_const_val (value);
      else if (prop->kind () == PROP_UNDEFINED)
	low_bound.set_undefined ();
      else
	low_bound.set_optimized_out ();
    }
  else
    low_bound.set_undefined ();

  prop = &dyn_range_type->bounds ()->high;
  if (resolve_p)
    {
      if (dwarf2_evaluate_property (prop, frame, addr_stack, &value,
				    { (CORE_ADDR) rank }))
	{
	  high_bound.set_const_val (value);

	  if (dyn_range_type->bounds ()->flag_upper_bound_is_count)
	    high_bound.set_const_val
	      (low_bound.const_val () + high_bound.const_val () - 1);
	}
      else if (prop->kind () == PROP_UNDEFINED)
	high_bound.set_undefined ();
      else
	high_bound.set_optimized_out ();
    }
  else
    high_bound.set_undefined ();

  bool byte_stride_p = dyn_range_type->bounds ()->flag_is_byte_stride;
  prop = &dyn_range_type->bounds ()->stride;
  if (resolve_p && dwarf2_evaluate_property (prop, frame, addr_stack, &value,
					     { (CORE_ADDR) rank }))
    {
      stride.set_const_val (value);

      /* If we have a bit stride that is not an exact number of bytes then
	 I really don't think this is going to work with current GDB, the
	 array indexing code in GDB seems to be pretty heavily tied to byte
	 offsets right now.  Assuming 8 bits in a byte.  */
      struct gdbarch *gdbarch = dyn_range_type->arch ();
      int unit_size = gdbarch_addressable_memory_unit_size (gdbarch);
      if (!byte_stride_p && (value % (unit_size * 8)) != 0)
	error (_("bit strides that are not a multiple of the byte size "
		 "are currently not supported"));
    }
  else
    {
      stride.set_undefined ();
      byte_stride_p = true;
    }

  static_target_type
    = resolve_dynamic_type_internal (dyn_range_type->target_type (),
				     addr_stack, frame, false);
  LONGEST bias = dyn_range_type->bounds ()->bias;
  type_allocator alloc (dyn_range_type);
  static_range_type = create_range_type_with_stride
    (alloc, static_target_type,
     &low_bound, &high_bound, bias, &stride, byte_stride_p);
  static_range_type->set_name (dyn_range_type->name ());
  static_range_type->bounds ()->flag_bound_evaluated = 1;
  return static_range_type;
}

/* Helper function for resolve_dynamic_array_or_string.  This function
   resolves the properties for a single array at RANK within a nested array
   of arrays structure.  The RANK value is greater than or equal to 0, and
   starts at it's maximum value and goes down by 1 for each recursive call
   to this function.  So, for a 3-dimensional array, the first call to this
   function has RANK == 2, then we call ourselves recursively with RANK ==
   1, than again with RANK == 0, and at that point we should return.

   TYPE is updated as the dynamic properties are resolved, and so, should
   be a copy of the dynamic type, rather than the original dynamic type
   itself.

   ADDR_STACK is a stack of struct property_addr_info to be used if needed
   during the dynamic resolution.

   When RESOLVE_P is true then the dynamic properties of TYPE are
   evaluated, otherwise the dynamic properties of TYPE are not evaluated,
   instead we assume the array is not allocated/associated yet.  */

static struct type *
resolve_dynamic_array_or_string_1 (struct type *type,
				   struct property_addr_info *addr_stack,
				   const frame_info_ptr &frame,
				   int rank, bool resolve_p)
{
  CORE_ADDR value;
  struct type *elt_type;
  struct type *range_type;
  struct type *ary_dim;
  struct dynamic_prop *prop;
  unsigned int bit_stride = 0;

  /* For dynamic type resolution strings can be treated like arrays of
     characters.  */
  gdb_assert (type->code () == TYPE_CODE_ARRAY
	      || type->code () == TYPE_CODE_STRING);

  /* As the rank is a zero based count we expect this to never be
     negative.  */
  gdb_assert (rank >= 0);

  /* Resolve the allocated and associated properties before doing anything
     else.  If an array is not allocated or not associated then (at least
     for Fortran) there is no guarantee that the data to define the upper
     bound, lower bound, or stride will be correct.  If RESOLVE_P is
     already false at this point then this is not the first dimension of
     the array and a more outer dimension has already marked this array as
     not allocated/associated, as such we just ignore this property.  This
     is fine as GDB only checks the allocated/associated on the outer most
     dimension of the array.  */
  prop = TYPE_ALLOCATED_PROP (type);
  if (prop != NULL && resolve_p
      && dwarf2_evaluate_property (prop, frame, addr_stack, &value))
    {
      prop->set_const_val (value);
      if (value == 0)
	resolve_p = false;
    }

  prop = TYPE_ASSOCIATED_PROP (type);
  if (prop != NULL && resolve_p
      && dwarf2_evaluate_property (prop, frame, addr_stack, &value))
    {
      prop->set_const_val (value);
      if (value == 0)
	resolve_p = false;
    }

  range_type = check_typedef (type->index_type ());
  range_type
    = resolve_dynamic_range (range_type, addr_stack, frame, rank, resolve_p);

  ary_dim = check_typedef (type->target_type ());
  if (ary_dim != NULL && ary_dim->code () == TYPE_CODE_ARRAY)
    {
      ary_dim = copy_type (ary_dim);
      elt_type = resolve_dynamic_array_or_string_1 (ary_dim, addr_stack,
						    frame, rank - 1,
						    resolve_p);
    }
  else
    elt_type = type->target_type ();

  prop = type->dyn_prop (DYN_PROP_BYTE_STRIDE);
  if (prop != NULL && resolve_p)
    {
      if (dwarf2_evaluate_property (prop, frame, addr_stack, &value))
	{
	  type->remove_dyn_prop (DYN_PROP_BYTE_STRIDE);
	  bit_stride = (unsigned int) (value * 8);
	}
      else
	{
	  /* Could be a bug in our code, but it could also happen
	     if the DWARF info is not correct.  Issue a warning,
	     and assume no byte/bit stride (leave bit_stride = 0).  */
	  warning (_("cannot determine array stride for type %s"),
		   type->name () ? type->name () : "<no name>");
	}
    }
  else
    bit_stride = type->field (0).bitsize ();

  type_allocator alloc (type, type_allocator::SMASH);
  return create_array_type_with_stride (alloc, elt_type, range_type, NULL,
					bit_stride);
}

/* Resolve an array or string type with dynamic properties, return a new
   type with the dynamic properties resolved to actual values.  The
   ADDR_STACK represents the location of the object being resolved.  */

static struct type *
resolve_dynamic_array_or_string (struct type *type,
				 struct property_addr_info *addr_stack,
				 const frame_info_ptr &frame)
{
  CORE_ADDR value;
  int rank = 0;

  /* For dynamic type resolution strings can be treated like arrays of
     characters.  */
  gdb_assert (type->code () == TYPE_CODE_ARRAY
	      || type->code () == TYPE_CODE_STRING);

  type = copy_type (type);

  /* Resolve the rank property to get rank value.  */
  struct dynamic_prop *prop = TYPE_RANK_PROP (type);
  if (dwarf2_evaluate_property (prop, frame, addr_stack, &value))
    {
      prop->set_const_val (value);
      rank = value;

      if (rank == 0)
	{
	  /* Rank is zero, if a variable is passed as an argument to a
	     function.  In this case the resolved type should not be an
	     array, but should instead be that of an array element.  */
	  struct type *dynamic_array_type = type;
	  type = copy_type (dynamic_array_type->target_type ());
	  struct dynamic_prop_list *prop_list
	    = TYPE_MAIN_TYPE (dynamic_array_type)->dyn_prop_list;
	  if (prop_list != nullptr)
	    {
	      struct obstack *obstack
		= &type->objfile_owner ()->objfile_obstack;
	      TYPE_MAIN_TYPE (type)->dyn_prop_list
		= copy_dynamic_prop_list (obstack, prop_list);
	    }
	  return type;
	}
      else if (type->code () == TYPE_CODE_STRING && rank != 1)
	{
	  /* What would this even mean?  A string with a dynamic rank
	     greater than 1.  */
	  error (_("unable to handle string with dynamic rank greater than 1"));
	}
      else if (rank > 1)
	{
	  /* Arrays with dynamic rank are initially just an array type
	     with a target type that is the array element.

	     However, now we know the rank of the array we need to build
	     the array of arrays structure that GDB expects, that is we
	     need an array type that has a target which is an array type,
	     and so on, until eventually, we have the element type at the
	     end of the chain.  Create all the additional array types here
	     by copying the top level array type.  */
	  struct type *element_type = type->target_type ();
	  struct type *rank_type = type;
	  for (int i = 1; i < rank; i++)
	    {
	      rank_type->set_target_type (copy_type (rank_type));
	      rank_type = rank_type->target_type ();
	    }
	  rank_type->set_target_type (element_type);
	}
    }
  else
    {
      rank = 1;

      for (struct type *tmp_type = check_typedef (type->target_type ());
	   tmp_type->code () == TYPE_CODE_ARRAY;
	   tmp_type = check_typedef (tmp_type->target_type ()))
	++rank;
    }

  /* The rank that we calculated above is actually a count of the number of
     ranks.  However, when we resolve the type of each individual array
     rank we should actually use a rank "offset", e.g. an array with a rank
     count of 1 (calculated above) will use the rank offset 0 in order to
     resolve the details of the first array dimension.  As a result, we
     reduce the rank by 1 here.  */
  --rank;

  return resolve_dynamic_array_or_string_1 (type, addr_stack, frame, rank,
					    true);
}

/* Resolve dynamic bounds of members of the union TYPE to static
   bounds.  ADDR_STACK is a stack of struct property_addr_info
   to be used if needed during the dynamic resolution.  */

static struct type *
resolve_dynamic_union (struct type *type,
		       struct property_addr_info *addr_stack,
		       const frame_info_ptr &frame)
{
  struct type *resolved_type;
  int i;
  unsigned int max_len = 0;

  gdb_assert (type->code () == TYPE_CODE_UNION);

  resolved_type = copy_type (type);
  resolved_type->copy_fields (type);
  for (i = 0; i < resolved_type->num_fields (); ++i)
    {
      struct type *t;

      if (type->field (i).is_static ())
	continue;

      t = resolve_dynamic_type_internal (resolved_type->field (i).type (),
					 addr_stack, frame, false);
      resolved_type->field (i).set_type (t);

      struct type *real_type = check_typedef (t);
      if (real_type->length () > max_len)
	max_len = real_type->length ();
    }

  resolved_type->set_length (max_len);
  return resolved_type;
}

/* See gdbtypes.h.  */

bool
variant::matches (ULONGEST value, bool is_unsigned) const
{
  for (const discriminant_range &range : discriminants)
    if (range.contains (value, is_unsigned))
      return true;
  return false;
}

static void
compute_variant_fields_inner (struct type *type,
			      struct property_addr_info *addr_stack,
			      const variant_part &part,
			      std::vector<bool> &flags);

/* A helper function to determine which variant fields will be active.
   This handles both the variant's direct fields, and any variant
   parts embedded in this variant.  TYPE is the type we're examining.
   ADDR_STACK holds information about the concrete object.  VARIANT is
   the current variant to be handled.  FLAGS is where the results are
   stored -- this function sets the Nth element in FLAGS if the
   corresponding field is enabled.  ENABLED is whether this variant is
   enabled or not.  */

static void
compute_variant_fields_recurse (struct type *type,
				struct property_addr_info *addr_stack,
				const variant &variant,
				std::vector<bool> &flags,
				bool enabled)
{
  for (int field = variant.first_field; field < variant.last_field; ++field)
    flags[field] = enabled;

  for (const variant_part &new_part : variant.parts)
    {
      if (enabled)
	compute_variant_fields_inner (type, addr_stack, new_part, flags);
      else
	{
	  for (const auto &sub_variant : new_part.variants)
	    compute_variant_fields_recurse (type, addr_stack, sub_variant,
					    flags, enabled);
	}
    }
}

/* A helper function to determine which variant fields will be active.
   This evaluates the discriminant, decides which variant (if any) is
   active, and then updates FLAGS to reflect which fields should be
   available.  TYPE is the type we're examining.  ADDR_STACK holds
   information about the concrete object.  VARIANT is the current
   variant to be handled.  FLAGS is where the results are stored --
   this function sets the Nth element in FLAGS if the corresponding
   field is enabled.  */

static void
compute_variant_fields_inner (struct type *type,
			      struct property_addr_info *addr_stack,
			      const variant_part &part,
			      std::vector<bool> &flags)
{
  /* Evaluate the discriminant.  */
  std::optional<ULONGEST> discr_value;
  if (part.discriminant_index != -1)
    {
      int idx = part.discriminant_index;

      if (type->field (idx).loc_kind () != FIELD_LOC_KIND_BITPOS)
	error (_("Cannot determine struct field location"
		 " (invalid location kind)"));

      if (addr_stack->valaddr.data () != NULL)
	discr_value = unpack_field_as_long (type, addr_stack->valaddr.data (),
					    idx);
      else
	{
	  CORE_ADDR addr = (addr_stack->addr
			    + (type->field (idx).loc_bitpos ()
			       / TARGET_CHAR_BIT));

	  LONGEST bitsize = type->field (idx).bitsize ();
	  LONGEST size = bitsize / 8;
	  if (size == 0)
	    size = type->field (idx).type ()->length ();

	  gdb_byte bits[sizeof (ULONGEST)];
	  read_memory (addr, bits, size);

	  LONGEST bitpos = (type->field (idx).loc_bitpos ()
			    % TARGET_CHAR_BIT);

	  discr_value = unpack_bits_as_long (type->field (idx).type (),
					     bits, bitpos, bitsize);
	}
    }

  /* Go through each variant and see which applies.  */
  const variant *default_variant = nullptr;
  const variant *applied_variant = nullptr;
  for (const auto &variant : part.variants)
    {
      if (variant.is_default ())
	default_variant = &variant;
      else if (discr_value.has_value ()
	       && variant.matches (*discr_value, part.is_unsigned))
	{
	  applied_variant = &variant;
	  break;
	}
    }
  if (applied_variant == nullptr)
    applied_variant = default_variant;

  for (const auto &variant : part.variants)
    compute_variant_fields_recurse (type, addr_stack, variant,
				    flags, applied_variant == &variant);
}  

/* Determine which variant fields are available in TYPE.  The enabled
   fields are stored in RESOLVED_TYPE.  ADDR_STACK holds information
   about the concrete object.  PARTS describes the top-level variant
   parts for this type.  */

static void
compute_variant_fields (struct type *type,
			struct type *resolved_type,
			struct property_addr_info *addr_stack,
			const gdb::array_view<variant_part> &parts)
{
  /* Assume all fields are included by default.  */
  std::vector<bool> flags (resolved_type->num_fields (), true);

  /* Now disable fields based on the variants that control them.  */
  for (const auto &part : parts)
    compute_variant_fields_inner (type, addr_stack, part, flags);

  unsigned int nfields = std::count (flags.begin (), flags.end (), true);
  /* No need to zero-initialize the newly allocated fields, they'll be
     initialized by the copy in the loop below.  */
  resolved_type->alloc_fields (nfields, false);

  int out = 0;
  for (int i = 0; i < type->num_fields (); ++i)
    {
      if (!flags[i])
	continue;

      resolved_type->field (out) = type->field (i);
      ++out;
    }
}

/* Resolve dynamic bounds of members of the struct TYPE to static
   bounds.  ADDR_STACK is a stack of struct property_addr_info to
   be used if needed during the dynamic resolution.  */

static struct type *
resolve_dynamic_struct (struct type *type,
			struct property_addr_info *addr_stack,
			const frame_info_ptr &frame)
{
  struct type *resolved_type;
  int i;
  unsigned resolved_type_bit_length = 0;

  gdb_assert (type->code () == TYPE_CODE_STRUCT);

  resolved_type = copy_type (type);

  dynamic_prop *variant_prop = resolved_type->dyn_prop (DYN_PROP_VARIANT_PARTS);
  if (variant_prop != nullptr && variant_prop->kind () == PROP_VARIANT_PARTS)
    {
      compute_variant_fields (type, resolved_type, addr_stack,
			      *variant_prop->variant_parts ());
      /* We want to leave the property attached, so that the Rust code
	 can tell whether the type was originally an enum.  */
      variant_prop->set_original_type (type);
    }
  else
    {
      resolved_type->copy_fields (type);
    }

  for (i = 0; i < resolved_type->num_fields (); ++i)
    {
      unsigned new_bit_length;
      struct property_addr_info pinfo;

      if (resolved_type->field (i).is_static ())
	continue;

      if (resolved_type->field (i).loc_kind () == FIELD_LOC_KIND_DWARF_BLOCK)
	{
	  struct dwarf2_property_baton baton;
	  baton.property_type
	    = lookup_pointer_type (resolved_type->field (i).type ());
	  baton.locexpr = *resolved_type->field (i).loc_dwarf_block ();

	  struct dynamic_prop prop;
	  prop.set_locexpr (&baton);

	  CORE_ADDR addr;
	  if (dwarf2_evaluate_property (&prop, frame, addr_stack, &addr,
					{addr_stack->addr}))
	    resolved_type->field (i).set_loc_bitpos
	      (TARGET_CHAR_BIT * (addr - addr_stack->addr));
	}

      /* As we know this field is not a static field, the field's
	 field_loc_kind should be FIELD_LOC_KIND_BITPOS.  Verify
	 this is the case, but only trigger a simple error rather
	 than an internal error if that fails.  While failing
	 that verification indicates a bug in our code, the error
	 is not severe enough to suggest to the user he stops
	 his debugging session because of it.  */
      if (resolved_type->field (i).loc_kind () != FIELD_LOC_KIND_BITPOS)
	error (_("Cannot determine struct field location"
		 " (invalid location kind)"));

      pinfo.type = check_typedef (resolved_type->field (i).type ());
      size_t offset = resolved_type->field (i).loc_bitpos () / TARGET_CHAR_BIT;
      pinfo.valaddr = addr_stack->valaddr;
      if (!pinfo.valaddr.empty ())
	pinfo.valaddr = pinfo.valaddr.slice (offset);
      pinfo.addr = addr_stack->addr + offset;
      pinfo.next = addr_stack;

      resolved_type->field (i).set_type
	(resolve_dynamic_type_internal (resolved_type->field (i).type (),
					&pinfo, frame, false));
      gdb_assert (resolved_type->field (i).loc_kind ()
		  == FIELD_LOC_KIND_BITPOS);

      new_bit_length = resolved_type->field (i).loc_bitpos ();
      if (resolved_type->field (i).bitsize () != 0)
	new_bit_length += resolved_type->field (i).bitsize ();
      else
	{
	  struct type *real_type
	    = check_typedef (resolved_type->field (i).type ());

	  new_bit_length += (real_type->length () * TARGET_CHAR_BIT);
	}

      /* Normally, we would use the position and size of the last field
	 to determine the size of the enclosing structure.  But GCC seems
	 to be encoding the position of some fields incorrectly when
	 the struct contains a dynamic field that is not placed last.
	 So we compute the struct size based on the field that has
	 the highest position + size - probably the best we can do.  */
      if (new_bit_length > resolved_type_bit_length)
	resolved_type_bit_length = new_bit_length;
    }

  /* The length of a type won't change for fortran, but it does for C and Ada.
     For fortran the size of dynamic fields might change over time but not the
     type length of the structure.  If we adapt it, we run into problems
     when calculating the element offset for arrays of structs.  */
  if (current_language->la_language != language_fortran)
    resolved_type->set_length ((resolved_type_bit_length + TARGET_CHAR_BIT - 1)
			       / TARGET_CHAR_BIT);

  /* The Ada language uses this field as a cache for static fixed types: reset
     it as RESOLVED_TYPE must have its own static fixed type.  */
  resolved_type->set_target_type (nullptr);

  return resolved_type;
}

/* Worker for resolved_dynamic_type.  */

static struct type *
resolve_dynamic_type_internal (struct type *type,
			       struct property_addr_info *addr_stack,
			       const frame_info_ptr &frame,
			       bool top_level)
{
  struct type *real_type = check_typedef (type);
  struct type *resolved_type = nullptr;
  struct dynamic_prop *prop;
  CORE_ADDR value;

  if (!is_dynamic_type_internal (real_type, top_level))
    return type;

  std::optional<CORE_ADDR> type_length;
  prop = TYPE_DYNAMIC_LENGTH (type);
  if (prop != NULL
      && dwarf2_evaluate_property (prop, frame, addr_stack, &value))
    type_length = value;

  if (type->code () == TYPE_CODE_TYPEDEF)
    {
      resolved_type = copy_type (type);
      resolved_type->set_target_type
	(resolve_dynamic_type_internal (type->target_type (), addr_stack,
					frame, top_level));
    }
  else
    {
      /* Before trying to resolve TYPE, make sure it is not a stub.  */
      type = real_type;

      switch (type->code ())
	{
	case TYPE_CODE_REF:
	case TYPE_CODE_PTR:
	case TYPE_CODE_RVALUE_REF:
	  {
	    struct property_addr_info pinfo;

	    pinfo.type = check_typedef (type->target_type ());
	    pinfo.valaddr = {};
	    if (addr_stack->valaddr.data () != NULL)
	      pinfo.addr = extract_typed_address (addr_stack->valaddr.data (),
						  type);
	    else
	      pinfo.addr = read_memory_typed_address (addr_stack->addr, type);
	    pinfo.next = addr_stack;

	    /* Special case a NULL pointer here -- we don't want to
	       dereference it.  */
	    if (pinfo.addr != 0)
	      {
		resolved_type = copy_type (type);
		resolved_type->set_target_type
		  (resolve_dynamic_type_internal (type->target_type (),
						  &pinfo, frame, true));
	      }
	    break;
	  }

	case TYPE_CODE_STRING:
	  /* Strings are very much like an array of characters, and can be
	     treated as one here.  */
	case TYPE_CODE_ARRAY:
	  resolved_type = resolve_dynamic_array_or_string (type, addr_stack,
							   frame);
	  break;

	case TYPE_CODE_RANGE:
	  /* Pass 0 for the rank value here, which indicates this is a
	     range for the first rank of an array.  The assumption is that
	     this rank value is not actually required for the resolution of
	     the dynamic range, otherwise, we'd be resolving this range
	     within the context of a dynamic array.  */
	  resolved_type = resolve_dynamic_range (type, addr_stack, frame, 0);
	  break;

	case TYPE_CODE_UNION:
	  resolved_type = resolve_dynamic_union (type, addr_stack, frame);
	  break;

	case TYPE_CODE_STRUCT:
	  resolved_type = resolve_dynamic_struct (type, addr_stack, frame);
	  break;
	}
    }

  if (resolved_type == nullptr)
    return type;

  if (type_length.has_value ())
    {
      resolved_type->set_length (*type_length);
      resolved_type->remove_dyn_prop (DYN_PROP_BYTE_SIZE);
    }

  /* Resolve data_location attribute.  */
  prop = TYPE_DATA_LOCATION (resolved_type);
  if (prop != NULL
      && dwarf2_evaluate_property (prop, frame, addr_stack, &value))
    {
      /* Start of Fortran hack.  See comment in f-lang.h for what is going
	 on here.*/
      if (current_language->la_language == language_fortran
	  && resolved_type->code () == TYPE_CODE_ARRAY)
	value = fortran_adjust_dynamic_array_base_address_hack (resolved_type,
								value);
      /* End of Fortran hack.  */
      prop->set_const_val (value);
    }

  return resolved_type;
}

/* See gdbtypes.h  */

struct type *
resolve_dynamic_type (struct type *type,
		      gdb::array_view<const gdb_byte> valaddr,
		      CORE_ADDR addr,
		      const frame_info_ptr *in_frame)
{
  struct property_addr_info pinfo
    = {check_typedef (type), valaddr, addr, NULL};

  frame_info_ptr frame;
  if (in_frame != nullptr)
    frame = *in_frame;

  return resolve_dynamic_type_internal (type, &pinfo, frame, true);
}

/* See gdbtypes.h  */

dynamic_prop *
type::dyn_prop (dynamic_prop_node_kind prop_kind) const
{
  dynamic_prop_list *node = this->main_type->dyn_prop_list;

  while (node != NULL)
    {
      if (node->prop_kind == prop_kind)
	return &node->prop;
      node = node->next;
    }
  return NULL;
}

/* See gdbtypes.h  */

void
type::add_dyn_prop (dynamic_prop_node_kind prop_kind, dynamic_prop prop)
{
  struct dynamic_prop_list *temp;

  gdb_assert (this->is_objfile_owned ());

  temp = XOBNEW (&this->objfile_owner ()->objfile_obstack,
		 struct dynamic_prop_list);
  temp->prop_kind = prop_kind;
  temp->prop = prop;
  temp->next = this->main_type->dyn_prop_list;

  this->main_type->dyn_prop_list = temp;
}

/* See gdbtypes.h.  */

void
type::remove_dyn_prop (dynamic_prop_node_kind kind)
{
  struct dynamic_prop_list *prev_node, *curr_node;

  curr_node = this->main_type->dyn_prop_list;
  prev_node = NULL;

  while (NULL != curr_node)
    {
      if (curr_node->prop_kind == kind)
	{
	  /* Update the linked list but don't free anything.
	     The property was allocated on obstack and it is not known
	     if we are on top of it.  Nevertheless, everything is released
	     when the complete obstack is freed.  */
	  if (NULL == prev_node)
	    this->main_type->dyn_prop_list = curr_node->next;
	  else
	    prev_node->next = curr_node->next;

	  return;
	}

      prev_node = curr_node;
      curr_node = curr_node->next;
    }
}

/* Find the real type of TYPE.  This function returns the real type,
   after removing all layers of typedefs, and completing opaque or stub
   types.  Completion changes the TYPE argument, but stripping of
   typedefs does not.

   Instance flags (e.g. const/volatile) are preserved as typedefs are
   stripped.  If necessary a new qualified form of the underlying type
   is created.

   NOTE: This will return a typedef if type::target_type for the typedef has
   not been computed and we're either in the middle of reading symbols, or
   there was no name for the typedef in the debug info.

   NOTE: Lookup of opaque types can throw errors for invalid symbol files.
   QUITs in the symbol reading code can also throw.
   Thus this function can throw an exception.

   If TYPE is a TYPE_CODE_TYPEDEF, its length is updated to the length of
   the target type.

   If this is a stubbed struct (i.e. declared as struct foo *), see if
   we can find a full definition in some other file.  If so, copy this
   definition, so we can use it in future.  There used to be a comment
   (but not any code) that if we don't find a full definition, we'd
   set a flag so we don't spend time in the future checking the same
   type.  That would be a mistake, though--we might load in more
   symbols which contain a full definition for the type.  */

struct type *
check_typedef (struct type *type)
{
  struct type *orig_type = type;

  gdb_assert (type);

  /* While we're removing typedefs, we don't want to lose qualifiers.
     E.g., const/volatile.  */
  type_instance_flags instance_flags = type->instance_flags ();

  while (type->code () == TYPE_CODE_TYPEDEF)
    {
      if (!type->target_type ())
	{
	  const char *name;
	  struct symbol *sym;

	  /* It is dangerous to call lookup_symbol if we are currently
	     reading a symtab.  Infinite recursion is one danger.  */
	  if (currently_reading_symtab)
	    return make_qualified_type (type, instance_flags, NULL);

	  name = type->name ();
	  if (name == NULL)
	    {
	      stub_noname_complaint ();
	      return make_qualified_type (type, instance_flags, NULL);
	    }
	  domain_search_flag flag
	    = ((type->language () == language_c
		|| type->language () == language_objc
		|| type->language () == language_opencl
		|| type->language () == language_minimal)
	       ? SEARCH_STRUCT_DOMAIN
	       : SEARCH_TYPE_DOMAIN);
	  sym = lookup_symbol (name, nullptr, flag, nullptr).symbol;
	  if (sym)
	    type->set_target_type (sym->type ());
	  else					/* TYPE_CODE_UNDEF */
	    type->set_target_type (type_allocator (type->arch ()).new_type ());
	}
      type = type->target_type ();

      /* Preserve the instance flags as we traverse down the typedef chain.

	 Handling address spaces/classes is nasty, what do we do if there's a
	 conflict?
	 E.g., what if an outer typedef marks the type as class_1 and an inner
	 typedef marks the type as class_2?
	 This is the wrong place to do such error checking.  We leave it to
	 the code that created the typedef in the first place to flag the
	 error.  We just pick the outer address space (akin to letting the
	 outer cast in a chain of casting win), instead of assuming
	 "it can't happen".  */
      {
	const type_instance_flags ALL_SPACES
	  = (TYPE_INSTANCE_FLAG_CODE_SPACE
	     | TYPE_INSTANCE_FLAG_DATA_SPACE);
	const type_instance_flags ALL_CLASSES
	  = TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL;

	type_instance_flags new_instance_flags = type->instance_flags ();

	/* Treat code vs data spaces and address classes separately.  */
	if ((instance_flags & ALL_SPACES) != 0)
	  new_instance_flags &= ~ALL_SPACES;
	if ((instance_flags & ALL_CLASSES) != 0)
	  new_instance_flags &= ~ALL_CLASSES;

	instance_flags |= new_instance_flags;
      }
    }

  /* If this is a struct/class/union with no fields, then check
     whether a full definition exists somewhere else.  This is for
     systems where a type definition with no fields is issued for such
     types, instead of identifying them as stub types in the first
     place.  */

  if (TYPE_IS_OPAQUE (type) 
      && opaque_type_resolution 
      && !currently_reading_symtab)
    {
      const char *name = type->name ();
      struct type *newtype;

      if (name == NULL)
	{
	  stub_noname_complaint ();
	  return make_qualified_type (type, instance_flags, NULL);
	}
      newtype = lookup_transparent_type (name);

      if (newtype)
	{
	  /* If the resolved type and the stub are in the same
	     objfile, then replace the stub type with the real deal.
	     But if they're in separate objfiles, leave the stub
	     alone; we'll just look up the transparent type every time
	     we call check_typedef.  We can't create pointers between
	     types allocated to different objfiles, since they may
	     have different lifetimes.  Trying to copy NEWTYPE over to
	     TYPE's objfile is pointless, too, since you'll have to
	     move over any other types NEWTYPE refers to, which could
	     be an unbounded amount of stuff.  */
	  if (newtype->objfile_owner () == type->objfile_owner ())
	    type = make_qualified_type (newtype, type->instance_flags (), type);
	  else
	    type = newtype;
	}
    }
  /* Otherwise, rely on the stub flag being set for opaque/stubbed
     types.  */
  else if (type->is_stub () && !currently_reading_symtab)
    {
      const char *name = type->name ();
      struct symbol *sym;

      if (name == NULL)
	{
	  stub_noname_complaint ();
	  return make_qualified_type (type, instance_flags, NULL);
	}
      domain_search_flag flag
	= ((type->language () == language_c
	    || type->language () == language_objc
	    || type->language () == language_opencl
	    || type->language () == language_minimal)
	   ? SEARCH_STRUCT_DOMAIN
	   : SEARCH_TYPE_DOMAIN);
      sym = lookup_symbol (name, nullptr, flag, nullptr).symbol;
      if (sym)
	{
	  /* Same as above for opaque types, we can replace the stub
	     with the complete type only if they are in the same
	     objfile.  */
	  if (sym->type ()->objfile_owner () == type->objfile_owner ())
	    type = make_qualified_type (sym->type (),
					type->instance_flags (), type);
	  else
	    type = sym->type ();
	}
    }

  if (type->target_is_stub ())
    {
      struct type *target_type = check_typedef (type->target_type ());

      if (target_type->is_stub () || target_type->target_is_stub ())
	{
	  /* Nothing we can do.  */
	}
      else if (type->code () == TYPE_CODE_RANGE)
	{
	  type->set_length (target_type->length ());
	  type->set_target_is_stub (false);
	}
      else if (type->code () == TYPE_CODE_ARRAY
	       && update_static_array_size (type))
	type->set_target_is_stub (false);
    }

  type = make_qualified_type (type, instance_flags, NULL);

  /* Cache TYPE_LENGTH for future use.  */
  orig_type->set_length (type->length ());

  return type;
}

/* Parse a type expression in the string [P..P+LENGTH).  If an error
   occurs, silently return a void type.  */

static struct type *
safe_parse_type (struct gdbarch *gdbarch, const char *p, int length)
{
  struct type *type = NULL; /* Initialize to keep gcc happy.  */

  /* Suppress error messages.  */
  scoped_restore saved_gdb_stderr = make_scoped_restore (&gdb_stderr,
							 &null_stream);

  /* Call parse_and_eval_type() without fear of longjmp()s.  */
  try
    {
      type = parse_and_eval_type (p, length);
    }
  catch (const gdb_exception_error &except)
    {
      type = builtin_type (gdbarch)->builtin_void;
    }

  return type;
}

/* Ugly hack to convert method stubs into method types.

   He ain't kiddin'.  This demangles the name of the method into a
   string including argument types, parses out each argument type,
   generates a string casting a zero to that type, evaluates the
   string, and stuffs the resulting type into an argtype vector!!!
   Then it knows the type of the whole function (including argument
   types for overloading), which info used to be in the stab's but was
   removed to hack back the space required for them.  */

static void
check_stub_method (struct type *type, int method_id, int signature_id)
{
  struct gdbarch *gdbarch = type->arch ();
  struct fn_field *f;
  char *mangled_name = gdb_mangle_name (type, method_id, signature_id);
  gdb::unique_xmalloc_ptr<char> demangled_name
    = gdb_demangle (mangled_name, DMGL_PARAMS | DMGL_ANSI);
  char *argtypetext, *p;
  int depth = 0, argcount = 1;
  struct field *argtypes;
  struct type *mtype;

  /* Make sure we got back a function string that we can use.  */
  if (demangled_name)
    p = strchr (demangled_name.get (), '(');
  else
    p = NULL;

  if (demangled_name == NULL || p == NULL)
    error (_("Internal: Cannot demangle mangled name `%s'."), 
	   mangled_name);

  /* Now, read in the parameters that define this type.  */
  p += 1;
  argtypetext = p;
  while (*p)
    {
      if (*p == '(' || *p == '<')
	{
	  depth += 1;
	}
      else if (*p == ')' || *p == '>')
	{
	  depth -= 1;
	}
      else if (*p == ',' && depth == 0)
	{
	  argcount += 1;
	}

      p += 1;
    }

  /* If we read one argument and it was ``void'', don't count it.  */
  if (startswith (argtypetext, "(void)"))
    argcount -= 1;

  /* We need one extra slot, for the THIS pointer.  */

  argtypes = (struct field *)
    TYPE_ZALLOC (type, (argcount + 1) * sizeof (struct field));
  p = argtypetext;

  /* Add THIS pointer for non-static methods.  */
  f = TYPE_FN_FIELDLIST1 (type, method_id);
  if (TYPE_FN_FIELD_STATIC_P (f, signature_id))
    argcount = 0;
  else
    {
      argtypes[0].set_type (lookup_pointer_type (type));
      argcount = 1;
    }

  if (*p != ')')		/* () means no args, skip while.  */
    {
      depth = 0;
      while (*p)
	{
	  if (depth <= 0 && (*p == ',' || *p == ')'))
	    {
	      /* Avoid parsing of ellipsis, they will be handled below.
		 Also avoid ``void'' as above.  */
	      if (strncmp (argtypetext, "...", p - argtypetext) != 0
		  && strncmp (argtypetext, "void", p - argtypetext) != 0)
		{
		  argtypes[argcount].set_type
		    (safe_parse_type (gdbarch, argtypetext, p - argtypetext));
		  argcount += 1;
		}
	      argtypetext = p + 1;
	    }

	  if (*p == '(' || *p == '<')
	    {
	      depth += 1;
	    }
	  else if (*p == ')' || *p == '>')
	    {
	      depth -= 1;
	    }

	  p += 1;
	}
    }

  TYPE_FN_FIELD_PHYSNAME (f, signature_id) = mangled_name;

  /* Now update the old "stub" type into a real type.  */
  mtype = TYPE_FN_FIELD_TYPE (f, signature_id);
  /* MTYPE may currently be a function (TYPE_CODE_FUNC).
     We want a method (TYPE_CODE_METHOD).  */
  smash_to_method_type (mtype, type, mtype->target_type (),
			argtypes, argcount, p[-2] == '.');
  mtype->set_is_stub (false);
  TYPE_FN_FIELD_STUB (f, signature_id) = 0;
}

/* This is the external interface to check_stub_method, above.  This
   function unstubs all of the signatures for TYPE's METHOD_ID method
   name.  After calling this function TYPE_FN_FIELD_STUB will be
   cleared for each signature and TYPE_FN_FIELDLIST_NAME will be
   correct.

   This function unfortunately can not die until stabs do.  */

void
check_stub_method_group (struct type *type, int method_id)
{
  int len = TYPE_FN_FIELDLIST_LENGTH (type, method_id);
  struct fn_field *f = TYPE_FN_FIELDLIST1 (type, method_id);

  for (int j = 0; j < len; j++)
    {
      if (TYPE_FN_FIELD_STUB (f, j))
	check_stub_method (type, method_id, j);
    }
}

/* Ensure it is in .rodata (if available) by working around GCC PR 44690.  */
const struct cplus_struct_type cplus_struct_default = { };

void
allocate_cplus_struct_type (struct type *type)
{
  if (HAVE_CPLUS_STRUCT (type))
    /* Structure was already allocated.  Nothing more to do.  */
    return;

  TYPE_SPECIFIC_FIELD (type) = TYPE_SPECIFIC_CPLUS_STUFF;
  TYPE_RAW_CPLUS_SPECIFIC (type) = (struct cplus_struct_type *)
    TYPE_ZALLOC (type, sizeof (struct cplus_struct_type));
  *(TYPE_RAW_CPLUS_SPECIFIC (type)) = cplus_struct_default;
  set_type_vptr_fieldno (type, -1);
}

const struct gnat_aux_type gnat_aux_default =
  { NULL };

/* Set the TYPE's type-specific kind to TYPE_SPECIFIC_GNAT_STUFF,
   and allocate the associated gnat-specific data.  The gnat-specific
   data is also initialized to gnat_aux_default.  */

void
allocate_gnat_aux_type (struct type *type)
{
  TYPE_SPECIFIC_FIELD (type) = TYPE_SPECIFIC_GNAT_STUFF;
  TYPE_GNAT_SPECIFIC (type) = (struct gnat_aux_type *)
    TYPE_ZALLOC (type, sizeof (struct gnat_aux_type));
  *(TYPE_GNAT_SPECIFIC (type)) = gnat_aux_default;
}

/* Helper function to verify floating-point format and size.
   BIT is the type size in bits; if BIT equals -1, the size is
   determined by the floatformat.  Returns size to be used.  */

static int
verify_floatformat (int bit, const struct floatformat *floatformat)
{
  gdb_assert (floatformat != NULL);

  if (bit == -1)
    bit = floatformat->totalsize;

  gdb_assert (bit >= 0);
  gdb_assert (bit >= floatformat->totalsize);

  return bit;
}

/* Return the floating-point format for a floating-point variable of
   type TYPE.  */

const struct floatformat *
floatformat_from_type (const struct type *type)
{
  gdb_assert (type->code () == TYPE_CODE_FLT);
  gdb_assert (TYPE_FLOATFORMAT (type));
  return TYPE_FLOATFORMAT (type);
}

/* See gdbtypes.h.  */

struct type *
init_integer_type (type_allocator &alloc,
		   int bit, int unsigned_p, const char *name)
{
  struct type *t;

  t = alloc.new_type (TYPE_CODE_INT, bit, name);
  if (unsigned_p)
    t->set_is_unsigned (true);

  TYPE_SPECIFIC_FIELD (t) = TYPE_SPECIFIC_INT;
  TYPE_MAIN_TYPE (t)->type_specific.int_stuff.bit_size = bit;
  TYPE_MAIN_TYPE (t)->type_specific.int_stuff.bit_offset = 0;

  return t;
}

/* See gdbtypes.h.  */

struct type *
init_character_type (type_allocator &alloc,
		     int bit, int unsigned_p, const char *name)
{
  struct type *t;

  t = alloc.new_type (TYPE_CODE_CHAR, bit, name);
  if (unsigned_p)
    t->set_is_unsigned (true);

  return t;
}

/* See gdbtypes.h.  */

struct type *
init_boolean_type (type_allocator &alloc,
		   int bit, int unsigned_p, const char *name)
{
  struct type *t;

  t = alloc.new_type (TYPE_CODE_BOOL, bit, name);
  if (unsigned_p)
    t->set_is_unsigned (true);

  TYPE_SPECIFIC_FIELD (t) = TYPE_SPECIFIC_INT;
  TYPE_MAIN_TYPE (t)->type_specific.int_stuff.bit_size = bit;
  TYPE_MAIN_TYPE (t)->type_specific.int_stuff.bit_offset = 0;

  return t;
}

/* See gdbtypes.h.  */

struct type *
init_float_type (type_allocator &alloc,
		 int bit, const char *name,
		 const struct floatformat **floatformats,
		 enum bfd_endian byte_order)
{
  if (byte_order == BFD_ENDIAN_UNKNOWN)
    {
      struct gdbarch *gdbarch = alloc.arch ();
      byte_order = gdbarch_byte_order (gdbarch);
    }
  const struct floatformat *fmt = floatformats[byte_order];
  struct type *t;

  bit = verify_floatformat (bit, fmt);
  t = alloc.new_type (TYPE_CODE_FLT, bit, name);
  TYPE_FLOATFORMAT (t) = fmt;

  return t;
}

/* See gdbtypes.h.  */

struct type *
init_decfloat_type (type_allocator &alloc, int bit, const char *name)
{
  return alloc.new_type (TYPE_CODE_DECFLOAT, bit, name);
}

/* Return true if init_complex_type can be called with TARGET_TYPE.  */

bool
can_create_complex_type (struct type *target_type)
{
  return (target_type->code () == TYPE_CODE_INT
	  || target_type->code () == TYPE_CODE_FLT);
}

/* Allocate a TYPE_CODE_COMPLEX type structure.  NAME is the type
   name.  TARGET_TYPE is the component type.  */

struct type *
init_complex_type (const char *name, struct type *target_type)
{
  struct type *t;

  gdb_assert (can_create_complex_type (target_type));

  if (TYPE_MAIN_TYPE (target_type)->flds_bnds.complex_type == nullptr)
    {
      if (name == nullptr && target_type->name () != nullptr)
	{
	  /* No zero-initialization required, initialized by strcpy/strcat
	     below.  */
	  char *new_name
	    = (char *) TYPE_ALLOC (target_type,
				   strlen (target_type->name ())
				   + strlen ("_Complex ") + 1);
	  strcpy (new_name, "_Complex ");
	  strcat (new_name, target_type->name ());
	  name = new_name;
	}

      t = type_allocator (target_type).new_type ();
      set_type_code (t, TYPE_CODE_COMPLEX);
      t->set_length (2 * target_type->length ());
      t->set_name (name);

      t->set_target_type (target_type);
      TYPE_MAIN_TYPE (target_type)->flds_bnds.complex_type = t;
    }

  return TYPE_MAIN_TYPE (target_type)->flds_bnds.complex_type;
}

/* See gdbtypes.h.  */

struct type *
init_pointer_type (type_allocator &alloc,
		   int bit, const char *name, struct type *target_type)
{
  struct type *t;

  t = alloc.new_type (TYPE_CODE_PTR, bit, name);
  t->set_target_type (target_type);
  t->set_is_unsigned (true);
  return t;
}

/* Allocate a TYPE_CODE_FIXED_POINT type structure associated with OBJFILE.
   BIT is the pointer type size in bits.
   UNSIGNED_P should be nonzero if the type is unsigned.
   NAME is the type name.  */

struct type *
init_fixed_point_type (type_allocator &alloc,
		       int bit, int unsigned_p, const char *name)
{
  struct type *t;

  t = alloc.new_type (TYPE_CODE_FIXED_POINT, bit, name);
  if (unsigned_p)
    t->set_is_unsigned (true);

  return t;
}

/* See gdbtypes.h.  */

unsigned
type_raw_align (struct type *type)
{
  if (type->align_log2 != 0)
    return 1 << (type->align_log2 - 1);
  return 0;
}

/* See gdbtypes.h.  */

unsigned
type_align (struct type *type)
{
  /* Check alignment provided in the debug information.  */
  unsigned raw_align = type_raw_align (type);
  if (raw_align != 0)
    return raw_align;

  /* Allow the architecture to provide an alignment.  */
  ULONGEST align = gdbarch_type_align (type->arch (), type);
  if (align != 0)
    return align;

  switch (type->code ())
    {
    case TYPE_CODE_PTR:
    case TYPE_CODE_FUNC:
    case TYPE_CODE_FLAGS:
    case TYPE_CODE_INT:
    case TYPE_CODE_RANGE:
    case TYPE_CODE_FLT:
    case TYPE_CODE_ENUM:
    case TYPE_CODE_REF:
    case TYPE_CODE_RVALUE_REF:
    case TYPE_CODE_CHAR:
    case TYPE_CODE_BOOL:
    case TYPE_CODE_DECFLOAT:
    case TYPE_CODE_METHODPTR:
    case TYPE_CODE_MEMBERPTR:
      align = type_length_units (check_typedef (type));
      break;

    case TYPE_CODE_ARRAY:
    case TYPE_CODE_COMPLEX:
    case TYPE_CODE_TYPEDEF:
      align = type_align (type->target_type ());
      break;

    case TYPE_CODE_STRUCT:
    case TYPE_CODE_UNION:
      {
	int number_of_non_static_fields = 0;
	for (unsigned i = 0; i < type->num_fields (); ++i)
	  {
	    if (!type->field (i).is_static ())
	      {
		number_of_non_static_fields++;
		ULONGEST f_align = type_align (type->field (i).type ());
		if (f_align == 0)
		  {
		    /* Don't pretend we know something we don't.  */
		    align = 0;
		    break;
		  }
		if (f_align > align)
		  align = f_align;
	      }
	  }
	/* A struct with no fields, or with only static fields has an
	   alignment of 1.  */
	if (number_of_non_static_fields == 0)
	  align = 1;
      }
      break;

    case TYPE_CODE_SET:
    case TYPE_CODE_STRING:
      /* Not sure what to do here, and these can't appear in C or C++
	 anyway.  */
      break;

    case TYPE_CODE_VOID:
      align = 1;
      break;

    case TYPE_CODE_ERROR:
    case TYPE_CODE_METHOD:
    default:
      break;
    }

  if ((align & (align - 1)) != 0)
    {
      /* Not a power of 2, so pass.  */
      align = 0;
    }

  return align;
}

/* See gdbtypes.h.  */

bool
set_type_align (struct type *type, ULONGEST align)
{
  /* Must be a power of 2.  Zero is ok.  */
  gdb_assert ((align & (align - 1)) == 0);

  unsigned result = 0;
  while (align != 0)
    {
      ++result;
      align >>= 1;
    }

  if (result >= (1 << TYPE_ALIGN_BITS))
    return false;

  type->align_log2 = result;
  return true;
}


/* Queries on types.  */

int
can_dereference (struct type *t)
{
  /* FIXME: Should we return true for references as well as
     pointers?  */
  t = check_typedef (t);
  return
    (t != NULL
     && t->code () == TYPE_CODE_PTR
     && t->target_type ()->code () != TYPE_CODE_VOID);
}

int
is_integral_type (struct type *t)
{
  t = check_typedef (t);
  return
    ((t != NULL)
     && !is_fixed_point_type (t)
     && ((t->code () == TYPE_CODE_INT)
	 || (t->code () == TYPE_CODE_ENUM)
	 || (t->code () == TYPE_CODE_FLAGS)
	 || (t->code () == TYPE_CODE_CHAR)
	 || (t->code () == TYPE_CODE_RANGE)
	 || (t->code () == TYPE_CODE_BOOL)));
}

int
is_floating_type (struct type *t)
{
  t = check_typedef (t);
  return
    ((t != NULL)
     && ((t->code () == TYPE_CODE_FLT)
	 || (t->code () == TYPE_CODE_DECFLOAT)));
}

/* Return true if TYPE is scalar.  */

int
is_scalar_type (struct type *type)
{
  type = check_typedef (type);

  if (is_fixed_point_type (type))
    return 0; /* Implemented as a scalar, but more like a floating point.  */

  switch (type->code ())
    {
    case TYPE_CODE_ARRAY:
    case TYPE_CODE_STRUCT:
    case TYPE_CODE_UNION:
    case TYPE_CODE_SET:
    case TYPE_CODE_STRING:
      return 0;
    default:
      return 1;
    }
}

/* Return true if T is scalar, or a composite type which in practice has
   the memory layout of a scalar type.  E.g., an array or struct with only
   one scalar element inside it, or a union with only scalar elements.  */

int
is_scalar_type_recursive (struct type *t)
{
  t = check_typedef (t);

  if (is_scalar_type (t))
    return 1;
  /* Are we dealing with an array or string of known dimensions?  */
  else if ((t->code () == TYPE_CODE_ARRAY
	    || t->code () == TYPE_CODE_STRING) && t->num_fields () == 1
	   && t->index_type ()->code () == TYPE_CODE_RANGE)
    {
      LONGEST low_bound, high_bound;
      struct type *elt_type = check_typedef (t->target_type ());

      if (get_discrete_bounds (t->index_type (), &low_bound, &high_bound))
	return (high_bound == low_bound
		&& is_scalar_type_recursive (elt_type));
      else
	return 0;
    }
  /* Are we dealing with a struct with one element?  */
  else if (t->code () == TYPE_CODE_STRUCT && t->num_fields () == 1)
    return is_scalar_type_recursive (t->field (0).type ());
  else if (t->code () == TYPE_CODE_UNION)
    {
      int i, n = t->num_fields ();

      /* If all elements of the union are scalar, then the union is scalar.  */
      for (i = 0; i < n; i++)
	if (!is_scalar_type_recursive (t->field (i).type ()))
	  return 0;

      return 1;
    }

  return 0;
}

/* Return true is T is a class or a union.  False otherwise.  */

int
class_or_union_p (const struct type *t)
{
  return (t->code () == TYPE_CODE_STRUCT
	  || t->code () == TYPE_CODE_UNION);
}

/* A helper function which returns true if types A and B represent the
   "same" class type.  This is true if the types have the same main
   type, or the same name.  */

int
class_types_same_p (const struct type *a, const struct type *b)
{
  return (TYPE_MAIN_TYPE (a) == TYPE_MAIN_TYPE (b)
	  || (a->name () && b->name ()
	      && !strcmp (a->name (), b->name ())));
}

/* If BASE is an ancestor of DCLASS return the distance between them.
   otherwise return -1;
   eg:

   class A {};
   class B: public A {};
   class C: public B {};
   class D: C {};

   distance_to_ancestor (A, A, 0) = 0
   distance_to_ancestor (A, B, 0) = 1
   distance_to_ancestor (A, C, 0) = 2
   distance_to_ancestor (A, D, 0) = 3

   If PUBLIC is 1 then only public ancestors are considered,
   and the function returns the distance only if BASE is a public ancestor
   of DCLASS.
   Eg:

   distance_to_ancestor (A, D, 1) = -1.  */

static int
distance_to_ancestor (struct type *base, struct type *dclass, int is_public)
{
  int i;
  int d;

  base = check_typedef (base);
  dclass = check_typedef (dclass);

  if (class_types_same_p (base, dclass))
    return 0;

  for (i = 0; i < TYPE_N_BASECLASSES (dclass); i++)
    {
      if (is_public && ! BASETYPE_VIA_PUBLIC (dclass, i))
	continue;

      d = distance_to_ancestor (base, TYPE_BASECLASS (dclass, i), is_public);
      if (d >= 0)
	return 1 + d;
    }

  return -1;
}

/* Check whether BASE is an ancestor or base class or DCLASS
   Return 1 if so, and 0 if not.
   Note: If BASE and DCLASS are of the same type, this function
   will return 1. So for some class A, is_ancestor (A, A) will
   return 1.  */

int
is_ancestor (struct type *base, struct type *dclass)
{
  return distance_to_ancestor (base, dclass, 0) >= 0;
}

/* Like is_ancestor, but only returns true when BASE is a public
   ancestor of DCLASS.  */

int
is_public_ancestor (struct type *base, struct type *dclass)
{
  return distance_to_ancestor (base, dclass, 1) >= 0;
}

/* A helper function for is_unique_ancestor.  */

static int
is_unique_ancestor_worker (struct type *base, struct type *dclass,
			   int *offset,
			   const gdb_byte *valaddr, int embedded_offset,
			   CORE_ADDR address, struct value *val)
{
  int i, count = 0;

  base = check_typedef (base);
  dclass = check_typedef (dclass);

  for (i = 0; i < TYPE_N_BASECLASSES (dclass) && count < 2; ++i)
    {
      struct type *iter;
      int this_offset;

      iter = check_typedef (TYPE_BASECLASS (dclass, i));

      this_offset = baseclass_offset (dclass, i, valaddr, embedded_offset,
				      address, val);

      if (class_types_same_p (base, iter))
	{
	  /* If this is the first subclass, set *OFFSET and set count
	     to 1.  Otherwise, if this is at the same offset as
	     previous instances, do nothing.  Otherwise, increment
	     count.  */
	  if (*offset == -1)
	    {
	      *offset = this_offset;
	      count = 1;
	    }
	  else if (this_offset == *offset)
	    {
	      /* Nothing.  */
	    }
	  else
	    ++count;
	}
      else
	count += is_unique_ancestor_worker (base, iter, offset,
					    valaddr,
					    embedded_offset + this_offset,
					    address, val);
    }

  return count;
}

/* Like is_ancestor, but only returns true if BASE is a unique base
   class of the type of VAL.  */

int
is_unique_ancestor (struct type *base, struct value *val)
{
  int offset = -1;

  return is_unique_ancestor_worker (base, val->type (), &offset,
				    val->contents_for_printing ().data (),
				    val->embedded_offset (),
				    val->address (), val) == 1;
}

/* See gdbtypes.h.  */

enum bfd_endian
type_byte_order (const struct type *type)
{
  bfd_endian byteorder = gdbarch_byte_order (type->arch ());
  if (type->endianity_is_not_default ())
    {
      if (byteorder == BFD_ENDIAN_BIG)
	return BFD_ENDIAN_LITTLE;
      else
	{
	  gdb_assert (byteorder == BFD_ENDIAN_LITTLE);
	  return BFD_ENDIAN_BIG;
	}
    }

  return byteorder;
}

/* See gdbtypes.h.  */

bool
is_nocall_function (const struct type *type)
{
  if (type->code () != TYPE_CODE_FUNC && type->code () != TYPE_CODE_METHOD)
    return false;

  return TYPE_CALLING_CONVENTION (type) == DW_CC_nocall;
}


/* Overload resolution.  */

/* Return the sum of the rank of A with the rank of B.  */

struct rank
sum_ranks (struct rank a, struct rank b)
{
  struct rank c;
  c.rank = a.rank + b.rank;
  c.subrank = a.subrank + b.subrank;
  return c;
}

/* Compare rank A and B and return:
   0 if a = b
   1 if a is better than b
  -1 if b is better than a.  */

int
compare_ranks (struct rank a, struct rank b)
{
  if (a.rank == b.rank)
    {
      if (a.subrank == b.subrank)
	return 0;
      if (a.subrank < b.subrank)
	return 1;
      if (a.subrank > b.subrank)
	return -1;
    }

  if (a.rank < b.rank)
    return 1;

  /* a.rank > b.rank */
  return -1;
}

/* Functions for overload resolution begin here.  */

/* Compare two badness vectors A and B and return the result.
   0 => A and B are identical
   1 => A and B are incomparable
   2 => A is better than B
   3 => A is worse than B  */

int
compare_badness (const badness_vector &a, const badness_vector &b)
{
  int i;
  int tmp;
  /* Any positives in comparison? */
  bool found_pos = false;
  /* Any negatives in comparison? */
  bool found_neg = false;
  /* Did A have any INVALID_CONVERSION entries.  */
  bool a_invalid = false;
  /* Did B have any INVALID_CONVERSION entries.  */
  bool b_invalid = false;

  /* differing sizes => incomparable */
  if (a.size () != b.size ())
    return 1;

  /* Subtract b from a */
  for (i = 0; i < a.size (); i++)
    {
      tmp = compare_ranks (b[i], a[i]);
      if (tmp > 0)
	found_pos = true;
      else if (tmp < 0)
	found_neg = true;
      if (a[i].rank >= INVALID_CONVERSION)
	a_invalid = true;
      if (b[i].rank >= INVALID_CONVERSION)
	b_invalid = true;
    }

  /* B will only be considered better than or incomparable to A if
     they both have invalid entries, or if neither does.  That is, if
     A has only valid entries, and B has an invalid entry, then A will
     be considered better than B, even if B happens to be better for
     some parameter.  */
  if (a_invalid != b_invalid)
    {
      if (a_invalid)
	return 3;		/* A > B */
      return 2;			/* A < B */
    }
  else if (found_pos)
    {
      if (found_neg)
	return 1;		/* incomparable */
      else
	return 3;		/* A > B */
    }
  else
    /* no positives */
    {
      if (found_neg)
	return 2;		/* A < B */
      else
	return 0;		/* A == B */
    }
}

/* Rank a function by comparing its parameter types (PARMS), to the
   types of an argument list (ARGS).  Return the badness vector.  This
   has ARGS.size() + 1 entries.  */

badness_vector
rank_function (gdb::array_view<type *> parms,
	       gdb::array_view<value *> args,
	       bool varargs)
{
  /* add 1 for the length-match rank.  */
  badness_vector bv;
  bv.reserve (1 + args.size ());

  /* First compare the lengths of the supplied lists.
     If there is a mismatch, set it to a high value.  */

  /* pai/1997-06-03 FIXME: when we have debug info about default
     arguments and ellipsis parameter lists, we should consider those
     and rank the length-match more finely.  */

  bv.push_back ((args.size () != parms.size ()
		 && (! varargs || args.size () < parms.size ()))
		? LENGTH_MISMATCH_BADNESS
		: EXACT_MATCH_BADNESS);

  /* Now rank all the parameters of the candidate function.  */
  size_t min_len = std::min (parms.size (), args.size ());

  for (size_t i = 0; i < min_len; i++)
    bv.push_back (rank_one_type (parms[i], args[i]->type (),
				 args[i]));

  /* If more arguments than parameters, add dummy entries.  */
  for (size_t i = min_len; i < args.size (); i++)
    bv.push_back (varargs ? VARARG_BADNESS : TOO_FEW_PARAMS_BADNESS);

  return bv;
}

/* Compare the names of two integer types, assuming that any sign
   qualifiers have been checked already.  We do it this way because
   there may be an "int" in the name of one of the types.  */

static int
integer_types_same_name_p (const char *first, const char *second)
{
  int first_p, second_p;

  /* If both are shorts, return 1; if neither is a short, keep
     checking.  */
  first_p = (strstr (first, "short") != NULL);
  second_p = (strstr (second, "short") != NULL);
  if (first_p && second_p)
    return 1;
  if (first_p || second_p)
    return 0;

  /* Likewise for long.  */
  first_p = (strstr (first, "long") != NULL);
  second_p = (strstr (second, "long") != NULL);
  if (first_p && second_p)
    return 1;
  if (first_p || second_p)
    return 0;

  /* Likewise for char.  */
  first_p = (strstr (first, "char") != NULL);
  second_p = (strstr (second, "char") != NULL);
  if (first_p && second_p)
    return 1;
  if (first_p || second_p)
    return 0;

  /* They must both be ints.  */
  return 1;
}

/* Compares type A to type B.  Returns true if they represent the same
   type, false otherwise.  */

bool
types_equal (struct type *a, struct type *b)
{
  /* Identical type pointers.  */
  /* However, this still doesn't catch all cases of same type for b
     and a.  The reason is that builtin types are different from
     the same ones constructed from the object.  */
  if (a == b)
    return true;

  /* Resolve typedefs */
  if (a->code () == TYPE_CODE_TYPEDEF)
    a = check_typedef (a);
  if (b->code () == TYPE_CODE_TYPEDEF)
    b = check_typedef (b);

  /* Check if identical after resolving typedefs.  */
  if (a == b)
    return true;

  /* If after resolving typedefs a and b are not of the same type
     code then they are not equal.  */
  if (a->code () != b->code ())
    return false;

  /* If a and b are both pointers types or both reference types then
     they are equal of the same type iff the objects they refer to are
     of the same type.  */
  if (a->code () == TYPE_CODE_PTR
      || a->code () == TYPE_CODE_REF)
    return types_equal (a->target_type (),
			b->target_type ());

  /* Well, damnit, if the names are exactly the same, I'll say they
     are exactly the same.  This happens when we generate method
     stubs.  The types won't point to the same address, but they
     really are the same.  */

  if (a->name () && b->name ()
      && strcmp (a->name (), b->name ()) == 0)
    return true;

  /* Two function types are equal if their argument and return types
     are equal.  */
  if (a->code () == TYPE_CODE_FUNC)
    {
      int i;

      if (a->num_fields () != b->num_fields ())
	return false;
      
      if (!types_equal (a->target_type (), b->target_type ()))
	return false;

      for (i = 0; i < a->num_fields (); ++i)
	if (!types_equal (a->field (i).type (), b->field (i).type ()))
	  return false;

      return true;
    }

  /* Two array types are the same if they have the same element types
     and array bounds.  */
  if (a->code () == TYPE_CODE_ARRAY)
    {
      if (!types_equal (a->target_type (), b->target_type ()))
	return false;

      if (*a->bounds () != *b->bounds ())
	return false;

      return true;
    }

  return false;
}

/* Deep comparison of types.  */

/* An entry in the type-equality bcache.  */

struct type_equality_entry
{
  type_equality_entry (struct type *t1, struct type *t2)
    : type1 (t1),
      type2 (t2)
  {
  }

  struct type *type1, *type2;
};

/* A helper function to compare two strings.  Returns true if they are
   the same, false otherwise.  Handles NULLs properly.  */

static bool
compare_maybe_null_strings (const char *s, const char *t)
{
  if (s == NULL || t == NULL)
    return s == t;
  return strcmp (s, t) == 0;
}

/* A helper function for check_types_worklist that checks two types for
   "deep" equality.  Returns true if the types are considered the
   same, false otherwise.  */

static bool
check_types_equal (struct type *type1, struct type *type2,
		   std::vector<type_equality_entry> *worklist)
{
  type1 = check_typedef (type1);
  type2 = check_typedef (type2);

  if (type1 == type2)
    return true;

  if (type1->code () != type2->code ()
      || type1->length () != type2->length ()
      || type1->is_unsigned () != type2->is_unsigned ()
      || type1->has_no_signedness () != type2->has_no_signedness ()
      || type1->endianity_is_not_default () != type2->endianity_is_not_default ()
      || type1->has_varargs () != type2->has_varargs ()
      || type1->is_vector () != type2->is_vector ()
      || TYPE_NOTTEXT (type1) != TYPE_NOTTEXT (type2)
      || type1->instance_flags () != type2->instance_flags ()
      || type1->num_fields () != type2->num_fields ())
    return false;

  if (!compare_maybe_null_strings (type1->name (), type2->name ()))
    return false;
  if (!compare_maybe_null_strings (type1->name (), type2->name ()))
    return false;

  if (type1->code () == TYPE_CODE_RANGE)
    {
      if (*type1->bounds () != *type2->bounds ())
	return false;
    }
  else
    {
      int i;

      for (i = 0; i < type1->num_fields (); ++i)
	{
	  const struct field *field1 = &type1->field (i);
	  const struct field *field2 = &type2->field (i);

	  if (field1->is_artificial () != field2->is_artificial ()
	      || field1->bitsize () != field2->bitsize ()
	      || field1->loc_kind () != field2->loc_kind ())
	    return false;
	  if (!compare_maybe_null_strings (field1->name (), field2->name ()))
	    return false;
	  switch (field1->loc_kind ())
	    {
	    case FIELD_LOC_KIND_BITPOS:
	      if (field1->loc_bitpos () != field2->loc_bitpos ())
		return false;
	      break;
	    case FIELD_LOC_KIND_ENUMVAL:
	      if (field1->loc_enumval () != field2->loc_enumval ())
		return false;
	      /* Don't compare types of enum fields, because they don't
		 have a type.  */
	      continue;
	    case FIELD_LOC_KIND_PHYSADDR:
	      if (field1->loc_physaddr () != field2->loc_physaddr ())
		return false;
	      break;
	    case FIELD_LOC_KIND_PHYSNAME:
	      if (!compare_maybe_null_strings (field1->loc_physname (),
					       field2->loc_physname ()))
		return false;
	      break;
	    case FIELD_LOC_KIND_DWARF_BLOCK:
	      {
		struct dwarf2_locexpr_baton *block1, *block2;

		block1 = field1->loc_dwarf_block ();
		block2 = field2->loc_dwarf_block ();
		if (block1->per_cu != block2->per_cu
		    || block1->size != block2->size
		    || memcmp (block1->data, block2->data, block1->size) != 0)
		  return false;
	      }
	      break;
	    default:
	      internal_error (_("Unsupported field kind "
						    "%d by check_types_equal"),
			      field1->loc_kind ());
	    }

	  worklist->emplace_back (field1->type (), field2->type ());
	}
    }

  if (type1->target_type () != NULL)
    {
      if (type2->target_type () == NULL)
	return false;

      worklist->emplace_back (type1->target_type (),
			      type2->target_type ());
    }
  else if (type2->target_type () != NULL)
    return false;

  return true;
}

/* Check types on a worklist for equality.  Returns false if any pair
   is not equal, true if they are all considered equal.  */

static bool
check_types_worklist (std::vector<type_equality_entry> *worklist,
		      gdb::bcache *cache)
{
  while (!worklist->empty ())
    {
      bool added;

      struct type_equality_entry entry = std::move (worklist->back ());
      worklist->pop_back ();

      /* If the type pair has already been visited, we know it is
	 ok.  */
      cache->insert (&entry, sizeof (entry), &added);
      if (!added)
	continue;

      if (!check_types_equal (entry.type1, entry.type2, worklist))
	return false;
    }

  return true;
}

/* Return true if types TYPE1 and TYPE2 are equal, as determined by a
   "deep comparison".  Otherwise return false.  */

bool
types_deeply_equal (struct type *type1, struct type *type2)
{
  std::vector<type_equality_entry> worklist;

  gdb_assert (type1 != NULL && type2 != NULL);

  /* Early exit for the simple case.  */
  if (type1 == type2)
    return true;

  gdb::bcache cache;
  worklist.emplace_back (type1, type2);
  return check_types_worklist (&worklist, &cache);
}

/* Allocated status of type TYPE.  Return zero if type TYPE is allocated.
   Otherwise return one.  */

int
type_not_allocated (const struct type *type)
{
  struct dynamic_prop *prop = TYPE_ALLOCATED_PROP (type);

  return prop != nullptr && prop->is_constant () && prop->const_val () == 0;
}

/* Associated status of type TYPE.  Return zero if type TYPE is associated.
   Otherwise return one.  */

int
type_not_associated (const struct type *type)
{
  struct dynamic_prop *prop = TYPE_ASSOCIATED_PROP (type);

  return prop != nullptr && prop->is_constant () && prop->const_val () == 0;
}

/* rank_one_type helper for when PARM's type code is TYPE_CODE_PTR.  */

static struct rank
rank_one_type_parm_ptr (struct type *parm, struct type *arg, struct value *value)
{
  struct rank rank = {0,0};

  switch (arg->code ())
    {
    case TYPE_CODE_PTR:

      /* Allowed pointer conversions are:
	 (a) pointer to void-pointer conversion.  */
      if (parm->target_type ()->code () == TYPE_CODE_VOID)
	return VOID_PTR_CONVERSION_BADNESS;

      /* (b) pointer to ancestor-pointer conversion.  */
      rank.subrank = distance_to_ancestor (parm->target_type (),
					   arg->target_type (),
					   0);
      if (rank.subrank >= 0)
	return sum_ranks (BASE_PTR_CONVERSION_BADNESS, rank);

      return INCOMPATIBLE_TYPE_BADNESS;
    case TYPE_CODE_ARRAY:
      {
	struct type *t1 = parm->target_type ();
	struct type *t2 = arg->target_type ();

	if (types_equal (t1, t2))
	  {
	    /* Make sure they are CV equal.  */
	    if (TYPE_CONST (t1) != TYPE_CONST (t2))
	      rank.subrank |= CV_CONVERSION_CONST;
	    if (TYPE_VOLATILE (t1) != TYPE_VOLATILE (t2))
	      rank.subrank |= CV_CONVERSION_VOLATILE;
	    if (rank.subrank != 0)
	      return sum_ranks (CV_CONVERSION_BADNESS, rank);
	    return EXACT_MATCH_BADNESS;
	  }
	return INCOMPATIBLE_TYPE_BADNESS;
      }
    case TYPE_CODE_FUNC:
      return rank_one_type (parm->target_type (), arg, NULL);
    case TYPE_CODE_INT:
      if (value != NULL && value->type ()->code () == TYPE_CODE_INT)
	{
	  if (value_as_long (value) == 0)
	    {
	      /* Null pointer conversion: allow it to be cast to a pointer.
		 [4.10.1 of C++ standard draft n3290]  */
	      return NULL_POINTER_CONVERSION_BADNESS;
	    }
	  else
	    {
	      /* If type checking is disabled, allow the conversion.  */
	      if (!strict_type_checking)
		return NS_INTEGER_POINTER_CONVERSION_BADNESS;
	    }
	}
      [[fallthrough]];
    case TYPE_CODE_ENUM:
    case TYPE_CODE_FLAGS:
    case TYPE_CODE_CHAR:
    case TYPE_CODE_RANGE:
    case TYPE_CODE_BOOL:
    default:
      return INCOMPATIBLE_TYPE_BADNESS;
    }
}

/* rank_one_type helper for when PARM's type code is TYPE_CODE_ARRAY.  */

static struct rank
rank_one_type_parm_array (struct type *parm, struct type *arg, struct value *value)
{
  switch (arg->code ())
    {
    case TYPE_CODE_PTR:
    case TYPE_CODE_ARRAY:
      return rank_one_type (parm->target_type (),
			    arg->target_type (), NULL);
    default:
      return INCOMPATIBLE_TYPE_BADNESS;
    }
}

/* rank_one_type helper for when PARM's type code is TYPE_CODE_FUNC.  */

static struct rank
rank_one_type_parm_func (struct type *parm, struct type *arg, struct value *value)
{
  switch (arg->code ())
    {
    case TYPE_CODE_PTR:	/* funcptr -> func */
      return rank_one_type (parm, arg->target_type (), NULL);
    default:
      return INCOMPATIBLE_TYPE_BADNESS;
    }
}

/* rank_one_type helper for when PARM's type code is TYPE_CODE_INT.  */

static struct rank
rank_one_type_parm_int (struct type *parm, struct type *arg, struct value *value)
{
  switch (arg->code ())
    {
    case TYPE_CODE_INT:
      if (arg->length () == parm->length ())
	{
	  /* Deal with signed, unsigned, and plain chars and
	     signed and unsigned ints.  */
	  if (parm->has_no_signedness ())
	    {
	      /* This case only for character types.  */
	      if (arg->has_no_signedness ())
		return EXACT_MATCH_BADNESS;	/* plain char -> plain char */
	      else		/* signed/unsigned char -> plain char */
		return INTEGER_CONVERSION_BADNESS;
	    }
	  else if (parm->is_unsigned ())
	    {
	      if (arg->is_unsigned ())
		{
		  /* unsigned int -> unsigned int, or
		     unsigned long -> unsigned long */
		  if (integer_types_same_name_p (parm->name (),
						 arg->name ()))
		    return EXACT_MATCH_BADNESS;
		  else if (integer_types_same_name_p (arg->name (),
						      "int")
			   && integer_types_same_name_p (parm->name (),
							 "long"))
		    /* unsigned int -> unsigned long */
		    return INTEGER_PROMOTION_BADNESS;
		  else
		    /* unsigned long -> unsigned int */
		    return INTEGER_CONVERSION_BADNESS;
		}
	      else
		{
		  if (integer_types_same_name_p (arg->name (),
						 "long")
		      && integer_types_same_name_p (parm->name (),
						    "int"))
		    /* signed long -> unsigned int */
		    return INTEGER_CONVERSION_BADNESS;
		  else
		    /* signed int/long -> unsigned int/long */
		    return INTEGER_CONVERSION_BADNESS;
		}
	    }
	  else if (!arg->has_no_signedness () && !arg->is_unsigned ())
	    {
	      if (integer_types_same_name_p (parm->name (),
					     arg->name ()))
		return EXACT_MATCH_BADNESS;
	      else if (integer_types_same_name_p (arg->name (),
						  "int")
		       && integer_types_same_name_p (parm->name (),
						     "long"))
		return INTEGER_PROMOTION_BADNESS;
	      else
		return INTEGER_CONVERSION_BADNESS;
	    }
	  else
	    return INTEGER_CONVERSION_BADNESS;
	}
      else if (arg->length () < parm->length ())
	return INTEGER_PROMOTION_BADNESS;
      else
	return INTEGER_CONVERSION_BADNESS;
    case TYPE_CODE_ENUM:
    case TYPE_CODE_FLAGS:
    case TYPE_CODE_CHAR:
    case TYPE_CODE_RANGE:
    case TYPE_CODE_BOOL:
      if (arg->is_declared_class ())
	return INCOMPATIBLE_TYPE_BADNESS;
      return INTEGER_PROMOTION_BADNESS;
    case TYPE_CODE_FLT:
      return INT_FLOAT_CONVERSION_BADNESS;
    case TYPE_CODE_PTR:
      return NS_POINTER_CONVERSION_BADNESS;
    default:
      return INCOMPATIBLE_TYPE_BADNESS;
    }
}

/* rank_one_type helper for when PARM's type code is TYPE_CODE_ENUM.  */

static struct rank
rank_one_type_parm_enum (struct type *parm, struct type *arg, struct value *value)
{
  switch (arg->code ())
    {
    case TYPE_CODE_INT:
    case TYPE_CODE_CHAR:
    case TYPE_CODE_RANGE:
    case TYPE_CODE_BOOL:
    case TYPE_CODE_ENUM:
      if (parm->is_declared_class () || arg->is_declared_class ())
	return INCOMPATIBLE_TYPE_BADNESS;
      return INTEGER_CONVERSION_BADNESS;
    case TYPE_CODE_FLT:
      return INT_FLOAT_CONVERSION_BADNESS;
    default:
      return INCOMPATIBLE_TYPE_BADNESS;
    }
}

/* rank_one_type helper for when PARM's type code is TYPE_CODE_CHAR.  */

static struct rank
rank_one_type_parm_char (struct type *parm, struct type *arg, struct value *value)
{
  switch (arg->code ())
    {
    case TYPE_CODE_RANGE:
    case TYPE_CODE_BOOL:
    case TYPE_CODE_ENUM:
      if (arg->is_declared_class ())
	return INCOMPATIBLE_TYPE_BADNESS;
      return INTEGER_CONVERSION_BADNESS;
    case TYPE_CODE_FLT:
      return INT_FLOAT_CONVERSION_BADNESS;
    case TYPE_CODE_INT:
      if (arg->length () > parm->length ())
	return INTEGER_CONVERSION_BADNESS;
      else if (arg->length () < parm->length ())
	return INTEGER_PROMOTION_BADNESS;
      [[fallthrough]];
    case TYPE_CODE_CHAR:
      /* Deal with signed, unsigned, and plain chars for C++ and
	 with int cases falling through from previous case.  */
      if (parm->has_no_signedness ())
	{
	  if (arg->has_no_signedness ())
	    return EXACT_MATCH_BADNESS;
	  else
	    return INTEGER_CONVERSION_BADNESS;
	}
      else if (parm->is_unsigned ())
	{
	  if (arg->is_unsigned ())
	    return EXACT_MATCH_BADNESS;
	  else
	    return INTEGER_PROMOTION_BADNESS;
	}
      else if (!arg->has_no_signedness () && !arg->is_unsigned ())
	return EXACT_MATCH_BADNESS;
      else
	return INTEGER_CONVERSION_BADNESS;
    default:
      return INCOMPATIBLE_TYPE_BADNESS;
    }
}

/* rank_one_type helper for when PARM's type code is TYPE_CODE_RANGE.  */

static struct rank
rank_one_type_parm_range (struct type *parm, struct type *arg, struct value *value)
{
  switch (arg->code ())
    {
    case TYPE_CODE_INT:
    case TYPE_CODE_CHAR:
    case TYPE_CODE_RANGE:
    case TYPE_CODE_BOOL:
    case TYPE_CODE_ENUM:
      return INTEGER_CONVERSION_BADNESS;
    case TYPE_CODE_FLT:
      return INT_FLOAT_CONVERSION_BADNESS;
    default:
      return INCOMPATIBLE_TYPE_BADNESS;
    }
}

/* rank_one_type helper for when PARM's type code is TYPE_CODE_BOOL.  */

static struct rank
rank_one_type_parm_bool (struct type *parm, struct type *arg, struct value *value)
{
  switch (arg->code ())
    {
      /* n3290 draft, section 4.12.1 (conv.bool):

	 "A prvalue of arithmetic, unscoped enumeration, pointer, or
	 pointer to member type can be converted to a prvalue of type
	 bool.  A zero value, null pointer value, or null member pointer
	 value is converted to false; any other value is converted to
	 true.  A prvalue of type std::nullptr_t can be converted to a
	 prvalue of type bool; the resulting value is false."  */
    case TYPE_CODE_INT:
    case TYPE_CODE_CHAR:
    case TYPE_CODE_ENUM:
    case TYPE_CODE_FLT:
    case TYPE_CODE_MEMBERPTR:
    case TYPE_CODE_PTR:
      return BOOL_CONVERSION_BADNESS;
    case TYPE_CODE_RANGE:
      return INCOMPATIBLE_TYPE_BADNESS;
    case TYPE_CODE_BOOL:
      return EXACT_MATCH_BADNESS;
    default:
      return INCOMPATIBLE_TYPE_BADNESS;
    }
}

/* rank_one_type helper for when PARM's type code is TYPE_CODE_FLOAT.  */

static struct rank
rank_one_type_parm_float (struct type *parm, struct type *arg, struct value *value)
{
  switch (arg->code ())
    {
    case TYPE_CODE_FLT:
      if (arg->length () < parm->length ())
	return FLOAT_PROMOTION_BADNESS;
      else if (arg->length () == parm->length ())
	return EXACT_MATCH_BADNESS;
      else
	return FLOAT_CONVERSION_BADNESS;
    case TYPE_CODE_INT:
    case TYPE_CODE_BOOL:
    case TYPE_CODE_ENUM:
    case TYPE_CODE_RANGE:
    case TYPE_CODE_CHAR:
      return INT_FLOAT_CONVERSION_BADNESS;
    default:
      return INCOMPATIBLE_TYPE_BADNESS;
    }
}

/* rank_one_type helper for when PARM's type code is TYPE_CODE_COMPLEX.  */

static struct rank
rank_one_type_parm_complex (struct type *parm, struct type *arg, struct value *value)
{
  switch (arg->code ())
    {		/* Strictly not needed for C++, but...  */
    case TYPE_CODE_FLT:
      return FLOAT_PROMOTION_BADNESS;
    case TYPE_CODE_COMPLEX:
      return EXACT_MATCH_BADNESS;
    default:
      return INCOMPATIBLE_TYPE_BADNESS;
    }
}

/* rank_one_type helper for when PARM's type code is TYPE_CODE_STRUCT.  */

static struct rank
rank_one_type_parm_struct (struct type *parm, struct type *arg, struct value *value)
{
  struct rank rank = {0, 0};

  switch (arg->code ())
    {
    case TYPE_CODE_STRUCT:
      /* Check for derivation */
      rank.subrank = distance_to_ancestor (parm, arg, 0);
      if (rank.subrank >= 0)
	return sum_ranks (BASE_CONVERSION_BADNESS, rank);
      [[fallthrough]];
    default:
      return INCOMPATIBLE_TYPE_BADNESS;
    }
}

/* rank_one_type helper for when PARM's type code is TYPE_CODE_SET.  */

static struct rank
rank_one_type_parm_set (struct type *parm, struct type *arg, struct value *value)
{
  switch (arg->code ())
    {
      /* Not in C++ */
    case TYPE_CODE_SET:
      return rank_one_type (parm->field (0).type (),
			    arg->field (0).type (), NULL);
    default:
      return INCOMPATIBLE_TYPE_BADNESS;
    }
}

/* Compare one type (PARM) for compatibility with another (ARG).
 * PARM is intended to be the parameter type of a function; and
 * ARG is the supplied argument's type.  This function tests if
 * the latter can be converted to the former.
 * VALUE is the argument's value or NULL if none (or called recursively)
 *
 * Return 0 if they are identical types;
 * Otherwise, return an integer which corresponds to how compatible
 * PARM is to ARG.  The higher the return value, the worse the match.
 * Generally the "bad" conversions are all uniformly assigned
 * INVALID_CONVERSION.  */

struct rank
rank_one_type (struct type *parm, struct type *arg, struct value *value)
{
  struct rank rank = {0,0};

  /* Resolve typedefs */
  if (parm->code () == TYPE_CODE_TYPEDEF)
    parm = check_typedef (parm);
  if (arg->code () == TYPE_CODE_TYPEDEF)
    arg = check_typedef (arg);

  if (TYPE_IS_REFERENCE (parm) && value != NULL)
    {
      if (value->lval () == not_lval)
	{
	  /* Rvalues should preferably bind to rvalue references or const
	     lvalue references.  */
	  if (parm->code () == TYPE_CODE_RVALUE_REF)
	    rank.subrank = REFERENCE_CONVERSION_RVALUE;
	  else if (TYPE_CONST (parm->target_type ()))
	    rank.subrank = REFERENCE_CONVERSION_CONST_LVALUE;
	  else
	    return INCOMPATIBLE_TYPE_BADNESS;
	  return sum_ranks (rank, REFERENCE_CONVERSION_BADNESS);
	}
      else
	{
	  /* It's illegal to pass an lvalue as an rvalue.  */
	  if (parm->code () == TYPE_CODE_RVALUE_REF)
	    return INCOMPATIBLE_TYPE_BADNESS;
	}
    }

  if (types_equal (parm, arg))
    {
      struct type *t1 = parm;
      struct type *t2 = arg;

      /* For pointers and references, compare target type.  */
      if (parm->is_pointer_or_reference ())
	{
	  t1 = parm->target_type ();
	  t2 = arg->target_type ();
	}

      /* Make sure they are CV equal, too.  */
      if (TYPE_CONST (t1) != TYPE_CONST (t2))
	rank.subrank |= CV_CONVERSION_CONST;
      if (TYPE_VOLATILE (t1) != TYPE_VOLATILE (t2))
	rank.subrank |= CV_CONVERSION_VOLATILE;
      if (rank.subrank != 0)
	return sum_ranks (CV_CONVERSION_BADNESS, rank);
      return EXACT_MATCH_BADNESS;
    }

  /* See through references, since we can almost make non-references
     references.  */

  if (TYPE_IS_REFERENCE (arg))
    return (sum_ranks (rank_one_type (parm, arg->target_type (), NULL),
		       REFERENCE_SEE_THROUGH_BADNESS));
  if (TYPE_IS_REFERENCE (parm))
    return (sum_ranks (rank_one_type (parm->target_type (), arg, NULL),
		       REFERENCE_SEE_THROUGH_BADNESS));
  if (overload_debug)
    {
      /* Debugging only.  */
      gdb_printf (gdb_stderr,
		  "------ Arg is %s [%d], parm is %s [%d]\n",
		  arg->name (), arg->code (),
		  parm->name (), parm->code ());
    }

  /* x -> y means arg of type x being supplied for parameter of type y.  */

  switch (parm->code ())
    {
    case TYPE_CODE_PTR:
      return rank_one_type_parm_ptr (parm, arg, value);
    case TYPE_CODE_ARRAY:
      return rank_one_type_parm_array (parm, arg, value);
    case TYPE_CODE_FUNC:
      return rank_one_type_parm_func (parm, arg, value);
    case TYPE_CODE_INT:
      return rank_one_type_parm_int (parm, arg, value);
    case TYPE_CODE_ENUM:
      return rank_one_type_parm_enum (parm, arg, value);
    case TYPE_CODE_CHAR:
      return rank_one_type_parm_char (parm, arg, value);
    case TYPE_CODE_RANGE:
      return rank_one_type_parm_range (parm, arg, value);
    case TYPE_CODE_BOOL:
      return rank_one_type_parm_bool (parm, arg, value);
    case TYPE_CODE_FLT:
      return rank_one_type_parm_float (parm, arg, value);
    case TYPE_CODE_COMPLEX:
      return rank_one_type_parm_complex (parm, arg, value);
    case TYPE_CODE_STRUCT:
      return rank_one_type_parm_struct (parm, arg, value);
    case TYPE_CODE_SET:
      return rank_one_type_parm_set (parm, arg, value);
    default:
      return INCOMPATIBLE_TYPE_BADNESS;
    }				/* switch (arg->code ()) */
}

/* End of functions for overload resolution.  */


/* Note the first arg should be the "this" pointer, we may not want to
   include it since we may get into a infinitely recursive
   situation.  */

static void
print_args (struct field *args, int nargs, int spaces)
{
  if (args != NULL)
    {
      int i;

      for (i = 0; i < nargs; i++)
	{
	  gdb_printf
	    ("%*s[%d] name '%s'\n", spaces, "", i,
	     args[i].name () != NULL ? args[i].name () : "<NULL>");
	  recursive_dump_type (args[i].type (), spaces + 2);
	}
    }
}

static void
dump_fn_fieldlists (struct type *type, int spaces)
{
  int method_idx;
  int overload_idx;
  struct fn_field *f;

  gdb_printf ("%*sfn_fieldlists %s\n", spaces, "",
	      host_address_to_string (TYPE_FN_FIELDLISTS (type)));
  for (method_idx = 0; method_idx < TYPE_NFN_FIELDS (type); method_idx++)
    {
      f = TYPE_FN_FIELDLIST1 (type, method_idx);
      gdb_printf
	("%*s[%d] name '%s' (%s) length %d\n", spaces + 2, "",
	 method_idx,
	 TYPE_FN_FIELDLIST_NAME (type, method_idx),
	 host_address_to_string (TYPE_FN_FIELDLIST_NAME (type, method_idx)),
	 TYPE_FN_FIELDLIST_LENGTH (type, method_idx));
      for (overload_idx = 0;
	   overload_idx < TYPE_FN_FIELDLIST_LENGTH (type, method_idx);
	   overload_idx++)
	{
	  gdb_printf
	    ("%*s[%d] physname '%s' (%s)\n",
	     spaces + 4, "", overload_idx,
	     TYPE_FN_FIELD_PHYSNAME (f, overload_idx),
	     host_address_to_string (TYPE_FN_FIELD_PHYSNAME (f,
							     overload_idx)));
	  gdb_printf
	    ("%*stype %s\n", spaces + 8, "",
	     host_address_to_string (TYPE_FN_FIELD_TYPE (f, overload_idx)));

	  recursive_dump_type (TYPE_FN_FIELD_TYPE (f, overload_idx),
			       spaces + 8 + 2);

	  gdb_printf
	    ("%*sargs %s\n", spaces + 8, "",
	     host_address_to_string (TYPE_FN_FIELD_ARGS (f, overload_idx)));
	  print_args (TYPE_FN_FIELD_ARGS (f, overload_idx),
		      TYPE_FN_FIELD_TYPE (f, overload_idx)->num_fields (),
		      spaces + 8 + 2);
	  gdb_printf
	    ("%*sfcontext %s\n", spaces + 8, "",
	     host_address_to_string (TYPE_FN_FIELD_FCONTEXT (f,
							     overload_idx)));

	  gdb_printf ("%*sis_const %d\n", spaces + 8, "",
		      TYPE_FN_FIELD_CONST (f, overload_idx));
	  gdb_printf ("%*sis_volatile %d\n", spaces + 8, "",
		      TYPE_FN_FIELD_VOLATILE (f, overload_idx));
	  gdb_printf ("%*sis_private %d\n", spaces + 8, "",
		      TYPE_FN_FIELD_PRIVATE (f, overload_idx));
	  gdb_printf ("%*sis_protected %d\n", spaces + 8, "",
		      TYPE_FN_FIELD_PROTECTED (f, overload_idx));
	  gdb_printf ("%*sis_stub %d\n", spaces + 8, "",
		      TYPE_FN_FIELD_STUB (f, overload_idx));
	  gdb_printf ("%*sdefaulted %d\n", spaces + 8, "",
		      TYPE_FN_FIELD_DEFAULTED (f, overload_idx));
	  gdb_printf ("%*sis_deleted %d\n", spaces + 8, "",
		      TYPE_FN_FIELD_DELETED (f, overload_idx));
	  gdb_printf ("%*svoffset %u\n", spaces + 8, "",
		      TYPE_FN_FIELD_VOFFSET (f, overload_idx));
	}
    }
}

static void
print_cplus_stuff (struct type *type, int spaces)
{
  gdb_printf ("%*svptr_fieldno %d\n", spaces, "",
	      TYPE_VPTR_FIELDNO (type));
  gdb_printf ("%*svptr_basetype %s\n", spaces, "",
	      host_address_to_string (TYPE_VPTR_BASETYPE (type)));
  if (TYPE_VPTR_BASETYPE (type) != NULL)
    recursive_dump_type (TYPE_VPTR_BASETYPE (type), spaces + 2);

  gdb_printf ("%*sn_baseclasses %d\n", spaces, "",
	      TYPE_N_BASECLASSES (type));
  gdb_printf ("%*snfn_fields %d\n", spaces, "",
	      TYPE_NFN_FIELDS (type));
  if (TYPE_NFN_FIELDS (type) > 0)
    {
      dump_fn_fieldlists (type, spaces);
    }

  gdb_printf ("%*scalling_convention %d\n", spaces, "",
	      TYPE_CPLUS_CALLING_CONVENTION (type));
}

/* Print the contents of the TYPE's type_specific union, assuming that
   its type-specific kind is TYPE_SPECIFIC_GNAT_STUFF.  */

static void
print_gnat_stuff (struct type *type, int spaces)
{
  struct type *descriptive_type = TYPE_DESCRIPTIVE_TYPE (type);

  if (descriptive_type == NULL)
    gdb_printf ("%*sno descriptive type\n", spaces + 2, "");
  else
    {
      gdb_printf ("%*sdescriptive type\n", spaces + 2, "");
      recursive_dump_type (descriptive_type, spaces + 4);
    }
}

/* Print the contents of the TYPE's type_specific union, assuming that
   its type-specific kind is TYPE_SPECIFIC_FIXED_POINT.  */

static void
print_fixed_point_type_info (struct type *type, int spaces)
{
  gdb_printf ("%*sscaling factor: %s\n", spaces + 2, "",
	      type->fixed_point_scaling_factor ().str ().c_str ());
}

static struct obstack dont_print_type_obstack;

/* Print the dynamic_prop PROP.  */

static void
dump_dynamic_prop (dynamic_prop const& prop)
{
  switch (prop.kind ())
    {
    case PROP_CONST:
      gdb_printf ("%s", plongest (prop.const_val ()));
      break;
    case PROP_UNDEFINED:
      gdb_printf ("(undefined)");
      break;
    case PROP_LOCEXPR:
    case PROP_LOCLIST:
      gdb_printf ("(dynamic)");
      break;
    default:
      gdb_assert_not_reached ("unhandled prop kind");
      break;
    }
}

/* Return a string that represents a type code.  */
static const char *
type_code_name (type_code code)
{
  switch (code)
    {
#define OP(X) case X: return # X;
#include "type-codes.def"
#undef OP

    case TYPE_CODE_UNDEF:
      return "TYPE_CODE_UNDEF";
    }

  gdb_assert_not_reached ("unhandled type_code");
}

void
recursive_dump_type (struct type *type, int spaces)
{
  int idx;

  if (spaces == 0)
    obstack_begin (&dont_print_type_obstack, 0);

  if (type->num_fields () > 0
      || (HAVE_CPLUS_STRUCT (type) && TYPE_NFN_FIELDS (type) > 0))
    {
      struct type **first_dont_print
	= (struct type **) obstack_base (&dont_print_type_obstack);

      int i = (struct type **) 
	obstack_next_free (&dont_print_type_obstack) - first_dont_print;

      while (--i >= 0)
	{
	  if (type == first_dont_print[i])
	    {
	      gdb_printf ("%*stype node %s", spaces, "",
			  host_address_to_string (type));
	      gdb_printf (_(" <same as already seen type>\n"));
	      return;
	    }
	}

      obstack_ptr_grow (&dont_print_type_obstack, type);
    }

  gdb_printf ("%*stype node %s\n", spaces, "",
	      host_address_to_string (type));
  gdb_printf ("%*sname '%s' (%s)\n", spaces, "",
	      type->name () ? type->name () : "<NULL>",
	      host_address_to_string (type->name ()));
  gdb_printf ("%*scode 0x%x ", spaces, "", type->code ());
  gdb_printf ("(%s)", type_code_name (type->code ()));
  gdb_puts ("\n");
  gdb_printf ("%*slength %s\n", spaces, "",
	      pulongest (type->length ()));
  if (type->is_objfile_owned ())
    gdb_printf ("%*sobjfile %s\n", spaces, "",
		host_address_to_string (type->objfile_owner ()));
  else
    gdb_printf ("%*sgdbarch %s\n", spaces, "",
		host_address_to_string (type->arch_owner ()));
  gdb_printf ("%*starget_type %s\n", spaces, "",
	      host_address_to_string (type->target_type ()));
  if (type->target_type () != NULL)
    {
      recursive_dump_type (type->target_type (), spaces + 2);
    }
  gdb_printf ("%*spointer_type %s\n", spaces, "",
	      host_address_to_string (TYPE_POINTER_TYPE (type)));
  gdb_printf ("%*sreference_type %s\n", spaces, "",
	      host_address_to_string (TYPE_REFERENCE_TYPE (type)));
  gdb_printf ("%*stype_chain %s\n", spaces, "",
	      host_address_to_string (TYPE_CHAIN (type)));
  gdb_printf ("%*sinstance_flags 0x%x", spaces, "", 
	      (unsigned) type->instance_flags ());
  if (TYPE_CONST (type))
    {
      gdb_puts (" TYPE_CONST");
    }
  if (TYPE_VOLATILE (type))
    {
      gdb_puts (" TYPE_VOLATILE");
    }
  if (TYPE_CODE_SPACE (type))
    {
      gdb_puts (" TYPE_CODE_SPACE");
    }
  if (TYPE_DATA_SPACE (type))
    {
      gdb_puts (" TYPE_DATA_SPACE");
    }
  if (TYPE_ADDRESS_CLASS_1 (type))
    {
      gdb_puts (" TYPE_ADDRESS_CLASS_1");
    }
  if (TYPE_ADDRESS_CLASS_2 (type))
    {
      gdb_puts (" TYPE_ADDRESS_CLASS_2");
    }
  if (TYPE_RESTRICT (type))
    {
      gdb_puts (" TYPE_RESTRICT");
    }
  if (TYPE_ATOMIC (type))
    {
      gdb_puts (" TYPE_ATOMIC");
    }
  gdb_puts ("\n");

  gdb_printf ("%*sflags", spaces, "");
  if (type->is_unsigned ())
    {
      gdb_puts (" TYPE_UNSIGNED");
    }
  if (type->has_no_signedness ())
    {
      gdb_puts (" TYPE_NOSIGN");
    }
  if (type->endianity_is_not_default ())
    {
      gdb_puts (" TYPE_ENDIANITY_NOT_DEFAULT");
    }
  if (type->is_stub ())
    {
      gdb_puts (" TYPE_STUB");
    }
  if (type->target_is_stub ())
    {
      gdb_puts (" TYPE_TARGET_STUB");
    }
  if (type->is_prototyped ())
    {
      gdb_puts (" TYPE_PROTOTYPED");
    }
  if (type->has_varargs ())
    {
      gdb_puts (" TYPE_VARARGS");
    }
  /* This is used for things like AltiVec registers on ppc.  Gcc emits
     an attribute for the array type, which tells whether or not we
     have a vector, instead of a regular array.  */
  if (type->is_vector ())
    {
      gdb_puts (" TYPE_VECTOR");
    }
  if (type->is_fixed_instance ())
    {
      gdb_puts (" TYPE_FIXED_INSTANCE");
    }
  if (type->stub_is_supported ())
    {
      gdb_puts (" TYPE_STUB_SUPPORTED");
    }
  if (TYPE_NOTTEXT (type))
    {
      gdb_puts (" TYPE_NOTTEXT");
    }
  gdb_puts ("\n");
  gdb_printf ("%*snfields %d ", spaces, "", type->num_fields ());
  if (TYPE_ASSOCIATED_PROP (type) != nullptr
      || TYPE_ALLOCATED_PROP (type) != nullptr)
    {
      gdb_printf ("%*s", spaces, "");
      if (TYPE_ASSOCIATED_PROP (type) != nullptr)
	{
	  gdb_printf ("associated ");
	  dump_dynamic_prop (*TYPE_ASSOCIATED_PROP (type));
	}
      if (TYPE_ALLOCATED_PROP (type) != nullptr)
	{
	  if (TYPE_ASSOCIATED_PROP (type) != nullptr)
	    gdb_printf ("  ");
	  gdb_printf ("allocated ");
	  dump_dynamic_prop (*TYPE_ALLOCATED_PROP (type));
	}
      gdb_printf ("\n");
    }
  gdb_printf ("%s\n", host_address_to_string (type->fields ()));
  for (idx = 0; idx < type->num_fields (); idx++)
    {
      field &fld = type->field (idx);
      if (type->code () == TYPE_CODE_ENUM)
	gdb_printf ("%*s[%d] enumval %s type ", spaces + 2, "",
		    idx, plongest (fld.loc_enumval ()));
      else
	gdb_printf ("%*s[%d] bitpos %s bitsize %d type ", spaces + 2, "",
		    idx, plongest (fld.loc_bitpos ()),
		    fld.bitsize ());
      gdb_printf ("%s name '%s' (%s)",
		  host_address_to_string (fld.type ()),
		  fld.name () != NULL
		  ? fld.name ()
		  : "<NULL>",
		  host_address_to_string (fld.name ()));
      if (fld.is_virtual ())
	gdb_printf (" virtual");

      if (fld.is_private ())
	gdb_printf (" private");
      else if (fld.is_protected ())
	gdb_printf (" protected");
      else if (fld.is_ignored ())
	gdb_printf (" ignored");

      gdb_printf ("\n");
      if (fld.type () != NULL)
	{
	  recursive_dump_type (fld.type (), spaces + 4);
	}
    }
  if (type->code () == TYPE_CODE_RANGE)
    {
      gdb_printf ("%*slow ", spaces, "");
      dump_dynamic_prop (type->bounds ()->low);
      gdb_printf ("  high ");
      dump_dynamic_prop (type->bounds ()->high);
      gdb_printf ("\n");
    }

  switch (TYPE_SPECIFIC_FIELD (type))
    {
    case TYPE_SPECIFIC_CPLUS_STUFF:
      gdb_printf ("%*scplus_stuff %s\n", spaces, "",
		  host_address_to_string (TYPE_CPLUS_SPECIFIC (type)));
      print_cplus_stuff (type, spaces);
      break;

    case TYPE_SPECIFIC_GNAT_STUFF:
      gdb_printf ("%*sgnat_stuff %s\n", spaces, "",
		  host_address_to_string (TYPE_GNAT_SPECIFIC (type)));
      print_gnat_stuff (type, spaces);
      break;

    case TYPE_SPECIFIC_FLOATFORMAT:
      gdb_printf ("%*sfloatformat ", spaces, "");
      if (TYPE_FLOATFORMAT (type) == NULL
	  || TYPE_FLOATFORMAT (type)->name == NULL)
	gdb_puts ("(null)");
      else
	gdb_puts (TYPE_FLOATFORMAT (type)->name);
      gdb_puts ("\n");
      break;

    case TYPE_SPECIFIC_FUNC:
      gdb_printf ("%*scalling_convention %d\n", spaces, "",
		  TYPE_CALLING_CONVENTION (type));
      /* tail_call_list is not printed.  */
      break;

    case TYPE_SPECIFIC_SELF_TYPE:
      gdb_printf ("%*sself_type %s\n", spaces, "",
		  host_address_to_string (TYPE_SELF_TYPE (type)));
      break;

    case TYPE_SPECIFIC_FIXED_POINT:
      gdb_printf ("%*sfixed_point_info ", spaces, "");
      print_fixed_point_type_info (type, spaces);
      gdb_puts ("\n");
      break;

    case TYPE_SPECIFIC_INT:
      if (type->bit_size_differs_p ())
	{
	  unsigned bit_size = type->bit_size ();
	  unsigned bit_off = type->bit_offset ();
	  gdb_printf ("%*s bit size = %u, bit offset = %u\n", spaces, "",
		      bit_size, bit_off);
	}
      break;
    }

  if (spaces == 0)
    obstack_free (&dont_print_type_obstack, NULL);
}

/* Trivial helpers for the libiberty hash table, for mapping one
   type to another.  */

struct type_pair
{
  type_pair (struct type *old_, struct type *newobj_)
    : old (old_), newobj (newobj_)
  {}

  struct type * const old, * const newobj;
};

static hashval_t
type_pair_hash (const void *item)
{
  const struct type_pair *pair = (const struct type_pair *) item;

  return htab_hash_pointer (pair->old);
}

static int
type_pair_eq (const void *item_lhs, const void *item_rhs)
{
  const struct type_pair *lhs = (const struct type_pair *) item_lhs;
  const struct type_pair *rhs = (const struct type_pair *) item_rhs;

  return lhs->old == rhs->old;
}

/* Allocate the hash table used by copy_type_recursive to walk
   types without duplicates.  */

htab_up
create_copied_types_hash ()
{
  return htab_up (htab_create_alloc (1, type_pair_hash, type_pair_eq,
				     htab_delete_entry<type_pair>,
				     xcalloc, xfree));
}

/* Recursively copy (deep copy) a dynamic attribute list of a type.  */

static struct dynamic_prop_list *
copy_dynamic_prop_list (struct obstack *storage,
			struct dynamic_prop_list *list)
{
  struct dynamic_prop_list *copy = list;
  struct dynamic_prop_list **node_ptr = &copy;

  while (*node_ptr != NULL)
    {
      struct dynamic_prop_list *node_copy;

      node_copy = ((struct dynamic_prop_list *)
		   obstack_copy (storage, *node_ptr,
				 sizeof (struct dynamic_prop_list)));
      node_copy->prop = (*node_ptr)->prop;
      *node_ptr = node_copy;

      node_ptr = &node_copy->next;
    }

  return copy;
}

/* Recursively copy (deep copy) TYPE, if it is associated with
   OBJFILE.  Return a new type owned by the gdbarch associated with the type, a
   saved type if we have already visited TYPE (using COPIED_TYPES), or TYPE if
   it is not associated with OBJFILE.  */

struct type *
copy_type_recursive (struct type *type, htab_t copied_types)
{
  void **slot;
  struct type *new_type;

  if (!type->is_objfile_owned ())
    return type;

  struct type_pair pair (type, nullptr);

  slot = htab_find_slot (copied_types, &pair, INSERT);
  if (*slot != NULL)
    return ((struct type_pair *) *slot)->newobj;

  new_type = type_allocator (type->arch ()).new_type ();

  /* We must add the new type to the hash table immediately, in case
     we encounter this type again during a recursive call below.  */
  struct type_pair *stored = new type_pair (type, new_type);

  *slot = stored;

  /* Copy the common fields of types.  For the main type, we simply
     copy the entire thing and then update specific fields as needed.  */
  *TYPE_MAIN_TYPE (new_type) = *TYPE_MAIN_TYPE (type);

  new_type->set_owner (type->arch ());

  if (type->name ())
    new_type->set_name (xstrdup (type->name ()));

  new_type->set_instance_flags (type->instance_flags ());
  new_type->set_length (type->length ());

  /* Copy the fields.  */
  if (type->num_fields ())
    {
      int i, nfields;

      nfields = type->num_fields ();
      new_type->alloc_fields (type->num_fields ());

      for (i = 0; i < nfields; i++)
	{
	  new_type->field (i).set_is_artificial
	    (type->field (i).is_artificial ());
	  new_type->field (i).set_bitsize (type->field (i).bitsize ());
	  if (type->field (i).type ())
	    new_type->field (i).set_type
	      (copy_type_recursive (type->field (i).type (), copied_types));
	  if (type->field (i).name ())
	    new_type->field (i).set_name (xstrdup (type->field (i).name ()));

	  switch (type->field (i).loc_kind ())
	    {
	    case FIELD_LOC_KIND_BITPOS:
	      new_type->field (i).set_loc_bitpos (type->field (i).loc_bitpos ());
	      break;
	    case FIELD_LOC_KIND_ENUMVAL:
	      new_type->field (i).set_loc_enumval (type->field (i).loc_enumval ());
	      break;
	    case FIELD_LOC_KIND_PHYSADDR:
	      new_type->field (i).set_loc_physaddr
		(type->field (i).loc_physaddr ());
	      break;
	    case FIELD_LOC_KIND_PHYSNAME:
	      new_type->field (i).set_loc_physname
		(xstrdup (type->field (i).loc_physname ()));
	      break;
	    case FIELD_LOC_KIND_DWARF_BLOCK:
	      new_type->field (i).set_loc_dwarf_block
		(type->field (i).loc_dwarf_block ());
	      break;
	    default:
	      internal_error (_("Unexpected type field location kind: %d"),
			      type->field (i).loc_kind ());
	    }
	}
    }

  /* For range types, copy the bounds information.  */
  if (type->code () == TYPE_CODE_RANGE)
    {
      range_bounds *bounds
	= ((struct range_bounds *) TYPE_ALLOC
	   (new_type, sizeof (struct range_bounds)));

      *bounds = *type->bounds ();
      new_type->set_bounds (bounds);
    }

  if (type->main_type->dyn_prop_list != NULL)
    new_type->main_type->dyn_prop_list
      = copy_dynamic_prop_list (gdbarch_obstack (new_type->arch_owner ()),
				type->main_type->dyn_prop_list);


  /* Copy pointers to other types.  */
  if (type->target_type ())
    new_type->set_target_type
      (copy_type_recursive (type->target_type (), copied_types));

  /* Maybe copy the type_specific bits.

     NOTE drow/2005-12-09: We do not copy the C++-specific bits like
     base classes and methods.  There's no fundamental reason why we
     can't, but at the moment it is not needed.  */

  switch (TYPE_SPECIFIC_FIELD (type))
    {
    case TYPE_SPECIFIC_NONE:
      break;
    case TYPE_SPECIFIC_FUNC:
      INIT_FUNC_SPECIFIC (new_type);
      TYPE_CALLING_CONVENTION (new_type) = TYPE_CALLING_CONVENTION (type);
      TYPE_NO_RETURN (new_type) = TYPE_NO_RETURN (type);
      TYPE_TAIL_CALL_LIST (new_type) = NULL;
      break;
    case TYPE_SPECIFIC_FLOATFORMAT:
      TYPE_FLOATFORMAT (new_type) = TYPE_FLOATFORMAT (type);
      break;
    case TYPE_SPECIFIC_CPLUS_STUFF:
      INIT_CPLUS_SPECIFIC (new_type);
      break;
    case TYPE_SPECIFIC_GNAT_STUFF:
      INIT_GNAT_SPECIFIC (new_type);
      break;
    case TYPE_SPECIFIC_SELF_TYPE:
      set_type_self_type (new_type,
			  copy_type_recursive (TYPE_SELF_TYPE (type),
					       copied_types));
      break;
    case TYPE_SPECIFIC_FIXED_POINT:
      INIT_FIXED_POINT_SPECIFIC (new_type);
      new_type->fixed_point_info ().scaling_factor
	= type->fixed_point_info ().scaling_factor;
      break;
    case TYPE_SPECIFIC_INT:
      TYPE_SPECIFIC_FIELD (new_type) = TYPE_SPECIFIC_INT;
      TYPE_MAIN_TYPE (new_type)->type_specific.int_stuff
	= TYPE_MAIN_TYPE (type)->type_specific.int_stuff;
      break;

    default:
      gdb_assert_not_reached ("bad type_specific_kind");
    }

  return new_type;
}

/* Make a copy of the given TYPE, except that the pointer & reference
   types are not preserved.  */

struct type *
copy_type (const struct type *type)
{
  struct type *new_type = type_allocator (type).new_type ();
  new_type->set_instance_flags (type->instance_flags ());
  new_type->set_length (type->length ());
  memcpy (TYPE_MAIN_TYPE (new_type), TYPE_MAIN_TYPE (type),
	  sizeof (struct main_type));
  if (type->main_type->dyn_prop_list != NULL)
    {
      struct obstack *storage = (type->is_objfile_owned ()
				 ? &type->objfile_owner ()->objfile_obstack
				 : gdbarch_obstack (type->arch_owner ()));
      new_type->main_type->dyn_prop_list
	= copy_dynamic_prop_list (storage, type->main_type->dyn_prop_list);
    }

  return new_type;
}

/* Helper functions to initialize architecture-specific types.  */

/* Allocate a TYPE_CODE_FLAGS type structure associated with GDBARCH.
   NAME is the type name.  BIT is the size of the flag word in bits.  */

struct type *
arch_flags_type (struct gdbarch *gdbarch, const char *name, int bit)
{
  struct type *type;

  type = type_allocator (gdbarch).new_type (TYPE_CODE_FLAGS, bit, name);
  type->set_is_unsigned (true);
  /* Pre-allocate enough space assuming every field is one bit.  */
  type->alloc_fields (bit);
  type->set_num_fields (0);

  return type;
}

/* Add field to TYPE_CODE_FLAGS type TYPE to indicate the bit at
   position BITPOS is called NAME.  Pass NAME as "" for fields that
   should not be printed.  */

void
append_flags_type_field (struct type *type, int start_bitpos, int nr_bits,
			 struct type *field_type, const char *name)
{
  int type_bitsize = type->length () * TARGET_CHAR_BIT;
  int field_nr = type->num_fields ();

  gdb_assert (type->code () == TYPE_CODE_FLAGS);
  gdb_assert (type->num_fields () + 1 <= type_bitsize);
  gdb_assert (start_bitpos >= 0 && start_bitpos < type_bitsize);
  gdb_assert (nr_bits >= 1 && (start_bitpos + nr_bits) <= type_bitsize);
  gdb_assert (name != NULL);

  type->set_num_fields (type->num_fields () + 1);
  type->field (field_nr).set_name (xstrdup (name));
  type->field (field_nr).set_type (field_type);
  type->field (field_nr).set_loc_bitpos (start_bitpos);
  type->field (field_nr).set_bitsize (nr_bits);
}

/* Special version of append_flags_type_field to add a flag field.
   Add field to TYPE_CODE_FLAGS type TYPE to indicate the bit at
   position BITPOS is called NAME.  */

void
append_flags_type_flag (struct type *type, int bitpos, const char *name)
{
  append_flags_type_field (type, bitpos, 1,
			   builtin_type (type->arch ())->builtin_bool,
			   name);
}

/* Allocate a TYPE_CODE_STRUCT or TYPE_CODE_UNION type structure (as
   specified by CODE) associated with GDBARCH.  NAME is the type name.  */

struct type *
arch_composite_type (struct gdbarch *gdbarch, const char *name,
		     enum type_code code)
{
  struct type *t;

  gdb_assert (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION);
  t = type_allocator (gdbarch).new_type (code, 0, NULL);
  t->set_name (name);
  INIT_CPLUS_SPECIFIC (t);
  return t;
}

/* Add new field with name NAME and type FIELD to composite type T.
   Do not set the field's position or adjust the type's length;
   the caller should do so.  Return the new field.  */

struct field *
append_composite_type_field_raw (struct type *t, const char *name,
				 struct type *field)
{
  struct field *f;

  t->set_num_fields (t->num_fields () + 1);
  t->set_fields (XRESIZEVEC (struct field, t->fields (),
			     t->num_fields ()));
  f = &t->field (t->num_fields () - 1);
  memset (f, 0, sizeof f[0]);
  f[0].set_type (field);
  f[0].set_name (name);
  return f;
}

/* Add new field with name NAME and type FIELD to composite type T.
   ALIGNMENT (if non-zero) specifies the minimum field alignment.  */

void
append_composite_type_field_aligned (struct type *t, const char *name,
				     struct type *field, int alignment)
{
  struct field *f = append_composite_type_field_raw (t, name, field);

  if (t->code () == TYPE_CODE_UNION)
    {
      if (t->length () < field->length ())
	t->set_length (field->length ());
    }
  else if (t->code () == TYPE_CODE_STRUCT)
    {
      t->set_length (t->length () + field->length ());
      if (t->num_fields () > 1)
	{
	  f->set_loc_bitpos
	    (f[-1].loc_bitpos ()
	     + (f[-1].type ()->length () * TARGET_CHAR_BIT));

	  if (alignment)
	    {
	      int left;

	      alignment *= TARGET_CHAR_BIT;
	      left = f[0].loc_bitpos () % alignment;

	      if (left)
		{
		  f->set_loc_bitpos (f[0].loc_bitpos () + (alignment - left));
		  t->set_length
		    (t->length () + (alignment - left) / TARGET_CHAR_BIT);
		}
	    }
	}
    }
}

/* Add new field with name NAME and type FIELD to composite type T.  */

void
append_composite_type_field (struct type *t, const char *name,
			     struct type *field)
{
  append_composite_type_field_aligned (t, name, field, 0);
}



/* We manage the lifetimes of fixed_point_type_info objects by
   attaching them to the objfile.  Currently, these objects are
   modified during construction, and GMP does not provide a way to
   hash the contents of an mpq_t; so it's a bit of a pain to hash-cons
   them.  If we did do this, they could be moved to the per-BFD and
   shared across objfiles.  */
typedef std::vector<std::unique_ptr<fixed_point_type_info>>
    fixed_point_type_storage;

/* Key used for managing the storage of fixed-point type info.  */
static const struct registry<objfile>::key<fixed_point_type_storage>
    fixed_point_objfile_key;

/* See gdbtypes.h.  */

void
allocate_fixed_point_type_info (struct type *type)
{
  auto up = std::make_unique<fixed_point_type_info> ();
  fixed_point_type_info *info;

  if (type->is_objfile_owned ())
    {
      fixed_point_type_storage *storage
	= fixed_point_objfile_key.get (type->objfile_owner ());
      if (storage == nullptr)
	storage = fixed_point_objfile_key.emplace (type->objfile_owner ());
      info = up.get ();
      storage->push_back (std::move (up));
    }
  else
    {
      /* We just leak the memory, because that's what we do generally
	 for non-objfile-attached types.  */
      info = up.release ();
    }

  type->set_fixed_point_info (info);
}

/* See gdbtypes.h.  */

bool
is_fixed_point_type (struct type *type)
{
  while (check_typedef (type)->code () == TYPE_CODE_RANGE)
    type = check_typedef (type)->target_type ();
  type = check_typedef (type);

  return type->code () == TYPE_CODE_FIXED_POINT;
}

/* See gdbtypes.h.  */

struct type *
type::fixed_point_type_base_type ()
{
  struct type *type = this;

  while (check_typedef (type)->code () == TYPE_CODE_RANGE)
    type = check_typedef (type)->target_type ();
  type = check_typedef (type);

  gdb_assert (type->code () == TYPE_CODE_FIXED_POINT);
  return type;
}

/* See gdbtypes.h.  */

const gdb_mpq &
type::fixed_point_scaling_factor ()
{
  struct type *type = this->fixed_point_type_base_type ();

  return type->fixed_point_info ().scaling_factor;
}

/* See gdbtypes.h.  */

void
type::alloc_fields (unsigned int nfields, bool init)
{
  this->set_num_fields (nfields);

  if (nfields == 0)
    {
      this->main_type->flds_bnds.fields = nullptr;
      return;
    }

  size_t size = nfields * sizeof (*this->fields ());
  struct field *fields
    = (struct field *) (init
			? TYPE_ZALLOC (this, size)
			: TYPE_ALLOC (this, size));

  this->main_type->flds_bnds.fields = fields;
}

/* See gdbtypes.h.  */

void
type::copy_fields (struct type *src)
{
  unsigned int nfields = src->num_fields ();
  alloc_fields (nfields, false);
  if (nfields == 0)
    return;

  size_t size = nfields * sizeof (*this->fields ());
  memcpy (this->fields (), src->fields (), size);
}

/* See gdbtypes.h.  */

void
type::copy_fields (std::vector<struct field> &src)
{
  unsigned int nfields = src.size ();
  alloc_fields (nfields, false);
  if (nfields == 0)
    return;

  size_t size = nfields * sizeof (*this->fields ());
  memcpy (this->fields (), src.data (), size);
}

/* See gdbtypes.h.  */

bool
type::is_string_like ()
{
  const language_defn *defn = language_def (this->language ());
  return defn->is_string_type_p (this);
}

/* See gdbtypes.h.  */

bool
type::is_array_like ()
{
  if (code () == TYPE_CODE_ARRAY)
    return true;
  const language_defn *defn = language_def (this->language ());
  return defn->is_array_like (this);
}



static const registry<gdbarch>::key<struct builtin_type> gdbtypes_data;

static struct builtin_type *
create_gdbtypes_data (struct gdbarch *gdbarch)
{
  struct builtin_type *builtin_type = new struct builtin_type;

  type_allocator alloc (gdbarch);

  /* Basic types.  */
  builtin_type->builtin_void
    = alloc.new_type (TYPE_CODE_VOID, TARGET_CHAR_BIT, "void");
  builtin_type->builtin_char
    = init_integer_type (alloc, TARGET_CHAR_BIT,
			 !gdbarch_char_signed (gdbarch), "char");
  builtin_type->builtin_char->set_has_no_signedness (true);
  builtin_type->builtin_signed_char
    = init_integer_type (alloc, TARGET_CHAR_BIT,
			 0, "signed char");
  builtin_type->builtin_unsigned_char
    = init_integer_type (alloc, TARGET_CHAR_BIT,
			 1, "unsigned char");
  builtin_type->builtin_short
    = init_integer_type (alloc, gdbarch_short_bit (gdbarch),
			 0, "short");
  builtin_type->builtin_unsigned_short
    = init_integer_type (alloc, gdbarch_short_bit (gdbarch),
			 1, "unsigned short");
  builtin_type->builtin_int
    = init_integer_type (alloc, gdbarch_int_bit (gdbarch),
			 0, "int");
  builtin_type->builtin_unsigned_int
    = init_integer_type (alloc, gdbarch_int_bit (gdbarch),
			 1, "unsigned int");
  builtin_type->builtin_long
    = init_integer_type (alloc, gdbarch_long_bit (gdbarch),
			 0, "long");
  builtin_type->builtin_unsigned_long
    = init_integer_type (alloc, gdbarch_long_bit (gdbarch),
			 1, "unsigned long");
  builtin_type->builtin_long_long
    = init_integer_type (alloc, gdbarch_long_long_bit (gdbarch),
			 0, "long long");
  builtin_type->builtin_unsigned_long_long
    = init_integer_type (alloc, gdbarch_long_long_bit (gdbarch),
			 1, "unsigned long long");
  builtin_type->builtin_half
    = init_float_type (alloc, gdbarch_half_bit (gdbarch),
		       "half", gdbarch_half_format (gdbarch));
  builtin_type->builtin_float
    = init_float_type (alloc, gdbarch_float_bit (gdbarch),
		       "float", gdbarch_float_format (gdbarch));
  builtin_type->builtin_bfloat16
    = init_float_type (alloc, gdbarch_bfloat16_bit (gdbarch),
		       "bfloat16", gdbarch_bfloat16_format (gdbarch));
  builtin_type->builtin_double
    = init_float_type (alloc, gdbarch_double_bit (gdbarch),
		       "double", gdbarch_double_format (gdbarch));
  builtin_type->builtin_long_double
    = init_float_type (alloc, gdbarch_long_double_bit (gdbarch),
		       "long double", gdbarch_long_double_format (gdbarch));
  builtin_type->builtin_complex
    = init_complex_type ("complex", builtin_type->builtin_float);
  builtin_type->builtin_double_complex
    = init_complex_type ("double complex", builtin_type->builtin_double);
  builtin_type->builtin_string
    = alloc.new_type (TYPE_CODE_STRING, TARGET_CHAR_BIT, "string");
  builtin_type->builtin_bool
    = init_boolean_type (alloc, TARGET_CHAR_BIT, 1, "bool");

  /* The following three are about decimal floating point types, which
     are 32-bits, 64-bits and 128-bits respectively.  */
  builtin_type->builtin_decfloat
    = init_decfloat_type (alloc, 32, "_Decimal32");
  builtin_type->builtin_decdouble
    = init_decfloat_type (alloc, 64, "_Decimal64");
  builtin_type->builtin_declong
    = init_decfloat_type (alloc, 128, "_Decimal128");

  /* "True" character types.  */
  builtin_type->builtin_true_char
    = init_character_type (alloc, TARGET_CHAR_BIT, 0, "true character");
  builtin_type->builtin_true_unsigned_char
    = init_character_type (alloc, TARGET_CHAR_BIT, 1, "true character");

  /* Fixed-size integer types.  */
  builtin_type->builtin_int0
    = init_integer_type (alloc, 0, 0, "int0_t");
  builtin_type->builtin_int8
    = init_integer_type (alloc, 8, 0, "int8_t");
  builtin_type->builtin_uint8
    = init_integer_type (alloc, 8, 1, "uint8_t");
  builtin_type->builtin_int16
    = init_integer_type (alloc, 16, 0, "int16_t");
  builtin_type->builtin_uint16
    = init_integer_type (alloc, 16, 1, "uint16_t");
  builtin_type->builtin_int24
    = init_integer_type (alloc, 24, 0, "int24_t");
  builtin_type->builtin_uint24
    = init_integer_type (alloc, 24, 1, "uint24_t");
  builtin_type->builtin_int32
    = init_integer_type (alloc, 32, 0, "int32_t");
  builtin_type->builtin_uint32
    = init_integer_type (alloc, 32, 1, "uint32_t");
  builtin_type->builtin_int64
    = init_integer_type (alloc, 64, 0, "int64_t");
  builtin_type->builtin_uint64
    = init_integer_type (alloc, 64, 1, "uint64_t");
  builtin_type->builtin_int128
    = init_integer_type (alloc, 128, 0, "int128_t");
  builtin_type->builtin_uint128
    = init_integer_type (alloc, 128, 1, "uint128_t");

  builtin_type->builtin_int8->set_instance_flags
    (builtin_type->builtin_int8->instance_flags ()
     | TYPE_INSTANCE_FLAG_NOTTEXT);

  builtin_type->builtin_uint8->set_instance_flags
    (builtin_type->builtin_uint8->instance_flags ()
     | TYPE_INSTANCE_FLAG_NOTTEXT);

  /* Wide character types.  */
  builtin_type->builtin_char16
    = init_integer_type (alloc, 16, 1, "char16_t");
  builtin_type->builtin_char32
    = init_integer_type (alloc, 32, 1, "char32_t");
  builtin_type->builtin_wchar
    = init_integer_type (alloc, gdbarch_wchar_bit (gdbarch),
			 !gdbarch_wchar_signed (gdbarch), "wchar_t");

  /* Default data/code pointer types.  */
  builtin_type->builtin_data_ptr
    = lookup_pointer_type (builtin_type->builtin_void);
  builtin_type->builtin_func_ptr
    = lookup_pointer_type (lookup_function_type (builtin_type->builtin_void));
  builtin_type->builtin_func_func
    = lookup_function_type (builtin_type->builtin_func_ptr);

  /* This type represents a GDB internal function.  */
  builtin_type->internal_fn
    = alloc.new_type (TYPE_CODE_INTERNAL_FUNCTION, 0,
		      "<internal function>");

  /* This type represents an xmethod.  */
  builtin_type->xmethod
    = alloc.new_type (TYPE_CODE_XMETHOD, 0, "<xmethod>");

  /* This type represents a type that was unrecognized in symbol read-in.  */
  builtin_type->builtin_error
    = alloc.new_type (TYPE_CODE_ERROR, 0, "<unknown type>");

  /* The following set of types is used for symbols with no
     debug information.  */
  builtin_type->nodebug_text_symbol
    = alloc.new_type (TYPE_CODE_FUNC, TARGET_CHAR_BIT,
		      "<text variable, no debug info>");

  builtin_type->nodebug_text_gnu_ifunc_symbol
    = alloc.new_type (TYPE_CODE_FUNC, TARGET_CHAR_BIT,
		      "<text gnu-indirect-function variable, no debug info>");
  builtin_type->nodebug_text_gnu_ifunc_symbol->set_is_gnu_ifunc (true);

  builtin_type->nodebug_got_plt_symbol
    = init_pointer_type (alloc, gdbarch_addr_bit (gdbarch),
			 "<text from jump slot in .got.plt, no debug info>",
			 builtin_type->nodebug_text_symbol);
  builtin_type->nodebug_data_symbol
    = alloc.new_type (TYPE_CODE_ERROR, 0, "<data variable, no debug info>");
  builtin_type->nodebug_unknown_symbol
    = alloc.new_type (TYPE_CODE_ERROR, 0,
		      "<variable (not text or data), no debug info>");
  builtin_type->nodebug_tls_symbol
    = alloc.new_type (TYPE_CODE_ERROR, 0,
		      "<thread local variable, no debug info>");

  /* NOTE: on some targets, addresses and pointers are not necessarily
     the same.

     The upshot is:
     - gdb's `struct type' always describes the target's
       representation.
     - gdb's `struct value' objects should always hold values in
       target form.
     - gdb's CORE_ADDR values are addresses in the unified virtual
       address space that the assembler and linker work with.  Thus,
       since target_read_memory takes a CORE_ADDR as an argument, it
       can access any memory on the target, even if the processor has
       separate code and data address spaces.

     In this context, builtin_type->builtin_core_addr is a bit odd:
     it's a target type for a value the target will never see.  It's
     only used to hold the values of (typeless) linker symbols, which
     are indeed in the unified virtual address space.  */

  builtin_type->builtin_core_addr
    = init_integer_type (alloc, gdbarch_addr_bit (gdbarch), 1,
			 "__CORE_ADDR");
  return builtin_type;
}

const struct builtin_type *
builtin_type (struct gdbarch *gdbarch)
{
  struct builtin_type *result = gdbtypes_data.get (gdbarch);
  if (result == nullptr)
    {
      result = create_gdbtypes_data (gdbarch);
      gdbtypes_data.set (gdbarch, result);
    }
  return result;
}

const struct builtin_type *
builtin_type (struct objfile *objfile)
{
  return builtin_type (objfile->arch ());
}

/* See gdbtypes.h.  */

CORE_ADDR
call_site::pc () const
{
  return per_objfile->relocate (m_unrelocated_pc);
}

void _initialize_gdbtypes ();
void
_initialize_gdbtypes ()
{
  add_setshow_zuinteger_cmd ("overload", no_class, &overload_debug,
			     _("Set debugging of C++ overloading."),
			     _("Show debugging of C++ overloading."),
			     _("When enabled, ranking of the "
			       "functions is displayed."),
			     NULL,
			     show_overload_debug,
			     &setdebuglist, &showdebuglist);

  /* Add user knob for controlling resolution of opaque types.  */
  add_setshow_boolean_cmd ("opaque-type-resolution", class_support,
			   &opaque_type_resolution,
			   _("Set resolution of opaque struct/class/union"
			     " types (if set before loading symbols)."),
			   _("Show resolution of opaque struct/class/union"
			     " types (if set before loading symbols)."),
			   NULL, NULL,
			   show_opaque_type_resolution,
			   &setlist, &showlist);

  /* Add an option to permit non-strict type checking.  */
  add_setshow_boolean_cmd ("type", class_support,
			   &strict_type_checking,
			   _("Set strict type checking."),
			   _("Show strict type checking."),
			   NULL, NULL,
			   show_strict_type_checking,
			   &setchecklist, &showchecklist);
}
