[gdb/symtab] Add get/set functions for per_cu->lang/unit_type
[binutils-gdb.git] / gdb / ada-lang.c
index d0374780b9891e9d3018409796d15c9647986d12..93e0c67613f0a927416d5618abacce71013b65de 100644 (file)
@@ -1,6 +1,6 @@
 /* Ada language support routines for GDB, the GNU debugger.
 
-   Copyright (C) 1992-2021 Free Software Foundation, Inc.
+   Copyright (C) 1992-2022 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -20,7 +20,7 @@
 
 #include "defs.h"
 #include <ctype.h>
-#include "gdb_regex.h"
+#include "gdbsupport/gdb_regex.h"
 #include "frame.h"
 #include "symtab.h"
 #include "gdbtypes.h"
@@ -35,7 +35,7 @@
 #include "breakpoint.h"
 #include "gdbcore.h"
 #include "hashtab.h"
-#include "gdb_obstack.h"
+#include "gdbsupport/gdb_obstack.h"
 #include "ada-lang.h"
 #include "completer.h"
 #include "ui-out.h"
@@ -49,6 +49,7 @@
 #include "typeprint.h"
 #include "namespace.h"
 #include "cli/cli-style.h"
+#include "cli/cli-decode.h"
 
 #include "value.h"
 #include "mi/mi-common.h"
@@ -58,6 +59,7 @@
 #include "gdbsupport/byte-vector.h"
 #include <algorithm>
 #include "ada-exp.h"
+#include "charset.h"
 
 /* Define whether or not the C operator '/' truncates towards zero for
    differently signed operands (truncation direction is undefined in C).
@@ -95,8 +97,6 @@ static struct type *desc_index_type (struct type *, int);
 
 static int desc_arity (struct type *);
 
-static int ada_type_match (struct type *, struct type *, int);
-
 static int ada_args_match (struct symbol *, struct value **, int);
 
 static struct value *make_array_descriptor (struct type *, struct value *);
@@ -210,6 +210,38 @@ static symbol_name_matcher_ftype *ada_get_symbol_name_matcher
 
 \f
 
+/* 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"
+};
+
+\f
+
 /* The result of a symbol lookup to be stored in our symbol cache.  */
 
 struct cache_entry
@@ -248,9 +280,6 @@ struct ada_symbol_cache
   struct cache_entry *root[HASH_SIZE] {};
 };
 
-/* Maximum-sized dynamic type.  */
-static unsigned int varsize_limit;
-
 static const char ada_completer_word_break_characters[] =
 #ifdef VMS
   " \t\n!@#%^&*()+=|~`}{[]\";:?/,-";
@@ -469,7 +498,7 @@ ada_get_field_index (const struct type *type, const char *field_name,
   struct type *struct_type = check_typedef ((struct type *) type);
 
   for (fieldno = 0; fieldno < struct_type->num_fields (); fieldno++)
-    if (field_name_match (TYPE_FIELD_NAME (struct_type, fieldno), field_name))
+    if (field_name_match (struct_type->field (fieldno).name (), field_name))
       return fieldno;
 
   if (!maybe_missing)
@@ -525,10 +554,6 @@ coerce_unspec_val_to_type (struct value *val, struct type *type)
     {
       struct value *result;
 
-      /* Make sure that the object size is not unreasonable before
-        trying to allocate some memory for it.  */
-      ada_ensure_varsize_limit (type);
-
       if (value_optimized_out (val))
        result = allocate_optimized_out_value (type);
       else if (value_lazy (val)
@@ -590,17 +615,6 @@ lim_warning (const char *format, ...)
   va_end (args);
 }
 
-/* Issue an error if the size of an object of type T is unreasonable,
-   i.e. if it would be a bad idea to allocate a value of this type in
-   GDB.  */
-
-void
-ada_ensure_varsize_limit (const struct type *type)
-{
-  if (TYPE_LENGTH (type) > varsize_limit)
-    error (_("object size is larger than varsize-limit"));
-}
-
 /* Maximum value of a SIZE-byte signed integer type.  */
 static LONGEST
 max_of_size (int size)
@@ -670,7 +684,7 @@ ada_discrete_type_high_bound (struct type *type)
          }
       }
     case TYPE_CODE_ENUM:
-      return TYPE_FIELD_ENUMVAL (type, type->num_fields () - 1);
+      return type->field (type->num_fields () - 1).loc_enumval ();
     case TYPE_CODE_BOOL:
       return 1;
     case TYPE_CODE_CHAR:
@@ -705,7 +719,7 @@ ada_discrete_type_low_bound (struct type *type)
          }
       }
     case TYPE_CODE_ENUM:
-      return TYPE_FIELD_ENUMVAL (type, 0);
+      return type->field (0).loc_enumval ();
     case TYPE_CODE_BOOL:
       return 0;
     case TYPE_CODE_CHAR:
@@ -805,7 +819,7 @@ ada_main_name (void)
 
   if (msym.minsym != NULL)
     {
-      CORE_ADDR main_program_name_addr = BMSYMBOL_VALUE_ADDRESS (msym);
+      CORE_ADDR main_program_name_addr = msym.value_address ();
       if (main_program_name_addr == 0)
        error (_("Invalid address for Ada main program name."));
 
@@ -847,6 +861,67 @@ const struct ada_opname_map ada_opname_table[] = {
   {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.  */
@@ -858,10 +933,21 @@ ada_encode_1 (const char *decoded, bool throw_errors)
     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;
@@ -884,23 +970,70 @@ ada_encode_1 (const char *decoded, bool throw_errors)
        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;
 }
 
-/* The "encoded" form of DECODED, according to GNAT conventions.  */
-
-std::string
-ada_encode (const char *decoded)
+/* 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)
 {
-  return ada_encode_1 (decoded, true);
+  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.  Result good
-   to next call.  */
+   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)
+ada_fold_name (gdb::string_view name, bool throw_on_error = false)
 {
   static std::string fold_storage;
 
@@ -908,14 +1041,120 @@ ada_fold_name (gdb::string_view name)
     fold_storage = gdb::to_string (name.substr (1, name.size () - 2));
   else
     {
-      fold_storage = gdb::to_string (name);
-      for (int i = 0; i < name.size (); i += 1)
-       fold_storage[i] = tolower (fold_storage[i]);
+      /* Why convert to UTF-32 and implement our own case-folding,
+        rather than convert to wchar_t and use the platform's
+        functions?  I'm glad you asked.
+
+        The main problem is that GNAT implements an unusual rule for
+        case folding.  For ASCII letters, letters in single-byte
+        encodings (such as ISO-8859-*), and Unicode letters that fit
+        in a single byte (i.e., code point is <= 0xff), the letter is
+        folded to lower case.  Other Unicode letters are folded to
+        upper case.
+
+        This rule means that the code must be able to examine the
+        value of the character.  And, some hosts do not use Unicode
+        for wchar_t, so examining the value of such characters is
+        forbidden.  */
+      auto_obstack storage;
+      try
+       {
+         convert_between_encodings
+           (host_charset (), HOST_UTF32,
+            (const gdb_byte *) name.data (),
+            name.length (), 1,
+            &storage, translit_none);
+       }
+      catch (const gdb_exception &)
+       {
+         if (throw_on_error)
+           throw;
+
+         static bool warned = false;
+
+         /* Converting to UTF-32 shouldn't fail, so if it doesn't, we
+            might like to know why.  */
+         if (!warned)
+           {
+             warned = true;
+             warning (_("could not convert '%s' from the host encoding (%s) to UTF-32.\n"
+                        "This normally should not happen, please file a bug report."),
+                      gdb::to_string (name).c_str (), host_charset ());
+           }
+
+         /* We don't try to recover from errors; just return the
+            original string.  */
+         fold_storage = gdb::to_string (name);
+         return fold_storage.c_str ();
+       }
+
+      bool is_utf8 = ada_source_charset == ada_utf8;
+      uint32_t *chars = (uint32_t *) obstack_base (&storage);
+      int num_chars = obstack_object_size (&storage) / sizeof (uint32_t);
+      for (int i = 0; i < num_chars; ++i)
+       {
+         const struct utf8_entry *entry = find_case_fold_entry (chars[i]);
+         if (entry != nullptr)
+           {
+             uint32_t low = chars[i] + entry->lower_delta;
+             if (!is_utf8 || low <= 0xff)
+               chars[i] = low;
+             else
+               chars[i] = chars[i] + entry->upper_delta;
+           }
+       }
+
+      /* Now convert back to ordinary characters.  */
+      auto_obstack reconverted;
+      try
+       {
+         convert_between_encodings (HOST_UTF32,
+                                    host_charset (),
+                                    (const gdb_byte *) chars,
+                                    num_chars * sizeof (uint32_t),
+                                    sizeof (uint32_t),
+                                    &reconverted,
+                                    translit_none);
+         obstack_1grow (&reconverted, '\0');
+         fold_storage = std::string ((const char *) obstack_base (&reconverted));
+       }
+      catch (const gdb_exception &)
+       {
+         if (throw_on_error)
+           throw;
+
+         static bool warned = false;
+
+         /* Converting back from UTF-32 shouldn't normally fail, but
+            there are some host encodings without upper/lower
+            equivalence.  */
+         if (!warned)
+           {
+             warned = true;
+             warning (_("could not convert the lower-cased variant of '%s'\n"
+                        "from UTF-32 to the host encoding (%s)."),
+                      gdb::to_string (name).c_str (), host_charset ());
+           }
+
+         /* We don't try to recover from errors; just return the
+            original string.  */
+         fold_storage = gdb::to_string (name);
+       }
     }
 
   return fold_storage.c_str ();
 }
 
+/* The "encoded" form of DECODED, according to GNAT conventions.  */
+
+std::string
+ada_encode (const char *decoded)
+{
+  if (decoded[0] != '<')
+    decoded = ada_fold_name (decoded);
+  return ada_encode_1 (decoded, true);
+}
+
 /* Return nonzero if C is either a digit or a lowercase alphabet character.  */
 
 static int
@@ -978,18 +1217,101 @@ ada_remove_po_subprogram_suffix (const char *encoded, int *len)
     *len = *len - 1;
 }
 
-/* If ENCODED follows the GNAT entity encoding conventions, then return
-   the decoded form of ENCODED.  Otherwise, return "<%s>" where "%s" is
-   replaced by ENCODED.  */
+/* 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)
+ada_decode (const char *encoded, bool wrap, bool operators)
 {
-  int i, j;
+  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".  */
@@ -1001,6 +1323,11 @@ ada_decode (const char *encoded)
      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
@@ -1010,6 +1337,8 @@ ada_decode (const char *encoded)
 
   len0 = strlen (encoded);
 
+  suffix = remove_compiler_suffix (encoded, &len0);
+
   ada_remove_trailing_digits (encoded, &len0);
   ada_remove_po_subprogram_suffix (encoded, &len0);
 
@@ -1046,10 +1375,6 @@ ada_decode (const char *encoded)
   if (len0 > 1 && startswith (encoded + len0 - 1, "B"))
     len0 -= 1;
 
-  /* Make decoded big enough for possible expansion by operator name.  */
-
-  decoded.resize (2 * len0 + 1, 'X');
-
   /* Remove trailing __{digit}+ or trailing ${digit}+.  */
 
   if (len0 > 1 && isdigit (encoded[len0 - 1]))
@@ -1067,14 +1392,14 @@ ada_decode (const char *encoded)
   /* 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, j = 0; i < len0 && !isalpha (encoded[i]); i += 1, j += 1)
-    decoded[j] = encoded[i];
+  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 (at_start_name && encoded[i] == 'O')
+      if (operators && at_start_name && encoded[i] == 'O')
        {
          int k;
 
@@ -1085,10 +1410,9 @@ ada_decode (const char *encoded)
                            op_len - 1) == 0)
                  && !isalnum (encoded[i + op_len]))
                {
-                 strcpy (&decoded.front() + j, ada_opname_table[k].decoded);
+                 decoded.append (ada_opname_table[k].decoded);
                  at_start_name = 0;
                  i += op_len;
-                 j += strlen (ada_opname_table[k].decoded);
                  break;
                }
            }
@@ -1174,6 +1498,32 @@ ada_decode (const char *encoded)
            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
@@ -1192,38 +1542,44 @@ ada_decode (const char *encoded)
       else if (i < len0 - 2 && encoded[i] == '_' && encoded[i + 1] == '_')
        {
         /* Replace '__' by '.'.  */
-         decoded[j] = '.';
+         decoded.push_back ('.');
          at_start_name = 1;
          i += 2;
-         j += 1;
        }
       else
        {
          /* It's a character part of the decoded name, so just copy it
             over.  */
-         decoded[j] = encoded[i];
+         decoded.push_back (encoded[i]);
          i += 1;
-         j += 1;
        }
     }
-  decoded.resize (j);
 
   /* Decoded names should never contain any uppercase character.
      Double-check this, and abort the decoding if we find one.  */
 
-  for (i = 0; i < decoded.length(); ++i)
-    if (isupper (decoded[i]) || decoded[i] == ' ')
-      goto Suppress;
+  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
@@ -1278,12 +1634,6 @@ ada_decode_symbol (const struct general_symbol_info *arg)
   return *resultp;
 }
 
-static char *
-ada_la_decode (const char *encoded, int options)
-{
-  return xstrdup (ada_decode (encoded).c_str ());
-}
-
 \f
 
                                /* Arrays */
@@ -1329,13 +1679,13 @@ ada_fixup_array_indexes_type (struct type *index_desc_type)
      is not equal to the field name.  */
   if (index_desc_type->field (0).type ()->name () != NULL
       && strcmp (index_desc_type->field (0).type ()->name (),
-                TYPE_FIELD_NAME (index_desc_type, 0)) == 0)
+                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 = TYPE_FIELD_NAME (index_desc_type, 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)
@@ -1486,7 +1836,7 @@ desc_bounds (struct value *arr)
 
   else if (is_thick_pntr (type))
     {
-      struct value *p_bounds = value_struct_elt (&arr, NULL, "P_BOUNDS", NULL,
+      struct value *p_bounds = value_struct_elt (&arr, {}, "P_BOUNDS", NULL,
                                               _("Bad GNAT array descriptor"));
       struct type *p_bounds_type = value_type (p_bounds);
 
@@ -1515,7 +1865,7 @@ desc_bounds (struct value *arr)
 static int
 fat_pntr_bounds_bitpos (struct type *type)
 {
-  return TYPE_FIELD_BITPOS (desc_base_type (type), 1);
+  return desc_base_type (type)->field (1).loc_bitpos ();
 }
 
 /* If TYPE is the type of an array-descriptor (fat pointer), the bit
@@ -1568,7 +1918,7 @@ desc_data (struct value *arr)
   if (is_thin_pntr (type))
     return thin_data_pntr (arr);
   else if (is_thick_pntr (type))
-    return value_struct_elt (&arr, NULL, "P_ARRAY", NULL,
+    return value_struct_elt (&arr, {}, "P_ARRAY", NULL,
                             _("Bad GNAT array descriptor"));
   else
     return NULL;
@@ -1581,7 +1931,7 @@ desc_data (struct value *arr)
 static int
 fat_pntr_data_bitpos (struct type *type)
 {
-  return TYPE_FIELD_BITPOS (desc_base_type (type), 0);
+  return desc_base_type (type)->field (0).loc_bitpos ();
 }
 
 /* If TYPE is the type of an array-descriptor (fat pointer), the bit
@@ -1608,7 +1958,7 @@ 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, NULL, bound_name, NULL,
+  return value_struct_elt (&bounds, {}, bound_name, NULL,
                           _("Bad GNAT array descriptor bounds"));
 }
 
@@ -1619,7 +1969,7 @@ desc_one_bound (struct value *bounds, int i, int which)
 static int
 desc_bound_bitpos (struct type *type, int i, int which)
 {
-  return TYPE_FIELD_BITPOS (desc_base_type (type), 2 * i + which - 2);
+  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
@@ -1858,7 +2208,6 @@ ada_coerce_to_simple_array (struct value *arr)
 
       if (arrVal == NULL)
        error (_("Bounds unavailable for null array pointer."));
-      ada_ensure_varsize_limit (TYPE_TARGET_TYPE (value_type (arrVal)));
       return value_ind (arrVal);
     }
   else if (ada_is_constrained_packed_array_type (value_type (arr)))
@@ -1928,6 +2277,8 @@ ada_is_unconstrained_packed_array_type (struct type *type)
       /* The structure's first field is a pointer to an array, so this
         fetches the array type.  */
       type = TYPE_TARGET_TYPE (type->field (0).type ());
+      if (type->code () == TYPE_CODE_TYPEDEF)
+       type = ada_typedef_target_type (type);
       /* Now we can see if the array elements are packed.  */
       return TYPE_FIELD_BITSIZE (type, 0) > 0;
     }
@@ -2160,7 +2511,7 @@ decode_constrained_packed_array (struct value *arr)
      bounds may be variable and were not passed to that function.  So,
      we further resolve the array bounds here and then update the
      sizes.  */
-  const gdb_byte *valaddr = value_contents_for_printing (arr);
+  const gdb_byte *valaddr = value_contents_for_printing (arr).data ();
   CORE_ADDR address = value_address (arr);
   gdb::array_view<const gdb_byte> view
     = gdb::make_array_view (valaddr, TYPE_LENGTH (type));
@@ -2171,9 +2522,9 @@ decode_constrained_packed_array (struct value *arr)
       && ada_is_modular_type (value_type (arr)))
     {
        /* This is a (right-justified) modular type representing a packed
-        array with no wrapper.  In order to interpret the value through
-        the (left-justified) packed array type we just built, we must
-        first left-justify it.  */
+         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;
 
@@ -2417,7 +2768,7 @@ ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr,
   if (obj == NULL)
     src = valaddr + offset;
   else
-    src = value_contents (obj) + offset;
+    src = value_contents (obj).data () + offset;
 
   if (is_dynamic_type (type))
     {
@@ -2467,7 +2818,7 @@ ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr,
   else
     {
       v = allocate_value (type);
-      src = value_contents (obj) + offset;
+      src = value_contents (obj).data () + offset;
     }
 
   if (obj != NULL)
@@ -2490,7 +2841,7 @@ ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr,
     }
   else
     set_value_bitsize (v, bit_size);
-  unpacked = value_contents_writeable (v);
+  unpacked = value_contents_writeable (v).data ();
 
   if (bit_size == 0)
     {
@@ -2560,12 +2911,13 @@ ada_value_assign (struct value *toval, struct value *fromval)
       if (is_big_endian && is_scalar_type (value_type (fromval)))
        from_offset = from_size - bits;
       copy_bitwise (buffer, value_bitpos (toval),
-                   value_contents (fromval), from_offset,
+                   value_contents (fromval).data (), from_offset,
                    bits, is_big_endian);
       write_memory_with_notification (to_addr, buffer, len);
 
       val = value_copy (toval);
-      memcpy (value_contents_raw (val), value_contents (fromval),
+      memcpy (value_contents_raw (val).data (),
+             value_contents (fromval).data (),
              TYPE_LENGTH (type));
       deprecated_set_value_type (val, type);
 
@@ -2613,14 +2965,16 @@ value_assign_to_component (struct value *container, struct value *component,
          = TYPE_LENGTH (value_type (component)) * TARGET_CHAR_BIT - bits;
       else
        src_offset = 0;
-      copy_bitwise (value_contents_writeable (container) + offset_in_container,
+      copy_bitwise ((value_contents_writeable (container).data ()
+                    + offset_in_container),
                    value_bitpos (container) + bit_offset_in_container,
-                   value_contents (val), src_offset, bits, 1);
+                   value_contents (val).data (), src_offset, bits, 1);
     }
   else
-    copy_bitwise (value_contents_writeable (container) + offset_in_container,
+    copy_bitwise ((value_contents_writeable (container).data ()
+                  + offset_in_container),
                  value_bitpos (container) + bit_offset_in_container,
-                 value_contents (val), 0, bits, 0);
+                 value_contents (val).data (), 0, bits, 0);
 }
 
 /* Determine if TYPE is an access to an unconstrained array.  */
@@ -2879,8 +3233,11 @@ ada_index_type (struct type *type, int n, const char *name)
       int i;
 
       for (i = 1; i < n; i += 1)
-       type = TYPE_TARGET_TYPE (type);
-      result_type = TYPE_TARGET_TYPE (type->index_type ());
+       {
+         type = ada_check_typedef (type);
+         type = TYPE_TARGET_TYPE (type);
+       }
+      result_type = TYPE_TARGET_TYPE (ada_check_typedef (type)->index_type ());
       /* FIXME: The stabs type r(0,0);bound;bound in an array type
         has a target type of TYPE_CODE_UNDEF.  We compensate here, but
         perhaps stabsread.c would make more sense.  */
@@ -3134,9 +3491,9 @@ static void
 ada_print_symbol_signature (struct ui_file *stream, struct symbol *sym,
                            const struct type_print_options *flags)
 {
-  struct type *type = SYMBOL_TYPE (sym);
+  struct type *type = sym->type ();
 
-  fprintf_filtered (stream, "%s", sym->print_name ());
+  gdb_printf (stream, "%s", sym->print_name ());
   if (!print_signatures
       || type == NULL
       || type->code () != TYPE_CODE_FUNC)
@@ -3146,20 +3503,20 @@ ada_print_symbol_signature (struct ui_file *stream, struct symbol *sym,
     {
       int i;
 
-      fprintf_filtered (stream, " (");
+      gdb_printf (stream, " (");
       for (i = 0; i < type->num_fields (); ++i)
        {
          if (i > 0)
-           fprintf_filtered (stream, "; ");
+           gdb_printf (stream, "; ");
          ada_print_type (type->field (i).type (), NULL, stream, -1, 0,
                          flags);
        }
-      fprintf_filtered (stream, ")");
+      gdb_printf (stream, ")");
     }
   if (TYPE_TARGET_TYPE (type) != NULL
       && TYPE_TARGET_TYPE (type)->code () != TYPE_CODE_VOID)
     {
-      fprintf_filtered (stream, " return ");
+      gdb_printf (stream, " return ");
       ada_print_type (TYPE_TARGET_TYPE (type), NULL, stream, -1, 0, flags);
     }
 }
@@ -3285,9 +3642,9 @@ See set/show multiple-symbol."));
   if (select_mode == multiple_symbols_all && max_results > 1)
     return nsyms;
 
-  printf_filtered (_("[0] cancel\n"));
+  gdb_printf (_("[0] cancel\n"));
   if (max_results > 1)
-    printf_filtered (_("[1] all\n"));
+    gdb_printf (_("[1] all\n"));
 
   sort_choices (syms, nsyms);
 
@@ -3296,19 +3653,19 @@ See set/show multiple-symbol."));
       if (syms[i].symbol == NULL)
        continue;
 
-      if (SYMBOL_CLASS (syms[i].symbol) == LOC_BLOCK)
+      if (syms[i].symbol->aclass () == LOC_BLOCK)
        {
          struct symtab_and_line sal =
            find_function_start_sal (syms[i].symbol, 1);
 
-         printf_filtered ("[%d] ", i + first_choice);
+         gdb_printf ("[%d] ", i + first_choice);
          ada_print_symbol_signature (gdb_stdout, syms[i].symbol,
                                      &type_print_raw_options);
          if (sal.symtab == NULL)
-           printf_filtered (_(" at %p[<no source file available>%p]:%d\n"),
-                            metadata_style.style ().ptr (), nullptr, sal.line);
+           gdb_printf (_(" at %p[<no source file available>%p]:%d\n"),
+                       metadata_style.style ().ptr (), nullptr, sal.line);
          else
-           printf_filtered
+           gdb_printf
              (_(" at %ps:%d\n"),
               styled_string (file_name_style.style (),
                              symtab_to_filename_for_display (sal.symtab)),
@@ -3318,47 +3675,47 @@ See set/show multiple-symbol."));
       else
        {
          int is_enumeral =
-           (SYMBOL_CLASS (syms[i].symbol) == LOC_CONST
-            && SYMBOL_TYPE (syms[i].symbol) != NULL
-            && SYMBOL_TYPE (syms[i].symbol)->code () == TYPE_CODE_ENUM);
+           (syms[i].symbol->aclass () == LOC_CONST
+            && syms[i].symbol->type () != NULL
+            && syms[i].symbol->type ()->code () == TYPE_CODE_ENUM);
          struct symtab *symtab = NULL;
 
-         if (SYMBOL_OBJFILE_OWNED (syms[i].symbol))
-           symtab = symbol_symtab (syms[i].symbol);
+         if (syms[i].symbol->is_objfile_owned ())
+           symtab = syms[i].symbol->symtab ();
 
-         if (SYMBOL_LINE (syms[i].symbol) != 0 && symtab != NULL)
+         if (syms[i].symbol->line () != 0 && symtab != NULL)
            {
-             printf_filtered ("[%d] ", i + first_choice);
+             gdb_printf ("[%d] ", i + first_choice);
              ada_print_symbol_signature (gdb_stdout, syms[i].symbol,
                                          &type_print_raw_options);
-             printf_filtered (_(" at %s:%d\n"),
-                              symtab_to_filename_for_display (symtab),
-                              SYMBOL_LINE (syms[i].symbol));
+             gdb_printf (_(" at %s:%d\n"),
+                         symtab_to_filename_for_display (symtab),
+                         syms[i].symbol->line ());
            }
          else if (is_enumeral
-                  && SYMBOL_TYPE (syms[i].symbol)->name () != NULL)
+                  && syms[i].symbol->type ()->name () != NULL)
            {
-             printf_filtered (("[%d] "), i + first_choice);
-             ada_print_type (SYMBOL_TYPE (syms[i].symbol), NULL,
+             gdb_printf (("[%d] "), i + first_choice);
+             ada_print_type (syms[i].symbol->type (), NULL,
                              gdb_stdout, -1, 0, &type_print_raw_options);
-             printf_filtered (_("'(%s) (enumeral)\n"),
-                              syms[i].symbol->print_name ());
+             gdb_printf (_("'(%s) (enumeral)\n"),
+                         syms[i].symbol->print_name ());
            }
          else
            {
-             printf_filtered ("[%d] ", i + first_choice);
+             gdb_printf ("[%d] ", i + first_choice);
              ada_print_symbol_signature (gdb_stdout, syms[i].symbol,
                                          &type_print_raw_options);
 
              if (symtab != NULL)
-               printf_filtered (is_enumeral
-                                ? _(" in %s (enumeral)\n")
-                                : _(" at %s:?\n"),
-                                symtab_to_filename_for_display (symtab));
+               gdb_printf (is_enumeral
+                           ? _(" in %s (enumeral)\n")
+                           : _(" at %s:?\n"),
+                           symtab_to_filename_for_display (symtab));
              else
-               printf_filtered (is_enumeral
-                                ? _(" (enumeral)\n")
-                                : _(" at ?\n"));
+               gdb_printf (is_enumeral
+                           ? _(" (enumeral)\n")
+                           : _(" at ?\n"));
            }
        }
     }
@@ -3423,6 +3780,29 @@ ada_resolve_funcall (struct symbol *sym, const struct block *block,
   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
@@ -3439,7 +3819,7 @@ ada_resolve_variable (struct symbol *sym, const struct block *block,
                   candidates.end (),
                   [] (block_symbol &bsym)
                   {
-                    switch (SYMBOL_CLASS (bsym.symbol))
+                    switch (bsym.symbol->aclass ())
                       {
                       case LOC_REGISTER:
                       case LOC_ARG:
@@ -3462,16 +3842,31 @@ ada_resolve_variable (struct symbol *sym, const struct block *block,
          candidates.end (),
          [] (block_symbol &bsym)
          {
-           return SYMBOL_CLASS (bsym.symbol) == LOC_TYPEDEF;
+           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
@@ -3483,7 +3878,7 @@ ada_resolve_variable (struct symbol *sym, const struct block *block,
     }
   else
     {
-      printf_filtered (_("Multiple matches for %s\n"), sym->print_name ());
+      gdb_printf (_("Multiple matches for %s\n"), sym->print_name ());
       user_select_syms (candidates.data (), candidates.size (), 1);
       i = 0;
     }
@@ -3492,14 +3887,12 @@ ada_resolve_variable (struct symbol *sym, const struct block *block,
   return candidates[i];
 }
 
-/* Return non-zero if formal type FTYPE matches actual type ATYPE.  If
-   MAY_DEREF is non-zero, the formal may be a pointer and the actual
-   a non-pointer.  */
+/* 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, int may_deref)
+ada_type_match (struct type *ftype, struct type *atype)
 {
   ftype = ada_check_typedef (ftype);
   atype = ada_check_typedef (atype);
@@ -3514,12 +3907,13 @@ ada_type_match (struct type *ftype, struct type *atype, int may_deref)
     default:
       return ftype->code () == atype->code ();
     case TYPE_CODE_PTR:
-      if (atype->code () == TYPE_CODE_PTR)
-       return ada_type_match (TYPE_TARGET_TYPE (ftype),
-                              TYPE_TARGET_TYPE (atype), 0);
-      else
-       return (may_deref
-               && ada_type_match (TYPE_TARGET_TYPE (ftype), atype, 0));
+      if (atype->code () != TYPE_CODE_PTR)
+       return 0;
+      atype = TYPE_TARGET_TYPE (atype);
+      /* This can only happen if the actual argument is 'null'.  */
+      if (atype->code () == TYPE_CODE_INT && TYPE_LENGTH (atype) == 0)
+       return 1;
+      return ada_type_match (TYPE_TARGET_TYPE (ftype), atype);
     case TYPE_CODE_INT:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_RANGE:
@@ -3560,9 +3954,9 @@ static int
 ada_args_match (struct symbol *func, struct value **actuals, int n_actuals)
 {
   int i;
-  struct type *func_type = SYMBOL_TYPE (func);
+  struct type *func_type = func->type ();
 
-  if (SYMBOL_CLASS (func) == LOC_CONST
+  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)
@@ -3580,7 +3974,7 @@ ada_args_match (struct symbol *func, struct value **actuals, int n_actuals)
          struct type *ftype = ada_check_typedef (func_type->field (i).type ());
          struct type *atype = ada_check_typedef (value_type (actuals[i]));
 
-         if (!ada_type_match (ftype, atype, 1))
+         if (!ada_type_match (ftype, atype))
            return 0;
        }
     }
@@ -3648,7 +4042,7 @@ ada_resolve_function (std::vector<struct block_symbol> &syms,
     {
       for (k = 0; k < syms.size (); k += 1)
        {
-         struct type *type = ada_check_typedef (SYMBOL_TYPE (syms[k].symbol));
+         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)))
@@ -3667,7 +4061,7 @@ ada_resolve_function (std::vector<struct block_symbol> &syms,
     return -1;
   else if (m > 1 && !parse_completion)
     {
-      printf_filtered (_("Multiple matches for %s\n"), name);
+      gdb_printf (_("Multiple matches for %s\n"), name);
       user_select_syms (syms.data (), m, 1);
       return 0;
     }
@@ -3868,7 +4262,7 @@ ada_parse_renaming (struct symbol *sym,
 
   if (sym == NULL)
     return ADA_NOT_RENAMING;
-  switch (SYMBOL_CLASS (sym)) 
+  switch (sym->aclass ()) 
     {
     default:
       return ADA_NOT_RENAMING;
@@ -3949,7 +4343,7 @@ ensure_lval (struct value *val)
 
       VALUE_LVAL (val) = lval_memory;
       set_value_address (val, addr);
-      write_memory (addr, value_contents (val), len);
+      write_memory (addr, value_contents (val).data (), len);
     }
 
   return val;
@@ -4034,8 +4428,8 @@ ada_value_struct_elt (struct value *arg, const char *name, int no_err)
             If not found then let's look in the fixed type.  */
 
          if (!find_struct_field (name, t1, 0,
-                                 &field_type, &byte_offset, &bit_offset,
-                                 &bit_size, NULL))
+                                 nullptr, nullptr, nullptr,
+                                 nullptr, nullptr))
            check_tag = 1;
          else
            check_tag = 0;
@@ -4120,9 +4514,7 @@ ada_convert_actual (struct value *actual, struct type *formal_type0)
 
              actual_type = ada_check_typedef (value_type (actual));
              val = allocate_value (actual_type);
-             memcpy ((char *) value_contents_raw (val),
-                     (char *) value_contents (actual),
-                     TYPE_LENGTH (actual_type));
+             copy (value_contents (actual), value_contents_raw (val));
              actual = ensure_lval (val);
            }
          result = value_addr (actual);
@@ -4184,11 +4576,13 @@ make_array_descriptor (struct type *type, struct value *arr)
   for (i = ada_array_arity (ada_check_typedef (value_type (arr)));
        i > 0; i -= 1)
     {
-      modify_field (value_type (bounds), value_contents_writeable (bounds),
+      modify_field (value_type (bounds),
+                   value_contents_writeable (bounds).data (),
                    ada_array_bound (arr, i, 0),
                    desc_bound_bitpos (bounds_type, i, 0),
                    desc_bound_bitsize (bounds_type, i, 0));
-      modify_field (value_type (bounds), value_contents_writeable (bounds),
+      modify_field (value_type (bounds),
+                   value_contents_writeable (bounds).data (),
                    ada_array_bound (arr, i, 1),
                    desc_bound_bitpos (bounds_type, i, 1),
                    desc_bound_bitsize (bounds_type, i, 1));
@@ -4197,14 +4591,14 @@ make_array_descriptor (struct type *type, struct value *arr)
   bounds = ensure_lval (bounds);
 
   modify_field (value_type (descriptor),
-               value_contents_writeable (descriptor),
+               value_contents_writeable (descriptor).data (),
                value_pointer (ensure_lval (arr),
                               desc_type->field (0).type ()),
                fat_pntr_data_bitpos (desc_type),
                fat_pntr_data_bitsize (desc_type));
 
   modify_field (value_type (descriptor),
-               value_contents_writeable (descriptor),
+               value_contents_writeable (descriptor).data (),
                value_pointer (bounds,
                               desc_type->field (1).type ()),
                fat_pntr_bounds_bitpos (desc_type),
@@ -4310,19 +4704,20 @@ cache_symbol (const char *name, domain_enum domain, struct symbol *sym,
 
   /* Symbols for builtin types don't have a block.
      For now don't cache such symbols.  */
-  if (sym != NULL && !SYMBOL_OBJFILE_OWNED (sym))
+  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
-      && BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (symbol_symtab (sym)),
-                           GLOBAL_BLOCK) != block
-      && BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (symbol_symtab (sym)),
-                           STATIC_BLOCK) != block)
-    return;
+  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);
@@ -4375,9 +4770,9 @@ static int
 is_nonfunction (const std::vector<struct block_symbol> &syms)
 {
   for (const block_symbol &sym : syms)
-    if (SYMBOL_TYPE (sym.symbol)->code () != TYPE_CODE_FUNC
-       && (SYMBOL_TYPE (sym.symbol)->code () != TYPE_CODE_ENUM
-           || SYMBOL_CLASS (sym.symbol) != LOC_CONST))
+    if (sym.symbol->type ()->code () != TYPE_CODE_FUNC
+       && (sym.symbol->type ()->code () != TYPE_CODE_ENUM
+           || sym.symbol->aclass () != LOC_CONST))
       return 1;
 
   return 0;
@@ -4411,18 +4806,18 @@ lesseq_defined_than (struct symbol *sym0, struct symbol *sym1)
 {
   if (sym0 == sym1)
     return 1;
-  if (SYMBOL_DOMAIN (sym0) != SYMBOL_DOMAIN (sym1)
-      || SYMBOL_CLASS (sym0) != SYMBOL_CLASS (sym1))
+  if (sym0->domain () != sym1->domain ()
+      || sym0->aclass () != sym1->aclass ())
     return 0;
 
-  switch (SYMBOL_CLASS (sym0))
+  switch (sym0->aclass ())
     {
     case LOC_UNDEF:
       return 1;
     case LOC_TYPEDEF:
       {
-       struct type *type0 = SYMBOL_TYPE (sym0);
-       struct type *type1 = SYMBOL_TYPE (sym1);
+       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);
@@ -4434,15 +4829,15 @@ lesseq_defined_than (struct symbol *sym0, struct symbol *sym1)
                  && startswith (name1 + len0, "___XV")));
       }
     case LOC_CONST:
-      return SYMBOL_VALUE (sym0) == SYMBOL_VALUE (sym1)
-       && equiv_types (SYMBOL_TYPE (sym0), SYMBOL_TYPE (sym1));
+      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
-               && SYMBOL_VALUE_ADDRESS (sym0) == SYMBOL_VALUE_ADDRESS (sym1));
+               && sym0->value_address () == sym1->value_address ());
       }
 
     default:
@@ -4496,8 +4891,6 @@ ada_lookup_simple_minsym (const char *name)
 {
   struct bound_minimal_symbol result;
 
-  memset (&result, 0, sizeof (result));
-
   symbol_name_match_type match_type = name_match_type_from_name (name);
   lookup_name_info lookup_name (name, match_type);
 
@@ -4509,7 +4902,7 @@ ada_lookup_simple_minsym (const char *name)
       for (minimal_symbol *msymbol : objfile->msymbols ())
        {
          if (match_name (msymbol->linkage_name (), lookup_name, NULL)
-             && MSYMBOL_TYPE (msymbol) != mst_solib_trampoline)
+             && msymbol->type () != mst_solib_trampoline)
            {
              result.minsym = msymbol;
              result.objfile = objfile;
@@ -4521,19 +4914,6 @@ ada_lookup_simple_minsym (const char *name)
   return result;
 }
 
-/* For all subprograms that statically enclose the subprogram of the
-   selected frame, add symbols matching identifier NAME in DOMAIN
-   and their blocks to the list of data in RESULT, as for
-   ada_add_block_symbols (q.v.).   If WILD_MATCH_P, treat as NAME
-   with a wildcard prefix.  */
-
-static void
-add_symbols_from_enclosing_procs (std::vector<struct block_symbol> &result,
-                                 const lookup_name_info &lookup_name,
-                                 domain_enum domain)
-{
-}
-
 /* True if TYPE is definitely an artificial type supplied to a symbol
    for which no debugging information was given in the symbol file.  */
 
@@ -4564,23 +4944,23 @@ ada_identical_enum_types_p (struct type *type1, struct type *type2)
 
   /* All enums in the type should have an identical underlying value.  */
   for (i = 0; i < type1->num_fields (); i++)
-    if (TYPE_FIELD_ENUMVAL (type1, i) != TYPE_FIELD_ENUMVAL (type2, 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 = TYPE_FIELD_NAME (type1, i);
-      const char *name_2 = TYPE_FIELD_NAME (type2, 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 (TYPE_FIELD_NAME (type1, i), &len_1);
-      ada_remove_trailing_digits (TYPE_FIELD_NAME (type2, i), &len_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 (TYPE_FIELD_NAME (type1, i),
-                     TYPE_FIELD_NAME (type2, i),
+         || strncmp (type1->field (i).name (),
+                     type2->field (i).name (),
                      len_1) != 0)
        return 0;
     }
@@ -4622,26 +5002,26 @@ symbols_are_identical_enums (const std::vector<struct block_symbol> &syms)
 
   /* Quick check: All symbols should have an enum type.  */
   for (i = 0; i < syms.size (); i++)
-    if (SYMBOL_TYPE (syms[i].symbol)->code () != TYPE_CODE_ENUM)
+    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 (SYMBOL_VALUE (syms[i].symbol) != SYMBOL_VALUE (syms[0].symbol))
+    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 (SYMBOL_TYPE (syms[i].symbol)->num_fields ()
-       != SYMBOL_TYPE (syms[0].symbol)->num_fields ())
+    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 (SYMBOL_TYPE (syms[i].symbol),
-                                    SYMBOL_TYPE (syms[0].symbol)))
+    if (!ada_identical_enum_types_p (syms[i].symbol->type (),
+                                    syms[0].symbol->type ()))
       return 0;
 
   return 1;
@@ -4672,13 +5052,13 @@ remove_extra_symbols (std::vector<struct block_symbol> *syms)
       /* If two symbols have the same name and one of them is a stub type,
         the get rid of the stub.  */
 
-      if (SYMBOL_TYPE ((*syms)[i].symbol)->is_stub ()
+      if ((*syms)[i].symbol->type ()->is_stub ()
          && (*syms)[i].symbol->linkage_name () != NULL)
        {
          for (j = 0; j < syms->size (); j++)
            {
              if (j != i
-                 && !SYMBOL_TYPE ((*syms)[j].symbol)->is_stub ()
+                 && !(*syms)[j].symbol->type ()->is_stub ()
                  && (*syms)[j].symbol->linkage_name () != NULL
                  && strcmp ((*syms)[i].symbol->linkage_name (),
                             (*syms)[j].symbol->linkage_name ()) == 0)
@@ -4690,8 +5070,8 @@ remove_extra_symbols (std::vector<struct block_symbol> *syms)
         should be identical.  */
 
       else if ((*syms)[i].symbol->linkage_name () != NULL
-         && SYMBOL_CLASS ((*syms)[i].symbol) == LOC_STATIC
-         && is_nondebugging_type (SYMBOL_TYPE ((*syms)[i].symbol)))
+         && (*syms)[i].symbol->aclass () == LOC_STATIC
+         && is_nondebugging_type ((*syms)[i].symbol->type ()))
        {
          for (j = 0; j < syms->size (); j += 1)
            {
@@ -4699,10 +5079,10 @@ remove_extra_symbols (std::vector<struct block_symbol> *syms)
                  && (*syms)[j].symbol->linkage_name () != NULL
                  && strcmp ((*syms)[i].symbol->linkage_name (),
                             (*syms)[j].symbol->linkage_name ()) == 0
-                 && SYMBOL_CLASS ((*syms)[i].symbol)
-                      == SYMBOL_CLASS ((*syms)[j].symbol)
-                 && SYMBOL_VALUE_ADDRESS ((*syms)[i].symbol)
-                 == SYMBOL_VALUE_ADDRESS ((*syms)[j].symbol))
+                 && ((*syms)[i].symbol->aclass ()
+                     == (*syms)[j].symbol->aclass ())
+                 && (*syms)[i].symbol->value_address ()
+                 == (*syms)[j].symbol->value_address ())
                remove_p = 1;
            }
        }
@@ -4792,10 +5172,10 @@ is_package_name (const char *name)
 static int
 old_renaming_is_invisible (const struct symbol *sym, const char *function_name)
 {
-  if (SYMBOL_CLASS (sym) != LOC_TYPEDEF)
+  if (sym->aclass () != LOC_TYPEDEF)
     return 0;
 
-  std::string scope = xget_renaming_scope (SYMBOL_TYPE (sym));
+  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 ()))
@@ -4871,7 +5251,7 @@ remove_irrelevant_renamings (std::vector<struct block_symbol> *syms,
       const char *name;
       const char *suffix;
 
-      if (sym == NULL || SYMBOL_CLASS (sym) == LOC_TYPEDEF)
+      if (sym == NULL || sym->aclass () == LOC_TYPEDEF)
        continue;
       name = sym->linkage_name ();
       suffix = strstr (name, "___XR");
@@ -4936,41 +5316,30 @@ remove_irrelevant_renamings (std::vector<struct block_symbol> *syms,
 }
 
 /* Add to RESULT all symbols from BLOCK (and its super-blocks)
-   whose name and domain match NAME and DOMAIN respectively.
-   If no match was found, then extend the search to "enclosing"
-   routines (in other words, if we're inside a nested function,
-   search the symbols defined inside the enclosing functions).
-   If WILD_MATCH_P is nonzero, perform the naming matching in
-   "wild" mode (see function "wild_match" for more info).
+   whose name and domain match LOOKUP_NAME and DOMAIN respectively.
 
-   Note: This function assumes that RESULT has 0 (zero) element in it.  */
+   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)
 {
-  int block_depth = 0;
-
   while (block != NULL)
     {
-      block_depth += 1;
       ada_add_block_symbols (result, block, lookup_name, domain, NULL);
 
-      /* If we found a non-function match, assume that's the one.  */
-      if (is_nonfunction (result))
+      /* 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 (block);
+      block = block->superblock ();
     }
-
-  /* If no luck so far, try to find NAME as a local symbol in some lexically
-     enclosing subprogram.  */
-  if (result.empty () && block_depth > 2)
-    add_symbols_from_enclosing_procs (result, lookup_name, domain);
 }
 
-/* An object of this type is used as the user_data argument when
+/* An object of this type is used as the callback argument when
    calling the map_matching_symbols method.  */
 
 struct match_data
@@ -4981,48 +5350,43 @@ struct match_data
   }
   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.  DATA is a pointer to a struct match_data *
-   containing the vector that collects the symbol list, the file that SYM
-   must come from, a flag indicating whether a non-argument symbol has
-   been found in the current block, and the last argument symbol
-   passed in SYM within the current block (if any).  When SYM is null,
-   marking the end of a block, the argument symbol is added if no
-   other has been found.  */
+/* A callback for add_nonlocal_symbols that adds symbol, found in
+   BSYM, to a list of symbols.  */
 
-static bool
-aux_add_nonlocal_symbols (struct block_symbol *bsym,
-                         struct match_data *data)
+bool
+match_data::operator() (struct block_symbol *bsym)
 {
   const struct block *block = bsym->block;
   struct symbol *sym = bsym->symbol;
 
   if (sym == NULL)
     {
-      if (!data->found_sym && data->arg_sym != NULL) 
-       add_defn_to_vec (*data->resultp,
-                        fixup_symbol_section (data->arg_sym, data->objfile),
+      if (!found_sym && arg_sym != NULL)
+       add_defn_to_vec (*resultp,
+                        fixup_symbol_section (arg_sym, objfile),
                         block);
-      data->found_sym = false;
-      data->arg_sym = NULL;
+      found_sym = false;
+      arg_sym = NULL;
     }
   else 
     {
-      if (SYMBOL_CLASS (sym) == LOC_UNRESOLVED)
+      if (sym->aclass () == LOC_UNRESOLVED)
        return true;
-      else if (SYMBOL_IS_ARGUMENT (sym))
-       data->arg_sym = sym;
+      else if (sym->is_argument ())
+       arg_sym = sym;
       else
        {
-         data->found_sym = true;
-         add_defn_to_vec (*data->resultp,
-                          fixup_symbol_section (sym, data->objfile),
+         found_sym = true;
+         add_defn_to_vec (*resultp,
+                          fixup_symbol_section (sym, objfile),
                           block);
        }
     }
@@ -5180,6 +5544,33 @@ 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
@@ -5194,22 +5585,15 @@ add_nonlocal_symbols (std::vector<struct block_symbol> &result,
 
   bool is_wild_match = lookup_name.ada ().wild_match_p ();
 
-  auto callback = [&] (struct block_symbol *bsym)
-    {
-      return aux_add_nonlocal_symbols (bsym, &data);
-    };
-
   for (objfile *objfile : current_program_space->objfiles ())
     {
-      data.objfile = objfile;
-
-      objfile->map_matching_symbols (lookup_name, domain, global, callback,
-                                    is_wild_match ? NULL : compare_names);
+      map_matching_symbols (objfile, lookup_name, is_wild_match, domain,
+                           global, data);
 
       for (compunit_symtab *cu : objfile->compunits ())
        {
          const struct block *global_block
-           = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cu), GLOBAL_BLOCK);
+           = cu->blockvector ()->global_block ();
 
          if (ada_add_block_renamings (result, global_block, lookup_name,
                                       domain))
@@ -5224,12 +5608,8 @@ add_nonlocal_symbols (std::vector<struct block_symbol> &result,
       lookup_name_info name1 (bracket_name, symbol_name_match_type::FULL);
 
       for (objfile *objfile : current_program_space->objfiles ())
-       {
-         data.objfile = objfile;
-         objfile->map_matching_symbols (name1, domain, global, callback,
-                                        compare_names);
-       }
-    }          
+       map_matching_symbols (objfile, name1, false, domain, global, data);
+    }
 }
 
 /* Find symbols in DOMAIN matching LOOKUP_NAME, in BLOCK and, if
@@ -5645,6 +6025,9 @@ 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;
@@ -5687,11 +6070,11 @@ ada_add_block_symbols (std::vector<struct block_symbol> &result,
        sym != NULL;
        sym = block_iter_match_next (lookup_name, &iter))
     {
-      if (symbol_matches_domain (sym->language (), SYMBOL_DOMAIN (sym), domain))
+      if (symbol_matches_domain (sym->language (), sym->domain (), domain))
        {
-         if (SYMBOL_CLASS (sym) != LOC_UNRESOLVED)
+         if (sym->aclass () != LOC_UNRESOLVED)
            {
-             if (SYMBOL_IS_ARGUMENT (sym))
+             if (sym->is_argument ())
                arg_sym = sym;
              else
                {
@@ -5727,7 +6110,7 @@ ada_add_block_symbols (std::vector<struct block_symbol> &result,
       ALL_BLOCK_SYMBOLS (block, iter, sym)
       {
        if (symbol_matches_domain (sym->language (),
-                                  SYMBOL_DOMAIN (sym), domain))
+                                  sym->domain (), domain))
          {
            int cmp;
 
@@ -5743,9 +6126,9 @@ ada_add_block_symbols (std::vector<struct block_symbol> &result,
            if (cmp == 0
                && is_name_suffix (sym->linkage_name () + name_len + 5))
              {
-               if (SYMBOL_CLASS (sym) != LOC_UNRESOLVED)
+               if (sym->aclass () != LOC_UNRESOLVED)
                  {
-                   if (SYMBOL_IS_ARGUMENT (sym))
+                   if (sym->is_argument ())
                      arg_sym = sym;
                    else
                      {
@@ -5899,7 +6282,7 @@ ada_is_ignored_field (struct type *type, int field_num)
 
   /* Check the name of that field.  */
   {
-    const char *name = TYPE_FIELD_NAME (type, field_num);
+    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
@@ -5916,6 +6299,18 @@ ada_is_ignored_field (struct type *type, int field_num)
        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,
@@ -5993,7 +6388,11 @@ value_tag_from_contents_and_address (struct type *type,
   int tag_byte_offset;
   struct type *tag_type;
 
-  if (find_struct_field ("_tag", type, 0, &tag_type, &tag_byte_offset,
+  gdb::array_view<const gdb_byte> contents;
+  if (valaddr != nullptr)
+    contents = gdb::make_array_view (valaddr, TYPE_LENGTH (type));
+  struct type *resolved_type = resolve_dynamic_type (type, contents, address);
+  if (find_struct_field ("_tag", resolved_type, 0, &tag_type, &tag_byte_offset,
                         NULL, NULL, NULL))
     {
       const gdb_byte *valaddr1 = ((valaddr == NULL)
@@ -6047,9 +6446,10 @@ ada_tag_value_at_base_address (struct value *obj)
   if (is_ada95_tag (tag))
     return obj;
 
-  ptr_type = language_lookup_primitive_type
-    (language_def (language_ada), target_gdbarch(), "storage_offset");
-  ptr_type = lookup_pointer_type (ptr_type);
+  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;
@@ -6081,16 +6481,29 @@ ada_tag_value_at_base_address (struct value *obj)
   if (offset_to_top == -1)
     return obj;
 
-  /* 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.  */
+  /* Storage_Offset'Last is used to indicate that a dynamic offset to
+     top is used.  In this situation the offset is stored just after
+     the tag, in the object itself.  */
+  ULONGEST last = (((ULONGEST) 1) << (8 * TYPE_LENGTH (offset_type) - 1)) - 1;
+  if (offset_to_top == last)
+    {
+      struct value *tem = value_addr (tag);
+      tem = value_ptradd (tem, 1);
+      tem = value_cast (ptr_type, tem);
+      offset_to_top = value_as_long (value_ind (tem));
+    }
 
   if (offset_to_top > 0)
-    offset_to_top = -offset_to_top;
+    {
+      /* OFFSET_TO_TOP used to be a positive value to be subtracted
+        from the base address.  This was however incompatible with
+        C++ dispatch table: C++ uses a *negative* value to *add*
+        to the base address.  Ada's convention has therefore been
+        changed in GNAT 19.0w 20171023: since then, C++ and Ada
+        use the same convention.  Here, we support both cases by
+        checking the sign of OFFSET_TO_TOP.  */
+      offset_to_top = -offset_to_top;
+    }
 
   base_address = value_address (obj) + offset_to_top;
   tag = value_tag_from_contents_and_address (obj_type, NULL, base_address);
@@ -6165,7 +6578,6 @@ ada_get_tsd_from_tag (struct value *tag)
 static gdb::unique_xmalloc_ptr<char>
 ada_tag_name_from_tsd (struct value *tsd)
 {
-  char *p;
   struct value *val;
 
   val = ada_value_struct_elt (tsd, "expanded_name", 1);
@@ -6176,13 +6588,18 @@ ada_tag_name_from_tsd (struct value *tsd)
   if (buffer == nullptr)
     return nullptr;
 
-  for (p = buffer.get (); *p != '\0'; ++p)
+  try
     {
-      if (isalpha (*p))
-       *p = tolower (*p);
+      /* 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;
     }
-
-  return buffer;
 }
 
 /* The type name of the dynamic type denoted by the 'tag value TAG, as
@@ -6258,7 +6675,7 @@ ada_parent_type (struct type *type)
 int
 ada_is_parent_field (struct type *type, int field_num)
 {
-  const char *name = TYPE_FIELD_NAME (ada_check_typedef (type), field_num);
+  const char *name = ada_check_typedef (type)->field (field_num).name ();
 
   return (name != NULL
          && (startswith (name, "PARENT")
@@ -6274,7 +6691,7 @@ ada_is_parent_field (struct type *type, int field_num)
 int
 ada_is_wrapper_field (struct type *type, int field_num)
 {
-  const char *name = TYPE_FIELD_NAME (type, field_num);
+  const char *name = type->field (field_num).name ();
 
   if (name != NULL && strcmp (name, "RETVAL") == 0)
     {
@@ -6333,7 +6750,7 @@ ada_variant_discrim_type (struct type *var_type, struct type *outer_type)
 static int
 ada_is_others_clause (struct type *type, int field_num)
 {
-  const char *name = TYPE_FIELD_NAME (type, field_num);
+  const char *name = type->field (field_num).name ();
 
   return (name != NULL && name[0] == 'O');
 }
@@ -6438,7 +6855,7 @@ ada_scan_number (const char str[], int k, LONGEST * R, int *new_k)
 static int
 ada_in_variant (LONGEST val, struct type *type, int field_num)
 {
-  const char *name = TYPE_FIELD_NAME (type, field_num);
+  const char *name = type->field (field_num).name ();
   int p;
 
   p = 0;
@@ -6498,10 +6915,11 @@ ada_value_primitive_field (struct value *arg1, int offset, int fieldno,
      packed; in this case we must take the bit-field path.  */
   if (TYPE_FIELD_BITSIZE (arg_type, fieldno) != 0 || value_bitpos (arg1) != 0)
     {
-      int bit_pos = TYPE_FIELD_BITPOS (arg_type, fieldno);
+      int bit_pos = arg_type->field (fieldno).loc_bitpos ();
       int bit_size = TYPE_FIELD_BITSIZE (arg_type, fieldno);
 
-      return ada_value_primitive_packed_val (arg1, value_contents (arg1),
+      return ada_value_primitive_packed_val (arg1,
+                                            value_contents (arg1).data (),
                                             offset + bit_pos / 8,
                                             bit_pos % 8, bit_size, type);
     }
@@ -6596,9 +7014,17 @@ find_struct_field (const char *name, struct type *type, int offset,
 
   for (i = 0; i < type->num_fields (); i += 1)
     {
-      int bit_pos = TYPE_FIELD_BITPOS (type, i);
-      int fld_offset = offset + bit_pos / 8;
-      const char *t_field_name = TYPE_FIELD_NAME (type, i);
+      /* 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;
@@ -6650,7 +7076,7 @@ find_struct_field (const char *name, struct type *type, int offset,
            {
              if (find_struct_field (name, field_type->field (j).type (),
                                     fld_offset
-                                    + TYPE_FIELD_BITPOS (field_type, j) / 8,
+                                    + field_type->field (j).loc_bitpos () / 8,
                                     field_type_p, byte_offset_p,
                                     bit_offset_p, bit_size_p, index_p))
                return 1;
@@ -6665,8 +7091,13 @@ find_struct_field (const char *name, struct type *type, int offset,
 
   if (parent_offset != -1)
     {
-      int bit_pos = TYPE_FIELD_BITPOS (type, parent_offset);
-      int fld_offset = offset + bit_pos / 8;
+      /* 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,
@@ -6708,7 +7139,7 @@ ada_search_struct_field (const char *name, struct value *arg, int offset,
   type = ada_check_typedef (type);
   for (i = 0; i < type->num_fields (); i += 1)
     {
-      const char *t_field_name = TYPE_FIELD_NAME (type, i);
+      const char *t_field_name = type->field (i).name ();
 
       if (t_field_name == NULL)
        continue;
@@ -6734,7 +7165,7 @@ ada_search_struct_field (const char *name, struct value *arg, int offset,
        {
          struct value *v =     /* Do not let indent join lines here.  */
            ada_search_struct_field (name, arg,
-                                    offset + TYPE_FIELD_BITPOS (type, i) / 8,
+                                    offset + type->field (i).loc_bitpos () / 8,
                                     type->field (i).type ());
 
          if (v != NULL)
@@ -6746,14 +7177,14 @@ ada_search_struct_field (const char *name, struct value *arg, int offset,
          /* 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_BITPOS (type, i) / 8;
+         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 + TYPE_FIELD_BITPOS (field_type, j) / 8,
+                var_offset + field_type->field (j).loc_bitpos () / 8,
                 field_type->field (j).type ());
 
              if (v != NULL)
@@ -6768,7 +7199,7 @@ ada_search_struct_field (const char *name, struct value *arg, int offset,
   if (parent_offset != -1)
     {
       struct value *v = ada_search_struct_field (
-       name, arg, offset + TYPE_FIELD_BITPOS (type, parent_offset) / 8,
+       name, arg, offset + type->field (parent_offset).loc_bitpos () / 8,
        type->field (parent_offset).type ());
 
       if (v != NULL)
@@ -6808,13 +7239,13 @@ ada_index_struct_field_1 (int *index_p, struct value *arg, int offset,
 
   for (i = 0; i < type->num_fields (); i += 1)
     {
-      if (TYPE_FIELD_NAME (type, i) == NULL)
+      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_BITPOS (type, i) / 8,
+                                     offset + type->field (i).loc_bitpos () / 8,
                                      type->field (i).type ());
 
          if (v != NULL)
@@ -6844,7 +7275,7 @@ type_as_string (struct type *type)
 
   type_print (type, "", &tmp_stream, -1);
 
-  return std::move (tmp_stream.string ());
+  return tmp_stream.release ();
 }
 
 /* Given a type TYPE, look up the type of the component of type named NAME.
@@ -6901,7 +7332,7 @@ ada_lookup_struct_elt_type (struct type *type, const char *name, int refok,
 
   for (i = 0; i < type->num_fields (); i += 1)
     {
-      const char *t_field_name = TYPE_FIELD_NAME (type, i);
+      const char *t_field_name = type->field (i).name ();
       struct type *t;
 
       if (t_field_name == NULL)
@@ -6943,7 +7374,7 @@ ada_lookup_struct_elt_type (struct type *type, const char *name, int refok,
                 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 = TYPE_FIELD_NAME (field_type, j);
+             const char *v_field_name = field_type->field (j).name ();
 
              if (v_field_name != NULL 
                  && field_name_match (v_field_name, name))
@@ -7109,7 +7540,7 @@ ada_coerce_ref (struct value *val0)
 static unsigned int
 field_alignment (struct type *type, int f)
 {
-  const char *name = TYPE_FIELD_NAME (type, f);
+  const char *name = type->field (f).name ();
   int len;
   int align_offset;
 
@@ -7143,7 +7574,7 @@ ada_find_any_type_symbol (const char *name)
   struct symbol *sym;
 
   sym = standard_lookup (name, get_selected_block (NULL), VAR_DOMAIN);
-  if (sym != NULL && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
+  if (sym != NULL && sym->aclass () == LOC_TYPEDEF)
     return sym;
 
   sym = standard_lookup (name, NULL, STRUCT_DOMAIN);
@@ -7160,7 +7591,7 @@ ada_find_any_type (const char *name)
   struct symbol *sym = ada_find_any_type_symbol (name);
 
   if (sym != NULL)
-    return SYMBOL_TYPE (sym);
+    return sym->type ();
 
   return NULL;
 }
@@ -7352,7 +7783,7 @@ dynamic_template_type (struct type *type)
 static int
 is_dynamic_field (struct type *templ_type, int field_num)
 {
-  const char *name = TYPE_FIELD_NAME (templ_type, field_num);
+  const char *name = templ_type->field (field_num).name ();
 
   return name != NULL
     && templ_type->field (field_num).type ()->code () == TYPE_CODE_PTR
@@ -7454,8 +7885,8 @@ ada_template_to_fixed_record_type_1 (struct type *type,
   for (f = 0; f < nfields; f += 1)
     {
       off = align_up (off, field_alignment (type, f))
-       + TYPE_FIELD_BITPOS (type, f);
-      SET_FIELD_BITPOS (rtype->field (f), off);
+       + 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))
@@ -7472,12 +7903,6 @@ ada_template_to_fixed_record_type_1 (struct type *type,
 
          if (dval0 == NULL)
            {
-             /* rtype's length is computed based on the run-time
-                value of discriminants.  If the discriminants are not
-                initialized, the type size may be completely bogus and
-                GDB may fail to allocate a value for it.  So check the
-                size first before creating the value.  */
-             ada_ensure_varsize_limit (rtype);
              /* Using plain value_from_contents_and_address here
                 causes problems because we will end up trying to
                 resolve a type that is currently being
@@ -7497,7 +7922,7 @@ ada_template_to_fixed_record_type_1 (struct type *type,
             that follow this one.  */
          if (ada_is_aligner_type (field_type))
            {
-             long field_offset = TYPE_FIELD_BITPOS (field_type, f);
+             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);
@@ -7518,17 +7943,9 @@ ada_template_to_fixed_record_type_1 (struct type *type,
          field_type = ada_get_base_type (field_type);
          field_type = ada_to_fixed_type (field_type, field_valaddr,
                                          field_address, dval, 0);
-         /* If the field size is already larger than the maximum
-            object size, then the record itself will necessarily
-            be larger than the maximum object size.  We need to make
-            this check now, because the size might be so ridiculously
-            large (due to an uninitialized variable in the inferior)
-            that it would cause an overflow when adding it to the
-            record size.  */
-         ada_ensure_varsize_limit (field_type);
 
          rtype->field (f).set_type (field_type);
-         TYPE_FIELD_NAME (rtype, f) = TYPE_FIELD_NAME (type, f);
+         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,
@@ -7551,7 +7968,7 @@ ada_template_to_fixed_record_type_1 (struct type *type,
             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 ());
-         TYPE_FIELD_NAME (rtype, f) = TYPE_FIELD_NAME (type, f);
+         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);
@@ -7585,7 +8002,7 @@ ada_template_to_fixed_record_type_1 (struct type *type,
     {
       struct type *branch_type;
 
-      off = TYPE_FIELD_BITPOS (rtype, variant_field);
+      off = rtype->field (variant_field).loc_bitpos ();
 
       if (dval0 == NULL)
        {
@@ -7613,7 +8030,7 @@ ada_template_to_fixed_record_type_1 (struct type *type,
       else
        {
          rtype->field (variant_field).set_type (branch_type);
-         TYPE_FIELD_NAME (rtype, variant_field) = "S";
+         rtype->field (variant_field).set_name ("S");
          fld_bit_len =
            TYPE_LENGTH (rtype->field (variant_field).type ()) *
            TARGET_CHAR_BIT;
@@ -7646,8 +8063,6 @@ ada_template_to_fixed_record_type_1 (struct type *type,
     }
 
   value_free_to_mark (mark);
-  if (TYPE_LENGTH (rtype) > varsize_limit)
-    error (_("record type with dynamic size is larger than varsize-limit"));
   return rtype;
 }
 
@@ -7729,7 +8144,7 @@ template_to_static_fixed_type (struct type *type0)
              TYPE_LENGTH (type) = 0;
            }
          type->field (f).set_type (new_type);
-         TYPE_FIELD_NAME (type, f) = TYPE_FIELD_NAME (type0, f);
+         type->field (f).set_name (type0->field (f).name ());
        }
     }
 
@@ -7782,10 +8197,10 @@ to_record_with_fixed_variant_part (struct type *type, const gdb_byte *valaddr,
   branch_type = to_fixed_variant_branch_type
     (type->field (variant_field).type (),
      cond_offset_host (valaddr,
-                      TYPE_FIELD_BITPOS (type, variant_field)
+                      type->field (variant_field).loc_bitpos ()
                       / TARGET_CHAR_BIT),
      cond_offset_target (address,
-                        TYPE_FIELD_BITPOS (type, variant_field)
+                        type->field (variant_field).loc_bitpos ()
                         / TARGET_CHAR_BIT), dval);
   if (branch_type == NULL)
     {
@@ -7798,7 +8213,7 @@ to_record_with_fixed_variant_part (struct type *type, const gdb_byte *valaddr,
   else
     {
       rtype->field (variant_field).set_type (branch_type);
-      TYPE_FIELD_NAME (rtype, variant_field) = "S";
+      rtype->field (variant_field).set_name ("S");
       TYPE_FIELD_BITSIZE (rtype, variant_field) = 0;
       TYPE_LENGTH (rtype) += TYPE_LENGTH (branch_type);
     }
@@ -8094,8 +8509,6 @@ to_fixed_array_type (struct type *type0, struct value *dval,
                                      result, range_type);
          elt_type0 = TYPE_TARGET_TYPE (elt_type0);
        }
-      if (!ignore_too_big && TYPE_LENGTH (result) > varsize_limit)
-       error (_("array type with dynamic size is larger than varsize-limit"));
     }
 
   /* We want to preserve the type name.  This can be useful when
@@ -8433,7 +8846,7 @@ ada_to_fixed_value_create (struct type *type0, CORE_ADDR address,
       /* Our value does not live in memory; it could be a convenience
         variable, for instance.  Create a not_lval value using val0's
         contents.  */
-      return value_from_contents (type, value_contents (val0));
+      return value_from_contents (type, value_contents (val0).data ());
     }
 
   return value_from_contents_and_address (type, 0, address);
@@ -8525,7 +8938,7 @@ val_atr (struct type *type, LONGEST val)
     {
       if (val < 0 || val >= type->num_fields ())
        error (_("argument to 'VAL out of range"));
-      val = TYPE_FIELD_ENUMVAL (type, val);
+      val = type->field (val).loc_enumval ();
     }
   return value_from_longest (type, val);
 }
@@ -8618,7 +9031,7 @@ ada_is_aligner_type (struct type *type)
 
   return (type->code () == TYPE_CODE_STRUCT
          && type->num_fields () == 1
-         && strcmp (TYPE_FIELD_NAME (type, 0), "F") == 0);
+         && strcmp (type->field (0).name (), "F") == 0);
 }
 
 /* If there is an ___XVS-convention type parallel to SUBTYPE, return
@@ -8659,7 +9072,7 @@ ada_get_base_type (struct type *raw_type)
       /* 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 (TYPE_FIELD_NAME (real_type_namer, 0));
+      raw_real_type = ada_find_any_type (real_type_namer->field (0).name ());
       if (raw_real_type == NULL)
        return raw_type;
       else
@@ -8689,10 +9102,9 @@ 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_BITPOS (type,
-                                                     0) / TARGET_CHAR_BIT);
+    return ada_aligned_value_addr
+      (type->field (0).type (),
+       valaddr + type->field (0).loc_bitpos () / TARGET_CHAR_BIT);
   else
     return valaddr;
 }
@@ -8736,7 +9148,13 @@ ada_enum_name (const char *name)
 
       if (name[1] == 'U' || name[1] == 'W')
        {
-         if (sscanf (name + 2, "%x", &v) != 1)
+         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')
@@ -8752,9 +9170,11 @@ ada_enum_name (const char *name)
       if (isascii (v) && isprint (v))
        storage = string_printf ("'%c'", v);
       else if (name[1] == 'U')
-       storage = string_printf ("[\"%02x\"]", v);
+       storage = string_printf ("'[\"%02x\"]'", v);
+      else if (name[2] != 'W')
+       storage = string_printf ("'[\"%04x\"]'", v);
       else
-       storage = string_printf ("[\"%04x\"]", v);
+       storage = string_printf ("'[\"%06x\"]'", v);
 
       return storage.c_str ();
     }
@@ -8846,7 +9266,6 @@ ada_promote_array_of_integrals (struct type *type, struct value *val)
 {
   struct type *elt_type = TYPE_TARGET_TYPE (type);
   LONGEST lo, hi;
-  struct value *res;
   LONGEST i;
 
   /* Verify that both val and type are arrays of scalars, and
@@ -8862,15 +9281,16 @@ ada_promote_array_of_integrals (struct type *type, struct value *val)
   if (!get_array_bounds (type, &lo, &hi))
     error (_("unable to determine array bounds"));
 
-  res = allocate_value (type);
+  value *res = allocate_value (type);
+  gdb::array_view<gdb_byte> res_contents = value_contents_writeable (res);
 
   /* Promote each array element.  */
   for (i = 0; i < hi - lo + 1; i++)
     {
       struct value *elt = value_cast (elt_type, value_subscript (val, lo + i));
+      int elt_len = TYPE_LENGTH (elt_type);
 
-      memcpy (value_contents_writeable (res) + (i * TYPE_LENGTH (elt_type)),
-             value_contents_all (elt), TYPE_LENGTH (elt_type));
+      copy (value_contents_all (elt), res_contents.slice (elt_len * i, elt_len));
     }
 
   return res;
@@ -8986,7 +9406,7 @@ ada_value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
     }
 
   val = allocate_value (type1);
-  store_unsigned_integer (value_contents_raw (val),
+  store_unsigned_integer (value_contents_raw (val).data (),
                          TYPE_LENGTH (value_type (val)),
                          type_byte_order (type1), v);
   return val;
@@ -9018,7 +9438,8 @@ ada_value_equal (struct value *arg1, struct value *arg2)
         representations use all bits (no padding or undefined bits)
         and do not have user-defined equality.  */
       return (TYPE_LENGTH (arg1_type) == TYPE_LENGTH (arg2_type)
-             && memcmp (value_contents (arg1), value_contents (arg2),
+             && memcmp (value_contents (arg1).data (),
+                        value_contents (arg2).data (),
                         TYPE_LENGTH (arg1_type)) == 0);
     }
   return value_equal (arg1, arg2);
@@ -9083,7 +9504,7 @@ ada_aggregate_component::uses_objfile (struct objfile *objfile)
 void
 ada_aggregate_component::dump (ui_file *stream, int depth)
 {
-  fprintf_filtered (stream, _("%*sAggregate\n"), depth, "");
+  gdb_printf (stream, _("%*sAggregate\n"), depth, "");
   for (const auto &item : m_components)
     item->dump (stream, depth + 1);
 }
@@ -9150,8 +9571,8 @@ ada_positional_component::uses_objfile (struct objfile *objfile)
 void
 ada_positional_component::dump (ui_file *stream, int depth)
 {
-  fprintf_filtered (stream, _("%*sPositional, index = %d\n"),
-                   depth, "", m_index);
+  gdb_printf (stream, _("%*sPositional, index = %d\n"),
+             depth, "", m_index);
   m_op->dump (stream, depth + 1);
 }
 
@@ -9185,7 +9606,7 @@ ada_discrete_range_association::uses_objfile (struct objfile *objfile)
 void
 ada_discrete_range_association::dump (ui_file *stream, int depth)
 {
-  fprintf_filtered (stream, _("%*sDiscrete range:\n"), depth, "");
+  gdb_printf (stream, _("%*sDiscrete range:\n"), depth, "");
   m_low->dump (stream, depth + 1);
   m_high->dump (stream, depth + 1);
 }
@@ -9221,7 +9642,7 @@ ada_name_association::uses_objfile (struct objfile *objfile)
 void
 ada_name_association::dump (ui_file *stream, int depth)
 {
-  fprintf_filtered (stream, _("%*sName:\n"), depth, "");
+  gdb_printf (stream, _("%*sName:\n"), depth, "");
   m_val->dump (stream, depth + 1);
 }
 
@@ -9279,7 +9700,7 @@ ada_choices_component::uses_objfile (struct objfile *objfile)
 void
 ada_choices_component::dump (ui_file *stream, int depth)
 {
-  fprintf_filtered (stream, _("%*sChoices:\n"), depth, "");
+  gdb_printf (stream, _("%*sChoices:\n"), depth, "");
   m_op->dump (stream, depth + 1);
   for (const auto &item : m_assocs)
     item->dump (stream, depth + 1);
@@ -9308,7 +9729,7 @@ ada_others_component::uses_objfile (struct objfile *objfile)
 void
 ada_others_component::dump (ui_file *stream, int depth)
 {
-  fprintf_filtered (stream, _("%*sOthers:\n"), depth, "");
+  gdb_printf (stream, _("%*sOthers:\n"), depth, "");
   m_op->dump (stream, depth + 1);
 }
 
@@ -10111,6 +10532,98 @@ ada_binop_exp (struct type *expect_type,
 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,
@@ -10139,12 +10652,108 @@ ada_string_operation::evaluate (struct type *expect_type,
                                struct expression *exp,
                                enum noside noside)
 {
-  value *result = string_operation::evaluate (expect_type, exp, noside);
-  /* The result type will have code OP_STRING, bashed there from 
-     OP_ARRAY.  Bash it back.  */
-  if (value_type (result)->code () == TYPE_CODE_STRING)
-    value_type (result)->set_code (TYPE_CODE_ARRAY);
-  return result;
+  struct type *char_type;
+  if (expect_type != nullptr && ada_is_string_type (expect_type))
+    char_type = ada_array_element_type (expect_type, 1);
+  else
+    char_type = language_string_char_type (exp->language_defn, exp->gdbarch);
+
+  const std::string &str = std::get<0> (m_storage);
+  const char *encoding;
+  switch (TYPE_LENGTH (char_type))
+    {
+    case 1:
+      {
+       /* Simply copy over the data -- this isn't perhaps strictly
+          correct according to the encodings, but it is gdb's
+          historical behavior.  */
+       struct type *stringtype
+         = lookup_array_range_type (char_type, 1, str.length ());
+       struct value *val = allocate_value (stringtype);
+       memcpy (value_contents_raw (val).data (), str.c_str (),
+               str.length ());
+       return val;
+      }
+
+    case 2:
+      if (gdbarch_byte_order (exp->gdbarch) == BFD_ENDIAN_BIG)
+       encoding = "UTF-16BE";
+      else
+       encoding = "UTF-16LE";
+      break;
+
+    case 4:
+      if (gdbarch_byte_order (exp->gdbarch) == BFD_ENDIAN_BIG)
+       encoding = "UTF-32BE";
+      else
+       encoding = "UTF-32LE";
+      break;
+
+    default:
+      error (_("unexpected character type size %s"),
+            pulongest (TYPE_LENGTH (char_type)));
+    }
+
+  auto_obstack converted;
+  convert_between_encodings (host_charset (), encoding,
+                            (const gdb_byte *) str.c_str (),
+                            str.length (), 1,
+                            &converted, translit_none);
+
+  struct type *stringtype
+    = lookup_array_range_type (char_type, 1,
+                              obstack_object_size (&converted)
+                              / TYPE_LENGTH (char_type));
+  struct value *val = allocate_value (stringtype);
+  memcpy (value_contents_raw (val).data (),
+         obstack_base (&converted),
+         obstack_object_size (&converted));
+  return val;
+}
+
+value *
+ada_concat_operation::evaluate (struct type *expect_type,
+                               struct expression *exp,
+                               enum noside noside)
+{
+  /* If one side is a literal, evaluate the other side first so that
+     the expected type can be set properly.  */
+  const operation_up &lhs_expr = std::get<0> (m_storage);
+  const operation_up &rhs_expr = std::get<1> (m_storage);
+
+  value *lhs, *rhs;
+  if (dynamic_cast<ada_string_operation *> (lhs_expr.get ()) != nullptr)
+    {
+      rhs = rhs_expr->evaluate (nullptr, exp, noside);
+      lhs = lhs_expr->evaluate (value_type (rhs), exp, noside);
+    }
+  else if (dynamic_cast<ada_char_operation *> (lhs_expr.get ()) != nullptr)
+    {
+      rhs = rhs_expr->evaluate (nullptr, exp, noside);
+      struct type *rhs_type = check_typedef (value_type (rhs));
+      struct type *elt_type = nullptr;
+      if (rhs_type->code () == TYPE_CODE_ARRAY)
+       elt_type = TYPE_TARGET_TYPE (rhs_type);
+      lhs = lhs_expr->evaluate (elt_type, exp, noside);
+    }
+  else if (dynamic_cast<ada_string_operation *> (rhs_expr.get ()) != nullptr)
+    {
+      lhs = lhs_expr->evaluate (nullptr, exp, noside);
+      rhs = rhs_expr->evaluate (value_type (lhs), exp, noside);
+    }
+  else if (dynamic_cast<ada_char_operation *> (rhs_expr.get ()) != nullptr)
+    {
+      lhs = lhs_expr->evaluate (nullptr, exp, noside);
+      struct type *lhs_type = check_typedef (value_type (lhs));
+      struct type *elt_type = nullptr;
+      if (lhs_type->code () == TYPE_CODE_ARRAY)
+       elt_type = TYPE_TARGET_TYPE (lhs_type);
+      rhs = rhs_expr->evaluate (elt_type, exp, noside);
+    }
+  else
+    return concat_operation::evaluate (expect_type, exp, noside);
+
+  return value_concat (lhs, rhs);
 }
 
 value *
@@ -10258,8 +10867,8 @@ ada_var_value_operation::evaluate_for_cast (struct type *expect_type,
                                            enum noside noside)
 {
   value *val = evaluate_var_value (noside,
-                                  std::get<1> (m_storage),
-                                  std::get<0> (m_storage));
+                                  std::get<0> (m_storage).block,
+                                  std::get<0> (m_storage).symbol);
 
   val = ada_value_cast (expect_type, val);
 
@@ -10279,9 +10888,9 @@ ada_var_value_operation::evaluate (struct type *expect_type,
                                   struct expression *exp,
                                   enum noside noside)
 {
-  symbol *sym = std::get<0> (m_storage);
+  symbol *sym = std::get<0> (m_storage).symbol;
 
-  if (SYMBOL_DOMAIN (sym) == UNDEF_DOMAIN)
+  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.  */
@@ -10290,7 +10899,7 @@ ada_var_value_operation::evaluate (struct type *expect_type,
 
   if (noside == EVAL_AVOID_SIDE_EFFECTS)
     {
-      struct type *type = static_unwrap_type (SYMBOL_TYPE (sym));
+      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.
@@ -10370,19 +10979,19 @@ ada_var_value_operation::resolve (struct expression *exp,
                                  innermost_block_tracker *tracker,
                                  struct type *context_type)
 {
-  symbol *sym = std::get<0> (m_storage);
-  if (SYMBOL_DOMAIN (sym) == UNDEF_DOMAIN)
+  symbol *sym = std::get<0> (m_storage).symbol;
+  if (sym->domain () == UNDEF_DOMAIN)
     {
       block_symbol resolved
-       = ada_resolve_variable (sym, std::get<1> (m_storage),
+       = ada_resolve_variable (sym, std::get<0> (m_storage).block,
                                context_type, parse_completion,
                                deprocedure_p, tracker);
-      std::get<0> (m_storage) = resolved.symbol;
-      std::get<1> (m_storage) = resolved.block;
+      std::get<0> (m_storage) = resolved;
     }
 
   if (deprocedure_p
-      && SYMBOL_TYPE (std::get<0> (m_storage))->code () == TYPE_CODE_FUNC)
+      && (std::get<0> (m_storage).symbol->type ()->code ()
+         == TYPE_CODE_FUNC))
     return true;
 
   return false;
@@ -10440,7 +11049,6 @@ ada_unop_ind_operation::evaluate (struct type *expect_type,
                (ada_aligned_type
                 (ada_check_typedef (TYPE_TARGET_TYPE (type))));
            }
-         ada_ensure_varsize_limit (type);
          return value_zero (type, lval_memory);
        }
       else if (type->code () == TYPE_CODE_INT)
@@ -10475,11 +11083,6 @@ ada_unop_ind_operation::evaluate (struct type *expect_type,
                              (CORE_ADDR) value_as_address (arg1));
     }
 
-  struct type *target_type = (to_static_fixed_type
-                             (ada_aligned_type
-                              (ada_check_typedef (TYPE_TARGET_TYPE (type)))));
-  ada_ensure_varsize_limit (target_type);
-
   if (ada_is_array_descriptor_type (type))
     /* GDB allows dereferencing GNAT array descriptors.  */
     return ada_coerce_to_simple_array (arg1);
@@ -10542,7 +11145,7 @@ ada_funcall_operation::evaluate (struct type *expect_type,
   ada_var_value_operation *avv
     = dynamic_cast<ada_var_value_operation *> (callee_op.get ());
   if (avv != nullptr
-      && SYMBOL_DOMAIN (avv->get_symbol ()) == UNDEF_DOMAIN)
+      && avv->get_symbol ()->domain () == UNDEF_DOMAIN)
     error (_("Unexpected unresolved symbol, %s, during evaluation"),
           avv->get_symbol ()->print_name ());
 
@@ -10686,7 +11289,7 @@ ada_funcall_operation::resolve (struct expression *exp,
     return false;
 
   symbol *sym = avv->get_symbol ();
-  if (SYMBOL_DOMAIN (sym) != UNDEF_DOMAIN)
+  if (sym->domain () != UNDEF_DOMAIN)
     return false;
 
   const std::vector<operation_up> &args_up = std::get<1> (m_storage);
@@ -10704,8 +11307,7 @@ ada_funcall_operation::resolve (struct expression *exp,
                           tracker);
 
   std::get<0> (m_storage)
-    = make_operation<ada_var_value_operation> (resolved.symbol,
-                                              resolved.block);
+    = make_operation<ada_var_value_operation> (resolved);
   return false;
 }
 
@@ -11120,7 +11722,7 @@ ada_has_this_exception_support (const struct exception_support_info *einfo)
       struct bound_minimal_symbol msym
        = lookup_minimal_symbol (einfo->catch_exception_sym, NULL, NULL);
 
-      if (msym.minsym && MSYMBOL_TYPE (msym.minsym) != mst_solib_trampoline)
+      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."));
@@ -11130,10 +11732,10 @@ ada_has_this_exception_support (const struct exception_support_info *einfo)
 
   /* Make sure that the symbol we found corresponds to a function.  */
 
-  if (SYMBOL_CLASS (sym) != LOC_BLOCK)
+  if (sym->aclass () != LOC_BLOCK)
     {
       error (_("Symbol \"%s\" is not a function (class = %d)"),
-            sym->linkage_name (), SYMBOL_CLASS (sym));
+            sym->linkage_name (), sym->aclass ());
       return 0;
     }
 
@@ -11143,7 +11745,7 @@ ada_has_this_exception_support (const struct exception_support_info *einfo)
       struct bound_minimal_symbol msym
        = lookup_minimal_symbol (einfo->catch_handlers_sym, NULL, NULL);
 
-      if (msym.minsym && MSYMBOL_TYPE (msym.minsym) != mst_solib_trampoline)
+      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."));
@@ -11153,10 +11755,10 @@ ada_has_this_exception_support (const struct exception_support_info *einfo)
 
   /* Make sure that the symbol we found corresponds to a function.  */
 
-  if (SYMBOL_CLASS (sym) != LOC_BLOCK)
+  if (sym->aclass () != LOC_BLOCK)
     {
       error (_("Symbol \"%s\" is not a function (class = %d)"),
-            sym->linkage_name (), SYMBOL_CLASS (sym));
+            sym->linkage_name (), sym->aclass ());
       return 0;
     }
 
@@ -11265,8 +11867,8 @@ is_known_support_routine (struct frame_info *frame)
       re_comp (known_runtime_file_name_patterns[i]);
       if (re_exec (lbasename (sal.symtab->filename)))
        return 1;
-      if (SYMTAB_OBJFILE (sal.symtab) != NULL
-         && re_exec (objfile_name (SYMTAB_OBJFILE (sal.symtab))))
+      if (sal.symtab->compunit ()->objfile () != NULL
+         && re_exec (objfile_name (sal.symtab->compunit ()->objfile ())))
        return 1;
     }
 
@@ -11368,8 +11970,7 @@ ada_unhandled_exception_name_addr_from_raise (void)
    Return zero if the address could not be computed, or if not relevant.  */
 
 static CORE_ADDR
-ada_exception_name_addr_1 (enum ada_exception_catchpoint_kind ex,
-                          struct breakpoint *b)
+ada_exception_name_addr_1 (enum ada_exception_catchpoint_kind ex)
 {
   struct ada_inferior_data *data = get_ada_inferior_data (current_inferior ());
 
@@ -11467,14 +12068,13 @@ ada_exception_message (void)
    and zero is returned.  */
 
 static CORE_ADDR
-ada_exception_name_addr (enum ada_exception_catchpoint_kind ex,
-                        struct breakpoint *b)
+ada_exception_name_addr (enum ada_exception_catchpoint_kind ex)
 {
   CORE_ADDR result = 0;
 
   try
     {
-      result = ada_exception_name_addr_1 (ex, b);
+      result = ada_exception_name_addr_1 (ex);
     }
 
   catch (const gdb_exception_error &e)
@@ -11503,13 +12103,74 @@ static std::string ada_exception_catchpoint_cond_string
    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:
-  ada_catchpoint_location (breakpoint *owner)
+  explicit ada_catchpoint_location (ada_catchpoint *owner)
     : bp_location (owner, bp_loc_software_breakpoint)
   {}
 
@@ -11519,22 +12180,6 @@ public:
   expression_up excep_cond_expr;
 };
 
-/* An instance of this type is used to represent an Ada catchpoint.  */
-
-struct ada_catchpoint : public breakpoint
-{
-  explicit ada_catchpoint (enum ada_exception_catchpoint_kind kind)
-    : m_kind (kind)
-  {
-  }
-
-  /* The name of the specific exception the user specified.  */
-  std::string excep_string;
-
-  /* What kind of catchpoint this is.  */
-  enum ada_exception_catchpoint_kind m_kind;
-};
-
 /* Parse the exception condition string in the context of each of the
    catchpoint's locations, and store them for later evaluation.  */
 
@@ -11542,8 +12187,6 @@ static void
 create_excep_cond_exprs (struct ada_catchpoint *c,
                         enum ada_exception_catchpoint_kind ex)
 {
-  struct bp_location *bl;
-
   /* Nothing to do if there's no specific exception to catch.  */
   if (c->excep_string.empty ())
     return;
@@ -11559,7 +12202,7 @@ create_excep_cond_exprs (struct ada_catchpoint *c,
 
   /* Iterate over all the catchpoint's locations, and parse an
      expression for each.  */
-  for (bl = c->loc; bl != NULL; bl = bl->next)
+  for (bp_location *bl : c->locations ())
     {
       struct ada_catchpoint_location *ada_loc
        = (struct ada_catchpoint_location *) bl;
@@ -11588,43 +12231,41 @@ create_excep_cond_exprs (struct ada_catchpoint *c,
     }
 }
 
-/* Implement the ALLOCATE_LOCATION method in the breakpoint_ops
-   structure for all exception catchpoint kinds.  */
+/* Implement the ALLOCATE_LOCATION method in the structure for all
+   exception catchpoint kinds.  */
 
-static struct bp_location *
-allocate_location_exception (struct breakpoint *self)
+struct bp_location *
+ada_catchpoint::allocate_location ()
 {
-  return new ada_catchpoint_location (self);
+  return new ada_catchpoint_location (this);
 }
 
-/* Implement the RE_SET method in the breakpoint_ops structure for all
-   exception catchpoint kinds.  */
+/* Implement the RE_SET method in the structure for all exception
+   catchpoint kinds.  */
 
-static void
-re_set_exception (struct breakpoint *b)
+void
+ada_catchpoint::re_set ()
 {
-  struct ada_catchpoint *c = (struct ada_catchpoint *) b;
-
   /* Call the base class's method.  This updates the catchpoint's
      locations.  */
-  bkpt_breakpoint_ops.re_set (b);
+  this->code_breakpoint::re_set ();
 
   /* Reparse the exception conditional expressions.  One for each
      location.  */
-  create_excep_cond_exprs (c, c->m_kind);
+  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 int
+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;
-  int stop;
+  bool stop;
 
   struct internalvar *var = lookup_internalvar ("_ada_exception");
   if (c->m_kind == ada_catch_assert)
@@ -11652,16 +12293,16 @@ should_stop_exception (const struct bp_location *bl)
 
   /* With no specific exception, should always stop.  */
   if (c->excep_string.empty ())
-    return 1;
+    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 1;
+      return true;
     }
 
-  stop = 1;
+  stop = true;
   try
     {
       struct value *mark;
@@ -11679,36 +12320,35 @@ should_stop_exception (const struct bp_location *bl)
   return stop;
 }
 
-/* Implement the CHECK_STATUS method in the breakpoint_ops structure
-   for all exception catchpoint kinds.  */
+/* Implement the CHECK_STATUS method in the structure for all
+   exception catchpoint kinds.  */
 
-static void
-check_status_exception (bpstat bs)
+void
+ada_catchpoint::check_status (bpstat *bs)
 {
   bs->stop = should_stop_exception (bs->bp_location_at.get ());
 }
 
-/* Implement the PRINT_IT method in the breakpoint_ops structure
-   for all exception catchpoint kinds.  */
+/* Implement the PRINT_IT method in the structure for all exception
+   catchpoint kinds.  */
 
-static enum print_stop_action
-print_it_exception (bpstat bs)
+enum print_stop_action
+ada_catchpoint::print_it (const bpstat *bs) const
 {
   struct ui_out *uiout = current_uiout;
-  struct breakpoint *b = bs->breakpoint_at;
 
-  annotate_catchpoint (b->number);
+  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 (b->disposition));
+      uiout->field_string ("disp", bpdisp_text (disposition));
     }
 
-  uiout->text (b->disposition == disp_del
+  uiout->text (disposition == disp_del
               ? "\nTemporary catchpoint " : "\nCatchpoint ");
-  uiout->field_signed ("bkptno", b->number);
+  uiout->field_signed ("bkptno", number);
   uiout->text (", ");
 
   /* ada_exception_name_addr relies on the selected frame being the
@@ -11718,14 +12358,13 @@ print_it_exception (bpstat bs)
      ada_find_printable_frame).  */
   select_frame (get_current_frame ());
 
-  struct ada_catchpoint *c = (struct ada_catchpoint *) b;
-  switch (c->m_kind)
+  switch (m_kind)
     {
       case ada_catch_exception:
       case ada_catch_exception_unhandled:
       case ada_catch_handlers:
        {
-         const CORE_ADDR addr = ada_exception_name_addr (c->m_kind, b);
+         const CORE_ADDR addr = ada_exception_name_addr (m_kind);
          char exception_name[256];
 
          if (addr != 0)
@@ -11749,7 +12388,7 @@ print_it_exception (bpstat bs)
             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 (c->m_kind == ada_catch_exception_unhandled)
+         if (m_kind == ada_catch_exception_unhandled)
            uiout->text ("unhandled ");
          uiout->field_string ("exception-name", exception_name);
        }
@@ -11778,14 +12417,13 @@ print_it_exception (bpstat bs)
   return PRINT_SRC_AND_LOC;
 }
 
-/* Implement the PRINT_ONE method in the breakpoint_ops structure
-   for all exception catchpoint kinds.  */
+/* Implement the PRINT_ONE method in the structure for all exception
+   catchpoint kinds.  */
 
-static void
-print_one_exception (struct breakpoint *b, struct bp_location **last_loc)
+bool
+ada_catchpoint::print_one (bp_location **last_loc) const
 { 
   struct ui_out *uiout = current_uiout;
-  struct ada_catchpoint *c = (struct ada_catchpoint *) b;
   struct value_print_options opts;
 
   get_user_print_options (&opts);
@@ -11794,13 +12432,13 @@ print_one_exception (struct breakpoint *b, struct bp_location **last_loc)
     uiout->field_skip ("addr");
 
   annotate_field (5);
-  switch (c->m_kind)
+  switch (m_kind)
     {
       case ada_catch_exception:
-       if (!c->excep_string.empty ())
+       if (!excep_string.empty ())
          {
            std::string msg = string_printf (_("`%s' Ada exception"),
-                                            c->excep_string.c_str ());
+                                            excep_string.c_str ());
 
            uiout->field_string ("what", msg);
          }
@@ -11814,11 +12452,11 @@ print_one_exception (struct breakpoint *b, struct bp_location **last_loc)
        break;
       
       case ada_catch_handlers:
-       if (!c->excep_string.empty ())
+       if (!excep_string.empty ())
          {
            uiout->field_fmt ("what",
                              _("`%s' Ada exception handlers"),
-                             c->excep_string.c_str ());
+                             excep_string.c_str ());
          }
        else
          uiout->field_string ("what", "all Ada exceptions handlers");
@@ -11832,30 +12470,31 @@ print_one_exception (struct breakpoint *b, struct bp_location **last_loc)
        internal_error (__FILE__, __LINE__, _("unexpected catchpoint type"));
        break;
     }
+
+  return true;
 }
 
 /* Implement the PRINT_MENTION method in the breakpoint_ops structure
    for all exception catchpoint kinds.  */
 
-static void
-print_mention_exception (struct breakpoint *b)
+void
+ada_catchpoint::print_mention () const
 {
-  struct ada_catchpoint *c = (struct ada_catchpoint *) b;
   struct ui_out *uiout = current_uiout;
 
-  uiout->text (b->disposition == disp_del ? _("Temporary catchpoint ")
+  uiout->text (disposition == disp_del ? _("Temporary catchpoint ")
                                                 : _("Catchpoint "));
-  uiout->field_signed ("bkptno", b->number);
+  uiout->field_signed ("bkptno", number);
   uiout->text (": ");
 
-  switch (c->m_kind)
+  switch (m_kind)
     {
       case ada_catch_exception:
-       if (!c->excep_string.empty ())
+       if (!excep_string.empty ())
          {
            std::string info = string_printf (_("`%s' Ada exception"),
-                                             c->excep_string.c_str ());
-           uiout->text (info.c_str ());
+                                             excep_string.c_str ());
+           uiout->text (info);
          }
        else
          uiout->text (_("all Ada exceptions"));
@@ -11866,12 +12505,12 @@ print_mention_exception (struct breakpoint *b)
        break;
 
       case ada_catch_handlers:
-       if (!c->excep_string.empty ())
+       if (!excep_string.empty ())
          {
            std::string info
              = string_printf (_("`%s' Ada exception handlers"),
-                              c->excep_string.c_str ());
-           uiout->text (info.c_str ());
+                              excep_string.c_str ());
+           uiout->text (info);
          }
        else
          uiout->text (_("all Ada exceptions handlers"));
@@ -11887,55 +12526,44 @@ print_mention_exception (struct breakpoint *b)
     }
 }
 
-/* Implement the PRINT_RECREATE method in the breakpoint_ops structure
-   for all exception catchpoint kinds.  */
+/* Implement the PRINT_RECREATE method in the structure for all
+   exception catchpoint kinds.  */
 
-static void
-print_recreate_exception (struct breakpoint *b, struct ui_file *fp)
+void
+ada_catchpoint::print_recreate (struct ui_file *fp) const
 {
-  struct ada_catchpoint *c = (struct ada_catchpoint *) b;
-
-  switch (c->m_kind)
+  switch (m_kind)
     {
       case ada_catch_exception:
-       fprintf_filtered (fp, "catch exception");
-       if (!c->excep_string.empty ())
-         fprintf_filtered (fp, " %s", c->excep_string.c_str ());
+       gdb_printf (fp, "catch exception");
+       if (!excep_string.empty ())
+         gdb_printf (fp, " %s", excep_string.c_str ());
        break;
 
       case ada_catch_exception_unhandled:
-       fprintf_filtered (fp, "catch exception unhandled");
+       gdb_printf (fp, "catch exception unhandled");
        break;
 
       case ada_catch_handlers:
-       fprintf_filtered (fp, "catch handlers");
+       gdb_printf (fp, "catch handlers");
        break;
 
       case ada_catch_assert:
-       fprintf_filtered (fp, "catch assert");
+       gdb_printf (fp, "catch assert");
        break;
 
       default:
        internal_error (__FILE__, __LINE__, _("unexpected catchpoint type"));
     }
-  print_recreate_thread (b, fp);
+  print_recreate_thread (fp);
 }
 
-/* Virtual tables for various breakpoint types.  */
-static struct breakpoint_ops catch_exception_breakpoint_ops;
-static struct breakpoint_ops catch_exception_unhandled_breakpoint_ops;
-static struct breakpoint_ops catch_assert_breakpoint_ops;
-static struct breakpoint_ops catch_handlers_breakpoint_ops;
-
 /* See ada-lang.h.  */
 
 bool
 is_ada_exception_catchpoint (breakpoint *bp)
 {
-  return (bp->ops == &catch_exception_breakpoint_ops
-         || bp->ops == &catch_exception_unhandled_breakpoint_ops
-         || bp->ops == &catch_assert_breakpoint_ops
-         || bp->ops == &catch_handlers_breakpoint_ops);
+  return dynamic_cast<ada_catchpoint *> (bp) != nullptr;
 }
 
 /* Split the arguments specified in a "catch exception" command.  
@@ -12045,32 +12673,6 @@ ada_exception_sym_name (enum ada_exception_catchpoint_kind ex)
     }
 }
 
-/* Return the breakpoint ops "virtual table" used for catchpoints
-   of the EX kind.  */
-
-static const struct breakpoint_ops *
-ada_exception_breakpoint_ops (enum ada_exception_catchpoint_kind ex)
-{
-  switch (ex)
-    {
-      case ada_catch_exception:
-       return (&catch_exception_breakpoint_ops);
-       break;
-      case ada_catch_exception_unhandled:
-       return (&catch_exception_unhandled_breakpoint_ops);
-       break;
-      case ada_catch_assert:
-       return (&catch_assert_breakpoint_ops);
-       break;
-      case ada_catch_handlers:
-       return (&catch_handlers_breakpoint_ops);
-       break;
-      default:
-       internal_error (__FILE__, __LINE__,
-                       _("unexpected catchpoint kind (%d)"), ex);
-    }
-}
-
 /* Return the condition that will be used to match the current exception
    being raised with the exception that the user wants to catch.  This
    assumes that this condition is used when the inferior just triggered
@@ -12081,7 +12683,6 @@ static std::string
 ada_exception_catchpoint_cond_string (const char *excep_string,
                                      enum ada_exception_catchpoint_kind ex)
 {
-  int i;
   bool is_standard_exc = false;
   std::string result;
 
@@ -12114,9 +12715,9 @@ ada_exception_catchpoint_cond_string (const char *excep_string,
      breakpoint condition is to use its fully-qualified named:
      e.g. my_package.constraint_error.  */
 
-  for (i = 0; i < sizeof (standard_exc) / sizeof (char *); i++)
+  for (const char *name : standard_exc)
     {
-      if (strcmp (standard_exc [i], excep_string) == 0)
+      if (strcmp (name, excep_string) == 0)
        {
          is_standard_exc = true;
          break;
@@ -12142,7 +12743,7 @@ ada_exception_catchpoint_cond_string (const char *excep_string,
 
 static struct symtab_and_line
 ada_exception_sal (enum ada_exception_catchpoint_kind ex,
-                  std::string *addr_string, const struct breakpoint_ops **ops)
+                  std::string *addr_string)
 {
   const char *sym_name;
   struct symbol *sym;
@@ -12158,15 +12759,12 @@ ada_exception_sal (enum ada_exception_catchpoint_kind ex,
   if (sym == NULL)
     error (_("Catchpoint symbol not found: %s"), sym_name);
 
-  if (SYMBOL_CLASS (sym) != LOC_BLOCK)
+  if (sym->aclass () != LOC_BLOCK)
     error (_("Unable to insert catchpoint. %s is not a function."), sym_name);
 
   /* Set ADDR_STRING.  */
   *addr_string = sym_name;
 
-  /* Set OPS.  */
-  *ops = ada_exception_breakpoint_ops (ex);
-
   return find_function_start_sal (sym, 1);
 }
 
@@ -12195,12 +12793,11 @@ create_ada_exception_catchpoint (struct gdbarch *gdbarch,
                                 int from_tty)
 {
   std::string addr_string;
-  const struct breakpoint_ops *ops = NULL;
-  struct symtab_and_line sal = ada_exception_sal (ex_kind, &addr_string, &ops);
+  struct symtab_and_line sal = ada_exception_sal (ex_kind, &addr_string);
 
-  std::unique_ptr<ada_catchpoint> c (new ada_catchpoint (ex_kind));
-  init_ada_exception_breakpoint (c.get (), gdbarch, sal, addr_string.c_str (),
-                                ops, tempflag, disabled, from_tty);
+  std::unique_ptr<ada_catchpoint> c
+    (new ada_catchpoint (gdbarch, ex_kind, sal, addr_string.c_str (),
+                        tempflag, disabled, from_tty));
   c->excep_string = excep_string;
   create_excep_cond_exprs (c.get (), ex_kind);
   if (!cond_string.empty ())
@@ -12221,7 +12818,7 @@ catch_ada_exception_command (const char *arg_entry, int from_tty,
   std::string excep_string;
   std::string cond_string;
 
-  tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
+  tempflag = command->context () == CATCH_TEMPORARY;
 
   if (!arg)
     arg = "";
@@ -12246,7 +12843,7 @@ catch_ada_handlers_command (const char *arg_entry, int from_tty,
   std::string excep_string;
   std::string cond_string;
 
-  tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
+  tempflag = command->context () == CATCH_TEMPORARY;
 
   if (!arg)
     arg = "";
@@ -12314,7 +12911,7 @@ catch_assert_command (const char *arg_entry, int from_tty,
   int tempflag;
   std::string cond_string;
 
-  tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
+  tempflag = command->context () == CATCH_TEMPORARY;
 
   if (!arg)
     arg = "";
@@ -12330,12 +12927,12 @@ catch_assert_command (const char *arg_entry, int from_tty,
 static int
 ada_is_exception_sym (struct symbol *sym)
 {
-  const char *type_name = SYMBOL_TYPE (sym)->name ();
+  const char *type_name = sym->type ()->name ();
 
-  return (SYMBOL_CLASS (sym) != LOC_TYPEDEF
-         && SYMBOL_CLASS (sym) != LOC_BLOCK
-         && SYMBOL_CLASS (sym) != LOC_CONST
-         && SYMBOL_CLASS (sym) != LOC_UNRESOLVED
+  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);
 }
 
@@ -12346,13 +12943,11 @@ ada_is_exception_sym (struct symbol *sym)
 static int
 ada_is_non_standard_exception_sym (struct symbol *sym)
 {
-  int i;
-
   if (!ada_is_exception_sym (sym))
     return 0;
 
-  for (i = 0; i < ARRAY_SIZE (standard_exc); i++)
-    if (strcmp (sym->linkage_name (), standard_exc[i]) == 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.
@@ -12417,20 +13012,17 @@ static void
 ada_add_standard_exceptions (compiled_regex *preg,
                             std::vector<ada_exc_info> *exceptions)
 {
-  int i;
-
-  for (i = 0; i < ARRAY_SIZE (standard_exc); i++)
+  for (const char *name : standard_exc)
     {
-      if (preg == NULL
-         || preg->exec (standard_exc[i], 0, NULL, 0) == 0)
+      if (preg == NULL || preg->exec (name, 0, NULL, 0) == 0)
        {
          struct bound_minimal_symbol msymbol
-           = ada_lookup_simple_minsym (standard_exc[i]);
+           = ada_lookup_simple_minsym (name);
 
          if (msymbol.minsym != NULL)
            {
              struct ada_exc_info info
-               = {standard_exc[i], BMSYMBOL_VALUE_ADDRESS (msymbol)};
+               = {name, msymbol.value_address ()};
 
              exceptions->push_back (info);
            }
@@ -12462,7 +13054,7 @@ ada_add_exceptions_from_frame (compiled_regex *preg,
 
       ALL_BLOCK_SYMBOLS (block, iter, sym)
        {
-         switch (SYMBOL_CLASS (sym))
+         switch (sym->aclass ())
            {
            case LOC_TYPEDEF:
            case LOC_BLOCK:
@@ -12472,15 +13064,15 @@ ada_add_exceptions_from_frame (compiled_regex *preg,
              if (ada_is_exception_sym (sym))
                {
                  struct ada_exc_info info = {sym->print_name (),
-                                             SYMBOL_VALUE_ADDRESS (sym)};
+                                             sym->value_address ()};
 
                  exceptions->push_back (info);
                }
            }
        }
-      if (BLOCK_FUNCTION (block) != NULL)
+      if (block->function () != NULL)
        break;
-      block = BLOCK_SUPERBLOCK (block);
+      block = block->superblock ();
     }
 }
 
@@ -12527,18 +13119,19 @@ ada_add_global_exceptions (compiled_regex *preg,
                             return name_matches_regex (decoded.c_str (), preg);
                           },
                           NULL,
+                          SEARCH_GLOBAL_BLOCK | SEARCH_STATIC_BLOCK,
                           VARIABLES_DOMAIN);
 
   for (objfile *objfile : current_program_space->objfiles ())
     {
       for (compunit_symtab *s : objfile->compunits ())
        {
-         const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (s);
+         const struct blockvector *bv = s->blockvector ();
          int i;
 
          for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++)
            {
-             const struct block *b = BLOCKVECTOR_BLOCK (bv, i);
+             const struct block *b = bv->block (i);
              struct block_iterator iter;
              struct symbol *sym;
 
@@ -12547,7 +13140,7 @@ ada_add_global_exceptions (compiled_regex *preg,
                    && name_matches_regex (sym->natural_name (), preg))
                  {
                    struct ada_exc_info info
-                     = {sym->print_name (), SYMBOL_VALUE_ADDRESS (sym)};
+                     = {sym->print_name (), sym->value_address ()};
 
                    exceptions->push_back (info);
                  }
@@ -12630,13 +13223,13 @@ info_exceptions_command (const char *regexp, int from_tty)
   std::vector<ada_exc_info> exceptions = ada_exceptions_list (regexp);
 
   if (regexp != NULL)
-    printf_filtered
+    gdb_printf
       (_("All Ada exceptions matching regular expression \"%s\":\n"), regexp);
   else
-    printf_filtered (_("All defined Ada exceptions:\n"));
+    gdb_printf (_("All defined Ada exceptions:\n"));
 
   for (const ada_exc_info &info : exceptions)
-    printf_filtered ("%s: %s\n", info.name, paddress (gdbarch, info.addr));
+    gdb_printf ("%s: %s\n", info.name, paddress (gdbarch, info.addr));
 }
 
 \f
@@ -12668,6 +13261,10 @@ do_full_match (const char *symbol_search_name,
   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')
@@ -12867,7 +13464,7 @@ public:
     struct value *index_value = val_atr (index_type, index);
 
     value_print (index_value, stream, options);
-    fprintf_filtered (stream, " => ");
+    gdb_printf (stream, " => ");
   }
 
   /* Implement the "read_var_value" language_defn method for Ada.  */
@@ -12890,6 +13487,12 @@ public:
     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
@@ -12909,9 +13512,11 @@ public:
     add (arch_integer_type (gdbarch, gdbarch_short_bit (gdbarch),
                            0, "short_integer"));
     struct type *char_type = arch_character_type (gdbarch, TARGET_CHAR_BIT,
-                                                 0, "character");
+                                                 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),
@@ -12962,8 +13567,9 @@ public:
   }
 
   /* See language.h.  */
-  bool sniff_from_mangled_name (const char *mangled,
-                               char **out) const override
+  bool sniff_from_mangled_name
+       (const char *mangled,
+       gdb::unique_xmalloc_ptr<char> *out) const override
   {
     std::string demangled = ada_decode (mangled);
 
@@ -13001,9 +13607,10 @@ public:
 
   /* See language.h.  */
 
-  char *demangle_symbol (const char *mangled, int options) const override
+  gdb::unique_xmalloc_ptr<char> demangle_symbol (const char *mangled,
+                                                int options) const override
   {
-    return ada_la_decode (mangled, options);
+    return make_unique_xstrdup (ada_decode (mangled).c_str ());
   }
 
   /* See language.h.  */
@@ -13043,6 +13650,7 @@ public:
                             lookup_name,
                             NULL,
                             NULL,
+                            SEARCH_GLOBAL_BLOCK | SEARCH_STATIC_BLOCK,
                             ALL_DOMAIN);
 
     /* At this point scan through the misc symbol vectors and add each
@@ -13086,9 +13694,9 @@ public:
     /* Search upwards from currently selected frame (so that we can
        complete on local vars.  */
 
-    for (b = get_selected_block (0); b != NULL; b = BLOCK_SUPERBLOCK (b))
+    for (b = get_selected_block (0); b != NULL; b = b->superblock ())
       {
-       if (!BLOCK_SUPERBLOCK (b))
+       if (!b->superblock ())
          surrounding_static_block = b;   /* For elmin of dups */
 
        ALL_BLOCK_SYMBOLS (b, iter, sym)
@@ -13111,7 +13719,7 @@ public:
        for (compunit_symtab *s : objfile->compunits ())
          {
            QUIT;
-           b = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (s), GLOBAL_BLOCK);
+           b = s->blockvector ()->global_block ();
            ALL_BLOCK_SYMBOLS (b, iter, sym)
              {
                if (completion_skip_symbol (mode, sym))
@@ -13130,7 +13738,7 @@ public:
        for (compunit_symtab *s : objfile->compunits ())
          {
            QUIT;
-           b = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (s), STATIC_BLOCK);
+           b = s->blockvector ()->static_block ();
            /* Don't do this block twice.  */
            if (b == surrounding_static_block)
              continue;
@@ -13155,8 +13763,7 @@ public:
   {
     type = check_typedef (TYPE_TARGET_TYPE (check_typedef (type)));
     std::string name = type_to_string (type);
-    return gdb::unique_xmalloc_ptr<char>
-      (xstrprintf ("{%s} %s", name.c_str (), core_addr_to_string (addr)));
+    return xstrprintf ("{%s} %s", name.c_str (), core_addr_to_string (addr));
   }
 
   /* See language.h.  */
@@ -13305,54 +13912,6 @@ static ada_language ada_language_defn;
 static struct cmd_list_element *set_ada_list;
 static struct cmd_list_element *show_ada_list;
 
-static void
-initialize_ada_catchpoint_ops (void)
-{
-  struct breakpoint_ops *ops;
-
-  initialize_breakpoint_ops ();
-
-  ops = &catch_exception_breakpoint_ops;
-  *ops = bkpt_breakpoint_ops;
-  ops->allocate_location = allocate_location_exception;
-  ops->re_set = re_set_exception;
-  ops->check_status = check_status_exception;
-  ops->print_it = print_it_exception;
-  ops->print_one = print_one_exception;
-  ops->print_mention = print_mention_exception;
-  ops->print_recreate = print_recreate_exception;
-
-  ops = &catch_exception_unhandled_breakpoint_ops;
-  *ops = bkpt_breakpoint_ops;
-  ops->allocate_location = allocate_location_exception;
-  ops->re_set = re_set_exception;
-  ops->check_status = check_status_exception;
-  ops->print_it = print_it_exception;
-  ops->print_one = print_one_exception;
-  ops->print_mention = print_mention_exception;
-  ops->print_recreate = print_recreate_exception;
-
-  ops = &catch_assert_breakpoint_ops;
-  *ops = bkpt_breakpoint_ops;
-  ops->allocate_location = allocate_location_exception;
-  ops->re_set = re_set_exception;
-  ops->check_status = check_status_exception;
-  ops->print_it = print_it_exception;
-  ops->print_one = print_one_exception;
-  ops->print_mention = print_mention_exception;
-  ops->print_recreate = print_recreate_exception;
-
-  ops = &catch_handlers_breakpoint_ops;
-  *ops = bkpt_breakpoint_ops;
-  ops->allocate_location = allocate_location_exception;
-  ops->re_set = re_set_exception;
-  ops->check_status = check_status_exception;
-  ops->print_it = print_it_exception;
-  ops->print_one = print_one_exception;
-  ops->print_mention = print_mention_exception;
-  ops->print_recreate = print_recreate_exception;
-}
-
 /* This module's 'new_objfile' observer.  */
 
 static void
@@ -13369,19 +13928,36 @@ 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 ()
 {
-  initialize_ada_catchpoint_ops ();
-
-  add_basic_prefix_cmd ("ada", no_class,
-                       _("Prefix command for changing Ada-specific settings."),
-                       &set_ada_list, "set ada ", 0, &setlist);
-
-  add_show_prefix_cmd ("ada", no_class,
-                      _("Generic command for showing Ada-specific settings."),
-                      &show_ada_list, "show ada ", 0, &showlist);
+  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, _("\
@@ -13405,6 +13981,17 @@ 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\
@@ -13442,15 +14029,6 @@ exception should cause a stop."),
                     CATCH_PERMANENT,
                     CATCH_TEMPORARY);
 
-  varsize_limit = 65536;
-  add_setshow_uinteger_cmd ("varsize-limit", class_support,
-                           &varsize_limit, _("\
-Set the maximum number of bytes allowed in a variable-size object."), _("\
-Show the maximum number of bytes allowed in a variable-size object."), _("\
-Attempts to access an object whose size is not a compile-time constant\n\
-and exceeds this limit will cause an error."),
-                           NULL, NULL, &setlist, &showlist);
-
   add_info ("exceptions", info_exceptions_command,
            _("\
 List all Ada exception names.\n\
@@ -13458,15 +14036,11 @@ Usage: info exceptions [REGEXP]\n\
 If a regular expression is passed as an argument, only those matching\n\
 the regular expression are listed."));
 
-  add_basic_prefix_cmd ("ada", class_maintenance,
-                       _("Set Ada maintenance-related variables."),
-                       &maint_set_ada_cmdlist, "maintenance set ada ",
-                       0/*allow-unknown*/, &maintenance_set_cmdlist);
-
-  add_show_prefix_cmd ("ada", class_maintenance,
-                      _("Show Ada maintenance-related variables."),
-                      &maint_show_ada_cmdlist, "maintenance show ada ",
-                      0/*allow-unknown*/, &maintenance_show_cmdlist);
+  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,
@@ -13478,11 +14052,12 @@ 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, streq_hash,
+  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);
-  gdb::observers::free_objfile.attach (ada_free_objfile_observer);
-  gdb::observers::inferior_exit.attach (ada_inferior_exit);
+  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");
 }