/* Ada language support routines for GDB, the GNU debugger.

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

   This file is part of GDB.

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

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

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


#include "defs.h"
#include <ctype.h>
#include "gdbsupport/gdb_regex.h"
#include "frame.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "gdbcmd.h"
#include "expression.h"
#include "parser-defs.h"
#include "language.h"
#include "varobj.h"
#include "inferior.h"
#include "symfile.h"
#include "objfiles.h"
#include "breakpoint.h"
#include "gdbcore.h"
#include "hashtab.h"
#include "gdbsupport/gdb_obstack.h"
#include "ada-lang.h"
#include "completer.h"
#include "ui-out.h"
#include "block.h"
#include "infcall.h"
#include "annotate.h"
#include "valprint.h"
#include "source.h"
#include "observable.h"
#include "stack.h"
#include "typeprint.h"
#include "namespace.h"
#include "cli/cli-style.h"
#include "cli/cli-decode.h"

#include "value.h"
#include "mi/mi-common.h"
#include "arch-utils.h"
#include "cli/cli-utils.h"
#include "gdbsupport/function-view.h"
#include "gdbsupport/byte-vector.h"
#include <algorithm>
#include "ada-exp.h"
#include "charset.h"

/* Define whether or not the C operator '/' truncates towards zero for
   differently signed operands (truncation direction is undefined in C).
   Copied from valarith.c.  */

#ifndef TRUNCATION_TOWARDS_ZERO
#define TRUNCATION_TOWARDS_ZERO ((-5 / 2) == -2)
#endif

static struct type *desc_base_type (struct type *);

static struct type *desc_bounds_type (struct type *);

static struct value *desc_bounds (struct value *);

static int fat_pntr_bounds_bitpos (struct type *);

static int fat_pntr_bounds_bitsize (struct type *);

static struct type *desc_data_target_type (struct type *);

static struct value *desc_data (struct value *);

static int fat_pntr_data_bitpos (struct type *);

static int fat_pntr_data_bitsize (struct type *);

static struct value *desc_one_bound (struct value *, int, int);

static int desc_bound_bitpos (struct type *, int, int);

static int desc_bound_bitsize (struct type *, int, int);

static struct type *desc_index_type (struct type *, int);

static int desc_arity (struct type *);

static int ada_args_match (struct symbol *, struct value **, int);

static struct value *make_array_descriptor (struct type *, struct value *);

static void ada_add_block_symbols (std::vector<struct block_symbol> &,
				   const struct block *,
				   const lookup_name_info &lookup_name,
				   domain_enum, struct objfile *);

static void ada_add_all_symbols (std::vector<struct block_symbol> &,
				 const struct block *,
				 const lookup_name_info &lookup_name,
				 domain_enum, int, int *);

static int is_nonfunction (const std::vector<struct block_symbol> &);

static void add_defn_to_vec (std::vector<struct block_symbol> &,
			     struct symbol *,
			     const struct block *);

static int possible_user_operator_p (enum exp_opcode, struct value **);

static const char *ada_decoded_op_name (enum exp_opcode);

static int numeric_type_p (struct type *);

static int integer_type_p (struct type *);

static int scalar_type_p (struct type *);

static int discrete_type_p (struct type *);

static struct type *ada_lookup_struct_elt_type (struct type *, const char *,
						int, int);

static struct type *ada_find_parallel_type_with_name (struct type *,
						      const char *);

static int is_dynamic_field (struct type *, int);

static struct type *to_fixed_variant_branch_type (struct type *,
						  const gdb_byte *,
						  CORE_ADDR, struct value *);

static struct type *to_fixed_array_type (struct type *, struct value *, int);

static struct type *to_fixed_range_type (struct type *, struct value *);

static struct type *to_static_fixed_type (struct type *);
static struct type *static_unwrap_type (struct type *type);

static struct value *unwrap_value (struct value *);

static struct type *constrained_packed_array_type (struct type *, long *);

static struct type *decode_constrained_packed_array_type (struct type *);

static long decode_packed_array_bitsize (struct type *);

static struct value *decode_constrained_packed_array (struct value *);

static int ada_is_unconstrained_packed_array_type (struct type *);

static struct value *value_subscript_packed (struct value *, int,
					     struct value **);

static struct value *coerce_unspec_val_to_type (struct value *,
						struct type *);

static int lesseq_defined_than (struct symbol *, struct symbol *);

static int equiv_types (struct type *, struct type *);

static int is_name_suffix (const char *);

static int advance_wild_match (const char **, const char *, char);

static bool wild_match (const char *name, const char *patn);

static struct value *ada_coerce_ref (struct value *);

static LONGEST pos_atr (struct value *);

static struct value *val_atr (struct type *, LONGEST);

static struct symbol *standard_lookup (const char *, const struct block *,
				       domain_enum);

static struct value *ada_search_struct_field (const char *, struct value *, int,
					      struct type *);

static int find_struct_field (const char *, struct type *, int,
			      struct type **, int *, int *, int *, int *);

static int ada_resolve_function (std::vector<struct block_symbol> &,
				 struct value **, int, const char *,
				 struct type *, bool);

static int ada_is_direct_array_type (struct type *);

static struct value *ada_index_struct_field (int, struct value *, int,
					     struct type *);

static void add_component_interval (LONGEST, LONGEST, std::vector<LONGEST> &);


static struct type *ada_find_any_type (const char *name);

static symbol_name_matcher_ftype *ada_get_symbol_name_matcher
  (const lookup_name_info &lookup_name);



/* The character set used for source files.  */
static const char *ada_source_charset;

/* The string "UTF-8".  This is here so we can check for the UTF-8
   charset using == rather than strcmp.  */
static const char ada_utf8[] = "UTF-8";

/* Each entry in the UTF-32 case-folding table is of this form.  */
struct utf8_entry
{
  /* The start and end, inclusive, of this range of codepoints.  */
  uint32_t start, end;
  /* The delta to apply to get the upper-case form.  0 if this is
     already upper-case.  */
  int upper_delta;
  /* The delta to apply to get the lower-case form.  0 if this is
     already lower-case.  */
  int lower_delta;

  bool operator< (uint32_t val) const
  {
    return end < val;
  }
};

static const utf8_entry ada_case_fold[] =
{
#include "ada-casefold.h"
};



/* The result of a symbol lookup to be stored in our symbol cache.  */

struct cache_entry
{
  /* The name used to perform the lookup.  */
  const char *name;
  /* The namespace used during the lookup.  */
  domain_enum domain;
  /* The symbol returned by the lookup, or NULL if no matching symbol
     was found.  */
  struct symbol *sym;
  /* The block where the symbol was found, or NULL if no matching
     symbol was found.  */
  const struct block *block;
  /* A pointer to the next entry with the same hash.  */
  struct cache_entry *next;
};

/* The Ada symbol cache, used to store the result of Ada-mode symbol
   lookups in the course of executing the user's commands.

   The cache is implemented using a simple, fixed-sized hash.
   The size is fixed on the grounds that there are not likely to be
   all that many symbols looked up during any given session, regardless
   of the size of the symbol table.  If we decide to go to a resizable
   table, let's just use the stuff from libiberty instead.  */

#define HASH_SIZE 1009

struct ada_symbol_cache
{
  /* An obstack used to store the entries in our cache.  */
  struct auto_obstack cache_space;

  /* The root of the hash table used to implement our symbol cache.  */
  struct cache_entry *root[HASH_SIZE] {};
};

static const char ada_completer_word_break_characters[] =
#ifdef VMS
  " \t\n!@#%^&*()+=|~`}{[]\";:?/,-";
#else
  " \t\n!@#$%^&*()+=|~`}{[]\";:?/,-";
#endif

/* The name of the symbol to use to get the name of the main subprogram.  */
static const char ADA_MAIN_PROGRAM_SYMBOL_NAME[]
  = "__gnat_ada_main_program_name";

/* Limit on the number of warnings to raise per expression evaluation.  */
static int warning_limit = 2;

/* Number of warning messages issued; reset to 0 by cleanups after
   expression evaluation.  */
static int warnings_issued = 0;

static const char * const known_runtime_file_name_patterns[] = {
  ADA_KNOWN_RUNTIME_FILE_NAME_PATTERNS NULL
};

static const char * const known_auxiliary_function_name_patterns[] = {
  ADA_KNOWN_AUXILIARY_FUNCTION_NAME_PATTERNS NULL
};

/* Maintenance-related settings for this module.  */

static struct cmd_list_element *maint_set_ada_cmdlist;
static struct cmd_list_element *maint_show_ada_cmdlist;

/* The "maintenance ada set/show ignore-descriptive-type" value.  */

static bool ada_ignore_descriptive_types_p = false;

			/* Inferior-specific data.  */

/* Per-inferior data for this module.  */

struct ada_inferior_data
{
  /* The ada__tags__type_specific_data type, which is used when decoding
     tagged types.  With older versions of GNAT, this type was directly
     accessible through a component ("tsd") in the object tag.  But this
     is no longer the case, so we cache it for each inferior.  */
  struct type *tsd_type = nullptr;

  /* The exception_support_info data.  This data is used to determine
     how to implement support for Ada exception catchpoints in a given
     inferior.  */
  const struct exception_support_info *exception_info = nullptr;
};

/* Our key to this module's inferior data.  */
static const struct inferior_key<ada_inferior_data> ada_inferior_data;

/* Return our inferior data for the given inferior (INF).

   This function always returns a valid pointer to an allocated
   ada_inferior_data structure.  If INF's inferior data has not
   been previously set, this functions creates a new one with all
   fields set to zero, sets INF's inferior to it, and then returns
   a pointer to that newly allocated ada_inferior_data.  */

static struct ada_inferior_data *
get_ada_inferior_data (struct inferior *inf)
{
  struct ada_inferior_data *data;

  data = ada_inferior_data.get (inf);
  if (data == NULL)
    data = ada_inferior_data.emplace (inf);

  return data;
}

/* Perform all necessary cleanups regarding our module's inferior data
   that is required after the inferior INF just exited.  */

static void
ada_inferior_exit (struct inferior *inf)
{
  ada_inferior_data.clear (inf);
}


			/* program-space-specific data.  */

/* This module's per-program-space data.  */
struct ada_pspace_data
{
  /* The Ada symbol cache.  */
  std::unique_ptr<ada_symbol_cache> sym_cache;
};

/* Key to our per-program-space data.  */
static const struct program_space_key<ada_pspace_data> ada_pspace_data_handle;

/* Return this module's data for the given program space (PSPACE).
   If not is found, add a zero'ed one now.

   This function always returns a valid object.  */

static struct ada_pspace_data *
get_ada_pspace_data (struct program_space *pspace)
{
  struct ada_pspace_data *data;

  data = ada_pspace_data_handle.get (pspace);
  if (data == NULL)
    data = ada_pspace_data_handle.emplace (pspace);

  return data;
}

			/* Utilities */

/* If TYPE is a TYPE_CODE_TYPEDEF type, return the target type after
   all typedef layers have been peeled.  Otherwise, return TYPE.

   Normally, we really expect a typedef type to only have 1 typedef layer.
   In other words, we really expect the target type of a typedef type to be
   a non-typedef type.  This is particularly true for Ada units, because
   the language does not have a typedef vs not-typedef distinction.
   In that respect, the Ada compiler has been trying to eliminate as many
   typedef definitions in the debugging information, since they generally
   do not bring any extra information (we still use typedef under certain
   circumstances related mostly to the GNAT encoding).

   Unfortunately, we have seen situations where the debugging information
   generated by the compiler leads to such multiple typedef layers.  For
   instance, consider the following example with stabs:

     .stabs  "pck__float_array___XUP:Tt(0,46)=s16P_ARRAY:(0,47)=[...]"[...]
     .stabs  "pck__float_array___XUP:t(0,36)=(0,46)",128,0,6,0

   This is an error in the debugging information which causes type
   pck__float_array___XUP to be defined twice, and the second time,
   it is defined as a typedef of a typedef.

   This is on the fringe of legality as far as debugging information is
   concerned, and certainly unexpected.  But it is easy to handle these
   situations correctly, so we can afford to be lenient in this case.  */

static struct type *
ada_typedef_target_type (struct type *type)
{
  while (type->code () == TYPE_CODE_TYPEDEF)
    type = TYPE_TARGET_TYPE (type);
  return type;
}

/* Given DECODED_NAME a string holding a symbol name in its
   decoded form (ie using the Ada dotted notation), returns
   its unqualified name.  */

static const char *
ada_unqualified_name (const char *decoded_name)
{
  const char *result;
  
  /* If the decoded name starts with '<', it means that the encoded
     name does not follow standard naming conventions, and thus that
     it is not your typical Ada symbol name.  Trying to unqualify it
     is therefore pointless and possibly erroneous.  */
  if (decoded_name[0] == '<')
    return decoded_name;

  result = strrchr (decoded_name, '.');
  if (result != NULL)
    result++;                   /* Skip the dot...  */
  else
    result = decoded_name;

  return result;
}

/* Return a string starting with '<', followed by STR, and '>'.  */

static std::string
add_angle_brackets (const char *str)
{
  return string_printf ("<%s>", str);
}

/* True (non-zero) iff TARGET matches FIELD_NAME up to any trailing
   suffix of FIELD_NAME beginning "___".  */

static int
field_name_match (const char *field_name, const char *target)
{
  int len = strlen (target);

  return
    (strncmp (field_name, target, len) == 0
     && (field_name[len] == '\0'
	 || (startswith (field_name + len, "___")
	     && strcmp (field_name + strlen (field_name) - 6,
			"___XVN") != 0)));
}


/* Assuming TYPE is a TYPE_CODE_STRUCT or a TYPE_CODE_TYPDEF to
   a TYPE_CODE_STRUCT, find the field whose name matches FIELD_NAME,
   and return its index.  This function also handles fields whose name
   have ___ suffixes because the compiler sometimes alters their name
   by adding such a suffix to represent fields with certain constraints.
   If the field could not be found, return a negative number if
   MAYBE_MISSING is set.  Otherwise raise an error.  */

int
ada_get_field_index (const struct type *type, const char *field_name,
		     int maybe_missing)
{
  int fieldno;
  struct type *struct_type = check_typedef ((struct type *) type);

  for (fieldno = 0; fieldno < struct_type->num_fields (); fieldno++)
    if (field_name_match (struct_type->field (fieldno).name (), field_name))
      return fieldno;

  if (!maybe_missing)
    error (_("Unable to find field %s in struct %s.  Aborting"),
	   field_name, struct_type->name ());

  return -1;
}

/* The length of the prefix of NAME prior to any "___" suffix.  */

int
ada_name_prefix_len (const char *name)
{
  if (name == NULL)
    return 0;
  else
    {
      const char *p = strstr (name, "___");

      if (p == NULL)
	return strlen (name);
      else
	return p - name;
    }
}

/* Return non-zero if SUFFIX is a suffix of STR.
   Return zero if STR is null.  */

static int
is_suffix (const char *str, const char *suffix)
{
  int len1, len2;

  if (str == NULL)
    return 0;
  len1 = strlen (str);
  len2 = strlen (suffix);
  return (len1 >= len2 && strcmp (str + len1 - len2, suffix) == 0);
}

/* The contents of value VAL, treated as a value of type TYPE.  The
   result is an lval in memory if VAL is.  */

static struct value *
coerce_unspec_val_to_type (struct value *val, struct type *type)
{
  type = ada_check_typedef (type);
  if (value_type (val) == type)
    return val;
  else
    {
      struct value *result;

      if (value_optimized_out (val))
	result = allocate_optimized_out_value (type);
      else if (value_lazy (val)
	       /* Be careful not to make a lazy not_lval value.  */
	       || (VALUE_LVAL (val) != not_lval
		   && TYPE_LENGTH (type) > TYPE_LENGTH (value_type (val))))
	result = allocate_value_lazy (type);
      else
	{
	  result = allocate_value (type);
	  value_contents_copy (result, 0, val, 0, TYPE_LENGTH (type));
	}
      set_value_component_location (result, val);
      set_value_bitsize (result, value_bitsize (val));
      set_value_bitpos (result, value_bitpos (val));
      if (VALUE_LVAL (result) == lval_memory)
	set_value_address (result, value_address (val));
      return result;
    }
}

static const gdb_byte *
cond_offset_host (const gdb_byte *valaddr, long offset)
{
  if (valaddr == NULL)
    return NULL;
  else
    return valaddr + offset;
}

static CORE_ADDR
cond_offset_target (CORE_ADDR address, long offset)
{
  if (address == 0)
    return 0;
  else
    return address + offset;
}

/* Issue a warning (as for the definition of warning in utils.c, but
   with exactly one argument rather than ...), unless the limit on the
   number of warnings has passed during the evaluation of the current
   expression.  */

/* FIXME: cagney/2004-10-10: This function is mimicking the behavior
   provided by "complaint".  */
static void lim_warning (const char *format, ...) ATTRIBUTE_PRINTF (1, 2);

static void
lim_warning (const char *format, ...)
{
  va_list args;

  va_start (args, format);
  warnings_issued += 1;
  if (warnings_issued <= warning_limit)
    vwarning (format, args);

  va_end (args);
}

/* Maximum value of a SIZE-byte signed integer type.  */
static LONGEST
max_of_size (int size)
{
  LONGEST top_bit = (LONGEST) 1 << (size * 8 - 2);

  return top_bit | (top_bit - 1);
}

/* Minimum value of a SIZE-byte signed integer type.  */
static LONGEST
min_of_size (int size)
{
  return -max_of_size (size) - 1;
}

/* Maximum value of a SIZE-byte unsigned integer type.  */
static ULONGEST
umax_of_size (int size)
{
  ULONGEST top_bit = (ULONGEST) 1 << (size * 8 - 1);

  return top_bit | (top_bit - 1);
}

/* Maximum value of integral type T, as a signed quantity.  */
static LONGEST
max_of_type (struct type *t)
{
  if (t->is_unsigned ())
    return (LONGEST) umax_of_size (TYPE_LENGTH (t));
  else
    return max_of_size (TYPE_LENGTH (t));
}

/* Minimum value of integral type T, as a signed quantity.  */
static LONGEST
min_of_type (struct type *t)
{
  if (t->is_unsigned ())
    return 0;
  else
    return min_of_size (TYPE_LENGTH (t));
}

/* The largest value in the domain of TYPE, a discrete type, as an integer.  */
LONGEST
ada_discrete_type_high_bound (struct type *type)
{
  type = resolve_dynamic_type (type, {}, 0);
  switch (type->code ())
    {
    case TYPE_CODE_RANGE:
      {
	const dynamic_prop &high = type->bounds ()->high;

	if (high.kind () == PROP_CONST)
	  return high.const_val ();
	else
	  {
	    gdb_assert (high.kind () == PROP_UNDEFINED);

	    /* This happens when trying to evaluate a type's dynamic bound
	       without a live target.  There is nothing relevant for us to
	       return here, so return 0.  */
	    return 0;
	  }
      }
    case TYPE_CODE_ENUM:
      return type->field (type->num_fields () - 1).loc_enumval ();
    case TYPE_CODE_BOOL:
      return 1;
    case TYPE_CODE_CHAR:
    case TYPE_CODE_INT:
      return max_of_type (type);
    default:
      error (_("Unexpected type in ada_discrete_type_high_bound."));
    }
}

/* The smallest value in the domain of TYPE, a discrete type, as an integer.  */
LONGEST
ada_discrete_type_low_bound (struct type *type)
{
  type = resolve_dynamic_type (type, {}, 0);
  switch (type->code ())
    {
    case TYPE_CODE_RANGE:
      {
	const dynamic_prop &low = type->bounds ()->low;

	if (low.kind () == PROP_CONST)
	  return low.const_val ();
	else
	  {
	    gdb_assert (low.kind () == PROP_UNDEFINED);

	    /* This happens when trying to evaluate a type's dynamic bound
	       without a live target.  There is nothing relevant for us to
	       return here, so return 0.  */
	    return 0;
	  }
      }
    case TYPE_CODE_ENUM:
      return type->field (0).loc_enumval ();
    case TYPE_CODE_BOOL:
      return 0;
    case TYPE_CODE_CHAR:
    case TYPE_CODE_INT:
      return min_of_type (type);
    default:
      error (_("Unexpected type in ada_discrete_type_low_bound."));
    }
}

/* The identity on non-range types.  For range types, the underlying
   non-range scalar type.  */

static struct type *
get_base_type (struct type *type)
{
  while (type != NULL && type->code () == TYPE_CODE_RANGE)
    {
      if (type == TYPE_TARGET_TYPE (type) || TYPE_TARGET_TYPE (type) == NULL)
	return type;
      type = TYPE_TARGET_TYPE (type);
    }
  return type;
}

/* Return a decoded version of the given VALUE.  This means returning
   a value whose type is obtained by applying all the GNAT-specific
   encodings, making the resulting type a static but standard description
   of the initial type.  */

struct value *
ada_get_decoded_value (struct value *value)
{
  struct type *type = ada_check_typedef (value_type (value));

  if (ada_is_array_descriptor_type (type)
      || (ada_is_constrained_packed_array_type (type)
	  && type->code () != TYPE_CODE_PTR))
    {
      if (type->code () == TYPE_CODE_TYPEDEF)  /* array access type.  */
	value = ada_coerce_to_simple_array_ptr (value);
      else
	value = ada_coerce_to_simple_array (value);
    }
  else
    value = ada_to_fixed_value (value);

  return value;
}

/* Same as ada_get_decoded_value, but with the given TYPE.
   Because there is no associated actual value for this type,
   the resulting type might be a best-effort approximation in
   the case of dynamic types.  */

struct type *
ada_get_decoded_type (struct type *type)
{
  type = to_static_fixed_type (type);
  if (ada_is_constrained_packed_array_type (type))
    type = ada_coerce_to_simple_array_type (type);
  return type;
}



				/* Language Selection */

/* If the main program is in Ada, return language_ada, otherwise return LANG
   (the main program is in Ada iif the adainit symbol is found).  */

static enum language
ada_update_initial_language (enum language lang)
{
  if (lookup_minimal_symbol ("adainit", NULL, NULL).minsym != NULL)
    return language_ada;

  return lang;
}

/* If the main procedure is written in Ada, then return its name.
   The result is good until the next call.  Return NULL if the main
   procedure doesn't appear to be in Ada.  */

char *
ada_main_name (void)
{
  struct bound_minimal_symbol msym;
  static gdb::unique_xmalloc_ptr<char> main_program_name;

  /* For Ada, the name of the main procedure is stored in a specific
     string constant, generated by the binder.  Look for that symbol,
     extract its address, and then read that string.  If we didn't find
     that string, then most probably the main procedure is not written
     in Ada.  */
  msym = lookup_minimal_symbol (ADA_MAIN_PROGRAM_SYMBOL_NAME, NULL, NULL);

  if (msym.minsym != NULL)
    {
      CORE_ADDR main_program_name_addr = msym.value_address ();
      if (main_program_name_addr == 0)
	error (_("Invalid address for Ada main program name."));

      main_program_name = target_read_string (main_program_name_addr, 1024);
      return main_program_name.get ();
    }

  /* The main procedure doesn't seem to be in Ada.  */
  return NULL;
}

				/* Symbols */

/* Table of Ada operators and their GNAT-encoded names.  Last entry is pair
   of NULLs.  */

const struct ada_opname_map ada_opname_table[] = {
  {"Oadd", "\"+\"", BINOP_ADD},
  {"Osubtract", "\"-\"", BINOP_SUB},
  {"Omultiply", "\"*\"", BINOP_MUL},
  {"Odivide", "\"/\"", BINOP_DIV},
  {"Omod", "\"mod\"", BINOP_MOD},
  {"Orem", "\"rem\"", BINOP_REM},
  {"Oexpon", "\"**\"", BINOP_EXP},
  {"Olt", "\"<\"", BINOP_LESS},
  {"Ole", "\"<=\"", BINOP_LEQ},
  {"Ogt", "\">\"", BINOP_GTR},
  {"Oge", "\">=\"", BINOP_GEQ},
  {"Oeq", "\"=\"", BINOP_EQUAL},
  {"One", "\"/=\"", BINOP_NOTEQUAL},
  {"Oand", "\"and\"", BINOP_BITWISE_AND},
  {"Oor", "\"or\"", BINOP_BITWISE_IOR},
  {"Oxor", "\"xor\"", BINOP_BITWISE_XOR},
  {"Oconcat", "\"&\"", BINOP_CONCAT},
  {"Oabs", "\"abs\"", UNOP_ABS},
  {"Onot", "\"not\"", UNOP_LOGICAL_NOT},
  {"Oadd", "\"+\"", UNOP_PLUS},
  {"Osubtract", "\"-\"", UNOP_NEG},
  {NULL, NULL}
};

/* If STR is a decoded version of a compiler-provided suffix (like the
   "[cold]" in "symbol[cold]"), return true.  Otherwise, return
   false.  */

static bool
is_compiler_suffix (const char *str)
{
  gdb_assert (*str == '[');
  ++str;
  while (*str != '\0' && isalpha (*str))
    ++str;
  /* We accept a missing "]" in order to support completion.  */
  return *str == '\0' || (str[0] == ']' && str[1] == '\0');
}

/* Append a non-ASCII character to RESULT.  */
static void
append_hex_encoded (std::string &result, uint32_t one_char)
{
  if (one_char <= 0xff)
    {
      result.append ("U");
      result.append (phex (one_char, 1));
    }
  else if (one_char <= 0xffff)
    {
      result.append ("W");
      result.append (phex (one_char, 2));
    }
  else
    {
      result.append ("WW");
      result.append (phex (one_char, 4));
    }
}

/* Return a string that is a copy of the data in STORAGE, with
   non-ASCII characters replaced by the appropriate hex encoding.  A
   template is used because, for UTF-8, we actually want to work with
   UTF-32 codepoints.  */
template<typename T>
std::string
copy_and_hex_encode (struct obstack *storage)
{
  const T *chars = (T *) obstack_base (storage);
  int num_chars = obstack_object_size (storage) / sizeof (T);
  std::string result;
  for (int i = 0; i < num_chars; ++i)
    {
      if (chars[i] <= 0x7f)
	{
	  /* The host character set has to be a superset of ASCII, as
	     are all the other character sets we can use.  */
	  result.push_back (chars[i]);
	}
      else
	append_hex_encoded (result, chars[i]);
    }
  return result;
}

/* The "encoded" form of DECODED, according to GNAT conventions.  If
   THROW_ERRORS, throw an error if invalid operator name is found.
   Otherwise, return the empty string in that case.  */

static std::string
ada_encode_1 (const char *decoded, bool throw_errors)
{
  if (decoded == NULL)
    return {};

  std::string encoding_buffer;
  bool saw_non_ascii = false;
  for (const char *p = decoded; *p != '\0'; p += 1)
    {
      if ((*p & 0x80) != 0)
	saw_non_ascii = true;

      if (*p == '.')
	encoding_buffer.append ("__");
      else if (*p == '[' && is_compiler_suffix (p))
	{
	  encoding_buffer = encoding_buffer + "." + (p + 1);
	  if (encoding_buffer.back () == ']')
	    encoding_buffer.pop_back ();
	  break;
	}
      else if (*p == '"')
	{
	  const struct ada_opname_map *mapping;

	  for (mapping = ada_opname_table;
	       mapping->encoded != NULL
	       && !startswith (p, mapping->decoded); mapping += 1)
	    ;
	  if (mapping->encoded == NULL)
	    {
	      if (throw_errors)
		error (_("invalid Ada operator name: %s"), p);
	      else
		return {};
	    }
	  encoding_buffer.append (mapping->encoded);
	  break;
	}
      else
	encoding_buffer.push_back (*p);
    }

  /* If a non-ASCII character is seen, we must convert it to the
     appropriate hex form.  As this is more expensive, we keep track
     of whether it is even necessary.  */
  if (saw_non_ascii)
    {
      auto_obstack storage;
      bool is_utf8 = ada_source_charset == ada_utf8;
      try
	{
	  convert_between_encodings
	    (host_charset (),
	     is_utf8 ? HOST_UTF32 : ada_source_charset,
	     (const gdb_byte *) encoding_buffer.c_str (),
	     encoding_buffer.length (), 1,
	     &storage, translit_none);
	}
      catch (const gdb_exception &)
	{
	  static bool warned = false;

	  /* Converting to UTF-32 shouldn't fail, so if it doesn't, we
	     might like to know why.  */
	  if (!warned)
	    {
	      warned = true;
	      warning (_("charset conversion failure for '%s'.\n"
			 "You may have the wrong value for 'set ada source-charset'."),
		       encoding_buffer.c_str ());
	    }

	  /* We don't try to recover from errors.  */
	  return encoding_buffer;
	}

      if (is_utf8)
	return copy_and_hex_encode<uint32_t> (&storage);
      return copy_and_hex_encode<gdb_byte> (&storage);
    }

  return encoding_buffer;
}

/* Find the entry for C in the case-folding table.  Return nullptr if
   the entry does not cover C.  */
static const utf8_entry *
find_case_fold_entry (uint32_t c)
{
  auto iter = std::lower_bound (std::begin (ada_case_fold),
				std::end (ada_case_fold),
				c);
  if (iter == std::end (ada_case_fold)
      || c < iter->start
      || c > iter->end)
    return nullptr;
  return &*iter;
}

/* Return NAME folded to lower case, or, if surrounded by single
   quotes, unfolded, but with the quotes stripped away.  If
   THROW_ON_ERROR is true, encoding failures will throw an exception
   rather than emitting a warning.  Result good to next call.  */

static const char *
ada_fold_name (gdb::string_view name, bool throw_on_error = false)
{
  static std::string fold_storage;

  if (!name.empty () && name[0] == '\'')
    fold_storage = gdb::to_string (name.substr (1, name.size () - 2));
  else
    {
      /* Why convert to UTF-32 and implement our own case-folding,
	 rather than convert to wchar_t and use the platform's
	 functions?  I'm glad you asked.

	 The main problem is that GNAT implements an unusual rule for
	 case folding.  For ASCII letters, letters in single-byte
	 encodings (such as ISO-8859-*), and Unicode letters that fit
	 in a single byte (i.e., code point is <= 0xff), the letter is
	 folded to lower case.  Other Unicode letters are folded to
	 upper case.

	 This rule means that the code must be able to examine the
	 value of the character.  And, some hosts do not use Unicode
	 for wchar_t, so examining the value of such characters is
	 forbidden.  */
      auto_obstack storage;
      try
	{
	  convert_between_encodings
	    (host_charset (), HOST_UTF32,
	     (const gdb_byte *) name.data (),
	     name.length (), 1,
	     &storage, translit_none);
	}
      catch (const gdb_exception &)
	{
	  if (throw_on_error)
	    throw;

	  static bool warned = false;

	  /* Converting to UTF-32 shouldn't fail, so if it doesn't, we
	     might like to know why.  */
	  if (!warned)
	    {
	      warned = true;
	      warning (_("could not convert '%s' from the host encoding (%s) to UTF-32.\n"
			 "This normally should not happen, please file a bug report."),
		       gdb::to_string (name).c_str (), host_charset ());
	    }

	  /* We don't try to recover from errors; just return the
	     original string.  */
	  fold_storage = gdb::to_string (name);
	  return fold_storage.c_str ();
	}

      bool is_utf8 = ada_source_charset == ada_utf8;
      uint32_t *chars = (uint32_t *) obstack_base (&storage);
      int num_chars = obstack_object_size (&storage) / sizeof (uint32_t);
      for (int i = 0; i < num_chars; ++i)
	{
	  const struct utf8_entry *entry = find_case_fold_entry (chars[i]);
	  if (entry != nullptr)
	    {
	      uint32_t low = chars[i] + entry->lower_delta;
	      if (!is_utf8 || low <= 0xff)
		chars[i] = low;
	      else
		chars[i] = chars[i] + entry->upper_delta;
	    }
	}

      /* Now convert back to ordinary characters.  */
      auto_obstack reconverted;
      try
	{
	  convert_between_encodings (HOST_UTF32,
				     host_charset (),
				     (const gdb_byte *) chars,
				     num_chars * sizeof (uint32_t),
				     sizeof (uint32_t),
				     &reconverted,
				     translit_none);
	  obstack_1grow (&reconverted, '\0');
	  fold_storage = std::string ((const char *) obstack_base (&reconverted));
	}
      catch (const gdb_exception &)
	{
	  if (throw_on_error)
	    throw;

	  static bool warned = false;

	  /* Converting back from UTF-32 shouldn't normally fail, but
	     there are some host encodings without upper/lower
	     equivalence.  */
	  if (!warned)
	    {
	      warned = true;
	      warning (_("could not convert the lower-cased variant of '%s'\n"
			 "from UTF-32 to the host encoding (%s)."),
		       gdb::to_string (name).c_str (), host_charset ());
	    }

	  /* We don't try to recover from errors; just return the
	     original string.  */
	  fold_storage = gdb::to_string (name);
	}
    }

  return fold_storage.c_str ();
}

/* The "encoded" form of DECODED, according to GNAT conventions.  */

std::string
ada_encode (const char *decoded)
{
  if (decoded[0] != '<')
    decoded = ada_fold_name (decoded);
  return ada_encode_1 (decoded, true);
}

/* Return nonzero if C is either a digit or a lowercase alphabet character.  */

static int
is_lower_alphanum (const char c)
{
  return (isdigit (c) || (isalpha (c) && islower (c)));
}

/* ENCODED is the linkage name of a symbol and LEN contains its length.
   This function saves in LEN the length of that same symbol name but
   without either of these suffixes:
     . .{DIGIT}+
     . ${DIGIT}+
     . ___{DIGIT}+
     . __{DIGIT}+.

   These are suffixes introduced by the compiler for entities such as
   nested subprogram for instance, in order to avoid name clashes.
   They do not serve any purpose for the debugger.  */

static void
ada_remove_trailing_digits (const char *encoded, int *len)
{
  if (*len > 1 && isdigit (encoded[*len - 1]))
    {
      int i = *len - 2;

      while (i > 0 && isdigit (encoded[i]))
	i--;
      if (i >= 0 && encoded[i] == '.')
	*len = i;
      else if (i >= 0 && encoded[i] == '$')
	*len = i;
      else if (i >= 2 && startswith (encoded + i - 2, "___"))
	*len = i - 2;
      else if (i >= 1 && startswith (encoded + i - 1, "__"))
	*len = i - 1;
    }
}

/* Remove the suffix introduced by the compiler for protected object
   subprograms.  */

static void
ada_remove_po_subprogram_suffix (const char *encoded, int *len)
{
  /* Remove trailing N.  */

  /* Protected entry subprograms are broken into two
     separate subprograms: The first one is unprotected, and has
     a 'N' suffix; the second is the protected version, and has
     the 'P' suffix.  The second calls the first one after handling
     the protection.  Since the P subprograms are internally generated,
     we leave these names undecoded, giving the user a clue that this
     entity is internal.  */

  if (*len > 1
      && encoded[*len - 1] == 'N'
      && (isdigit (encoded[*len - 2]) || islower (encoded[*len - 2])))
    *len = *len - 1;
}

/* If ENCODED ends with a compiler-provided suffix (like ".cold"),
   then update *LEN to remove the suffix and return the offset of the
   character just past the ".".  Otherwise, return -1.  */

static int
remove_compiler_suffix (const char *encoded, int *len)
{
  int offset = *len - 1;
  while (offset > 0 && isalpha (encoded[offset]))
    --offset;
  if (offset > 0 && encoded[offset] == '.')
    {
      *len = offset;
      return offset + 1;
    }
  return -1;
}

/* Convert an ASCII hex string to a number.  Reads exactly N
   characters from STR.  Returns true on success, false if one of the
   digits was not a hex digit.  */
static bool
convert_hex (const char *str, int n, uint32_t *out)
{
  uint32_t result = 0;

  for (int i = 0; i < n; ++i)
    {
      if (!isxdigit (str[i]))
	return false;
      result <<= 4;
      result |= fromhex (str[i]);
    }

  *out = result;
  return true;
}

/* Convert a wide character from its ASCII hex representation in STR
   (consisting of exactly N characters) to the host encoding,
   appending the resulting bytes to OUT.  If N==2 and the Ada source
   charset is not UTF-8, then hex refers to an encoding in the
   ADA_SOURCE_CHARSET; otherwise, use UTF-32.  Return true on success.
   Return false and do not modify OUT on conversion failure.  */
static bool
convert_from_hex_encoded (std::string &out, const char *str, int n)
{
  uint32_t value;

  if (!convert_hex (str, n, &value))
    return false;
  try
    {
      auto_obstack bytes;
      /* In the 'U' case, the hex digits encode the character in the
	 Ada source charset.  However, if the source charset is UTF-8,
	 this really means it is a single-byte UTF-32 character.  */
      if (n == 2 && ada_source_charset != ada_utf8)
	{
	  gdb_byte one_char = (gdb_byte) value;

	  convert_between_encodings (ada_source_charset, host_charset (),
				     &one_char,
				     sizeof (one_char), sizeof (one_char),
				     &bytes, translit_none);
	}
      else
	convert_between_encodings (HOST_UTF32, host_charset (),
				   (const gdb_byte *) &value,
				   sizeof (value), sizeof (value),
				   &bytes, translit_none);
      obstack_1grow (&bytes, '\0');
      out.append ((const char *) obstack_base (&bytes));
    }
  catch (const gdb_exception &)
    {
      /* On failure, the caller will just let the encoded form
	 through, which seems basically reasonable.  */
      return false;
    }

  return true;
}

/* See ada-lang.h.  */

std::string
ada_decode (const char *encoded, bool wrap, bool operators)
{
  int i;
  int len0;
  const char *p;
  int at_start_name;
  std::string decoded;
  int suffix = -1;

  /* With function descriptors on PPC64, the value of a symbol named
     ".FN", if it exists, is the entry point of the function "FN".  */
  if (encoded[0] == '.')
    encoded += 1;

  /* The name of the Ada main procedure starts with "_ada_".
     This prefix is not part of the decoded name, so skip this part
     if we see this prefix.  */
  if (startswith (encoded, "_ada_"))
    encoded += 5;
  /* The "___ghost_" prefix is used for ghost entities.  Normally
     these aren't preserved but when they are, it's useful to see
     them.  */
  if (startswith (encoded, "___ghost_"))
    encoded += 9;

  /* If the name starts with '_', then it is not a properly encoded
     name, so do not attempt to decode it.  Similarly, if the name
     starts with '<', the name should not be decoded.  */
  if (encoded[0] == '_' || encoded[0] == '<')
    goto Suppress;

  len0 = strlen (encoded);

  suffix = remove_compiler_suffix (encoded, &len0);

  ada_remove_trailing_digits (encoded, &len0);
  ada_remove_po_subprogram_suffix (encoded, &len0);

  /* Remove the ___X.* suffix if present.  Do not forget to verify that
     the suffix is located before the current "end" of ENCODED.  We want
     to avoid re-matching parts of ENCODED that have previously been
     marked as discarded (by decrementing LEN0).  */
  p = strstr (encoded, "___");
  if (p != NULL && p - encoded < len0 - 3)
    {
      if (p[3] == 'X')
	len0 = p - encoded;
      else
	goto Suppress;
    }

  /* Remove any trailing TKB suffix.  It tells us that this symbol
     is for the body of a task, but that information does not actually
     appear in the decoded name.  */

  if (len0 > 3 && startswith (encoded + len0 - 3, "TKB"))
    len0 -= 3;

  /* Remove any trailing TB suffix.  The TB suffix is slightly different
     from the TKB suffix because it is used for non-anonymous task
     bodies.  */

  if (len0 > 2 && startswith (encoded + len0 - 2, "TB"))
    len0 -= 2;

  /* Remove trailing "B" suffixes.  */
  /* FIXME: brobecker/2006-04-19: Not sure what this are used for...  */

  if (len0 > 1 && startswith (encoded + len0 - 1, "B"))
    len0 -= 1;

  /* Remove trailing __{digit}+ or trailing ${digit}+.  */

  if (len0 > 1 && isdigit (encoded[len0 - 1]))
    {
      i = len0 - 2;
      while ((i >= 0 && isdigit (encoded[i]))
	     || (i >= 1 && encoded[i] == '_' && isdigit (encoded[i - 1])))
	i -= 1;
      if (i > 1 && encoded[i] == '_' && encoded[i - 1] == '_')
	len0 = i - 1;
      else if (encoded[i] == '$')
	len0 = i;
    }

  /* The first few characters that are not alphabetic are not part
     of any encoding we use, so we can copy them over verbatim.  */

  for (i = 0; i < len0 && !isalpha (encoded[i]); i += 1)
    decoded.push_back (encoded[i]);

  at_start_name = 1;
  while (i < len0)
    {
      /* Is this a symbol function?  */
      if (operators && at_start_name && encoded[i] == 'O')
	{
	  int k;

	  for (k = 0; ada_opname_table[k].encoded != NULL; k += 1)
	    {
	      int op_len = strlen (ada_opname_table[k].encoded);
	      if ((strncmp (ada_opname_table[k].encoded + 1, encoded + i + 1,
			    op_len - 1) == 0)
		  && !isalnum (encoded[i + op_len]))
		{
		  decoded.append (ada_opname_table[k].decoded);
		  at_start_name = 0;
		  i += op_len;
		  break;
		}
	    }
	  if (ada_opname_table[k].encoded != NULL)
	    continue;
	}
      at_start_name = 0;

      /* Replace "TK__" with "__", which will eventually be translated
	 into "." (just below).  */

      if (i < len0 - 4 && startswith (encoded + i, "TK__"))
	i += 2;

      /* Replace "__B_{DIGITS}+__" sequences by "__", which will eventually
	 be translated into "." (just below).  These are internal names
	 generated for anonymous blocks inside which our symbol is nested.  */

      if (len0 - i > 5 && encoded [i] == '_' && encoded [i+1] == '_'
	  && encoded [i+2] == 'B' && encoded [i+3] == '_'
	  && isdigit (encoded [i+4]))
	{
	  int k = i + 5;
	  
	  while (k < len0 && isdigit (encoded[k]))
	    k++;  /* Skip any extra digit.  */

	  /* Double-check that the "__B_{DIGITS}+" sequence we found
	     is indeed followed by "__".  */
	  if (len0 - k > 2 && encoded [k] == '_' && encoded [k+1] == '_')
	    i = k;
	}

      /* Remove _E{DIGITS}+[sb] */

      /* Just as for protected object subprograms, there are 2 categories
	 of subprograms created by the compiler for each entry.  The first
	 one implements the actual entry code, and has a suffix following
	 the convention above; the second one implements the barrier and
	 uses the same convention as above, except that the 'E' is replaced
	 by a 'B'.

	 Just as above, we do not decode the name of barrier functions
	 to give the user a clue that the code he is debugging has been
	 internally generated.  */

      if (len0 - i > 3 && encoded [i] == '_' && encoded[i+1] == 'E'
	  && isdigit (encoded[i+2]))
	{
	  int k = i + 3;

	  while (k < len0 && isdigit (encoded[k]))
	    k++;

	  if (k < len0
	      && (encoded[k] == 'b' || encoded[k] == 's'))
	    {
	      k++;
	      /* Just as an extra precaution, make sure that if this
		 suffix is followed by anything else, it is a '_'.
		 Otherwise, we matched this sequence by accident.  */
	      if (k == len0
		  || (k < len0 && encoded[k] == '_'))
		i = k;
	    }
	}

      /* Remove trailing "N" in [a-z0-9]+N__.  The N is added by
	 the GNAT front-end in protected object subprograms.  */

      if (i < len0 + 3
	  && encoded[i] == 'N' && encoded[i+1] == '_' && encoded[i+2] == '_')
	{
	  /* Backtrack a bit up until we reach either the begining of
	     the encoded name, or "__".  Make sure that we only find
	     digits or lowercase characters.  */
	  const char *ptr = encoded + i - 1;

	  while (ptr >= encoded && is_lower_alphanum (ptr[0]))
	    ptr--;
	  if (ptr < encoded
	      || (ptr > encoded && ptr[0] == '_' && ptr[-1] == '_'))
	    i++;
	}

      if (i < len0 + 3 && encoded[i] == 'U' && isxdigit (encoded[i + 1]))
	{
	  if (convert_from_hex_encoded (decoded, &encoded[i + 1], 2))
	    {
	      i += 3;
	      continue;
	    }
	}
      else if (i < len0 + 5 && encoded[i] == 'W' && isxdigit (encoded[i + 1]))
	{
	  if (convert_from_hex_encoded (decoded, &encoded[i + 1], 4))
	    {
	      i += 5;
	      continue;
	    }
	}
      else if (i < len0 + 10 && encoded[i] == 'W' && encoded[i + 1] == 'W'
	       && isxdigit (encoded[i + 2]))
	{
	  if (convert_from_hex_encoded (decoded, &encoded[i + 2], 8))
	    {
	      i += 10;
	      continue;
	    }
	}

      if (encoded[i] == 'X' && i != 0 && isalnum (encoded[i - 1]))
	{
	  /* This is a X[bn]* sequence not separated from the previous
	     part of the name with a non-alpha-numeric character (in other
	     words, immediately following an alpha-numeric character), then
	     verify that it is placed at the end of the encoded name.  If
	     not, then the encoding is not valid and we should abort the
	     decoding.  Otherwise, just skip it, it is used in body-nested
	     package names.  */
	  do
	    i += 1;
	  while (i < len0 && (encoded[i] == 'b' || encoded[i] == 'n'));
	  if (i < len0)
	    goto Suppress;
	}
      else if (i < len0 - 2 && encoded[i] == '_' && encoded[i + 1] == '_')
	{
	 /* Replace '__' by '.'.  */
	  decoded.push_back ('.');
	  at_start_name = 1;
	  i += 2;
	}
      else
	{
	  /* It's a character part of the decoded name, so just copy it
	     over.  */
	  decoded.push_back (encoded[i]);
	  i += 1;
	}
    }

  /* Decoded names should never contain any uppercase character.
     Double-check this, and abort the decoding if we find one.  */

  if (operators)
    {
      for (i = 0; i < decoded.length(); ++i)
	if (isupper (decoded[i]) || decoded[i] == ' ')
	  goto Suppress;
    }

  /* If the compiler added a suffix, append it now.  */
  if (suffix >= 0)
    decoded = decoded + "[" + &encoded[suffix] + "]";

  return decoded;

Suppress:
  if (!wrap)
    return {};

  if (encoded[0] == '<')
    decoded = encoded;
  else
    decoded = '<' + std::string(encoded) + '>';
  return decoded;
}

/* Table for keeping permanent unique copies of decoded names.  Once
   allocated, names in this table are never released.  While this is a
   storage leak, it should not be significant unless there are massive
   changes in the set of decoded names in successive versions of a 
   symbol table loaded during a single session.  */
static struct htab *decoded_names_store;

/* Returns the decoded name of GSYMBOL, as for ada_decode, caching it
   in the language-specific part of GSYMBOL, if it has not been
   previously computed.  Tries to save the decoded name in the same
   obstack as GSYMBOL, if possible, and otherwise on the heap (so that,
   in any case, the decoded symbol has a lifetime at least that of
   GSYMBOL).
   The GSYMBOL parameter is "mutable" in the C++ sense: logically
   const, but nevertheless modified to a semantically equivalent form
   when a decoded name is cached in it.  */

const char *
ada_decode_symbol (const struct general_symbol_info *arg)
{
  struct general_symbol_info *gsymbol = (struct general_symbol_info *) arg;
  const char **resultp =
    &gsymbol->language_specific.demangled_name;

  if (!gsymbol->ada_mangled)
    {
      std::string decoded = ada_decode (gsymbol->linkage_name ());
      struct obstack *obstack = gsymbol->language_specific.obstack;

      gsymbol->ada_mangled = 1;

      if (obstack != NULL)
	*resultp = obstack_strdup (obstack, decoded.c_str ());
      else
	{
	  /* Sometimes, we can't find a corresponding objfile, in
	     which case, we put the result on the heap.  Since we only
	     decode when needed, we hope this usually does not cause a
	     significant memory leak (FIXME).  */

	  char **slot = (char **) htab_find_slot (decoded_names_store,
						  decoded.c_str (), INSERT);

	  if (*slot == NULL)
	    *slot = xstrdup (decoded.c_str ());
	  *resultp = *slot;
	}
    }

  return *resultp;
}



				/* Arrays */

/* Assuming that INDEX_DESC_TYPE is an ___XA structure, a structure
   generated by the GNAT compiler to describe the index type used
   for each dimension of an array, check whether it follows the latest
   known encoding.  If not, fix it up to conform to the latest encoding.
   Otherwise, do nothing.  This function also does nothing if
   INDEX_DESC_TYPE is NULL.

   The GNAT encoding used to describe the array index type evolved a bit.
   Initially, the information would be provided through the name of each
   field of the structure type only, while the type of these fields was
   described as unspecified and irrelevant.  The debugger was then expected
   to perform a global type lookup using the name of that field in order
   to get access to the full index type description.  Because these global
   lookups can be very expensive, the encoding was later enhanced to make
   the global lookup unnecessary by defining the field type as being
   the full index type description.

   The purpose of this routine is to allow us to support older versions
   of the compiler by detecting the use of the older encoding, and by
   fixing up the INDEX_DESC_TYPE to follow the new one (at this point,
   we essentially replace each field's meaningless type by the associated
   index subtype).  */

void
ada_fixup_array_indexes_type (struct type *index_desc_type)
{
  int i;

  if (index_desc_type == NULL)
    return;
  gdb_assert (index_desc_type->num_fields () > 0);

  /* Check if INDEX_DESC_TYPE follows the older encoding (it is sufficient
     to check one field only, no need to check them all).  If not, return
     now.

     If our INDEX_DESC_TYPE was generated using the older encoding,
     the field type should be a meaningless integer type whose name
     is not equal to the field name.  */
  if (index_desc_type->field (0).type ()->name () != NULL
      && strcmp (index_desc_type->field (0).type ()->name (),
		 index_desc_type->field (0).name ()) == 0)
    return;

  /* Fixup each field of INDEX_DESC_TYPE.  */
  for (i = 0; i < index_desc_type->num_fields (); i++)
   {
     const char *name = index_desc_type->field (i).name ();
     struct type *raw_type = ada_check_typedef (ada_find_any_type (name));

     if (raw_type)
       index_desc_type->field (i).set_type (raw_type);
   }
}

/* The desc_* routines return primitive portions of array descriptors
   (fat pointers).  */

/* The descriptor or array type, if any, indicated by TYPE; removes
   level of indirection, if needed.  */

static struct type *
desc_base_type (struct type *type)
{
  if (type == NULL)
    return NULL;
  type = ada_check_typedef (type);
  if (type->code () == TYPE_CODE_TYPEDEF)
    type = ada_typedef_target_type (type);

  if (type != NULL
      && (type->code () == TYPE_CODE_PTR
	  || type->code () == TYPE_CODE_REF))
    return ada_check_typedef (TYPE_TARGET_TYPE (type));
  else
    return type;
}

/* True iff TYPE indicates a "thin" array pointer type.  */

static int
is_thin_pntr (struct type *type)
{
  return
    is_suffix (ada_type_name (desc_base_type (type)), "___XUT")
    || is_suffix (ada_type_name (desc_base_type (type)), "___XUT___XVE");
}

/* The descriptor type for thin pointer type TYPE.  */

static struct type *
thin_descriptor_type (struct type *type)
{
  struct type *base_type = desc_base_type (type);

  if (base_type == NULL)
    return NULL;
  if (is_suffix (ada_type_name (base_type), "___XVE"))
    return base_type;
  else
    {
      struct type *alt_type = ada_find_parallel_type (base_type, "___XVE");

      if (alt_type == NULL)
	return base_type;
      else
	return alt_type;
    }
}

/* A pointer to the array data for thin-pointer value VAL.  */

static struct value *
thin_data_pntr (struct value *val)
{
  struct type *type = ada_check_typedef (value_type (val));
  struct type *data_type = desc_data_target_type (thin_descriptor_type (type));

  data_type = lookup_pointer_type (data_type);

  if (type->code () == TYPE_CODE_PTR)
    return value_cast (data_type, value_copy (val));
  else
    return value_from_longest (data_type, value_address (val));
}

/* True iff TYPE indicates a "thick" array pointer type.  */

static int
is_thick_pntr (struct type *type)
{
  type = desc_base_type (type);
  return (type != NULL && type->code () == TYPE_CODE_STRUCT
	  && lookup_struct_elt_type (type, "P_BOUNDS", 1) != NULL);
}

/* If TYPE is the type of an array descriptor (fat or thin pointer) or a
   pointer to one, the type of its bounds data; otherwise, NULL.  */

static struct type *
desc_bounds_type (struct type *type)
{
  struct type *r;

  type = desc_base_type (type);

  if (type == NULL)
    return NULL;
  else if (is_thin_pntr (type))
    {
      type = thin_descriptor_type (type);
      if (type == NULL)
	return NULL;
      r = lookup_struct_elt_type (type, "BOUNDS", 1);
      if (r != NULL)
	return ada_check_typedef (r);
    }
  else if (type->code () == TYPE_CODE_STRUCT)
    {
      r = lookup_struct_elt_type (type, "P_BOUNDS", 1);
      if (r != NULL)
	return ada_check_typedef (TYPE_TARGET_TYPE (ada_check_typedef (r)));
    }
  return NULL;
}

/* If ARR is an array descriptor (fat or thin pointer), or pointer to
   one, a pointer to its bounds data.   Otherwise NULL.  */

static struct value *
desc_bounds (struct value *arr)
{
  struct type *type = ada_check_typedef (value_type (arr));

  if (is_thin_pntr (type))
    {
      struct type *bounds_type =
	desc_bounds_type (thin_descriptor_type (type));
      LONGEST addr;

      if (bounds_type == NULL)
	error (_("Bad GNAT array descriptor"));

      /* NOTE: The following calculation is not really kosher, but
	 since desc_type is an XVE-encoded type (and shouldn't be),
	 the correct calculation is a real pain.  FIXME (and fix GCC).  */
      if (type->code () == TYPE_CODE_PTR)
	addr = value_as_long (arr);
      else
	addr = value_address (arr);

      return
	value_from_longest (lookup_pointer_type (bounds_type),
			    addr - TYPE_LENGTH (bounds_type));
    }

  else if (is_thick_pntr (type))
    {
      struct value *p_bounds = value_struct_elt (&arr, {}, "P_BOUNDS", NULL,
					       _("Bad GNAT array descriptor"));
      struct type *p_bounds_type = value_type (p_bounds);

      if (p_bounds_type
	  && p_bounds_type->code () == TYPE_CODE_PTR)
	{
	  struct type *target_type = TYPE_TARGET_TYPE (p_bounds_type);

	  if (target_type->is_stub ())
	    p_bounds = value_cast (lookup_pointer_type
				   (ada_check_typedef (target_type)),
				   p_bounds);
	}
      else
	error (_("Bad GNAT array descriptor"));

      return p_bounds;
    }
  else
    return NULL;
}

/* If TYPE is the type of an array-descriptor (fat pointer),  the bit
   position of the field containing the address of the bounds data.  */

static int
fat_pntr_bounds_bitpos (struct type *type)
{
  return desc_base_type (type)->field (1).loc_bitpos ();
}

/* If TYPE is the type of an array-descriptor (fat pointer), the bit
   size of the field containing the address of the bounds data.  */

static int
fat_pntr_bounds_bitsize (struct type *type)
{
  type = desc_base_type (type);

  if (TYPE_FIELD_BITSIZE (type, 1) > 0)
    return TYPE_FIELD_BITSIZE (type, 1);
  else
    return 8 * TYPE_LENGTH (ada_check_typedef (type->field (1).type ()));
}

/* If TYPE is the type of an array descriptor (fat or thin pointer) or a
   pointer to one, the type of its array data (a array-with-no-bounds type);
   otherwise, NULL.  Use ada_type_of_array to get an array type with bounds
   data.  */

static struct type *
desc_data_target_type (struct type *type)
{
  type = desc_base_type (type);

  /* NOTE: The following is bogus; see comment in desc_bounds.  */
  if (is_thin_pntr (type))
    return desc_base_type (thin_descriptor_type (type)->field (1).type ());
  else if (is_thick_pntr (type))
    {
      struct type *data_type = lookup_struct_elt_type (type, "P_ARRAY", 1);

      if (data_type
	  && ada_check_typedef (data_type)->code () == TYPE_CODE_PTR)
	return ada_check_typedef (TYPE_TARGET_TYPE (data_type));
    }

  return NULL;
}

/* If ARR is an array descriptor (fat or thin pointer), a pointer to
   its array data.  */

static struct value *
desc_data (struct value *arr)
{
  struct type *type = value_type (arr);

  if (is_thin_pntr (type))
    return thin_data_pntr (arr);
  else if (is_thick_pntr (type))
    return value_struct_elt (&arr, {}, "P_ARRAY", NULL,
			     _("Bad GNAT array descriptor"));
  else
    return NULL;
}


/* If TYPE is the type of an array-descriptor (fat pointer), the bit
   position of the field containing the address of the data.  */

static int
fat_pntr_data_bitpos (struct type *type)
{
  return desc_base_type (type)->field (0).loc_bitpos ();
}

/* If TYPE is the type of an array-descriptor (fat pointer), the bit
   size of the field containing the address of the data.  */

static int
fat_pntr_data_bitsize (struct type *type)
{
  type = desc_base_type (type);

  if (TYPE_FIELD_BITSIZE (type, 0) > 0)
    return TYPE_FIELD_BITSIZE (type, 0);
  else
    return TARGET_CHAR_BIT * TYPE_LENGTH (type->field (0).type ());
}

/* If BOUNDS is an array-bounds structure (or pointer to one), return
   the Ith lower bound stored in it, if WHICH is 0, and the Ith upper
   bound, if WHICH is 1.  The first bound is I=1.  */

static struct value *
desc_one_bound (struct value *bounds, int i, int which)
{
  char bound_name[20];
  xsnprintf (bound_name, sizeof (bound_name), "%cB%d",
	     which ? 'U' : 'L', i - 1);
  return value_struct_elt (&bounds, {}, bound_name, NULL,
			   _("Bad GNAT array descriptor bounds"));
}

/* If BOUNDS is an array-bounds structure type, return the bit position
   of the Ith lower bound stored in it, if WHICH is 0, and the Ith upper
   bound, if WHICH is 1.  The first bound is I=1.  */

static int
desc_bound_bitpos (struct type *type, int i, int which)
{
  return desc_base_type (type)->field (2 * i + which - 2).loc_bitpos ();
}

/* If BOUNDS is an array-bounds structure type, return the bit field size
   of the Ith lower bound stored in it, if WHICH is 0, and the Ith upper
   bound, if WHICH is 1.  The first bound is I=1.  */

static int
desc_bound_bitsize (struct type *type, int i, int which)
{
  type = desc_base_type (type);

  if (TYPE_FIELD_BITSIZE (type, 2 * i + which - 2) > 0)
    return TYPE_FIELD_BITSIZE (type, 2 * i + which - 2);
  else
    return 8 * TYPE_LENGTH (type->field (2 * i + which - 2).type ());
}

/* If TYPE is the type of an array-bounds structure, the type of its
   Ith bound (numbering from 1).  Otherwise, NULL.  */

static struct type *
desc_index_type (struct type *type, int i)
{
  type = desc_base_type (type);

  if (type->code () == TYPE_CODE_STRUCT)
    {
      char bound_name[20];
      xsnprintf (bound_name, sizeof (bound_name), "LB%d", i - 1);
      return lookup_struct_elt_type (type, bound_name, 1);
    }
  else
    return NULL;
}

/* The number of index positions in the array-bounds type TYPE.
   Return 0 if TYPE is NULL.  */

static int
desc_arity (struct type *type)
{
  type = desc_base_type (type);

  if (type != NULL)
    return type->num_fields () / 2;
  return 0;
}

/* Non-zero iff TYPE is a simple array type (not a pointer to one) or 
   an array descriptor type (representing an unconstrained array
   type).  */

static int
ada_is_direct_array_type (struct type *type)
{
  if (type == NULL)
    return 0;
  type = ada_check_typedef (type);
  return (type->code () == TYPE_CODE_ARRAY
	  || ada_is_array_descriptor_type (type));
}

/* Non-zero iff TYPE represents any kind of array in Ada, or a pointer
 * to one.  */

static int
ada_is_array_type (struct type *type)
{
  while (type != NULL
	 && (type->code () == TYPE_CODE_PTR
	     || type->code () == TYPE_CODE_REF))
    type = TYPE_TARGET_TYPE (type);
  return ada_is_direct_array_type (type);
}

/* Non-zero iff TYPE is a simple array type or pointer to one.  */

int
ada_is_simple_array_type (struct type *type)
{
  if (type == NULL)
    return 0;
  type = ada_check_typedef (type);
  return (type->code () == TYPE_CODE_ARRAY
	  || (type->code () == TYPE_CODE_PTR
	      && (ada_check_typedef (TYPE_TARGET_TYPE (type))->code ()
		  == TYPE_CODE_ARRAY)));
}

/* Non-zero iff TYPE belongs to a GNAT array descriptor.  */

int
ada_is_array_descriptor_type (struct type *type)
{
  struct type *data_type = desc_data_target_type (type);

  if (type == NULL)
    return 0;
  type = ada_check_typedef (type);
  return (data_type != NULL
	  && data_type->code () == TYPE_CODE_ARRAY
	  && desc_arity (desc_bounds_type (type)) > 0);
}

/* Non-zero iff type is a partially mal-formed GNAT array
   descriptor.  FIXME: This is to compensate for some problems with
   debugging output from GNAT.  Re-examine periodically to see if it
   is still needed.  */

int
ada_is_bogus_array_descriptor (struct type *type)
{
  return
    type != NULL
    && type->code () == TYPE_CODE_STRUCT
    && (lookup_struct_elt_type (type, "P_BOUNDS", 1) != NULL
	|| lookup_struct_elt_type (type, "P_ARRAY", 1) != NULL)
    && !ada_is_array_descriptor_type (type);
}


/* If ARR has a record type in the form of a standard GNAT array descriptor,
   (fat pointer) returns the type of the array data described---specifically,
   a pointer-to-array type.  If BOUNDS is non-zero, the bounds data are filled
   in from the descriptor; otherwise, they are left unspecified.  If
   the ARR denotes a null array descriptor and BOUNDS is non-zero,
   returns NULL.  The result is simply the type of ARR if ARR is not
   a descriptor.  */

static struct type *
ada_type_of_array (struct value *arr, int bounds)
{
  if (ada_is_constrained_packed_array_type (value_type (arr)))
    return decode_constrained_packed_array_type (value_type (arr));

  if (!ada_is_array_descriptor_type (value_type (arr)))
    return value_type (arr);

  if (!bounds)
    {
      struct type *array_type =
	ada_check_typedef (desc_data_target_type (value_type (arr)));

      if (ada_is_unconstrained_packed_array_type (value_type (arr)))
	TYPE_FIELD_BITSIZE (array_type, 0) =
	  decode_packed_array_bitsize (value_type (arr));
      
      return array_type;
    }
  else
    {
      struct type *elt_type;
      int arity;
      struct value *descriptor;

      elt_type = ada_array_element_type (value_type (arr), -1);
      arity = ada_array_arity (value_type (arr));

      if (elt_type == NULL || arity == 0)
	return ada_check_typedef (value_type (arr));

      descriptor = desc_bounds (arr);
      if (value_as_long (descriptor) == 0)
	return NULL;
      while (arity > 0)
	{
	  struct type *range_type = alloc_type_copy (value_type (arr));
	  struct type *array_type = alloc_type_copy (value_type (arr));
	  struct value *low = desc_one_bound (descriptor, arity, 0);
	  struct value *high = desc_one_bound (descriptor, arity, 1);

	  arity -= 1;
	  create_static_range_type (range_type, value_type (low),
				    longest_to_int (value_as_long (low)),
				    longest_to_int (value_as_long (high)));
	  elt_type = create_array_type (array_type, elt_type, range_type);

	  if (ada_is_unconstrained_packed_array_type (value_type (arr)))
	    {
	      /* We need to store the element packed bitsize, as well as
		 recompute the array size, because it was previously
		 computed based on the unpacked element size.  */
	      LONGEST lo = value_as_long (low);
	      LONGEST hi = value_as_long (high);

	      TYPE_FIELD_BITSIZE (elt_type, 0) =
		decode_packed_array_bitsize (value_type (arr));
	      /* If the array has no element, then the size is already
		 zero, and does not need to be recomputed.  */
	      if (lo < hi)
		{
		  int array_bitsize =
			(hi - lo + 1) * TYPE_FIELD_BITSIZE (elt_type, 0);

		  TYPE_LENGTH (array_type) = (array_bitsize + 7) / 8;
		}
	    }
	}

      return lookup_pointer_type (elt_type);
    }
}

/* If ARR does not represent an array, returns ARR unchanged.
   Otherwise, returns either a standard GDB array with bounds set
   appropriately or, if ARR is a non-null fat pointer, a pointer to a standard
   GDB array.  Returns NULL if ARR is a null fat pointer.  */

struct value *
ada_coerce_to_simple_array_ptr (struct value *arr)
{
  if (ada_is_array_descriptor_type (value_type (arr)))
    {
      struct type *arrType = ada_type_of_array (arr, 1);

      if (arrType == NULL)
	return NULL;
      return value_cast (arrType, value_copy (desc_data (arr)));
    }
  else if (ada_is_constrained_packed_array_type (value_type (arr)))
    return decode_constrained_packed_array (arr);
  else
    return arr;
}

/* If ARR does not represent an array, returns ARR unchanged.
   Otherwise, returns a standard GDB array describing ARR (which may
   be ARR itself if it already is in the proper form).  */

struct value *
ada_coerce_to_simple_array (struct value *arr)
{
  if (ada_is_array_descriptor_type (value_type (arr)))
    {
      struct value *arrVal = ada_coerce_to_simple_array_ptr (arr);

      if (arrVal == NULL)
	error (_("Bounds unavailable for null array pointer."));
      return value_ind (arrVal);
    }
  else if (ada_is_constrained_packed_array_type (value_type (arr)))
    return decode_constrained_packed_array (arr);
  else
    return arr;
}

/* If TYPE represents a GNAT array type, return it translated to an
   ordinary GDB array type (possibly with BITSIZE fields indicating
   packing).  For other types, is the identity.  */

struct type *
ada_coerce_to_simple_array_type (struct type *type)
{
  if (ada_is_constrained_packed_array_type (type))
    return decode_constrained_packed_array_type (type);

  if (ada_is_array_descriptor_type (type))
    return ada_check_typedef (desc_data_target_type (type));

  return type;
}

/* Non-zero iff TYPE represents a standard GNAT packed-array type.  */

static int
ada_is_gnat_encoded_packed_array_type  (struct type *type)
{
  if (type == NULL)
    return 0;
  type = desc_base_type (type);
  type = ada_check_typedef (type);
  return
    ada_type_name (type) != NULL
    && strstr (ada_type_name (type), "___XP") != NULL;
}

/* Non-zero iff TYPE represents a standard GNAT constrained
   packed-array type.  */

int
ada_is_constrained_packed_array_type (struct type *type)
{
  return ada_is_gnat_encoded_packed_array_type (type)
    && !ada_is_array_descriptor_type (type);
}

/* Non-zero iff TYPE represents an array descriptor for a
   unconstrained packed-array type.  */

static int
ada_is_unconstrained_packed_array_type (struct type *type)
{
  if (!ada_is_array_descriptor_type (type))
    return 0;

  if (ada_is_gnat_encoded_packed_array_type (type))
    return 1;

  /* If we saw GNAT encodings, then the above code is sufficient.
     However, with minimal encodings, we will just have a thick
     pointer instead.  */
  if (is_thick_pntr (type))
    {
      type = desc_base_type (type);
      /* The structure's first field is a pointer to an array, so this
	 fetches the array type.  */
      type = TYPE_TARGET_TYPE (type->field (0).type ());
      if (type->code () == TYPE_CODE_TYPEDEF)
	type = ada_typedef_target_type (type);
      /* Now we can see if the array elements are packed.  */
      return TYPE_FIELD_BITSIZE (type, 0) > 0;
    }

  return 0;
}

/* Return true if TYPE is a (Gnat-encoded) constrained packed array
   type, or if it is an ordinary (non-Gnat-encoded) packed array.  */

static bool
ada_is_any_packed_array_type (struct type *type)
{
  return (ada_is_constrained_packed_array_type (type)
	  || (type->code () == TYPE_CODE_ARRAY
	      && TYPE_FIELD_BITSIZE (type, 0) % 8 != 0));
}

/* Given that TYPE encodes a packed array type (constrained or unconstrained),
   return the size of its elements in bits.  */

static long
decode_packed_array_bitsize (struct type *type)
{
  const char *raw_name;
  const char *tail;
  long bits;

  /* Access to arrays implemented as fat pointers are encoded as a typedef
     of the fat pointer type.  We need the name of the fat pointer type
     to do the decoding, so strip the typedef layer.  */
  if (type->code () == TYPE_CODE_TYPEDEF)
    type = ada_typedef_target_type (type);

  raw_name = ada_type_name (ada_check_typedef (type));
  if (!raw_name)
    raw_name = ada_type_name (desc_base_type (type));

  if (!raw_name)
    return 0;

  tail = strstr (raw_name, "___XP");
  if (tail == nullptr)
    {
      gdb_assert (is_thick_pntr (type));
      /* The structure's first field is a pointer to an array, so this
	 fetches the array type.  */
      type = TYPE_TARGET_TYPE (type->field (0).type ());
      /* Now we can see if the array elements are packed.  */
      return TYPE_FIELD_BITSIZE (type, 0);
    }

  if (sscanf (tail + sizeof ("___XP") - 1, "%ld", &bits) != 1)
    {
      lim_warning
	(_("could not understand bit size information on packed array"));
      return 0;
    }

  return bits;
}

/* Given that TYPE is a standard GDB array type with all bounds filled
   in, and that the element size of its ultimate scalar constituents
   (that is, either its elements, or, if it is an array of arrays, its
   elements' elements, etc.) is *ELT_BITS, return an identical type,
   but with the bit sizes of its elements (and those of any
   constituent arrays) recorded in the BITSIZE components of its
   TYPE_FIELD_BITSIZE values, and with *ELT_BITS set to its total size
   in bits.

   Note that, for arrays whose index type has an XA encoding where
   a bound references a record discriminant, getting that discriminant,
   and therefore the actual value of that bound, is not possible
   because none of the given parameters gives us access to the record.
   This function assumes that it is OK in the context where it is being
   used to return an array whose bounds are still dynamic and where
   the length is arbitrary.  */

static struct type *
constrained_packed_array_type (struct type *type, long *elt_bits)
{
  struct type *new_elt_type;
  struct type *new_type;
  struct type *index_type_desc;
  struct type *index_type;
  LONGEST low_bound, high_bound;

  type = ada_check_typedef (type);
  if (type->code () != TYPE_CODE_ARRAY)
    return type;

  index_type_desc = ada_find_parallel_type (type, "___XA");
  if (index_type_desc)
    index_type = to_fixed_range_type (index_type_desc->field (0).type (),
				      NULL);
  else
    index_type = type->index_type ();

  new_type = alloc_type_copy (type);
  new_elt_type =
    constrained_packed_array_type (ada_check_typedef (TYPE_TARGET_TYPE (type)),
				   elt_bits);
  create_array_type (new_type, new_elt_type, index_type);
  TYPE_FIELD_BITSIZE (new_type, 0) = *elt_bits;
  new_type->set_name (ada_type_name (type));

  if ((check_typedef (index_type)->code () == TYPE_CODE_RANGE
       && is_dynamic_type (check_typedef (index_type)))
      || !get_discrete_bounds (index_type, &low_bound, &high_bound))
    low_bound = high_bound = 0;
  if (high_bound < low_bound)
    *elt_bits = TYPE_LENGTH (new_type) = 0;
  else
    {
      *elt_bits *= (high_bound - low_bound + 1);
      TYPE_LENGTH (new_type) =
	(*elt_bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
    }

  new_type->set_is_fixed_instance (true);
  return new_type;
}

/* The array type encoded by TYPE, where
   ada_is_constrained_packed_array_type (TYPE).  */

static struct type *
decode_constrained_packed_array_type (struct type *type)
{
  const char *raw_name = ada_type_name (ada_check_typedef (type));
  char *name;
  const char *tail;
  struct type *shadow_type;
  long bits;

  if (!raw_name)
    raw_name = ada_type_name (desc_base_type (type));

  if (!raw_name)
    return NULL;

  name = (char *) alloca (strlen (raw_name) + 1);
  tail = strstr (raw_name, "___XP");
  type = desc_base_type (type);

  memcpy (name, raw_name, tail - raw_name);
  name[tail - raw_name] = '\000';

  shadow_type = ada_find_parallel_type_with_name (type, name);

  if (shadow_type == NULL)
    {
      lim_warning (_("could not find bounds information on packed array"));
      return NULL;
    }
  shadow_type = check_typedef (shadow_type);

  if (shadow_type->code () != TYPE_CODE_ARRAY)
    {
      lim_warning (_("could not understand bounds "
		     "information on packed array"));
      return NULL;
    }

  bits = decode_packed_array_bitsize (type);
  return constrained_packed_array_type (shadow_type, &bits);
}

/* Helper function for decode_constrained_packed_array.  Set the field
   bitsize on a series of packed arrays.  Returns the number of
   elements in TYPE.  */

static LONGEST
recursively_update_array_bitsize (struct type *type)
{
  gdb_assert (type->code () == TYPE_CODE_ARRAY);

  LONGEST low, high;
  if (!get_discrete_bounds (type->index_type (), &low, &high)
      || low > high)
    return 0;
  LONGEST our_len = high - low + 1;

  struct type *elt_type = TYPE_TARGET_TYPE (type);
  if (elt_type->code () == TYPE_CODE_ARRAY)
    {
      LONGEST elt_len = recursively_update_array_bitsize (elt_type);
      LONGEST elt_bitsize = elt_len * TYPE_FIELD_BITSIZE (elt_type, 0);
      TYPE_FIELD_BITSIZE (type, 0) = elt_bitsize;

      TYPE_LENGTH (type) = ((our_len * elt_bitsize + HOST_CHAR_BIT - 1)
			    / HOST_CHAR_BIT);
    }

  return our_len;
}

/* Given that ARR is a struct value *indicating a GNAT constrained packed
   array, returns a simple array that denotes that array.  Its type is a
   standard GDB array type except that the BITSIZEs of the array
   target types are set to the number of bits in each element, and the
   type length is set appropriately.  */

static struct value *
decode_constrained_packed_array (struct value *arr)
{
  struct type *type;

  /* If our value is a pointer, then dereference it. Likewise if
     the value is a reference.  Make sure that this operation does not
     cause the target type to be fixed, as this would indirectly cause
     this array to be decoded.  The rest of the routine assumes that
     the array hasn't been decoded yet, so we use the basic "coerce_ref"
     and "value_ind" routines to perform the dereferencing, as opposed
     to using "ada_coerce_ref" or "ada_value_ind".  */
  arr = coerce_ref (arr);
  if (ada_check_typedef (value_type (arr))->code () == TYPE_CODE_PTR)
    arr = value_ind (arr);

  type = decode_constrained_packed_array_type (value_type (arr));
  if (type == NULL)
    {
      error (_("can't unpack array"));
      return NULL;
    }

  /* Decoding the packed array type could not correctly set the field
     bitsizes for any dimension except the innermost, because the
     bounds may be variable and were not passed to that function.  So,
     we further resolve the array bounds here and then update the
     sizes.  */
  const gdb_byte *valaddr = value_contents_for_printing (arr).data ();
  CORE_ADDR address = value_address (arr);
  gdb::array_view<const gdb_byte> view
    = gdb::make_array_view (valaddr, TYPE_LENGTH (type));
  type = resolve_dynamic_type (type, view, address);
  recursively_update_array_bitsize (type);

  if (type_byte_order (value_type (arr)) == BFD_ENDIAN_BIG
      && ada_is_modular_type (value_type (arr)))
    {
       /* This is a (right-justified) modular type representing a packed
	  array with no wrapper.  In order to interpret the value through
	  the (left-justified) packed array type we just built, we must
	  first left-justify it.  */
      int bit_size, bit_pos;
      ULONGEST mod;

      mod = ada_modulus (value_type (arr)) - 1;
      bit_size = 0;
      while (mod > 0)
	{
	  bit_size += 1;
	  mod >>= 1;
	}
      bit_pos = HOST_CHAR_BIT * TYPE_LENGTH (value_type (arr)) - bit_size;
      arr = ada_value_primitive_packed_val (arr, NULL,
					    bit_pos / HOST_CHAR_BIT,
					    bit_pos % HOST_CHAR_BIT,
					    bit_size,
					    type);
    }

  return coerce_unspec_val_to_type (arr, type);
}


/* The value of the element of packed array ARR at the ARITY indices
   given in IND.   ARR must be a simple array.  */

static struct value *
value_subscript_packed (struct value *arr, int arity, struct value **ind)
{
  int i;
  int bits, elt_off, bit_off;
  long elt_total_bit_offset;
  struct type *elt_type;
  struct value *v;

  bits = 0;
  elt_total_bit_offset = 0;
  elt_type = ada_check_typedef (value_type (arr));
  for (i = 0; i < arity; i += 1)
    {
      if (elt_type->code () != TYPE_CODE_ARRAY
	  || TYPE_FIELD_BITSIZE (elt_type, 0) == 0)
	error
	  (_("attempt to do packed indexing of "
	     "something other than a packed array"));
      else
	{
	  struct type *range_type = elt_type->index_type ();
	  LONGEST lowerbound, upperbound;
	  LONGEST idx;

	  if (!get_discrete_bounds (range_type, &lowerbound, &upperbound))
	    {
	      lim_warning (_("don't know bounds of array"));
	      lowerbound = upperbound = 0;
	    }

	  idx = pos_atr (ind[i]);
	  if (idx < lowerbound || idx > upperbound)
	    lim_warning (_("packed array index %ld out of bounds"),
			 (long) idx);
	  bits = TYPE_FIELD_BITSIZE (elt_type, 0);
	  elt_total_bit_offset += (idx - lowerbound) * bits;
	  elt_type = ada_check_typedef (TYPE_TARGET_TYPE (elt_type));
	}
    }
  elt_off = elt_total_bit_offset / HOST_CHAR_BIT;
  bit_off = elt_total_bit_offset % HOST_CHAR_BIT;

  v = ada_value_primitive_packed_val (arr, NULL, elt_off, bit_off,
				      bits, elt_type);
  return v;
}

/* Non-zero iff TYPE includes negative integer values.  */

static int
has_negatives (struct type *type)
{
  switch (type->code ())
    {
    default:
      return 0;
    case TYPE_CODE_INT:
      return !type->is_unsigned ();
    case TYPE_CODE_RANGE:
      return type->bounds ()->low.const_val () - type->bounds ()->bias < 0;
    }
}

/* With SRC being a buffer containing BIT_SIZE bits of data at BIT_OFFSET,
   unpack that data into UNPACKED.  UNPACKED_LEN is the size in bytes of
   the unpacked buffer.

   The size of the unpacked buffer (UNPACKED_LEN) is expected to be large
   enough to contain at least BIT_OFFSET bits.  If not, an error is raised.

   IS_BIG_ENDIAN is nonzero if the data is stored in big endian mode,
   zero otherwise.

   IS_SIGNED_TYPE is nonzero if the data corresponds to a signed type.

   IS_SCALAR is nonzero if the data corresponds to a signed type.  */

static void
ada_unpack_from_contents (const gdb_byte *src, int bit_offset, int bit_size,
			  gdb_byte *unpacked, int unpacked_len,
			  int is_big_endian, int is_signed_type,
			  int is_scalar)
{
  int src_len = (bit_size + bit_offset + HOST_CHAR_BIT - 1) / 8;
  int src_idx;                  /* Index into the source area */
  int src_bytes_left;           /* Number of source bytes left to process.  */
  int srcBitsLeft;              /* Number of source bits left to move */
  int unusedLS;                 /* Number of bits in next significant
				   byte of source that are unused */

  int unpacked_idx;             /* Index into the unpacked buffer */
  int unpacked_bytes_left;      /* Number of bytes left to set in unpacked.  */

  unsigned long accum;          /* Staging area for bits being transferred */
  int accumSize;                /* Number of meaningful bits in accum */
  unsigned char sign;

  /* Transmit bytes from least to most significant; delta is the direction
     the indices move.  */
  int delta = is_big_endian ? -1 : 1;

  /* Make sure that unpacked is large enough to receive the BIT_SIZE
     bits from SRC.  .*/
  if ((bit_size + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT > unpacked_len)
    error (_("Cannot unpack %d bits into buffer of %d bytes"),
	   bit_size, unpacked_len);

  srcBitsLeft = bit_size;
  src_bytes_left = src_len;
  unpacked_bytes_left = unpacked_len;
  sign = 0;

  if (is_big_endian)
    {
      src_idx = src_len - 1;
      if (is_signed_type
	  && ((src[0] << bit_offset) & (1 << (HOST_CHAR_BIT - 1))))
	sign = ~0;

      unusedLS =
	(HOST_CHAR_BIT - (bit_size + bit_offset) % HOST_CHAR_BIT)
	% HOST_CHAR_BIT;

      if (is_scalar)
	{
	  accumSize = 0;
	  unpacked_idx = unpacked_len - 1;
	}
      else
	{
	  /* Non-scalar values must be aligned at a byte boundary...  */
	  accumSize =
	    (HOST_CHAR_BIT - bit_size % HOST_CHAR_BIT) % HOST_CHAR_BIT;
	  /* ... And are placed at the beginning (most-significant) bytes
	     of the target.  */
	  unpacked_idx = (bit_size + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT - 1;
	  unpacked_bytes_left = unpacked_idx + 1;
	}
    }
  else
    {
      int sign_bit_offset = (bit_size + bit_offset - 1) % 8;

      src_idx = unpacked_idx = 0;
      unusedLS = bit_offset;
      accumSize = 0;

      if (is_signed_type && (src[src_len - 1] & (1 << sign_bit_offset)))
	sign = ~0;
    }

  accum = 0;
  while (src_bytes_left > 0)
    {
      /* Mask for removing bits of the next source byte that are not
	 part of the value.  */
      unsigned int unusedMSMask =
	(1 << (srcBitsLeft >= HOST_CHAR_BIT ? HOST_CHAR_BIT : srcBitsLeft)) -
	1;
      /* Sign-extend bits for this byte.  */
      unsigned int signMask = sign & ~unusedMSMask;

      accum |=
	(((src[src_idx] >> unusedLS) & unusedMSMask) | signMask) << accumSize;
      accumSize += HOST_CHAR_BIT - unusedLS;
      if (accumSize >= HOST_CHAR_BIT)
	{
	  unpacked[unpacked_idx] = accum & ~(~0UL << HOST_CHAR_BIT);
	  accumSize -= HOST_CHAR_BIT;
	  accum >>= HOST_CHAR_BIT;
	  unpacked_bytes_left -= 1;
	  unpacked_idx += delta;
	}
      srcBitsLeft -= HOST_CHAR_BIT - unusedLS;
      unusedLS = 0;
      src_bytes_left -= 1;
      src_idx += delta;
    }
  while (unpacked_bytes_left > 0)
    {
      accum |= sign << accumSize;
      unpacked[unpacked_idx] = accum & ~(~0UL << HOST_CHAR_BIT);
      accumSize -= HOST_CHAR_BIT;
      if (accumSize < 0)
	accumSize = 0;
      accum >>= HOST_CHAR_BIT;
      unpacked_bytes_left -= 1;
      unpacked_idx += delta;
    }
}

/* Create a new value of type TYPE from the contents of OBJ starting
   at byte OFFSET, and bit offset BIT_OFFSET within that byte,
   proceeding for BIT_SIZE bits.  If OBJ is an lval in memory, then
   assigning through the result will set the field fetched from.
   VALADDR is ignored unless OBJ is NULL, in which case,
   VALADDR+OFFSET must address the start of storage containing the 
   packed value.  The value returned  in this case is never an lval.
   Assumes 0 <= BIT_OFFSET < HOST_CHAR_BIT.  */

struct value *
ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr,
				long offset, int bit_offset, int bit_size,
				struct type *type)
{
  struct value *v;
  const gdb_byte *src;                /* First byte containing data to unpack */
  gdb_byte *unpacked;
  const int is_scalar = is_scalar_type (type);
  const int is_big_endian = type_byte_order (type) == BFD_ENDIAN_BIG;
  gdb::byte_vector staging;

  type = ada_check_typedef (type);

  if (obj == NULL)
    src = valaddr + offset;
  else
    src = value_contents (obj).data () + offset;

  if (is_dynamic_type (type))
    {
      /* The length of TYPE might by dynamic, so we need to resolve
	 TYPE in order to know its actual size, which we then use
	 to create the contents buffer of the value we return.
	 The difficulty is that the data containing our object is
	 packed, and therefore maybe not at a byte boundary.  So, what
	 we do, is unpack the data into a byte-aligned buffer, and then
	 use that buffer as our object's value for resolving the type.  */
      int staging_len = (bit_size + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
      staging.resize (staging_len);

      ada_unpack_from_contents (src, bit_offset, bit_size,
				staging.data (), staging.size (),
				is_big_endian, has_negatives (type),
				is_scalar);
      type = resolve_dynamic_type (type, staging, 0);
      if (TYPE_LENGTH (type) < (bit_size + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT)
	{
	  /* This happens when the length of the object is dynamic,
	     and is actually smaller than the space reserved for it.
	     For instance, in an array of variant records, the bit_size
	     we're given is the array stride, which is constant and
	     normally equal to the maximum size of its element.
	     But, in reality, each element only actually spans a portion
	     of that stride.  */
	  bit_size = TYPE_LENGTH (type) * HOST_CHAR_BIT;
	}
    }

  if (obj == NULL)
    {
      v = allocate_value (type);
      src = valaddr + offset;
    }
  else if (VALUE_LVAL (obj) == lval_memory && value_lazy (obj))
    {
      int src_len = (bit_size + bit_offset + HOST_CHAR_BIT - 1) / 8;
      gdb_byte *buf;

      v = value_at (type, value_address (obj) + offset);
      buf = (gdb_byte *) alloca (src_len);
      read_memory (value_address (v), buf, src_len);
      src = buf;
    }
  else
    {
      v = allocate_value (type);
      src = value_contents (obj).data () + offset;
    }

  if (obj != NULL)
    {
      long new_offset = offset;

      set_value_component_location (v, obj);
      set_value_bitpos (v, bit_offset + value_bitpos (obj));
      set_value_bitsize (v, bit_size);
      if (value_bitpos (v) >= HOST_CHAR_BIT)
	{
	  ++new_offset;
	  set_value_bitpos (v, value_bitpos (v) - HOST_CHAR_BIT);
	}
      set_value_offset (v, new_offset);

      /* Also set the parent value.  This is needed when trying to
	 assign a new value (in inferior memory).  */
      set_value_parent (v, obj);
    }
  else
    set_value_bitsize (v, bit_size);
  unpacked = value_contents_writeable (v).data ();

  if (bit_size == 0)
    {
      memset (unpacked, 0, TYPE_LENGTH (type));
      return v;
    }

  if (staging.size () == TYPE_LENGTH (type))
    {
      /* Small short-cut: If we've unpacked the data into a buffer
	 of the same size as TYPE's length, then we can reuse that,
	 instead of doing the unpacking again.  */
      memcpy (unpacked, staging.data (), staging.size ());
    }
  else
    ada_unpack_from_contents (src, bit_offset, bit_size,
			      unpacked, TYPE_LENGTH (type),
			      is_big_endian, has_negatives (type), is_scalar);

  return v;
}

/* Store the contents of FROMVAL into the location of TOVAL.
   Return a new value with the location of TOVAL and contents of
   FROMVAL.   Handles assignment into packed fields that have
   floating-point or non-scalar types.  */

static struct value *
ada_value_assign (struct value *toval, struct value *fromval)
{
  struct type *type = value_type (toval);
  int bits = value_bitsize (toval);

  toval = ada_coerce_ref (toval);
  fromval = ada_coerce_ref (fromval);

  if (ada_is_direct_array_type (value_type (toval)))
    toval = ada_coerce_to_simple_array (toval);
  if (ada_is_direct_array_type (value_type (fromval)))
    fromval = ada_coerce_to_simple_array (fromval);

  if (!deprecated_value_modifiable (toval))
    error (_("Left operand of assignment is not a modifiable lvalue."));

  if (VALUE_LVAL (toval) == lval_memory
      && bits > 0
      && (type->code () == TYPE_CODE_FLT
	  || type->code () == TYPE_CODE_STRUCT))
    {
      int len = (value_bitpos (toval)
		 + bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
      int from_size;
      gdb_byte *buffer = (gdb_byte *) alloca (len);
      struct value *val;
      CORE_ADDR to_addr = value_address (toval);

      if (type->code () == TYPE_CODE_FLT)
	fromval = value_cast (type, fromval);

      read_memory (to_addr, buffer, len);
      from_size = value_bitsize (fromval);
      if (from_size == 0)
	from_size = TYPE_LENGTH (value_type (fromval)) * TARGET_CHAR_BIT;

      const int is_big_endian = type_byte_order (type) == BFD_ENDIAN_BIG;
      ULONGEST from_offset = 0;
      if (is_big_endian && is_scalar_type (value_type (fromval)))
	from_offset = from_size - bits;
      copy_bitwise (buffer, value_bitpos (toval),
		    value_contents (fromval).data (), from_offset,
		    bits, is_big_endian);
      write_memory_with_notification (to_addr, buffer, len);

      val = value_copy (toval);
      memcpy (value_contents_raw (val).data (),
	      value_contents (fromval).data (),
	      TYPE_LENGTH (type));
      deprecated_set_value_type (val, type);

      return val;
    }

  return value_assign (toval, fromval);
}


/* Given that COMPONENT is a memory lvalue that is part of the lvalue
   CONTAINER, assign the contents of VAL to COMPONENTS's place in
   CONTAINER.  Modifies the VALUE_CONTENTS of CONTAINER only, not
   COMPONENT, and not the inferior's memory.  The current contents
   of COMPONENT are ignored.

   Although not part of the initial design, this function also works
   when CONTAINER and COMPONENT are not_lval's: it works as if CONTAINER
   had a null address, and COMPONENT had an address which is equal to
   its offset inside CONTAINER.  */

static void
value_assign_to_component (struct value *container, struct value *component,
			   struct value *val)
{
  LONGEST offset_in_container =
    (LONGEST)  (value_address (component) - value_address (container));
  int bit_offset_in_container =
    value_bitpos (component) - value_bitpos (container);
  int bits;

  val = value_cast (value_type (component), val);

  if (value_bitsize (component) == 0)
    bits = TARGET_CHAR_BIT * TYPE_LENGTH (value_type (component));
  else
    bits = value_bitsize (component);

  if (type_byte_order (value_type (container)) == BFD_ENDIAN_BIG)
    {
      int src_offset;

      if (is_scalar_type (check_typedef (value_type (component))))
	src_offset
	  = TYPE_LENGTH (value_type (component)) * TARGET_CHAR_BIT - bits;
      else
	src_offset = 0;
      copy_bitwise ((value_contents_writeable (container).data ()
		     + offset_in_container),
		    value_bitpos (container) + bit_offset_in_container,
		    value_contents (val).data (), src_offset, bits, 1);
    }
  else
    copy_bitwise ((value_contents_writeable (container).data ()
		   + offset_in_container),
		  value_bitpos (container) + bit_offset_in_container,
		  value_contents (val).data (), 0, bits, 0);
}

/* Determine if TYPE is an access to an unconstrained array.  */

bool
ada_is_access_to_unconstrained_array (struct type *type)
{
  return (type->code () == TYPE_CODE_TYPEDEF
	  && is_thick_pntr (ada_typedef_target_type (type)));
}

/* The value of the element of array ARR at the ARITY indices given in IND.
   ARR may be either a simple array, GNAT array descriptor, or pointer
   thereto.  */

struct value *
ada_value_subscript (struct value *arr, int arity, struct value **ind)
{
  int k;
  struct value *elt;
  struct type *elt_type;

  elt = ada_coerce_to_simple_array (arr);

  elt_type = ada_check_typedef (value_type (elt));
  if (elt_type->code () == TYPE_CODE_ARRAY
      && TYPE_FIELD_BITSIZE (elt_type, 0) > 0)
    return value_subscript_packed (elt, arity, ind);

  for (k = 0; k < arity; k += 1)
    {
      struct type *saved_elt_type = TYPE_TARGET_TYPE (elt_type);

      if (elt_type->code () != TYPE_CODE_ARRAY)
	error (_("too many subscripts (%d expected)"), k);

      elt = value_subscript (elt, pos_atr (ind[k]));

      if (ada_is_access_to_unconstrained_array (saved_elt_type)
	  && value_type (elt)->code () != TYPE_CODE_TYPEDEF)
	{
	  /* The element is a typedef to an unconstrained array,
	     except that the value_subscript call stripped the
	     typedef layer.  The typedef layer is GNAT's way to
	     specify that the element is, at the source level, an
	     access to the unconstrained array, rather than the
	     unconstrained array.  So, we need to restore that
	     typedef layer, which we can do by forcing the element's
	     type back to its original type. Otherwise, the returned
	     value is going to be printed as the array, rather
	     than as an access.  Another symptom of the same issue
	     would be that an expression trying to dereference the
	     element would also be improperly rejected.  */
	  deprecated_set_value_type (elt, saved_elt_type);
	}

      elt_type = ada_check_typedef (value_type (elt));
    }

  return elt;
}

/* Assuming ARR is a pointer to a GDB array, the value of the element
   of *ARR at the ARITY indices given in IND.
   Does not read the entire array into memory.

   Note: Unlike what one would expect, this function is used instead of
   ada_value_subscript for basically all non-packed array types.  The reason
   for this is that a side effect of doing our own pointer arithmetics instead
   of relying on value_subscript is that there is no implicit typedef peeling.
   This is important for arrays of array accesses, where it allows us to
   preserve the fact that the array's element is an array access, where the
   access part os encoded in a typedef layer.  */

static struct value *
ada_value_ptr_subscript (struct value *arr, int arity, struct value **ind)
{
  int k;
  struct value *array_ind = ada_value_ind (arr);
  struct type *type
    = check_typedef (value_enclosing_type (array_ind));

  if (type->code () == TYPE_CODE_ARRAY
      && TYPE_FIELD_BITSIZE (type, 0) > 0)
    return value_subscript_packed (array_ind, arity, ind);

  for (k = 0; k < arity; k += 1)
    {
      LONGEST lwb, upb;

      if (type->code () != TYPE_CODE_ARRAY)
	error (_("too many subscripts (%d expected)"), k);
      arr = value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
			value_copy (arr));
      get_discrete_bounds (type->index_type (), &lwb, &upb);
      arr = value_ptradd (arr, pos_atr (ind[k]) - lwb);
      type = TYPE_TARGET_TYPE (type);
    }

  return value_ind (arr);
}

/* Given that ARRAY_PTR is a pointer or reference to an array of type TYPE (the
   actual type of ARRAY_PTR is ignored), returns the Ada slice of
   HIGH'Pos-LOW'Pos+1 elements starting at index LOW.  The lower bound of
   this array is LOW, as per Ada rules.  */
static struct value *
ada_value_slice_from_ptr (struct value *array_ptr, struct type *type,
			  int low, int high)
{
  struct type *type0 = ada_check_typedef (type);
  struct type *base_index_type = TYPE_TARGET_TYPE (type0->index_type ());
  struct type *index_type
    = create_static_range_type (NULL, base_index_type, low, high);
  struct type *slice_type = create_array_type_with_stride
			      (NULL, TYPE_TARGET_TYPE (type0), index_type,
			       type0->dyn_prop (DYN_PROP_BYTE_STRIDE),
			       TYPE_FIELD_BITSIZE (type0, 0));
  int base_low =  ada_discrete_type_low_bound (type0->index_type ());
  gdb::optional<LONGEST> base_low_pos, low_pos;
  CORE_ADDR base;

  low_pos = discrete_position (base_index_type, low);
  base_low_pos = discrete_position (base_index_type, base_low);

  if (!low_pos.has_value () || !base_low_pos.has_value ())
    {
      warning (_("unable to get positions in slice, use bounds instead"));
      low_pos = low;
      base_low_pos = base_low;
    }

  ULONGEST stride = TYPE_FIELD_BITSIZE (slice_type, 0) / 8;
  if (stride == 0)
    stride = TYPE_LENGTH (TYPE_TARGET_TYPE (type0));

  base = value_as_address (array_ptr) + (*low_pos - *base_low_pos) * stride;
  return value_at_lazy (slice_type, base);
}


static struct value *
ada_value_slice (struct value *array, int low, int high)
{
  struct type *type = ada_check_typedef (value_type (array));
  struct type *base_index_type = TYPE_TARGET_TYPE (type->index_type ());
  struct type *index_type
    = create_static_range_type (NULL, type->index_type (), low, high);
  struct type *slice_type = create_array_type_with_stride
			      (NULL, TYPE_TARGET_TYPE (type), index_type,
			       type->dyn_prop (DYN_PROP_BYTE_STRIDE),
			       TYPE_FIELD_BITSIZE (type, 0));
  gdb::optional<LONGEST> low_pos, high_pos;


  low_pos = discrete_position (base_index_type, low);
  high_pos = discrete_position (base_index_type, high);

  if (!low_pos.has_value () || !high_pos.has_value ())
    {
      warning (_("unable to get positions in slice, use bounds instead"));
      low_pos = low;
      high_pos = high;
    }

  return value_cast (slice_type,
		     value_slice (array, low, *high_pos - *low_pos + 1));
}

/* If type is a record type in the form of a standard GNAT array
   descriptor, returns the number of dimensions for type.  If arr is a
   simple array, returns the number of "array of"s that prefix its
   type designation.  Otherwise, returns 0.  */

int
ada_array_arity (struct type *type)
{
  int arity;

  if (type == NULL)
    return 0;

  type = desc_base_type (type);

  arity = 0;
  if (type->code () == TYPE_CODE_STRUCT)
    return desc_arity (desc_bounds_type (type));
  else
    while (type->code () == TYPE_CODE_ARRAY)
      {
	arity += 1;
	type = ada_check_typedef (TYPE_TARGET_TYPE (type));
      }

  return arity;
}

/* If TYPE is a record type in the form of a standard GNAT array
   descriptor or a simple array type, returns the element type for
   TYPE after indexing by NINDICES indices, or by all indices if
   NINDICES is -1.  Otherwise, returns NULL.  */

struct type *
ada_array_element_type (struct type *type, int nindices)
{
  type = desc_base_type (type);

  if (type->code () == TYPE_CODE_STRUCT)
    {
      int k;
      struct type *p_array_type;

      p_array_type = desc_data_target_type (type);

      k = ada_array_arity (type);
      if (k == 0)
	return NULL;

      /* Initially p_array_type = elt_type(*)[]...(k times)...[].  */
      if (nindices >= 0 && k > nindices)
	k = nindices;
      while (k > 0 && p_array_type != NULL)
	{
	  p_array_type = ada_check_typedef (TYPE_TARGET_TYPE (p_array_type));
	  k -= 1;
	}
      return p_array_type;
    }
  else if (type->code () == TYPE_CODE_ARRAY)
    {
      while (nindices != 0 && type->code () == TYPE_CODE_ARRAY)
	{
	  type = TYPE_TARGET_TYPE (type);
	  nindices -= 1;
	}
      return type;
    }

  return NULL;
}

/* See ada-lang.h.  */

struct type *
ada_index_type (struct type *type, int n, const char *name)
{
  struct type *result_type;

  type = desc_base_type (type);

  if (n < 0 || n > ada_array_arity (type))
    error (_("invalid dimension number to '%s"), name);

  if (ada_is_simple_array_type (type))
    {
      int i;

      for (i = 1; i < n; i += 1)
	{
	  type = ada_check_typedef (type);
	  type = TYPE_TARGET_TYPE (type);
	}
      result_type = TYPE_TARGET_TYPE (ada_check_typedef (type)->index_type ());
      /* FIXME: The stabs type r(0,0);bound;bound in an array type
	 has a target type of TYPE_CODE_UNDEF.  We compensate here, but
	 perhaps stabsread.c would make more sense.  */
      if (result_type && result_type->code () == TYPE_CODE_UNDEF)
	result_type = NULL;
    }
  else
    {
      result_type = desc_index_type (desc_bounds_type (type), n);
      if (result_type == NULL)
	error (_("attempt to take bound of something that is not an array"));
    }

  return result_type;
}

/* Given that arr is an array type, returns the lower bound of the
   Nth index (numbering from 1) if WHICH is 0, and the upper bound if
   WHICH is 1.  This returns bounds 0 .. -1 if ARR_TYPE is an
   array-descriptor type.  It works for other arrays with bounds supplied
   by run-time quantities other than discriminants.  */

static LONGEST
ada_array_bound_from_type (struct type *arr_type, int n, int which)
{
  struct type *type, *index_type_desc, *index_type;
  int i;

  gdb_assert (which == 0 || which == 1);

  if (ada_is_constrained_packed_array_type (arr_type))
    arr_type = decode_constrained_packed_array_type (arr_type);

  if (arr_type == NULL || !ada_is_simple_array_type (arr_type))
    return (LONGEST) - which;

  if (arr_type->code () == TYPE_CODE_PTR)
    type = TYPE_TARGET_TYPE (arr_type);
  else
    type = arr_type;

  if (type->is_fixed_instance ())
    {
      /* The array has already been fixed, so we do not need to
	 check the parallel ___XA type again.  That encoding has
	 already been applied, so ignore it now.  */
      index_type_desc = NULL;
    }
  else
    {
      index_type_desc = ada_find_parallel_type (type, "___XA");
      ada_fixup_array_indexes_type (index_type_desc);
    }

  if (index_type_desc != NULL)
    index_type = to_fixed_range_type (index_type_desc->field (n - 1).type (),
				      NULL);
  else
    {
      struct type *elt_type = check_typedef (type);

      for (i = 1; i < n; i++)
	elt_type = check_typedef (TYPE_TARGET_TYPE (elt_type));

      index_type = elt_type->index_type ();
    }

  return
    (LONGEST) (which == 0
	       ? ada_discrete_type_low_bound (index_type)
	       : ada_discrete_type_high_bound (index_type));
}

/* Given that arr is an array value, returns the lower bound of the
   nth index (numbering from 1) if WHICH is 0, and the upper bound if
   WHICH is 1.  This routine will also work for arrays with bounds
   supplied by run-time quantities other than discriminants.  */

static LONGEST
ada_array_bound (struct value *arr, int n, int which)
{
  struct type *arr_type;

  if (check_typedef (value_type (arr))->code () == TYPE_CODE_PTR)
    arr = value_ind (arr);
  arr_type = value_enclosing_type (arr);

  if (ada_is_constrained_packed_array_type (arr_type))
    return ada_array_bound (decode_constrained_packed_array (arr), n, which);
  else if (ada_is_simple_array_type (arr_type))
    return ada_array_bound_from_type (arr_type, n, which);
  else
    return value_as_long (desc_one_bound (desc_bounds (arr), n, which));
}

/* Given that arr is an array value, returns the length of the
   nth index.  This routine will also work for arrays with bounds
   supplied by run-time quantities other than discriminants.
   Does not work for arrays indexed by enumeration types with representation
   clauses at the moment.  */

static LONGEST
ada_array_length (struct value *arr, int n)
{
  struct type *arr_type, *index_type;
  int low, high;

  if (check_typedef (value_type (arr))->code () == TYPE_CODE_PTR)
    arr = value_ind (arr);
  arr_type = value_enclosing_type (arr);

  if (ada_is_constrained_packed_array_type (arr_type))
    return ada_array_length (decode_constrained_packed_array (arr), n);

  if (ada_is_simple_array_type (arr_type))
    {
      low = ada_array_bound_from_type (arr_type, n, 0);
      high = ada_array_bound_from_type (arr_type, n, 1);
    }
  else
    {
      low = value_as_long (desc_one_bound (desc_bounds (arr), n, 0));
      high = value_as_long (desc_one_bound (desc_bounds (arr), n, 1));
    }

  arr_type = check_typedef (arr_type);
  index_type = ada_index_type (arr_type, n, "length");
  if (index_type != NULL)
    {
      struct type *base_type;
      if (index_type->code () == TYPE_CODE_RANGE)
	base_type = TYPE_TARGET_TYPE (index_type);
      else
	base_type = index_type;

      low = pos_atr (value_from_longest (base_type, low));
      high = pos_atr (value_from_longest (base_type, high));
    }
  return high - low + 1;
}

/* An array whose type is that of ARR_TYPE (an array type), with
   bounds LOW to HIGH, but whose contents are unimportant.  If HIGH is
   less than LOW, then LOW-1 is used.  */

static struct value *
empty_array (struct type *arr_type, int low, int high)
{
  struct type *arr_type0 = ada_check_typedef (arr_type);
  struct type *index_type
    = create_static_range_type
	(NULL, TYPE_TARGET_TYPE (arr_type0->index_type ()), low,
	 high < low ? low - 1 : high);
  struct type *elt_type = ada_array_element_type (arr_type0, 1);

  return allocate_value (create_array_type (NULL, elt_type, index_type));
}


				/* Name resolution */

/* The "decoded" name for the user-definable Ada operator corresponding
   to OP.  */

static const char *
ada_decoded_op_name (enum exp_opcode op)
{
  int i;

  for (i = 0; ada_opname_table[i].encoded != NULL; i += 1)
    {
      if (ada_opname_table[i].op == op)
	return ada_opname_table[i].decoded;
    }
  error (_("Could not find operator name for opcode"));
}

/* Returns true (non-zero) iff decoded name N0 should appear before N1
   in a listing of choices during disambiguation (see sort_choices, below).
   The idea is that overloadings of a subprogram name from the
   same package should sort in their source order.  We settle for ordering
   such symbols by their trailing number (__N  or $N).  */

static int
encoded_ordered_before (const char *N0, const char *N1)
{
  if (N1 == NULL)
    return 0;
  else if (N0 == NULL)
    return 1;
  else
    {
      int k0, k1;

      for (k0 = strlen (N0) - 1; k0 > 0 && isdigit (N0[k0]); k0 -= 1)
	;
      for (k1 = strlen (N1) - 1; k1 > 0 && isdigit (N1[k1]); k1 -= 1)
	;
      if ((N0[k0] == '_' || N0[k0] == '$') && N0[k0 + 1] != '\000'
	  && (N1[k1] == '_' || N1[k1] == '$') && N1[k1 + 1] != '\000')
	{
	  int n0, n1;

	  n0 = k0;
	  while (N0[n0] == '_' && n0 > 0 && N0[n0 - 1] == '_')
	    n0 -= 1;
	  n1 = k1;
	  while (N1[n1] == '_' && n1 > 0 && N1[n1 - 1] == '_')
	    n1 -= 1;
	  if (n0 == n1 && strncmp (N0, N1, n0) == 0)
	    return (atoi (N0 + k0 + 1) < atoi (N1 + k1 + 1));
	}
      return (strcmp (N0, N1) < 0);
    }
}

/* Sort SYMS[0..NSYMS-1] to put the choices in a canonical order by the
   encoded names.  */

static void
sort_choices (struct block_symbol syms[], int nsyms)
{
  int i;

  for (i = 1; i < nsyms; i += 1)
    {
      struct block_symbol sym = syms[i];
      int j;

      for (j = i - 1; j >= 0; j -= 1)
	{
	  if (encoded_ordered_before (syms[j].symbol->linkage_name (),
				      sym.symbol->linkage_name ()))
	    break;
	  syms[j + 1] = syms[j];
	}
      syms[j + 1] = sym;
    }
}

/* Whether GDB should display formals and return types for functions in the
   overloads selection menu.  */
static bool print_signatures = true;

/* Print the signature for SYM on STREAM according to the FLAGS options.  For
   all but functions, the signature is just the name of the symbol.  For
   functions, this is the name of the function, the list of types for formals
   and the return type (if any).  */

static void
ada_print_symbol_signature (struct ui_file *stream, struct symbol *sym,
			    const struct type_print_options *flags)
{
  struct type *type = sym->type ();

  gdb_printf (stream, "%s", sym->print_name ());
  if (!print_signatures
      || type == NULL
      || type->code () != TYPE_CODE_FUNC)
    return;

  if (type->num_fields () > 0)
    {
      int i;

      gdb_printf (stream, " (");
      for (i = 0; i < type->num_fields (); ++i)
	{
	  if (i > 0)
	    gdb_printf (stream, "; ");
	  ada_print_type (type->field (i).type (), NULL, stream, -1, 0,
			  flags);
	}
      gdb_printf (stream, ")");
    }
  if (TYPE_TARGET_TYPE (type) != NULL
      && TYPE_TARGET_TYPE (type)->code () != TYPE_CODE_VOID)
    {
      gdb_printf (stream, " return ");
      ada_print_type (TYPE_TARGET_TYPE (type), NULL, stream, -1, 0, flags);
    }
}

/* Read and validate a set of numeric choices from the user in the
   range 0 .. N_CHOICES-1.  Place the results in increasing
   order in CHOICES[0 .. N-1], and return N.

   The user types choices as a sequence of numbers on one line
   separated by blanks, encoding them as follows:

     + A choice of 0 means to cancel the selection, throwing an error.
     + If IS_ALL_CHOICE, a choice of 1 selects the entire set 0 .. N_CHOICES-1.
     + The user chooses k by typing k+IS_ALL_CHOICE+1.

   The user is not allowed to choose more than MAX_RESULTS values.

   ANNOTATION_SUFFIX, if present, is used to annotate the input
   prompts (for use with the -f switch).  */

static int
get_selections (int *choices, int n_choices, int max_results,
		int is_all_choice, const char *annotation_suffix)
{
  const char *args;
  const char *prompt;
  int n_chosen;
  int first_choice = is_all_choice ? 2 : 1;

  prompt = getenv ("PS2");
  if (prompt == NULL)
    prompt = "> ";

  args = command_line_input (prompt, annotation_suffix);

  if (args == NULL)
    error_no_arg (_("one or more choice numbers"));

  n_chosen = 0;

  /* Set choices[0 .. n_chosen-1] to the users' choices in ascending
     order, as given in args.  Choices are validated.  */
  while (1)
    {
      char *args2;
      int choice, j;

      args = skip_spaces (args);
      if (*args == '\0' && n_chosen == 0)
	error_no_arg (_("one or more choice numbers"));
      else if (*args == '\0')
	break;

      choice = strtol (args, &args2, 10);
      if (args == args2 || choice < 0
	  || choice > n_choices + first_choice - 1)
	error (_("Argument must be choice number"));
      args = args2;

      if (choice == 0)
	error (_("cancelled"));

      if (choice < first_choice)
	{
	  n_chosen = n_choices;
	  for (j = 0; j < n_choices; j += 1)
	    choices[j] = j;
	  break;
	}
      choice -= first_choice;

      for (j = n_chosen - 1; j >= 0 && choice < choices[j]; j -= 1)
	{
	}

      if (j < 0 || choice != choices[j])
	{
	  int k;

	  for (k = n_chosen - 1; k > j; k -= 1)
	    choices[k + 1] = choices[k];
	  choices[j + 1] = choice;
	  n_chosen += 1;
	}
    }

  if (n_chosen > max_results)
    error (_("Select no more than %d of the above"), max_results);

  return n_chosen;
}

/* Given a list of NSYMS symbols in SYMS, select up to MAX_RESULTS>0
   by asking the user (if necessary), returning the number selected,
   and setting the first elements of SYMS items.  Error if no symbols
   selected.  */

/* NOTE: Adapted from decode_line_2 in symtab.c, with which it ought
   to be re-integrated one of these days.  */

static int
user_select_syms (struct block_symbol *syms, int nsyms, int max_results)
{
  int i;
  int *chosen = XALLOCAVEC (int , nsyms);
  int n_chosen;
  int first_choice = (max_results == 1) ? 1 : 2;
  const char *select_mode = multiple_symbols_select_mode ();

  if (max_results < 1)
    error (_("Request to select 0 symbols!"));
  if (nsyms <= 1)
    return nsyms;

  if (select_mode == multiple_symbols_cancel)
    error (_("\
canceled because the command is ambiguous\n\
See set/show multiple-symbol."));

  /* If select_mode is "all", then return all possible symbols.
     Only do that if more than one symbol can be selected, of course.
     Otherwise, display the menu as usual.  */
  if (select_mode == multiple_symbols_all && max_results > 1)
    return nsyms;

  gdb_printf (_("[0] cancel\n"));
  if (max_results > 1)
    gdb_printf (_("[1] all\n"));

  sort_choices (syms, nsyms);

  for (i = 0; i < nsyms; i += 1)
    {
      if (syms[i].symbol == NULL)
	continue;

      if (syms[i].symbol->aclass () == LOC_BLOCK)
	{
	  struct symtab_and_line sal =
	    find_function_start_sal (syms[i].symbol, 1);

	  gdb_printf ("[%d] ", i + first_choice);
	  ada_print_symbol_signature (gdb_stdout, syms[i].symbol,
				      &type_print_raw_options);
	  if (sal.symtab == NULL)
	    gdb_printf (_(" at %p[<no source file available>%p]:%d\n"),
			metadata_style.style ().ptr (), nullptr, sal.line);
	  else
	    gdb_printf
	      (_(" at %ps:%d\n"),
	       styled_string (file_name_style.style (),
			      symtab_to_filename_for_display (sal.symtab)),
	       sal.line);
	  continue;
	}
      else
	{
	  int is_enumeral =
	    (syms[i].symbol->aclass () == LOC_CONST
	     && syms[i].symbol->type () != NULL
	     && syms[i].symbol->type ()->code () == TYPE_CODE_ENUM);
	  struct symtab *symtab = NULL;

	  if (syms[i].symbol->is_objfile_owned ())
	    symtab = syms[i].symbol->symtab ();

	  if (syms[i].symbol->line () != 0 && symtab != NULL)
	    {
	      gdb_printf ("[%d] ", i + first_choice);
	      ada_print_symbol_signature (gdb_stdout, syms[i].symbol,
					  &type_print_raw_options);
	      gdb_printf (_(" at %s:%d\n"),
			  symtab_to_filename_for_display (symtab),
			  syms[i].symbol->line ());
	    }
	  else if (is_enumeral
		   && syms[i].symbol->type ()->name () != NULL)
	    {
	      gdb_printf (("[%d] "), i + first_choice);
	      ada_print_type (syms[i].symbol->type (), NULL,
			      gdb_stdout, -1, 0, &type_print_raw_options);
	      gdb_printf (_("'(%s) (enumeral)\n"),
			  syms[i].symbol->print_name ());
	    }
	  else
	    {
	      gdb_printf ("[%d] ", i + first_choice);
	      ada_print_symbol_signature (gdb_stdout, syms[i].symbol,
					  &type_print_raw_options);

	      if (symtab != NULL)
		gdb_printf (is_enumeral
			    ? _(" in %s (enumeral)\n")
			    : _(" at %s:?\n"),
			    symtab_to_filename_for_display (symtab));
	      else
		gdb_printf (is_enumeral
			    ? _(" (enumeral)\n")
			    : _(" at ?\n"));
	    }
	}
    }

  n_chosen = get_selections (chosen, nsyms, max_results, max_results > 1,
			     "overload-choice");

  for (i = 0; i < n_chosen; i += 1)
    syms[i] = syms[chosen[i]];

  return n_chosen;
}

/* See ada-lang.h.  */

block_symbol
ada_find_operator_symbol (enum exp_opcode op, bool parse_completion,
			  int nargs, value *argvec[])
{
  if (possible_user_operator_p (op, argvec))
    {
      std::vector<struct block_symbol> candidates
	= ada_lookup_symbol_list (ada_decoded_op_name (op),
				  NULL, VAR_DOMAIN);

      int i = ada_resolve_function (candidates, argvec,
				    nargs, ada_decoded_op_name (op), NULL,
				    parse_completion);
      if (i >= 0)
	return candidates[i];
    }
  return {};
}

/* See ada-lang.h.  */

block_symbol
ada_resolve_funcall (struct symbol *sym, const struct block *block,
		     struct type *context_type,
		     bool parse_completion,
		     int nargs, value *argvec[],
		     innermost_block_tracker *tracker)
{
  std::vector<struct block_symbol> candidates
    = ada_lookup_symbol_list (sym->linkage_name (), block, VAR_DOMAIN);

  int i;
  if (candidates.size () == 1)
    i = 0;
  else
    {
      i = ada_resolve_function
	(candidates,
	 argvec, nargs,
	 sym->linkage_name (),
	 context_type, parse_completion);
      if (i < 0)
	error (_("Could not find a match for %s"), sym->print_name ());
    }

  tracker->update (candidates[i]);
  return candidates[i];
}

/* Resolve a mention of a name where the context type is an
   enumeration type.  */

static int
ada_resolve_enum (std::vector<struct block_symbol> &syms,
		  const char *name, struct type *context_type,
		  bool parse_completion)
{
  gdb_assert (context_type->code () == TYPE_CODE_ENUM);
  context_type = ada_check_typedef (context_type);

  for (int i = 0; i < syms.size (); ++i)
    {
      /* We already know the name matches, so we're just looking for
	 an element of the correct enum type.  */
      if (ada_check_typedef (syms[i].symbol->type ()) == context_type)
	return i;
    }

  error (_("No name '%s' in enumeration type '%s'"), name,
	 ada_type_name (context_type));
}

/* See ada-lang.h.  */

block_symbol
ada_resolve_variable (struct symbol *sym, const struct block *block,
		      struct type *context_type,
		      bool parse_completion,
		      int deprocedure_p,
		      innermost_block_tracker *tracker)
{
  std::vector<struct block_symbol> candidates
    = ada_lookup_symbol_list (sym->linkage_name (), block, VAR_DOMAIN);

  if (std::any_of (candidates.begin (),
		   candidates.end (),
		   [] (block_symbol &bsym)
		   {
		     switch (bsym.symbol->aclass ())
		       {
		       case LOC_REGISTER:
		       case LOC_ARG:
		       case LOC_REF_ARG:
		       case LOC_REGPARM_ADDR:
		       case LOC_LOCAL:
		       case LOC_COMPUTED:
			 return true;
		       default:
			 return false;
		       }
		   }))
    {
      /* Types tend to get re-introduced locally, so if there
	 are any local symbols that are not types, first filter
	 out all types.  */
      candidates.erase
	(std::remove_if
	 (candidates.begin (),
	  candidates.end (),
	  [] (block_symbol &bsym)
	  {
	    return bsym.symbol->aclass () == LOC_TYPEDEF;
	  }),
	 candidates.end ());
    }

  /* Filter out artificial symbols.  */
  candidates.erase
    (std::remove_if
     (candidates.begin (),
      candidates.end (),
      [] (block_symbol &bsym)
      {
	return bsym.symbol->is_artificial ();
      }),
     candidates.end ());

  int i;
  if (candidates.empty ())
    error (_("No definition found for %s"), sym->print_name ());
  else if (candidates.size () == 1)
    i = 0;
  else if (context_type != nullptr
	   && context_type->code () == TYPE_CODE_ENUM)
    i = ada_resolve_enum (candidates, sym->linkage_name (), context_type,
			  parse_completion);
  else if (deprocedure_p && !is_nonfunction (candidates))
    {
      i = ada_resolve_function
	(candidates, NULL, 0,
	 sym->linkage_name (),
	 context_type, parse_completion);
      if (i < 0)
	error (_("Could not find a match for %s"), sym->print_name ());
    }
  else
    {
      gdb_printf (_("Multiple matches for %s\n"), sym->print_name ());
      user_select_syms (candidates.data (), candidates.size (), 1);
      i = 0;
    }

  tracker->update (candidates[i]);
  return candidates[i];
}

/* Return non-zero if formal type FTYPE matches actual type ATYPE.  */
/* The term "match" here is rather loose.  The match is heuristic and
   liberal.  */

static int
ada_type_match (struct type *ftype, struct type *atype)
{
  ftype = ada_check_typedef (ftype);
  atype = ada_check_typedef (atype);

  if (ftype->code () == TYPE_CODE_REF)
    ftype = TYPE_TARGET_TYPE (ftype);
  if (atype->code () == TYPE_CODE_REF)
    atype = TYPE_TARGET_TYPE (atype);

  switch (ftype->code ())
    {
    default:
      return ftype->code () == atype->code ();
    case TYPE_CODE_PTR:
      if (atype->code () != TYPE_CODE_PTR)
	return 0;
      atype = TYPE_TARGET_TYPE (atype);
      /* This can only happen if the actual argument is 'null'.  */
      if (atype->code () == TYPE_CODE_INT && TYPE_LENGTH (atype) == 0)
	return 1;
      return ada_type_match (TYPE_TARGET_TYPE (ftype), atype);
    case TYPE_CODE_INT:
    case TYPE_CODE_ENUM:
    case TYPE_CODE_RANGE:
      switch (atype->code ())
	{
	case TYPE_CODE_INT:
	case TYPE_CODE_ENUM:
	case TYPE_CODE_RANGE:
	  return 1;
	default:
	  return 0;
	}

    case TYPE_CODE_ARRAY:
      return (atype->code () == TYPE_CODE_ARRAY
	      || ada_is_array_descriptor_type (atype));

    case TYPE_CODE_STRUCT:
      if (ada_is_array_descriptor_type (ftype))
	return (atype->code () == TYPE_CODE_ARRAY
		|| ada_is_array_descriptor_type (atype));
      else
	return (atype->code () == TYPE_CODE_STRUCT
		&& !ada_is_array_descriptor_type (atype));

    case TYPE_CODE_UNION:
    case TYPE_CODE_FLT:
      return (atype->code () == ftype->code ());
    }
}

/* Return non-zero if the formals of FUNC "sufficiently match" the
   vector of actual argument types ACTUALS of size N_ACTUALS.  FUNC
   may also be an enumeral, in which case it is treated as a 0-
   argument function.  */

static int
ada_args_match (struct symbol *func, struct value **actuals, int n_actuals)
{
  int i;
  struct type *func_type = func->type ();

  if (func->aclass () == LOC_CONST
      && func_type->code () == TYPE_CODE_ENUM)
    return (n_actuals == 0);
  else if (func_type == NULL || func_type->code () != TYPE_CODE_FUNC)
    return 0;

  if (func_type->num_fields () != n_actuals)
    return 0;

  for (i = 0; i < n_actuals; i += 1)
    {
      if (actuals[i] == NULL)
	return 0;
      else
	{
	  struct type *ftype = ada_check_typedef (func_type->field (i).type ());
	  struct type *atype = ada_check_typedef (value_type (actuals[i]));

	  if (!ada_type_match (ftype, atype))
	    return 0;
	}
    }
  return 1;
}

/* False iff function type FUNC_TYPE definitely does not produce a value
   compatible with type CONTEXT_TYPE.  Conservatively returns 1 if
   FUNC_TYPE is not a valid function type with a non-null return type
   or an enumerated type.  A null CONTEXT_TYPE indicates any non-void type.  */

static int
return_match (struct type *func_type, struct type *context_type)
{
  struct type *return_type;

  if (func_type == NULL)
    return 1;

  if (func_type->code () == TYPE_CODE_FUNC)
    return_type = get_base_type (TYPE_TARGET_TYPE (func_type));
  else
    return_type = get_base_type (func_type);
  if (return_type == NULL)
    return 1;

  context_type = get_base_type (context_type);

  if (return_type->code () == TYPE_CODE_ENUM)
    return context_type == NULL || return_type == context_type;
  else if (context_type == NULL)
    return return_type->code () != TYPE_CODE_VOID;
  else
    return return_type->code () == context_type->code ();
}


/* Returns the index in SYMS that contains the symbol for the
   function (if any) that matches the types of the NARGS arguments in
   ARGS.  If CONTEXT_TYPE is non-null and there is at least one match
   that returns that type, then eliminate matches that don't.  If
   CONTEXT_TYPE is void and there is at least one match that does not
   return void, eliminate all matches that do.

   Asks the user if there is more than one match remaining.  Returns -1
   if there is no such symbol or none is selected.  NAME is used
   solely for messages.  May re-arrange and modify SYMS in
   the process; the index returned is for the modified vector.  */

static int
ada_resolve_function (std::vector<struct block_symbol> &syms,
		      struct value **args, int nargs,
		      const char *name, struct type *context_type,
		      bool parse_completion)
{
  int fallback;
  int k;
  int m;                        /* Number of hits */

  m = 0;
  /* In the first pass of the loop, we only accept functions matching
     context_type.  If none are found, we add a second pass of the loop
     where every function is accepted.  */
  for (fallback = 0; m == 0 && fallback < 2; fallback++)
    {
      for (k = 0; k < syms.size (); k += 1)
	{
	  struct type *type = ada_check_typedef (syms[k].symbol->type ());

	  if (ada_args_match (syms[k].symbol, args, nargs)
	      && (fallback || return_match (type, context_type)))
	    {
	      syms[m] = syms[k];
	      m += 1;
	    }
	}
    }

  /* If we got multiple matches, ask the user which one to use.  Don't do this
     interactive thing during completion, though, as the purpose of the
     completion is providing a list of all possible matches.  Prompting the
     user to filter it down would be completely unexpected in this case.  */
  if (m == 0)
    return -1;
  else if (m > 1 && !parse_completion)
    {
      gdb_printf (_("Multiple matches for %s\n"), name);
      user_select_syms (syms.data (), m, 1);
      return 0;
    }
  return 0;
}

/* Type-class predicates */

/* True iff TYPE is numeric (i.e., an INT, RANGE (of numeric type),
   or FLOAT).  */

static int
numeric_type_p (struct type *type)
{
  if (type == NULL)
    return 0;
  else
    {
      switch (type->code ())
	{
	case TYPE_CODE_INT:
	case TYPE_CODE_FLT:
	case TYPE_CODE_FIXED_POINT:
	  return 1;
	case TYPE_CODE_RANGE:
	  return (type == TYPE_TARGET_TYPE (type)
		  || numeric_type_p (TYPE_TARGET_TYPE (type)));
	default:
	  return 0;
	}
    }
}

/* True iff TYPE is integral (an INT or RANGE of INTs).  */

static int
integer_type_p (struct type *type)
{
  if (type == NULL)
    return 0;
  else
    {
      switch (type->code ())
	{
	case TYPE_CODE_INT:
	  return 1;
	case TYPE_CODE_RANGE:
	  return (type == TYPE_TARGET_TYPE (type)
		  || integer_type_p (TYPE_TARGET_TYPE (type)));
	default:
	  return 0;
	}
    }
}

/* True iff TYPE is scalar (INT, RANGE, FLOAT, ENUM).  */

static int
scalar_type_p (struct type *type)
{
  if (type == NULL)
    return 0;
  else
    {
      switch (type->code ())
	{
	case TYPE_CODE_INT:
	case TYPE_CODE_RANGE:
	case TYPE_CODE_ENUM:
	case TYPE_CODE_FLT:
	case TYPE_CODE_FIXED_POINT:
	  return 1;
	default:
	  return 0;
	}
    }
}

/* True iff TYPE is discrete (INT, RANGE, ENUM).  */

static int
discrete_type_p (struct type *type)
{
  if (type == NULL)
    return 0;
  else
    {
      switch (type->code ())
	{
	case TYPE_CODE_INT:
	case TYPE_CODE_RANGE:
	case TYPE_CODE_ENUM:
	case TYPE_CODE_BOOL:
	  return 1;
	default:
	  return 0;
	}
    }
}

/* Returns non-zero if OP with operands in the vector ARGS could be
   a user-defined function.  Errs on the side of pre-defined operators
   (i.e., result 0).  */

static int
possible_user_operator_p (enum exp_opcode op, struct value *args[])
{
  struct type *type0 =
    (args[0] == NULL) ? NULL : ada_check_typedef (value_type (args[0]));
  struct type *type1 =
    (args[1] == NULL) ? NULL : ada_check_typedef (value_type (args[1]));

  if (type0 == NULL)
    return 0;

  switch (op)
    {
    default:
      return 0;

    case BINOP_ADD:
    case BINOP_SUB:
    case BINOP_MUL:
    case BINOP_DIV:
      return (!(numeric_type_p (type0) && numeric_type_p (type1)));

    case BINOP_REM:
    case BINOP_MOD:
    case BINOP_BITWISE_AND:
    case BINOP_BITWISE_IOR:
    case BINOP_BITWISE_XOR:
      return (!(integer_type_p (type0) && integer_type_p (type1)));

    case BINOP_EQUAL:
    case BINOP_NOTEQUAL:
    case BINOP_LESS:
    case BINOP_GTR:
    case BINOP_LEQ:
    case BINOP_GEQ:
      return (!(scalar_type_p (type0) && scalar_type_p (type1)));

    case BINOP_CONCAT:
      return !ada_is_array_type (type0) || !ada_is_array_type (type1);

    case BINOP_EXP:
      return (!(numeric_type_p (type0) && integer_type_p (type1)));

    case UNOP_NEG:
    case UNOP_PLUS:
    case UNOP_LOGICAL_NOT:
    case UNOP_ABS:
      return (!numeric_type_p (type0));

    }
}

				/* Renaming */

/* NOTES: 

   1. In the following, we assume that a renaming type's name may
      have an ___XD suffix.  It would be nice if this went away at some
      point.
   2. We handle both the (old) purely type-based representation of 
      renamings and the (new) variable-based encoding.  At some point,
      it is devoutly to be hoped that the former goes away 
      (FIXME: hilfinger-2007-07-09).
   3. Subprogram renamings are not implemented, although the XRS
      suffix is recognized (FIXME: hilfinger-2007-07-09).  */

/* If SYM encodes a renaming, 

       <renaming> renames <renamed entity>,

   sets *LEN to the length of the renamed entity's name,
   *RENAMED_ENTITY to that name (not null-terminated), and *RENAMING_EXPR to
   the string describing the subcomponent selected from the renamed
   entity.  Returns ADA_NOT_RENAMING if SYM does not encode a renaming
   (in which case, the values of *RENAMED_ENTITY, *LEN, and *RENAMING_EXPR
   are undefined).  Otherwise, returns a value indicating the category
   of entity renamed: an object (ADA_OBJECT_RENAMING), exception
   (ADA_EXCEPTION_RENAMING), package (ADA_PACKAGE_RENAMING), or
   subprogram (ADA_SUBPROGRAM_RENAMING).  Does no allocation; the
   strings returned in *RENAMED_ENTITY and *RENAMING_EXPR should not be
   deallocated.  The values of RENAMED_ENTITY, LEN, or RENAMING_EXPR
   may be NULL, in which case they are not assigned.

   [Currently, however, GCC does not generate subprogram renamings.]  */

enum ada_renaming_category
ada_parse_renaming (struct symbol *sym,
		    const char **renamed_entity, int *len, 
		    const char **renaming_expr)
{
  enum ada_renaming_category kind;
  const char *info;
  const char *suffix;

  if (sym == NULL)
    return ADA_NOT_RENAMING;
  switch (sym->aclass ()) 
    {
    default:
      return ADA_NOT_RENAMING;
    case LOC_LOCAL:
    case LOC_STATIC:
    case LOC_COMPUTED:
    case LOC_OPTIMIZED_OUT:
      info = strstr (sym->linkage_name (), "___XR");
      if (info == NULL)
	return ADA_NOT_RENAMING;
      switch (info[5])
	{
	case '_':
	  kind = ADA_OBJECT_RENAMING;
	  info += 6;
	  break;
	case 'E':
	  kind = ADA_EXCEPTION_RENAMING;
	  info += 7;
	  break;
	case 'P':
	  kind = ADA_PACKAGE_RENAMING;
	  info += 7;
	  break;
	case 'S':
	  kind = ADA_SUBPROGRAM_RENAMING;
	  info += 7;
	  break;
	default:
	  return ADA_NOT_RENAMING;
	}
    }

  if (renamed_entity != NULL)
    *renamed_entity = info;
  suffix = strstr (info, "___XE");
  if (suffix == NULL || suffix == info)
    return ADA_NOT_RENAMING;
  if (len != NULL)
    *len = strlen (info) - strlen (suffix);
  suffix += 5;
  if (renaming_expr != NULL)
    *renaming_expr = suffix;
  return kind;
}

/* Compute the value of the given RENAMING_SYM, which is expected to
   be a symbol encoding a renaming expression.  BLOCK is the block
   used to evaluate the renaming.  */

static struct value *
ada_read_renaming_var_value (struct symbol *renaming_sym,
			     const struct block *block)
{
  const char *sym_name;

  sym_name = renaming_sym->linkage_name ();
  expression_up expr = parse_exp_1 (&sym_name, 0, block, 0);
  return evaluate_expression (expr.get ());
}


				/* Evaluation: Function Calls */

/* Return an lvalue containing the value VAL.  This is the identity on
   lvalues, and otherwise has the side-effect of allocating memory
   in the inferior where a copy of the value contents is copied.  */

static struct value *
ensure_lval (struct value *val)
{
  if (VALUE_LVAL (val) == not_lval
      || VALUE_LVAL (val) == lval_internalvar)
    {
      int len = TYPE_LENGTH (ada_check_typedef (value_type (val)));
      const CORE_ADDR addr =
	value_as_long (value_allocate_space_in_inferior (len));

      VALUE_LVAL (val) = lval_memory;
      set_value_address (val, addr);
      write_memory (addr, value_contents (val).data (), len);
    }

  return val;
}

/* Given ARG, a value of type (pointer or reference to a)*
   structure/union, extract the component named NAME from the ultimate
   target structure/union and return it as a value with its
   appropriate type.

   The routine searches for NAME among all members of the structure itself
   and (recursively) among all members of any wrapper members
   (e.g., '_parent').

   If NO_ERR, then simply return NULL in case of error, rather than
   calling error.  */

static struct value *
ada_value_struct_elt (struct value *arg, const char *name, int no_err)
{
  struct type *t, *t1;
  struct value *v;
  int check_tag;

  v = NULL;
  t1 = t = ada_check_typedef (value_type (arg));
  if (t->code () == TYPE_CODE_REF)
    {
      t1 = TYPE_TARGET_TYPE (t);
      if (t1 == NULL)
	goto BadValue;
      t1 = ada_check_typedef (t1);
      if (t1->code () == TYPE_CODE_PTR)
	{
	  arg = coerce_ref (arg);
	  t = t1;
	}
    }

  while (t->code () == TYPE_CODE_PTR)
    {
      t1 = TYPE_TARGET_TYPE (t);
      if (t1 == NULL)
	goto BadValue;
      t1 = ada_check_typedef (t1);
      if (t1->code () == TYPE_CODE_PTR)
	{
	  arg = value_ind (arg);
	  t = t1;
	}
      else
	break;
    }

  if (t1->code () != TYPE_CODE_STRUCT && t1->code () != TYPE_CODE_UNION)
    goto BadValue;

  if (t1 == t)
    v = ada_search_struct_field (name, arg, 0, t);
  else
    {
      int bit_offset, bit_size, byte_offset;
      struct type *field_type;
      CORE_ADDR address;

      if (t->code () == TYPE_CODE_PTR)
	address = value_address (ada_value_ind (arg));
      else
	address = value_address (ada_coerce_ref (arg));

      /* Check to see if this is a tagged type.  We also need to handle
	 the case where the type is a reference to a tagged type, but
	 we have to be careful to exclude pointers to tagged types.
	 The latter should be shown as usual (as a pointer), whereas
	 a reference should mostly be transparent to the user.  */

      if (ada_is_tagged_type (t1, 0)
	  || (t1->code () == TYPE_CODE_REF
	      && ada_is_tagged_type (TYPE_TARGET_TYPE (t1), 0)))
	{
	  /* We first try to find the searched field in the current type.
	     If not found then let's look in the fixed type.  */

	  if (!find_struct_field (name, t1, 0,
				  nullptr, nullptr, nullptr,
				  nullptr, nullptr))
	    check_tag = 1;
	  else
	    check_tag = 0;
	}
      else
	check_tag = 0;

      /* Convert to fixed type in all cases, so that we have proper
	 offsets to each field in unconstrained record types.  */
      t1 = ada_to_fixed_type (ada_get_base_type (t1), NULL,
			      address, NULL, check_tag);

      /* Resolve the dynamic type as well.  */
      arg = value_from_contents_and_address (t1, nullptr, address);
      t1 = value_type (arg);

      if (find_struct_field (name, t1, 0,
			     &field_type, &byte_offset, &bit_offset,
			     &bit_size, NULL))
	{
	  if (bit_size != 0)
	    {
	      if (t->code () == TYPE_CODE_REF)
		arg = ada_coerce_ref (arg);
	      else
		arg = ada_value_ind (arg);
	      v = ada_value_primitive_packed_val (arg, NULL, byte_offset,
						  bit_offset, bit_size,
						  field_type);
	    }
	  else
	    v = value_at_lazy (field_type, address + byte_offset);
	}
    }

  if (v != NULL || no_err)
    return v;
  else
    error (_("There is no member named %s."), name);

 BadValue:
  if (no_err)
    return NULL;
  else
    error (_("Attempt to extract a component of "
	     "a value that is not a record."));
}

/* Return the value ACTUAL, converted to be an appropriate value for a
   formal of type FORMAL_TYPE.  Use *SP as a stack pointer for
   allocating any necessary descriptors (fat pointers), or copies of
   values not residing in memory, updating it as needed.  */

struct value *
ada_convert_actual (struct value *actual, struct type *formal_type0)
{
  struct type *actual_type = ada_check_typedef (value_type (actual));
  struct type *formal_type = ada_check_typedef (formal_type0);
  struct type *formal_target =
    formal_type->code () == TYPE_CODE_PTR
    ? ada_check_typedef (TYPE_TARGET_TYPE (formal_type)) : formal_type;
  struct type *actual_target =
    actual_type->code () == TYPE_CODE_PTR
    ? ada_check_typedef (TYPE_TARGET_TYPE (actual_type)) : actual_type;

  if (ada_is_array_descriptor_type (formal_target)
      && actual_target->code () == TYPE_CODE_ARRAY)
    return make_array_descriptor (formal_type, actual);
  else if (formal_type->code () == TYPE_CODE_PTR
	   || formal_type->code () == TYPE_CODE_REF)
    {
      struct value *result;

      if (formal_target->code () == TYPE_CODE_ARRAY
	  && ada_is_array_descriptor_type (actual_target))
	result = desc_data (actual);
      else if (formal_type->code () != TYPE_CODE_PTR)
	{
	  if (VALUE_LVAL (actual) != lval_memory)
	    {
	      struct value *val;

	      actual_type = ada_check_typedef (value_type (actual));
	      val = allocate_value (actual_type);
	      copy (value_contents (actual), value_contents_raw (val));
	      actual = ensure_lval (val);
	    }
	  result = value_addr (actual);
	}
      else
	return actual;
      return value_cast_pointers (formal_type, result, 0);
    }
  else if (actual_type->code () == TYPE_CODE_PTR)
    return ada_value_ind (actual);
  else if (ada_is_aligner_type (formal_type))
    {
      /* We need to turn this parameter into an aligner type
	 as well.  */
      struct value *aligner = allocate_value (formal_type);
      struct value *component = ada_value_struct_elt (aligner, "F", 0);

      value_assign_to_component (aligner, component, actual);
      return aligner;
    }

  return actual;
}

/* Convert VALUE (which must be an address) to a CORE_ADDR that is a pointer of
   type TYPE.  This is usually an inefficient no-op except on some targets
   (such as AVR) where the representation of a pointer and an address
   differs.  */

static CORE_ADDR
value_pointer (struct value *value, struct type *type)
{
  unsigned len = TYPE_LENGTH (type);
  gdb_byte *buf = (gdb_byte *) alloca (len);
  CORE_ADDR addr;

  addr = value_address (value);
  gdbarch_address_to_pointer (type->arch (), type, buf, addr);
  addr = extract_unsigned_integer (buf, len, type_byte_order (type));
  return addr;
}


/* Push a descriptor of type TYPE for array value ARR on the stack at
   *SP, updating *SP to reflect the new descriptor.  Return either
   an lvalue representing the new descriptor, or (if TYPE is a pointer-
   to-descriptor type rather than a descriptor type), a struct value *
   representing a pointer to this descriptor.  */

static struct value *
make_array_descriptor (struct type *type, struct value *arr)
{
  struct type *bounds_type = desc_bounds_type (type);
  struct type *desc_type = desc_base_type (type);
  struct value *descriptor = allocate_value (desc_type);
  struct value *bounds = allocate_value (bounds_type);
  int i;

  for (i = ada_array_arity (ada_check_typedef (value_type (arr)));
       i > 0; i -= 1)
    {
      modify_field (value_type (bounds),
		    value_contents_writeable (bounds).data (),
		    ada_array_bound (arr, i, 0),
		    desc_bound_bitpos (bounds_type, i, 0),
		    desc_bound_bitsize (bounds_type, i, 0));
      modify_field (value_type (bounds),
		    value_contents_writeable (bounds).data (),
		    ada_array_bound (arr, i, 1),
		    desc_bound_bitpos (bounds_type, i, 1),
		    desc_bound_bitsize (bounds_type, i, 1));
    }

  bounds = ensure_lval (bounds);

  modify_field (value_type (descriptor),
		value_contents_writeable (descriptor).data (),
		value_pointer (ensure_lval (arr),
			       desc_type->field (0).type ()),
		fat_pntr_data_bitpos (desc_type),
		fat_pntr_data_bitsize (desc_type));

  modify_field (value_type (descriptor),
		value_contents_writeable (descriptor).data (),
		value_pointer (bounds,
			       desc_type->field (1).type ()),
		fat_pntr_bounds_bitpos (desc_type),
		fat_pntr_bounds_bitsize (desc_type));

  descriptor = ensure_lval (descriptor);

  if (type->code () == TYPE_CODE_PTR)
    return value_addr (descriptor);
  else
    return descriptor;
}

				/* Symbol Cache Module */

/* Performance measurements made as of 2010-01-15 indicate that
   this cache does bring some noticeable improvements.  Depending
   on the type of entity being printed, the cache can make it as much
   as an order of magnitude faster than without it.

   The descriptive type DWARF extension has significantly reduced
   the need for this cache, at least when DWARF is being used.  However,
   even in this case, some expensive name-based symbol searches are still
   sometimes necessary - to find an XVZ variable, mostly.  */

/* Return the symbol cache associated to the given program space PSPACE.
   If not allocated for this PSPACE yet, allocate and initialize one.  */

static struct ada_symbol_cache *
ada_get_symbol_cache (struct program_space *pspace)
{
  struct ada_pspace_data *pspace_data = get_ada_pspace_data (pspace);

  if (pspace_data->sym_cache == nullptr)
    pspace_data->sym_cache.reset (new ada_symbol_cache);

  return pspace_data->sym_cache.get ();
}

/* Clear all entries from the symbol cache.  */

static void
ada_clear_symbol_cache ()
{
  struct ada_pspace_data *pspace_data
    = get_ada_pspace_data (current_program_space);

  if (pspace_data->sym_cache != nullptr)
    pspace_data->sym_cache.reset ();
}

/* Search our cache for an entry matching NAME and DOMAIN.
   Return it if found, or NULL otherwise.  */

static struct cache_entry **
find_entry (const char *name, domain_enum domain)
{
  struct ada_symbol_cache *sym_cache
    = ada_get_symbol_cache (current_program_space);
  int h = msymbol_hash (name) % HASH_SIZE;
  struct cache_entry **e;

  for (e = &sym_cache->root[h]; *e != NULL; e = &(*e)->next)
    {
      if (domain == (*e)->domain && strcmp (name, (*e)->name) == 0)
	return e;
    }
  return NULL;
}

/* Search the symbol cache for an entry matching NAME and DOMAIN.
   Return 1 if found, 0 otherwise.

   If an entry was found and SYM is not NULL, set *SYM to the entry's
   SYM.  Same principle for BLOCK if not NULL.  */

static int
lookup_cached_symbol (const char *name, domain_enum domain,
		      struct symbol **sym, const struct block **block)
{
  struct cache_entry **e = find_entry (name, domain);

  if (e == NULL)
    return 0;
  if (sym != NULL)
    *sym = (*e)->sym;
  if (block != NULL)
    *block = (*e)->block;
  return 1;
}

/* Assuming that (SYM, BLOCK) is the result of the lookup of NAME
   in domain DOMAIN, save this result in our symbol cache.  */

static void
cache_symbol (const char *name, domain_enum domain, struct symbol *sym,
	      const struct block *block)
{
  struct ada_symbol_cache *sym_cache
    = ada_get_symbol_cache (current_program_space);
  int h;
  struct cache_entry *e;

  /* Symbols for builtin types don't have a block.
     For now don't cache such symbols.  */
  if (sym != NULL && !sym->is_objfile_owned ())
    return;

  /* If the symbol is a local symbol, then do not cache it, as a search
     for that symbol depends on the context.  To determine whether
     the symbol is local or not, we check the block where we found it
     against the global and static blocks of its associated symtab.  */
  if (sym != nullptr)
    {
      const blockvector &bv = *sym->symtab ()->compunit ()->blockvector ();

      if (bv.global_block () != block && bv.static_block () != block)
	return;
    }

  h = msymbol_hash (name) % HASH_SIZE;
  e = XOBNEW (&sym_cache->cache_space, cache_entry);
  e->next = sym_cache->root[h];
  sym_cache->root[h] = e;
  e->name = obstack_strdup (&sym_cache->cache_space, name);
  e->sym = sym;
  e->domain = domain;
  e->block = block;
}

				/* Symbol Lookup */

/* Return the symbol name match type that should be used used when
   searching for all symbols matching LOOKUP_NAME.

   LOOKUP_NAME is expected to be a symbol name after transformation
   for Ada lookups.  */

static symbol_name_match_type
name_match_type_from_name (const char *lookup_name)
{
  return (strstr (lookup_name, "__") == NULL
	  ? symbol_name_match_type::WILD
	  : symbol_name_match_type::FULL);
}

/* Return the result of a standard (literal, C-like) lookup of NAME in
   given DOMAIN, visible from lexical block BLOCK.  */

static struct symbol *
standard_lookup (const char *name, const struct block *block,
		 domain_enum domain)
{
  /* Initialize it just to avoid a GCC false warning.  */
  struct block_symbol sym = {};

  if (lookup_cached_symbol (name, domain, &sym.symbol, NULL))
    return sym.symbol;
  ada_lookup_encoded_symbol (name, block, domain, &sym);
  cache_symbol (name, domain, sym.symbol, sym.block);
  return sym.symbol;
}


/* Non-zero iff there is at least one non-function/non-enumeral symbol
   in the symbol fields of SYMS.  We treat enumerals as functions, 
   since they contend in overloading in the same way.  */
static int
is_nonfunction (const std::vector<struct block_symbol> &syms)
{
  for (const block_symbol &sym : syms)
    if (sym.symbol->type ()->code () != TYPE_CODE_FUNC
	&& (sym.symbol->type ()->code () != TYPE_CODE_ENUM
	    || sym.symbol->aclass () != LOC_CONST))
      return 1;

  return 0;
}

/* If true (non-zero), then TYPE0 and TYPE1 represent equivalent
   struct types.  Otherwise, they may not.  */

static int
equiv_types (struct type *type0, struct type *type1)
{
  if (type0 == type1)
    return 1;
  if (type0 == NULL || type1 == NULL
      || type0->code () != type1->code ())
    return 0;
  if ((type0->code () == TYPE_CODE_STRUCT
       || type0->code () == TYPE_CODE_ENUM)
      && ada_type_name (type0) != NULL && ada_type_name (type1) != NULL
      && strcmp (ada_type_name (type0), ada_type_name (type1)) == 0)
    return 1;

  return 0;
}

/* True iff SYM0 represents the same entity as SYM1, or one that is
   no more defined than that of SYM1.  */

static int
lesseq_defined_than (struct symbol *sym0, struct symbol *sym1)
{
  if (sym0 == sym1)
    return 1;
  if (sym0->domain () != sym1->domain ()
      || sym0->aclass () != sym1->aclass ())
    return 0;

  switch (sym0->aclass ())
    {
    case LOC_UNDEF:
      return 1;
    case LOC_TYPEDEF:
      {
	struct type *type0 = sym0->type ();
	struct type *type1 = sym1->type ();
	const char *name0 = sym0->linkage_name ();
	const char *name1 = sym1->linkage_name ();
	int len0 = strlen (name0);

	return
	  type0->code () == type1->code ()
	  && (equiv_types (type0, type1)
	      || (len0 < strlen (name1) && strncmp (name0, name1, len0) == 0
		  && startswith (name1 + len0, "___XV")));
      }
    case LOC_CONST:
      return sym0->value_longest () == sym1->value_longest ()
	&& equiv_types (sym0->type (), sym1->type ());

    case LOC_STATIC:
      {
	const char *name0 = sym0->linkage_name ();
	const char *name1 = sym1->linkage_name ();
	return (strcmp (name0, name1) == 0
		&& sym0->value_address () == sym1->value_address ());
      }

    default:
      return 0;
    }
}

/* Append (SYM,BLOCK) to the end of the array of struct block_symbol
   records in RESULT.  Do nothing if SYM is a duplicate.  */

static void
add_defn_to_vec (std::vector<struct block_symbol> &result,
		 struct symbol *sym,
		 const struct block *block)
{
  /* Do not try to complete stub types, as the debugger is probably
     already scanning all symbols matching a certain name at the
     time when this function is called.  Trying to replace the stub
     type by its associated full type will cause us to restart a scan
     which may lead to an infinite recursion.  Instead, the client
     collecting the matching symbols will end up collecting several
     matches, with at least one of them complete.  It can then filter
     out the stub ones if needed.  */

  for (int i = result.size () - 1; i >= 0; i -= 1)
    {
      if (lesseq_defined_than (sym, result[i].symbol))
	return;
      else if (lesseq_defined_than (result[i].symbol, sym))
	{
	  result[i].symbol = sym;
	  result[i].block = block;
	  return;
	}
    }

  struct block_symbol info;
  info.symbol = sym;
  info.block = block;
  result.push_back (info);
}

/* Return a bound minimal symbol matching NAME according to Ada
   decoding rules.  Returns an invalid symbol if there is no such
   minimal symbol.  Names prefixed with "standard__" are handled
   specially: "standard__" is first stripped off, and only static and
   global symbols are searched.  */

struct bound_minimal_symbol
ada_lookup_simple_minsym (const char *name)
{
  struct bound_minimal_symbol result;

  symbol_name_match_type match_type = name_match_type_from_name (name);
  lookup_name_info lookup_name (name, match_type);

  symbol_name_matcher_ftype *match_name
    = ada_get_symbol_name_matcher (lookup_name);

  for (objfile *objfile : current_program_space->objfiles ())
    {
      for (minimal_symbol *msymbol : objfile->msymbols ())
	{
	  if (match_name (msymbol->linkage_name (), lookup_name, NULL)
	      && msymbol->type () != mst_solib_trampoline)
	    {
	      result.minsym = msymbol;
	      result.objfile = objfile;
	      break;
	    }
	}
    }

  return result;
}

/* True if TYPE is definitely an artificial type supplied to a symbol
   for which no debugging information was given in the symbol file.  */

static int
is_nondebugging_type (struct type *type)
{
  const char *name = ada_type_name (type);

  return (name != NULL && strcmp (name, "<variable, no debug info>") == 0);
}

/* Return nonzero if TYPE1 and TYPE2 are two enumeration types
   that are deemed "identical" for practical purposes.

   This function assumes that TYPE1 and TYPE2 are both TYPE_CODE_ENUM
   types and that their number of enumerals is identical (in other
   words, type1->num_fields () == type2->num_fields ()).  */

static int
ada_identical_enum_types_p (struct type *type1, struct type *type2)
{
  int i;

  /* The heuristic we use here is fairly conservative.  We consider
     that 2 enumerate types are identical if they have the same
     number of enumerals and that all enumerals have the same
     underlying value and name.  */

  /* All enums in the type should have an identical underlying value.  */
  for (i = 0; i < type1->num_fields (); i++)
    if (type1->field (i).loc_enumval () != type2->field (i).loc_enumval ())
      return 0;

  /* All enumerals should also have the same name (modulo any numerical
     suffix).  */
  for (i = 0; i < type1->num_fields (); i++)
    {
      const char *name_1 = type1->field (i).name ();
      const char *name_2 = type2->field (i).name ();
      int len_1 = strlen (name_1);
      int len_2 = strlen (name_2);

      ada_remove_trailing_digits (type1->field (i).name (), &len_1);
      ada_remove_trailing_digits (type2->field (i).name (), &len_2);
      if (len_1 != len_2
	  || strncmp (type1->field (i).name (),
		      type2->field (i).name (),
		      len_1) != 0)
	return 0;
    }

  return 1;
}

/* Return nonzero if all the symbols in SYMS are all enumeral symbols
   that are deemed "identical" for practical purposes.  Sometimes,
   enumerals are not strictly identical, but their types are so similar
   that they can be considered identical.

   For instance, consider the following code:

      type Color is (Black, Red, Green, Blue, White);
      type RGB_Color is new Color range Red .. Blue;

   Type RGB_Color is a subrange of an implicit type which is a copy
   of type Color. If we call that implicit type RGB_ColorB ("B" is
   for "Base Type"), then type RGB_ColorB is a copy of type Color.
   As a result, when an expression references any of the enumeral
   by name (Eg. "print green"), the expression is technically
   ambiguous and the user should be asked to disambiguate. But
   doing so would only hinder the user, since it wouldn't matter
   what choice he makes, the outcome would always be the same.
   So, for practical purposes, we consider them as the same.  */

static int
symbols_are_identical_enums (const std::vector<struct block_symbol> &syms)
{
  int i;

  /* Before performing a thorough comparison check of each type,
     we perform a series of inexpensive checks.  We expect that these
     checks will quickly fail in the vast majority of cases, and thus
     help prevent the unnecessary use of a more expensive comparison.
     Said comparison also expects us to make some of these checks
     (see ada_identical_enum_types_p).  */

  /* Quick check: All symbols should have an enum type.  */
  for (i = 0; i < syms.size (); i++)
    if (syms[i].symbol->type ()->code () != TYPE_CODE_ENUM)
      return 0;

  /* Quick check: They should all have the same value.  */
  for (i = 1; i < syms.size (); i++)
    if (syms[i].symbol->value_longest () != syms[0].symbol->value_longest ())
      return 0;

  /* Quick check: They should all have the same number of enumerals.  */
  for (i = 1; i < syms.size (); i++)
    if (syms[i].symbol->type ()->num_fields ()
	!= syms[0].symbol->type ()->num_fields ())
      return 0;

  /* All the sanity checks passed, so we might have a set of
     identical enumeration types.  Perform a more complete
     comparison of the type of each symbol.  */
  for (i = 1; i < syms.size (); i++)
    if (!ada_identical_enum_types_p (syms[i].symbol->type (),
				     syms[0].symbol->type ()))
      return 0;

  return 1;
}

/* Remove any non-debugging symbols in SYMS that definitely
   duplicate other symbols in the list (The only case I know of where
   this happens is when object files containing stabs-in-ecoff are
   linked with files containing ordinary ecoff debugging symbols (or no
   debugging symbols)).  Modifies SYMS to squeeze out deleted entries.  */

static void
remove_extra_symbols (std::vector<struct block_symbol> *syms)
{
  int i, j;

  /* We should never be called with less than 2 symbols, as there
     cannot be any extra symbol in that case.  But it's easy to
     handle, since we have nothing to do in that case.  */
  if (syms->size () < 2)
    return;

  i = 0;
  while (i < syms->size ())
    {
      int remove_p = 0;

      /* If two symbols have the same name and one of them is a stub type,
	 the get rid of the stub.  */

      if ((*syms)[i].symbol->type ()->is_stub ()
	  && (*syms)[i].symbol->linkage_name () != NULL)
	{
	  for (j = 0; j < syms->size (); j++)
	    {
	      if (j != i
		  && !(*syms)[j].symbol->type ()->is_stub ()
		  && (*syms)[j].symbol->linkage_name () != NULL
		  && strcmp ((*syms)[i].symbol->linkage_name (),
			     (*syms)[j].symbol->linkage_name ()) == 0)
		remove_p = 1;
	    }
	}

      /* Two symbols with the same name, same class and same address
	 should be identical.  */

      else if ((*syms)[i].symbol->linkage_name () != NULL
	  && (*syms)[i].symbol->aclass () == LOC_STATIC
	  && is_nondebugging_type ((*syms)[i].symbol->type ()))
	{
	  for (j = 0; j < syms->size (); j += 1)
	    {
	      if (i != j
		  && (*syms)[j].symbol->linkage_name () != NULL
		  && strcmp ((*syms)[i].symbol->linkage_name (),
			     (*syms)[j].symbol->linkage_name ()) == 0
		  && ((*syms)[i].symbol->aclass ()
		      == (*syms)[j].symbol->aclass ())
		  && (*syms)[i].symbol->value_address ()
		  == (*syms)[j].symbol->value_address ())
		remove_p = 1;
	    }
	}
      
      if (remove_p)
	syms->erase (syms->begin () + i);
      else
	i += 1;
    }

  /* If all the remaining symbols are identical enumerals, then
     just keep the first one and discard the rest.

     Unlike what we did previously, we do not discard any entry
     unless they are ALL identical.  This is because the symbol
     comparison is not a strict comparison, but rather a practical
     comparison.  If all symbols are considered identical, then
     we can just go ahead and use the first one and discard the rest.
     But if we cannot reduce the list to a single element, we have
     to ask the user to disambiguate anyways.  And if we have to
     present a multiple-choice menu, it's less confusing if the list
     isn't missing some choices that were identical and yet distinct.  */
  if (symbols_are_identical_enums (*syms))
    syms->resize (1);
}

/* Given a type that corresponds to a renaming entity, use the type name
   to extract the scope (package name or function name, fully qualified,
   and following the GNAT encoding convention) where this renaming has been
   defined.  */

static std::string
xget_renaming_scope (struct type *renaming_type)
{
  /* The renaming types adhere to the following convention:
     <scope>__<rename>___<XR extension>.
     So, to extract the scope, we search for the "___XR" extension,
     and then backtrack until we find the first "__".  */

  const char *name = renaming_type->name ();
  const char *suffix = strstr (name, "___XR");
  const char *last;

  /* Now, backtrack a bit until we find the first "__".  Start looking
     at suffix - 3, as the <rename> part is at least one character long.  */

  for (last = suffix - 3; last > name; last--)
    if (last[0] == '_' && last[1] == '_')
      break;

  /* Make a copy of scope and return it.  */
  return std::string (name, last);
}

/* Return nonzero if NAME corresponds to a package name.  */

static int
is_package_name (const char *name)
{
  /* Here, We take advantage of the fact that no symbols are generated
     for packages, while symbols are generated for each function.
     So the condition for NAME represent a package becomes equivalent
     to NAME not existing in our list of symbols.  There is only one
     small complication with library-level functions (see below).  */

  /* If it is a function that has not been defined at library level,
     then we should be able to look it up in the symbols.  */
  if (standard_lookup (name, NULL, VAR_DOMAIN) != NULL)
    return 0;

  /* Library-level function names start with "_ada_".  See if function
     "_ada_" followed by NAME can be found.  */

  /* Do a quick check that NAME does not contain "__", since library-level
     functions names cannot contain "__" in them.  */
  if (strstr (name, "__") != NULL)
    return 0;

  std::string fun_name = string_printf ("_ada_%s", name);

  return (standard_lookup (fun_name.c_str (), NULL, VAR_DOMAIN) == NULL);
}

/* Return nonzero if SYM corresponds to a renaming entity that is
   not visible from FUNCTION_NAME.  */

static int
old_renaming_is_invisible (const struct symbol *sym, const char *function_name)
{
  if (sym->aclass () != LOC_TYPEDEF)
    return 0;

  std::string scope = xget_renaming_scope (sym->type ());

  /* If the rename has been defined in a package, then it is visible.  */
  if (is_package_name (scope.c_str ()))
    return 0;

  /* Check that the rename is in the current function scope by checking
     that its name starts with SCOPE.  */

  /* If the function name starts with "_ada_", it means that it is
     a library-level function.  Strip this prefix before doing the
     comparison, as the encoding for the renaming does not contain
     this prefix.  */
  if (startswith (function_name, "_ada_"))
    function_name += 5;

  return !startswith (function_name, scope.c_str ());
}

/* Remove entries from SYMS that corresponds to a renaming entity that
   is not visible from the function associated with CURRENT_BLOCK or
   that is superfluous due to the presence of more specific renaming
   information.  Places surviving symbols in the initial entries of
   SYMS.

   Rationale:
   First, in cases where an object renaming is implemented as a
   reference variable, GNAT may produce both the actual reference
   variable and the renaming encoding.  In this case, we discard the
   latter.

   Second, GNAT emits a type following a specified encoding for each renaming
   entity.  Unfortunately, STABS currently does not support the definition
   of types that are local to a given lexical block, so all renamings types
   are emitted at library level.  As a consequence, if an application
   contains two renaming entities using the same name, and a user tries to
   print the value of one of these entities, the result of the ada symbol
   lookup will also contain the wrong renaming type.

   This function partially covers for this limitation by attempting to
   remove from the SYMS list renaming symbols that should be visible
   from CURRENT_BLOCK.  However, there does not seem be a 100% reliable
   method with the current information available.  The implementation
   below has a couple of limitations (FIXME: brobecker-2003-05-12):  
   
      - When the user tries to print a rename in a function while there
	is another rename entity defined in a package:  Normally, the
	rename in the function has precedence over the rename in the
	package, so the latter should be removed from the list.  This is
	currently not the case.
	
      - This function will incorrectly remove valid renames if
	the CURRENT_BLOCK corresponds to a function which symbol name
	has been changed by an "Export" pragma.  As a consequence,
	the user will be unable to print such rename entities.  */

static void
remove_irrelevant_renamings (std::vector<struct block_symbol> *syms,
			     const struct block *current_block)
{
  struct symbol *current_function;
  const char *current_function_name;
  int i;
  int is_new_style_renaming;

  /* If there is both a renaming foo___XR... encoded as a variable and
     a simple variable foo in the same block, discard the latter.
     First, zero out such symbols, then compress.  */
  is_new_style_renaming = 0;
  for (i = 0; i < syms->size (); i += 1)
    {
      struct symbol *sym = (*syms)[i].symbol;
      const struct block *block = (*syms)[i].block;
      const char *name;
      const char *suffix;

      if (sym == NULL || sym->aclass () == LOC_TYPEDEF)
	continue;
      name = sym->linkage_name ();
      suffix = strstr (name, "___XR");

      if (suffix != NULL)
	{
	  int name_len = suffix - name;
	  int j;

	  is_new_style_renaming = 1;
	  for (j = 0; j < syms->size (); j += 1)
	    if (i != j && (*syms)[j].symbol != NULL
		&& strncmp (name, (*syms)[j].symbol->linkage_name (),
			    name_len) == 0
		&& block == (*syms)[j].block)
	      (*syms)[j].symbol = NULL;
	}
    }
  if (is_new_style_renaming)
    {
      int j, k;

      for (j = k = 0; j < syms->size (); j += 1)
	if ((*syms)[j].symbol != NULL)
	    {
	      (*syms)[k] = (*syms)[j];
	      k += 1;
	    }
      syms->resize (k);
      return;
    }

  /* Extract the function name associated to CURRENT_BLOCK.
     Abort if unable to do so.  */

  if (current_block == NULL)
    return;

  current_function = block_linkage_function (current_block);
  if (current_function == NULL)
    return;

  current_function_name = current_function->linkage_name ();
  if (current_function_name == NULL)
    return;

  /* Check each of the symbols, and remove it from the list if it is
     a type corresponding to a renaming that is out of the scope of
     the current block.  */

  i = 0;
  while (i < syms->size ())
    {
      if (ada_parse_renaming ((*syms)[i].symbol, NULL, NULL, NULL)
	  == ADA_OBJECT_RENAMING
	  && old_renaming_is_invisible ((*syms)[i].symbol,
					current_function_name))
	syms->erase (syms->begin () + i);
      else
	i += 1;
    }
}

/* Add to RESULT all symbols from BLOCK (and its super-blocks)
   whose name and domain match LOOKUP_NAME and DOMAIN respectively.

   Note: This function assumes that RESULT is empty.  */

static void
ada_add_local_symbols (std::vector<struct block_symbol> &result,
		       const lookup_name_info &lookup_name,
		       const struct block *block, domain_enum domain)
{
  while (block != NULL)
    {
      ada_add_block_symbols (result, block, lookup_name, domain, NULL);

      /* If we found a non-function match, assume that's the one.  We
	 only check this when finding a function boundary, so that we
	 can accumulate all results from intervening blocks first.  */
      if (block->function () != nullptr && is_nonfunction (result))
	return;

      block = block->superblock ();
    }
}

/* An object of this type is used as the callback argument when
   calling the map_matching_symbols method.  */

struct match_data
{
  explicit match_data (std::vector<struct block_symbol> *rp)
    : resultp (rp)
  {
  }
  DISABLE_COPY_AND_ASSIGN (match_data);

  bool operator() (struct block_symbol *bsym);

  struct objfile *objfile = nullptr;
  std::vector<struct block_symbol> *resultp;
  struct symbol *arg_sym = nullptr;
  bool found_sym = false;
};

/* A callback for add_nonlocal_symbols that adds symbol, found in
   BSYM, to a list of symbols.  */

bool
match_data::operator() (struct block_symbol *bsym)
{
  const struct block *block = bsym->block;
  struct symbol *sym = bsym->symbol;

  if (sym == NULL)
    {
      if (!found_sym && arg_sym != NULL)
	add_defn_to_vec (*resultp,
			 fixup_symbol_section (arg_sym, objfile),
			 block);
      found_sym = false;
      arg_sym = NULL;
    }
  else 
    {
      if (sym->aclass () == LOC_UNRESOLVED)
	return true;
      else if (sym->is_argument ())
	arg_sym = sym;
      else
	{
	  found_sym = true;
	  add_defn_to_vec (*resultp,
			   fixup_symbol_section (sym, objfile),
			   block);
	}
    }
  return true;
}

/* Helper for add_nonlocal_symbols.  Find symbols in DOMAIN which are
   targeted by renamings matching LOOKUP_NAME in BLOCK.  Add these
   symbols to RESULT.  Return whether we found such symbols.  */

static int
ada_add_block_renamings (std::vector<struct block_symbol> &result,
			 const struct block *block,
			 const lookup_name_info &lookup_name,
			 domain_enum domain)
{
  struct using_direct *renaming;
  int defns_mark = result.size ();

  symbol_name_matcher_ftype *name_match
    = ada_get_symbol_name_matcher (lookup_name);

  for (renaming = block_using (block);
       renaming != NULL;
       renaming = renaming->next)
    {
      const char *r_name;

      /* Avoid infinite recursions: skip this renaming if we are actually
	 already traversing it.

	 Currently, symbol lookup in Ada don't use the namespace machinery from
	 C++/Fortran support: skip namespace imports that use them.  */
      if (renaming->searched
	  || (renaming->import_src != NULL
	      && renaming->import_src[0] != '\0')
	  || (renaming->import_dest != NULL
	      && renaming->import_dest[0] != '\0'))
	continue;
      renaming->searched = 1;

      /* TODO: here, we perform another name-based symbol lookup, which can
	 pull its own multiple overloads.  In theory, we should be able to do
	 better in this case since, in DWARF, DW_AT_import is a DIE reference,
	 not a simple name.  But in order to do this, we would need to enhance
	 the DWARF reader to associate a symbol to this renaming, instead of a
	 name.  So, for now, we do something simpler: re-use the C++/Fortran
	 namespace machinery.  */
      r_name = (renaming->alias != NULL
		? renaming->alias
		: renaming->declaration);
      if (name_match (r_name, lookup_name, NULL))
	{
	  lookup_name_info decl_lookup_name (renaming->declaration,
					     lookup_name.match_type ());
	  ada_add_all_symbols (result, block, decl_lookup_name, domain,
			       1, NULL);
	}
      renaming->searched = 0;
    }
  return result.size () != defns_mark;
}

/* Implements compare_names, but only applying the comparision using
   the given CASING.  */

static int
compare_names_with_case (const char *string1, const char *string2,
			 enum case_sensitivity casing)
{
  while (*string1 != '\0' && *string2 != '\0')
    {
      char c1, c2;

      if (isspace (*string1) || isspace (*string2))
	return strcmp_iw_ordered (string1, string2);

      if (casing == case_sensitive_off)
	{
	  c1 = tolower (*string1);
	  c2 = tolower (*string2);
	}
      else
	{
	  c1 = *string1;
	  c2 = *string2;
	}
      if (c1 != c2)
	break;

      string1 += 1;
      string2 += 1;
    }

  switch (*string1)
    {
    case '(':
      return strcmp_iw_ordered (string1, string2);
    case '_':
      if (*string2 == '\0')
	{
	  if (is_name_suffix (string1))
	    return 0;
	  else
	    return 1;
	}
      /* FALLTHROUGH */
    default:
      if (*string2 == '(')
	return strcmp_iw_ordered (string1, string2);
      else
	{
	  if (casing == case_sensitive_off)
	    return tolower (*string1) - tolower (*string2);
	  else
	    return *string1 - *string2;
	}
    }
}

/* Compare STRING1 to STRING2, with results as for strcmp.
   Compatible with strcmp_iw_ordered in that...

       strcmp_iw_ordered (STRING1, STRING2) <= 0

   ... implies...

       compare_names (STRING1, STRING2) <= 0

   (they may differ as to what symbols compare equal).  */

static int
compare_names (const char *string1, const char *string2)
{
  int result;

  /* Similar to what strcmp_iw_ordered does, we need to perform
     a case-insensitive comparison first, and only resort to
     a second, case-sensitive, comparison if the first one was
     not sufficient to differentiate the two strings.  */

  result = compare_names_with_case (string1, string2, case_sensitive_off);
  if (result == 0)
    result = compare_names_with_case (string1, string2, case_sensitive_on);

  return result;
}

/* Convenience function to get at the Ada encoded lookup name for
   LOOKUP_NAME, as a C string.  */

static const char *
ada_lookup_name (const lookup_name_info &lookup_name)
{
  return lookup_name.ada ().lookup_name ().c_str ();
}

/* A helper for add_nonlocal_symbols.  Call expand_matching_symbols
   for OBJFILE, then walk the objfile's symtabs and update the
   results.  */

static void
map_matching_symbols (struct objfile *objfile,
		      const lookup_name_info &lookup_name,
		      bool is_wild_match,
		      domain_enum domain,
		      int global,
		      match_data &data)
{
  data.objfile = objfile;
  objfile->expand_matching_symbols (lookup_name, domain, global,
				    is_wild_match ? nullptr : compare_names);

  const int block_kind = global ? GLOBAL_BLOCK : STATIC_BLOCK;
  for (compunit_symtab *symtab : objfile->compunits ())
    {
      const struct block *block
	= symtab->blockvector ()->block (block_kind);
      if (!iterate_over_symbols_terminated (block, lookup_name,
					    domain, data))
	break;
    }
}

/* Add to RESULT all non-local symbols whose name and domain match
   LOOKUP_NAME and DOMAIN respectively.  The search is performed on
   GLOBAL_BLOCK symbols if GLOBAL is non-zero, or on STATIC_BLOCK
   symbols otherwise.  */

static void
add_nonlocal_symbols (std::vector<struct block_symbol> &result,
		      const lookup_name_info &lookup_name,
		      domain_enum domain, int global)
{
  struct match_data data (&result);

  bool is_wild_match = lookup_name.ada ().wild_match_p ();

  for (objfile *objfile : current_program_space->objfiles ())
    {
      map_matching_symbols (objfile, lookup_name, is_wild_match, domain,
			    global, data);

      for (compunit_symtab *cu : objfile->compunits ())
	{
	  const struct block *global_block
	    = cu->blockvector ()->global_block ();

	  if (ada_add_block_renamings (result, global_block, lookup_name,
				       domain))
	    data.found_sym = true;
	}
    }

  if (result.empty () && global && !is_wild_match)
    {
      const char *name = ada_lookup_name (lookup_name);
      std::string bracket_name = std::string ("<_ada_") + name + '>';
      lookup_name_info name1 (bracket_name, symbol_name_match_type::FULL);

      for (objfile *objfile : current_program_space->objfiles ())
	map_matching_symbols (objfile, name1, false, domain, global, data);
    }
}

/* Find symbols in DOMAIN matching LOOKUP_NAME, in BLOCK and, if
   FULL_SEARCH is non-zero, enclosing scope and in global scopes,
   returning the number of matches.  Add these to RESULT.

   When FULL_SEARCH is non-zero, any non-function/non-enumeral
   symbol match within the nest of blocks whose innermost member is BLOCK,
   is the one match returned (no other matches in that or
   enclosing blocks is returned).  If there are any matches in or
   surrounding BLOCK, then these alone are returned.

   Names prefixed with "standard__" are handled specially:
   "standard__" is first stripped off (by the lookup_name
   constructor), and only static and global symbols are searched.

   If MADE_GLOBAL_LOOKUP_P is non-null, set it before return to whether we had
   to lookup global symbols.  */

static void
ada_add_all_symbols (std::vector<struct block_symbol> &result,
		     const struct block *block,
		     const lookup_name_info &lookup_name,
		     domain_enum domain,
		     int full_search,
		     int *made_global_lookup_p)
{
  struct symbol *sym;

  if (made_global_lookup_p)
    *made_global_lookup_p = 0;

  /* Special case: If the user specifies a symbol name inside package
     Standard, do a non-wild matching of the symbol name without
     the "standard__" prefix.  This was primarily introduced in order
     to allow the user to specifically access the standard exceptions
     using, for instance, Standard.Constraint_Error when Constraint_Error
     is ambiguous (due to the user defining its own Constraint_Error
     entity inside its program).  */
  if (lookup_name.ada ().standard_p ())
    block = NULL;

  /* Check the non-global symbols.  If we have ANY match, then we're done.  */

  if (block != NULL)
    {
      if (full_search)
	ada_add_local_symbols (result, lookup_name, block, domain);
      else
	{
	  /* In the !full_search case we're are being called by
	     iterate_over_symbols, and we don't want to search
	     superblocks.  */
	  ada_add_block_symbols (result, block, lookup_name, domain, NULL);
	}
      if (!result.empty () || !full_search)
	return;
    }

  /* No non-global symbols found.  Check our cache to see if we have
     already performed this search before.  If we have, then return
     the same result.  */

  if (lookup_cached_symbol (ada_lookup_name (lookup_name),
			    domain, &sym, &block))
    {
      if (sym != NULL)
	add_defn_to_vec (result, sym, block);
      return;
    }

  if (made_global_lookup_p)
    *made_global_lookup_p = 1;

  /* Search symbols from all global blocks.  */
 
  add_nonlocal_symbols (result, lookup_name, domain, 1);

  /* Now add symbols from all per-file blocks if we've gotten no hits
     (not strictly correct, but perhaps better than an error).  */

  if (result.empty ())
    add_nonlocal_symbols (result, lookup_name, domain, 0);
}

/* Find symbols in DOMAIN matching LOOKUP_NAME, in BLOCK and, if FULL_SEARCH
   is non-zero, enclosing scope and in global scopes.

   Returns (SYM,BLOCK) tuples, indicating the symbols found and the
   blocks and symbol tables (if any) in which they were found.

   When full_search is non-zero, any non-function/non-enumeral
   symbol match within the nest of blocks whose innermost member is BLOCK,
   is the one match returned (no other matches in that or
   enclosing blocks is returned).  If there are any matches in or
   surrounding BLOCK, then these alone are returned.

   Names prefixed with "standard__" are handled specially: "standard__"
   is first stripped off, and only static and global symbols are searched.  */

static std::vector<struct block_symbol>
ada_lookup_symbol_list_worker (const lookup_name_info &lookup_name,
			       const struct block *block,
			       domain_enum domain,
			       int full_search)
{
  int syms_from_global_search;
  std::vector<struct block_symbol> results;

  ada_add_all_symbols (results, block, lookup_name,
		       domain, full_search, &syms_from_global_search);

  remove_extra_symbols (&results);

  if (results.empty () && full_search && syms_from_global_search)
    cache_symbol (ada_lookup_name (lookup_name), domain, NULL, NULL);

  if (results.size () == 1 && full_search && syms_from_global_search)
    cache_symbol (ada_lookup_name (lookup_name), domain,
		  results[0].symbol, results[0].block);

  remove_irrelevant_renamings (&results, block);
  return results;
}

/* Find symbols in DOMAIN matching NAME, in BLOCK and enclosing scope and
   in global scopes, returning (SYM,BLOCK) tuples.

   See ada_lookup_symbol_list_worker for further details.  */

std::vector<struct block_symbol>
ada_lookup_symbol_list (const char *name, const struct block *block,
			domain_enum domain)
{
  symbol_name_match_type name_match_type = name_match_type_from_name (name);
  lookup_name_info lookup_name (name, name_match_type);

  return ada_lookup_symbol_list_worker (lookup_name, block, domain, 1);
}

/* The result is as for ada_lookup_symbol_list with FULL_SEARCH set
   to 1, but choosing the first symbol found if there are multiple
   choices.

   The result is stored in *INFO, which must be non-NULL.
   If no match is found, INFO->SYM is set to NULL.  */

void
ada_lookup_encoded_symbol (const char *name, const struct block *block,
			   domain_enum domain,
			   struct block_symbol *info)
{
  /* Since we already have an encoded name, wrap it in '<>' to force a
     verbatim match.  Otherwise, if the name happens to not look like
     an encoded name (because it doesn't include a "__"),
     ada_lookup_name_info would re-encode/fold it again, and that
     would e.g., incorrectly lowercase object renaming names like
     "R28b" -> "r28b".  */
  std::string verbatim = add_angle_brackets (name);

  gdb_assert (info != NULL);
  *info = ada_lookup_symbol (verbatim.c_str (), block, domain);
}

/* Return a symbol in DOMAIN matching NAME, in BLOCK0 and enclosing
   scope and in global scopes, or NULL if none.  NAME is folded and
   encoded first.  Otherwise, the result is as for ada_lookup_symbol_list,
   choosing the first symbol if there are multiple choices.  */

struct block_symbol
ada_lookup_symbol (const char *name, const struct block *block0,
		   domain_enum domain)
{
  std::vector<struct block_symbol> candidates
    = ada_lookup_symbol_list (name, block0, domain);

  if (candidates.empty ())
    return {};

  block_symbol info = candidates[0];
  info.symbol = fixup_symbol_section (info.symbol, NULL);
  return info;
}


/* True iff STR is a possible encoded suffix of a normal Ada name
   that is to be ignored for matching purposes.  Suffixes of parallel
   names (e.g., XVE) are not included here.  Currently, the possible suffixes
   are given by any of the regular expressions:

   [.$][0-9]+       [nested subprogram suffix, on platforms such as GNU/Linux]
   ___[0-9]+        [nested subprogram suffix, on platforms such as HP/UX]
   TKB              [subprogram suffix for task bodies]
   _E[0-9]+[bs]$    [protected object entry suffixes]
   (X[nb]*)?((\$|__)[0-9](_?[0-9]+)|___(JM|LJM|X([FDBUP].*|R[^T]?)))?$

   Also, any leading "__[0-9]+" sequence is skipped before the suffix
   match is performed.  This sequence is used to differentiate homonyms,
   is an optional part of a valid name suffix.  */

static int
is_name_suffix (const char *str)
{
  int k;
  const char *matching;
  const int len = strlen (str);

  /* Skip optional leading __[0-9]+.  */

  if (len > 3 && str[0] == '_' && str[1] == '_' && isdigit (str[2]))
    {
      str += 3;
      while (isdigit (str[0]))
	str += 1;
    }
  
  /* [.$][0-9]+ */

  if (str[0] == '.' || str[0] == '$')
    {
      matching = str + 1;
      while (isdigit (matching[0]))
	matching += 1;
      if (matching[0] == '\0')
	return 1;
    }

  /* ___[0-9]+ */

  if (len > 3 && str[0] == '_' && str[1] == '_' && str[2] == '_')
    {
      matching = str + 3;
      while (isdigit (matching[0]))
	matching += 1;
      if (matching[0] == '\0')
	return 1;
    }

  /* "TKB" suffixes are used for subprograms implementing task bodies.  */

  if (strcmp (str, "TKB") == 0)
    return 1;

#if 0
  /* FIXME: brobecker/2005-09-23: Protected Object subprograms end
     with a N at the end.  Unfortunately, the compiler uses the same
     convention for other internal types it creates.  So treating
     all entity names that end with an "N" as a name suffix causes
     some regressions.  For instance, consider the case of an enumerated
     type.  To support the 'Image attribute, it creates an array whose
     name ends with N.
     Having a single character like this as a suffix carrying some
     information is a bit risky.  Perhaps we should change the encoding
     to be something like "_N" instead.  In the meantime, do not do
     the following check.  */
  /* Protected Object Subprograms */
  if (len == 1 && str [0] == 'N')
    return 1;
#endif

  /* _E[0-9]+[bs]$ */
  if (len > 3 && str[0] == '_' && str [1] == 'E' && isdigit (str[2]))
    {
      matching = str + 3;
      while (isdigit (matching[0]))
	matching += 1;
      if ((matching[0] == 'b' || matching[0] == 's')
	  && matching [1] == '\0')
	return 1;
    }

  /* ??? We should not modify STR directly, as we are doing below.  This
     is fine in this case, but may become problematic later if we find
     that this alternative did not work, and want to try matching
     another one from the begining of STR.  Since we modified it, we
     won't be able to find the begining of the string anymore!  */
  if (str[0] == 'X')
    {
      str += 1;
      while (str[0] != '_' && str[0] != '\0')
	{
	  if (str[0] != 'n' && str[0] != 'b')
	    return 0;
	  str += 1;
	}
    }

  if (str[0] == '\000')
    return 1;

  if (str[0] == '_')
    {
      if (str[1] != '_' || str[2] == '\000')
	return 0;
      if (str[2] == '_')
	{
	  if (strcmp (str + 3, "JM") == 0)
	    return 1;
	  /* FIXME: brobecker/2004-09-30: GNAT will soon stop using
	     the LJM suffix in favor of the JM one.  But we will
	     still accept LJM as a valid suffix for a reasonable
	     amount of time, just to allow ourselves to debug programs
	     compiled using an older version of GNAT.  */
	  if (strcmp (str + 3, "LJM") == 0)
	    return 1;
	  if (str[3] != 'X')
	    return 0;
	  if (str[4] == 'F' || str[4] == 'D' || str[4] == 'B'
	      || str[4] == 'U' || str[4] == 'P')
	    return 1;
	  if (str[4] == 'R' && str[5] != 'T')
	    return 1;
	  return 0;
	}
      if (!isdigit (str[2]))
	return 0;
      for (k = 3; str[k] != '\0'; k += 1)
	if (!isdigit (str[k]) && str[k] != '_')
	  return 0;
      return 1;
    }
  if (str[0] == '$' && isdigit (str[1]))
    {
      for (k = 2; str[k] != '\0'; k += 1)
	if (!isdigit (str[k]) && str[k] != '_')
	  return 0;
      return 1;
    }
  return 0;
}

/* Return non-zero if the string starting at NAME and ending before
   NAME_END contains no capital letters.  */

static int
is_valid_name_for_wild_match (const char *name0)
{
  std::string decoded_name = ada_decode (name0);
  int i;

  /* If the decoded name starts with an angle bracket, it means that
     NAME0 does not follow the GNAT encoding format.  It should then
     not be allowed as a possible wild match.  */
  if (decoded_name[0] == '<')
    return 0;

  for (i=0; decoded_name[i] != '\0'; i++)
    if (isalpha (decoded_name[i]) && !islower (decoded_name[i]))
      return 0;

  return 1;
}

/* Advance *NAMEP to next occurrence in the string NAME0 of the TARGET0
   character which could start a simple name.  Assumes that *NAMEP points
   somewhere inside the string beginning at NAME0.  */

static int
advance_wild_match (const char **namep, const char *name0, char target0)
{
  const char *name = *namep;

  while (1)
    {
      char t0, t1;

      t0 = *name;
      if (t0 == '_')
	{
	  t1 = name[1];
	  if ((t1 >= 'a' && t1 <= 'z') || (t1 >= '0' && t1 <= '9'))
	    {
	      name += 1;
	      if (name == name0 + 5 && startswith (name0, "_ada"))
		break;
	      else
		name += 1;
	    }
	  else if (t1 == '_' && ((name[2] >= 'a' && name[2] <= 'z')
				 || name[2] == target0))
	    {
	      name += 2;
	      break;
	    }
	  else if (t1 == '_' && name[2] == 'B' && name[3] == '_')
	    {
	      /* Names like "pkg__B_N__name", where N is a number, are
		 block-local.  We can handle these by simply skipping
		 the "B_" here.  */
	      name += 4;
	    }
	  else
	    return 0;
	}
      else if ((t0 >= 'a' && t0 <= 'z') || (t0 >= '0' && t0 <= '9'))
	name += 1;
      else
	return 0;
    }

  *namep = name;
  return 1;
}

/* Return true iff NAME encodes a name of the form prefix.PATN.
   Ignores any informational suffixes of NAME (i.e., for which
   is_name_suffix is true).  Assumes that PATN is a lower-cased Ada
   simple name.  */

static bool
wild_match (const char *name, const char *patn)
{
  const char *p;
  const char *name0 = name;

  if (startswith (name, "___ghost_"))
    name += 9;

  while (1)
    {
      const char *match = name;

      if (*name == *patn)
	{
	  for (name += 1, p = patn + 1; *p != '\0'; name += 1, p += 1)
	    if (*p != *name)
	      break;
	  if (*p == '\0' && is_name_suffix (name))
	    return match == name0 || is_valid_name_for_wild_match (name0);

	  if (name[-1] == '_')
	    name -= 1;
	}
      if (!advance_wild_match (&name, name0, *patn))
	return false;
    }
}

/* Add symbols from BLOCK matching LOOKUP_NAME in DOMAIN to RESULT (if
   necessary).  OBJFILE is the section containing BLOCK.  */

static void
ada_add_block_symbols (std::vector<struct block_symbol> &result,
		       const struct block *block,
		       const lookup_name_info &lookup_name,
		       domain_enum domain, struct objfile *objfile)
{
  struct block_iterator iter;
  /* A matching argument symbol, if any.  */
  struct symbol *arg_sym;
  /* Set true when we find a matching non-argument symbol.  */
  bool found_sym;
  struct symbol *sym;

  arg_sym = NULL;
  found_sym = false;
  for (sym = block_iter_match_first (block, lookup_name, &iter);
       sym != NULL;
       sym = block_iter_match_next (lookup_name, &iter))
    {
      if (symbol_matches_domain (sym->language (), sym->domain (), domain))
	{
	  if (sym->aclass () != LOC_UNRESOLVED)
	    {
	      if (sym->is_argument ())
		arg_sym = sym;
	      else
		{
		  found_sym = true;
		  add_defn_to_vec (result,
				   fixup_symbol_section (sym, objfile),
				   block);
		}
	    }
	}
    }

  /* Handle renamings.  */

  if (ada_add_block_renamings (result, block, lookup_name, domain))
    found_sym = true;

  if (!found_sym && arg_sym != NULL)
    {
      add_defn_to_vec (result,
		       fixup_symbol_section (arg_sym, objfile),
		       block);
    }

  if (!lookup_name.ada ().wild_match_p ())
    {
      arg_sym = NULL;
      found_sym = false;
      const std::string &ada_lookup_name = lookup_name.ada ().lookup_name ();
      const char *name = ada_lookup_name.c_str ();
      size_t name_len = ada_lookup_name.size ();

      ALL_BLOCK_SYMBOLS (block, iter, sym)
      {
	if (symbol_matches_domain (sym->language (),
				   sym->domain (), domain))
	  {
	    int cmp;

	    cmp = (int) '_' - (int) sym->linkage_name ()[0];
	    if (cmp == 0)
	      {
		cmp = !startswith (sym->linkage_name (), "_ada_");
		if (cmp == 0)
		  cmp = strncmp (name, sym->linkage_name () + 5,
				 name_len);
	      }

	    if (cmp == 0
		&& is_name_suffix (sym->linkage_name () + name_len + 5))
	      {
		if (sym->aclass () != LOC_UNRESOLVED)
		  {
		    if (sym->is_argument ())
		      arg_sym = sym;
		    else
		      {
			found_sym = true;
			add_defn_to_vec (result,
					 fixup_symbol_section (sym, objfile),
					 block);
		      }
		  }
	      }
	  }
      }

      /* NOTE: This really shouldn't be needed for _ada_ symbols.
	 They aren't parameters, right?  */
      if (!found_sym && arg_sym != NULL)
	{
	  add_defn_to_vec (result,
			   fixup_symbol_section (arg_sym, objfile),
			   block);
	}
    }
}


				/* Symbol Completion */

/* See symtab.h.  */

bool
ada_lookup_name_info::matches
  (const char *sym_name,
   symbol_name_match_type match_type,
   completion_match_result *comp_match_res) const
{
  bool match = false;
  const char *text = m_encoded_name.c_str ();
  size_t text_len = m_encoded_name.size ();

  /* First, test against the fully qualified name of the symbol.  */

  if (strncmp (sym_name, text, text_len) == 0)
    match = true;

  std::string decoded_name = ada_decode (sym_name);
  if (match && !m_encoded_p)
    {
      /* One needed check before declaring a positive match is to verify
	 that iff we are doing a verbatim match, the decoded version
	 of the symbol name starts with '<'.  Otherwise, this symbol name
	 is not a suitable completion.  */

      bool has_angle_bracket = (decoded_name[0] == '<');
      match = (has_angle_bracket == m_verbatim_p);
    }

  if (match && !m_verbatim_p)
    {
      /* When doing non-verbatim match, another check that needs to
	 be done is to verify that the potentially matching symbol name
	 does not include capital letters, because the ada-mode would
	 not be able to understand these symbol names without the
	 angle bracket notation.  */
      const char *tmp;

      for (tmp = sym_name; *tmp != '\0' && !isupper (*tmp); tmp++);
      if (*tmp != '\0')
	match = false;
    }

  /* Second: Try wild matching...  */

  if (!match && m_wild_match_p)
    {
      /* Since we are doing wild matching, this means that TEXT
	 may represent an unqualified symbol name.  We therefore must
	 also compare TEXT against the unqualified name of the symbol.  */
      sym_name = ada_unqualified_name (decoded_name.c_str ());

      if (strncmp (sym_name, text, text_len) == 0)
	match = true;
    }

  /* Finally: If we found a match, prepare the result to return.  */

  if (!match)
    return false;

  if (comp_match_res != NULL)
    {
      std::string &match_str = comp_match_res->match.storage ();

      if (!m_encoded_p)
	match_str = ada_decode (sym_name);
      else
	{
	  if (m_verbatim_p)
	    match_str = add_angle_brackets (sym_name);
	  else
	    match_str = sym_name;

	}

      comp_match_res->set_match (match_str.c_str ());
    }

  return true;
}

				/* Field Access */

/* Return non-zero if TYPE is a pointer to the GNAT dispatch table used
   for tagged types.  */

static int
ada_is_dispatch_table_ptr_type (struct type *type)
{
  const char *name;

  if (type->code () != TYPE_CODE_PTR)
    return 0;

  name = TYPE_TARGET_TYPE (type)->name ();
  if (name == NULL)
    return 0;

  return (strcmp (name, "ada__tags__dispatch_table") == 0);
}

/* Return non-zero if TYPE is an interface tag.  */

static int
ada_is_interface_tag (struct type *type)
{
  const char *name = type->name ();

  if (name == NULL)
    return 0;

  return (strcmp (name, "ada__tags__interface_tag") == 0);
}

/* True if field number FIELD_NUM in struct or union type TYPE is supposed
   to be invisible to users.  */

int
ada_is_ignored_field (struct type *type, int field_num)
{
  if (field_num < 0 || field_num > type->num_fields ())
    return 1;

  /* Check the name of that field.  */
  {
    const char *name = type->field (field_num).name ();

    /* Anonymous field names should not be printed.
       brobecker/2007-02-20: I don't think this can actually happen
       but we don't want to print the value of anonymous fields anyway.  */
    if (name == NULL)
      return 1;

    /* Normally, fields whose name start with an underscore ("_")
       are fields that have been internally generated by the compiler,
       and thus should not be printed.  The "_parent" field is special,
       however: This is a field internally generated by the compiler
       for tagged types, and it contains the components inherited from
       the parent type.  This field should not be printed as is, but
       should not be ignored either.  */
    if (name[0] == '_' && !startswith (name, "_parent"))
      return 1;

    /* The compiler doesn't document this, but sometimes it emits
       a field whose name starts with a capital letter, like 'V148s'.
       These aren't marked as artificial in any way, but we know they
       should be ignored.  However, wrapper fields should not be
       ignored.  */
    if (name[0] == 'S' || name[0] == 'R' || name[0] == 'O')
      {
	/* Wrapper field.  */
      }
    else if (isupper (name[0]))
      return 1;
  }

  /* If this is the dispatch table of a tagged type or an interface tag,
     then ignore.  */
  if (ada_is_tagged_type (type, 1)
      && (ada_is_dispatch_table_ptr_type (type->field (field_num).type ())
	  || ada_is_interface_tag (type->field (field_num).type ())))
    return 1;

  /* Not a special field, so it should not be ignored.  */
  return 0;
}

/* True iff TYPE has a tag field.  If REFOK, then TYPE may also be a
   pointer or reference type whose ultimate target has a tag field.  */

int
ada_is_tagged_type (struct type *type, int refok)
{
  return (ada_lookup_struct_elt_type (type, "_tag", refok, 1) != NULL);
}

/* True iff TYPE represents the type of X'Tag */

int
ada_is_tag_type (struct type *type)
{
  type = ada_check_typedef (type);

  if (type == NULL || type->code () != TYPE_CODE_PTR)
    return 0;
  else
    {
      const char *name = ada_type_name (TYPE_TARGET_TYPE (type));

      return (name != NULL
	      && strcmp (name, "ada__tags__dispatch_table") == 0);
    }
}

/* The type of the tag on VAL.  */

static struct type *
ada_tag_type (struct value *val)
{
  return ada_lookup_struct_elt_type (value_type (val), "_tag", 1, 0);
}

/* Return 1 if TAG follows the old scheme for Ada tags (used for Ada 95,
   retired at Ada 05).  */

static int
is_ada95_tag (struct value *tag)
{
  return ada_value_struct_elt (tag, "tsd", 1) != NULL;
}

/* The value of the tag on VAL.  */

static struct value *
ada_value_tag (struct value *val)
{
  return ada_value_struct_elt (val, "_tag", 0);
}

/* The value of the tag on the object of type TYPE whose contents are
   saved at VALADDR, if it is non-null, or is at memory address
   ADDRESS.  */

static struct value *
value_tag_from_contents_and_address (struct type *type,
				     const gdb_byte *valaddr,
				     CORE_ADDR address)
{
  int tag_byte_offset;
  struct type *tag_type;

  gdb::array_view<const gdb_byte> contents;
  if (valaddr != nullptr)
    contents = gdb::make_array_view (valaddr, TYPE_LENGTH (type));
  struct type *resolved_type = resolve_dynamic_type (type, contents, address);
  if (find_struct_field ("_tag", resolved_type, 0, &tag_type, &tag_byte_offset,
			 NULL, NULL, NULL))
    {
      const gdb_byte *valaddr1 = ((valaddr == NULL)
				  ? NULL
				  : valaddr + tag_byte_offset);
      CORE_ADDR address1 = (address == 0) ? 0 : address + tag_byte_offset;

      return value_from_contents_and_address (tag_type, valaddr1, address1);
    }
  return NULL;
}

static struct type *
type_from_tag (struct value *tag)
{
  gdb::unique_xmalloc_ptr<char> type_name = ada_tag_name (tag);

  if (type_name != NULL)
    return ada_find_any_type (ada_encode (type_name.get ()).c_str ());
  return NULL;
}

/* Given a value OBJ of a tagged type, return a value of this
   type at the base address of the object.  The base address, as
   defined in Ada.Tags, it is the address of the primary tag of
   the object, and therefore where the field values of its full
   view can be fetched.  */

struct value *
ada_tag_value_at_base_address (struct value *obj)
{
  struct value *val;
  LONGEST offset_to_top = 0;
  struct type *ptr_type, *obj_type;
  struct value *tag;
  CORE_ADDR base_address;

  obj_type = value_type (obj);

  /* It is the responsability of the caller to deref pointers.  */

  if (obj_type->code () == TYPE_CODE_PTR || obj_type->code () == TYPE_CODE_REF)
    return obj;

  tag = ada_value_tag (obj);
  if (!tag)
    return obj;

  /* Base addresses only appeared with Ada 05 and multiple inheritance.  */

  if (is_ada95_tag (tag))
    return obj;

  struct type *offset_type
    = language_lookup_primitive_type (language_def (language_ada),
				      target_gdbarch(), "storage_offset");
  ptr_type = lookup_pointer_type (offset_type);
  val = value_cast (ptr_type, tag);
  if (!val)
    return obj;

  /* It is perfectly possible that an exception be raised while
     trying to determine the base address, just like for the tag;
     see ada_tag_name for more details.  We do not print the error
     message for the same reason.  */

  try
    {
      offset_to_top = value_as_long (value_ind (value_ptradd (val, -2)));
    }

  catch (const gdb_exception_error &e)
    {
      return obj;
    }

  /* If offset is null, nothing to do.  */

  if (offset_to_top == 0)
    return obj;

  /* -1 is a special case in Ada.Tags; however, what should be done
     is not quite clear from the documentation.  So do nothing for
     now.  */

  if (offset_to_top == -1)
    return obj;

  /* Storage_Offset'Last is used to indicate that a dynamic offset to
     top is used.  In this situation the offset is stored just after
     the tag, in the object itself.  */
  ULONGEST last = (((ULONGEST) 1) << (8 * TYPE_LENGTH (offset_type) - 1)) - 1;
  if (offset_to_top == last)
    {
      struct value *tem = value_addr (tag);
      tem = value_ptradd (tem, 1);
      tem = value_cast (ptr_type, tem);
      offset_to_top = value_as_long (value_ind (tem));
    }
  else if (offset_to_top > 0)
    {
      /* OFFSET_TO_TOP used to be a positive value to be subtracted
	 from the base address.  This was however incompatible with
	 C++ dispatch table: C++ uses a *negative* value to *add*
	 to the base address.  Ada's convention has therefore been
	 changed in GNAT 19.0w 20171023: since then, C++ and Ada
	 use the same convention.  Here, we support both cases by
	 checking the sign of OFFSET_TO_TOP.  */
      offset_to_top = -offset_to_top;
    }

  base_address = value_address (obj) + offset_to_top;
  tag = value_tag_from_contents_and_address (obj_type, NULL, base_address);

  /* Make sure that we have a proper tag at the new address.
     Otherwise, offset_to_top is bogus (which can happen when
     the object is not initialized yet).  */

  if (!tag)
    return obj;

  obj_type = type_from_tag (tag);

  if (!obj_type)
    return obj;

  return value_from_contents_and_address (obj_type, NULL, base_address);
}

/* Return the "ada__tags__type_specific_data" type.  */

static struct type *
ada_get_tsd_type (struct inferior *inf)
{
  struct ada_inferior_data *data = get_ada_inferior_data (inf);

  if (data->tsd_type == 0)
    data->tsd_type = ada_find_any_type ("ada__tags__type_specific_data");
  return data->tsd_type;
}

/* Return the TSD (type-specific data) associated to the given TAG.
   TAG is assumed to be the tag of a tagged-type entity.

   May return NULL if we are unable to get the TSD.  */

static struct value *
ada_get_tsd_from_tag (struct value *tag)
{
  struct value *val;
  struct type *type;

  /* First option: The TSD is simply stored as a field of our TAG.
     Only older versions of GNAT would use this format, but we have
     to test it first, because there are no visible markers for
     the current approach except the absence of that field.  */

  val = ada_value_struct_elt (tag, "tsd", 1);
  if (val)
    return val;

  /* Try the second representation for the dispatch table (in which
     there is no explicit 'tsd' field in the referent of the tag pointer,
     and instead the tsd pointer is stored just before the dispatch
     table.  */

  type = ada_get_tsd_type (current_inferior());
  if (type == NULL)
    return NULL;
  type = lookup_pointer_type (lookup_pointer_type (type));
  val = value_cast (type, tag);
  if (val == NULL)
    return NULL;
  return value_ind (value_ptradd (val, -1));
}

/* Given the TSD of a tag (type-specific data), return a string
   containing the name of the associated type.

   May return NULL if we are unable to determine the tag name.  */

static gdb::unique_xmalloc_ptr<char>
ada_tag_name_from_tsd (struct value *tsd)
{
  struct value *val;

  val = ada_value_struct_elt (tsd, "expanded_name", 1);
  if (val == NULL)
    return NULL;
  gdb::unique_xmalloc_ptr<char> buffer
    = target_read_string (value_as_address (val), INT_MAX);
  if (buffer == nullptr)
    return nullptr;

  try
    {
      /* Let this throw an exception on error.  If the data is
	 uninitialized, we'd rather not have the user see a
	 warning.  */
      const char *folded = ada_fold_name (buffer.get (), true);
      return make_unique_xstrdup (folded);
    }
  catch (const gdb_exception &)
    {
      return nullptr;
    }
}

/* The type name of the dynamic type denoted by the 'tag value TAG, as
   a C string.

   Return NULL if the TAG is not an Ada tag, or if we were unable to
   determine the name of that tag.  */

gdb::unique_xmalloc_ptr<char>
ada_tag_name (struct value *tag)
{
  gdb::unique_xmalloc_ptr<char> name;

  if (!ada_is_tag_type (value_type (tag)))
    return NULL;

  /* It is perfectly possible that an exception be raised while trying
     to determine the TAG's name, even under normal circumstances:
     The associated variable may be uninitialized or corrupted, for
     instance. We do not let any exception propagate past this point.
     instead we return NULL.

     We also do not print the error message either (which often is very
     low-level (Eg: "Cannot read memory at 0x[...]"), but instead let
     the caller print a more meaningful message if necessary.  */
  try
    {
      struct value *tsd = ada_get_tsd_from_tag (tag);

      if (tsd != NULL)
	name = ada_tag_name_from_tsd (tsd);
    }
  catch (const gdb_exception_error &e)
    {
    }

  return name;
}

/* The parent type of TYPE, or NULL if none.  */

struct type *
ada_parent_type (struct type *type)
{
  int i;

  type = ada_check_typedef (type);

  if (type == NULL || type->code () != TYPE_CODE_STRUCT)
    return NULL;

  for (i = 0; i < type->num_fields (); i += 1)
    if (ada_is_parent_field (type, i))
      {
	struct type *parent_type = type->field (i).type ();

	/* If the _parent field is a pointer, then dereference it.  */
	if (parent_type->code () == TYPE_CODE_PTR)
	  parent_type = TYPE_TARGET_TYPE (parent_type);
	/* If there is a parallel XVS type, get the actual base type.  */
	parent_type = ada_get_base_type (parent_type);

	return ada_check_typedef (parent_type);
      }

  return NULL;
}

/* True iff field number FIELD_NUM of structure type TYPE contains the
   parent-type (inherited) fields of a derived type.  Assumes TYPE is
   a structure type with at least FIELD_NUM+1 fields.  */

int
ada_is_parent_field (struct type *type, int field_num)
{
  const char *name = ada_check_typedef (type)->field (field_num).name ();

  return (name != NULL
	  && (startswith (name, "PARENT")
	      || startswith (name, "_parent")));
}

/* True iff field number FIELD_NUM of structure type TYPE is a
   transparent wrapper field (which should be silently traversed when doing
   field selection and flattened when printing).  Assumes TYPE is a
   structure type with at least FIELD_NUM+1 fields.  Such fields are always
   structures.  */

int
ada_is_wrapper_field (struct type *type, int field_num)
{
  const char *name = type->field (field_num).name ();

  if (name != NULL && strcmp (name, "RETVAL") == 0)
    {
      /* This happens in functions with "out" or "in out" parameters
	 which are passed by copy.  For such functions, GNAT describes
	 the function's return type as being a struct where the return
	 value is in a field called RETVAL, and where the other "out"
	 or "in out" parameters are fields of that struct.  This is not
	 a wrapper.  */
      return 0;
    }

  return (name != NULL
	  && (startswith (name, "PARENT")
	      || strcmp (name, "REP") == 0
	      || startswith (name, "_parent")
	      || name[0] == 'S' || name[0] == 'R' || name[0] == 'O'));
}

/* True iff field number FIELD_NUM of structure or union type TYPE
   is a variant wrapper.  Assumes TYPE is a structure type with at least
   FIELD_NUM+1 fields.  */

int
ada_is_variant_part (struct type *type, int field_num)
{
  /* Only Ada types are eligible.  */
  if (!ADA_TYPE_P (type))
    return 0;

  struct type *field_type = type->field (field_num).type ();

  return (field_type->code () == TYPE_CODE_UNION
	  || (is_dynamic_field (type, field_num)
	      && (TYPE_TARGET_TYPE (field_type)->code ()
		  == TYPE_CODE_UNION)));
}

/* Assuming that VAR_TYPE is a variant wrapper (type of the variant part)
   whose discriminants are contained in the record type OUTER_TYPE,
   returns the type of the controlling discriminant for the variant.
   May return NULL if the type could not be found.  */

struct type *
ada_variant_discrim_type (struct type *var_type, struct type *outer_type)
{
  const char *name = ada_variant_discrim_name (var_type);

  return ada_lookup_struct_elt_type (outer_type, name, 1, 1);
}

/* Assuming that TYPE is the type of a variant wrapper, and FIELD_NUM is a
   valid field number within it, returns 1 iff field FIELD_NUM of TYPE
   represents a 'when others' clause; otherwise 0.  */

static int
ada_is_others_clause (struct type *type, int field_num)
{
  const char *name = type->field (field_num).name ();

  return (name != NULL && name[0] == 'O');
}

/* Assuming that TYPE0 is the type of the variant part of a record,
   returns the name of the discriminant controlling the variant.
   The value is valid until the next call to ada_variant_discrim_name.  */

const char *
ada_variant_discrim_name (struct type *type0)
{
  static std::string result;
  struct type *type;
  const char *name;
  const char *discrim_end;
  const char *discrim_start;

  if (type0->code () == TYPE_CODE_PTR)
    type = TYPE_TARGET_TYPE (type0);
  else
    type = type0;

  name = ada_type_name (type);

  if (name == NULL || name[0] == '\000')
    return "";

  for (discrim_end = name + strlen (name) - 6; discrim_end != name;
       discrim_end -= 1)
    {
      if (startswith (discrim_end, "___XVN"))
	break;
    }
  if (discrim_end == name)
    return "";

  for (discrim_start = discrim_end; discrim_start != name + 3;
       discrim_start -= 1)
    {
      if (discrim_start == name + 1)
	return "";
      if ((discrim_start > name + 3
	   && startswith (discrim_start - 3, "___"))
	  || discrim_start[-1] == '.')
	break;
    }

  result = std::string (discrim_start, discrim_end - discrim_start);
  return result.c_str ();
}

/* Scan STR for a subtype-encoded number, beginning at position K.
   Put the position of the character just past the number scanned in
   *NEW_K, if NEW_K!=NULL.  Put the scanned number in *R, if R!=NULL.
   Return 1 if there was a valid number at the given position, and 0
   otherwise.  A "subtype-encoded" number consists of the absolute value
   in decimal, followed by the letter 'm' to indicate a negative number.
   Assumes 0m does not occur.  */

int
ada_scan_number (const char str[], int k, LONGEST * R, int *new_k)
{
  ULONGEST RU;

  if (!isdigit (str[k]))
    return 0;

  /* Do it the hard way so as not to make any assumption about
     the relationship of unsigned long (%lu scan format code) and
     LONGEST.  */
  RU = 0;
  while (isdigit (str[k]))
    {
      RU = RU * 10 + (str[k] - '0');
      k += 1;
    }

  if (str[k] == 'm')
    {
      if (R != NULL)
	*R = (-(LONGEST) (RU - 1)) - 1;
      k += 1;
    }
  else if (R != NULL)
    *R = (LONGEST) RU;

  /* NOTE on the above: Technically, C does not say what the results of
     - (LONGEST) RU or (LONGEST) -RU are for RU == largest positive
     number representable as a LONGEST (although either would probably work
     in most implementations).  When RU>0, the locution in the then branch
     above is always equivalent to the negative of RU.  */

  if (new_k != NULL)
    *new_k = k;
  return 1;
}

/* Assuming that TYPE is a variant part wrapper type (a VARIANTS field),
   and FIELD_NUM is a valid field number within it, returns 1 iff VAL is
   in the range encoded by field FIELD_NUM of TYPE; otherwise 0.  */

static int
ada_in_variant (LONGEST val, struct type *type, int field_num)
{
  const char *name = type->field (field_num).name ();
  int p;

  p = 0;
  while (1)
    {
      switch (name[p])
	{
	case '\0':
	  return 0;
	case 'S':
	  {
	    LONGEST W;

	    if (!ada_scan_number (name, p + 1, &W, &p))
	      return 0;
	    if (val == W)
	      return 1;
	    break;
	  }
	case 'R':
	  {
	    LONGEST L, U;

	    if (!ada_scan_number (name, p + 1, &L, &p)
		|| name[p] != 'T' || !ada_scan_number (name, p + 1, &U, &p))
	      return 0;
	    if (val >= L && val <= U)
	      return 1;
	    break;
	  }
	case 'O':
	  return 1;
	default:
	  return 0;
	}
    }
}

/* FIXME: Lots of redundancy below.  Try to consolidate.  */

/* Given a value ARG1 (offset by OFFSET bytes) of a struct or union type
   ARG_TYPE, extract and return the value of one of its (non-static)
   fields.  FIELDNO says which field.   Differs from value_primitive_field
   only in that it can handle packed values of arbitrary type.  */

struct value *
ada_value_primitive_field (struct value *arg1, int offset, int fieldno,
			   struct type *arg_type)
{
  struct type *type;

  arg_type = ada_check_typedef (arg_type);
  type = arg_type->field (fieldno).type ();

  /* Handle packed fields.  It might be that the field is not packed
     relative to its containing structure, but the structure itself is
     packed; in this case we must take the bit-field path.  */
  if (TYPE_FIELD_BITSIZE (arg_type, fieldno) != 0 || value_bitpos (arg1) != 0)
    {
      int bit_pos = arg_type->field (fieldno).loc_bitpos ();
      int bit_size = TYPE_FIELD_BITSIZE (arg_type, fieldno);

      return ada_value_primitive_packed_val (arg1,
					     value_contents (arg1).data (),
					     offset + bit_pos / 8,
					     bit_pos % 8, bit_size, type);
    }
  else
    return value_primitive_field (arg1, offset, fieldno, arg_type);
}

/* Find field with name NAME in object of type TYPE.  If found, 
   set the following for each argument that is non-null:
    - *FIELD_TYPE_P to the field's type; 
    - *BYTE_OFFSET_P to OFFSET + the byte offset of the field within 
      an object of that type;
    - *BIT_OFFSET_P to the bit offset modulo byte size of the field; 
    - *BIT_SIZE_P to its size in bits if the field is packed, and 
      0 otherwise;
   If INDEX_P is non-null, increment *INDEX_P by the number of source-visible
   fields up to but not including the desired field, or by the total
   number of fields if not found.   A NULL value of NAME never
   matches; the function just counts visible fields in this case.
   
   Notice that we need to handle when a tagged record hierarchy
   has some components with the same name, like in this scenario:

      type Top_T is tagged record
	 N : Integer := 1;
	 U : Integer := 974;
	 A : Integer := 48;
      end record;

      type Middle_T is new Top.Top_T with record
	 N : Character := 'a';
	 C : Integer := 3;
      end record;

     type Bottom_T is new Middle.Middle_T with record
	N : Float := 4.0;
	C : Character := '5';
	X : Integer := 6;
	A : Character := 'J';
     end record;

   Let's say we now have a variable declared and initialized as follow:

     TC : Top_A := new Bottom_T;

   And then we use this variable to call this function

     procedure Assign (Obj: in out Top_T; TV : Integer);

   as follow:

      Assign (Top_T (B), 12);

   Now, we're in the debugger, and we're inside that procedure
   then and we want to print the value of obj.c:

   Usually, the tagged record or one of the parent type owns the
   component to print and there's no issue but in this particular
   case, what does it mean to ask for Obj.C? Since the actual
   type for object is type Bottom_T, it could mean two things: type
   component C from the Middle_T view, but also component C from
   Bottom_T.  So in that "undefined" case, when the component is
   not found in the non-resolved type (which includes all the
   components of the parent type), then resolve it and see if we
   get better luck once expanded.

   In the case of homonyms in the derived tagged type, we don't
   guaranty anything, and pick the one that's easiest for us
   to program.

   Returns 1 if found, 0 otherwise.  */

static int
find_struct_field (const char *name, struct type *type, int offset,
		   struct type **field_type_p,
		   int *byte_offset_p, int *bit_offset_p, int *bit_size_p,
		   int *index_p)
{
  int i;
  int parent_offset = -1;

  type = ada_check_typedef (type);

  if (field_type_p != NULL)
    *field_type_p = NULL;
  if (byte_offset_p != NULL)
    *byte_offset_p = 0;
  if (bit_offset_p != NULL)
    *bit_offset_p = 0;
  if (bit_size_p != NULL)
    *bit_size_p = 0;

  for (i = 0; i < type->num_fields (); i += 1)
    {
      /* These can't be computed using TYPE_FIELD_BITPOS for a dynamic
	 type.  However, we only need the values to be correct when
	 the caller asks for them.  */
      int bit_pos = 0, fld_offset = 0;
      if (byte_offset_p != nullptr || bit_offset_p != nullptr)
	{
	  bit_pos = type->field (i).loc_bitpos ();
	  fld_offset = offset + bit_pos / 8;
	}

      const char *t_field_name = type->field (i).name ();

      if (t_field_name == NULL)
	continue;

      else if (ada_is_parent_field (type, i))
	{
	  /* This is a field pointing us to the parent type of a tagged
	     type.  As hinted in this function's documentation, we give
	     preference to fields in the current record first, so what
	     we do here is just record the index of this field before
	     we skip it.  If it turns out we couldn't find our field
	     in the current record, then we'll get back to it and search
	     inside it whether the field might exist in the parent.  */

	  parent_offset = i;
	  continue;
	}

      else if (name != NULL && field_name_match (t_field_name, name))
	{
	  int bit_size = TYPE_FIELD_BITSIZE (type, i);

	  if (field_type_p != NULL)
	    *field_type_p = type->field (i).type ();
	  if (byte_offset_p != NULL)
	    *byte_offset_p = fld_offset;
	  if (bit_offset_p != NULL)
	    *bit_offset_p = bit_pos % 8;
	  if (bit_size_p != NULL)
	    *bit_size_p = bit_size;
	  return 1;
	}
      else if (ada_is_wrapper_field (type, i))
	{
	  if (find_struct_field (name, type->field (i).type (), fld_offset,
				 field_type_p, byte_offset_p, bit_offset_p,
				 bit_size_p, index_p))
	    return 1;
	}
      else if (ada_is_variant_part (type, i))
	{
	  /* PNH: Wait.  Do we ever execute this section, or is ARG always of 
	     fixed type?? */
	  int j;
	  struct type *field_type
	    = ada_check_typedef (type->field (i).type ());

	  for (j = 0; j < field_type->num_fields (); j += 1)
	    {
	      if (find_struct_field (name, field_type->field (j).type (),
				     fld_offset
				     + field_type->field (j).loc_bitpos () / 8,
				     field_type_p, byte_offset_p,
				     bit_offset_p, bit_size_p, index_p))
		return 1;
	    }
	}
      else if (index_p != NULL)
	*index_p += 1;
    }

  /* Field not found so far.  If this is a tagged type which
     has a parent, try finding that field in the parent now.  */

  if (parent_offset != -1)
    {
      /* As above, only compute the offset when truly needed.  */
      int fld_offset = offset;
      if (byte_offset_p != nullptr || bit_offset_p != nullptr)
	{
	  int bit_pos = type->field (parent_offset).loc_bitpos ();
	  fld_offset += bit_pos / 8;
	}

      if (find_struct_field (name, type->field (parent_offset).type (),
			     fld_offset, field_type_p, byte_offset_p,
			     bit_offset_p, bit_size_p, index_p))
	return 1;
    }

  return 0;
}

/* Number of user-visible fields in record type TYPE.  */

static int
num_visible_fields (struct type *type)
{
  int n;

  n = 0;
  find_struct_field (NULL, type, 0, NULL, NULL, NULL, NULL, &n);
  return n;
}

/* Look for a field NAME in ARG.  Adjust the address of ARG by OFFSET bytes,
   and search in it assuming it has (class) type TYPE.
   If found, return value, else return NULL.

   Searches recursively through wrapper fields (e.g., '_parent').

   In the case of homonyms in the tagged types, please refer to the
   long explanation in find_struct_field's function documentation.  */

static struct value *
ada_search_struct_field (const char *name, struct value *arg, int offset,
			 struct type *type)
{
  int i;
  int parent_offset = -1;

  type = ada_check_typedef (type);
  for (i = 0; i < type->num_fields (); i += 1)
    {
      const char *t_field_name = type->field (i).name ();

      if (t_field_name == NULL)
	continue;

      else if (ada_is_parent_field (type, i))
	{
	  /* This is a field pointing us to the parent type of a tagged
	     type.  As hinted in this function's documentation, we give
	     preference to fields in the current record first, so what
	     we do here is just record the index of this field before
	     we skip it.  If it turns out we couldn't find our field
	     in the current record, then we'll get back to it and search
	     inside it whether the field might exist in the parent.  */

	  parent_offset = i;
	  continue;
	}

      else if (field_name_match (t_field_name, name))
	return ada_value_primitive_field (arg, offset, i, type);

      else if (ada_is_wrapper_field (type, i))
	{
	  struct value *v =     /* Do not let indent join lines here.  */
	    ada_search_struct_field (name, arg,
				     offset + type->field (i).loc_bitpos () / 8,
				     type->field (i).type ());

	  if (v != NULL)
	    return v;
	}

      else if (ada_is_variant_part (type, i))
	{
	  /* PNH: Do we ever get here?  See find_struct_field.  */
	  int j;
	  struct type *field_type = ada_check_typedef (type->field (i).type ());
	  int var_offset = offset + type->field (i).loc_bitpos () / 8;

	  for (j = 0; j < field_type->num_fields (); j += 1)
	    {
	      struct value *v = ada_search_struct_field /* Force line
							   break.  */
		(name, arg,
		 var_offset + field_type->field (j).loc_bitpos () / 8,
		 field_type->field (j).type ());

	      if (v != NULL)
		return v;
	    }
	}
    }

  /* Field not found so far.  If this is a tagged type which
     has a parent, try finding that field in the parent now.  */

  if (parent_offset != -1)
    {
      struct value *v = ada_search_struct_field (
	name, arg, offset + type->field (parent_offset).loc_bitpos () / 8,
	type->field (parent_offset).type ());

      if (v != NULL)
	return v;
    }

  return NULL;
}

static struct value *ada_index_struct_field_1 (int *, struct value *,
					       int, struct type *);


/* Return field #INDEX in ARG, where the index is that returned by
 * find_struct_field through its INDEX_P argument.  Adjust the address
 * of ARG by OFFSET bytes, and search in it assuming it has (class) type TYPE.
 * If found, return value, else return NULL.  */

static struct value *
ada_index_struct_field (int index, struct value *arg, int offset,
			struct type *type)
{
  return ada_index_struct_field_1 (&index, arg, offset, type);
}


/* Auxiliary function for ada_index_struct_field.  Like
 * ada_index_struct_field, but takes index from *INDEX_P and modifies
 * *INDEX_P.  */

static struct value *
ada_index_struct_field_1 (int *index_p, struct value *arg, int offset,
			  struct type *type)
{
  int i;
  type = ada_check_typedef (type);

  for (i = 0; i < type->num_fields (); i += 1)
    {
      if (type->field (i).name () == NULL)
	continue;
      else if (ada_is_wrapper_field (type, i))
	{
	  struct value *v =     /* Do not let indent join lines here.  */
	    ada_index_struct_field_1 (index_p, arg,
				      offset + type->field (i).loc_bitpos () / 8,
				      type->field (i).type ());

	  if (v != NULL)
	    return v;
	}

      else if (ada_is_variant_part (type, i))
	{
	  /* PNH: Do we ever get here?  See ada_search_struct_field,
	     find_struct_field.  */
	  error (_("Cannot assign this kind of variant record"));
	}
      else if (*index_p == 0)
	return ada_value_primitive_field (arg, offset, i, type);
      else
	*index_p -= 1;
    }
  return NULL;
}

/* Return a string representation of type TYPE.  */

static std::string
type_as_string (struct type *type)
{
  string_file tmp_stream;

  type_print (type, "", &tmp_stream, -1);

  return tmp_stream.release ();
}

/* Given a type TYPE, look up the type of the component of type named NAME.
   If DISPP is non-null, add its byte displacement from the beginning of a
   structure (pointed to by a value) of type TYPE to *DISPP (does not
   work for packed fields).

   Matches any field whose name has NAME as a prefix, possibly
   followed by "___".

   TYPE can be either a struct or union.  If REFOK, TYPE may also 
   be a (pointer or reference)+ to a struct or union, and the
   ultimate target type will be searched.

   Looks recursively into variant clauses and parent types.

   In the case of homonyms in the tagged types, please refer to the
   long explanation in find_struct_field's function documentation.

   If NOERR is nonzero, return NULL if NAME is not suitably defined or
   TYPE is not a type of the right kind.  */

static struct type *
ada_lookup_struct_elt_type (struct type *type, const char *name, int refok,
			    int noerr)
{
  int i;
  int parent_offset = -1;

  if (name == NULL)
    goto BadName;

  if (refok && type != NULL)
    while (1)
      {
	type = ada_check_typedef (type);
	if (type->code () != TYPE_CODE_PTR && type->code () != TYPE_CODE_REF)
	  break;
	type = TYPE_TARGET_TYPE (type);
      }

  if (type == NULL
      || (type->code () != TYPE_CODE_STRUCT
	  && type->code () != TYPE_CODE_UNION))
    {
      if (noerr)
	return NULL;

      error (_("Type %s is not a structure or union type"),
	     type != NULL ? type_as_string (type).c_str () : _("(null)"));
    }

  type = to_static_fixed_type (type);

  for (i = 0; i < type->num_fields (); i += 1)
    {
      const char *t_field_name = type->field (i).name ();
      struct type *t;

      if (t_field_name == NULL)
	continue;

      else if (ada_is_parent_field (type, i))
	{
	  /* This is a field pointing us to the parent type of a tagged
	     type.  As hinted in this function's documentation, we give
	     preference to fields in the current record first, so what
	     we do here is just record the index of this field before
	     we skip it.  If it turns out we couldn't find our field
	     in the current record, then we'll get back to it and search
	     inside it whether the field might exist in the parent.  */

	  parent_offset = i;
	  continue;
	}

      else if (field_name_match (t_field_name, name))
	return type->field (i).type ();

      else if (ada_is_wrapper_field (type, i))
	{
	  t = ada_lookup_struct_elt_type (type->field (i).type (), name,
					  0, 1);
	  if (t != NULL)
	    return t;
	}

      else if (ada_is_variant_part (type, i))
	{
	  int j;
	  struct type *field_type = ada_check_typedef (type->field (i).type ());

	  for (j = field_type->num_fields () - 1; j >= 0; j -= 1)
	    {
	      /* FIXME pnh 2008/01/26: We check for a field that is
		 NOT wrapped in a struct, since the compiler sometimes
		 generates these for unchecked variant types.  Revisit
		 if the compiler changes this practice.  */
	      const char *v_field_name = field_type->field (j).name ();

	      if (v_field_name != NULL 
		  && field_name_match (v_field_name, name))
		t = field_type->field (j).type ();
	      else
		t = ada_lookup_struct_elt_type (field_type->field (j).type (),
						name, 0, 1);

	      if (t != NULL)
		return t;
	    }
	}

    }

    /* Field not found so far.  If this is a tagged type which
       has a parent, try finding that field in the parent now.  */

    if (parent_offset != -1)
      {
	struct type *t;

	t = ada_lookup_struct_elt_type (type->field (parent_offset).type (),
					name, 0, 1);
	if (t != NULL)
	  return t;
      }

BadName:
  if (!noerr)
    {
      const char *name_str = name != NULL ? name : _("<null>");

      error (_("Type %s has no component named %s"),
	     type_as_string (type).c_str (), name_str);
    }

  return NULL;
}

/* Assuming that VAR_TYPE is the type of a variant part of a record (a union),
   within a value of type OUTER_TYPE, return true iff VAR_TYPE
   represents an unchecked union (that is, the variant part of a
   record that is named in an Unchecked_Union pragma).  */

static int
is_unchecked_variant (struct type *var_type, struct type *outer_type)
{
  const char *discrim_name = ada_variant_discrim_name (var_type);

  return (ada_lookup_struct_elt_type (outer_type, discrim_name, 0, 1) == NULL);
}


/* Assuming that VAR_TYPE is the type of a variant part of a record (a union),
   within OUTER, determine which variant clause (field number in VAR_TYPE,
   numbering from 0) is applicable.  Returns -1 if none are.  */

int
ada_which_variant_applies (struct type *var_type, struct value *outer)
{
  int others_clause;
  int i;
  const char *discrim_name = ada_variant_discrim_name (var_type);
  struct value *discrim;
  LONGEST discrim_val;

  /* Using plain value_from_contents_and_address here causes problems
     because we will end up trying to resolve a type that is currently
     being constructed.  */
  discrim = ada_value_struct_elt (outer, discrim_name, 1);
  if (discrim == NULL)
    return -1;
  discrim_val = value_as_long (discrim);

  others_clause = -1;
  for (i = 0; i < var_type->num_fields (); i += 1)
    {
      if (ada_is_others_clause (var_type, i))
	others_clause = i;
      else if (ada_in_variant (discrim_val, var_type, i))
	return i;
    }

  return others_clause;
}



				/* Dynamic-Sized Records */

/* Strategy: The type ostensibly attached to a value with dynamic size
   (i.e., a size that is not statically recorded in the debugging
   data) does not accurately reflect the size or layout of the value.
   Our strategy is to convert these values to values with accurate,
   conventional types that are constructed on the fly.  */

/* There is a subtle and tricky problem here.  In general, we cannot
   determine the size of dynamic records without its data.  However,
   the 'struct value' data structure, which GDB uses to represent
   quantities in the inferior process (the target), requires the size
   of the type at the time of its allocation in order to reserve space
   for GDB's internal copy of the data.  That's why the
   'to_fixed_xxx_type' routines take (target) addresses as parameters,
   rather than struct value*s.

   However, GDB's internal history variables ($1, $2, etc.) are
   struct value*s containing internal copies of the data that are not, in
   general, the same as the data at their corresponding addresses in
   the target.  Fortunately, the types we give to these values are all
   conventional, fixed-size types (as per the strategy described
   above), so that we don't usually have to perform the
   'to_fixed_xxx_type' conversions to look at their values.
   Unfortunately, there is one exception: if one of the internal
   history variables is an array whose elements are unconstrained
   records, then we will need to create distinct fixed types for each
   element selected.  */

/* The upshot of all of this is that many routines take a (type, host
   address, target address) triple as arguments to represent a value.
   The host address, if non-null, is supposed to contain an internal
   copy of the relevant data; otherwise, the program is to consult the
   target at the target address.  */

/* Assuming that VAL0 represents a pointer value, the result of
   dereferencing it.  Differs from value_ind in its treatment of
   dynamic-sized types.  */

struct value *
ada_value_ind (struct value *val0)
{
  struct value *val = value_ind (val0);

  if (ada_is_tagged_type (value_type (val), 0))
    val = ada_tag_value_at_base_address (val);

  return ada_to_fixed_value (val);
}

/* The value resulting from dereferencing any "reference to"
   qualifiers on VAL0.  */

static struct value *
ada_coerce_ref (struct value *val0)
{
  if (value_type (val0)->code () == TYPE_CODE_REF)
    {
      struct value *val = val0;

      val = coerce_ref (val);

      if (ada_is_tagged_type (value_type (val), 0))
	val = ada_tag_value_at_base_address (val);

      return ada_to_fixed_value (val);
    }
  else
    return val0;
}

/* Return the bit alignment required for field #F of template type TYPE.  */

static unsigned int
field_alignment (struct type *type, int f)
{
  const char *name = type->field (f).name ();
  int len;
  int align_offset;

  /* The field name should never be null, unless the debugging information
     is somehow malformed.  In this case, we assume the field does not
     require any alignment.  */
  if (name == NULL)
    return 1;

  len = strlen (name);

  if (!isdigit (name[len - 1]))
    return 1;

  if (isdigit (name[len - 2]))
    align_offset = len - 2;
  else
    align_offset = len - 1;

  if (align_offset < 7 || !startswith (name + align_offset - 6, "___XV"))
    return TARGET_CHAR_BIT;

  return atoi (name + align_offset) * TARGET_CHAR_BIT;
}

/* Find a typedef or tag symbol named NAME.  Ignores ambiguity.  */

static struct symbol *
ada_find_any_type_symbol (const char *name)
{
  struct symbol *sym;

  sym = standard_lookup (name, get_selected_block (NULL), VAR_DOMAIN);
  if (sym != NULL && sym->aclass () == LOC_TYPEDEF)
    return sym;

  sym = standard_lookup (name, NULL, STRUCT_DOMAIN);
  return sym;
}

/* Find a type named NAME.  Ignores ambiguity.  This routine will look
   solely for types defined by debug info, it will not search the GDB
   primitive types.  */

static struct type *
ada_find_any_type (const char *name)
{
  struct symbol *sym = ada_find_any_type_symbol (name);

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

  return NULL;
}

/* Given NAME_SYM and an associated BLOCK, find a "renaming" symbol
   associated with NAME_SYM's name.  NAME_SYM may itself be a renaming
   symbol, in which case it is returned.  Otherwise, this looks for
   symbols whose name is that of NAME_SYM suffixed with  "___XR".
   Return symbol if found, and NULL otherwise.  */

static bool
ada_is_renaming_symbol (struct symbol *name_sym)
{
  const char *name = name_sym->linkage_name ();
  return strstr (name, "___XR") != NULL;
}

/* Because of GNAT encoding conventions, several GDB symbols may match a
   given type name.  If the type denoted by TYPE0 is to be preferred to
   that of TYPE1 for purposes of type printing, return non-zero;
   otherwise return 0.  */

int
ada_prefer_type (struct type *type0, struct type *type1)
{
  if (type1 == NULL)
    return 1;
  else if (type0 == NULL)
    return 0;
  else if (type1->code () == TYPE_CODE_VOID)
    return 1;
  else if (type0->code () == TYPE_CODE_VOID)
    return 0;
  else if (type1->name () == NULL && type0->name () != NULL)
    return 1;
  else if (ada_is_constrained_packed_array_type (type0))
    return 1;
  else if (ada_is_array_descriptor_type (type0)
	   && !ada_is_array_descriptor_type (type1))
    return 1;
  else
    {
      const char *type0_name = type0->name ();
      const char *type1_name = type1->name ();

      if (type0_name != NULL && strstr (type0_name, "___XR") != NULL
	  && (type1_name == NULL || strstr (type1_name, "___XR") == NULL))
	return 1;
    }
  return 0;
}

/* The name of TYPE, which is its TYPE_NAME.  Null if TYPE is
   null.  */

const char *
ada_type_name (struct type *type)
{
  if (type == NULL)
    return NULL;
  return type->name ();
}

/* Search the list of "descriptive" types associated to TYPE for a type
   whose name is NAME.  */

static struct type *
find_parallel_type_by_descriptive_type (struct type *type, const char *name)
{
  struct type *result, *tmp;

  if (ada_ignore_descriptive_types_p)
    return NULL;

  /* If there no descriptive-type info, then there is no parallel type
     to be found.  */
  if (!HAVE_GNAT_AUX_INFO (type))
    return NULL;

  result = TYPE_DESCRIPTIVE_TYPE (type);
  while (result != NULL)
    {
      const char *result_name = ada_type_name (result);

      if (result_name == NULL)
	{
	  warning (_("unexpected null name on descriptive type"));
	  return NULL;
	}

      /* If the names match, stop.  */
      if (strcmp (result_name, name) == 0)
	break;

      /* Otherwise, look at the next item on the list, if any.  */
      if (HAVE_GNAT_AUX_INFO (result))
	tmp = TYPE_DESCRIPTIVE_TYPE (result);
      else
	tmp = NULL;

      /* If not found either, try after having resolved the typedef.  */
      if (tmp != NULL)
	result = tmp;
      else
	{
	  result = check_typedef (result);
	  if (HAVE_GNAT_AUX_INFO (result))
	    result = TYPE_DESCRIPTIVE_TYPE (result);
	  else
	    result = NULL;
	}
    }

  /* If we didn't find a match, see whether this is a packed array.  With
     older compilers, the descriptive type information is either absent or
     irrelevant when it comes to packed arrays so the above lookup fails.
     Fall back to using a parallel lookup by name in this case.  */
  if (result == NULL && ada_is_constrained_packed_array_type (type))
    return ada_find_any_type (name);

  return result;
}

/* Find a parallel type to TYPE with the specified NAME, using the
   descriptive type taken from the debugging information, if available,
   and otherwise using the (slower) name-based method.  */

static struct type *
ada_find_parallel_type_with_name (struct type *type, const char *name)
{
  struct type *result = NULL;

  if (HAVE_GNAT_AUX_INFO (type))
    result = find_parallel_type_by_descriptive_type (type, name);
  else
    result = ada_find_any_type (name);

  return result;
}

/* Same as above, but specify the name of the parallel type by appending
   SUFFIX to the name of TYPE.  */

struct type *
ada_find_parallel_type (struct type *type, const char *suffix)
{
  char *name;
  const char *type_name = ada_type_name (type);
  int len;

  if (type_name == NULL)
    return NULL;

  len = strlen (type_name);

  name = (char *) alloca (len + strlen (suffix) + 1);

  strcpy (name, type_name);
  strcpy (name + len, suffix);

  return ada_find_parallel_type_with_name (type, name);
}

/* If TYPE is a variable-size record type, return the corresponding template
   type describing its fields.  Otherwise, return NULL.  */

static struct type *
dynamic_template_type (struct type *type)
{
  type = ada_check_typedef (type);

  if (type == NULL || type->code () != TYPE_CODE_STRUCT
      || ada_type_name (type) == NULL)
    return NULL;
  else
    {
      int len = strlen (ada_type_name (type));

      if (len > 6 && strcmp (ada_type_name (type) + len - 6, "___XVE") == 0)
	return type;
      else
	return ada_find_parallel_type (type, "___XVE");
    }
}

/* Assuming that TEMPL_TYPE is a union or struct type, returns
   non-zero iff field FIELD_NUM of TEMPL_TYPE has dynamic size.  */

static int
is_dynamic_field (struct type *templ_type, int field_num)
{
  const char *name = templ_type->field (field_num).name ();

  return name != NULL
    && templ_type->field (field_num).type ()->code () == TYPE_CODE_PTR
    && strstr (name, "___XVL") != NULL;
}

/* The index of the variant field of TYPE, or -1 if TYPE does not
   represent a variant record type.  */

static int
variant_field_index (struct type *type)
{
  int f;

  if (type == NULL || type->code () != TYPE_CODE_STRUCT)
    return -1;

  for (f = 0; f < type->num_fields (); f += 1)
    {
      if (ada_is_variant_part (type, f))
	return f;
    }
  return -1;
}

/* A record type with no fields.  */

static struct type *
empty_record (struct type *templ)
{
  struct type *type = alloc_type_copy (templ);

  type->set_code (TYPE_CODE_STRUCT);
  INIT_NONE_SPECIFIC (type);
  type->set_name ("<empty>");
  TYPE_LENGTH (type) = 0;
  return type;
}

/* An ordinary record type (with fixed-length fields) that describes
   the value of type TYPE at VALADDR or ADDRESS (see comments at
   the beginning of this section) VAL according to GNAT conventions.
   DVAL0 should describe the (portion of a) record that contains any
   necessary discriminants.  It should be NULL if value_type (VAL) is
   an outer-level type (i.e., as opposed to a branch of a variant.)  A
   variant field (unless unchecked) is replaced by a particular branch
   of the variant.

   If not KEEP_DYNAMIC_FIELDS, then all fields whose position or
   length are not statically known are discarded.  As a consequence,
   VALADDR, ADDRESS and DVAL0 are ignored.

   NOTE: Limitations: For now, we assume that dynamic fields and
   variants occupy whole numbers of bytes.  However, they need not be
   byte-aligned.  */

struct type *
ada_template_to_fixed_record_type_1 (struct type *type,
				     const gdb_byte *valaddr,
				     CORE_ADDR address, struct value *dval0,
				     int keep_dynamic_fields)
{
  struct value *mark = value_mark ();
  struct value *dval;
  struct type *rtype;
  int nfields, bit_len;
  int variant_field;
  long off;
  int fld_bit_len;
  int f;

  /* Compute the number of fields in this record type that are going
     to be processed: unless keep_dynamic_fields, this includes only
     fields whose position and length are static will be processed.  */
  if (keep_dynamic_fields)
    nfields = type->num_fields ();
  else
    {
      nfields = 0;
      while (nfields < type->num_fields ()
	     && !ada_is_variant_part (type, nfields)
	     && !is_dynamic_field (type, nfields))
	nfields++;
    }

  rtype = alloc_type_copy (type);
  rtype->set_code (TYPE_CODE_STRUCT);
  INIT_NONE_SPECIFIC (rtype);
  rtype->set_num_fields (nfields);
  rtype->set_fields
   ((struct field *) TYPE_ZALLOC (rtype, nfields * sizeof (struct field)));
  rtype->set_name (ada_type_name (type));
  rtype->set_is_fixed_instance (true);

  off = 0;
  bit_len = 0;
  variant_field = -1;

  for (f = 0; f < nfields; f += 1)
    {
      off = align_up (off, field_alignment (type, f))
	+ type->field (f).loc_bitpos ();
      rtype->field (f).set_loc_bitpos (off);
      TYPE_FIELD_BITSIZE (rtype, f) = 0;

      if (ada_is_variant_part (type, f))
	{
	  variant_field = f;
	  fld_bit_len = 0;
	}
      else if (is_dynamic_field (type, f))
	{
	  const gdb_byte *field_valaddr = valaddr;
	  CORE_ADDR field_address = address;
	  struct type *field_type =
	    TYPE_TARGET_TYPE (type->field (f).type ());

	  if (dval0 == NULL)
	    {
	      /* Using plain value_from_contents_and_address here
		 causes problems because we will end up trying to
		 resolve a type that is currently being
		 constructed.  */
	      dval = value_from_contents_and_address_unresolved (rtype,
								 valaddr,
								 address);
	      rtype = value_type (dval);
	    }
	  else
	    dval = dval0;

	  /* If the type referenced by this field is an aligner type, we need
	     to unwrap that aligner type, because its size might not be set.
	     Keeping the aligner type would cause us to compute the wrong
	     size for this field, impacting the offset of the all the fields
	     that follow this one.  */
	  if (ada_is_aligner_type (field_type))
	    {
	      long field_offset = type->field (f).loc_bitpos ();

	      field_valaddr = cond_offset_host (field_valaddr, field_offset);
	      field_address = cond_offset_target (field_address, field_offset);
	      field_type = ada_aligned_type (field_type);
	    }

	  field_valaddr = cond_offset_host (field_valaddr,
					    off / TARGET_CHAR_BIT);
	  field_address = cond_offset_target (field_address,
					      off / TARGET_CHAR_BIT);

	  /* Get the fixed type of the field.  Note that, in this case,
	     we do not want to get the real type out of the tag: if
	     the current field is the parent part of a tagged record,
	     we will get the tag of the object.  Clearly wrong: the real
	     type of the parent is not the real type of the child.  We
	     would end up in an infinite loop.	*/
	  field_type = ada_get_base_type (field_type);
	  field_type = ada_to_fixed_type (field_type, field_valaddr,
					  field_address, dval, 0);

	  rtype->field (f).set_type (field_type);
	  rtype->field (f).set_name (type->field (f).name ());
	  /* The multiplication can potentially overflow.  But because
	     the field length has been size-checked just above, and
	     assuming that the maximum size is a reasonable value,
	     an overflow should not happen in practice.  So rather than
	     adding overflow recovery code to this already complex code,
	     we just assume that it's not going to happen.  */
	  fld_bit_len =
	    TYPE_LENGTH (rtype->field (f).type ()) * TARGET_CHAR_BIT;
	}
      else
	{
	  /* Note: If this field's type is a typedef, it is important
	     to preserve the typedef layer.

	     Otherwise, we might be transforming a typedef to a fat
	     pointer (encoding a pointer to an unconstrained array),
	     into a basic fat pointer (encoding an unconstrained
	     array).  As both types are implemented using the same
	     structure, the typedef is the only clue which allows us
	     to distinguish between the two options.  Stripping it
	     would prevent us from printing this field appropriately.  */
	  rtype->field (f).set_type (type->field (f).type ());
	  rtype->field (f).set_name (type->field (f).name ());
	  if (TYPE_FIELD_BITSIZE (type, f) > 0)
	    fld_bit_len =
	      TYPE_FIELD_BITSIZE (rtype, f) = TYPE_FIELD_BITSIZE (type, f);
	  else
	    {
	      struct type *field_type = type->field (f).type ();

	      /* We need to be careful of typedefs when computing
		 the length of our field.  If this is a typedef,
		 get the length of the target type, not the length
		 of the typedef.  */
	      if (field_type->code () == TYPE_CODE_TYPEDEF)
		field_type = ada_typedef_target_type (field_type);

	      fld_bit_len =
		TYPE_LENGTH (ada_check_typedef (field_type)) * TARGET_CHAR_BIT;
	    }
	}
      if (off + fld_bit_len > bit_len)
	bit_len = off + fld_bit_len;
      off += fld_bit_len;
      TYPE_LENGTH (rtype) =
	align_up (bit_len, TARGET_CHAR_BIT) / TARGET_CHAR_BIT;
    }

  /* We handle the variant part, if any, at the end because of certain
     odd cases in which it is re-ordered so as NOT to be the last field of
     the record.  This can happen in the presence of representation
     clauses.  */
  if (variant_field >= 0)
    {
      struct type *branch_type;

      off = rtype->field (variant_field).loc_bitpos ();

      if (dval0 == NULL)
	{
	  /* Using plain value_from_contents_and_address here causes
	     problems because we will end up trying to resolve a type
	     that is currently being constructed.  */
	  dval = value_from_contents_and_address_unresolved (rtype, valaddr,
							     address);
	  rtype = value_type (dval);
	}
      else
	dval = dval0;

      branch_type =
	to_fixed_variant_branch_type
	(type->field (variant_field).type (),
	 cond_offset_host (valaddr, off / TARGET_CHAR_BIT),
	 cond_offset_target (address, off / TARGET_CHAR_BIT), dval);
      if (branch_type == NULL)
	{
	  for (f = variant_field + 1; f < rtype->num_fields (); f += 1)
	    rtype->field (f - 1) = rtype->field (f);
	  rtype->set_num_fields (rtype->num_fields () - 1);
	}
      else
	{
	  rtype->field (variant_field).set_type (branch_type);
	  rtype->field (variant_field).set_name ("S");
	  fld_bit_len =
	    TYPE_LENGTH (rtype->field (variant_field).type ()) *
	    TARGET_CHAR_BIT;
	  if (off + fld_bit_len > bit_len)
	    bit_len = off + fld_bit_len;
	  TYPE_LENGTH (rtype) =
	    align_up (bit_len, TARGET_CHAR_BIT) / TARGET_CHAR_BIT;
	}
    }

  /* According to exp_dbug.ads, the size of TYPE for variable-size records
     should contain the alignment of that record, which should be a strictly
     positive value.  If null or negative, then something is wrong, most
     probably in the debug info.  In that case, we don't round up the size
     of the resulting type.  If this record is not part of another structure,
     the current RTYPE length might be good enough for our purposes.  */
  if (TYPE_LENGTH (type) <= 0)
    {
      if (rtype->name ())
	warning (_("Invalid type size for `%s' detected: %s."),
		 rtype->name (), pulongest (TYPE_LENGTH (type)));
      else
	warning (_("Invalid type size for <unnamed> detected: %s."),
		 pulongest (TYPE_LENGTH (type)));
    }
  else
    {
      TYPE_LENGTH (rtype) = align_up (TYPE_LENGTH (rtype),
				      TYPE_LENGTH (type));
    }

  value_free_to_mark (mark);
  return rtype;
}

/* As for ada_template_to_fixed_record_type_1 with KEEP_DYNAMIC_FIELDS
   of 1.  */

static struct type *
template_to_fixed_record_type (struct type *type, const gdb_byte *valaddr,
			       CORE_ADDR address, struct value *dval0)
{
  return ada_template_to_fixed_record_type_1 (type, valaddr,
					      address, dval0, 1);
}

/* An ordinary record type in which ___XVL-convention fields and
   ___XVU- and ___XVN-convention field types in TYPE0 are replaced with
   static approximations, containing all possible fields.  Uses
   no runtime values.  Useless for use in values, but that's OK,
   since the results are used only for type determinations.   Works on both
   structs and unions.  Representation note: to save space, we memorize
   the result of this function in the TYPE_TARGET_TYPE of the
   template type.  */

static struct type *
template_to_static_fixed_type (struct type *type0)
{
  struct type *type;
  int nfields;
  int f;

  /* No need no do anything if the input type is already fixed.  */
  if (type0->is_fixed_instance ())
    return type0;

  /* Likewise if we already have computed the static approximation.  */
  if (TYPE_TARGET_TYPE (type0) != NULL)
    return TYPE_TARGET_TYPE (type0);

  /* Don't clone TYPE0 until we are sure we are going to need a copy.  */
  type = type0;
  nfields = type0->num_fields ();

  /* Whether or not we cloned TYPE0, cache the result so that we don't do
     recompute all over next time.  */
  TYPE_TARGET_TYPE (type0) = type;

  for (f = 0; f < nfields; f += 1)
    {
      struct type *field_type = type0->field (f).type ();
      struct type *new_type;

      if (is_dynamic_field (type0, f))
	{
	  field_type = ada_check_typedef (field_type);
	  new_type = to_static_fixed_type (TYPE_TARGET_TYPE (field_type));
	}
      else
	new_type = static_unwrap_type (field_type);

      if (new_type != field_type)
	{
	  /* Clone TYPE0 only the first time we get a new field type.  */
	  if (type == type0)
	    {
	      TYPE_TARGET_TYPE (type0) = type = alloc_type_copy (type0);
	      type->set_code (type0->code ());
	      INIT_NONE_SPECIFIC (type);
	      type->set_num_fields (nfields);

	      field *fields =
		((struct field *)
		 TYPE_ALLOC (type, nfields * sizeof (struct field)));
	      memcpy (fields, type0->fields (),
		      sizeof (struct field) * nfields);
	      type->set_fields (fields);

	      type->set_name (ada_type_name (type0));
	      type->set_is_fixed_instance (true);
	      TYPE_LENGTH (type) = 0;
	    }
	  type->field (f).set_type (new_type);
	  type->field (f).set_name (type0->field (f).name ());
	}
    }

  return type;
}

/* Given an object of type TYPE whose contents are at VALADDR and
   whose address in memory is ADDRESS, returns a revision of TYPE,
   which should be a non-dynamic-sized record, in which the variant
   part, if any, is replaced with the appropriate branch.  Looks
   for discriminant values in DVAL0, which can be NULL if the record
   contains the necessary discriminant values.  */

static struct type *
to_record_with_fixed_variant_part (struct type *type, const gdb_byte *valaddr,
				   CORE_ADDR address, struct value *dval0)
{
  struct value *mark = value_mark ();
  struct value *dval;
  struct type *rtype;
  struct type *branch_type;
  int nfields = type->num_fields ();
  int variant_field = variant_field_index (type);

  if (variant_field == -1)
    return type;

  if (dval0 == NULL)
    {
      dval = value_from_contents_and_address (type, valaddr, address);
      type = value_type (dval);
    }
  else
    dval = dval0;

  rtype = alloc_type_copy (type);
  rtype->set_code (TYPE_CODE_STRUCT);
  INIT_NONE_SPECIFIC (rtype);
  rtype->set_num_fields (nfields);

  field *fields =
    (struct field *) TYPE_ALLOC (rtype, nfields * sizeof (struct field));
  memcpy (fields, type->fields (), sizeof (struct field) * nfields);
  rtype->set_fields (fields);

  rtype->set_name (ada_type_name (type));
  rtype->set_is_fixed_instance (true);
  TYPE_LENGTH (rtype) = TYPE_LENGTH (type);

  branch_type = to_fixed_variant_branch_type
    (type->field (variant_field).type (),
     cond_offset_host (valaddr,
		       type->field (variant_field).loc_bitpos ()
		       / TARGET_CHAR_BIT),
     cond_offset_target (address,
			 type->field (variant_field).loc_bitpos ()
			 / TARGET_CHAR_BIT), dval);
  if (branch_type == NULL)
    {
      int f;

      for (f = variant_field + 1; f < nfields; f += 1)
	rtype->field (f - 1) = rtype->field (f);
      rtype->set_num_fields (rtype->num_fields () - 1);
    }
  else
    {
      rtype->field (variant_field).set_type (branch_type);
      rtype->field (variant_field).set_name ("S");
      TYPE_FIELD_BITSIZE (rtype, variant_field) = 0;
      TYPE_LENGTH (rtype) += TYPE_LENGTH (branch_type);
    }
  TYPE_LENGTH (rtype) -= TYPE_LENGTH (type->field (variant_field).type ());

  value_free_to_mark (mark);
  return rtype;
}

/* An ordinary record type (with fixed-length fields) that describes
   the value at (TYPE0, VALADDR, ADDRESS) [see explanation at
   beginning of this section].   Any necessary discriminants' values
   should be in DVAL, a record value; it may be NULL if the object
   at ADDR itself contains any necessary discriminant values.
   Additionally, VALADDR and ADDRESS may also be NULL if no discriminant
   values from the record are needed.  Except in the case that DVAL,
   VALADDR, and ADDRESS are all 0 or NULL, a variant field (unless
   unchecked) is replaced by a particular branch of the variant.

   NOTE: the case in which DVAL and VALADDR are NULL and ADDRESS is 0
   is questionable and may be removed.  It can arise during the
   processing of an unconstrained-array-of-record type where all the
   variant branches have exactly the same size.  This is because in
   such cases, the compiler does not bother to use the XVS convention
   when encoding the record.  I am currently dubious of this
   shortcut and suspect the compiler should be altered.  FIXME.  */

static struct type *
to_fixed_record_type (struct type *type0, const gdb_byte *valaddr,
		      CORE_ADDR address, struct value *dval)
{
  struct type *templ_type;

  if (type0->is_fixed_instance ())
    return type0;

  templ_type = dynamic_template_type (type0);

  if (templ_type != NULL)
    return template_to_fixed_record_type (templ_type, valaddr, address, dval);
  else if (variant_field_index (type0) >= 0)
    {
      if (dval == NULL && valaddr == NULL && address == 0)
	return type0;
      return to_record_with_fixed_variant_part (type0, valaddr, address,
						dval);
    }
  else
    {
      type0->set_is_fixed_instance (true);
      return type0;
    }

}

/* An ordinary record type (with fixed-length fields) that describes
   the value at (VAR_TYPE0, VALADDR, ADDRESS), where VAR_TYPE0 is a
   union type.  Any necessary discriminants' values should be in DVAL,
   a record value.  That is, this routine selects the appropriate
   branch of the union at ADDR according to the discriminant value
   indicated in the union's type name.  Returns VAR_TYPE0 itself if
   it represents a variant subject to a pragma Unchecked_Union.  */

static struct type *
to_fixed_variant_branch_type (struct type *var_type0, const gdb_byte *valaddr,
			      CORE_ADDR address, struct value *dval)
{
  int which;
  struct type *templ_type;
  struct type *var_type;

  if (var_type0->code () == TYPE_CODE_PTR)
    var_type = TYPE_TARGET_TYPE (var_type0);
  else
    var_type = var_type0;

  templ_type = ada_find_parallel_type (var_type, "___XVU");

  if (templ_type != NULL)
    var_type = templ_type;

  if (is_unchecked_variant (var_type, value_type (dval)))
      return var_type0;
  which = ada_which_variant_applies (var_type, dval);

  if (which < 0)
    return empty_record (var_type);
  else if (is_dynamic_field (var_type, which))
    return to_fixed_record_type
      (TYPE_TARGET_TYPE (var_type->field (which).type ()),
       valaddr, address, dval);
  else if (variant_field_index (var_type->field (which).type ()) >= 0)
    return
      to_fixed_record_type
      (var_type->field (which).type (), valaddr, address, dval);
  else
    return var_type->field (which).type ();
}

/* Assuming RANGE_TYPE is a TYPE_CODE_RANGE, return nonzero if
   ENCODING_TYPE, a type following the GNAT conventions for discrete
   type encodings, only carries redundant information.  */

static int
ada_is_redundant_range_encoding (struct type *range_type,
				 struct type *encoding_type)
{
  const char *bounds_str;
  int n;
  LONGEST lo, hi;

  gdb_assert (range_type->code () == TYPE_CODE_RANGE);

  if (get_base_type (range_type)->code ()
      != get_base_type (encoding_type)->code ())
    {
      /* The compiler probably used a simple base type to describe
	 the range type instead of the range's actual base type,
	 expecting us to get the real base type from the encoding
	 anyway.  In this situation, the encoding cannot be ignored
	 as redundant.  */
      return 0;
    }

  if (is_dynamic_type (range_type))
    return 0;

  if (encoding_type->name () == NULL)
    return 0;

  bounds_str = strstr (encoding_type->name (), "___XDLU_");
  if (bounds_str == NULL)
    return 0;

  n = 8; /* Skip "___XDLU_".  */
  if (!ada_scan_number (bounds_str, n, &lo, &n))
    return 0;
  if (range_type->bounds ()->low.const_val () != lo)
    return 0;

  n += 2; /* Skip the "__" separator between the two bounds.  */
  if (!ada_scan_number (bounds_str, n, &hi, &n))
    return 0;
  if (range_type->bounds ()->high.const_val () != hi)
    return 0;

  return 1;
}

/* Given the array type ARRAY_TYPE, return nonzero if DESC_TYPE,
   a type following the GNAT encoding for describing array type
   indices, only carries redundant information.  */

static int
ada_is_redundant_index_type_desc (struct type *array_type,
				  struct type *desc_type)
{
  struct type *this_layer = check_typedef (array_type);
  int i;

  for (i = 0; i < desc_type->num_fields (); i++)
    {
      if (!ada_is_redundant_range_encoding (this_layer->index_type (),
					    desc_type->field (i).type ()))
	return 0;
      this_layer = check_typedef (TYPE_TARGET_TYPE (this_layer));
    }

  return 1;
}

/* Assuming that TYPE0 is an array type describing the type of a value
   at ADDR, and that DVAL describes a record containing any
   discriminants used in TYPE0, returns a type for the value that
   contains no dynamic components (that is, no components whose sizes
   are determined by run-time quantities).  Unless IGNORE_TOO_BIG is
   true, gives an error message if the resulting type's size is over
   varsize_limit.  */

static struct type *
to_fixed_array_type (struct type *type0, struct value *dval,
		     int ignore_too_big)
{
  struct type *index_type_desc;
  struct type *result;
  int constrained_packed_array_p;
  static const char *xa_suffix = "___XA";

  type0 = ada_check_typedef (type0);
  if (type0->is_fixed_instance ())
    return type0;

  constrained_packed_array_p = ada_is_constrained_packed_array_type (type0);
  if (constrained_packed_array_p)
    {
      type0 = decode_constrained_packed_array_type (type0);
      if (type0 == nullptr)
	error (_("could not decode constrained packed array type"));
    }

  index_type_desc = ada_find_parallel_type (type0, xa_suffix);

  /* As mentioned in exp_dbug.ads, for non bit-packed arrays an
     encoding suffixed with 'P' may still be generated.  If so,
     it should be used to find the XA type.  */

  if (index_type_desc == NULL)
    {
      const char *type_name = ada_type_name (type0);

      if (type_name != NULL)
	{
	  const int len = strlen (type_name);
	  char *name = (char *) alloca (len + strlen (xa_suffix));

	  if (type_name[len - 1] == 'P')
	    {
	      strcpy (name, type_name);
	      strcpy (name + len - 1, xa_suffix);
	      index_type_desc = ada_find_parallel_type_with_name (type0, name);
	    }
	}
    }

  ada_fixup_array_indexes_type (index_type_desc);
  if (index_type_desc != NULL
      && ada_is_redundant_index_type_desc (type0, index_type_desc))
    {
      /* Ignore this ___XA parallel type, as it does not bring any
	 useful information.  This allows us to avoid creating fixed
	 versions of the array's index types, which would be identical
	 to the original ones.  This, in turn, can also help avoid
	 the creation of fixed versions of the array itself.  */
      index_type_desc = NULL;
    }

  if (index_type_desc == NULL)
    {
      struct type *elt_type0 = ada_check_typedef (TYPE_TARGET_TYPE (type0));

      /* NOTE: elt_type---the fixed version of elt_type0---should never
	 depend on the contents of the array in properly constructed
	 debugging data.  */
      /* Create a fixed version of the array element type.
	 We're not providing the address of an element here,
	 and thus the actual object value cannot be inspected to do
	 the conversion.  This should not be a problem, since arrays of
	 unconstrained objects are not allowed.  In particular, all
	 the elements of an array of a tagged type should all be of
	 the same type specified in the debugging info.  No need to
	 consult the object tag.  */
      struct type *elt_type = ada_to_fixed_type (elt_type0, 0, 0, dval, 1);

      /* Make sure we always create a new array type when dealing with
	 packed array types, since we're going to fix-up the array
	 type length and element bitsize a little further down.  */
      if (elt_type0 == elt_type && !constrained_packed_array_p)
	result = type0;
      else
	result = create_array_type (alloc_type_copy (type0),
				    elt_type, type0->index_type ());
    }
  else
    {
      int i;
      struct type *elt_type0;

      elt_type0 = type0;
      for (i = index_type_desc->num_fields (); i > 0; i -= 1)
	elt_type0 = TYPE_TARGET_TYPE (elt_type0);

      /* NOTE: result---the fixed version of elt_type0---should never
	 depend on the contents of the array in properly constructed
	 debugging data.  */
      /* Create a fixed version of the array element type.
	 We're not providing the address of an element here,
	 and thus the actual object value cannot be inspected to do
	 the conversion.  This should not be a problem, since arrays of
	 unconstrained objects are not allowed.  In particular, all
	 the elements of an array of a tagged type should all be of
	 the same type specified in the debugging info.  No need to
	 consult the object tag.  */
      result =
	ada_to_fixed_type (ada_check_typedef (elt_type0), 0, 0, dval, 1);

      elt_type0 = type0;
      for (i = index_type_desc->num_fields () - 1; i >= 0; i -= 1)
	{
	  struct type *range_type =
	    to_fixed_range_type (index_type_desc->field (i).type (), dval);

	  result = create_array_type (alloc_type_copy (elt_type0),
				      result, range_type);
	  elt_type0 = TYPE_TARGET_TYPE (elt_type0);
	}
    }

  /* We want to preserve the type name.  This can be useful when
     trying to get the type name of a value that has already been
     printed (for instance, if the user did "print VAR; whatis $".  */
  result->set_name (type0->name ());

  if (constrained_packed_array_p)
    {
      /* So far, the resulting type has been created as if the original
	 type was a regular (non-packed) array type.  As a result, the
	 bitsize of the array elements needs to be set again, and the array
	 length needs to be recomputed based on that bitsize.  */
      int len = TYPE_LENGTH (result) / TYPE_LENGTH (TYPE_TARGET_TYPE (result));
      int elt_bitsize = TYPE_FIELD_BITSIZE (type0, 0);

      TYPE_FIELD_BITSIZE (result, 0) = TYPE_FIELD_BITSIZE (type0, 0);
      TYPE_LENGTH (result) = len * elt_bitsize / HOST_CHAR_BIT;
      if (TYPE_LENGTH (result) * HOST_CHAR_BIT < len * elt_bitsize)
	TYPE_LENGTH (result)++;
    }

  result->set_is_fixed_instance (true);
  return result;
}


/* A standard type (containing no dynamically sized components)
   corresponding to TYPE for the value (TYPE, VALADDR, ADDRESS)
   DVAL describes a record containing any discriminants used in TYPE0,
   and may be NULL if there are none, or if the object of type TYPE at
   ADDRESS or in VALADDR contains these discriminants.
   
   If CHECK_TAG is not null, in the case of tagged types, this function
   attempts to locate the object's tag and use it to compute the actual
   type.  However, when ADDRESS is null, we cannot use it to determine the
   location of the tag, and therefore compute the tagged type's actual type.
   So we return the tagged type without consulting the tag.  */
   
static struct type *
ada_to_fixed_type_1 (struct type *type, const gdb_byte *valaddr,
		   CORE_ADDR address, struct value *dval, int check_tag)
{
  type = ada_check_typedef (type);

  /* Only un-fixed types need to be handled here.  */
  if (!HAVE_GNAT_AUX_INFO (type))
    return type;

  switch (type->code ())
    {
    default:
      return type;
    case TYPE_CODE_STRUCT:
      {
	struct type *static_type = to_static_fixed_type (type);
	struct type *fixed_record_type =
	  to_fixed_record_type (type, valaddr, address, NULL);

	/* If STATIC_TYPE is a tagged type and we know the object's address,
	   then we can determine its tag, and compute the object's actual
	   type from there.  Note that we have to use the fixed record
	   type (the parent part of the record may have dynamic fields
	   and the way the location of _tag is expressed may depend on
	   them).  */

	if (check_tag && address != 0 && ada_is_tagged_type (static_type, 0))
	  {
	    struct value *tag =
	      value_tag_from_contents_and_address
	      (fixed_record_type,
	       valaddr,
	       address);
	    struct type *real_type = type_from_tag (tag);
	    struct value *obj =
	      value_from_contents_and_address (fixed_record_type,
					       valaddr,
					       address);
	    fixed_record_type = value_type (obj);
	    if (real_type != NULL)
	      return to_fixed_record_type
		(real_type, NULL,
		 value_address (ada_tag_value_at_base_address (obj)), NULL);
	  }

	/* Check to see if there is a parallel ___XVZ variable.
	   If there is, then it provides the actual size of our type.  */
	else if (ada_type_name (fixed_record_type) != NULL)
	  {
	    const char *name = ada_type_name (fixed_record_type);
	    char *xvz_name
	      = (char *) alloca (strlen (name) + 7 /* "___XVZ\0" */);
	    bool xvz_found = false;
	    LONGEST size;

	    xsnprintf (xvz_name, strlen (name) + 7, "%s___XVZ", name);
	    try
	      {
		xvz_found = get_int_var_value (xvz_name, size);
	      }
	    catch (const gdb_exception_error &except)
	      {
		/* We found the variable, but somehow failed to read
		   its value.  Rethrow the same error, but with a little
		   bit more information, to help the user understand
		   what went wrong (Eg: the variable might have been
		   optimized out).  */
		throw_error (except.error,
			     _("unable to read value of %s (%s)"),
			     xvz_name, except.what ());
	      }

	    if (xvz_found && TYPE_LENGTH (fixed_record_type) != size)
	      {
		fixed_record_type = copy_type (fixed_record_type);
		TYPE_LENGTH (fixed_record_type) = size;

		/* The FIXED_RECORD_TYPE may have be a stub.  We have
		   observed this when the debugging info is STABS, and
		   apparently it is something that is hard to fix.

		   In practice, we don't need the actual type definition
		   at all, because the presence of the XVZ variable allows us
		   to assume that there must be a XVS type as well, which we
		   should be able to use later, when we need the actual type
		   definition.

		   In the meantime, pretend that the "fixed" type we are
		   returning is NOT a stub, because this can cause trouble
		   when using this type to create new types targeting it.
		   Indeed, the associated creation routines often check
		   whether the target type is a stub and will try to replace
		   it, thus using a type with the wrong size.  This, in turn,
		   might cause the new type to have the wrong size too.
		   Consider the case of an array, for instance, where the size
		   of the array is computed from the number of elements in
		   our array multiplied by the size of its element.  */
		fixed_record_type->set_is_stub (false);
	      }
	  }
	return fixed_record_type;
      }
    case TYPE_CODE_ARRAY:
      return to_fixed_array_type (type, dval, 1);
    case TYPE_CODE_UNION:
      if (dval == NULL)
	return type;
      else
	return to_fixed_variant_branch_type (type, valaddr, address, dval);
    }
}

/* The same as ada_to_fixed_type_1, except that it preserves the type
   if it is a TYPE_CODE_TYPEDEF of a type that is already fixed.

   The typedef layer needs be preserved in order to differentiate between
   arrays and array pointers when both types are implemented using the same
   fat pointer.  In the array pointer case, the pointer is encoded as
   a typedef of the pointer type.  For instance, considering:

	  type String_Access is access String;
	  S1 : String_Access := null;

   To the debugger, S1 is defined as a typedef of type String.  But
   to the user, it is a pointer.  So if the user tries to print S1,
   we should not dereference the array, but print the array address
   instead.

   If we didn't preserve the typedef layer, we would lose the fact that
   the type is to be presented as a pointer (needs de-reference before
   being printed).  And we would also use the source-level type name.  */

struct type *
ada_to_fixed_type (struct type *type, const gdb_byte *valaddr,
		   CORE_ADDR address, struct value *dval, int check_tag)

{
  struct type *fixed_type =
    ada_to_fixed_type_1 (type, valaddr, address, dval, check_tag);

  /*  If TYPE is a typedef and its target type is the same as the FIXED_TYPE,
      then preserve the typedef layer.

      Implementation note: We can only check the main-type portion of
      the TYPE and FIXED_TYPE, because eliminating the typedef layer
      from TYPE now returns a type that has the same instance flags
      as TYPE.  For instance, if TYPE is a "typedef const", and its
      target type is a "struct", then the typedef elimination will return
      a "const" version of the target type.  See check_typedef for more
      details about how the typedef layer elimination is done.

      brobecker/2010-11-19: It seems to me that the only case where it is
      useful to preserve the typedef layer is when dealing with fat pointers.
      Perhaps, we could add a check for that and preserve the typedef layer
      only in that situation.  But this seems unnecessary so far, probably
      because we call check_typedef/ada_check_typedef pretty much everywhere.
      */
  if (type->code () == TYPE_CODE_TYPEDEF
      && (TYPE_MAIN_TYPE (ada_typedef_target_type (type))
	  == TYPE_MAIN_TYPE (fixed_type)))
    return type;

  return fixed_type;
}

/* A standard (static-sized) type corresponding as well as possible to
   TYPE0, but based on no runtime data.  */

static struct type *
to_static_fixed_type (struct type *type0)
{
  struct type *type;

  if (type0 == NULL)
    return NULL;

  if (type0->is_fixed_instance ())
    return type0;

  type0 = ada_check_typedef (type0);

  switch (type0->code ())
    {
    default:
      return type0;
    case TYPE_CODE_STRUCT:
      type = dynamic_template_type (type0);
      if (type != NULL)
	return template_to_static_fixed_type (type);
      else
	return template_to_static_fixed_type (type0);
    case TYPE_CODE_UNION:
      type = ada_find_parallel_type (type0, "___XVU");
      if (type != NULL)
	return template_to_static_fixed_type (type);
      else
	return template_to_static_fixed_type (type0);
    }
}

/* A static approximation of TYPE with all type wrappers removed.  */

static struct type *
static_unwrap_type (struct type *type)
{
  if (ada_is_aligner_type (type))
    {
      struct type *type1 = ada_check_typedef (type)->field (0).type ();
      if (ada_type_name (type1) == NULL)
	type1->set_name (ada_type_name (type));

      return static_unwrap_type (type1);
    }
  else
    {
      struct type *raw_real_type = ada_get_base_type (type);

      if (raw_real_type == type)
	return type;
      else
	return to_static_fixed_type (raw_real_type);
    }
}

/* In some cases, incomplete and private types require
   cross-references that are not resolved as records (for example,
      type Foo;
      type FooP is access Foo;
      V: FooP;
      type Foo is array ...;
   ).  In these cases, since there is no mechanism for producing
   cross-references to such types, we instead substitute for FooP a
   stub enumeration type that is nowhere resolved, and whose tag is
   the name of the actual type.  Call these types "non-record stubs".  */

/* A type equivalent to TYPE that is not a non-record stub, if one
   exists, otherwise TYPE.  */

struct type *
ada_check_typedef (struct type *type)
{
  if (type == NULL)
    return NULL;

  /* If our type is an access to an unconstrained array, which is encoded
     as a TYPE_CODE_TYPEDEF of a fat pointer, then we're done.
     We don't want to strip the TYPE_CODE_TYPDEF layer, because this is
     what allows us to distinguish between fat pointers that represent
     array types, and fat pointers that represent array access types
     (in both cases, the compiler implements them as fat pointers).  */
  if (ada_is_access_to_unconstrained_array (type))
    return type;

  type = check_typedef (type);
  if (type == NULL || type->code () != TYPE_CODE_ENUM
      || !type->is_stub ()
      || type->name () == NULL)
    return type;
  else
    {
      const char *name = type->name ();
      struct type *type1 = ada_find_any_type (name);

      if (type1 == NULL)
	return type;

      /* TYPE1 might itself be a TYPE_CODE_TYPEDEF (this can happen with
	 stubs pointing to arrays, as we don't create symbols for array
	 types, only for the typedef-to-array types).  If that's the case,
	 strip the typedef layer.  */
      if (type1->code () == TYPE_CODE_TYPEDEF)
	type1 = ada_check_typedef (type1);

      return type1;
    }
}

/* A value representing the data at VALADDR/ADDRESS as described by
   type TYPE0, but with a standard (static-sized) type that correctly
   describes it.  If VAL0 is not NULL and TYPE0 already is a standard
   type, then return VAL0 [this feature is simply to avoid redundant
   creation of struct values].  */

static struct value *
ada_to_fixed_value_create (struct type *type0, CORE_ADDR address,
			   struct value *val0)
{
  struct type *type = ada_to_fixed_type (type0, 0, address, NULL, 1);

  if (type == type0 && val0 != NULL)
    return val0;

  if (VALUE_LVAL (val0) != lval_memory)
    {
      /* Our value does not live in memory; it could be a convenience
	 variable, for instance.  Create a not_lval value using val0's
	 contents.  */
      return value_from_contents (type, value_contents (val0).data ());
    }

  return value_from_contents_and_address (type, 0, address);
}

/* A value representing VAL, but with a standard (static-sized) type
   that correctly describes it.  Does not necessarily create a new
   value.  */

struct value *
ada_to_fixed_value (struct value *val)
{
  val = unwrap_value (val);
  val = ada_to_fixed_value_create (value_type (val), value_address (val), val);
  return val;
}


/* Attributes */

/* Table mapping attribute numbers to names.
   NOTE: Keep up to date with enum ada_attribute definition in ada-lang.h.  */

static const char * const attribute_names[] = {
  "<?>",

  "first",
  "last",
  "length",
  "image",
  "max",
  "min",
  "modulus",
  "pos",
  "size",
  "tag",
  "val",
  0
};

static const char *
ada_attribute_name (enum exp_opcode n)
{
  if (n >= OP_ATR_FIRST && n <= (int) OP_ATR_VAL)
    return attribute_names[n - OP_ATR_FIRST + 1];
  else
    return attribute_names[0];
}

/* Evaluate the 'POS attribute applied to ARG.  */

static LONGEST
pos_atr (struct value *arg)
{
  struct value *val = coerce_ref (arg);
  struct type *type = value_type (val);

  if (!discrete_type_p (type))
    error (_("'POS only defined on discrete types"));

  gdb::optional<LONGEST> result = discrete_position (type, value_as_long (val));
  if (!result.has_value ())
    error (_("enumeration value is invalid: can't find 'POS"));

  return *result;
}

struct value *
ada_pos_atr (struct type *expect_type,
	     struct expression *exp,
	     enum noside noside, enum exp_opcode op,
	     struct value *arg)
{
  struct type *type = builtin_type (exp->gdbarch)->builtin_int;
  if (noside == EVAL_AVOID_SIDE_EFFECTS)
    return value_zero (type, not_lval);
  return value_from_longest (type, pos_atr (arg));
}

/* Evaluate the TYPE'VAL attribute applied to ARG.  */

static struct value *
val_atr (struct type *type, LONGEST val)
{
  gdb_assert (discrete_type_p (type));
  if (type->code () == TYPE_CODE_RANGE)
    type = TYPE_TARGET_TYPE (type);
  if (type->code () == TYPE_CODE_ENUM)
    {
      if (val < 0 || val >= type->num_fields ())
	error (_("argument to 'VAL out of range"));
      val = type->field (val).loc_enumval ();
    }
  return value_from_longest (type, val);
}

struct value *
ada_val_atr (enum noside noside, struct type *type, struct value *arg)
{
  if (noside == EVAL_AVOID_SIDE_EFFECTS)
    return value_zero (type, not_lval);

  if (!discrete_type_p (type))
    error (_("'VAL only defined on discrete types"));
  if (!integer_type_p (value_type (arg)))
    error (_("'VAL requires integral argument"));

  return val_atr (type, value_as_long (arg));
}


				/* Evaluation */

/* True if TYPE appears to be an Ada character type.
   [At the moment, this is true only for Character and Wide_Character;
   It is a heuristic test that could stand improvement].  */

bool
ada_is_character_type (struct type *type)
{
  const char *name;

  /* If the type code says it's a character, then assume it really is,
     and don't check any further.  */
  if (type->code () == TYPE_CODE_CHAR)
    return true;
  
  /* Otherwise, assume it's a character type iff it is a discrete type
     with a known character type name.  */
  name = ada_type_name (type);
  return (name != NULL
	  && (type->code () == TYPE_CODE_INT
	      || type->code () == TYPE_CODE_RANGE)
	  && (strcmp (name, "character") == 0
	      || strcmp (name, "wide_character") == 0
	      || strcmp (name, "wide_wide_character") == 0
	      || strcmp (name, "unsigned char") == 0));
}

/* True if TYPE appears to be an Ada string type.  */

bool
ada_is_string_type (struct type *type)
{
  type = ada_check_typedef (type);
  if (type != NULL
      && type->code () != TYPE_CODE_PTR
      && (ada_is_simple_array_type (type)
	  || ada_is_array_descriptor_type (type))
      && ada_array_arity (type) == 1)
    {
      struct type *elttype = ada_array_element_type (type, 1);

      return ada_is_character_type (elttype);
    }
  else
    return false;
}

/* The compiler sometimes provides a parallel XVS type for a given
   PAD type.  Normally, it is safe to follow the PAD type directly,
   but older versions of the compiler have a bug that causes the offset
   of its "F" field to be wrong.  Following that field in that case
   would lead to incorrect results, but this can be worked around
   by ignoring the PAD type and using the associated XVS type instead.

   Set to True if the debugger should trust the contents of PAD types.
   Otherwise, ignore the PAD type if there is a parallel XVS type.  */
static bool trust_pad_over_xvs = true;

/* True if TYPE is a struct type introduced by the compiler to force the
   alignment of a value.  Such types have a single field with a
   distinctive name.  */

int
ada_is_aligner_type (struct type *type)
{
  type = ada_check_typedef (type);

  if (!trust_pad_over_xvs && ada_find_parallel_type (type, "___XVS") != NULL)
    return 0;

  return (type->code () == TYPE_CODE_STRUCT
	  && type->num_fields () == 1
	  && strcmp (type->field (0).name (), "F") == 0);
}

/* If there is an ___XVS-convention type parallel to SUBTYPE, return
   the parallel type.  */

struct type *
ada_get_base_type (struct type *raw_type)
{
  struct type *real_type_namer;
  struct type *raw_real_type;

  if (raw_type == NULL || raw_type->code () != TYPE_CODE_STRUCT)
    return raw_type;

  if (ada_is_aligner_type (raw_type))
    /* The encoding specifies that we should always use the aligner type.
       So, even if this aligner type has an associated XVS type, we should
       simply ignore it.

       According to the compiler gurus, an XVS type parallel to an aligner
       type may exist because of a stabs limitation.  In stabs, aligner
       types are empty because the field has a variable-sized type, and
       thus cannot actually be used as an aligner type.  As a result,
       we need the associated parallel XVS type to decode the type.
       Since the policy in the compiler is to not change the internal
       representation based on the debugging info format, we sometimes
       end up having a redundant XVS type parallel to the aligner type.  */
    return raw_type;

  real_type_namer = ada_find_parallel_type (raw_type, "___XVS");
  if (real_type_namer == NULL
      || real_type_namer->code () != TYPE_CODE_STRUCT
      || real_type_namer->num_fields () != 1)
    return raw_type;

  if (real_type_namer->field (0).type ()->code () != TYPE_CODE_REF)
    {
      /* This is an older encoding form where the base type needs to be
	 looked up by name.  We prefer the newer encoding because it is
	 more efficient.  */
      raw_real_type = ada_find_any_type (real_type_namer->field (0).name ());
      if (raw_real_type == NULL)
	return raw_type;
      else
	return raw_real_type;
    }

  /* The field in our XVS type is a reference to the base type.  */
  return TYPE_TARGET_TYPE (real_type_namer->field (0).type ());
}

/* The type of value designated by TYPE, with all aligners removed.  */

struct type *
ada_aligned_type (struct type *type)
{
  if (ada_is_aligner_type (type))
    return ada_aligned_type (type->field (0).type ());
  else
    return ada_get_base_type (type);
}


/* The address of the aligned value in an object at address VALADDR
   having type TYPE.  Assumes ada_is_aligner_type (TYPE).  */

const gdb_byte *
ada_aligned_value_addr (struct type *type, const gdb_byte *valaddr)
{
  if (ada_is_aligner_type (type))
    return ada_aligned_value_addr
      (type->field (0).type (),
       valaddr + type->field (0).loc_bitpos () / TARGET_CHAR_BIT);
  else
    return valaddr;
}



/* The printed representation of an enumeration literal with encoded
   name NAME.  The value is good to the next call of ada_enum_name.  */
const char *
ada_enum_name (const char *name)
{
  static std::string storage;
  const char *tmp;

  /* First, unqualify the enumeration name:
     1. Search for the last '.' character.  If we find one, then skip
     all the preceding characters, the unqualified name starts
     right after that dot.
     2. Otherwise, we may be debugging on a target where the compiler
     translates dots into "__".  Search forward for double underscores,
     but stop searching when we hit an overloading suffix, which is
     of the form "__" followed by digits.  */

  tmp = strrchr (name, '.');
  if (tmp != NULL)
    name = tmp + 1;
  else
    {
      while ((tmp = strstr (name, "__")) != NULL)
	{
	  if (isdigit (tmp[2]))
	    break;
	  else
	    name = tmp + 2;
	}
    }

  if (name[0] == 'Q')
    {
      int v;

      if (name[1] == 'U' || name[1] == 'W')
	{
	  int offset = 2;
	  if (name[1] == 'W' && name[2] == 'W')
	    {
	      /* Also handle the QWW case.  */
	      ++offset;
	    }
	  if (sscanf (name + offset, "%x", &v) != 1)
	    return name;
	}
      else if (((name[1] >= '0' && name[1] <= '9')
		|| (name[1] >= 'a' && name[1] <= 'z'))
	       && name[2] == '\0')
	{
	  storage = string_printf ("'%c'", name[1]);
	  return storage.c_str ();
	}
      else
	return name;

      if (isascii (v) && isprint (v))
	storage = string_printf ("'%c'", v);
      else if (name[1] == 'U')
	storage = string_printf ("'[\"%02x\"]'", v);
      else if (name[2] != 'W')
	storage = string_printf ("'[\"%04x\"]'", v);
      else
	storage = string_printf ("'[\"%06x\"]'", v);

      return storage.c_str ();
    }
  else
    {
      tmp = strstr (name, "__");
      if (tmp == NULL)
	tmp = strstr (name, "$");
      if (tmp != NULL)
	{
	  storage = std::string (name, tmp - name);
	  return storage.c_str ();
	}

      return name;
    }
}

/* If VAL is wrapped in an aligner or subtype wrapper, return the
   value it wraps.  */

static struct value *
unwrap_value (struct value *val)
{
  struct type *type = ada_check_typedef (value_type (val));

  if (ada_is_aligner_type (type))
    {
      struct value *v = ada_value_struct_elt (val, "F", 0);
      struct type *val_type = ada_check_typedef (value_type (v));

      if (ada_type_name (val_type) == NULL)
	val_type->set_name (ada_type_name (type));

      return unwrap_value (v);
    }
  else
    {
      struct type *raw_real_type =
	ada_check_typedef (ada_get_base_type (type));

      /* If there is no parallel XVS or XVE type, then the value is
	 already unwrapped.  Return it without further modification.  */
      if ((type == raw_real_type)
	  && ada_find_parallel_type (type, "___XVE") == NULL)
	return val;

      return
	coerce_unspec_val_to_type
	(val, ada_to_fixed_type (raw_real_type, 0,
				 value_address (val),
				 NULL, 1));
    }
}

/* Given two array types T1 and T2, return nonzero iff both arrays
   contain the same number of elements.  */

static int
ada_same_array_size_p (struct type *t1, struct type *t2)
{
  LONGEST lo1, hi1, lo2, hi2;

  /* Get the array bounds in order to verify that the size of
     the two arrays match.  */
  if (!get_array_bounds (t1, &lo1, &hi1)
      || !get_array_bounds (t2, &lo2, &hi2))
    error (_("unable to determine array bounds"));

  /* To make things easier for size comparison, normalize a bit
     the case of empty arrays by making sure that the difference
     between upper bound and lower bound is always -1.  */
  if (lo1 > hi1)
    hi1 = lo1 - 1;
  if (lo2 > hi2)
    hi2 = lo2 - 1;

  return (hi1 - lo1 == hi2 - lo2);
}

/* Assuming that VAL is an array of integrals, and TYPE represents
   an array with the same number of elements, but with wider integral
   elements, return an array "casted" to TYPE.  In practice, this
   means that the returned array is built by casting each element
   of the original array into TYPE's (wider) element type.  */

static struct value *
ada_promote_array_of_integrals (struct type *type, struct value *val)
{
  struct type *elt_type = TYPE_TARGET_TYPE (type);
  LONGEST lo, hi;
  LONGEST i;

  /* Verify that both val and type are arrays of scalars, and
     that the size of val's elements is smaller than the size
     of type's element.  */
  gdb_assert (type->code () == TYPE_CODE_ARRAY);
  gdb_assert (is_integral_type (TYPE_TARGET_TYPE (type)));
  gdb_assert (value_type (val)->code () == TYPE_CODE_ARRAY);
  gdb_assert (is_integral_type (TYPE_TARGET_TYPE (value_type (val))));
  gdb_assert (TYPE_LENGTH (TYPE_TARGET_TYPE (type))
	      > TYPE_LENGTH (TYPE_TARGET_TYPE (value_type (val))));

  if (!get_array_bounds (type, &lo, &hi))
    error (_("unable to determine array bounds"));

  value *res = allocate_value (type);
  gdb::array_view<gdb_byte> res_contents = value_contents_writeable (res);

  /* Promote each array element.  */
  for (i = 0; i < hi - lo + 1; i++)
    {
      struct value *elt = value_cast (elt_type, value_subscript (val, lo + i));
      int elt_len = TYPE_LENGTH (elt_type);

      copy (value_contents_all (elt), res_contents.slice (elt_len * i, elt_len));
    }

  return res;
}

/* Coerce VAL as necessary for assignment to an lval of type TYPE, and
   return the converted value.  */

static struct value *
coerce_for_assign (struct type *type, struct value *val)
{
  struct type *type2 = value_type (val);

  if (type == type2)
    return val;

  type2 = ada_check_typedef (type2);
  type = ada_check_typedef (type);

  if (type2->code () == TYPE_CODE_PTR
      && type->code () == TYPE_CODE_ARRAY)
    {
      val = ada_value_ind (val);
      type2 = value_type (val);
    }

  if (type2->code () == TYPE_CODE_ARRAY
      && type->code () == TYPE_CODE_ARRAY)
    {
      if (!ada_same_array_size_p (type, type2))
	error (_("cannot assign arrays of different length"));

      if (is_integral_type (TYPE_TARGET_TYPE (type))
	  && is_integral_type (TYPE_TARGET_TYPE (type2))
	  && TYPE_LENGTH (TYPE_TARGET_TYPE (type2))
	       < TYPE_LENGTH (TYPE_TARGET_TYPE (type)))
	{
	  /* Allow implicit promotion of the array elements to
	     a wider type.  */
	  return ada_promote_array_of_integrals (type, val);
	}

      if (TYPE_LENGTH (TYPE_TARGET_TYPE (type2))
	  != TYPE_LENGTH (TYPE_TARGET_TYPE (type)))
	error (_("Incompatible types in assignment"));
      deprecated_set_value_type (val, type);
    }
  return val;
}

static struct value *
ada_value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
{
  struct value *val;
  struct type *type1, *type2;
  LONGEST v, v1, v2;

  arg1 = coerce_ref (arg1);
  arg2 = coerce_ref (arg2);
  type1 = get_base_type (ada_check_typedef (value_type (arg1)));
  type2 = get_base_type (ada_check_typedef (value_type (arg2)));

  if (type1->code () != TYPE_CODE_INT
      || type2->code () != TYPE_CODE_INT)
    return value_binop (arg1, arg2, op);

  switch (op)
    {
    case BINOP_MOD:
    case BINOP_DIV:
    case BINOP_REM:
      break;
    default:
      return value_binop (arg1, arg2, op);
    }

  v2 = value_as_long (arg2);
  if (v2 == 0)
    {
      const char *name;
      if (op == BINOP_MOD)
	name = "mod";
      else if (op == BINOP_DIV)
	name = "/";
      else
	{
	  gdb_assert (op == BINOP_REM);
	  name = "rem";
	}

      error (_("second operand of %s must not be zero."), name);
    }

  if (type1->is_unsigned () || op == BINOP_MOD)
    return value_binop (arg1, arg2, op);

  v1 = value_as_long (arg1);
  switch (op)
    {
    case BINOP_DIV:
      v = v1 / v2;
      if (!TRUNCATION_TOWARDS_ZERO && v1 * (v1 % v2) < 0)
	v += v > 0 ? -1 : 1;
      break;
    case BINOP_REM:
      v = v1 % v2;
      if (v * v1 < 0)
	v -= v2;
      break;
    default:
      /* Should not reach this point.  */
      v = 0;
    }

  val = allocate_value (type1);
  store_unsigned_integer (value_contents_raw (val).data (),
			  TYPE_LENGTH (value_type (val)),
			  type_byte_order (type1), v);
  return val;
}

static int
ada_value_equal (struct value *arg1, struct value *arg2)
{
  if (ada_is_direct_array_type (value_type (arg1))
      || ada_is_direct_array_type (value_type (arg2)))
    {
      struct type *arg1_type, *arg2_type;

      /* Automatically dereference any array reference before
	 we attempt to perform the comparison.  */
      arg1 = ada_coerce_ref (arg1);
      arg2 = ada_coerce_ref (arg2);

      arg1 = ada_coerce_to_simple_array (arg1);
      arg2 = ada_coerce_to_simple_array (arg2);

      arg1_type = ada_check_typedef (value_type (arg1));
      arg2_type = ada_check_typedef (value_type (arg2));

      if (arg1_type->code () != TYPE_CODE_ARRAY
	  || arg2_type->code () != TYPE_CODE_ARRAY)
	error (_("Attempt to compare array with non-array"));
      /* FIXME: The following works only for types whose
	 representations use all bits (no padding or undefined bits)
	 and do not have user-defined equality.  */
      return (TYPE_LENGTH (arg1_type) == TYPE_LENGTH (arg2_type)
	      && memcmp (value_contents (arg1).data (),
			 value_contents (arg2).data (),
			 TYPE_LENGTH (arg1_type)) == 0);
    }
  return value_equal (arg1, arg2);
}

namespace expr
{

bool
check_objfile (const std::unique_ptr<ada_component> &comp,
	       struct objfile *objfile)
{
  return comp->uses_objfile (objfile);
}

/* Assign the result of evaluating ARG starting at *POS to the INDEXth
   component of LHS (a simple array or a record).  Does not modify the
   inferior's memory, nor does it modify LHS (unless LHS ==
   CONTAINER).  */

static void
assign_component (struct value *container, struct value *lhs, LONGEST index,
		  struct expression *exp, operation_up &arg)
{
  scoped_value_mark mark;

  struct value *elt;
  struct type *lhs_type = check_typedef (value_type (lhs));

  if (lhs_type->code () == TYPE_CODE_ARRAY)
    {
      struct type *index_type = builtin_type (exp->gdbarch)->builtin_int;
      struct value *index_val = value_from_longest (index_type, index);

      elt = unwrap_value (ada_value_subscript (lhs, 1, &index_val));
    }
  else
    {
      elt = ada_index_struct_field (index, lhs, 0, value_type (lhs));
      elt = ada_to_fixed_value (elt);
    }

  ada_aggregate_operation *ag_op
    = dynamic_cast<ada_aggregate_operation *> (arg.get ());
  if (ag_op != nullptr)
    ag_op->assign_aggregate (container, elt, exp);
  else
    value_assign_to_component (container, elt,
			       arg->evaluate (nullptr, exp,
					      EVAL_NORMAL));
}

bool
ada_aggregate_component::uses_objfile (struct objfile *objfile)
{
  for (const auto &item : m_components)
    if (item->uses_objfile (objfile))
      return true;
  return false;
}

void
ada_aggregate_component::dump (ui_file *stream, int depth)
{
  gdb_printf (stream, _("%*sAggregate\n"), depth, "");
  for (const auto &item : m_components)
    item->dump (stream, depth + 1);
}

void
ada_aggregate_component::assign (struct value *container,
				 struct value *lhs, struct expression *exp,
				 std::vector<LONGEST> &indices,
				 LONGEST low, LONGEST high)
{
  for (auto &item : m_components)
    item->assign (container, lhs, exp, indices, low, high);
}

/* See ada-exp.h.  */

value *
ada_aggregate_operation::assign_aggregate (struct value *container,
					   struct value *lhs,
					   struct expression *exp)
{
  struct type *lhs_type;
  LONGEST low_index, high_index;

  container = ada_coerce_ref (container);
  if (ada_is_direct_array_type (value_type (container)))
    container = ada_coerce_to_simple_array (container);
  lhs = ada_coerce_ref (lhs);
  if (!deprecated_value_modifiable (lhs))
    error (_("Left operand of assignment is not a modifiable lvalue."));

  lhs_type = check_typedef (value_type (lhs));
  if (ada_is_direct_array_type (lhs_type))
    {
      lhs = ada_coerce_to_simple_array (lhs);
      lhs_type = check_typedef (value_type (lhs));
      low_index = lhs_type->bounds ()->low.const_val ();
      high_index = lhs_type->bounds ()->high.const_val ();
    }
  else if (lhs_type->code () == TYPE_CODE_STRUCT)
    {
      low_index = 0;
      high_index = num_visible_fields (lhs_type) - 1;
    }
  else
    error (_("Left-hand side must be array or record."));

  std::vector<LONGEST> indices (4);
  indices[0] = indices[1] = low_index - 1;
  indices[2] = indices[3] = high_index + 1;

  std::get<0> (m_storage)->assign (container, lhs, exp, indices,
				   low_index, high_index);

  return container;
}

bool
ada_positional_component::uses_objfile (struct objfile *objfile)
{
  return m_op->uses_objfile (objfile);
}

void
ada_positional_component::dump (ui_file *stream, int depth)
{
  gdb_printf (stream, _("%*sPositional, index = %d\n"),
	      depth, "", m_index);
  m_op->dump (stream, depth + 1);
}

/* Assign into the component of LHS indexed by the OP_POSITIONAL
   construct, given that the positions are relative to lower bound
   LOW, where HIGH is the upper bound.  Record the position in
   INDICES.  CONTAINER is as for assign_aggregate.  */
void
ada_positional_component::assign (struct value *container,
				  struct value *lhs, struct expression *exp,
				  std::vector<LONGEST> &indices,
				  LONGEST low, LONGEST high)
{
  LONGEST ind = m_index + low;

  if (ind - 1 == high)
    warning (_("Extra components in aggregate ignored."));
  if (ind <= high)
    {
      add_component_interval (ind, ind, indices);
      assign_component (container, lhs, ind, exp, m_op);
    }
}

bool
ada_discrete_range_association::uses_objfile (struct objfile *objfile)
{
  return m_low->uses_objfile (objfile) || m_high->uses_objfile (objfile);
}

void
ada_discrete_range_association::dump (ui_file *stream, int depth)
{
  gdb_printf (stream, _("%*sDiscrete range:\n"), depth, "");
  m_low->dump (stream, depth + 1);
  m_high->dump (stream, depth + 1);
}

void
ada_discrete_range_association::assign (struct value *container,
					struct value *lhs,
					struct expression *exp,
					std::vector<LONGEST> &indices,
					LONGEST low, LONGEST high,
					operation_up &op)
{
  LONGEST lower = value_as_long (m_low->evaluate (nullptr, exp, EVAL_NORMAL));
  LONGEST upper = value_as_long (m_high->evaluate (nullptr, exp, EVAL_NORMAL));

  if (lower <= upper && (lower < low || upper > high))
    error (_("Index in component association out of bounds."));

  add_component_interval (lower, upper, indices);
  while (lower <= upper)
    {
      assign_component (container, lhs, lower, exp, op);
      lower += 1;
    }
}

bool
ada_name_association::uses_objfile (struct objfile *objfile)
{
  return m_val->uses_objfile (objfile);
}

void
ada_name_association::dump (ui_file *stream, int depth)
{
  gdb_printf (stream, _("%*sName:\n"), depth, "");
  m_val->dump (stream, depth + 1);
}

void
ada_name_association::assign (struct value *container,
			      struct value *lhs,
			      struct expression *exp,
			      std::vector<LONGEST> &indices,
			      LONGEST low, LONGEST high,
			      operation_up &op)
{
  int index;

  if (ada_is_direct_array_type (value_type (lhs)))
    index = longest_to_int (value_as_long (m_val->evaluate (nullptr, exp,
							    EVAL_NORMAL)));
  else
    {
      ada_string_operation *strop
	= dynamic_cast<ada_string_operation *> (m_val.get ());

      const char *name;
      if (strop != nullptr)
	name = strop->get_name ();
      else
	{
	  ada_var_value_operation *vvo
	    = dynamic_cast<ada_var_value_operation *> (m_val.get ());
	  if (vvo != nullptr)
	    error (_("Invalid record component association."));
	  name = vvo->get_symbol ()->natural_name ();
	}

      index = 0;
      if (! find_struct_field (name, value_type (lhs), 0,
			       NULL, NULL, NULL, NULL, &index))
	error (_("Unknown component name: %s."), name);
    }

  add_component_interval (index, index, indices);
  assign_component (container, lhs, index, exp, op);
}

bool
ada_choices_component::uses_objfile (struct objfile *objfile)
{
  if (m_op->uses_objfile (objfile))
    return true;
  for (const auto &item : m_assocs)
    if (item->uses_objfile (objfile))
      return true;
  return false;
}

void
ada_choices_component::dump (ui_file *stream, int depth)
{
  gdb_printf (stream, _("%*sChoices:\n"), depth, "");
  m_op->dump (stream, depth + 1);
  for (const auto &item : m_assocs)
    item->dump (stream, depth + 1);
}

/* Assign into the components of LHS indexed by the OP_CHOICES
   construct at *POS, updating *POS past the construct, given that
   the allowable indices are LOW..HIGH.  Record the indices assigned
   to in INDICES.  CONTAINER is as for assign_aggregate.  */
void
ada_choices_component::assign (struct value *container,
			       struct value *lhs, struct expression *exp,
			       std::vector<LONGEST> &indices,
			       LONGEST low, LONGEST high)
{
  for (auto &item : m_assocs)
    item->assign (container, lhs, exp, indices, low, high, m_op);
}

bool
ada_others_component::uses_objfile (struct objfile *objfile)
{
  return m_op->uses_objfile (objfile);
}

void
ada_others_component::dump (ui_file *stream, int depth)
{
  gdb_printf (stream, _("%*sOthers:\n"), depth, "");
  m_op->dump (stream, depth + 1);
}

/* Assign the value of the expression in the OP_OTHERS construct in
   EXP at *POS into the components of LHS indexed from LOW .. HIGH that
   have not been previously assigned.  The index intervals already assigned
   are in INDICES.  CONTAINER is as for assign_aggregate.  */
void
ada_others_component::assign (struct value *container,
			      struct value *lhs, struct expression *exp,
			      std::vector<LONGEST> &indices,
			      LONGEST low, LONGEST high)
{
  int num_indices = indices.size ();
  for (int i = 0; i < num_indices - 2; i += 2)
    {
      for (LONGEST ind = indices[i + 1] + 1; ind < indices[i + 2]; ind += 1)
	assign_component (container, lhs, ind, exp, m_op);
    }
}

struct value *
ada_assign_operation::evaluate (struct type *expect_type,
				struct expression *exp,
				enum noside noside)
{
  value *arg1 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);

  ada_aggregate_operation *ag_op
    = dynamic_cast<ada_aggregate_operation *> (std::get<1> (m_storage).get ());
  if (ag_op != nullptr)
    {
      if (noside != EVAL_NORMAL)
	return arg1;

      arg1 = ag_op->assign_aggregate (arg1, arg1, exp);
      return ada_value_assign (arg1, arg1);
    }
  /* Force the evaluation of the rhs ARG2 to the type of the lhs ARG1,
     except if the lhs of our assignment is a convenience variable.
     In the case of assigning to a convenience variable, the lhs
     should be exactly the result of the evaluation of the rhs.  */
  struct type *type = value_type (arg1);
  if (VALUE_LVAL (arg1) == lval_internalvar)
    type = NULL;
  value *arg2 = std::get<1> (m_storage)->evaluate (type, exp, noside);
  if (noside == EVAL_AVOID_SIDE_EFFECTS)
    return arg1;
  if (VALUE_LVAL (arg1) == lval_internalvar)
    {
      /* Nothing.  */
    }
  else
    arg2 = coerce_for_assign (value_type (arg1), arg2);
  return ada_value_assign (arg1, arg2);
}

} /* namespace expr */

/* Add the interval [LOW .. HIGH] to the sorted set of intervals
   [ INDICES[0] .. INDICES[1] ],...  The resulting intervals do not
   overlap.  */
static void
add_component_interval (LONGEST low, LONGEST high, 
			std::vector<LONGEST> &indices)
{
  int i, j;

  int size = indices.size ();
  for (i = 0; i < size; i += 2) {
    if (high >= indices[i] && low <= indices[i + 1])
      {
	int kh;

	for (kh = i + 2; kh < size; kh += 2)
	  if (high < indices[kh])
	    break;
	if (low < indices[i])
	  indices[i] = low;
	indices[i + 1] = indices[kh - 1];
	if (high > indices[i + 1])
	  indices[i + 1] = high;
	memcpy (indices.data () + i + 2, indices.data () + kh, size - kh);
	indices.resize (kh - i - 2);
	return;
      }
    else if (high < indices[i])
      break;
  }
	
  indices.resize (indices.size () + 2);
  for (j = indices.size () - 1; j >= i + 2; j -= 1)
    indices[j] = indices[j - 2];
  indices[i] = low;
  indices[i + 1] = high;
}

/* Perform and Ada cast of ARG2 to type TYPE if the type of ARG2
   is different.  */

static struct value *
ada_value_cast (struct type *type, struct value *arg2)
{
  if (type == ada_check_typedef (value_type (arg2)))
    return arg2;

  return value_cast (type, arg2);
}

/*  Evaluating Ada expressions, and printing their result.
    ------------------------------------------------------

    1. Introduction:
    ----------------

    We usually evaluate an Ada expression in order to print its value.
    We also evaluate an expression in order to print its type, which
    happens during the EVAL_AVOID_SIDE_EFFECTS phase of the evaluation,
    but we'll focus mostly on the EVAL_NORMAL phase.  In practice, the
    EVAL_AVOID_SIDE_EFFECTS phase allows us to simplify certain aspects of
    the evaluation compared to the EVAL_NORMAL, but is otherwise very
    similar.

    Evaluating expressions is a little more complicated for Ada entities
    than it is for entities in languages such as C.  The main reason for
    this is that Ada provides types whose definition might be dynamic.
    One example of such types is variant records.  Or another example
    would be an array whose bounds can only be known at run time.

    The following description is a general guide as to what should be
    done (and what should NOT be done) in order to evaluate an expression
    involving such types, and when.  This does not cover how the semantic
    information is encoded by GNAT as this is covered separatly.  For the
    document used as the reference for the GNAT encoding, see exp_dbug.ads
    in the GNAT sources.

    Ideally, we should embed each part of this description next to its
    associated code.  Unfortunately, the amount of code is so vast right
    now that it's hard to see whether the code handling a particular
    situation might be duplicated or not.  One day, when the code is
    cleaned up, this guide might become redundant with the comments
    inserted in the code, and we might want to remove it.

    2. ``Fixing'' an Entity, the Simple Case:
    -----------------------------------------

    When evaluating Ada expressions, the tricky issue is that they may
    reference entities whose type contents and size are not statically
    known.  Consider for instance a variant record:

       type Rec (Empty : Boolean := True) is record
	  case Empty is
	     when True => null;
	     when False => Value : Integer;
	  end case;
       end record;
       Yes : Rec := (Empty => False, Value => 1);
       No  : Rec := (empty => True);

    The size and contents of that record depends on the value of the
    descriminant (Rec.Empty).  At this point, neither the debugging
    information nor the associated type structure in GDB are able to
    express such dynamic types.  So what the debugger does is to create
    "fixed" versions of the type that applies to the specific object.
    We also informally refer to this operation as "fixing" an object,
    which means creating its associated fixed type.

    Example: when printing the value of variable "Yes" above, its fixed
    type would look like this:

       type Rec is record
	  Empty : Boolean;
	  Value : Integer;
       end record;

    On the other hand, if we printed the value of "No", its fixed type
    would become:

       type Rec is record
	  Empty : Boolean;
       end record;

    Things become a little more complicated when trying to fix an entity
    with a dynamic type that directly contains another dynamic type,
    such as an array of variant records, for instance.  There are
    two possible cases: Arrays, and records.

    3. ``Fixing'' Arrays:
    ---------------------

    The type structure in GDB describes an array in terms of its bounds,
    and the type of its elements.  By design, all elements in the array
    have the same type and we cannot represent an array of variant elements
    using the current type structure in GDB.  When fixing an array,
    we cannot fix the array element, as we would potentially need one
    fixed type per element of the array.  As a result, the best we can do
    when fixing an array is to produce an array whose bounds and size
    are correct (allowing us to read it from memory), but without having
    touched its element type.  Fixing each element will be done later,
    when (if) necessary.

    Arrays are a little simpler to handle than records, because the same
    amount of memory is allocated for each element of the array, even if
    the amount of space actually used by each element differs from element
    to element.  Consider for instance the following array of type Rec:

       type Rec_Array is array (1 .. 2) of Rec;

    The actual amount of memory occupied by each element might be different
    from element to element, depending on the value of their discriminant.
    But the amount of space reserved for each element in the array remains
    fixed regardless.  So we simply need to compute that size using
    the debugging information available, from which we can then determine
    the array size (we multiply the number of elements of the array by
    the size of each element).

    The simplest case is when we have an array of a constrained element
    type. For instance, consider the following type declarations:

	type Bounded_String (Max_Size : Integer) is
	   Length : Integer;
	   Buffer : String (1 .. Max_Size);
	end record;
	type Bounded_String_Array is array (1 ..2) of Bounded_String (80);

    In this case, the compiler describes the array as an array of
    variable-size elements (identified by its XVS suffix) for which
    the size can be read in the parallel XVZ variable.

    In the case of an array of an unconstrained element type, the compiler
    wraps the array element inside a private PAD type.  This type should not
    be shown to the user, and must be "unwrap"'ed before printing.  Note
    that we also use the adjective "aligner" in our code to designate
    these wrapper types.

    In some cases, the size allocated for each element is statically
    known.  In that case, the PAD type already has the correct size,
    and the array element should remain unfixed.

    But there are cases when this size is not statically known.
    For instance, assuming that "Five" is an integer variable:

	type Dynamic is array (1 .. Five) of Integer;
	type Wrapper (Has_Length : Boolean := False) is record
	   Data : Dynamic;
	   case Has_Length is
	      when True => Length : Integer;
	      when False => null;
	   end case;
	end record;
	type Wrapper_Array is array (1 .. 2) of Wrapper;

	Hello : Wrapper_Array := (others => (Has_Length => True,
					     Data => (others => 17),
					     Length => 1));


    The debugging info would describe variable Hello as being an
    array of a PAD type.  The size of that PAD type is not statically
    known, but can be determined using a parallel XVZ variable.
    In that case, a copy of the PAD type with the correct size should
    be used for the fixed array.

    3. ``Fixing'' record type objects:
    ----------------------------------

    Things are slightly different from arrays in the case of dynamic
    record types.  In this case, in order to compute the associated
    fixed type, we need to determine the size and offset of each of
    its components.  This, in turn, requires us to compute the fixed
    type of each of these components.

    Consider for instance the example:

	type Bounded_String (Max_Size : Natural) is record
	   Str : String (1 .. Max_Size);
	   Length : Natural;
	end record;
	My_String : Bounded_String (Max_Size => 10);

    In that case, the position of field "Length" depends on the size
    of field Str, which itself depends on the value of the Max_Size
    discriminant.  In order to fix the type of variable My_String,
    we need to fix the type of field Str.  Therefore, fixing a variant
    record requires us to fix each of its components.

    However, if a component does not have a dynamic size, the component
    should not be fixed.  In particular, fields that use a PAD type
    should not fixed.  Here is an example where this might happen
    (assuming type Rec above):

       type Container (Big : Boolean) is record
	  First : Rec;
	  After : Integer;
	  case Big is
	     when True => Another : Integer;
	     when False => null;
	  end case;
       end record;
       My_Container : Container := (Big => False,
				    First => (Empty => True),
				    After => 42);

    In that example, the compiler creates a PAD type for component First,
    whose size is constant, and then positions the component After just
    right after it.  The offset of component After is therefore constant
    in this case.

    The debugger computes the position of each field based on an algorithm
    that uses, among other things, the actual position and size of the field
    preceding it.  Let's now imagine that the user is trying to print
    the value of My_Container.  If the type fixing was recursive, we would
    end up computing the offset of field After based on the size of the
    fixed version of field First.  And since in our example First has
    only one actual field, the size of the fixed type is actually smaller
    than the amount of space allocated to that field, and thus we would
    compute the wrong offset of field After.

    To make things more complicated, we need to watch out for dynamic
    components of variant records (identified by the ___XVL suffix in
    the component name).  Even if the target type is a PAD type, the size
    of that type might not be statically known.  So the PAD type needs
    to be unwrapped and the resulting type needs to be fixed.  Otherwise,
    we might end up with the wrong size for our component.  This can be
    observed with the following type declarations:

	type Octal is new Integer range 0 .. 7;
	type Octal_Array is array (Positive range <>) of Octal;
	pragma Pack (Octal_Array);

	type Octal_Buffer (Size : Positive) is record
	   Buffer : Octal_Array (1 .. Size);
	   Length : Integer;
	end record;

    In that case, Buffer is a PAD type whose size is unset and needs
    to be computed by fixing the unwrapped type.

    4. When to ``Fix'' un-``Fixed'' sub-elements of an entity:
    ----------------------------------------------------------

    Lastly, when should the sub-elements of an entity that remained unfixed
    thus far, be actually fixed?

    The answer is: Only when referencing that element.  For instance
    when selecting one component of a record, this specific component
    should be fixed at that point in time.  Or when printing the value
    of a record, each component should be fixed before its value gets
    printed.  Similarly for arrays, the element of the array should be
    fixed when printing each element of the array, or when extracting
    one element out of that array.  On the other hand, fixing should
    not be performed on the elements when taking a slice of an array!

    Note that one of the side effects of miscomputing the offset and
    size of each field is that we end up also miscomputing the size
    of the containing type.  This can have adverse results when computing
    the value of an entity.  GDB fetches the value of an entity based
    on the size of its type, and thus a wrong size causes GDB to fetch
    the wrong amount of memory.  In the case where the computed size is
    too small, GDB fetches too little data to print the value of our
    entity.  Results in this case are unpredictable, as we usually read
    past the buffer containing the data =:-o.  */

/* A helper function for TERNOP_IN_RANGE.  */

static value *
eval_ternop_in_range (struct type *expect_type, struct expression *exp,
		      enum noside noside,
		      value *arg1, value *arg2, value *arg3)
{
  binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
  binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg3);
  struct type *type = language_bool_type (exp->language_defn, exp->gdbarch);
  return
    value_from_longest (type,
			(value_less (arg1, arg3)
			 || value_equal (arg1, arg3))
			&& (value_less (arg2, arg1)
			    || value_equal (arg2, arg1)));
}

/* A helper function for UNOP_NEG.  */

value *
ada_unop_neg (struct type *expect_type,
	      struct expression *exp,
	      enum noside noside, enum exp_opcode op,
	      struct value *arg1)
{
  unop_promote (exp->language_defn, exp->gdbarch, &arg1);
  return value_neg (arg1);
}

/* A helper function for UNOP_IN_RANGE.  */

value *
ada_unop_in_range (struct type *expect_type,
		   struct expression *exp,
		   enum noside noside, enum exp_opcode op,
		   struct value *arg1, struct type *type)
{
  struct value *arg2, *arg3;
  switch (type->code ())
    {
    default:
      lim_warning (_("Membership test incompletely implemented; "
		     "always returns true"));
      type = language_bool_type (exp->language_defn, exp->gdbarch);
      return value_from_longest (type, (LONGEST) 1);

    case TYPE_CODE_RANGE:
      arg2 = value_from_longest (type,
				 type->bounds ()->low.const_val ());
      arg3 = value_from_longest (type,
				 type->bounds ()->high.const_val ());
      binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
      binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg3);
      type = language_bool_type (exp->language_defn, exp->gdbarch);
      return
	value_from_longest (type,
			    (value_less (arg1, arg3)
			     || value_equal (arg1, arg3))
			    && (value_less (arg2, arg1)
				|| value_equal (arg2, arg1)));
    }
}

/* A helper function for OP_ATR_TAG.  */

value *
ada_atr_tag (struct type *expect_type,
	     struct expression *exp,
	     enum noside noside, enum exp_opcode op,
	     struct value *arg1)
{
  if (noside == EVAL_AVOID_SIDE_EFFECTS)
    return value_zero (ada_tag_type (arg1), not_lval);

  return ada_value_tag (arg1);
}

/* A helper function for OP_ATR_SIZE.  */

value *
ada_atr_size (struct type *expect_type,
	      struct expression *exp,
	      enum noside noside, enum exp_opcode op,
	      struct value *arg1)
{
  struct type *type = value_type (arg1);

  /* If the argument is a reference, then dereference its type, since
     the user is really asking for the size of the actual object,
     not the size of the pointer.  */
  if (type->code () == TYPE_CODE_REF)
    type = TYPE_TARGET_TYPE (type);

  if (noside == EVAL_AVOID_SIDE_EFFECTS)
    return value_zero (builtin_type (exp->gdbarch)->builtin_int, not_lval);
  else
    return value_from_longest (builtin_type (exp->gdbarch)->builtin_int,
			       TARGET_CHAR_BIT * TYPE_LENGTH (type));
}

/* A helper function for UNOP_ABS.  */

value *
ada_abs (struct type *expect_type,
	 struct expression *exp,
	 enum noside noside, enum exp_opcode op,
	 struct value *arg1)
{
  unop_promote (exp->language_defn, exp->gdbarch, &arg1);
  if (value_less (arg1, value_zero (value_type (arg1), not_lval)))
    return value_neg (arg1);
  else
    return arg1;
}

/* A helper function for BINOP_MUL.  */

value *
ada_mult_binop (struct type *expect_type,
		struct expression *exp,
		enum noside noside, enum exp_opcode op,
		struct value *arg1, struct value *arg2)
{
  if (noside == EVAL_AVOID_SIDE_EFFECTS)
    {
      binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
      return value_zero (value_type (arg1), not_lval);
    }
  else
    {
      binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
      return ada_value_binop (arg1, arg2, op);
    }
}

/* A helper function for BINOP_EQUAL and BINOP_NOTEQUAL.  */

value *
ada_equal_binop (struct type *expect_type,
		 struct expression *exp,
		 enum noside noside, enum exp_opcode op,
		 struct value *arg1, struct value *arg2)
{
  int tem;
  if (noside == EVAL_AVOID_SIDE_EFFECTS)
    tem = 0;
  else
    {
      binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
      tem = ada_value_equal (arg1, arg2);
    }
  if (op == BINOP_NOTEQUAL)
    tem = !tem;
  struct type *type = language_bool_type (exp->language_defn, exp->gdbarch);
  return value_from_longest (type, (LONGEST) tem);
}

/* A helper function for TERNOP_SLICE.  */

value *
ada_ternop_slice (struct expression *exp,
		  enum noside noside,
		  struct value *array, struct value *low_bound_val,
		  struct value *high_bound_val)
{
  LONGEST low_bound;
  LONGEST high_bound;

  low_bound_val = coerce_ref (low_bound_val);
  high_bound_val = coerce_ref (high_bound_val);
  low_bound = value_as_long (low_bound_val);
  high_bound = value_as_long (high_bound_val);

  /* If this is a reference to an aligner type, then remove all
     the aligners.  */
  if (value_type (array)->code () == TYPE_CODE_REF
      && ada_is_aligner_type (TYPE_TARGET_TYPE (value_type (array))))
    TYPE_TARGET_TYPE (value_type (array)) =
      ada_aligned_type (TYPE_TARGET_TYPE (value_type (array)));

  if (ada_is_any_packed_array_type (value_type (array)))
    error (_("cannot slice a packed array"));

  /* If this is a reference to an array or an array lvalue,
     convert to a pointer.  */
  if (value_type (array)->code () == TYPE_CODE_REF
      || (value_type (array)->code () == TYPE_CODE_ARRAY
	  && VALUE_LVAL (array) == lval_memory))
    array = value_addr (array);

  if (noside == EVAL_AVOID_SIDE_EFFECTS
      && ada_is_array_descriptor_type (ada_check_typedef
				       (value_type (array))))
    return empty_array (ada_type_of_array (array, 0), low_bound,
			high_bound);

  array = ada_coerce_to_simple_array_ptr (array);

  /* If we have more than one level of pointer indirection,
     dereference the value until we get only one level.  */
  while (value_type (array)->code () == TYPE_CODE_PTR
	 && (TYPE_TARGET_TYPE (value_type (array))->code ()
	     == TYPE_CODE_PTR))
    array = value_ind (array);

  /* Make sure we really do have an array type before going further,
     to avoid a SEGV when trying to get the index type or the target
     type later down the road if the debug info generated by
     the compiler is incorrect or incomplete.  */
  if (!ada_is_simple_array_type (value_type (array)))
    error (_("cannot take slice of non-array"));

  if (ada_check_typedef (value_type (array))->code ()
      == TYPE_CODE_PTR)
    {
      struct type *type0 = ada_check_typedef (value_type (array));

      if (high_bound < low_bound || noside == EVAL_AVOID_SIDE_EFFECTS)
	return empty_array (TYPE_TARGET_TYPE (type0), low_bound, high_bound);
      else
	{
	  struct type *arr_type0 =
	    to_fixed_array_type (TYPE_TARGET_TYPE (type0), NULL, 1);

	  return ada_value_slice_from_ptr (array, arr_type0,
					   longest_to_int (low_bound),
					   longest_to_int (high_bound));
	}
    }
  else if (noside == EVAL_AVOID_SIDE_EFFECTS)
    return array;
  else if (high_bound < low_bound)
    return empty_array (value_type (array), low_bound, high_bound);
  else
    return ada_value_slice (array, longest_to_int (low_bound),
			    longest_to_int (high_bound));
}

/* A helper function for BINOP_IN_BOUNDS.  */

value *
ada_binop_in_bounds (struct expression *exp, enum noside noside,
		     struct value *arg1, struct value *arg2, int n)
{
  if (noside == EVAL_AVOID_SIDE_EFFECTS)
    {
      struct type *type = language_bool_type (exp->language_defn,
					      exp->gdbarch);
      return value_zero (type, not_lval);
    }

  struct type *type = ada_index_type (value_type (arg2), n, "range");
  if (!type)
    type = value_type (arg1);

  value *arg3 = value_from_longest (type, ada_array_bound (arg2, n, 1));
  arg2 = value_from_longest (type, ada_array_bound (arg2, n, 0));

  binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
  binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg3);
  type = language_bool_type (exp->language_defn, exp->gdbarch);
  return value_from_longest (type,
			     (value_less (arg1, arg3)
			      || value_equal (arg1, arg3))
			     && (value_less (arg2, arg1)
				 || value_equal (arg2, arg1)));
}

/* A helper function for some attribute operations.  */

static value *
ada_unop_atr (struct expression *exp, enum noside noside, enum exp_opcode op,
	      struct value *arg1, struct type *type_arg, int tem)
{
  if (noside == EVAL_AVOID_SIDE_EFFECTS)
    {
      if (type_arg == NULL)
	type_arg = value_type (arg1);

      if (ada_is_constrained_packed_array_type (type_arg))
	type_arg = decode_constrained_packed_array_type (type_arg);

      if (!discrete_type_p (type_arg))
	{
	  switch (op)
	    {
	    default:          /* Should never happen.  */
	      error (_("unexpected attribute encountered"));
	    case OP_ATR_FIRST:
	    case OP_ATR_LAST:
	      type_arg = ada_index_type (type_arg, tem,
					 ada_attribute_name (op));
	      break;
	    case OP_ATR_LENGTH:
	      type_arg = builtin_type (exp->gdbarch)->builtin_int;
	      break;
	    }
	}

      return value_zero (type_arg, not_lval);
    }
  else if (type_arg == NULL)
    {
      arg1 = ada_coerce_ref (arg1);

      if (ada_is_constrained_packed_array_type (value_type (arg1)))
	arg1 = ada_coerce_to_simple_array (arg1);

      struct type *type;
      if (op == OP_ATR_LENGTH)
	type = builtin_type (exp->gdbarch)->builtin_int;
      else
	{
	  type = ada_index_type (value_type (arg1), tem,
				 ada_attribute_name (op));
	  if (type == NULL)
	    type = builtin_type (exp->gdbarch)->builtin_int;
	}

      switch (op)
	{
	default:          /* Should never happen.  */
	  error (_("unexpected attribute encountered"));
	case OP_ATR_FIRST:
	  return value_from_longest
	    (type, ada_array_bound (arg1, tem, 0));
	case OP_ATR_LAST:
	  return value_from_longest
	    (type, ada_array_bound (arg1, tem, 1));
	case OP_ATR_LENGTH:
	  return value_from_longest
	    (type, ada_array_length (arg1, tem));
	}
    }
  else if (discrete_type_p (type_arg))
    {
      struct type *range_type;
      const char *name = ada_type_name (type_arg);

      range_type = NULL;
      if (name != NULL && type_arg->code () != TYPE_CODE_ENUM)
	range_type = to_fixed_range_type (type_arg, NULL);
      if (range_type == NULL)
	range_type = type_arg;
      switch (op)
	{
	default:
	  error (_("unexpected attribute encountered"));
	case OP_ATR_FIRST:
	  return value_from_longest 
	    (range_type, ada_discrete_type_low_bound (range_type));
	case OP_ATR_LAST:
	  return value_from_longest
	    (range_type, ada_discrete_type_high_bound (range_type));
	case OP_ATR_LENGTH:
	  error (_("the 'length attribute applies only to array types"));
	}
    }
  else if (type_arg->code () == TYPE_CODE_FLT)
    error (_("unimplemented type attribute"));
  else
    {
      LONGEST low, high;

      if (ada_is_constrained_packed_array_type (type_arg))
	type_arg = decode_constrained_packed_array_type (type_arg);

      struct type *type;
      if (op == OP_ATR_LENGTH)
	type = builtin_type (exp->gdbarch)->builtin_int;
      else
	{
	  type = ada_index_type (type_arg, tem, ada_attribute_name (op));
	  if (type == NULL)
	    type = builtin_type (exp->gdbarch)->builtin_int;
	}

      switch (op)
	{
	default:
	  error (_("unexpected attribute encountered"));
	case OP_ATR_FIRST:
	  low = ada_array_bound_from_type (type_arg, tem, 0);
	  return value_from_longest (type, low);
	case OP_ATR_LAST:
	  high = ada_array_bound_from_type (type_arg, tem, 1);
	  return value_from_longest (type, high);
	case OP_ATR_LENGTH:
	  low = ada_array_bound_from_type (type_arg, tem, 0);
	  high = ada_array_bound_from_type (type_arg, tem, 1);
	  return value_from_longest (type, high - low + 1);
	}
    }
}

/* A helper function for OP_ATR_MIN and OP_ATR_MAX.  */

struct value *
ada_binop_minmax (struct type *expect_type,
		  struct expression *exp,
		  enum noside noside, enum exp_opcode op,
		  struct value *arg1, struct value *arg2)
{
  if (noside == EVAL_AVOID_SIDE_EFFECTS)
    return value_zero (value_type (arg1), not_lval);
  else
    {
      binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
      return value_binop (arg1, arg2, op);
    }
}

/* A helper function for BINOP_EXP.  */

struct value *
ada_binop_exp (struct type *expect_type,
	       struct expression *exp,
	       enum noside noside, enum exp_opcode op,
	       struct value *arg1, struct value *arg2)
{
  if (noside == EVAL_AVOID_SIDE_EFFECTS)
    return value_zero (value_type (arg1), not_lval);
  else
    {
      /* For integer exponentiation operations,
	 only promote the first argument.  */
      if (is_integral_type (value_type (arg2)))
	unop_promote (exp->language_defn, exp->gdbarch, &arg1);
      else
	binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);

      return value_binop (arg1, arg2, op);
    }
}

namespace expr
{

/* See ada-exp.h.  */

operation_up
ada_resolvable::replace (operation_up &&owner,
			 struct expression *exp,
			 bool deprocedure_p,
			 bool parse_completion,
			 innermost_block_tracker *tracker,
			 struct type *context_type)
{
  if (resolve (exp, deprocedure_p, parse_completion, tracker, context_type))
    return (make_operation<ada_funcall_operation>
	    (std::move (owner),
	     std::vector<operation_up> ()));
  return std::move (owner);
}

/* Convert the character literal whose value would be VAL to the
   appropriate value of type TYPE, if there is a translation.
   Otherwise return VAL.  Hence, in an enumeration type ('A', 'B'),
   the literal 'A' (VAL == 65), returns 0.  */

static LONGEST
convert_char_literal (struct type *type, LONGEST val)
{
  char name[12];
  int f;

  if (type == NULL)
    return val;
  type = check_typedef (type);
  if (type->code () != TYPE_CODE_ENUM)
    return val;

  if ((val >= 'a' && val <= 'z') || (val >= '0' && val <= '9'))
    xsnprintf (name, sizeof (name), "Q%c", (int) val);
  else if (val >= 0 && val < 256)
    xsnprintf (name, sizeof (name), "QU%02x", (unsigned) val);
  else if (val >= 0 && val < 0x10000)
    xsnprintf (name, sizeof (name), "QW%04x", (unsigned) val);
  else
    xsnprintf (name, sizeof (name), "QWW%08lx", (unsigned long) val);
  size_t len = strlen (name);
  for (f = 0; f < type->num_fields (); f += 1)
    {
      /* Check the suffix because an enum constant in a package will
	 have a name like "pkg__QUxx".  This is safe enough because we
	 already have the correct type, and because mangling means
	 there can't be clashes.  */
      const char *ename = type->field (f).name ();
      size_t elen = strlen (ename);

      if (elen >= len && strcmp (name, ename + elen - len) == 0)
	return type->field (f).loc_enumval ();
    }
  return val;
}

value *
ada_char_operation::evaluate (struct type *expect_type,
			      struct expression *exp,
			      enum noside noside)
{
  value *result = long_const_operation::evaluate (expect_type, exp, noside);
  if (expect_type != nullptr)
    result = ada_value_cast (expect_type, result);
  return result;
}

/* See ada-exp.h.  */

operation_up
ada_char_operation::replace (operation_up &&owner,
			     struct expression *exp,
			     bool deprocedure_p,
			     bool parse_completion,
			     innermost_block_tracker *tracker,
			     struct type *context_type)
{
  operation_up result = std::move (owner);

  if (context_type != nullptr && context_type->code () == TYPE_CODE_ENUM)
    {
      gdb_assert (result.get () == this);
      std::get<0> (m_storage) = context_type;
      std::get<1> (m_storage)
	= convert_char_literal (context_type, std::get<1> (m_storage));
    }

  return result;
}

value *
ada_wrapped_operation::evaluate (struct type *expect_type,
				 struct expression *exp,
				 enum noside noside)
{
  value *result = std::get<0> (m_storage)->evaluate (expect_type, exp, noside);
  if (noside == EVAL_NORMAL)
    result = unwrap_value (result);

  /* If evaluating an OP_FLOAT and an EXPECT_TYPE was provided,
     then we need to perform the conversion manually, because
     evaluate_subexp_standard doesn't do it.  This conversion is
     necessary in Ada because the different kinds of float/fixed
     types in Ada have different representations.

     Similarly, we need to perform the conversion from OP_LONG
     ourselves.  */
  if ((opcode () == OP_FLOAT || opcode () == OP_LONG) && expect_type != NULL)
    result = ada_value_cast (expect_type, result);

  return result;
}

value *
ada_string_operation::evaluate (struct type *expect_type,
				struct expression *exp,
				enum noside noside)
{
  struct type *char_type;
  if (expect_type != nullptr && ada_is_string_type (expect_type))
    char_type = ada_array_element_type (expect_type, 1);
  else
    char_type = language_string_char_type (exp->language_defn, exp->gdbarch);

  const std::string &str = std::get<0> (m_storage);
  const char *encoding;
  switch (TYPE_LENGTH (char_type))
    {
    case 1:
      {
	/* Simply copy over the data -- this isn't perhaps strictly
	   correct according to the encodings, but it is gdb's
	   historical behavior.  */
	struct type *stringtype
	  = lookup_array_range_type (char_type, 1, str.length ());
	struct value *val = allocate_value (stringtype);
	memcpy (value_contents_raw (val).data (), str.c_str (),
		str.length ());
	return val;
      }

    case 2:
      if (gdbarch_byte_order (exp->gdbarch) == BFD_ENDIAN_BIG)
	encoding = "UTF-16BE";
      else
	encoding = "UTF-16LE";
      break;

    case 4:
      if (gdbarch_byte_order (exp->gdbarch) == BFD_ENDIAN_BIG)
	encoding = "UTF-32BE";
      else
	encoding = "UTF-32LE";
      break;

    default:
      error (_("unexpected character type size %s"),
	     pulongest (TYPE_LENGTH (char_type)));
    }

  auto_obstack converted;
  convert_between_encodings (host_charset (), encoding,
			     (const gdb_byte *) str.c_str (),
			     str.length (), 1,
			     &converted, translit_none);

  struct type *stringtype
    = lookup_array_range_type (char_type, 1,
			       obstack_object_size (&converted)
			       / TYPE_LENGTH (char_type));
  struct value *val = allocate_value (stringtype);
  memcpy (value_contents_raw (val).data (),
	  obstack_base (&converted),
	  obstack_object_size (&converted));
  return val;
}

value *
ada_concat_operation::evaluate (struct type *expect_type,
				struct expression *exp,
				enum noside noside)
{
  /* If one side is a literal, evaluate the other side first so that
     the expected type can be set properly.  */
  const operation_up &lhs_expr = std::get<0> (m_storage);
  const operation_up &rhs_expr = std::get<1> (m_storage);

  value *lhs, *rhs;
  if (dynamic_cast<ada_string_operation *> (lhs_expr.get ()) != nullptr)
    {
      rhs = rhs_expr->evaluate (nullptr, exp, noside);
      lhs = lhs_expr->evaluate (value_type (rhs), exp, noside);
    }
  else if (dynamic_cast<ada_char_operation *> (lhs_expr.get ()) != nullptr)
    {
      rhs = rhs_expr->evaluate (nullptr, exp, noside);
      struct type *rhs_type = check_typedef (value_type (rhs));
      struct type *elt_type = nullptr;
      if (rhs_type->code () == TYPE_CODE_ARRAY)
	elt_type = TYPE_TARGET_TYPE (rhs_type);
      lhs = lhs_expr->evaluate (elt_type, exp, noside);
    }
  else if (dynamic_cast<ada_string_operation *> (rhs_expr.get ()) != nullptr)
    {
      lhs = lhs_expr->evaluate (nullptr, exp, noside);
      rhs = rhs_expr->evaluate (value_type (lhs), exp, noside);
    }
  else if (dynamic_cast<ada_char_operation *> (rhs_expr.get ()) != nullptr)
    {
      lhs = lhs_expr->evaluate (nullptr, exp, noside);
      struct type *lhs_type = check_typedef (value_type (lhs));
      struct type *elt_type = nullptr;
      if (lhs_type->code () == TYPE_CODE_ARRAY)
	elt_type = TYPE_TARGET_TYPE (lhs_type);
      rhs = rhs_expr->evaluate (elt_type, exp, noside);
    }
  else
    return concat_operation::evaluate (expect_type, exp, noside);

  return value_concat (lhs, rhs);
}

value *
ada_qual_operation::evaluate (struct type *expect_type,
			      struct expression *exp,
			      enum noside noside)
{
  struct type *type = std::get<1> (m_storage);
  return std::get<0> (m_storage)->evaluate (type, exp, noside);
}

value *
ada_ternop_range_operation::evaluate (struct type *expect_type,
				      struct expression *exp,
				      enum noside noside)
{
  value *arg0 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
  value *arg1 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
  value *arg2 = std::get<2> (m_storage)->evaluate (nullptr, exp, noside);
  return eval_ternop_in_range (expect_type, exp, noside, arg0, arg1, arg2);
}

value *
ada_binop_addsub_operation::evaluate (struct type *expect_type,
				      struct expression *exp,
				      enum noside noside)
{
  value *arg1 = std::get<1> (m_storage)->evaluate_with_coercion (exp, noside);
  value *arg2 = std::get<2> (m_storage)->evaluate_with_coercion (exp, noside);

  auto do_op = [=] (LONGEST x, LONGEST y)
    {
      if (std::get<0> (m_storage) == BINOP_ADD)
	return x + y;
      return x - y;
    };

  if (value_type (arg1)->code () == TYPE_CODE_PTR)
    return (value_from_longest
	    (value_type (arg1),
	     do_op (value_as_long (arg1), value_as_long (arg2))));
  if (value_type (arg2)->code () == TYPE_CODE_PTR)
    return (value_from_longest
	    (value_type (arg2),
	     do_op (value_as_long (arg1), value_as_long (arg2))));
  /* Preserve the original type for use by the range case below.
     We cannot cast the result to a reference type, so if ARG1 is
     a reference type, find its underlying type.  */
  struct type *type = value_type (arg1);
  while (type->code () == TYPE_CODE_REF)
    type = TYPE_TARGET_TYPE (type);
  binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
  arg1 = value_binop (arg1, arg2, std::get<0> (m_storage));
  /* We need to special-case the result with a range.
     This is done for the benefit of "ptype".  gdb's Ada support
     historically used the LHS to set the result type here, so
     preserve this behavior.  */
  if (type->code () == TYPE_CODE_RANGE)
    arg1 = value_cast (type, arg1);
  return arg1;
}

value *
ada_unop_atr_operation::evaluate (struct type *expect_type,
				  struct expression *exp,
				  enum noside noside)
{
  struct type *type_arg = nullptr;
  value *val = nullptr;

  if (std::get<0> (m_storage)->opcode () == OP_TYPE)
    {
      value *tem = std::get<0> (m_storage)->evaluate (nullptr, exp,
						      EVAL_AVOID_SIDE_EFFECTS);
      type_arg = value_type (tem);
    }
  else
    val = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);

  return ada_unop_atr (exp, noside, std::get<1> (m_storage),
		       val, type_arg, std::get<2> (m_storage));
}

value *
ada_var_msym_value_operation::evaluate_for_cast (struct type *expect_type,
						 struct expression *exp,
						 enum noside noside)
{
  if (noside == EVAL_AVOID_SIDE_EFFECTS)
    return value_zero (expect_type, not_lval);

  const bound_minimal_symbol &b = std::get<0> (m_storage);
  value *val = evaluate_var_msym_value (noside, b.objfile, b.minsym);

  val = ada_value_cast (expect_type, val);

  /* Follow the Ada language semantics that do not allow taking
     an address of the result of a cast (view conversion in Ada).  */
  if (VALUE_LVAL (val) == lval_memory)
    {
      if (value_lazy (val))
	value_fetch_lazy (val);
      VALUE_LVAL (val) = not_lval;
    }
  return val;
}

value *
ada_var_value_operation::evaluate_for_cast (struct type *expect_type,
					    struct expression *exp,
					    enum noside noside)
{
  value *val = evaluate_var_value (noside,
				   std::get<0> (m_storage).block,
				   std::get<0> (m_storage).symbol);

  val = ada_value_cast (expect_type, val);

  /* Follow the Ada language semantics that do not allow taking
     an address of the result of a cast (view conversion in Ada).  */
  if (VALUE_LVAL (val) == lval_memory)
    {
      if (value_lazy (val))
	value_fetch_lazy (val);
      VALUE_LVAL (val) = not_lval;
    }
  return val;
}

value *
ada_var_value_operation::evaluate (struct type *expect_type,
				   struct expression *exp,
				   enum noside noside)
{
  symbol *sym = std::get<0> (m_storage).symbol;

  if (sym->domain () == UNDEF_DOMAIN)
    /* Only encountered when an unresolved symbol occurs in a
       context other than a function call, in which case, it is
       invalid.  */
    error (_("Unexpected unresolved symbol, %s, during evaluation"),
	   sym->print_name ());

  if (noside == EVAL_AVOID_SIDE_EFFECTS)
    {
      struct type *type = static_unwrap_type (sym->type ());
      /* Check to see if this is a tagged type.  We also need to handle
	 the case where the type is a reference to a tagged type, but
	 we have to be careful to exclude pointers to tagged types.
	 The latter should be shown as usual (as a pointer), whereas
	 a reference should mostly be transparent to the user.  */
      if (ada_is_tagged_type (type, 0)
	  || (type->code () == TYPE_CODE_REF
	      && ada_is_tagged_type (TYPE_TARGET_TYPE (type), 0)))
	{
	  /* Tagged types are a little special in the fact that the real
	     type is dynamic and can only be determined by inspecting the
	     object's tag.  This means that we need to get the object's
	     value first (EVAL_NORMAL) and then extract the actual object
	     type from its tag.

	     Note that we cannot skip the final step where we extract
	     the object type from its tag, because the EVAL_NORMAL phase
	     results in dynamic components being resolved into fixed ones.
	     This can cause problems when trying to print the type
	     description of tagged types whose parent has a dynamic size:
	     We use the type name of the "_parent" component in order
	     to print the name of the ancestor type in the type description.
	     If that component had a dynamic size, the resolution into
	     a fixed type would result in the loss of that type name,
	     thus preventing us from printing the name of the ancestor
	     type in the type description.  */
	  value *arg1 = evaluate (nullptr, exp, EVAL_NORMAL);

	  if (type->code () != TYPE_CODE_REF)
	    {
	      struct type *actual_type;

	      actual_type = type_from_tag (ada_value_tag (arg1));
	      if (actual_type == NULL)
		/* If, for some reason, we were unable to determine
		   the actual type from the tag, then use the static
		   approximation that we just computed as a fallback.
		   This can happen if the debugging information is
		   incomplete, for instance.  */
		actual_type = type;
	      return value_zero (actual_type, not_lval);
	    }
	  else
	    {
	      /* In the case of a ref, ada_coerce_ref takes care
		 of determining the actual type.  But the evaluation
		 should return a ref as it should be valid to ask
		 for its address; so rebuild a ref after coerce.  */
	      arg1 = ada_coerce_ref (arg1);
	      return value_ref (arg1, TYPE_CODE_REF);
	    }
	}

      /* Records and unions for which GNAT encodings have been
	 generated need to be statically fixed as well.
	 Otherwise, non-static fixing produces a type where
	 all dynamic properties are removed, which prevents "ptype"
	 from being able to completely describe the type.
	 For instance, a case statement in a variant record would be
	 replaced by the relevant components based on the actual
	 value of the discriminants.  */
      if ((type->code () == TYPE_CODE_STRUCT
	   && dynamic_template_type (type) != NULL)
	  || (type->code () == TYPE_CODE_UNION
	      && ada_find_parallel_type (type, "___XVU") != NULL))
	return value_zero (to_static_fixed_type (type), not_lval);
    }

  value *arg1 = var_value_operation::evaluate (expect_type, exp, noside);
  return ada_to_fixed_value (arg1);
}

bool
ada_var_value_operation::resolve (struct expression *exp,
				  bool deprocedure_p,
				  bool parse_completion,
				  innermost_block_tracker *tracker,
				  struct type *context_type)
{
  symbol *sym = std::get<0> (m_storage).symbol;
  if (sym->domain () == UNDEF_DOMAIN)
    {
      block_symbol resolved
	= ada_resolve_variable (sym, std::get<0> (m_storage).block,
				context_type, parse_completion,
				deprocedure_p, tracker);
      std::get<0> (m_storage) = resolved;
    }

  if (deprocedure_p
      && (std::get<0> (m_storage).symbol->type ()->code ()
	  == TYPE_CODE_FUNC))
    return true;

  return false;
}

value *
ada_atr_val_operation::evaluate (struct type *expect_type,
				 struct expression *exp,
				 enum noside noside)
{
  value *arg = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
  return ada_val_atr (noside, std::get<0> (m_storage), arg);
}

value *
ada_unop_ind_operation::evaluate (struct type *expect_type,
				  struct expression *exp,
				  enum noside noside)
{
  value *arg1 = std::get<0> (m_storage)->evaluate (expect_type, exp, noside);

  struct type *type = ada_check_typedef (value_type (arg1));
  if (noside == EVAL_AVOID_SIDE_EFFECTS)
    {
      if (ada_is_array_descriptor_type (type))
	/* GDB allows dereferencing GNAT array descriptors.  */
	{
	  struct type *arrType = ada_type_of_array (arg1, 0);

	  if (arrType == NULL)
	    error (_("Attempt to dereference null array pointer."));
	  return value_at_lazy (arrType, 0);
	}
      else if (type->code () == TYPE_CODE_PTR
	       || type->code () == TYPE_CODE_REF
	       /* In C you can dereference an array to get the 1st elt.  */
	       || type->code () == TYPE_CODE_ARRAY)
	{
	  /* As mentioned in the OP_VAR_VALUE case, tagged types can
	     only be determined by inspecting the object's tag.
	     This means that we need to evaluate completely the
	     expression in order to get its type.  */

	  if ((type->code () == TYPE_CODE_REF
	       || type->code () == TYPE_CODE_PTR)
	      && ada_is_tagged_type (TYPE_TARGET_TYPE (type), 0))
	    {
	      arg1 = std::get<0> (m_storage)->evaluate (nullptr, exp,
							EVAL_NORMAL);
	      type = value_type (ada_value_ind (arg1));
	    }
	  else
	    {
	      type = to_static_fixed_type
		(ada_aligned_type
		 (ada_check_typedef (TYPE_TARGET_TYPE (type))));
	    }
	  return value_zero (type, lval_memory);
	}
      else if (type->code () == TYPE_CODE_INT)
	{
	  /* GDB allows dereferencing an int.  */
	  if (expect_type == NULL)
	    return value_zero (builtin_type (exp->gdbarch)->builtin_int,
			       lval_memory);
	  else
	    {
	      expect_type =
		to_static_fixed_type (ada_aligned_type (expect_type));
	      return value_zero (expect_type, lval_memory);
	    }
	}
      else
	error (_("Attempt to take contents of a non-pointer value."));
    }
  arg1 = ada_coerce_ref (arg1);     /* FIXME: What is this for??  */
  type = ada_check_typedef (value_type (arg1));

  if (type->code () == TYPE_CODE_INT)
    /* GDB allows dereferencing an int.  If we were given
       the expect_type, then use that as the target type.
       Otherwise, assume that the target type is an int.  */
    {
      if (expect_type != NULL)
	return ada_value_ind (value_cast (lookup_pointer_type (expect_type),
					  arg1));
      else
	return value_at_lazy (builtin_type (exp->gdbarch)->builtin_int,
			      (CORE_ADDR) value_as_address (arg1));
    }

  if (ada_is_array_descriptor_type (type))
    /* GDB allows dereferencing GNAT array descriptors.  */
    return ada_coerce_to_simple_array (arg1);
  else
    return ada_value_ind (arg1);
}

value *
ada_structop_operation::evaluate (struct type *expect_type,
				  struct expression *exp,
				  enum noside noside)
{
  value *arg1 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
  const char *str = std::get<1> (m_storage).c_str ();
  if (noside == EVAL_AVOID_SIDE_EFFECTS)
    {
      struct type *type;
      struct type *type1 = value_type (arg1);

      if (ada_is_tagged_type (type1, 1))
	{
	  type = ada_lookup_struct_elt_type (type1, str, 1, 1);

	  /* If the field is not found, check if it exists in the
	     extension of this object's type. This means that we
	     need to evaluate completely the expression.  */

	  if (type == NULL)
	    {
	      arg1 = std::get<0> (m_storage)->evaluate (nullptr, exp,
							EVAL_NORMAL);
	      arg1 = ada_value_struct_elt (arg1, str, 0);
	      arg1 = unwrap_value (arg1);
	      type = value_type (ada_to_fixed_value (arg1));
	    }
	}
      else
	type = ada_lookup_struct_elt_type (type1, str, 1, 0);

      return value_zero (ada_aligned_type (type), lval_memory);
    }
  else
    {
      arg1 = ada_value_struct_elt (arg1, str, 0);
      arg1 = unwrap_value (arg1);
      return ada_to_fixed_value (arg1);
    }
}

value *
ada_funcall_operation::evaluate (struct type *expect_type,
				 struct expression *exp,
				 enum noside noside)
{
  const std::vector<operation_up> &args_up = std::get<1> (m_storage);
  int nargs = args_up.size ();
  std::vector<value *> argvec (nargs);
  operation_up &callee_op = std::get<0> (m_storage);

  ada_var_value_operation *avv
    = dynamic_cast<ada_var_value_operation *> (callee_op.get ());
  if (avv != nullptr
      && avv->get_symbol ()->domain () == UNDEF_DOMAIN)
    error (_("Unexpected unresolved symbol, %s, during evaluation"),
	   avv->get_symbol ()->print_name ());

  value *callee = callee_op->evaluate (nullptr, exp, noside);
  for (int i = 0; i < args_up.size (); ++i)
    argvec[i] = args_up[i]->evaluate (nullptr, exp, noside);

  if (ada_is_constrained_packed_array_type
      (desc_base_type (value_type (callee))))
    callee = ada_coerce_to_simple_array (callee);
  else if (value_type (callee)->code () == TYPE_CODE_ARRAY
	   && TYPE_FIELD_BITSIZE (value_type (callee), 0) != 0)
    /* This is a packed array that has already been fixed, and
       therefore already coerced to a simple array.  Nothing further
       to do.  */
    ;
  else if (value_type (callee)->code () == TYPE_CODE_REF)
    {
      /* Make sure we dereference references so that all the code below
	 feels like it's really handling the referenced value.  Wrapping
	 types (for alignment) may be there, so make sure we strip them as
	 well.  */
      callee = ada_to_fixed_value (coerce_ref (callee));
    }
  else if (value_type (callee)->code () == TYPE_CODE_ARRAY
	   && VALUE_LVAL (callee) == lval_memory)
    callee = value_addr (callee);

  struct type *type = ada_check_typedef (value_type (callee));

  /* Ada allows us to implicitly dereference arrays when subscripting
     them.  So, if this is an array typedef (encoding use for array
     access types encoded as fat pointers), strip it now.  */
  if (type->code () == TYPE_CODE_TYPEDEF)
    type = ada_typedef_target_type (type);

  if (type->code () == TYPE_CODE_PTR)
    {
      switch (ada_check_typedef (TYPE_TARGET_TYPE (type))->code ())
	{
	case TYPE_CODE_FUNC:
	  type = ada_check_typedef (TYPE_TARGET_TYPE (type));
	  break;
	case TYPE_CODE_ARRAY:
	  break;
	case TYPE_CODE_STRUCT:
	  if (noside != EVAL_AVOID_SIDE_EFFECTS)
	    callee = ada_value_ind (callee);
	  type = ada_check_typedef (TYPE_TARGET_TYPE (type));
	  break;
	default:
	  error (_("cannot subscript or call something of type `%s'"),
		 ada_type_name (value_type (callee)));
	  break;
	}
    }

  switch (type->code ())
    {
    case TYPE_CODE_FUNC:
      if (noside == EVAL_AVOID_SIDE_EFFECTS)
	{
	  if (TYPE_TARGET_TYPE (type) == NULL)
	    error_call_unknown_return_type (NULL);
	  return allocate_value (TYPE_TARGET_TYPE (type));
	}
      return call_function_by_hand (callee, NULL, argvec);
    case TYPE_CODE_INTERNAL_FUNCTION:
      if (noside == EVAL_AVOID_SIDE_EFFECTS)
	/* We don't know anything about what the internal
	   function might return, but we have to return
	   something.  */
	return value_zero (builtin_type (exp->gdbarch)->builtin_int,
			   not_lval);
      else
	return call_internal_function (exp->gdbarch, exp->language_defn,
				       callee, nargs,
				       argvec.data ());

    case TYPE_CODE_STRUCT:
      {
	int arity;

	arity = ada_array_arity (type);
	type = ada_array_element_type (type, nargs);
	if (type == NULL)
	  error (_("cannot subscript or call a record"));
	if (arity != nargs)
	  error (_("wrong number of subscripts; expecting %d"), arity);
	if (noside == EVAL_AVOID_SIDE_EFFECTS)
	  return value_zero (ada_aligned_type (type), lval_memory);
	return
	  unwrap_value (ada_value_subscript
			(callee, nargs, argvec.data ()));
      }
    case TYPE_CODE_ARRAY:
      if (noside == EVAL_AVOID_SIDE_EFFECTS)
	{
	  type = ada_array_element_type (type, nargs);
	  if (type == NULL)
	    error (_("element type of array unknown"));
	  else
	    return value_zero (ada_aligned_type (type), lval_memory);
	}
      return
	unwrap_value (ada_value_subscript
		      (ada_coerce_to_simple_array (callee),
		       nargs, argvec.data ()));
    case TYPE_CODE_PTR:     /* Pointer to array */
      if (noside == EVAL_AVOID_SIDE_EFFECTS)
	{
	  type = to_fixed_array_type (TYPE_TARGET_TYPE (type), NULL, 1);
	  type = ada_array_element_type (type, nargs);
	  if (type == NULL)
	    error (_("element type of array unknown"));
	  else
	    return value_zero (ada_aligned_type (type), lval_memory);
	}
      return
	unwrap_value (ada_value_ptr_subscript (callee, nargs,
					       argvec.data ()));

    default:
      error (_("Attempt to index or call something other than an "
	       "array or function"));
    }
}

bool
ada_funcall_operation::resolve (struct expression *exp,
				bool deprocedure_p,
				bool parse_completion,
				innermost_block_tracker *tracker,
				struct type *context_type)
{
  operation_up &callee_op = std::get<0> (m_storage);

  ada_var_value_operation *avv
    = dynamic_cast<ada_var_value_operation *> (callee_op.get ());
  if (avv == nullptr)
    return false;

  symbol *sym = avv->get_symbol ();
  if (sym->domain () != UNDEF_DOMAIN)
    return false;

  const std::vector<operation_up> &args_up = std::get<1> (m_storage);
  int nargs = args_up.size ();
  std::vector<value *> argvec (nargs);

  for (int i = 0; i < args_up.size (); ++i)
    argvec[i] = args_up[i]->evaluate (nullptr, exp, EVAL_AVOID_SIDE_EFFECTS);

  const block *block = avv->get_block ();
  block_symbol resolved
    = ada_resolve_funcall (sym, block,
			   context_type, parse_completion,
			   nargs, argvec.data (),
			   tracker);

  std::get<0> (m_storage)
    = make_operation<ada_var_value_operation> (resolved);
  return false;
}

bool
ada_ternop_slice_operation::resolve (struct expression *exp,
				     bool deprocedure_p,
				     bool parse_completion,
				     innermost_block_tracker *tracker,
				     struct type *context_type)
{
  /* Historically this check was done during resolution, so we
     continue that here.  */
  value *v = std::get<0> (m_storage)->evaluate (context_type, exp,
						EVAL_AVOID_SIDE_EFFECTS);
  if (ada_is_any_packed_array_type (value_type (v)))
    error (_("cannot slice a packed array"));
  return false;
}

}



/* Return non-zero iff TYPE represents a System.Address type.  */

int
ada_is_system_address_type (struct type *type)
{
  return (type->name () && strcmp (type->name (), "system__address") == 0);
}



				/* Range types */

/* Scan STR beginning at position K for a discriminant name, and
   return the value of that discriminant field of DVAL in *PX.  If
   PNEW_K is not null, put the position of the character beyond the
   name scanned in *PNEW_K.  Return 1 if successful; return 0 and do
   not alter *PX and *PNEW_K if unsuccessful.  */

static int
scan_discrim_bound (const char *str, int k, struct value *dval, LONGEST * px,
		    int *pnew_k)
{
  static std::string storage;
  const char *pstart, *pend, *bound;
  struct value *bound_val;

  if (dval == NULL || str == NULL || str[k] == '\0')
    return 0;

  pstart = str + k;
  pend = strstr (pstart, "__");
  if (pend == NULL)
    {
      bound = pstart;
      k += strlen (bound);
    }
  else
    {
      int len = pend - pstart;

      /* Strip __ and beyond.  */
      storage = std::string (pstart, len);
      bound = storage.c_str ();
      k = pend - str;
    }

  bound_val = ada_search_struct_field (bound, dval, 0, value_type (dval));
  if (bound_val == NULL)
    return 0;

  *px = value_as_long (bound_val);
  if (pnew_k != NULL)
    *pnew_k = k;
  return 1;
}

/* Value of variable named NAME.  Only exact matches are considered.
   If no such variable found, then if ERR_MSG is null, returns 0, and
   otherwise causes an error with message ERR_MSG.  */

static struct value *
get_var_value (const char *name, const char *err_msg)
{
  std::string quoted_name = add_angle_brackets (name);

  lookup_name_info lookup_name (quoted_name, symbol_name_match_type::FULL);

  std::vector<struct block_symbol> syms
    = ada_lookup_symbol_list_worker (lookup_name,
				     get_selected_block (0),
				     VAR_DOMAIN, 1);

  if (syms.size () != 1)
    {
      if (err_msg == NULL)
	return 0;
      else
	error (("%s"), err_msg);
    }

  return value_of_variable (syms[0].symbol, syms[0].block);
}

/* Value of integer variable named NAME in the current environment.
   If no such variable is found, returns false.  Otherwise, sets VALUE
   to the variable's value and returns true.  */

bool
get_int_var_value (const char *name, LONGEST &value)
{
  struct value *var_val = get_var_value (name, 0);

  if (var_val == 0)
    return false;

  value = value_as_long (var_val);
  return true;
}


/* Return a range type whose base type is that of the range type named
   NAME in the current environment, and whose bounds are calculated
   from NAME according to the GNAT range encoding conventions.
   Extract discriminant values, if needed, from DVAL.  ORIG_TYPE is the
   corresponding range type from debug information; fall back to using it
   if symbol lookup fails.  If a new type must be created, allocate it
   like ORIG_TYPE was.  The bounds information, in general, is encoded
   in NAME, the base type given in the named range type.  */

static struct type *
to_fixed_range_type (struct type *raw_type, struct value *dval)
{
  const char *name;
  struct type *base_type;
  const char *subtype_info;

  gdb_assert (raw_type != NULL);
  gdb_assert (raw_type->name () != NULL);

  if (raw_type->code () == TYPE_CODE_RANGE)
    base_type = TYPE_TARGET_TYPE (raw_type);
  else
    base_type = raw_type;

  name = raw_type->name ();
  subtype_info = strstr (name, "___XD");
  if (subtype_info == NULL)
    {
      LONGEST L = ada_discrete_type_low_bound (raw_type);
      LONGEST U = ada_discrete_type_high_bound (raw_type);

      if (L < INT_MIN || U > INT_MAX)
	return raw_type;
      else
	return create_static_range_type (alloc_type_copy (raw_type), raw_type,
					 L, U);
    }
  else
    {
      int prefix_len = subtype_info - name;
      LONGEST L, U;
      struct type *type;
      const char *bounds_str;
      int n;

      subtype_info += 5;
      bounds_str = strchr (subtype_info, '_');
      n = 1;

      if (*subtype_info == 'L')
	{
	  if (!ada_scan_number (bounds_str, n, &L, &n)
	      && !scan_discrim_bound (bounds_str, n, dval, &L, &n))
	    return raw_type;
	  if (bounds_str[n] == '_')
	    n += 2;
	  else if (bounds_str[n] == '.')     /* FIXME? SGI Workshop kludge.  */
	    n += 1;
	  subtype_info += 1;
	}
      else
	{
	  std::string name_buf = std::string (name, prefix_len) + "___L";
	  if (!get_int_var_value (name_buf.c_str (), L))
	    {
	      lim_warning (_("Unknown lower bound, using 1."));
	      L = 1;
	    }
	}

      if (*subtype_info == 'U')
	{
	  if (!ada_scan_number (bounds_str, n, &U, &n)
	      && !scan_discrim_bound (bounds_str, n, dval, &U, &n))
	    return raw_type;
	}
      else
	{
	  std::string name_buf = std::string (name, prefix_len) + "___U";
	  if (!get_int_var_value (name_buf.c_str (), U))
	    {
	      lim_warning (_("Unknown upper bound, using %ld."), (long) L);
	      U = L;
	    }
	}

      type = create_static_range_type (alloc_type_copy (raw_type),
				       base_type, L, U);
      /* create_static_range_type alters the resulting type's length
	 to match the size of the base_type, which is not what we want.
	 Set it back to the original range type's length.  */
      TYPE_LENGTH (type) = TYPE_LENGTH (raw_type);
      type->set_name (name);
      return type;
    }
}

/* True iff NAME is the name of a range type.  */

int
ada_is_range_type_name (const char *name)
{
  return (name != NULL && strstr (name, "___XD"));
}


				/* Modular types */

/* True iff TYPE is an Ada modular type.  */

int
ada_is_modular_type (struct type *type)
{
  struct type *subranged_type = get_base_type (type);

  return (subranged_type != NULL && type->code () == TYPE_CODE_RANGE
	  && subranged_type->code () == TYPE_CODE_INT
	  && subranged_type->is_unsigned ());
}

/* Assuming ada_is_modular_type (TYPE), the modulus of TYPE.  */

ULONGEST
ada_modulus (struct type *type)
{
  const dynamic_prop &high = type->bounds ()->high;

  if (high.kind () == PROP_CONST)
    return (ULONGEST) high.const_val () + 1;

  /* If TYPE is unresolved, the high bound might be a location list.  Return
     0, for lack of a better value to return.  */
  return 0;
}


/* Ada exception catchpoint support:
   ---------------------------------

   We support 3 kinds of exception catchpoints:
     . catchpoints on Ada exceptions
     . catchpoints on unhandled Ada exceptions
     . catchpoints on failed assertions

   Exceptions raised during failed assertions, or unhandled exceptions
   could perfectly be caught with the general catchpoint on Ada exceptions.
   However, we can easily differentiate these two special cases, and having
   the option to distinguish these two cases from the rest can be useful
   to zero-in on certain situations.

   Exception catchpoints are a specialized form of breakpoint,
   since they rely on inserting breakpoints inside known routines
   of the GNAT runtime.  The implementation therefore uses a standard
   breakpoint structure of the BP_BREAKPOINT type, but with its own set
   of breakpoint_ops.

   Support in the runtime for exception catchpoints have been changed
   a few times already, and these changes affect the implementation
   of these catchpoints.  In order to be able to support several
   variants of the runtime, we use a sniffer that will determine
   the runtime variant used by the program being debugged.  */

/* Ada's standard exceptions.

   The Ada 83 standard also defined Numeric_Error.  But there so many
   situations where it was unclear from the Ada 83 Reference Manual
   (RM) whether Constraint_Error or Numeric_Error should be raised,
   that the ARG (Ada Rapporteur Group) eventually issued a Binding
   Interpretation saying that anytime the RM says that Numeric_Error
   should be raised, the implementation may raise Constraint_Error.
   Ada 95 went one step further and pretty much removed Numeric_Error
   from the list of standard exceptions (it made it a renaming of
   Constraint_Error, to help preserve compatibility when compiling
   an Ada83 compiler). As such, we do not include Numeric_Error from
   this list of standard exceptions.  */

static const char * const standard_exc[] = {
  "constraint_error",
  "program_error",
  "storage_error",
  "tasking_error"
};

typedef CORE_ADDR (ada_unhandled_exception_name_addr_ftype) (void);

/* A structure that describes how to support exception catchpoints
   for a given executable.  */

struct exception_support_info
{
   /* The name of the symbol to break on in order to insert
      a catchpoint on exceptions.  */
   const char *catch_exception_sym;

   /* The name of the symbol to break on in order to insert
      a catchpoint on unhandled exceptions.  */
   const char *catch_exception_unhandled_sym;

   /* The name of the symbol to break on in order to insert
      a catchpoint on failed assertions.  */
   const char *catch_assert_sym;

   /* The name of the symbol to break on in order to insert
      a catchpoint on exception handling.  */
   const char *catch_handlers_sym;

   /* Assuming that the inferior just triggered an unhandled exception
      catchpoint, this function is responsible for returning the address
      in inferior memory where the name of that exception is stored.
      Return zero if the address could not be computed.  */
   ada_unhandled_exception_name_addr_ftype *unhandled_exception_name_addr;
};

static CORE_ADDR ada_unhandled_exception_name_addr (void);
static CORE_ADDR ada_unhandled_exception_name_addr_from_raise (void);

/* The following exception support info structure describes how to
   implement exception catchpoints with the latest version of the
   Ada runtime (as of 2019-08-??).  */

static const struct exception_support_info default_exception_support_info =
{
  "__gnat_debug_raise_exception", /* catch_exception_sym */
  "__gnat_unhandled_exception", /* catch_exception_unhandled_sym */
  "__gnat_debug_raise_assert_failure", /* catch_assert_sym */
  "__gnat_begin_handler_v1", /* catch_handlers_sym */
  ada_unhandled_exception_name_addr
};

/* The following exception support info structure describes how to
   implement exception catchpoints with an earlier version of the
   Ada runtime (as of 2007-03-06) using v0 of the EH ABI.  */

static const struct exception_support_info exception_support_info_v0 =
{
  "__gnat_debug_raise_exception", /* catch_exception_sym */
  "__gnat_unhandled_exception", /* catch_exception_unhandled_sym */
  "__gnat_debug_raise_assert_failure", /* catch_assert_sym */
  "__gnat_begin_handler", /* catch_handlers_sym */
  ada_unhandled_exception_name_addr
};

/* The following exception support info structure describes how to
   implement exception catchpoints with a slightly older version
   of the Ada runtime.  */

static const struct exception_support_info exception_support_info_fallback =
{
  "__gnat_raise_nodefer_with_msg", /* catch_exception_sym */
  "__gnat_unhandled_exception", /* catch_exception_unhandled_sym */
  "system__assertions__raise_assert_failure",  /* catch_assert_sym */
  "__gnat_begin_handler", /* catch_handlers_sym */
  ada_unhandled_exception_name_addr_from_raise
};

/* Return nonzero if we can detect the exception support routines
   described in EINFO.

   This function errors out if an abnormal situation is detected
   (for instance, if we find the exception support routines, but
   that support is found to be incomplete).  */

static int
ada_has_this_exception_support (const struct exception_support_info *einfo)
{
  struct symbol *sym;

  /* The symbol we're looking up is provided by a unit in the GNAT runtime
     that should be compiled with debugging information.  As a result, we
     expect to find that symbol in the symtabs.  */

  sym = standard_lookup (einfo->catch_exception_sym, NULL, VAR_DOMAIN);
  if (sym == NULL)
    {
      /* Perhaps we did not find our symbol because the Ada runtime was
	 compiled without debugging info, or simply stripped of it.
	 It happens on some GNU/Linux distributions for instance, where
	 users have to install a separate debug package in order to get
	 the runtime's debugging info.  In that situation, let the user
	 know why we cannot insert an Ada exception catchpoint.

	 Note: Just for the purpose of inserting our Ada exception
	 catchpoint, we could rely purely on the associated minimal symbol.
	 But we would be operating in degraded mode anyway, since we are
	 still lacking the debugging info needed later on to extract
	 the name of the exception being raised (this name is printed in
	 the catchpoint message, and is also used when trying to catch
	 a specific exception).  We do not handle this case for now.  */
      struct bound_minimal_symbol msym
	= lookup_minimal_symbol (einfo->catch_exception_sym, NULL, NULL);

      if (msym.minsym && msym.minsym->type () != mst_solib_trampoline)
	error (_("Your Ada runtime appears to be missing some debugging "
		 "information.\nCannot insert Ada exception catchpoint "
		 "in this configuration."));

      return 0;
    }

  /* Make sure that the symbol we found corresponds to a function.  */

  if (sym->aclass () != LOC_BLOCK)
    {
      error (_("Symbol \"%s\" is not a function (class = %d)"),
	     sym->linkage_name (), sym->aclass ());
      return 0;
    }

  sym = standard_lookup (einfo->catch_handlers_sym, NULL, VAR_DOMAIN);
  if (sym == NULL)
    {
      struct bound_minimal_symbol msym
	= lookup_minimal_symbol (einfo->catch_handlers_sym, NULL, NULL);

      if (msym.minsym && msym.minsym->type () != mst_solib_trampoline)
	error (_("Your Ada runtime appears to be missing some debugging "
		 "information.\nCannot insert Ada exception catchpoint "
		 "in this configuration."));

      return 0;
    }

  /* Make sure that the symbol we found corresponds to a function.  */

  if (sym->aclass () != LOC_BLOCK)
    {
      error (_("Symbol \"%s\" is not a function (class = %d)"),
	     sym->linkage_name (), sym->aclass ());
      return 0;
    }

  return 1;
}

/* Inspect the Ada runtime and determine which exception info structure
   should be used to provide support for exception catchpoints.

   This function will always set the per-inferior exception_info,
   or raise an error.  */

static void
ada_exception_support_info_sniffer (void)
{
  struct ada_inferior_data *data = get_ada_inferior_data (current_inferior ());

  /* If the exception info is already known, then no need to recompute it.  */
  if (data->exception_info != NULL)
    return;

  /* Check the latest (default) exception support info.  */
  if (ada_has_this_exception_support (&default_exception_support_info))
    {
      data->exception_info = &default_exception_support_info;
      return;
    }

  /* Try the v0 exception suport info.  */
  if (ada_has_this_exception_support (&exception_support_info_v0))
    {
      data->exception_info = &exception_support_info_v0;
      return;
    }

  /* Try our fallback exception suport info.  */
  if (ada_has_this_exception_support (&exception_support_info_fallback))
    {
      data->exception_info = &exception_support_info_fallback;
      return;
    }

  /* Sometimes, it is normal for us to not be able to find the routine
     we are looking for.  This happens when the program is linked with
     the shared version of the GNAT runtime, and the program has not been
     started yet.  Inform the user of these two possible causes if
     applicable.  */

  if (ada_update_initial_language (language_unknown) != language_ada)
    error (_("Unable to insert catchpoint.  Is this an Ada main program?"));

  /* If the symbol does not exist, then check that the program is
     already started, to make sure that shared libraries have been
     loaded.  If it is not started, this may mean that the symbol is
     in a shared library.  */

  if (inferior_ptid.pid () == 0)
    error (_("Unable to insert catchpoint. Try to start the program first."));

  /* At this point, we know that we are debugging an Ada program and
     that the inferior has been started, but we still are not able to
     find the run-time symbols.  That can mean that we are in
     configurable run time mode, or that a-except as been optimized
     out by the linker...  In any case, at this point it is not worth
     supporting this feature.  */

  error (_("Cannot insert Ada exception catchpoints in this configuration."));
}

/* True iff FRAME is very likely to be that of a function that is
   part of the runtime system.  This is all very heuristic, but is
   intended to be used as advice as to what frames are uninteresting
   to most users.  */

static int
is_known_support_routine (struct frame_info *frame)
{
  enum language func_lang;
  int i;
  const char *fullname;

  /* If this code does not have any debugging information (no symtab),
     This cannot be any user code.  */

  symtab_and_line sal = find_frame_sal (frame);
  if (sal.symtab == NULL)
    return 1;

  /* If there is a symtab, but the associated source file cannot be
     located, then assume this is not user code:  Selecting a frame
     for which we cannot display the code would not be very helpful
     for the user.  This should also take care of case such as VxWorks
     where the kernel has some debugging info provided for a few units.  */

  fullname = symtab_to_fullname (sal.symtab);
  if (access (fullname, R_OK) != 0)
    return 1;

  /* Check the unit filename against the Ada runtime file naming.
     We also check the name of the objfile against the name of some
     known system libraries that sometimes come with debugging info
     too.  */

  for (i = 0; known_runtime_file_name_patterns[i] != NULL; i += 1)
    {
      re_comp (known_runtime_file_name_patterns[i]);
      if (re_exec (lbasename (sal.symtab->filename)))
	return 1;
      if (sal.symtab->compunit ()->objfile () != NULL
	  && re_exec (objfile_name (sal.symtab->compunit ()->objfile ())))
	return 1;
    }

  /* Check whether the function is a GNAT-generated entity.  */

  gdb::unique_xmalloc_ptr<char> func_name
    = find_frame_funname (frame, &func_lang, NULL);
  if (func_name == NULL)
    return 1;

  for (i = 0; known_auxiliary_function_name_patterns[i] != NULL; i += 1)
    {
      re_comp (known_auxiliary_function_name_patterns[i]);
      if (re_exec (func_name.get ()))
	return 1;
    }

  return 0;
}

/* Find the first frame that contains debugging information and that is not
   part of the Ada run-time, starting from FI and moving upward.  */

void
ada_find_printable_frame (struct frame_info *fi)
{
  for (; fi != NULL; fi = get_prev_frame (fi))
    {
      if (!is_known_support_routine (fi))
	{
	  select_frame (fi);
	  break;
	}
    }

}

/* Assuming that the inferior just triggered an unhandled exception
   catchpoint, return the address in inferior memory where the name
   of the exception is stored.
   
   Return zero if the address could not be computed.  */

static CORE_ADDR
ada_unhandled_exception_name_addr (void)
{
  return parse_and_eval_address ("e.full_name");
}

/* Same as ada_unhandled_exception_name_addr, except that this function
   should be used when the inferior uses an older version of the runtime,
   where the exception name needs to be extracted from a specific frame
   several frames up in the callstack.  */

static CORE_ADDR
ada_unhandled_exception_name_addr_from_raise (void)
{
  int frame_level;
  struct frame_info *fi;
  struct ada_inferior_data *data = get_ada_inferior_data (current_inferior ());

  /* To determine the name of this exception, we need to select
     the frame corresponding to RAISE_SYM_NAME.  This frame is
     at least 3 levels up, so we simply skip the first 3 frames
     without checking the name of their associated function.  */
  fi = get_current_frame ();
  for (frame_level = 0; frame_level < 3; frame_level += 1)
    if (fi != NULL)
      fi = get_prev_frame (fi); 

  while (fi != NULL)
    {
      enum language func_lang;

      gdb::unique_xmalloc_ptr<char> func_name
	= find_frame_funname (fi, &func_lang, NULL);
      if (func_name != NULL)
	{
	  if (strcmp (func_name.get (),
		      data->exception_info->catch_exception_sym) == 0)
	    break; /* We found the frame we were looking for...  */
	}
      fi = get_prev_frame (fi);
    }

  if (fi == NULL)
    return 0;

  select_frame (fi);
  return parse_and_eval_address ("id.full_name");
}

/* Assuming the inferior just triggered an Ada exception catchpoint
   (of any type), return the address in inferior memory where the name
   of the exception is stored, if applicable.

   Assumes the selected frame is the current frame.

   Return zero if the address could not be computed, or if not relevant.  */

static CORE_ADDR
ada_exception_name_addr_1 (enum ada_exception_catchpoint_kind ex,
			   struct breakpoint *b)
{
  struct ada_inferior_data *data = get_ada_inferior_data (current_inferior ());

  switch (ex)
    {
      case ada_catch_exception:
	return (parse_and_eval_address ("e.full_name"));
	break;

      case ada_catch_exception_unhandled:
	return data->exception_info->unhandled_exception_name_addr ();
	break;

      case ada_catch_handlers:
	return 0;  /* The runtimes does not provide access to the exception
		      name.  */
	break;

      case ada_catch_assert:
	return 0;  /* Exception name is not relevant in this case.  */
	break;

      default:
	internal_error (__FILE__, __LINE__, _("unexpected catchpoint type"));
	break;
    }

  return 0; /* Should never be reached.  */
}

/* Assuming the inferior is stopped at an exception catchpoint,
   return the message which was associated to the exception, if
   available.  Return NULL if the message could not be retrieved.

   Note: The exception message can be associated to an exception
   either through the use of the Raise_Exception function, or
   more simply (Ada 2005 and later), via:

       raise Exception_Name with "exception message";

   */

static gdb::unique_xmalloc_ptr<char>
ada_exception_message_1 (void)
{
  struct value *e_msg_val;
  int e_msg_len;

  /* For runtimes that support this feature, the exception message
     is passed as an unbounded string argument called "message".  */
  e_msg_val = parse_and_eval ("message");
  if (e_msg_val == NULL)
    return NULL; /* Exception message not supported.  */

  e_msg_val = ada_coerce_to_simple_array (e_msg_val);
  gdb_assert (e_msg_val != NULL);
  e_msg_len = TYPE_LENGTH (value_type (e_msg_val));

  /* If the message string is empty, then treat it as if there was
     no exception message.  */
  if (e_msg_len <= 0)
    return NULL;

  gdb::unique_xmalloc_ptr<char> e_msg ((char *) xmalloc (e_msg_len + 1));
  read_memory (value_address (e_msg_val), (gdb_byte *) e_msg.get (),
	       e_msg_len);
  e_msg.get ()[e_msg_len] = '\0';

  return e_msg;
}

/* Same as ada_exception_message_1, except that all exceptions are
   contained here (returning NULL instead).  */

static gdb::unique_xmalloc_ptr<char>
ada_exception_message (void)
{
  gdb::unique_xmalloc_ptr<char> e_msg;

  try
    {
      e_msg = ada_exception_message_1 ();
    }
  catch (const gdb_exception_error &e)
    {
      e_msg.reset (nullptr);
    }

  return e_msg;
}

/* Same as ada_exception_name_addr_1, except that it intercepts and contains
   any error that ada_exception_name_addr_1 might cause to be thrown.
   When an error is intercepted, a warning with the error message is printed,
   and zero is returned.  */

static CORE_ADDR
ada_exception_name_addr (enum ada_exception_catchpoint_kind ex,
			 struct breakpoint *b)
{
  CORE_ADDR result = 0;

  try
    {
      result = ada_exception_name_addr_1 (ex, b);
    }

  catch (const gdb_exception_error &e)
    {
      warning (_("failed to get exception name: %s"), e.what ());
      return 0;
    }

  return result;
}

static std::string ada_exception_catchpoint_cond_string
  (const char *excep_string,
   enum ada_exception_catchpoint_kind ex);

/* Ada catchpoints.

   In the case of catchpoints on Ada exceptions, the catchpoint will
   stop the target on every exception the program throws.  When a user
   specifies the name of a specific exception, we translate this
   request into a condition expression (in text form), and then parse
   it into an expression stored in each of the catchpoint's locations.
   We then use this condition to check whether the exception that was
   raised is the one the user is interested in.  If not, then the
   target is resumed again.  We store the name of the requested
   exception, in order to be able to re-set the condition expression
   when symbols change.  */

/* An instance of this type is used to represent an Ada catchpoint
   breakpoint location.  */

class ada_catchpoint_location : public bp_location
{
public:
  ada_catchpoint_location (breakpoint *owner)
    : bp_location (owner, bp_loc_software_breakpoint)
  {}

  /* The condition that checks whether the exception that was raised
     is the specific exception the user specified on catchpoint
     creation.  */
  expression_up excep_cond_expr;
};

/* An instance of this type is used to represent an Ada catchpoint.  */

struct ada_catchpoint : public base_breakpoint
{
  explicit ada_catchpoint (enum ada_exception_catchpoint_kind kind)
    : m_kind (kind)
  {
  }

  struct bp_location *allocate_location () override;
  void re_set () override;
  void check_status (struct bpstat *bs) override;
  enum print_stop_action print_it (struct bpstat *bs) override;
  bool print_one (struct bp_location **) override;
  void print_mention () override;
  void print_recreate (struct ui_file *fp) override;

  /* The name of the specific exception the user specified.  */
  std::string excep_string;

  /* What kind of catchpoint this is.  */
  enum ada_exception_catchpoint_kind m_kind;
};

/* Parse the exception condition string in the context of each of the
   catchpoint's locations, and store them for later evaluation.  */

static void
create_excep_cond_exprs (struct ada_catchpoint *c,
			 enum ada_exception_catchpoint_kind ex)
{
  /* Nothing to do if there's no specific exception to catch.  */
  if (c->excep_string.empty ())
    return;

  /* Same if there are no locations... */
  if (c->loc == NULL)
    return;

  /* Compute the condition expression in text form, from the specific
     expection we want to catch.  */
  std::string cond_string
    = ada_exception_catchpoint_cond_string (c->excep_string.c_str (), ex);

  /* Iterate over all the catchpoint's locations, and parse an
     expression for each.  */
  for (bp_location *bl : c->locations ())
    {
      struct ada_catchpoint_location *ada_loc
	= (struct ada_catchpoint_location *) bl;
      expression_up exp;

      if (!bl->shlib_disabled)
	{
	  const char *s;

	  s = cond_string.c_str ();
	  try
	    {
	      exp = parse_exp_1 (&s, bl->address,
				 block_for_pc (bl->address),
				 0);
	    }
	  catch (const gdb_exception_error &e)
	    {
	      warning (_("failed to reevaluate internal exception condition "
			 "for catchpoint %d: %s"),
		       c->number, e.what ());
	    }
	}

      ada_loc->excep_cond_expr = std::move (exp);
    }
}

/* Implement the ALLOCATE_LOCATION method in the structure for all
   exception catchpoint kinds.  */

struct bp_location *
ada_catchpoint::allocate_location ()
{
  return new ada_catchpoint_location (this);
}

/* Implement the RE_SET method in the structure for all exception
   catchpoint kinds.  */

void
ada_catchpoint::re_set ()
{
  /* Call the base class's method.  This updates the catchpoint's
     locations.  */
  this->breakpoint::re_set ();

  /* Reparse the exception conditional expressions.  One for each
     location.  */
  create_excep_cond_exprs (this, m_kind);
}

/* Returns true if we should stop for this breakpoint hit.  If the
   user specified a specific exception, we only want to cause a stop
   if the program thrown that exception.  */

static bool
should_stop_exception (const struct bp_location *bl)
{
  struct ada_catchpoint *c = (struct ada_catchpoint *) bl->owner;
  const struct ada_catchpoint_location *ada_loc
    = (const struct ada_catchpoint_location *) bl;
  bool stop;

  struct internalvar *var = lookup_internalvar ("_ada_exception");
  if (c->m_kind == ada_catch_assert)
    clear_internalvar (var);
  else
    {
      try
	{
	  const char *expr;

	  if (c->m_kind == ada_catch_handlers)
	    expr = ("GNAT_GCC_exception_Access(gcc_exception)"
		    ".all.occurrence.id");
	  else
	    expr = "e";

	  struct value *exc = parse_and_eval (expr);
	  set_internalvar (var, exc);
	}
      catch (const gdb_exception_error &ex)
	{
	  clear_internalvar (var);
	}
    }

  /* With no specific exception, should always stop.  */
  if (c->excep_string.empty ())
    return true;

  if (ada_loc->excep_cond_expr == NULL)
    {
      /* We will have a NULL expression if back when we were creating
	 the expressions, this location's had failed to parse.  */
      return true;
    }

  stop = true;
  try
    {
      struct value *mark;

      mark = value_mark ();
      stop = value_true (evaluate_expression (ada_loc->excep_cond_expr.get ()));
      value_free_to_mark (mark);
    }
  catch (const gdb_exception &ex)
    {
      exception_fprintf (gdb_stderr, ex,
			 _("Error in testing exception condition:\n"));
    }

  return stop;
}

/* Implement the CHECK_STATUS method in the structure for all
   exception catchpoint kinds.  */

void
ada_catchpoint::check_status (bpstat *bs)
{
  bs->stop = should_stop_exception (bs->bp_location_at.get ());
}

/* Implement the PRINT_IT method in the structure for all exception
   catchpoint kinds.  */

enum print_stop_action
ada_catchpoint::print_it (bpstat *bs)
{
  struct ui_out *uiout = current_uiout;

  annotate_catchpoint (number);

  if (uiout->is_mi_like_p ())
    {
      uiout->field_string ("reason",
			   async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
      uiout->field_string ("disp", bpdisp_text (disposition));
    }

  uiout->text (disposition == disp_del
	       ? "\nTemporary catchpoint " : "\nCatchpoint ");
  uiout->field_signed ("bkptno", number);
  uiout->text (", ");

  /* ada_exception_name_addr relies on the selected frame being the
     current frame.  Need to do this here because this function may be
     called more than once when printing a stop, and below, we'll
     select the first frame past the Ada run-time (see
     ada_find_printable_frame).  */
  select_frame (get_current_frame ());

  switch (m_kind)
    {
      case ada_catch_exception:
      case ada_catch_exception_unhandled:
      case ada_catch_handlers:
	{
	  const CORE_ADDR addr = ada_exception_name_addr (m_kind, this);
	  char exception_name[256];

	  if (addr != 0)
	    {
	      read_memory (addr, (gdb_byte *) exception_name,
			   sizeof (exception_name) - 1);
	      exception_name [sizeof (exception_name) - 1] = '\0';
	    }
	  else
	    {
	      /* For some reason, we were unable to read the exception
		 name.  This could happen if the Runtime was compiled
		 without debugging info, for instance.  In that case,
		 just replace the exception name by the generic string
		 "exception" - it will read as "an exception" in the
		 notification we are about to print.  */
	      memcpy (exception_name, "exception", sizeof ("exception"));
	    }
	  /* In the case of unhandled exception breakpoints, we print
	     the exception name as "unhandled EXCEPTION_NAME", to make
	     it clearer to the user which kind of catchpoint just got
	     hit.  We used ui_out_text to make sure that this extra
	     info does not pollute the exception name in the MI case.  */
	  if (m_kind == ada_catch_exception_unhandled)
	    uiout->text ("unhandled ");
	  uiout->field_string ("exception-name", exception_name);
	}
	break;
      case ada_catch_assert:
	/* In this case, the name of the exception is not really
	   important.  Just print "failed assertion" to make it clearer
	   that his program just hit an assertion-failure catchpoint.
	   We used ui_out_text because this info does not belong in
	   the MI output.  */
	uiout->text ("failed assertion");
	break;
    }

  gdb::unique_xmalloc_ptr<char> exception_message = ada_exception_message ();
  if (exception_message != NULL)
    {
      uiout->text (" (");
      uiout->field_string ("exception-message", exception_message.get ());
      uiout->text (")");
    }

  uiout->text (" at ");
  ada_find_printable_frame (get_current_frame ());

  return PRINT_SRC_AND_LOC;
}

/* Implement the PRINT_ONE method in the structure for all exception
   catchpoint kinds.  */

bool
ada_catchpoint::print_one (struct bp_location **last_loc)
{ 
  struct ui_out *uiout = current_uiout;
  struct value_print_options opts;

  get_user_print_options (&opts);

  if (opts.addressprint)
    uiout->field_skip ("addr");

  annotate_field (5);
  switch (m_kind)
    {
      case ada_catch_exception:
	if (!excep_string.empty ())
	  {
	    std::string msg = string_printf (_("`%s' Ada exception"),
					     excep_string.c_str ());

	    uiout->field_string ("what", msg);
	  }
	else
	  uiout->field_string ("what", "all Ada exceptions");
	
	break;

      case ada_catch_exception_unhandled:
	uiout->field_string ("what", "unhandled Ada exceptions");
	break;
      
      case ada_catch_handlers:
	if (!excep_string.empty ())
	  {
	    uiout->field_fmt ("what",
			      _("`%s' Ada exception handlers"),
			      excep_string.c_str ());
	  }
	else
	  uiout->field_string ("what", "all Ada exceptions handlers");
	break;

      case ada_catch_assert:
	uiout->field_string ("what", "failed Ada assertions");
	break;

      default:
	internal_error (__FILE__, __LINE__, _("unexpected catchpoint type"));
	break;
    }

  return true;
}

/* Implement the PRINT_MENTION method in the breakpoint_ops structure
   for all exception catchpoint kinds.  */

void
ada_catchpoint::print_mention ()
{
  struct ui_out *uiout = current_uiout;

  uiout->text (disposition == disp_del ? _("Temporary catchpoint ")
						 : _("Catchpoint "));
  uiout->field_signed ("bkptno", number);
  uiout->text (": ");

  switch (m_kind)
    {
      case ada_catch_exception:
	if (!excep_string.empty ())
	  {
	    std::string info = string_printf (_("`%s' Ada exception"),
					      excep_string.c_str ());
	    uiout->text (info);
	  }
	else
	  uiout->text (_("all Ada exceptions"));
	break;

      case ada_catch_exception_unhandled:
	uiout->text (_("unhandled Ada exceptions"));
	break;

      case ada_catch_handlers:
	if (!excep_string.empty ())
	  {
	    std::string info
	      = string_printf (_("`%s' Ada exception handlers"),
			       excep_string.c_str ());
	    uiout->text (info);
	  }
	else
	  uiout->text (_("all Ada exceptions handlers"));
	break;

      case ada_catch_assert:
	uiout->text (_("failed Ada assertions"));
	break;

      default:
	internal_error (__FILE__, __LINE__, _("unexpected catchpoint type"));
	break;
    }
}

/* Implement the PRINT_RECREATE method in the structure for all
   exception catchpoint kinds.  */

void
ada_catchpoint::print_recreate (struct ui_file *fp)
{
  switch (m_kind)
    {
      case ada_catch_exception:
	gdb_printf (fp, "catch exception");
	if (!excep_string.empty ())
	  gdb_printf (fp, " %s", excep_string.c_str ());
	break;

      case ada_catch_exception_unhandled:
	gdb_printf (fp, "catch exception unhandled");
	break;

      case ada_catch_handlers:
	gdb_printf (fp, "catch handlers");
	break;

      case ada_catch_assert:
	gdb_printf (fp, "catch assert");
	break;

      default:
	internal_error (__FILE__, __LINE__, _("unexpected catchpoint type"));
    }
  print_recreate_thread (this, fp);
}

/* See ada-lang.h.  */

bool
is_ada_exception_catchpoint (breakpoint *bp)
{
  return dynamic_cast<ada_catchpoint *> (bp) != nullptr;
}

/* Split the arguments specified in a "catch exception" command.  
   Set EX to the appropriate catchpoint type.
   Set EXCEP_STRING to the name of the specific exception if
   specified by the user.
   IS_CATCH_HANDLERS_CMD: True if the arguments are for a
   "catch handlers" command.  False otherwise.
   If a condition is found at the end of the arguments, the condition
   expression is stored in COND_STRING (memory must be deallocated
   after use).  Otherwise COND_STRING is set to NULL.  */

static void
catch_ada_exception_command_split (const char *args,
				   bool is_catch_handlers_cmd,
				   enum ada_exception_catchpoint_kind *ex,
				   std::string *excep_string,
				   std::string *cond_string)
{
  std::string exception_name;

  exception_name = extract_arg (&args);
  if (exception_name == "if")
    {
      /* This is not an exception name; this is the start of a condition
	 expression for a catchpoint on all exceptions.  So, "un-get"
	 this token, and set exception_name to NULL.  */
      exception_name.clear ();
      args -= 2;
    }

  /* Check to see if we have a condition.  */

  args = skip_spaces (args);
  if (startswith (args, "if")
      && (isspace (args[2]) || args[2] == '\0'))
    {
      args += 2;
      args = skip_spaces (args);

      if (args[0] == '\0')
	error (_("Condition missing after `if' keyword"));
      *cond_string = args;

      args += strlen (args);
    }

  /* Check that we do not have any more arguments.  Anything else
     is unexpected.  */

  if (args[0] != '\0')
    error (_("Junk at end of expression"));

  if (is_catch_handlers_cmd)
    {
      /* Catch handling of exceptions.  */
      *ex = ada_catch_handlers;
      *excep_string = exception_name;
    }
  else if (exception_name.empty ())
    {
      /* Catch all exceptions.  */
      *ex = ada_catch_exception;
      excep_string->clear ();
    }
  else if (exception_name == "unhandled")
    {
      /* Catch unhandled exceptions.  */
      *ex = ada_catch_exception_unhandled;
      excep_string->clear ();
    }
  else
    {
      /* Catch a specific exception.  */
      *ex = ada_catch_exception;
      *excep_string = exception_name;
    }
}

/* Return the name of the symbol on which we should break in order to
   implement a catchpoint of the EX kind.  */

static const char *
ada_exception_sym_name (enum ada_exception_catchpoint_kind ex)
{
  struct ada_inferior_data *data = get_ada_inferior_data (current_inferior ());

  gdb_assert (data->exception_info != NULL);

  switch (ex)
    {
      case ada_catch_exception:
	return (data->exception_info->catch_exception_sym);
	break;
      case ada_catch_exception_unhandled:
	return (data->exception_info->catch_exception_unhandled_sym);
	break;
      case ada_catch_assert:
	return (data->exception_info->catch_assert_sym);
	break;
      case ada_catch_handlers:
	return (data->exception_info->catch_handlers_sym);
	break;
      default:
	internal_error (__FILE__, __LINE__,
			_("unexpected catchpoint kind (%d)"), ex);
    }
}

/* Return the condition that will be used to match the current exception
   being raised with the exception that the user wants to catch.  This
   assumes that this condition is used when the inferior just triggered
   an exception catchpoint.
   EX: the type of catchpoints used for catching Ada exceptions.  */

static std::string
ada_exception_catchpoint_cond_string (const char *excep_string,
				      enum ada_exception_catchpoint_kind ex)
{
  bool is_standard_exc = false;
  std::string result;

  if (ex == ada_catch_handlers)
    {
      /* For exception handlers catchpoints, the condition string does
	 not use the same parameter as for the other exceptions.  */
      result = ("long_integer (GNAT_GCC_exception_Access"
		"(gcc_exception).all.occurrence.id)");
    }
  else
    result = "long_integer (e)";

  /* The standard exceptions are a special case.  They are defined in
     runtime units that have been compiled without debugging info; if
     EXCEP_STRING is the not-fully-qualified name of a standard
     exception (e.g. "constraint_error") then, during the evaluation
     of the condition expression, the symbol lookup on this name would
     *not* return this standard exception.  The catchpoint condition
     may then be set only on user-defined exceptions which have the
     same not-fully-qualified name (e.g. my_package.constraint_error).

     To avoid this unexcepted behavior, these standard exceptions are
     systematically prefixed by "standard".  This means that "catch
     exception constraint_error" is rewritten into "catch exception
     standard.constraint_error".

     If an exception named constraint_error is defined in another package of
     the inferior program, then the only way to specify this exception as a
     breakpoint condition is to use its fully-qualified named:
     e.g. my_package.constraint_error.  */

  for (const char *name : standard_exc)
    {
      if (strcmp (name, excep_string) == 0)
	{
	  is_standard_exc = true;
	  break;
	}
    }

  result += " = ";

  if (is_standard_exc)
    string_appendf (result, "long_integer (&standard.%s)", excep_string);
  else
    string_appendf (result, "long_integer (&%s)", excep_string);

  return result;
}

/* Return the symtab_and_line that should be used to insert an exception
   catchpoint of the TYPE kind.

   ADDR_STRING returns the name of the function where the real
   breakpoint that implements the catchpoints is set, depending on the
   type of catchpoint we need to create.  */

static struct symtab_and_line
ada_exception_sal (enum ada_exception_catchpoint_kind ex,
		   std::string *addr_string)
{
  const char *sym_name;
  struct symbol *sym;

  /* First, find out which exception support info to use.  */
  ada_exception_support_info_sniffer ();

  /* Then lookup the function on which we will break in order to catch
     the Ada exceptions requested by the user.  */
  sym_name = ada_exception_sym_name (ex);
  sym = standard_lookup (sym_name, NULL, VAR_DOMAIN);

  if (sym == NULL)
    error (_("Catchpoint symbol not found: %s"), sym_name);

  if (sym->aclass () != LOC_BLOCK)
    error (_("Unable to insert catchpoint. %s is not a function."), sym_name);

  /* Set ADDR_STRING.  */
  *addr_string = sym_name;

  return find_function_start_sal (sym, 1);
}

/* Create an Ada exception catchpoint.

   EX_KIND is the kind of exception catchpoint to be created.

   If EXCEPT_STRING is empty, this catchpoint is expected to trigger
   for all exceptions.  Otherwise, EXCEPT_STRING indicates the name
   of the exception to which this catchpoint applies.

   COND_STRING, if not empty, is the catchpoint condition.

   TEMPFLAG, if nonzero, means that the underlying breakpoint
   should be temporary.

   FROM_TTY is the usual argument passed to all commands implementations.  */

void
create_ada_exception_catchpoint (struct gdbarch *gdbarch,
				 enum ada_exception_catchpoint_kind ex_kind,
				 const std::string &excep_string,
				 const std::string &cond_string,
				 int tempflag,
				 int disabled,
				 int from_tty)
{
  std::string addr_string;
  struct symtab_and_line sal = ada_exception_sal (ex_kind, &addr_string);

  std::unique_ptr<ada_catchpoint> c (new ada_catchpoint (ex_kind));
  init_ada_exception_breakpoint (c.get (), gdbarch, sal, addr_string.c_str (),
				 tempflag, disabled, from_tty);
  c->excep_string = excep_string;
  create_excep_cond_exprs (c.get (), ex_kind);
  if (!cond_string.empty ())
    set_breakpoint_condition (c.get (), cond_string.c_str (), from_tty, false);
  install_breakpoint (0, std::move (c), 1);
}

/* Implement the "catch exception" command.  */

static void
catch_ada_exception_command (const char *arg_entry, int from_tty,
			     struct cmd_list_element *command)
{
  const char *arg = arg_entry;
  struct gdbarch *gdbarch = get_current_arch ();
  int tempflag;
  enum ada_exception_catchpoint_kind ex_kind;
  std::string excep_string;
  std::string cond_string;

  tempflag = command->context () == CATCH_TEMPORARY;

  if (!arg)
    arg = "";
  catch_ada_exception_command_split (arg, false, &ex_kind, &excep_string,
				     &cond_string);
  create_ada_exception_catchpoint (gdbarch, ex_kind,
				   excep_string, cond_string,
				   tempflag, 1 /* enabled */,
				   from_tty);
}

/* Implement the "catch handlers" command.  */

static void
catch_ada_handlers_command (const char *arg_entry, int from_tty,
			    struct cmd_list_element *command)
{
  const char *arg = arg_entry;
  struct gdbarch *gdbarch = get_current_arch ();
  int tempflag;
  enum ada_exception_catchpoint_kind ex_kind;
  std::string excep_string;
  std::string cond_string;

  tempflag = command->context () == CATCH_TEMPORARY;

  if (!arg)
    arg = "";
  catch_ada_exception_command_split (arg, true, &ex_kind, &excep_string,
				     &cond_string);
  create_ada_exception_catchpoint (gdbarch, ex_kind,
				   excep_string, cond_string,
				   tempflag, 1 /* enabled */,
				   from_tty);
}

/* Completion function for the Ada "catch" commands.  */

static void
catch_ada_completer (struct cmd_list_element *cmd, completion_tracker &tracker,
		     const char *text, const char *word)
{
  std::vector<ada_exc_info> exceptions = ada_exceptions_list (NULL);

  for (const ada_exc_info &info : exceptions)
    {
      if (startswith (info.name, word))
	tracker.add_completion (make_unique_xstrdup (info.name));
    }
}

/* Split the arguments specified in a "catch assert" command.

   ARGS contains the command's arguments (or the empty string if
   no arguments were passed).

   If ARGS contains a condition, set COND_STRING to that condition
   (the memory needs to be deallocated after use).  */

static void
catch_ada_assert_command_split (const char *args, std::string &cond_string)
{
  args = skip_spaces (args);

  /* Check whether a condition was provided.  */
  if (startswith (args, "if")
      && (isspace (args[2]) || args[2] == '\0'))
    {
      args += 2;
      args = skip_spaces (args);
      if (args[0] == '\0')
	error (_("condition missing after `if' keyword"));
      cond_string.assign (args);
    }

  /* Otherwise, there should be no other argument at the end of
     the command.  */
  else if (args[0] != '\0')
    error (_("Junk at end of arguments."));
}

/* Implement the "catch assert" command.  */

static void
catch_assert_command (const char *arg_entry, int from_tty,
		      struct cmd_list_element *command)
{
  const char *arg = arg_entry;
  struct gdbarch *gdbarch = get_current_arch ();
  int tempflag;
  std::string cond_string;

  tempflag = command->context () == CATCH_TEMPORARY;

  if (!arg)
    arg = "";
  catch_ada_assert_command_split (arg, cond_string);
  create_ada_exception_catchpoint (gdbarch, ada_catch_assert,
				   "", cond_string,
				   tempflag, 1 /* enabled */,
				   from_tty);
}

/* Return non-zero if the symbol SYM is an Ada exception object.  */

static int
ada_is_exception_sym (struct symbol *sym)
{
  const char *type_name = sym->type ()->name ();

  return (sym->aclass () != LOC_TYPEDEF
	  && sym->aclass () != LOC_BLOCK
	  && sym->aclass () != LOC_CONST
	  && sym->aclass () != LOC_UNRESOLVED
	  && type_name != NULL && strcmp (type_name, "exception") == 0);
}

/* Given a global symbol SYM, return non-zero iff SYM is a non-standard
   Ada exception object.  This matches all exceptions except the ones
   defined by the Ada language.  */

static int
ada_is_non_standard_exception_sym (struct symbol *sym)
{
  if (!ada_is_exception_sym (sym))
    return 0;

  for (const char *name : standard_exc)
    if (strcmp (sym->linkage_name (), name) == 0)
      return 0;  /* A standard exception.  */

  /* Numeric_Error is also a standard exception, so exclude it.
     See the STANDARD_EXC description for more details as to why
     this exception is not listed in that array.  */
  if (strcmp (sym->linkage_name (), "numeric_error") == 0)
    return 0;

  return 1;
}

/* A helper function for std::sort, comparing two struct ada_exc_info
   objects.

   The comparison is determined first by exception name, and then
   by exception address.  */

bool
ada_exc_info::operator< (const ada_exc_info &other) const
{
  int result;

  result = strcmp (name, other.name);
  if (result < 0)
    return true;
  if (result == 0 && addr < other.addr)
    return true;
  return false;
}

bool
ada_exc_info::operator== (const ada_exc_info &other) const
{
  return addr == other.addr && strcmp (name, other.name) == 0;
}

/* Sort EXCEPTIONS using compare_ada_exception_info as the comparison
   routine, but keeping the first SKIP elements untouched.

   All duplicates are also removed.  */

static void
sort_remove_dups_ada_exceptions_list (std::vector<ada_exc_info> *exceptions,
				      int skip)
{
  std::sort (exceptions->begin () + skip, exceptions->end ());
  exceptions->erase (std::unique (exceptions->begin () + skip, exceptions->end ()),
		     exceptions->end ());
}

/* Add all exceptions defined by the Ada standard whose name match
   a regular expression.

   If PREG is not NULL, then this regexp_t object is used to
   perform the symbol name matching.  Otherwise, no name-based
   filtering is performed.

   EXCEPTIONS is a vector of exceptions to which matching exceptions
   gets pushed.  */

static void
ada_add_standard_exceptions (compiled_regex *preg,
			     std::vector<ada_exc_info> *exceptions)
{
  for (const char *name : standard_exc)
    {
      if (preg == NULL || preg->exec (name, 0, NULL, 0) == 0)
	{
	  struct bound_minimal_symbol msymbol
	    = ada_lookup_simple_minsym (name);

	  if (msymbol.minsym != NULL)
	    {
	      struct ada_exc_info info
		= {name, msymbol.value_address ()};

	      exceptions->push_back (info);
	    }
	}
    }
}

/* Add all Ada exceptions defined locally and accessible from the given
   FRAME.

   If PREG is not NULL, then this regexp_t object is used to
   perform the symbol name matching.  Otherwise, no name-based
   filtering is performed.

   EXCEPTIONS is a vector of exceptions to which matching exceptions
   gets pushed.  */

static void
ada_add_exceptions_from_frame (compiled_regex *preg,
			       struct frame_info *frame,
			       std::vector<ada_exc_info> *exceptions)
{
  const struct block *block = get_frame_block (frame, 0);

  while (block != 0)
    {
      struct block_iterator iter;
      struct symbol *sym;

      ALL_BLOCK_SYMBOLS (block, iter, sym)
	{
	  switch (sym->aclass ())
	    {
	    case LOC_TYPEDEF:
	    case LOC_BLOCK:
	    case LOC_CONST:
	      break;
	    default:
	      if (ada_is_exception_sym (sym))
		{
		  struct ada_exc_info info = {sym->print_name (),
					      sym->value_address ()};

		  exceptions->push_back (info);
		}
	    }
	}
      if (block->function () != NULL)
	break;
      block = block->superblock ();
    }
}

/* Return true if NAME matches PREG or if PREG is NULL.  */

static bool
name_matches_regex (const char *name, compiled_regex *preg)
{
  return (preg == NULL
	  || preg->exec (ada_decode (name).c_str (), 0, NULL, 0) == 0);
}

/* Add all exceptions defined globally whose name name match
   a regular expression, excluding standard exceptions.

   The reason we exclude standard exceptions is that they need
   to be handled separately: Standard exceptions are defined inside
   a runtime unit which is normally not compiled with debugging info,
   and thus usually do not show up in our symbol search.  However,
   if the unit was in fact built with debugging info, we need to
   exclude them because they would duplicate the entry we found
   during the special loop that specifically searches for those
   standard exceptions.

   If PREG is not NULL, then this regexp_t object is used to
   perform the symbol name matching.  Otherwise, no name-based
   filtering is performed.

   EXCEPTIONS is a vector of exceptions to which matching exceptions
   gets pushed.  */

static void
ada_add_global_exceptions (compiled_regex *preg,
			   std::vector<ada_exc_info> *exceptions)
{
  /* In Ada, the symbol "search name" is a linkage name, whereas the
     regular expression used to do the matching refers to the natural
     name.  So match against the decoded name.  */
  expand_symtabs_matching (NULL,
			   lookup_name_info::match_any (),
			   [&] (const char *search_name)
			   {
			     std::string decoded = ada_decode (search_name);
			     return name_matches_regex (decoded.c_str (), preg);
			   },
			   NULL,
			   SEARCH_GLOBAL_BLOCK | SEARCH_STATIC_BLOCK,
			   VARIABLES_DOMAIN);

  for (objfile *objfile : current_program_space->objfiles ())
    {
      for (compunit_symtab *s : objfile->compunits ())
	{
	  const struct blockvector *bv = s->blockvector ();
	  int i;

	  for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++)
	    {
	      const struct block *b = bv->block (i);
	      struct block_iterator iter;
	      struct symbol *sym;

	      ALL_BLOCK_SYMBOLS (b, iter, sym)
		if (ada_is_non_standard_exception_sym (sym)
		    && name_matches_regex (sym->natural_name (), preg))
		  {
		    struct ada_exc_info info
		      = {sym->print_name (), sym->value_address ()};

		    exceptions->push_back (info);
		  }
	    }
	}
    }
}

/* Implements ada_exceptions_list with the regular expression passed
   as a regex_t, rather than a string.

   If not NULL, PREG is used to filter out exceptions whose names
   do not match.  Otherwise, all exceptions are listed.  */

static std::vector<ada_exc_info>
ada_exceptions_list_1 (compiled_regex *preg)
{
  std::vector<ada_exc_info> result;
  int prev_len;

  /* First, list the known standard exceptions.  These exceptions
     need to be handled separately, as they are usually defined in
     runtime units that have been compiled without debugging info.  */

  ada_add_standard_exceptions (preg, &result);

  /* Next, find all exceptions whose scope is local and accessible
     from the currently selected frame.  */

  if (has_stack_frames ())
    {
      prev_len = result.size ();
      ada_add_exceptions_from_frame (preg, get_selected_frame (NULL),
				     &result);
      if (result.size () > prev_len)
	sort_remove_dups_ada_exceptions_list (&result, prev_len);
    }

  /* Add all exceptions whose scope is global.  */

  prev_len = result.size ();
  ada_add_global_exceptions (preg, &result);
  if (result.size () > prev_len)
    sort_remove_dups_ada_exceptions_list (&result, prev_len);

  return result;
}

/* Return a vector of ada_exc_info.

   If REGEXP is NULL, all exceptions are included in the result.
   Otherwise, it should contain a valid regular expression,
   and only the exceptions whose names match that regular expression
   are included in the result.

   The exceptions are sorted in the following order:
     - Standard exceptions (defined by the Ada language), in
       alphabetical order;
     - Exceptions only visible from the current frame, in
       alphabetical order;
     - Exceptions whose scope is global, in alphabetical order.  */

std::vector<ada_exc_info>
ada_exceptions_list (const char *regexp)
{
  if (regexp == NULL)
    return ada_exceptions_list_1 (NULL);

  compiled_regex reg (regexp, REG_NOSUB, _("invalid regular expression"));
  return ada_exceptions_list_1 (&reg);
}

/* Implement the "info exceptions" command.  */

static void
info_exceptions_command (const char *regexp, int from_tty)
{
  struct gdbarch *gdbarch = get_current_arch ();

  std::vector<ada_exc_info> exceptions = ada_exceptions_list (regexp);

  if (regexp != NULL)
    gdb_printf
      (_("All Ada exceptions matching regular expression \"%s\":\n"), regexp);
  else
    gdb_printf (_("All defined Ada exceptions:\n"));

  for (const ada_exc_info &info : exceptions)
    gdb_printf ("%s: %s\n", info.name, paddress (gdbarch, info.addr));
}


				/* Language vector */

/* symbol_name_matcher_ftype adapter for wild_match.  */

static bool
do_wild_match (const char *symbol_search_name,
	       const lookup_name_info &lookup_name,
	       completion_match_result *comp_match_res)
{
  return wild_match (symbol_search_name, ada_lookup_name (lookup_name));
}

/* symbol_name_matcher_ftype adapter for full_match.  */

static bool
do_full_match (const char *symbol_search_name,
	       const lookup_name_info &lookup_name,
	       completion_match_result *comp_match_res)
{
  const char *lname = lookup_name.ada ().lookup_name ().c_str ();

  /* If both symbols start with "_ada_", just let the loop below
     handle the comparison.  However, if only the symbol name starts
     with "_ada_", skip the prefix and let the match proceed as
     usual.  */
  if (startswith (symbol_search_name, "_ada_")
      && !startswith (lname, "_ada"))
    symbol_search_name += 5;
  /* Likewise for ghost entities.  */
  if (startswith (symbol_search_name, "___ghost_")
      && !startswith (lname, "___ghost_"))
    symbol_search_name += 9;

  int uscore_count = 0;
  while (*lname != '\0')
    {
      if (*symbol_search_name != *lname)
	{
	  if (*symbol_search_name == 'B' && uscore_count == 2
	      && symbol_search_name[1] == '_')
	    {
	      symbol_search_name += 2;
	      while (isdigit (*symbol_search_name))
		++symbol_search_name;
	      if (symbol_search_name[0] == '_'
		  && symbol_search_name[1] == '_')
		{
		  symbol_search_name += 2;
		  continue;
		}
	    }
	  return false;
	}

      if (*symbol_search_name == '_')
	++uscore_count;
      else
	uscore_count = 0;

      ++symbol_search_name;
      ++lname;
    }

  return is_name_suffix (symbol_search_name);
}

/* symbol_name_matcher_ftype for exact (verbatim) matches.  */

static bool
do_exact_match (const char *symbol_search_name,
		const lookup_name_info &lookup_name,
		completion_match_result *comp_match_res)
{
  return strcmp (symbol_search_name, ada_lookup_name (lookup_name)) == 0;
}

/* Build the Ada lookup name for LOOKUP_NAME.  */

ada_lookup_name_info::ada_lookup_name_info (const lookup_name_info &lookup_name)
{
  gdb::string_view user_name = lookup_name.name ();

  if (!user_name.empty () && user_name[0] == '<')
    {
      if (user_name.back () == '>')
	m_encoded_name
	  = gdb::to_string (user_name.substr (1, user_name.size () - 2));
      else
	m_encoded_name
	  = gdb::to_string (user_name.substr (1, user_name.size () - 1));
      m_encoded_p = true;
      m_verbatim_p = true;
      m_wild_match_p = false;
      m_standard_p = false;
    }
  else
    {
      m_verbatim_p = false;

      m_encoded_p = user_name.find ("__") != gdb::string_view::npos;

      if (!m_encoded_p)
	{
	  const char *folded = ada_fold_name (user_name);
	  m_encoded_name = ada_encode_1 (folded, false);
	  if (m_encoded_name.empty ())
	    m_encoded_name = gdb::to_string (user_name);
	}
      else
	m_encoded_name = gdb::to_string (user_name);

      /* Handle the 'package Standard' special case.  See description
	 of m_standard_p.  */
      if (startswith (m_encoded_name.c_str (), "standard__"))
	{
	  m_encoded_name = m_encoded_name.substr (sizeof ("standard__") - 1);
	  m_standard_p = true;
	}
      else
	m_standard_p = false;

      /* If the name contains a ".", then the user is entering a fully
	 qualified entity name, and the match must not be done in wild
	 mode.  Similarly, if the user wants to complete what looks
	 like an encoded name, the match must not be done in wild
	 mode.  Also, in the standard__ special case always do
	 non-wild matching.  */
      m_wild_match_p
	= (lookup_name.match_type () != symbol_name_match_type::FULL
	   && !m_encoded_p
	   && !m_standard_p
	   && user_name.find ('.') == std::string::npos);
    }
}

/* symbol_name_matcher_ftype method for Ada.  This only handles
   completion mode.  */

static bool
ada_symbol_name_matches (const char *symbol_search_name,
			 const lookup_name_info &lookup_name,
			 completion_match_result *comp_match_res)
{
  return lookup_name.ada ().matches (symbol_search_name,
				     lookup_name.match_type (),
				     comp_match_res);
}

/* A name matcher that matches the symbol name exactly, with
   strcmp.  */

static bool
literal_symbol_name_matcher (const char *symbol_search_name,
			     const lookup_name_info &lookup_name,
			     completion_match_result *comp_match_res)
{
  gdb::string_view name_view = lookup_name.name ();

  if (lookup_name.completion_mode ()
      ? (strncmp (symbol_search_name, name_view.data (),
		  name_view.size ()) == 0)
      : symbol_search_name == name_view)
    {
      if (comp_match_res != NULL)
	comp_match_res->set_match (symbol_search_name);
      return true;
    }
  else
    return false;
}

/* Implement the "get_symbol_name_matcher" language_defn method for
   Ada.  */

static symbol_name_matcher_ftype *
ada_get_symbol_name_matcher (const lookup_name_info &lookup_name)
{
  if (lookup_name.match_type () == symbol_name_match_type::SEARCH_NAME)
    return literal_symbol_name_matcher;

  if (lookup_name.completion_mode ())
    return ada_symbol_name_matches;
  else
    {
      if (lookup_name.ada ().wild_match_p ())
	return do_wild_match;
      else if (lookup_name.ada ().verbatim_p ())
	return do_exact_match;
      else
	return do_full_match;
    }
}

/* Class representing the Ada language.  */

class ada_language : public language_defn
{
public:
  ada_language ()
    : language_defn (language_ada)
  { /* Nothing.  */ }

  /* See language.h.  */

  const char *name () const override
  { return "ada"; }

  /* See language.h.  */

  const char *natural_name () const override
  { return "Ada"; }

  /* See language.h.  */

  const std::vector<const char *> &filename_extensions () const override
  {
    static const std::vector<const char *> extensions
      = { ".adb", ".ads", ".a", ".ada", ".dg" };
    return extensions;
  }

  /* Print an array element index using the Ada syntax.  */

  void print_array_index (struct type *index_type,
			  LONGEST index,
			  struct ui_file *stream,
			  const value_print_options *options) const override
  {
    struct value *index_value = val_atr (index_type, index);

    value_print (index_value, stream, options);
    gdb_printf (stream, " => ");
  }

  /* Implement the "read_var_value" language_defn method for Ada.  */

  struct value *read_var_value (struct symbol *var,
				const struct block *var_block,
				struct frame_info *frame) const override
  {
    /* The only case where default_read_var_value is not sufficient
       is when VAR is a renaming...  */
    if (frame != nullptr)
      {
	const struct block *frame_block = get_frame_block (frame, NULL);
	if (frame_block != nullptr && ada_is_renaming_symbol (var))
	  return ada_read_renaming_var_value (var, frame_block);
      }

    /* This is a typical case where we expect the default_read_var_value
       function to work.  */
    return language_defn::read_var_value (var, var_block, frame);
  }

  /* See language.h.  */
  bool symbol_printing_suppressed (struct symbol *symbol) const override
  {
    return symbol->is_artificial ();
  }

  /* See language.h.  */
  void language_arch_info (struct gdbarch *gdbarch,
			   struct language_arch_info *lai) const override
  {
    const struct builtin_type *builtin = builtin_type (gdbarch);

    /* Helper function to allow shorter lines below.  */
    auto add = [&] (struct type *t)
    {
      lai->add_primitive_type (t);
    };

    add (arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch),
			    0, "integer"));
    add (arch_integer_type (gdbarch, gdbarch_long_bit (gdbarch),
			    0, "long_integer"));
    add (arch_integer_type (gdbarch, gdbarch_short_bit (gdbarch),
			    0, "short_integer"));
    struct type *char_type = arch_character_type (gdbarch, TARGET_CHAR_BIT,
						  1, "character");
    lai->set_string_char_type (char_type);
    add (char_type);
    add (arch_character_type (gdbarch, 16, 1, "wide_character"));
    add (arch_character_type (gdbarch, 32, 1, "wide_wide_character"));
    add (arch_float_type (gdbarch, gdbarch_float_bit (gdbarch),
			  "float", gdbarch_float_format (gdbarch)));
    add (arch_float_type (gdbarch, gdbarch_double_bit (gdbarch),
			  "long_float", gdbarch_double_format (gdbarch)));
    add (arch_integer_type (gdbarch, gdbarch_long_long_bit (gdbarch),
			    0, "long_long_integer"));
    add (arch_float_type (gdbarch, gdbarch_long_double_bit (gdbarch),
			  "long_long_float",
			  gdbarch_long_double_format (gdbarch)));
    add (arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch),
			    0, "natural"));
    add (arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch),
			    0, "positive"));
    add (builtin->builtin_void);

    struct type *system_addr_ptr
      = lookup_pointer_type (arch_type (gdbarch, TYPE_CODE_VOID, TARGET_CHAR_BIT,
					"void"));
    system_addr_ptr->set_name ("system__address");
    add (system_addr_ptr);

    /* Create the equivalent of the System.Storage_Elements.Storage_Offset
       type.  This is a signed integral type whose size is the same as
       the size of addresses.  */
    unsigned int addr_length = TYPE_LENGTH (system_addr_ptr);
    add (arch_integer_type (gdbarch, addr_length * HOST_CHAR_BIT, 0,
			    "storage_offset"));

    lai->set_bool_type (builtin->builtin_bool);
  }

  /* See language.h.  */

  bool iterate_over_symbols
	(const struct block *block, const lookup_name_info &name,
	 domain_enum domain,
	 gdb::function_view<symbol_found_callback_ftype> callback) const override
  {
    std::vector<struct block_symbol> results
      = ada_lookup_symbol_list_worker (name, block, domain, 0);
    for (block_symbol &sym : results)
      {
	if (!callback (&sym))
	  return false;
      }

    return true;
  }

  /* See language.h.  */
  bool sniff_from_mangled_name
       (const char *mangled,
	gdb::unique_xmalloc_ptr<char> *out) const override
  {
    std::string demangled = ada_decode (mangled);

    *out = NULL;

    if (demangled != mangled && demangled[0] != '<')
      {
	/* Set the gsymbol language to Ada, but still return 0.
	   Two reasons for that:

	   1. For Ada, we prefer computing the symbol's decoded name
	   on the fly rather than pre-compute it, in order to save
	   memory (Ada projects are typically very large).

	   2. There are some areas in the definition of the GNAT
	   encoding where, with a bit of bad luck, we might be able
	   to decode a non-Ada symbol, generating an incorrect
	   demangled name (Eg: names ending with "TB" for instance
	   are identified as task bodies and so stripped from
	   the decoded name returned).

	   Returning true, here, but not setting *DEMANGLED, helps us get
	   a little bit of the best of both worlds.  Because we're last,
	   we should not affect any of the other languages that were
	   able to demangle the symbol before us; we get to correctly
	   tag Ada symbols as such; and even if we incorrectly tagged a
	   non-Ada symbol, which should be rare, any routing through the
	   Ada language should be transparent (Ada tries to behave much
	   like C/C++ with non-Ada symbols).  */
	return true;
      }

    return false;
  }

  /* See language.h.  */

  gdb::unique_xmalloc_ptr<char> demangle_symbol (const char *mangled,
						 int options) const override
  {
    return make_unique_xstrdup (ada_decode (mangled).c_str ());
  }

  /* See language.h.  */

  void print_type (struct type *type, const char *varstring,
		   struct ui_file *stream, int show, int level,
		   const struct type_print_options *flags) const override
  {
    ada_print_type (type, varstring, stream, show, level, flags);
  }

  /* See language.h.  */

  const char *word_break_characters (void) const override
  {
    return ada_completer_word_break_characters;
  }

  /* See language.h.  */

  void collect_symbol_completion_matches (completion_tracker &tracker,
					  complete_symbol_mode mode,
					  symbol_name_match_type name_match_type,
					  const char *text, const char *word,
					  enum type_code code) const override
  {
    struct symbol *sym;
    const struct block *b, *surrounding_static_block = 0;
    struct block_iterator iter;

    gdb_assert (code == TYPE_CODE_UNDEF);

    lookup_name_info lookup_name (text, name_match_type, true);

    /* First, look at the partial symtab symbols.  */
    expand_symtabs_matching (NULL,
			     lookup_name,
			     NULL,
			     NULL,
			     SEARCH_GLOBAL_BLOCK | SEARCH_STATIC_BLOCK,
			     ALL_DOMAIN);

    /* At this point scan through the misc symbol vectors and add each
       symbol you find to the list.  Eventually we want to ignore
       anything that isn't a text symbol (everything else will be
       handled by the psymtab code above).  */

    for (objfile *objfile : current_program_space->objfiles ())
      {
	for (minimal_symbol *msymbol : objfile->msymbols ())
	  {
	    QUIT;

	    if (completion_skip_symbol (mode, msymbol))
	      continue;

	    language symbol_language = msymbol->language ();

	    /* Ada minimal symbols won't have their language set to Ada.  If
	       we let completion_list_add_name compare using the
	       default/C-like matcher, then when completing e.g., symbols in a
	       package named "pck", we'd match internal Ada symbols like
	       "pckS", which are invalid in an Ada expression, unless you wrap
	       them in '<' '>' to request a verbatim match.

	       Unfortunately, some Ada encoded names successfully demangle as
	       C++ symbols (using an old mangling scheme), such as "name__2Xn"
	       -> "Xn::name(void)" and thus some Ada minimal symbols end up
	       with the wrong language set.  Paper over that issue here.  */
	    if (symbol_language == language_auto
		|| symbol_language == language_cplus)
	      symbol_language = language_ada;

	    completion_list_add_name (tracker,
				      symbol_language,
				      msymbol->linkage_name (),
				      lookup_name, text, word);
	  }
      }

    /* Search upwards from currently selected frame (so that we can
       complete on local vars.  */

    for (b = get_selected_block (0); b != NULL; b = b->superblock ())
      {
	if (!b->superblock ())
	  surrounding_static_block = b;   /* For elmin of dups */

	ALL_BLOCK_SYMBOLS (b, iter, sym)
	  {
	    if (completion_skip_symbol (mode, sym))
	      continue;

	    completion_list_add_name (tracker,
				      sym->language (),
				      sym->linkage_name (),
				      lookup_name, text, word);
	  }
      }

    /* Go through the symtabs and check the externs and statics for
       symbols which match.  */

    for (objfile *objfile : current_program_space->objfiles ())
      {
	for (compunit_symtab *s : objfile->compunits ())
	  {
	    QUIT;
	    b = s->blockvector ()->global_block ();
	    ALL_BLOCK_SYMBOLS (b, iter, sym)
	      {
		if (completion_skip_symbol (mode, sym))
		  continue;

		completion_list_add_name (tracker,
					  sym->language (),
					  sym->linkage_name (),
					  lookup_name, text, word);
	      }
	  }
      }

    for (objfile *objfile : current_program_space->objfiles ())
      {
	for (compunit_symtab *s : objfile->compunits ())
	  {
	    QUIT;
	    b = s->blockvector ()->static_block ();
	    /* Don't do this block twice.  */
	    if (b == surrounding_static_block)
	      continue;
	    ALL_BLOCK_SYMBOLS (b, iter, sym)
	      {
		if (completion_skip_symbol (mode, sym))
		  continue;

		completion_list_add_name (tracker,
					  sym->language (),
					  sym->linkage_name (),
					  lookup_name, text, word);
	      }
	  }
      }
  }

  /* See language.h.  */

  gdb::unique_xmalloc_ptr<char> watch_location_expression
	(struct type *type, CORE_ADDR addr) const override
  {
    type = check_typedef (TYPE_TARGET_TYPE (check_typedef (type)));
    std::string name = type_to_string (type);
    return xstrprintf ("{%s} %s", name.c_str (), core_addr_to_string (addr));
  }

  /* See language.h.  */

  void value_print (struct value *val, struct ui_file *stream,
		    const struct value_print_options *options) const override
  {
    return ada_value_print (val, stream, options);
  }

  /* See language.h.  */

  void value_print_inner
	(struct value *val, struct ui_file *stream, int recurse,
	 const struct value_print_options *options) const override
  {
    return ada_value_print_inner (val, stream, recurse, options);
  }

  /* See language.h.  */

  struct block_symbol lookup_symbol_nonlocal
	(const char *name, const struct block *block,
	 const domain_enum domain) const override
  {
    struct block_symbol sym;

    sym = ada_lookup_symbol (name, block_static_block (block), domain);
    if (sym.symbol != NULL)
      return sym;

    /* If we haven't found a match at this point, try the primitive
       types.  In other languages, this search is performed before
       searching for global symbols in order to short-circuit that
       global-symbol search if it happens that the name corresponds
       to a primitive type.  But we cannot do the same in Ada, because
       it is perfectly legitimate for a program to declare a type which
       has the same name as a standard type.  If looking up a type in
       that situation, we have traditionally ignored the primitive type
       in favor of user-defined types.  This is why, unlike most other
       languages, we search the primitive types this late and only after
       having searched the global symbols without success.  */

    if (domain == VAR_DOMAIN)
      {
	struct gdbarch *gdbarch;

	if (block == NULL)
	  gdbarch = target_gdbarch ();
	else
	  gdbarch = block_gdbarch (block);
	sym.symbol
	  = language_lookup_primitive_type_as_symbol (this, gdbarch, name);
	if (sym.symbol != NULL)
	  return sym;
      }

    return {};
  }

  /* See language.h.  */

  int parser (struct parser_state *ps) const override
  {
    warnings_issued = 0;
    return ada_parse (ps);
  }

  /* See language.h.  */

  void emitchar (int ch, struct type *chtype,
		 struct ui_file *stream, int quoter) const override
  {
    ada_emit_char (ch, chtype, stream, quoter, 1);
  }

  /* See language.h.  */

  void printchar (int ch, struct type *chtype,
		  struct ui_file *stream) const override
  {
    ada_printchar (ch, chtype, stream);
  }

  /* See language.h.  */

  void printstr (struct ui_file *stream, struct type *elttype,
		 const gdb_byte *string, unsigned int length,
		 const char *encoding, int force_ellipses,
		 const struct value_print_options *options) const override
  {
    ada_printstr (stream, elttype, string, length, encoding,
		  force_ellipses, options);
  }

  /* See language.h.  */

  void print_typedef (struct type *type, struct symbol *new_symbol,
		      struct ui_file *stream) const override
  {
    ada_print_typedef (type, new_symbol, stream);
  }

  /* See language.h.  */

  bool is_string_type_p (struct type *type) const override
  {
    return ada_is_string_type (type);
  }

  /* See language.h.  */

  const char *struct_too_deep_ellipsis () const override
  { return "(...)"; }

  /* See language.h.  */

  bool c_style_arrays_p () const override
  { return false; }

  /* See language.h.  */

  bool store_sym_names_in_linkage_form_p () const override
  { return true; }

  /* See language.h.  */

  const struct lang_varobj_ops *varobj_ops () const override
  { return &ada_varobj_ops; }

protected:
  /* See language.h.  */

  symbol_name_matcher_ftype *get_symbol_name_matcher_inner
	(const lookup_name_info &lookup_name) const override
  {
    return ada_get_symbol_name_matcher (lookup_name);
  }
};

/* Single instance of the Ada language class.  */

static ada_language ada_language_defn;

/* Command-list for the "set/show ada" prefix command.  */
static struct cmd_list_element *set_ada_list;
static struct cmd_list_element *show_ada_list;

/* This module's 'new_objfile' observer.  */

static void
ada_new_objfile_observer (struct objfile *objfile)
{
  ada_clear_symbol_cache ();
}

/* This module's 'free_objfile' observer.  */

static void
ada_free_objfile_observer (struct objfile *objfile)
{
  ada_clear_symbol_cache ();
}

/* Charsets known to GNAT.  */
static const char * const gnat_source_charsets[] =
{
  /* Note that code below assumes that the default comes first.
     Latin-1 is the default here, because that is also GNAT's
     default.  */
  "ISO-8859-1",
  "ISO-8859-2",
  "ISO-8859-3",
  "ISO-8859-4",
  "ISO-8859-5",
  "ISO-8859-15",
  "CP437",
  "CP850",
  /* Note that this value is special-cased in the encoder and
     decoder.  */
  ada_utf8,
  nullptr
};

void _initialize_ada_language ();
void
_initialize_ada_language ()
{
  add_setshow_prefix_cmd
    ("ada", no_class,
     _("Prefix command for changing Ada-specific settings."),
     _("Generic command for showing Ada-specific settings."),
     &set_ada_list, &show_ada_list,
     &setlist, &showlist);

  add_setshow_boolean_cmd ("trust-PAD-over-XVS", class_obscure,
			   &trust_pad_over_xvs, _("\
Enable or disable an optimization trusting PAD types over XVS types."), _("\
Show whether an optimization trusting PAD types over XVS types is activated."),
			   _("\
This is related to the encoding used by the GNAT compiler.  The debugger\n\
should normally trust the contents of PAD types, but certain older versions\n\
of GNAT have a bug that sometimes causes the information in the PAD type\n\
to be incorrect.  Turning this setting \"off\" allows the debugger to\n\
work around this bug.  It is always safe to turn this option \"off\", but\n\
this incurs a slight performance penalty, so it is recommended to NOT change\n\
this option to \"off\" unless necessary."),
			    NULL, NULL, &set_ada_list, &show_ada_list);

  add_setshow_boolean_cmd ("print-signatures", class_vars,
			   &print_signatures, _("\
Enable or disable the output of formal and return types for functions in the \
overloads selection menu."), _("\
Show whether the output of formal and return types for functions in the \
overloads selection menu is activated."),
			   NULL, NULL, NULL, &set_ada_list, &show_ada_list);

  ada_source_charset = gnat_source_charsets[0];
  add_setshow_enum_cmd ("source-charset", class_files,
			gnat_source_charsets,
			&ada_source_charset,  _("\
Set the Ada source character set."), _("\
Show the Ada source character set."), _("\
The character set used for Ada source files.\n\
This must correspond to the '-gnati' or '-gnatW' option passed to GNAT."),
			nullptr, nullptr,
			&set_ada_list, &show_ada_list);

  add_catch_command ("exception", _("\
Catch Ada exceptions, when raised.\n\
Usage: catch exception [ARG] [if CONDITION]\n\
Without any argument, stop when any Ada exception is raised.\n\
If ARG is \"unhandled\" (without the quotes), only stop when the exception\n\
being raised does not have a handler (and will therefore lead to the task's\n\
termination).\n\
Otherwise, the catchpoint only stops when the name of the exception being\n\
raised is the same as ARG.\n\
CONDITION is a boolean expression that is evaluated to see whether the\n\
exception should cause a stop."),
		     catch_ada_exception_command,
		     catch_ada_completer,
		     CATCH_PERMANENT,
		     CATCH_TEMPORARY);

  add_catch_command ("handlers", _("\
Catch Ada exceptions, when handled.\n\
Usage: catch handlers [ARG] [if CONDITION]\n\
Without any argument, stop when any Ada exception is handled.\n\
With an argument, catch only exceptions with the given name.\n\
CONDITION is a boolean expression that is evaluated to see whether the\n\
exception should cause a stop."),
		     catch_ada_handlers_command,
		     catch_ada_completer,
		     CATCH_PERMANENT,
		     CATCH_TEMPORARY);
  add_catch_command ("assert", _("\
Catch failed Ada assertions, when raised.\n\
Usage: catch assert [if CONDITION]\n\
CONDITION is a boolean expression that is evaluated to see whether the\n\
exception should cause a stop."),
		     catch_assert_command,
		     NULL,
		     CATCH_PERMANENT,
		     CATCH_TEMPORARY);

  add_info ("exceptions", info_exceptions_command,
	    _("\
List all Ada exception names.\n\
Usage: info exceptions [REGEXP]\n\
If a regular expression is passed as an argument, only those matching\n\
the regular expression are listed."));

  add_setshow_prefix_cmd ("ada", class_maintenance,
			  _("Set Ada maintenance-related variables."),
			  _("Show Ada maintenance-related variables."),
			  &maint_set_ada_cmdlist, &maint_show_ada_cmdlist,
			  &maintenance_set_cmdlist, &maintenance_show_cmdlist);

  add_setshow_boolean_cmd
    ("ignore-descriptive-types", class_maintenance,
     &ada_ignore_descriptive_types_p,
     _("Set whether descriptive types generated by GNAT should be ignored."),
     _("Show whether descriptive types generated by GNAT should be ignored."),
     _("\
When enabled, the debugger will stop using the DW_AT_GNAT_descriptive_type\n\
DWARF attribute."),
     NULL, NULL, &maint_set_ada_cmdlist, &maint_show_ada_cmdlist);

  decoded_names_store = htab_create_alloc (256, htab_hash_string,
					   htab_eq_string,
					   NULL, xcalloc, xfree);

  /* The ada-lang observers.  */
  gdb::observers::new_objfile.attach (ada_new_objfile_observer, "ada-lang");
  gdb::observers::free_objfile.attach (ada_free_objfile_observer, "ada-lang");
  gdb::observers::inferior_exit.attach (ada_inferior_exit, "ada-lang");
}
