Automatic date update in version.in
[deliverable/binutils-gdb.git] / gdb / c-lang.c
index 8d96f94cbb2d884c02085bd6d4078e288b0b4e15..98f4984b020e4d735f88baa7dfad6254ef2bbcf2 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-2021 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,6 +35,9 @@
 #include "gdb_obstack.h"
 #include <ctype.h>
 #include "gdbcore.h"
+#include "gdbarch.h"
+#include "compile/compile-internal.h"
+#include "c-exp.h"
 
 /* Given a C string type, STR_TYPE, return the corresponding target
    character set name.  */
@@ -82,9 +86,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;
@@ -108,7 +112,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.  */
@@ -145,16 +149,19 @@ c_emit_char (int c, struct type *type,
 {
   const char *encoding;
 
-  classify_type (type, get_type_arch (type), &encoding);
+  classify_type (type, type->arch (), &encoding);
   generic_emit_char (c, type, stream, quoter, encoding);
 }
 
+/* See language.h.  */
+
 void
-c_printchar (int c, struct type *type, struct ui_file *stream)
+language_defn::printchar (int c, struct type *type,
+                         struct ui_file * stream) const
 {
   c_string_type str_type;
 
-  str_type = classify_type (type, get_type_arch (type), NULL);
+  str_type = classify_type (type, type->arch (), NULL);
   switch (str_type)
     {
     case C_CHAR:
@@ -171,7 +178,7 @@ c_printchar (int c, struct type *type, struct ui_file *stream)
     }
 
   fputc_filtered ('\'', stream);
-  LA_EMIT_CHAR (c, type, stream, '\'');
+  emitchar (c, type, stream, '\'');
   fputc_filtered ('\'', stream);
 }
 
@@ -192,7 +199,7 @@ c_printstr (struct ui_file *stream, struct type *type,
   const char *type_encoding;
   const char *encoding;
 
-  str_type = (classify_type (type, get_type_arch (type), &type_encoding)
+  str_type = (classify_type (type, type->arch (), &type_encoding)
              & ~C_CHAR);
   switch (str_type)
     {
@@ -233,7 +240,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)
 {
@@ -243,28 +250,28 @@ 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 (0).type ()->code () == TYPE_CODE_RANGE)
        {
          LONGEST low_bound, high_bound;
 
-         get_discrete_bounds (TYPE_FIELD_TYPE (type, 0),
+         get_discrete_bounds (type->field (0).type (),
                               &low_bound, &high_bound);
          fetchlimit = high_bound - low_bound + 1;
        }
       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.  */
@@ -272,16 +279,27 @@ c_get_string (struct value *value, gdb_byte **buffer,
 
   if (! c_textual_element_type (element_type, 0))
     goto error;
-  classify_type (element_type, get_type_arch (element_type), charset);
+  classify_type (element_type, element_type->arch (), charset);
   width = TYPE_LENGTH (element_type);
 
   /* 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);
@@ -290,22 +308,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:
@@ -325,10 +355,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
@@ -338,7 +365,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;
   
@@ -374,15 +401,15 @@ c_get_string (struct value *value, gdb_byte **buffer,
    OUTPUT.  LENGTH is the maximum length of the UCN, either 4 or 8.
    Returns a pointer to just after the final digit of the UCN.  */
 
-static char *
-convert_ucn (char *p, char *limit, const char *dest_charset,
+static const char *
+convert_ucn (const char *p, const char *limit, const char *dest_charset,
             struct obstack *output, int length)
 {
   unsigned long result = 0;
   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)
@@ -416,15 +443,15 @@ emit_numeric_character (struct type *type, unsigned long value,
    farther than LIMIT.  The result is written to OUTPUT.  Returns a
    pointer to just after the final digit of the escape sequence.  */
 
-static char *
-convert_octal (struct type *type, char *p, 
-              char *limit, struct obstack *output)
+static const char *
+convert_octal (struct type *type, const char *p,
+              const char *limit, struct obstack *output)
 {
   int i;
   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);
@@ -441,13 +468,13 @@ convert_octal (struct type *type, char *p,
    than LIMIT.  The result is written to OUTPUT.  Returns a pointer to
    just after the final digit of the escape sequence.  */
 
-static char *
-convert_hex (struct type *type, char *p,
-            char *limit, struct obstack *output)
+static const char *
+convert_hex (struct type *type, const char *p,
+            const char *limit, struct obstack *output)
 {
   unsigned long value = 0;
 
-  while (p < limit && isxdigit (*p))
+  while (p < limit && ISXDIGIT (*p))
     {
       value = 16 * value + host_hex_value (*p);
       ++p;
@@ -472,9 +499,9 @@ convert_hex (struct type *type, char *p,
    written to OUTPUT.  Returns a pointer to just past the final
    character of the escape sequence.  */
 
-static char *
+static const char *
 convert_escape (struct type *type, const char *dest_charset,
-               char *p, char *limit, struct obstack *output)
+               const char *p, const char *limit, struct obstack *output)
 {
   /* Skip the backslash.  */
   ADVANCE;
@@ -488,7 +515,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;
@@ -510,7 +537,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);
       }
@@ -526,16 +553,16 @@ convert_escape (struct type *type, const char *dest_charset,
    and TYPE is the type of target character to use.  */
 
 static void
-parse_one_string (struct obstack *output, char *data, int len,
+parse_one_string (struct obstack *output, const char *data, int len,
                  const char *dest_charset, struct type *type)
 {
-  char *limit;
+  const char *limit;
 
   limit = data + len;
 
   while (data < limit)
     {
-      char *p = data;
+      const char *p = data;
 
       /* Look for next escape, or the end of the input.  */
       while (p < limit && *p != '\\')
@@ -543,7 +570,7 @@ parse_one_string (struct obstack *output, char *data, int len,
       /* If we saw a run of characters, convert them all.  */
       if (p > data)
        convert_between_encodings (host_charset (), dest_charset,
-                                  (gdb_byte *) data, p - data, 1,
+                                  (const gdb_byte *) data, p - data, 1,
                                   output, translit_none);
       /* If we saw an escape, convert it.  */
       if (p < limit)
@@ -552,233 +579,153 @@ parse_one_string (struct obstack *output, char *data, int len,
     }
 }
 
-/* Expression evaluator for the C language family.  Most operations
-   are delegated to evaluate_subexp_standard; see that function for a
-   description of the arguments.  */
+namespace expr
+{
 
-struct value *
-evaluate_subexp_c (struct type *expect_type, struct expression *exp,
-                  int *pos, enum noside noside)
+value *
+c_string_operation::evaluate (struct type *expect_type,
+                             struct expression *exp,
+                             enum noside noside)
 {
-  enum exp_opcode op = exp->elts[*pos].opcode;
+  struct type *type;
+  struct value *result;
+  c_string_type dest_type;
+  const char *dest_charset;
+  int satisfy_expected = 0;
 
-  switch (op)
+  auto_obstack output;
+
+  dest_type = std::get<0> (m_storage);
+
+  switch (dest_type & ~C_CHAR)
     {
-    case OP_STRING:
-      {
-       int oplen, limit;
-       struct type *type;
-       struct value *result;
-       c_string_type dest_type;
-       const char *dest_charset;
-       int satisfy_expected = 0;
-
-       auto_obstack output;
-
-       ++*pos;
-       oplen = longest_to_int (exp->elts[*pos].longconst);
-
-       ++*pos;
-       limit = *pos + BYTES_TO_EXP_ELEM (oplen + 1);
-       dest_type = ((enum c_string_type_values)
-                    longest_to_int (exp->elts[*pos].longconst));
-       switch (dest_type & ~C_CHAR)
-         {
-         case C_STRING:
-           type = language_string_char_type (exp->language_defn,
-                                             exp->gdbarch);
-           break;
-         case C_WIDE_STRING:
-           type = lookup_typename (exp->language_defn, exp->gdbarch,
-                                   "wchar_t", NULL, 0);
-           break;
-         case C_STRING_16:
-           type = lookup_typename (exp->language_defn, exp->gdbarch,
-                                   "char16_t", NULL, 0);
-           break;
-         case C_STRING_32:
-           type = lookup_typename (exp->language_defn, exp->gdbarch,
-                                   "char32_t", NULL, 0);
-           break;
-         default:
-           internal_error (__FILE__, __LINE__, _("unhandled c_string_type"));
-         }
-
-       /* Ensure TYPE_LENGTH is valid for TYPE.  */
-       check_typedef (type);
-
-       /* 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)
-         {
-           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)
-             {
-               type = element_type;
-               satisfy_expected = 1;
-             }
-         }
-
-       dest_charset = charset_for_string_type (dest_type, exp->gdbarch);
-
-       ++*pos;
-       while (*pos < limit)
-         {
-           int len;
-
-           len = longest_to_int (exp->elts[*pos].longconst);
-
-           ++*pos;
-           if (noside != EVAL_SKIP)
-             parse_one_string (&output, &exp->elts[*pos].string, len,
-                               dest_charset, type);
-           *pos += BYTES_TO_EXP_ELEM (len);
-         }
-
-       /* Skip the trailing length and opcode.  */
-       *pos += 2;
-
-       if (noside == EVAL_SKIP)
-         {
-           /* Return a dummy value of the appropriate type.  */
-           if (expect_type != NULL)
-             result = allocate_value (expect_type);
-           else if ((dest_type & C_CHAR) != 0)
-             result = allocate_value (type);
-           else
-             result = value_cstring ("", 0, type);
-           return result;
-         }
-
-       if ((dest_type & C_CHAR) != 0)
-         {
-           LONGEST value;
-
-           if (obstack_object_size (&output) != TYPE_LENGTH (type))
-             error (_("Could not convert character "
-                      "constant to target character set"));
-           value = unpack_long (type, (gdb_byte *) obstack_base (&output));
-           result = value_from_longest (type, value);
-         }
-       else
-         {
-           int i;
-
-           /* Write the terminating character.  */
-           for (i = 0; i < TYPE_LENGTH (type); ++i)
-             obstack_1grow (&output, 0);
-
-           if (satisfy_expected)
-             {
-               LONGEST low_bound, high_bound;
-               int element_size = TYPE_LENGTH (type);
-
-               if (get_discrete_bounds (TYPE_INDEX_TYPE (expect_type),
-                                        &low_bound, &high_bound) < 0)
-                 {
-                   low_bound = 0;
-                   high_bound = (TYPE_LENGTH (expect_type) / element_size) - 1;
-                 }
-               if (obstack_object_size (&output) / element_size
-                   > (high_bound - low_bound + 1))
-                 error (_("Too many array elements"));
-
-               result = allocate_value (expect_type);
-               memcpy (value_contents_raw (result), obstack_base (&output),
-                       obstack_object_size (&output));
-             }
-           else
-             result = value_cstring ((const char *) obstack_base (&output),
-                                     obstack_object_size (&output),
-                                     type);
-         }
-       return result;
-      }
+    case C_STRING:
+      type = language_string_char_type (exp->language_defn,
+                                       exp->gdbarch);
       break;
-
-    default:
+    case C_WIDE_STRING:
+      type = lookup_typename (exp->language_defn, "wchar_t", NULL, 0);
+      break;
+    case C_STRING_16:
+      type = lookup_typename (exp->language_defn, "char16_t", NULL, 0);
+      break;
+    case C_STRING_32:
+      type = lookup_typename (exp->language_defn, "char32_t", NULL, 0);
       break;
+    default:
+      internal_error (__FILE__, __LINE__, _("unhandled c_string_type"));
     }
-  return evaluate_subexp_standard (expect_type, exp, pos, noside);
-}
-\f
-/* la_watch_location_expression for C.  */
 
-gdb::unique_xmalloc_ptr<char>
-c_watch_location_expression (struct type *type, CORE_ADDR addr)
-{
-  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)));
+  /* Ensure TYPE_LENGTH is valid for TYPE.  */
+  check_typedef (type);
+
+  /* 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 && expect_type->code () == TYPE_CODE_ARRAY)
+    {
+      struct type *element_type
+       = check_typedef (TYPE_TARGET_TYPE (expect_type));
+
+      if (element_type->code () == TYPE_CODE_INT
+         || element_type->code () == TYPE_CODE_CHAR)
+       {
+         type = element_type;
+         satisfy_expected = 1;
+       }
+    }
+
+  dest_charset = charset_for_string_type (dest_type, exp->gdbarch);
+
+  for (const std::string &item : std::get<1> (m_storage))
+    parse_one_string (&output, item.c_str (), item.size (),
+                     dest_charset, type);
+
+  if ((dest_type & C_CHAR) != 0)
+    {
+      LONGEST value;
+
+      if (obstack_object_size (&output) != TYPE_LENGTH (type))
+       error (_("Could not convert character "
+                "constant to target character set"));
+      value = unpack_long (type, (gdb_byte *) obstack_base (&output));
+      result = value_from_longest (type, value);
+    }
+  else
+    {
+      int i;
+
+      /* Write the terminating character.  */
+      for (i = 0; i < TYPE_LENGTH (type); ++i)
+       obstack_1grow (&output, 0);
+
+      if (satisfy_expected)
+       {
+         LONGEST low_bound, high_bound;
+         int element_size = TYPE_LENGTH (type);
+
+         if (!get_discrete_bounds (expect_type->index_type (),
+                                   &low_bound, &high_bound))
+           {
+             low_bound = 0;
+             high_bound = (TYPE_LENGTH (expect_type) / element_size) - 1;
+           }
+         if (obstack_object_size (&output) / element_size
+             > (high_bound - low_bound + 1))
+           error (_("Too many array elements"));
+
+         result = allocate_value (expect_type);
+         memcpy (value_contents_raw (result), obstack_base (&output),
+                 obstack_object_size (&output));
+       }
+      else
+       result = value_cstring ((const char *) obstack_base (&output),
+                               obstack_object_size (&output),
+                               type);
+    }
+  return result;
 }
 
+} /* namespace expr */
+
 \f
-/* Table mapping opcodes into strings for printing operators
-   and precedences of the operators.  */
+/* See c-lang.h.  */
 
-const struct op_print c_op_print_tab[] =
+bool
+c_is_string_type_p (struct type *type)
 {
-  {",", BINOP_COMMA, PREC_COMMA, 0},
-  {"=", BINOP_ASSIGN, PREC_ASSIGN, 1},
-  {"||", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
-  {"&&", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
-  {"|", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0},
-  {"^", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0},
-  {"&", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0},
-  {"==", BINOP_EQUAL, PREC_EQUAL, 0},
-  {"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
-  {"<=", BINOP_LEQ, PREC_ORDER, 0},
-  {">=", BINOP_GEQ, PREC_ORDER, 0},
-  {">", BINOP_GTR, PREC_ORDER, 0},
-  {"<", BINOP_LESS, PREC_ORDER, 0},
-  {">>", BINOP_RSH, PREC_SHIFT, 0},
-  {"<<", BINOP_LSH, PREC_SHIFT, 0},
-  {"+", BINOP_ADD, PREC_ADD, 0},
-  {"-", BINOP_SUB, PREC_ADD, 0},
-  {"*", BINOP_MUL, PREC_MUL, 0},
-  {"/", BINOP_DIV, PREC_MUL, 0},
-  {"%", BINOP_REM, PREC_MUL, 0},
-  {"@", BINOP_REPEAT, PREC_REPEAT, 0},
-  {"+", UNOP_PLUS, PREC_PREFIX, 0},
-  {"-", UNOP_NEG, PREC_PREFIX, 0},
-  {"!", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
-  {"~", UNOP_COMPLEMENT, PREC_PREFIX, 0},
-  {"*", UNOP_IND, PREC_PREFIX, 0},
-  {"&", UNOP_ADDR, PREC_PREFIX, 0},
-  {"sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0},
-  {"++", UNOP_PREINCREMENT, PREC_PREFIX, 0},
-  {"--", UNOP_PREDECREMENT, PREC_PREFIX, 0},
-  {NULL, OP_NULL, PREC_PREFIX, 0}
-};
+  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
-enum c_primitive_types {
-  c_primitive_type_int,
-  c_primitive_type_long,
-  c_primitive_type_short,
-  c_primitive_type_char,
-  c_primitive_type_float,
-  c_primitive_type_double,
-  c_primitive_type_void,
-  c_primitive_type_long_long,
-  c_primitive_type_signed_char,
-  c_primitive_type_unsigned_char,
-  c_primitive_type_unsigned_short,
-  c_primitive_type_unsigned_int,
-  c_primitive_type_unsigned_long,
-  c_primitive_type_unsigned_long_long,
-  c_primitive_type_long_double,
-  c_primitive_type_complex,
-  c_primitive_type_double_complex,
-  c_primitive_type_decfloat,
-  c_primitive_type_decdouble,
-  c_primitive_type_declong,
-  nr_c_primitive_types
-};
 
 void
 c_language_arch_info (struct gdbarch *gdbarch,
@@ -786,347 +733,402 @@ c_language_arch_info (struct gdbarch *gdbarch,
 {
   const struct builtin_type *builtin = builtin_type (gdbarch);
 
-  lai->string_char_type = builtin->builtin_char;
-  lai->primitive_type_vector
-    = GDBARCH_OBSTACK_CALLOC (gdbarch, nr_c_primitive_types + 1,
-                             struct type *);
-  lai->primitive_type_vector [c_primitive_type_int] = builtin->builtin_int;
-  lai->primitive_type_vector [c_primitive_type_long] = builtin->builtin_long;
-  lai->primitive_type_vector [c_primitive_type_short] = builtin->builtin_short;
-  lai->primitive_type_vector [c_primitive_type_char] = builtin->builtin_char;
-  lai->primitive_type_vector [c_primitive_type_float] = builtin->builtin_float;
-  lai->primitive_type_vector [c_primitive_type_double] = builtin->builtin_double;
-  lai->primitive_type_vector [c_primitive_type_void] = builtin->builtin_void;
-  lai->primitive_type_vector [c_primitive_type_long_long] = builtin->builtin_long_long;
-  lai->primitive_type_vector [c_primitive_type_signed_char] = builtin->builtin_signed_char;
-  lai->primitive_type_vector [c_primitive_type_unsigned_char] = builtin->builtin_unsigned_char;
-  lai->primitive_type_vector [c_primitive_type_unsigned_short] = builtin->builtin_unsigned_short;
-  lai->primitive_type_vector [c_primitive_type_unsigned_int] = builtin->builtin_unsigned_int;
-  lai->primitive_type_vector [c_primitive_type_unsigned_long] = builtin->builtin_unsigned_long;
-  lai->primitive_type_vector [c_primitive_type_unsigned_long_long] = builtin->builtin_unsigned_long_long;
-  lai->primitive_type_vector [c_primitive_type_long_double] = builtin->builtin_long_double;
-  lai->primitive_type_vector [c_primitive_type_complex] = builtin->builtin_complex;
-  lai->primitive_type_vector [c_primitive_type_double_complex] = builtin->builtin_double_complex;
-  lai->primitive_type_vector [c_primitive_type_decfloat] = builtin->builtin_decfloat;
-  lai->primitive_type_vector [c_primitive_type_decdouble] = builtin->builtin_decdouble;
-  lai->primitive_type_vector [c_primitive_type_declong] = builtin->builtin_declong;
-
-  lai->bool_type_default = builtin->builtin_int;
+  /* Helper function to allow shorter lines below.  */
+  auto add  = [&] (struct type * t)
+  {
+    lai->add_primitive_type (t);
+  };
+
+  add (builtin->builtin_int);
+  add (builtin->builtin_long);
+  add (builtin->builtin_short);
+  add (builtin->builtin_char);
+  add (builtin->builtin_float);
+  add (builtin->builtin_double);
+  add (builtin->builtin_void);
+  add (builtin->builtin_long_long);
+  add (builtin->builtin_signed_char);
+  add (builtin->builtin_unsigned_char);
+  add (builtin->builtin_unsigned_short);
+  add (builtin->builtin_unsigned_int);
+  add (builtin->builtin_unsigned_long);
+  add (builtin->builtin_unsigned_long_long);
+  add (builtin->builtin_long_double);
+  add (builtin->builtin_complex);
+  add (builtin->builtin_double_complex);
+  add (builtin->builtin_decfloat);
+  add (builtin->builtin_decdouble);
+  add (builtin->builtin_declong);
+
+  lai->set_string_char_type (builtin->builtin_char);
+  lai->set_bool_type (builtin->builtin_int);
 }
 
-const struct exp_descriptor exp_descriptor_c = 
-{
-  print_subexp_standard,
-  operator_length_standard,
-  operator_check_standard,
-  op_name_standard,
-  dump_subexp_body_standard,
-  evaluate_subexp_c
-};
+/* Class representing the C language.  */
 
-static const char *c_extensions[] =
+class c_language : public language_defn
 {
-  ".c", NULL
-};
+public:
+  c_language ()
+    : language_defn (language_c)
+  { /* Nothing.  */ }
 
-extern const struct language_defn c_language_defn =
-{
-  "c",                         /* Language name */
-  "C",
-  language_c,
-  range_check_off,
-  case_sensitive_on,
-  array_row_major,
-  macro_expansion_c,
-  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,               /* Print a top-level value */
-  default_read_var_value,      /* la_read_var_value */
-  NULL,                                /* Language specific skip_trampoline */
-  NULL,                                /* name_of_this */
-  basic_lookup_symbol_nonlocal,        /* lookup_symbol_nonlocal */
-  basic_lookup_transparent_type,/* lookup_transparent_type */
-  NULL,                                /* Language specific symbol demangler */
-  NULL,
-  NULL,                                /* Language specific
-                                  class_name_from_physname */
-  c_op_print_tab,              /* expression operators for printing */
-  1,                           /* c-style arrays */
-  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_matcher */
-  iterate_over_symbols,
-  default_search_name_hash,
-  &c_varobj_ops,
-  c_get_compile_context,
-  c_compute_program,
-  LANG_MAGIC
-};
+  /* See language.h.  */
 
-enum cplus_primitive_types {
-  cplus_primitive_type_int,
-  cplus_primitive_type_long,
-  cplus_primitive_type_short,
-  cplus_primitive_type_char,
-  cplus_primitive_type_float,
-  cplus_primitive_type_double,
-  cplus_primitive_type_void,
-  cplus_primitive_type_long_long,
-  cplus_primitive_type_signed_char,
-  cplus_primitive_type_unsigned_char,
-  cplus_primitive_type_unsigned_short,
-  cplus_primitive_type_unsigned_int,
-  cplus_primitive_type_unsigned_long,
-  cplus_primitive_type_unsigned_long_long,
-  cplus_primitive_type_long_double,
-  cplus_primitive_type_complex,
-  cplus_primitive_type_double_complex,
-  cplus_primitive_type_bool,
-  cplus_primitive_type_decfloat,
-  cplus_primitive_type_decdouble,
-  cplus_primitive_type_declong,
-  cplus_primitive_type_char16_t,
-  cplus_primitive_type_char32_t,
-  cplus_primitive_type_wchar_t,
-  nr_cplus_primitive_types
-};
+  const char *name () const override
+  { return "c"; }
 
-static void
-cplus_language_arch_info (struct gdbarch *gdbarch,
-                         struct language_arch_info *lai)
-{
-  const struct builtin_type *builtin = builtin_type (gdbarch);
+  /* See language.h.  */
 
-  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;
-}
+  const char *natural_name () const override
+  { return "C"; }
 
-static const char *cplus_extensions[] =
-{
-  ".C", ".cc", ".cp", ".cpp", ".cxx", ".c++", NULL
-};
+  /* See language.h.  */
 
-extern const struct language_defn cplus_language_defn =
-{
-  "c++",                       /* Language name */
-  "C++",
-  language_cplus,
-  range_check_off,
-  case_sensitive_on,
-  array_row_major,
-  macro_expansion_c,
-  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,               /* Print a top-level value */
-  default_read_var_value,      /* la_read_var_value */
-  cplus_skip_trampoline,       /* Language specific skip_trampoline */
-  "this",                       /* name_of_this */
-  cp_lookup_symbol_nonlocal,   /* lookup_symbol_nonlocal */
-  cp_lookup_transparent_type,   /* lookup_transparent_type */
-  gdb_demangle,                        /* Language specific symbol demangler */
-  gdb_sniff_from_mangled_name,
-  cp_class_name_from_physname,  /* Language specific
-                                  class_name_from_physname */
-  c_op_print_tab,              /* expression operators for printing */
-  1,                           /* c-style arrays */
-  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,
-  cp_get_symbol_name_matcher,
-  iterate_over_symbols,
-  cp_search_name_hash,
-  &cplus_varobj_ops,
-  NULL,
-  NULL,
-  LANG_MAGIC
+  const std::vector<const char *> &filename_extensions () const override
+  {
+    static const std::vector<const char *> extensions = { ".c" };
+    return extensions;
+  }
+
+  /* See language.h.  */
+  void language_arch_info (struct gdbarch *gdbarch,
+                          struct language_arch_info *lai) const override
+  {
+    c_language_arch_info (gdbarch, lai);
+  }
+
+  /* See language.h.  */
+  std::unique_ptr<compile_instance> get_compile_instance () const override
+  {
+    return c_get_compile_context ();
+  }
+
+  /* See language.h.  */
+  std::string compute_program (compile_instance *inst,
+                              const char *input,
+                              struct gdbarch *gdbarch,
+                              const struct block *expr_block,
+                              CORE_ADDR expr_pc) const override
+  {
+    return c_compute_program (inst, input, gdbarch, expr_block, expr_pc);
+  }
+
+  /* See language.h.  */
+
+  void print_type (struct type *type, const char *varstring,
+                  struct ui_file *stream, int show, int level,
+                  const struct type_print_options *flags) const override
+  {
+    c_print_type (type, varstring, stream, show, level, flags);
+  }
+
+  /* See language.h.  */
+
+  bool store_sym_names_in_linkage_form_p () const override
+  { return true; }
+
+  /* See language.h.  */
+
+  enum macro_expansion macro_expansion () const override
+  { return macro_expansion_c; }
 };
 
-static const char *asm_extensions[] =
+/* Single instance of the C language class.  */
+
+static c_language c_language_defn;
+
+/* A class for the C++ language.  */
+
+class cplus_language : public language_defn
 {
-  ".s", ".sx", ".S", NULL
+public:
+  cplus_language ()
+    : language_defn (language_cplus)
+  { /* Nothing.  */ }
+
+  /* See language.h.  */
+
+  const char *name () const override
+  { return "c++"; }
+
+  /* See language.h.  */
+
+  const char *natural_name () const override
+  { return "C++"; }
+
+  /* See language.h.  */
+
+  const std::vector<const char *> &filename_extensions () const override
+  {
+    static const std::vector<const char *> extensions
+      = { ".C", ".cc", ".cp", ".cpp", ".cxx", ".c++" };
+    return extensions;
+  }
+
+  /* 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);
+
+    /* Helper function to allow shorter lines below.  */
+    auto add  = [&] (struct type * t)
+    {
+      lai->add_primitive_type (t);
+    };
+
+    add (builtin->builtin_int);
+    add (builtin->builtin_long);
+    add (builtin->builtin_short);
+    add (builtin->builtin_char);
+    add (builtin->builtin_float);
+    add (builtin->builtin_double);
+    add (builtin->builtin_void);
+    add (builtin->builtin_long_long);
+    add (builtin->builtin_signed_char);
+    add (builtin->builtin_unsigned_char);
+    add (builtin->builtin_unsigned_short);
+    add (builtin->builtin_unsigned_int);
+    add (builtin->builtin_unsigned_long);
+    add (builtin->builtin_unsigned_long_long);
+    add (builtin->builtin_long_double);
+    add (builtin->builtin_complex);
+    add (builtin->builtin_double_complex);
+    add (builtin->builtin_bool);
+    add (builtin->builtin_decfloat);
+    add (builtin->builtin_decdouble);
+    add (builtin->builtin_declong);
+    add (builtin->builtin_char16);
+    add (builtin->builtin_char32);
+    add (builtin->builtin_wchar);
+
+    lai->set_string_char_type (builtin->builtin_char);
+    lai->set_bool_type (builtin->builtin_bool, "bool");
+  }
+
+  /* See language.h.  */
+  struct type *lookup_transparent_type (const char *name) const override
+  {
+    return cp_lookup_transparent_type (name);
+  }
+
+  /* See language.h.  */
+  std::unique_ptr<compile_instance> get_compile_instance () const override
+  {
+    return cplus_get_compile_context ();
+  }
+
+  /* See language.h.  */
+  std::string compute_program (compile_instance *inst,
+                              const char *input,
+                              struct gdbarch *gdbarch,
+                              const struct block *expr_block,
+                              CORE_ADDR expr_pc) const override
+  {
+    return cplus_compute_program (inst, input, gdbarch, expr_block, expr_pc);
+  }
+
+  /* See language.h.  */
+  unsigned int search_name_hash (const char *name) const override
+  {
+    return cp_search_name_hash (name);
+  }
+
+  /* See language.h.  */
+  bool sniff_from_mangled_name (const char *mangled,
+                               char **demangled) const override
+  {
+    *demangled = gdb_demangle (mangled, DMGL_PARAMS | DMGL_ANSI);
+    return *demangled != NULL;
+  }
+
+  /* See language.h.  */
+
+  char *demangle_symbol (const char *mangled, int options) const override
+  {
+    return gdb_demangle (mangled, options);
+  }
+
+  /* See language.h.  */
+
+  void print_type (struct type *type, const char *varstring,
+                  struct ui_file *stream, int show, int level,
+                  const struct type_print_options *flags) const override
+  {
+    c_print_type (type, varstring, stream, show, level, flags);
+  }
+
+  /* See language.h.  */
+
+  CORE_ADDR skip_trampoline (struct frame_info *fi,
+                            CORE_ADDR pc) const override
+  {
+    return cplus_skip_trampoline (fi, pc);
+  }
+
+  /* See language.h.  */
+
+  char *class_name_from_physname (const char *physname) const override
+  {
+    return cp_class_name_from_physname (physname);
+  }
+
+  /* See language.h.  */
+
+  struct block_symbol lookup_symbol_nonlocal
+       (const char *name, const struct block *block,
+        const domain_enum domain) const override
+  {
+    return cp_lookup_symbol_nonlocal (this, name, block, domain);
+  }
+
+  /* See language.h.  */
+
+  const char *name_of_this () const override
+  { return "this"; }
+
+  /* See language.h.  */
+
+  enum macro_expansion macro_expansion () const override
+  { return macro_expansion_c; }
+
+  /* See language.h.  */
+
+  const struct lang_varobj_ops *varobj_ops () const override
+  { return &cplus_varobj_ops; }
+
+protected:
+
+  /* See language.h.  */
+
+  symbol_name_matcher_ftype *get_symbol_name_matcher_inner
+       (const lookup_name_info &lookup_name) const override
+  {
+    return cp_get_symbol_name_matcher (lookup_name);
+  }
 };
 
-extern const struct language_defn asm_language_defn =
+/* The single instance of the C++ language class.  */
+
+static cplus_language cplus_language_defn;
+
+/* A class for the ASM language.  */
+
+class asm_language : public language_defn
 {
-  "asm",                       /* Language name */
-  "assembly",
-  language_asm,
-  range_check_off,
-  case_sensitive_on,
-  array_row_major,
-  macro_expansion_c,
-  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,               /* Print a top-level value */
-  default_read_var_value,      /* la_read_var_value */
-  NULL,                                /* Language specific skip_trampoline */
-  NULL,                                /* name_of_this */
-  basic_lookup_symbol_nonlocal,        /* lookup_symbol_nonlocal */
-  basic_lookup_transparent_type,/* lookup_transparent_type */
-  NULL,                                /* Language specific symbol demangler */
-  NULL,
-  NULL,                                /* Language specific
-                                  class_name_from_physname */
-  c_op_print_tab,              /* expression operators for printing */
-  1,                           /* c-style arrays */
-  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_matcher */
-  iterate_over_symbols,
-  default_search_name_hash,
-  &default_varobj_ops,
-  NULL,
-  NULL,
-  LANG_MAGIC
+public:
+  asm_language ()
+    : language_defn (language_asm)
+  { /* Nothing.  */ }
+
+  /* See language.h.  */
+
+  const char *name () const override
+  { return "asm"; }
+
+  /* See language.h.  */
+
+  const char *natural_name () const override
+  { return "Assembly"; }
+
+  /* See language.h.  */
+
+  const std::vector<const char *> &filename_extensions () const override
+  {
+    static const std::vector<const char *> extensions
+      = { ".s", ".sx", ".S" };
+    return extensions;
+  }
+
+  /* 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);
+  }
+
+  /* See language.h.  */
+
+  void print_type (struct type *type, const char *varstring,
+                  struct ui_file *stream, int show, int level,
+                  const struct type_print_options *flags) const override
+  {
+    c_print_type (type, varstring, stream, show, level, flags);
+  }
+
+  /* See language.h.  */
+
+  bool store_sym_names_in_linkage_form_p () const override
+  { return true; }
+
+  /* See language.h.  */
+
+  enum macro_expansion macro_expansion () const override
+  { return macro_expansion_c; }
 };
 
-/* 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
+/* The single instance of the ASM language class.  */
+static asm_language asm_language_defn;
+
+/* A class for the minimal language.  This 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.  */
 
-extern const struct language_defn minimal_language_defn =
+class minimal_language : public language_defn
 {
-  "minimal",                   /* Language name */
-  "Minimal",
-  language_minimal,
-  range_check_off,
-  case_sensitive_on,
-  array_row_major,
-  macro_expansion_c,
-  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,               /* Print a top-level value */
-  default_read_var_value,      /* la_read_var_value */
-  NULL,                                /* Language specific skip_trampoline */
-  NULL,                                /* name_of_this */
-  basic_lookup_symbol_nonlocal,        /* lookup_symbol_nonlocal */
-  basic_lookup_transparent_type,/* lookup_transparent_type */
-  NULL,                                /* Language specific symbol demangler */
-  NULL,
-  NULL,                                /* Language specific
-                                  class_name_from_physname */
-  c_op_print_tab,              /* expression operators for printing */
-  1,                           /* c-style arrays */
-  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_matcher */
-  iterate_over_symbols,
-  default_search_name_hash,
-  &default_varobj_ops,
-  NULL,
-  NULL,
-  LANG_MAGIC
+public:
+  minimal_language ()
+    : language_defn (language_minimal)
+  { /* Nothing.  */ }
+
+  /* See language.h.  */
+
+  const char *name () const override
+  { return "minimal"; }
+
+  /* See language.h.  */
+
+  const char *natural_name () const override
+  { return "Minimal"; }
+
+  /* See language.h.  */
+  void language_arch_info (struct gdbarch *gdbarch,
+                          struct language_arch_info *lai) const override
+  {
+    c_language_arch_info (gdbarch, lai);
+  }
+
+  /* See language.h.  */
+
+  void print_type (struct type *type, const char *varstring,
+                  struct ui_file *stream, int show, int level,
+                  const struct type_print_options *flags) const override
+  {
+    c_print_type (type, varstring, stream, show, level, flags);
+  }
+
+  /* See language.h.  */
+
+  bool store_sym_names_in_linkage_form_p () const override
+  { return true; }
+
+  /* See language.h.  */
+
+  enum macro_expansion macro_expansion () const override
+  { return macro_expansion_c; }
 };
+
+/* The single instance of the minimal language class.  */
+static minimal_language minimal_language_defn;
This page took 0.042346 seconds and 4 git commands to generate.