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

   Copyright (C) 1992-2023 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"
#include "ax-gdb.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 registry<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 registry<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 ();
  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 (val->type () == type)
    return val;
  else
    {
      struct value *result;

      if (val->optimized_out ())
	result = value::allocate_optimized_out (type);
      else if (val->lazy ()
	       /* Be careful not to make a lazy not_lval value.  */
	       || (val->lval () != not_lval
		   && type->length () > val->type ()->length ()))
	result = value::allocate_lazy (type);
      else
	{
	  result = value::allocate (type);
	  val->contents_copy (result, 0, 0, type->length ());
	}
      result->set_component_location (val);
      result->set_bitsize (val->bitsize ());
      result->set_bitpos (val->bitpos ());
      if (result->lval () == lval_memory)
	result->set_address (val->address ());
      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 (t->length ());
  else
    return max_of_size (t->length ());
}

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

/* 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->target_type () == NULL)
	return type;
      type = type->target_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 ());

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

const char *
ada_main_name ()
{
  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.  If
   FOLD is true (the default), case-fold any ordinary symbol.  Symbols
   with <...> quoting are not folded in any case.  */

std::string
ada_encode (const char *decoded, bool fold)
{
  if (fold && 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 ());
  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 (val->type ());
  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, val->copy ());
  else
    return value_from_longest (data_type, val->address ());
}

/* 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 (ada_check_typedef (r)->target_type ());
    }
  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 (arr->type ());

  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 = arr->address ();

      return
	value_from_longest (lookup_pointer_type (bounds_type),
			    addr - bounds_type->length ());
    }

  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 = p_bounds->type ();

      if (p_bounds_type
	  && p_bounds_type->code () == TYPE_CODE_PTR)
	{
	  struct type *target_type = p_bounds_type->target_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 * ada_check_typedef (type->field (1).type ())->length ();
}

/* 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 (data_type->target_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 = arr->type ();

  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->field (0).type ()->length ();
}

/* 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->field (2 * i + which - 2).type ()->length ();
}

/* 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 ();
  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 ())->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 (arr->type ()))
    return decode_constrained_packed_array_type (arr->type ());

  if (!ada_is_array_descriptor_type (arr->type ()))
    return arr->type ();

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

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

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

      if (elt_type == NULL || arity == 0)
	return ada_check_typedef (arr->type ());

      descriptor = desc_bounds (arr);
      if (value_as_long (descriptor) == 0)
	return NULL;
      while (arity > 0)
	{
	  struct type *range_type = alloc_type_copy (arr->type ());
	  struct type *array_type = alloc_type_copy (arr->type ());
	  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, low->type (),
				    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 (arr->type ()))
	    {
	      /* 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 (arr->type ());
	      /* 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);

		  array_type->set_length ((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 (arr->type ()))
    {
      struct type *arrType = ada_type_of_array (arr, 1);

      if (arrType == NULL)
	return NULL;
      return value_cast (arrType, desc_data (arr)->copy ());
    }
  else if (ada_is_constrained_packed_array_type (arr->type ()))
    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 (arr->type ()))
    {
      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 (arr->type ()))
    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->field (0).type ()->target_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->field (0).type ()->target_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 ()),
				   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 = 0;
      new_type->set_length (0);
    }
  else
    {
      *elt_bits *= (high_bound - low_bound + 1);
      new_type->set_length ((*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 ();
  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->set_length (((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 (arr->type ())->code () == TYPE_CODE_PTR)
    arr = value_ind (arr);

  type = decode_constrained_packed_array_type (arr->type ());
  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 = arr->contents_for_printing ().data ();
  CORE_ADDR address = arr->address ();
  gdb::array_view<const gdb_byte> view
    = gdb::make_array_view (valaddr, type->length ());
  type = resolve_dynamic_type (type, view, address);
  recursively_update_array_bitsize (type);

  if (type_byte_order (arr->type ()) == BFD_ENDIAN_BIG
      && ada_is_modular_type (arr->type ()))
    {
       /* 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 (arr->type ()) - 1;
      bit_size = 0;
      while (mod > 0)
	{
	  bit_size += 1;
	  mod >>= 1;
	}
      bit_pos = HOST_CHAR_BIT * arr->type ()->length () - 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 (arr->type ());
  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 (elt_type->target_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 = obj->contents ().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 () < (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 () * HOST_CHAR_BIT;
	}
    }

  if (obj == NULL)
    {
      v = value::allocate (type);
      src = valaddr + offset;
    }
  else if (obj->lval () == lval_memory && obj->lazy ())
    {
      int src_len = (bit_size + bit_offset + HOST_CHAR_BIT - 1) / 8;
      gdb_byte *buf;

      v = value_at (type, obj->address () + offset);
      buf = (gdb_byte *) alloca (src_len);
      read_memory (v->address (), buf, src_len);
      src = buf;
    }
  else
    {
      v = value::allocate (type);
      src = obj->contents ().data () + offset;
    }

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

      v->set_component_location (obj);
      v->set_bitpos (bit_offset + obj->bitpos ());
      v->set_bitsize (bit_size);
      if (v->bitpos () >= HOST_CHAR_BIT)
	{
	  ++new_offset;
	  v->set_bitpos (v->bitpos () - HOST_CHAR_BIT);
	}
      v->set_offset (new_offset);

      /* Also set the parent value.  This is needed when trying to
	 assign a new value (in inferior memory).  */
      v->set_parent (obj);
    }
  else
    v->set_bitsize (bit_size);
  unpacked = v->contents_writeable ().data ();

  if (bit_size == 0)
    {
      memset (unpacked, 0, type->length ());
      return v;
    }

  if (staging.size () == type->length ())
    {
      /* 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 (),
			      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 = toval->type ();
  int bits = toval->bitsize ();

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

  if (ada_is_direct_array_type (toval->type ()))
    toval = ada_coerce_to_simple_array (toval);
  if (ada_is_direct_array_type (fromval->type ()))
    fromval = ada_coerce_to_simple_array (fromval);

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

  if (toval->lval () == lval_memory
      && bits > 0
      && (type->code () == TYPE_CODE_FLT
	  || type->code () == TYPE_CODE_STRUCT))
    {
      int len = (toval->bitpos ()
		 + 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 = toval->address ();

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

      read_memory (to_addr, buffer, len);
      from_size = fromval->bitsize ();
      if (from_size == 0)
	from_size = fromval->type ()->length () * 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 (fromval->type ()))
	from_offset = from_size - bits;
      copy_bitwise (buffer, toval->bitpos (),
		    fromval->contents ().data (), from_offset,
		    bits, is_big_endian);
      write_memory_with_notification (to_addr, buffer, len);

      val = toval->copy ();
      memcpy (val->contents_raw ().data (),
	      fromval->contents ().data (),
	      type->length ());
      val->deprecated_set_type (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)  (component->address () - container->address ());
  int bit_offset_in_container =
    component->bitpos () - container->bitpos ();
  int bits;

  val = value_cast (component->type (), val);

  if (component->bitsize () == 0)
    bits = TARGET_CHAR_BIT * component->type ()->length ();
  else
    bits = component->bitsize ();

  if (type_byte_order (container->type ()) == BFD_ENDIAN_BIG)
    {
      int src_offset;

      if (is_scalar_type (check_typedef (component->type ())))
	src_offset
	  = component->type ()->length () * TARGET_CHAR_BIT - bits;
      else
	src_offset = 0;
      copy_bitwise ((container->contents_writeable ().data ()
		     + offset_in_container),
		    container->bitpos () + bit_offset_in_container,
		    val->contents ().data (), src_offset, bits, 1);
    }
  else
    copy_bitwise ((container->contents_writeable ().data ()
		   + offset_in_container),
		  container->bitpos () + bit_offset_in_container,
		  val->contents ().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 (elt->type ());
  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 = elt_type->target_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)
	  && elt->type ()->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.  */
	  elt->deprecated_set_type (saved_elt_type);
	}

      elt_type = ada_check_typedef (elt->type ());
    }

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

  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 ()),
			arr->copy ());
      get_discrete_bounds (type->index_type (), &lwb, &upb);
      arr = value_ptradd (arr, pos_atr (ind[k]) - lwb);
      type = type->target_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 = type0->index_type ()->target_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, type0->target_type (), 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 = type0->target_type ()->length ();

  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 (array->type ());
  struct type *base_index_type = type->index_type ()->target_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 (), 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 ());
      }

  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 (p_array_type->target_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 ();
	  /* A multi-dimensional array is represented using a sequence
	     of array types.  If one of these types has a name, then
	     it is not another dimension of the outer array, but
	     rather the element type of the outermost array.  */
	  if (type->name () != nullptr)
	    break;
	  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 ();
	}
      result_type = ada_check_typedef (type)->index_type ()->target_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 = arr_type->target_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 (elt_type->target_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 (arr->type ())->code () == TYPE_CODE_PTR)
    arr = value_ind (arr);
  arr_type = arr->enclosing_type ();

  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 (arr->type ())->code () == TYPE_CODE_PTR)
    arr = value_ind (arr);
  arr_type = arr->enclosing_type ();

  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 = index_type->target_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, arr_type0->index_type ()->target_type (), low,
	 high < low ? low - 1 : high);
  struct type *elt_type = ada_array_element_type (arr_type0, 1);

  return value::allocate (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 () != NULL
      && type->target_type ()->code () != TYPE_CODE_VOID)
    {
      gdb_printf (stream, " return ");
      ada_print_type (type->target_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 = "> ";

  std::string buffer;
  args = command_line_input (buffer, 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 = ftype->target_type ();
  if (atype->code () == TYPE_CODE_REF)
    atype = atype->target_type ();

  switch (ftype->code ())
    {
    default:
      return ftype->code () == atype->code ();
    case TYPE_CODE_PTR:
      if (atype->code () != TYPE_CODE_PTR)
	return 0;
      atype = atype->target_type ();
      /* This can only happen if the actual argument is 'null'.  */
      if (atype->code () == TYPE_CODE_INT && atype->length () == 0)
	return 1;
      return ada_type_match (ftype->target_type (), 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 (actuals[i]->type ());

	  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 (func_type->target_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 ()
		  || numeric_type_p (type->target_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 ()
		  || integer_type_p (type->target_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, as defined in the Ada Reference Manual.
   This essentially means one of (INT, RANGE, ENUM) -- but note that
   "enum" includes character and boolean as well.  */

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:
	case TYPE_CODE_CHAR:
	  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 (args[0]->type ());
  struct type *type1 =
    (args[1] == NULL) ? NULL : ada_check_typedef (args[1]->type ());

  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 (val->lval () == not_lval
      || val->lval () == lval_internalvar)
    {
      int len = ada_check_typedef (val->type ())->length ();
      const CORE_ADDR addr =
	value_as_long (value_allocate_space_in_inferior (len));

      val->set_lval (lval_memory);
      val->set_address (addr);
      write_memory (addr, val->contents ().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 (arg->type ());
  if (t->code () == TYPE_CODE_REF)
    {
      t1 = t->target_type ();
      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 = t->target_type ();
      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 = ada_value_ind (arg)->address ();
      else
	address = ada_coerce_ref (arg)->address ();

      /* 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 (t1->target_type (), 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 = arg->type ();

      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 (actual->type ());
  struct type *formal_type = ada_check_typedef (formal_type0);
  struct type *formal_target =
    formal_type->code () == TYPE_CODE_PTR
    ? ada_check_typedef (formal_type->target_type ()) : formal_type;
  struct type *actual_target =
    actual_type->code () == TYPE_CODE_PTR
    ? ada_check_typedef (actual_type->target_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 (actual->lval () != lval_memory)
	    {
	      struct value *val;

	      actual_type = ada_check_typedef (actual->type ());
	      val = value::allocate (actual_type);
	      copy (actual->contents (), val->contents_raw ());
	      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 = value::allocate (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 ();
  gdb_byte *buf = (gdb_byte *) alloca (len);
  CORE_ADDR addr;

  addr = value->address ();
  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 = value::allocate (desc_type);
  struct value *bounds = value::allocate (bounds_type);
  int i;

  for (i = ada_array_arity (ada_check_typedef (arr->type ()));
       i > 0; i -= 1)
    {
      modify_field (bounds->type (),
		    bounds->contents_writeable ().data (),
		    ada_array_bound (arr, i, 0),
		    desc_bound_bitpos (bounds_type, i, 0),
		    desc_bound_bitsize (bounds_type, i, 0));
      modify_field (bounds->type (),
		    bounds->contents_writeable ().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 (descriptor->type (),
		descriptor->contents_writeable ().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 (descriptor->type (),
		descriptor->contents_writeable ().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 objfile *objfile)
{
  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);

  gdbarch_iterate_over_objfiles_in_search_order
    (objfile != NULL ? objfile->arch () : target_gdbarch (),
     [&result, lookup_name, match_name] (struct objfile *obj)
       {
	 for (minimal_symbol *msymbol : obj->msymbols ())
	   {
	     if (match_name (msymbol->linkage_name (), lookup_name, nullptr)
		 && msymbol->type () != mst_solib_trampoline)
	       {
		 result.minsym = msymbol;
		 result.objfile = obj;
		 return 1;
	       }
	   }

	 return 0;
       }, objfile);

  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 = current_block->linkage_function ();
  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, arg_sym, 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, sym, 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->get_using ();
       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 {};

  return candidates[0];
}


/* 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)
{
  /* A matching argument symbol, if any.  */
  struct symbol *arg_sym;
  /* Set true when we find a matching non-argument symbol.  */
  bool found_sym;

  arg_sym = NULL;
  found_sym = false;
  for (struct symbol *sym : block_iterator_range (block, &lookup_name))
    {
      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, sym, 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, arg_sym, 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 ();

      for (struct symbol *sym : block_iterator_range (block))
      {
	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, sym, 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, arg_sym, 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 ()->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 ());

      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 (val->type (), "_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 ());
  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 = obj->type ();

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

  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 = obj->address () + 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 (tag->type ()))
    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 = parent_type->target_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)
	      && (field_type->target_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 = type0->target_type ();
  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 || arg1->bitpos () != 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,
					     arg1->contents ().data (),
					     offset + bit_pos / 8,
					     bit_pos % 8, bit_size, type);
    }
  else
    return arg1->primitive_field (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 ();
      }

  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 (val->type (), 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 (val0->type ()->code () == TYPE_CODE_REF)
    {
      struct value *val = val0;

      val = coerce_ref (val);

      if (ada_is_tagged_type (val->type (), 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->set_length (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 VAL->type () 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 *dval;
  struct type *rtype;
  int nfields, bit_len;
  int variant_field;
  long off;
  int fld_bit_len;
  int f;

  scoped_value_mark mark;

  /* 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->field (f).type ()->target_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 = dval->type ();
	    }
	  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 = rtype->field (f).type ()->length () * 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 =
		ada_check_typedef (field_type)->length () * TARGET_CHAR_BIT;
	    }
	}
      if (off + fld_bit_len > bit_len)
	bit_len = off + fld_bit_len;
      off += fld_bit_len;
      rtype->set_length (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 = dval->type ();
	}
      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 =
	    rtype->field (variant_field).type ()->length () * TARGET_CHAR_BIT;
	  if (off + fld_bit_len > bit_len)
	    bit_len = off + fld_bit_len;

	  rtype->set_length
	    (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 () <= 0)
    {
      if (rtype->name ())
	warning (_("Invalid type size for `%s' detected: %s."),
		 rtype->name (), pulongest (type->length ()));
      else
	warning (_("Invalid type size for <unnamed> detected: %s."),
		 pulongest (type->length ()));
    }
  else
    rtype->set_length (align_up (rtype->length (), type->length ()));

  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 (type0->target_type () != NULL)
    return type0->target_type ();

  /* 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.  */
  type0->set_target_type (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 (field_type->target_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 = alloc_type_copy (type0);
	      type0->set_target_type (type);
	      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->set_length (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 *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;

  scoped_value_mark mark;
  if (dval0 == NULL)
    {
      dval = value_from_contents_and_address (type, valaddr, address);
      type = dval->type ();
    }
  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);
  rtype->set_length (type->length ());

  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;
      rtype->set_length (rtype->length () + branch_type->length ());
    }

  rtype->set_length (rtype->length ()
		     - type->field (variant_field).type ()->length ());

  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 = var_type0->target_type ();
  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, dval->type ()))
      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
      (var_type->field (which).type ()->target_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 (this_layer->target_type ());
    }

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

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

      /* 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 = elt_type0->target_type ();
	}
    }

  /* 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 = result->length () / result->target_type ()->length ();
      int elt_bitsize = TYPE_FIELD_BITSIZE (type0, 0);

      TYPE_FIELD_BITSIZE (result, 0) = TYPE_FIELD_BITSIZE (type0, 0);
      result->set_length (len * elt_bitsize / HOST_CHAR_BIT);
      if (result->length () * HOST_CHAR_BIT < len * elt_bitsize)
	result->set_length (result->length () + 1);
    }

  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 = obj->type ();
	    if (real_type != NULL)
	      return to_fixed_record_type
		(real_type, NULL,
		 ada_tag_value_at_base_address (obj)->address (), 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 && fixed_record_type->length () != size)
	      {
		fixed_record_type = copy_type (fixed_record_type);
		fixed_record_type->set_length (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 (val0->lval () != 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, val0->contents ().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 (val->type (), val->address (), 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 = val->type ();

  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 ();
  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 (arg->type ()))
    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 real_type_namer->field (0).type ()->target_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 TYPE is a dynamic type, return the base type.  Otherwise, if
   there is no parallel type, return nullptr.  */

static struct type *
find_base_type (struct type *type)
{
  struct type *raw_real_type
    = ada_check_typedef (ada_get_base_type (type));

  /* No parallel XVS or XVE type.  */
  if (type == raw_real_type
      && ada_find_parallel_type (type, "___XVE") == nullptr)
    return nullptr;

  return raw_real_type;
}

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

  if (ada_is_aligner_type (type))
    {
      struct value *v = ada_value_struct_elt (val, "F", 0);
      struct type *val_type = ada_check_typedef (v->type ());

      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 = find_base_type (type);
      if (raw_real_type == nullptr)
	return val;

      return
	coerce_unspec_val_to_type
	(val, ada_to_fixed_type (raw_real_type, 0,
				 val->address (),
				 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 ();
  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 ()));
  gdb_assert (val->type ()->code () == TYPE_CODE_ARRAY);
  gdb_assert (is_integral_type (val->type ()->target_type ()));
  gdb_assert (type->target_type ()->length ()
	      > val->type ()->target_type ()->length ());

  if (!get_array_bounds (type, &lo, &hi))
    error (_("unable to determine array bounds"));

  value *res = value::allocate (type);
  gdb::array_view<gdb_byte> res_contents = res->contents_writeable ();

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

      copy (elt->contents_all (), 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 = val->type ();

  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 = val->type ();
    }

  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 ())
	  && is_integral_type (type2->target_type ())
	  && type2->target_type ()->length () < type->target_type ()->length ())
	{
	  /* Allow implicit promotion of the array elements to
	     a wider type.  */
	  return ada_promote_array_of_integrals (type, val);
	}

      if (type2->target_type ()->length () != type->target_type ()->length ())
	error (_("Incompatible types in assignment"));
      val->deprecated_set_type (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 (arg1->type ()));
  type2 = get_base_type (ada_check_typedef (arg2->type ()));

  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 = value::allocate (type1);
  store_unsigned_integer (val->contents_raw ().data (),
			  val->type ()->length (),
			  type_byte_order (type1), v);
  return val;
}

static int
ada_value_equal (struct value *arg1, struct value *arg2)
{
  if (ada_is_direct_array_type (arg1->type ())
      || ada_is_direct_array_type (arg2->type ()))
    {
      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 (arg1->type ());
      arg2_type = ada_check_typedef (arg2->type ());

      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 (arg1_type->length () == arg2_type->length ()
	      && memcmp (arg1->contents ().data (),
			 arg2->contents ().data (),
			 arg1_type->length ()) == 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 (lhs->type ());

  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, lhs->type ());
      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 (container->type ()))
    container = ada_coerce_to_simple_array (container);
  lhs = ada_coerce_ref (lhs);
  if (!lhs->deprecated_modifiable ())
    error (_("Left operand of assignment is not a modifiable lvalue."));

  lhs_type = check_typedef (lhs->type ());
  if (ada_is_direct_array_type (lhs_type))
    {
      lhs = ada_coerce_to_simple_array (lhs);
      lhs_type = check_typedef (lhs->type ());
      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 (lhs->type ()))
    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, lhs->type (), 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 = arg1->type ();
  if (arg1->lval () == lval_internalvar)
    type = NULL;
  value *arg2 = std::get<1> (m_storage)->evaluate (type, exp, noside);
  if (noside == EVAL_AVOID_SIDE_EFFECTS)
    return arg1;
  if (arg1->lval () == lval_internalvar)
    {
      /* Nothing.  */
    }
  else
    arg2 = coerce_for_assign (arg1->type (), 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 (arg2->type ()))
    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 = arg1->type ();

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

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

/* 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 (arg1->type (), 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 (arg1->type (), 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 (array->type ()->code () == TYPE_CODE_REF
      && ada_is_aligner_type (array->type ()->target_type ()))
    array->type ()->set_target_type
      (ada_aligned_type (array->type ()->target_type ()));

  if (ada_is_any_packed_array_type (array->type ()))
    error (_("cannot slice a packed array"));

  /* If this is a reference to an array or an array lvalue,
     convert to a pointer.  */
  if (array->type ()->code () == TYPE_CODE_REF
      || (array->type ()->code () == TYPE_CODE_ARRAY
	  && array->lval () == lval_memory))
    array = value_addr (array);

  if (noside == EVAL_AVOID_SIDE_EFFECTS
      && ada_is_array_descriptor_type (ada_check_typedef
				       (array->type ())))
    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 (array->type ()->code () == TYPE_CODE_PTR
	 && (array->type ()->target_type ()->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 (array->type ()))
    error (_("cannot take slice of non-array"));

  if (ada_check_typedef (array->type ())->code ()
      == TYPE_CODE_PTR)
    {
      struct type *type0 = ada_check_typedef (array->type ());

      if (high_bound < low_bound || noside == EVAL_AVOID_SIDE_EFFECTS)
	return empty_array (type0->target_type (), low_bound, high_bound);
      else
	{
	  struct type *arr_type0 =
	    to_fixed_array_type (type0->target_type (), 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 (array->type (), 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 (arg2->type (), n, "range");
  if (!type)
    type = arg1->type ();

  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 = arg1->type ();

      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 (arg1->type ()))
	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 (arg1->type (), 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 (arg1->type (), 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 (arg1->type (), not_lval);
  else
    {
      /* For integer exponentiation operations,
	 only promote the first argument.  */
      if (is_integral_type (arg2->type ()))
	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;
}

void
ada_wrapped_operation::do_generate_ax (struct expression *exp,
				       struct agent_expr *ax,
				       struct axs_value *value,
				       struct type *cast_type)
{
  std::get<0> (m_storage)->generate_ax (exp, ax, value, cast_type);

  struct type *type = value->type;
  if (ada_is_aligner_type (type))
    error (_("Aligner types cannot be handled in agent expressions"));
  else if (find_base_type (type) != nullptr)
    error (_("Dynamic types cannot be handled in agent expressions"));
}

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 (char_type->length ())
    {
    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 = value::allocate (stringtype);
	memcpy (val->contents_raw ().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 (char_type->length ()));
    }

  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)
			       / char_type->length ());
  struct value *val = value::allocate (stringtype);
  memcpy (val->contents_raw ().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 (rhs->type (), 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 (rhs->type ());
      struct type *elt_type = nullptr;
      if (rhs_type->code () == TYPE_CODE_ARRAY)
	elt_type = rhs_type->target_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 (lhs->type (), 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 (lhs->type ());
      struct type *elt_type = nullptr;
      if (lhs_type->code () == TYPE_CODE_ARRAY)
	elt_type = lhs_type->target_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 (arg1->type ()->code () == TYPE_CODE_PTR)
    return (value_from_longest
	    (arg1->type (),
	     do_op (value_as_long (arg1), value_as_long (arg2))));
  if (arg2->type ()->code () == TYPE_CODE_PTR)
    return (value_from_longest
	    (arg2->type (),
	     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 = arg1->type ();
  while (type->code () == TYPE_CODE_REF)
    type = type->target_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 = tem->type ();
    }
  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 (val->lval () == lval_memory)
    {
      if (val->lazy ())
	val->fetch_lazy ();
      val->set_lval (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 (val->lval () == lval_memory)
    {
      if (val->lazy ())
	val->fetch_lazy ();
      val->set_lval (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 (), 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;
}

void
ada_var_value_operation::do_generate_ax (struct expression *exp,
					 struct agent_expr *ax,
					 struct axs_value *value,
					 struct type *cast_type)
{
  symbol *sym = std::get<0> (m_storage).symbol;

  if (sym->domain () == UNDEF_DOMAIN)
    error (_("Unexpected unresolved symbol, %s, during evaluation"),
	   sym->print_name ());

  struct type *type = static_unwrap_type (sym->type ());
  if (ada_is_tagged_type (type, 0)
      || (type->code () == TYPE_CODE_REF
	  && ada_is_tagged_type (type->target_type (), 0)))
    error (_("Tagged types cannot be handled in agent expressions"));

  if ((type->code () == TYPE_CODE_STRUCT
       && dynamic_template_type (type) != NULL)
      || (type->code () == TYPE_CODE_UNION
	  && ada_find_parallel_type (type, "___XVU") != NULL))
    error (_("Dynamic types cannot be handled in agent expressions"));

  var_value_operation::do_generate_ax (exp, ax, value, cast_type);
}

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 (arg1->type ());
  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 (), 0))
	    {
	      arg1 = std::get<0> (m_storage)->evaluate (nullptr, exp,
							EVAL_NORMAL);
	      type = ada_value_ind (arg1)->type ();
	    }
	  else
	    {
	      type = to_static_fixed_type
		(ada_aligned_type
		 (ada_check_typedef (type->target_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 (arg1->type ());

  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 = arg1->type ();

      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 = ada_to_fixed_value (arg1)->type ();
	    }
	}
      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 (callee->type ())))
    callee = ada_coerce_to_simple_array (callee);
  else if (callee->type ()->code () == TYPE_CODE_ARRAY
	   && TYPE_FIELD_BITSIZE (callee->type (), 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 (callee->type ()->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 (callee->type ()->code () == TYPE_CODE_ARRAY
	   && callee->lval () == lval_memory)
    callee = value_addr (callee);

  struct type *type = ada_check_typedef (callee->type ());

  /* 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 ())->code ())
	{
	case TYPE_CODE_FUNC:
	  type = ada_check_typedef (type->target_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 ());
	  break;
	default:
	  error (_("cannot subscript or call something of type `%s'"),
		 ada_type_name (callee->type ()));
	  break;
	}
    }

  switch (type->code ())
    {
    case TYPE_CODE_FUNC:
      if (noside == EVAL_AVOID_SIDE_EFFECTS)
	{
	  if (type->target_type () == NULL)
	    error_call_unknown_return_type (NULL);
	  return value::allocate (type->target_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 (), 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 (v->type ()))
    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, dval->type ());
  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 = raw_type->target_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->set_length (raw_type->length ());
      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 ());

  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 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 (frame_info_ptr 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 (frame_info_ptr 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;
  frame_info_ptr 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 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 (_("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 = e_msg_val->type ()->length ();

  /* 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 (e_msg_val->address (), (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)
{
  CORE_ADDR result = 0;

  try
    {
      result = ada_exception_name_addr_1 (ex);
    }

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

struct ada_catchpoint : public code_breakpoint
{
  ada_catchpoint (struct gdbarch *gdbarch_,
		  enum ada_exception_catchpoint_kind kind,
		  struct symtab_and_line sal,
		  const char *addr_string_,
		  bool tempflag,
		  bool enabled,
		  bool from_tty)
    : code_breakpoint (gdbarch_, bp_catchpoint),
      m_kind (kind)
  {
    add_location (sal);

    /* Unlike most code_breakpoint types, Ada catchpoints are
       pspace-specific.  */
    gdb_assert (sal.pspace != nullptr);
    this->pspace = sal.pspace;

    if (from_tty)
      {
	struct gdbarch *loc_gdbarch = get_sal_arch (sal);
	if (!loc_gdbarch)
	  loc_gdbarch = gdbarch;

	describe_other_breakpoints (loc_gdbarch,
				    sal.pspace, sal.pc, sal.section, -1);
	/* FIXME: brobecker/2006-12-28: Actually, re-implement a special
	   version for exception catchpoints, because two catchpoints
	   used for different exception names will use the same address.
	   In this case, a "breakpoint ... also set at..." warning is
	   unproductive.  Besides, the warning phrasing is also a bit
	   inappropriate, we should use the word catchpoint, and tell
	   the user what type of catchpoint it is.  The above is good
	   enough for now, though.  */
      }

    enable_state = enabled ? bp_enabled : bp_disabled;
    disposition = tempflag ? disp_del : disp_donttouch;
    locspec = string_to_location_spec (&addr_string_,
				       language_def (language_ada));
    language = language_ada;
  }

  struct bp_location *allocate_location () override;
  void re_set () override;
  void check_status (struct bpstat *bs) override;
  enum print_stop_action print_it (const bpstat *bs) const override;
  bool print_one (bp_location **) const override;
  void print_mention () const override;
  void print_recreate (struct ui_file *fp) const 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;
};

/* An instance of this type is used to represent an Ada catchpoint
   breakpoint location.  */

class ada_catchpoint_location : public bp_location
{
public:
  explicit ada_catchpoint_location (ada_catchpoint *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;
};

/* 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->code_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
    {
      scoped_value_mark mark;
      stop = value_true (evaluate_expression (ada_loc->excep_cond_expr.get ()));
    }
  catch (const gdb_exception_error &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 (const bpstat *bs) const
{
  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 ");
  print_num_locno (bs, uiout);
  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);
	  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 (bp_location **last_loc) const
{ 
  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 (_("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 () const
{
  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 (_("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) const
{
  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 (_("unexpected catchpoint type"));
    }
  print_recreate_thread (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 (_("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 enabled,
				 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 (gdbarch, ex_kind, sal, addr_string.c_str (),
			 tempflag, enabled, 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)
	{
	  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);

	  /* Iterate over all objfiles irrespective of scope or linker
	     namespaces so we get all exceptions anywhere in the
	     progspace.  */
	  for (objfile *objfile : current_program_space->objfiles ())
	    {
	      for (minimal_symbol *msymbol : objfile->msymbols ())
		{
		  if (match_name (msymbol->linkage_name (), lookup_name,
				  nullptr)
		      && msymbol->type () != mst_solib_trampoline)
		    {
		      ada_exc_info info
			= {name, msymbol->value_address (objfile)};

		      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,
			       frame_info_ptr frame,
			       std::vector<ada_exc_info> *exceptions)
{
  const struct block *block = get_frame_block (frame, 0);

  while (block != 0)
    {
      for (struct symbol *sym : block_iterator_range (block))
	{
	  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);

  /* Iterate over all objfiles irrespective of scope or linker namespaces
     so we get all exceptions anywhere in the progspace.  */
  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);

	      for (struct symbol *sym : block_iterator_range (b))
		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,
				frame_info_ptr 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 = system_addr_ptr->length ();
    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
  {
    const struct block *b, *surrounding_static_block = 0;

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

	for (struct symbol *sym : block_iterator_range (b))
	  {
	    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 ();
	    for (struct symbol *sym : block_iterator_range (b))
	      {
		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;
	    for (struct symbol *sym : block_iterator_range (b))
	      {
		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 (check_typedef (type)->target_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 == nullptr
			      ? nullptr
			      : block->static_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 ();
	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");
}
