]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/c-lang.c
gdb: Convert language la_language_arch_info field to a method
[thirdparty/binutils-gdb.git] / gdb / c-lang.c
index 695b2371d046178b3e207700d8ddd92b1002c0ff..e82d058777ed9ff2a15f1ff167feb278c7a96bd0 100644 (file)
@@ -1,6 +1,6 @@
 /* C language support routines for GDB, the GNU debugger.
 
-   Copyright (C) 1992-2017 Free Software Foundation, Inc.
+   Copyright (C) 1992-2020 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -25,6 +25,7 @@
 #include "language.h"
 #include "varobj.h"
 #include "c-lang.h"
+#include "c-support.h"
 #include "valprint.h"
 #include "macroscope.h"
 #include "charset.h"
@@ -34,8 +35,7 @@
 #include "gdb_obstack.h"
 #include <ctype.h>
 #include "gdbcore.h"
-
-extern void _initialize_c_language (void);
+#include "gdbarch.h"
 
 /* Given a C string type, STR_TYPE, return the corresponding target
    character set name.  */
@@ -84,9 +84,9 @@ classify_type (struct type *elttype, struct gdbarch *gdbarch,
      that would do the wrong thing.  */
   while (elttype)
     {
-      const char *name = TYPE_NAME (elttype);
+      const char *name = elttype->name ();
 
-      if (TYPE_CODE (elttype) == TYPE_CODE_CHAR || !name)
+      if (elttype->code () == TYPE_CODE_CHAR || !name)
        {
          result = C_CHAR;
          goto done;
@@ -110,7 +110,7 @@ classify_type (struct type *elttype, struct gdbarch *gdbarch,
          goto done;
        }
 
-      if (TYPE_CODE (elttype) != TYPE_CODE_TYPEDEF)
+      if (elttype->code () != TYPE_CODE_TYPEDEF)
        break;
 
       /* Call for side effects.  */
@@ -235,7 +235,7 @@ c_printstr (struct ui_file *stream, struct type *type,
    target charset.  */
 
 void
-c_get_string (struct value *value, gdb_byte **buffer,
+c_get_string (struct value *value, gdb::unique_xmalloc_ptr<gdb_byte> *buffer,
              int *length, struct type **char_type,
              const char **charset)
 {
@@ -245,17 +245,17 @@ c_get_string (struct value *value, gdb_byte **buffer,
   struct type *element_type = TYPE_TARGET_TYPE (type);
   int req_length = *length;
   enum bfd_endian byte_order
-    = gdbarch_byte_order (get_type_arch (type));
+    = type_byte_order (type);
 
   if (element_type == NULL)
     goto error;
 
-  if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+  if (type->code () == TYPE_CODE_ARRAY)
     {
       /* If we know the size of the array, we can use it as a limit on
         the number of characters to be fetched.  */
-      if (TYPE_NFIELDS (type) == 1
-         && TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_RANGE)
+      if (type->num_fields () == 1
+         && TYPE_FIELD_TYPE (type, 0)->code () == TYPE_CODE_RANGE)
        {
          LONGEST low_bound, high_bound;
 
@@ -266,7 +266,7 @@ c_get_string (struct value *value, gdb_byte **buffer,
       else
        fetchlimit = UINT_MAX;
     }
-  else if (TYPE_CODE (type) == TYPE_CODE_PTR)
+  else if (type->code () == TYPE_CODE_PTR)
     fetchlimit = UINT_MAX;
   else
     /* We work only with arrays and pointers.  */
@@ -280,10 +280,21 @@ c_get_string (struct value *value, gdb_byte **buffer,
   /* If the string lives in GDB's memory instead of the inferior's,
      then we just need to copy it to BUFFER.  Also, since such strings
      are arrays with known size, FETCHLIMIT will hold the size of the
-     array.  */
+     array.
+
+     An array is assumed to live in GDB's memory, so we take this path
+     here.
+
+     However, it's possible for the caller to request more array
+     elements than apparently exist -- this can happen when using the
+     C struct hack.  So, only do this if either no length was
+     specified, or the length is within the existing bounds.  This
+     avoids running off the end of the value's contents.  */
   if ((VALUE_LVAL (value) == not_lval
-       || VALUE_LVAL (value) == lval_internalvar)
-      && fetchlimit != UINT_MAX)
+       || VALUE_LVAL (value) == lval_internalvar
+       || type->code () == TYPE_CODE_ARRAY)
+      && fetchlimit != UINT_MAX
+      && (*length < 0 || *length <= fetchlimit))
     {
       int i;
       const gdb_byte *contents = value_contents (value);
@@ -292,22 +303,34 @@ c_get_string (struct value *value, gdb_byte **buffer,
       if (*length >= 0)
        i  = *length;
       else
-       /* Otherwise, look for a null character.  */
-       for (i = 0; i < fetchlimit; i++)
+       /* Otherwise, look for a null character.  */
+       for (i = 0; i < fetchlimit; i++)
          if (extract_unsigned_integer (contents + i * width,
                                        width, byte_order) == 0)
-           break;
+           break;
   
       /* I is now either a user-defined length, the number of non-null
-        characters, or FETCHLIMIT.  */
+        characters, or FETCHLIMIT.  */
       *length = i * width;
-      *buffer = (gdb_byte *) xmalloc (*length);
-      memcpy (*buffer, contents, *length);
+      buffer->reset ((gdb_byte *) xmalloc (*length));
+      memcpy (buffer->get (), contents, *length);
       err = 0;
     }
   else
     {
-      CORE_ADDR addr = value_as_address (value);
+      /* value_as_address does not return an address for an array when
+        c_style_arrays is false, so we handle that specially
+        here.  */
+      CORE_ADDR addr;
+      if (type->code () == TYPE_CODE_ARRAY)
+       {
+         if (VALUE_LVAL (value) != lval_memory)
+           error (_("Attempt to take address of value "
+                    "not located in memory."));
+         addr = value_address (value);
+       }
+      else
+       addr = value_as_address (value);
 
       /* Prior to the fix for PR 16196 read_string would ignore fetchlimit
         if length > 0.  The old "broken" behaviour is the behaviour we want:
@@ -327,10 +350,7 @@ c_get_string (struct value *value, gdb_byte **buffer,
       err = read_string (addr, *length, width, fetchlimit,
                         byte_order, buffer, length);
       if (err != 0)
-       {
-         xfree (*buffer);
-         memory_error (TARGET_XFER_E_IO, addr);
-       }
+       memory_error (TARGET_XFER_E_IO, addr);
     }
 
   /* If the LENGTH is specified at -1, we want to return the string
@@ -340,7 +360,7 @@ c_get_string (struct value *value, gdb_byte **buffer,
   if (req_length == -1)
     /* If the last character is null, subtract it from LENGTH.  */
     if (*length > 0
-       && extract_unsigned_integer (*buffer + *length - width,
+       && extract_unsigned_integer (buffer->get () + *length - width,
                                     width, byte_order) == 0)
       *length -= width;
   
@@ -384,7 +404,7 @@ convert_ucn (char *p, char *limit, const char *dest_charset,
   gdb_byte data[4];
   int i;
 
-  for (i = 0; i < length && p < limit && isxdigit (*p); ++i, ++p)
+  for (i = 0; i < length && p < limit && ISXDIGIT (*p); ++i, ++p)
     result = (result << 4) + host_hex_value (*p);
 
   for (i = 3; i >= 0; --i)
@@ -426,7 +446,7 @@ convert_octal (struct type *type, char *p,
   unsigned long value = 0;
 
   for (i = 0;
-       i < 3 && p < limit && isdigit (*p) && *p != '8' && *p != '9';
+       i < 3 && p < limit && ISDIGIT (*p) && *p != '8' && *p != '9';
        ++i)
     {
       value = 8 * value + host_hex_value (*p);
@@ -449,7 +469,7 @@ convert_hex (struct type *type, char *p,
 {
   unsigned long value = 0;
 
-  while (p < limit && isxdigit (*p))
+  while (p < limit && ISXDIGIT (*p))
     {
       value = 16 * value + host_hex_value (*p);
       ++p;
@@ -490,7 +510,7 @@ convert_escape (struct type *type, const char *dest_charset,
 
     case 'x':
       ADVANCE;
-      if (!isxdigit (*p))
+      if (!ISXDIGIT (*p))
        error (_("\\x used with no following hex digits."));
       p = convert_hex (type, p, limit, output);
       break;
@@ -512,7 +532,7 @@ convert_escape (struct type *type, const char *dest_charset,
        int length = *p == 'u' ? 4 : 8;
 
        ADVANCE;
-       if (!isxdigit (*p))
+       if (!ISXDIGIT (*p))
          error (_("\\u used with no following hex digits"));
        p = convert_ucn (p, limit, dest_charset, output, length);
       }
@@ -591,16 +611,13 @@ evaluate_subexp_c (struct type *expect_type, struct expression *exp,
                                              exp->gdbarch);
            break;
          case C_WIDE_STRING:
-           type = lookup_typename (exp->language_defn, exp->gdbarch,
-                                   "wchar_t", NULL, 0);
+           type = lookup_typename (exp->language_defn, "wchar_t", NULL, 0);
            break;
          case C_STRING_16:
-           type = lookup_typename (exp->language_defn, exp->gdbarch,
-                                   "char16_t", NULL, 0);
+           type = lookup_typename (exp->language_defn, "char16_t", NULL, 0);
            break;
          case C_STRING_32:
-           type = lookup_typename (exp->language_defn, exp->gdbarch,
-                                   "char32_t", NULL, 0);
+           type = lookup_typename (exp->language_defn, "char32_t", NULL, 0);
            break;
          default:
            internal_error (__FILE__, __LINE__, _("unhandled c_string_type"));
@@ -612,13 +629,13 @@ evaluate_subexp_c (struct type *expect_type, struct expression *exp,
        /* If the caller expects an array of some integral type,
           satisfy them.  If something odder is expected, rely on the
           caller to cast.  */
-       if (expect_type && TYPE_CODE (expect_type) == TYPE_CODE_ARRAY)
+       if (expect_type && expect_type->code () == TYPE_CODE_ARRAY)
          {
            struct type *element_type
              = check_typedef (TYPE_TARGET_TYPE (expect_type));
 
-           if (TYPE_CODE (element_type) == TYPE_CODE_INT
-               || TYPE_CODE (element_type) == TYPE_CODE_CHAR)
+           if (element_type->code () == TYPE_CODE_INT
+               || element_type->code () == TYPE_CODE_CHAR)
              {
                type = element_type;
                satisfy_expected = 1;
@@ -719,6 +736,42 @@ c_watch_location_expression (struct type *type, CORE_ADDR addr)
     (xstrprintf ("* (%s *) %s", name.c_str (), core_addr_to_string (addr)));
 }
 
+/* See c-lang.h.  */
+
+bool
+c_is_string_type_p (struct type *type)
+{
+  type = check_typedef (type);
+  while (type->code () == TYPE_CODE_REF)
+    {
+      type = TYPE_TARGET_TYPE (type);
+      type = check_typedef (type);
+    }
+
+  switch (type->code ())
+    {
+    case TYPE_CODE_ARRAY:
+      {
+       /* See if target type looks like a string.  */
+       struct type *array_target_type = TYPE_TARGET_TYPE (type);
+       return (TYPE_LENGTH (type) > 0
+               && TYPE_LENGTH (array_target_type) > 0
+               && c_textual_element_type (array_target_type, 0));
+      }
+    case TYPE_CODE_STRING:
+      return true;
+    case TYPE_CODE_PTR:
+      {
+       struct type *element_type = TYPE_TARGET_TYPE (type);
+       return c_textual_element_type (element_type, 0);
+      }
+    default:
+      break;
+    }
+
+  return false;
+}
+
 \f
 /* Table mapping opcodes into strings for printing operators
    and precedences of the operators.  */
@@ -753,6 +806,7 @@ const struct op_print c_op_print_tab[] =
   {"*", UNOP_IND, PREC_PREFIX, 0},
   {"&", UNOP_ADDR, PREC_PREFIX, 0},
   {"sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0},
+  {"alignof ", UNOP_ALIGNOF, PREC_PREFIX, 0},
   {"++", UNOP_PREINCREMENT, PREC_PREFIX, 0},
   {"--", UNOP_PREDECREMENT, PREC_PREFIX, 0},
   {NULL, OP_NULL, PREC_PREFIX, 0}
@@ -831,7 +885,9 @@ static const char *c_extensions[] =
   ".c", NULL
 };
 
-const struct language_defn c_language_defn =
+/* Constant data that describes the C language.  */
+
+extern const struct language_data c_language_data =
 {
   "c",                         /* Language name */
   "C",
@@ -843,18 +899,17 @@ const struct language_defn c_language_defn =
   c_extensions,
   &exp_descriptor_c,
   c_parse,
-  c_yyerror,
   null_post_parser,
   c_printchar,                 /* Print a character constant */
   c_printstr,                  /* Function to print string constant */
   c_emit_char,                 /* Print a single char */
   c_print_type,                        /* Print a type using appropriate syntax */
   c_print_typedef,             /* Print a typedef using appropriate syntax */
-  c_val_print,                 /* Print a value using appropriate syntax */
+  c_value_print_inner,         /* la_value_print_inner */
   c_value_print,               /* Print a top-level value */
-  default_read_var_value,      /* la_read_var_value */
   NULL,                                /* Language specific skip_trampoline */
   NULL,                                /* name_of_this */
+  true,                                /* la_store_sym_names_in_linkage_form_p */
   basic_lookup_symbol_nonlocal,        /* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   NULL,                                /* Language specific symbol demangler */
@@ -866,19 +921,38 @@ const struct language_defn c_language_defn =
   0,                           /* String lower bound */
   default_word_break_characters,
   default_collect_symbol_completion_matches,
-  c_language_arch_info,
-  default_print_array_index,
-  default_pass_by_reference,
-  c_get_string,
   c_watch_location_expression,
-  NULL,                                /* la_get_symbol_name_cmp */
+  NULL,                                /* la_get_symbol_name_matcher */
   iterate_over_symbols,
+  default_search_name_hash,
   &c_varobj_ops,
   c_get_compile_context,
   c_compute_program,
-  LANG_MAGIC
+  c_is_string_type_p,
+  "{...}"                      /* la_struct_too_deep_ellipsis */
 };
 
+/* Class representing the C language.  */
+
+class c_language : public language_defn
+{
+public:
+  c_language ()
+    : language_defn (language_c, c_language_data)
+  { /* Nothing.  */ }
+
+  /* See language.h.  */
+  void language_arch_info (struct gdbarch *gdbarch,
+                          struct language_arch_info *lai) const override
+  {
+    c_language_arch_info (gdbarch, lai);
+  }
+};
+
+/* Single instance of the C language class.  */
+
+static c_language c_language_defn;
+
 enum cplus_primitive_types {
   cplus_primitive_type_int,
   cplus_primitive_type_long,
@@ -907,75 +981,14 @@ enum cplus_primitive_types {
   nr_cplus_primitive_types
 };
 
-static void
-cplus_language_arch_info (struct gdbarch *gdbarch,
-                         struct language_arch_info *lai)
-{
-  const struct builtin_type *builtin = builtin_type (gdbarch);
-
-  lai->string_char_type = builtin->builtin_char;
-  lai->primitive_type_vector
-    = GDBARCH_OBSTACK_CALLOC (gdbarch, nr_cplus_primitive_types + 1,
-                             struct type *);
-  lai->primitive_type_vector [cplus_primitive_type_int]
-    = builtin->builtin_int;
-  lai->primitive_type_vector [cplus_primitive_type_long]
-    = builtin->builtin_long;
-  lai->primitive_type_vector [cplus_primitive_type_short]
-    = builtin->builtin_short;
-  lai->primitive_type_vector [cplus_primitive_type_char]
-    = builtin->builtin_char;
-  lai->primitive_type_vector [cplus_primitive_type_float]
-    = builtin->builtin_float;
-  lai->primitive_type_vector [cplus_primitive_type_double]
-    = builtin->builtin_double;
-  lai->primitive_type_vector [cplus_primitive_type_void]
-    = builtin->builtin_void;
-  lai->primitive_type_vector [cplus_primitive_type_long_long]
-    = builtin->builtin_long_long;
-  lai->primitive_type_vector [cplus_primitive_type_signed_char]
-    = builtin->builtin_signed_char;
-  lai->primitive_type_vector [cplus_primitive_type_unsigned_char]
-    = builtin->builtin_unsigned_char;
-  lai->primitive_type_vector [cplus_primitive_type_unsigned_short]
-    = builtin->builtin_unsigned_short;
-  lai->primitive_type_vector [cplus_primitive_type_unsigned_int]
-    = builtin->builtin_unsigned_int;
-  lai->primitive_type_vector [cplus_primitive_type_unsigned_long]
-    = builtin->builtin_unsigned_long;
-  lai->primitive_type_vector [cplus_primitive_type_unsigned_long_long]
-    = builtin->builtin_unsigned_long_long;
-  lai->primitive_type_vector [cplus_primitive_type_long_double]
-    = builtin->builtin_long_double;
-  lai->primitive_type_vector [cplus_primitive_type_complex]
-    = builtin->builtin_complex;
-  lai->primitive_type_vector [cplus_primitive_type_double_complex]
-    = builtin->builtin_double_complex;
-  lai->primitive_type_vector [cplus_primitive_type_bool]
-    = builtin->builtin_bool;
-  lai->primitive_type_vector [cplus_primitive_type_decfloat]
-    = builtin->builtin_decfloat;
-  lai->primitive_type_vector [cplus_primitive_type_decdouble]
-    = builtin->builtin_decdouble;
-  lai->primitive_type_vector [cplus_primitive_type_declong]
-    = builtin->builtin_declong;
-  lai->primitive_type_vector [cplus_primitive_type_char16_t]
-    = builtin->builtin_char16;
-  lai->primitive_type_vector [cplus_primitive_type_char32_t]
-    = builtin->builtin_char32;
-  lai->primitive_type_vector [cplus_primitive_type_wchar_t]
-    = builtin->builtin_wchar;
-
-  lai->bool_type_symbol = "bool";
-  lai->bool_type_default = builtin->builtin_bool;
-}
-
 static const char *cplus_extensions[] =
 {
   ".C", ".cc", ".cp", ".cpp", ".cxx", ".c++", NULL
 };
 
-const struct language_defn cplus_language_defn =
+/* Constant data that describes the C++ language.  */
+
+extern const struct language_data cplus_language_data =
 {
   "c++",                       /* Language name */
   "C++",
@@ -987,18 +1000,17 @@ const struct language_defn cplus_language_defn =
   cplus_extensions,
   &exp_descriptor_c,
   c_parse,
-  c_yyerror,
   null_post_parser,
   c_printchar,                 /* Print a character constant */
   c_printstr,                  /* Function to print string constant */
   c_emit_char,                 /* Print a single char */
   c_print_type,                        /* Print a type using appropriate syntax */
   c_print_typedef,             /* Print a typedef using appropriate syntax */
-  c_val_print,                 /* Print a value using appropriate syntax */
+  c_value_print_inner,         /* la_value_print_inner */
   c_value_print,               /* Print a top-level value */
-  default_read_var_value,      /* la_read_var_value */
   cplus_skip_trampoline,       /* Language specific skip_trampoline */
   "this",                       /* name_of_this */
+  false,                       /* la_store_sym_names_in_linkage_form_p */
   cp_lookup_symbol_nonlocal,   /* lookup_symbol_nonlocal */
   cp_lookup_transparent_type,   /* lookup_transparent_type */
   gdb_demangle,                        /* Language specific symbol demangler */
@@ -1010,25 +1022,110 @@ const struct language_defn cplus_language_defn =
   0,                           /* String lower bound */
   default_word_break_characters,
   default_collect_symbol_completion_matches,
-  cplus_language_arch_info,
-  default_print_array_index,
-  cp_pass_by_reference,
-  c_get_string,
   c_watch_location_expression,
-  NULL,                                /* la_get_symbol_name_cmp */
+  cp_get_symbol_name_matcher,
   iterate_over_symbols,
+  cp_search_name_hash,
   &cplus_varobj_ops,
-  NULL,
-  NULL,
-  LANG_MAGIC
+  cplus_get_compile_context,
+  cplus_compute_program,
+  c_is_string_type_p,
+  "{...}"                      /* la_struct_too_deep_ellipsis */
+};
+
+/* A class for the C++ language.  */
+
+class cplus_language : public language_defn
+{
+public:
+  cplus_language ()
+    : language_defn (language_cplus, cplus_language_data)
+  { /* Nothing.  */ }
+
+  /* See language.h.  */
+
+  struct language_pass_by_ref_info pass_by_reference_info
+       (struct type *type) const override
+  {
+    return cp_pass_by_reference (type);
+  }
+
+  /* See language.h.  */
+  void language_arch_info (struct gdbarch *gdbarch,
+                          struct language_arch_info *lai) const override
+  {
+    const struct builtin_type *builtin = builtin_type (gdbarch);
+
+    lai->string_char_type = builtin->builtin_char;
+    lai->primitive_type_vector
+      = GDBARCH_OBSTACK_CALLOC (gdbarch, nr_cplus_primitive_types + 1,
+                               struct type *);
+    lai->primitive_type_vector [cplus_primitive_type_int]
+      = builtin->builtin_int;
+    lai->primitive_type_vector [cplus_primitive_type_long]
+      = builtin->builtin_long;
+    lai->primitive_type_vector [cplus_primitive_type_short]
+      = builtin->builtin_short;
+    lai->primitive_type_vector [cplus_primitive_type_char]
+      = builtin->builtin_char;
+    lai->primitive_type_vector [cplus_primitive_type_float]
+      = builtin->builtin_float;
+    lai->primitive_type_vector [cplus_primitive_type_double]
+      = builtin->builtin_double;
+    lai->primitive_type_vector [cplus_primitive_type_void]
+      = builtin->builtin_void;
+    lai->primitive_type_vector [cplus_primitive_type_long_long]
+      = builtin->builtin_long_long;
+    lai->primitive_type_vector [cplus_primitive_type_signed_char]
+      = builtin->builtin_signed_char;
+    lai->primitive_type_vector [cplus_primitive_type_unsigned_char]
+      = builtin->builtin_unsigned_char;
+    lai->primitive_type_vector [cplus_primitive_type_unsigned_short]
+      = builtin->builtin_unsigned_short;
+    lai->primitive_type_vector [cplus_primitive_type_unsigned_int]
+      = builtin->builtin_unsigned_int;
+    lai->primitive_type_vector [cplus_primitive_type_unsigned_long]
+      = builtin->builtin_unsigned_long;
+    lai->primitive_type_vector [cplus_primitive_type_unsigned_long_long]
+      = builtin->builtin_unsigned_long_long;
+    lai->primitive_type_vector [cplus_primitive_type_long_double]
+      = builtin->builtin_long_double;
+    lai->primitive_type_vector [cplus_primitive_type_complex]
+      = builtin->builtin_complex;
+    lai->primitive_type_vector [cplus_primitive_type_double_complex]
+      = builtin->builtin_double_complex;
+    lai->primitive_type_vector [cplus_primitive_type_bool]
+      = builtin->builtin_bool;
+    lai->primitive_type_vector [cplus_primitive_type_decfloat]
+      = builtin->builtin_decfloat;
+    lai->primitive_type_vector [cplus_primitive_type_decdouble]
+      = builtin->builtin_decdouble;
+    lai->primitive_type_vector [cplus_primitive_type_declong]
+      = builtin->builtin_declong;
+    lai->primitive_type_vector [cplus_primitive_type_char16_t]
+      = builtin->builtin_char16;
+    lai->primitive_type_vector [cplus_primitive_type_char32_t]
+      = builtin->builtin_char32;
+    lai->primitive_type_vector [cplus_primitive_type_wchar_t]
+      = builtin->builtin_wchar;
+
+    lai->bool_type_symbol = "bool";
+    lai->bool_type_default = builtin->builtin_bool;
+  }
 };
 
+/* The single instance of the C++ language class.  */
+
+static cplus_language cplus_language_defn;
+
 static const char *asm_extensions[] =
 {
   ".s", ".sx", ".S", NULL
 };
 
-const struct language_defn asm_language_defn =
+/* Constant data that describes the ASM language.  */
+
+extern const struct language_data asm_language_data =
 {
   "asm",                       /* Language name */
   "assembly",
@@ -1040,18 +1137,17 @@ const struct language_defn asm_language_defn =
   asm_extensions,
   &exp_descriptor_c,
   c_parse,
-  c_yyerror,
   null_post_parser,
   c_printchar,                 /* Print a character constant */
   c_printstr,                  /* Function to print string constant */
   c_emit_char,                 /* Print a single char */
   c_print_type,                        /* Print a type using appropriate syntax */
   c_print_typedef,             /* Print a typedef using appropriate syntax */
-  c_val_print,                 /* Print a value using appropriate syntax */
+  c_value_print_inner,         /* la_value_print_inner */
   c_value_print,               /* Print a top-level value */
-  default_read_var_value,      /* la_read_var_value */
   NULL,                                /* Language specific skip_trampoline */
   NULL,                                /* name_of_this */
+  true,                                /* la_store_sym_names_in_linkage_form_p */
   basic_lookup_symbol_nonlocal,        /* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   NULL,                                /* Language specific symbol demangler */
@@ -1063,25 +1159,45 @@ const struct language_defn asm_language_defn =
   0,                           /* String lower bound */
   default_word_break_characters,
   default_collect_symbol_completion_matches,
-  c_language_arch_info,        /* FIXME: la_language_arch_info.  */
-  default_print_array_index,
-  default_pass_by_reference,
-  c_get_string,
   c_watch_location_expression,
-  NULL,                                /* la_get_symbol_name_cmp */
+  NULL,                                /* la_get_symbol_name_matcher */
   iterate_over_symbols,
+  default_search_name_hash,
   &default_varobj_ops,
   NULL,
   NULL,
-  LANG_MAGIC
+  c_is_string_type_p,
+  "{...}"                      /* la_struct_too_deep_ellipsis */
 };
 
+/* A class for the ASM language.  */
+
+class asm_language : public language_defn
+{
+public:
+  asm_language ()
+    : language_defn (language_asm, asm_language_data)
+  { /* Nothing.  */ }
+
+  /* See language.h.
+
+     FIXME: Should this have its own arch info method?  */
+  void language_arch_info (struct gdbarch *gdbarch,
+                          struct language_arch_info *lai) const override
+  {
+    c_language_arch_info (gdbarch, lai);
+  }
+};
+
+/* The single instance of the ASM language class.  */
+static asm_language asm_language_defn;
+
 /* The following language_defn does not represent a real language.
    It just provides a minimal support a-la-C that should allow users
    to do some simple operations when debugging applications that use
    a language currently not supported by GDB.  */
 
-const struct language_defn minimal_language_defn =
+extern const struct language_data minimal_language_data =
 {
   "minimal",                   /* Language name */
   "Minimal",
@@ -1093,18 +1209,17 @@ const struct language_defn minimal_language_defn =
   NULL,
   &exp_descriptor_c,
   c_parse,
-  c_yyerror,
   null_post_parser,
   c_printchar,                 /* Print a character constant */
   c_printstr,                  /* Function to print string constant */
   c_emit_char,                 /* Print a single char */
   c_print_type,                        /* Print a type using appropriate syntax */
   c_print_typedef,             /* Print a typedef using appropriate syntax */
-  c_val_print,                 /* Print a value using appropriate syntax */
+  c_value_print_inner,         /* la_value_print_inner */
   c_value_print,               /* Print a top-level value */
-  default_read_var_value,      /* la_read_var_value */
   NULL,                                /* Language specific skip_trampoline */
   NULL,                                /* name_of_this */
+  true,                                /* la_store_sym_names_in_linkage_form_p */
   basic_lookup_symbol_nonlocal,        /* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   NULL,                                /* Language specific symbol demangler */
@@ -1116,24 +1231,33 @@ const struct language_defn minimal_language_defn =
   0,                           /* String lower bound */
   default_word_break_characters,
   default_collect_symbol_completion_matches,
-  c_language_arch_info,
-  default_print_array_index,
-  default_pass_by_reference,
-  c_get_string,
   c_watch_location_expression,
-  NULL,                                /* la_get_symbol_name_cmp */
+  NULL,                                /* la_get_symbol_name_matcher */
   iterate_over_symbols,
+  default_search_name_hash,
   &default_varobj_ops,
   NULL,
   NULL,
-  LANG_MAGIC
+  c_is_string_type_p,
+  "{...}"                      /* la_struct_too_deep_ellipsis */
 };
 
-void
-_initialize_c_language (void)
+/* A class for the minimal language.  */
+
+class minimal_language : public language_defn
 {
-  add_language (&c_language_defn);
-  add_language (&cplus_language_defn);
-  add_language (&asm_language_defn);
-  add_language (&minimal_language_defn);
-}
+public:
+  minimal_language ()
+    : language_defn (language_minimal, minimal_language_data)
+  { /* Nothing.  */ }
+
+  /* See language.h.  */
+  void language_arch_info (struct gdbarch *gdbarch,
+                          struct language_arch_info *lai) const override
+  {
+    c_language_arch_info (gdbarch, lai);
+  }
+};
+
+/* The single instance of the minimal language class.  */
+static minimal_language minimal_language_defn;