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

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

   This file is part of GDB.

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

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

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

#include "extract-store-integer.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "expression.h"
#include "parser-defs.h"
#include "language.h"
#include "varobj.h"
#include "c-lang.h"
#include "c-support.h"
#include "valprint.h"
#include "macroscope.h"
#include "charset.h"
#include "demangle.h"
#include "cp-abi.h"
#include "cp-support.h"
#include "gdbsupport/gdb_obstack.h"
#include "gdbcore.h"
#include "gdbarch.h"
#include "c-exp.h"

/* Given a C string type, STR_TYPE, return the corresponding target
   character set name.  */

static const char *
charset_for_string_type (c_string_type str_type, struct gdbarch *gdbarch)
{
  switch (str_type & ~C_CHAR)
    {
    case C_STRING:
      return target_charset (gdbarch);
    case C_WIDE_STRING:
      return target_wide_charset (gdbarch);
    case C_STRING_16:
      /* FIXME: UTF-16 is not always correct.  */
      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
	return "UTF-16BE";
      else
	return "UTF-16LE";
    case C_STRING_32:
      /* FIXME: UTF-32 is not always correct.  */
      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
	return "UTF-32BE";
      else
	return "UTF-32LE";
    }
  internal_error (_("unhandled c_string_type"));
}

/* Classify ELTTYPE according to what kind of character it is.  Return
   the enum constant representing the character type.  Also set
   *ENCODING to the name of the character set to use when converting
   characters of this type in target BYTE_ORDER to the host character
   set.  */

static c_string_type
classify_type (struct type *elttype, struct gdbarch *gdbarch,
	       const char **encoding)
{
  c_string_type result;

  /* We loop because ELTTYPE may be a typedef, and we want to
     successively peel each typedef until we reach a type we
     understand.  We don't use CHECK_TYPEDEF because that will strip
     all typedefs at once -- but in C, wchar_t is itself a typedef, so
     that would do the wrong thing.  */
  while (elttype)
    {
      const char *name = elttype->name ();

      if (name == nullptr)
	{
	  result = C_CHAR;
	  goto done;
	}

      if (!strcmp (name, "wchar_t"))
	{
	  result = C_WIDE_CHAR;
	  goto done;
	}

      if (!strcmp (name, "char16_t"))
	{
	  result = C_CHAR_16;
	  goto done;
	}

      if (!strcmp (name, "char32_t"))
	{
	  result = C_CHAR_32;
	  goto done;
	}

      if (elttype->code () != TYPE_CODE_TYPEDEF)
	break;

      /* Call for side effects.  */
      check_typedef (elttype);

      if (elttype->target_type ())
	elttype = elttype->target_type ();
      else
	{
	  /* Perhaps check_typedef did not update the target type.  In
	     this case, force the lookup again and hope it works out.
	     It never will for C, but it might for C++.  */
	  elttype = check_typedef (elttype);
	}
    }

  /* Punt.  */
  result = C_CHAR;

 done:
  if (encoding)
    *encoding = charset_for_string_type (result, gdbarch);

  return result;
}

/* Print the character C on STREAM as part of the contents of a
   literal string whose delimiter is QUOTER.  Note that that format
   for printing characters and strings is language specific.  */

void
language_defn::emitchar (int c, struct type *type,
			 struct ui_file *stream, int quoter) const
{
  const char *encoding;

  classify_type (type, type->arch (), &encoding);
  generic_emit_char (c, type, stream, quoter, encoding);
}

/* See language.h.  */

void
language_defn::printchar (int c, struct type *type,
			  struct ui_file * stream) const
{
  c_string_type str_type;

  str_type = classify_type (type, type->arch (), NULL);
  switch (str_type)
    {
    case C_CHAR:
      break;
    case C_WIDE_CHAR:
      gdb_putc ('L', stream);
      break;
    case C_CHAR_16:
      gdb_putc ('u', stream);
      break;
    case C_CHAR_32:
      gdb_putc ('U', stream);
      break;
    }

  gdb_putc ('\'', stream);
  emitchar (c, type, stream, '\'');
  gdb_putc ('\'', stream);
}

/* Print the character string STRING, printing at most LENGTH
   characters.  LENGTH is -1 if the string is nul terminated.  Each
   character is WIDTH bytes long.  Printing stops early if the number
   hits print_max_chars; repeat counts are printed as appropriate.
   Print ellipses at the end if we had to stop before printing LENGTH
   characters, or if FORCE_ELLIPSES.  */

void
language_defn::printstr (struct ui_file *stream, struct type *type,
			 const gdb_byte *string, unsigned int length,
			 const char *user_encoding, int force_ellipses,
			 const struct value_print_options *options) const
{
  c_string_type str_type;
  const char *type_encoding;
  const char *encoding;

  str_type = (classify_type (type, type->arch (), &type_encoding)
	      & ~C_CHAR);
  switch (str_type)
    {
    case C_STRING:
      break;
    case C_WIDE_STRING:
      gdb_puts ("L", stream);
      break;
    case C_STRING_16:
      gdb_puts ("u", stream);
      break;
    case C_STRING_32:
      gdb_puts ("U", stream);
      break;
    }

  encoding = (user_encoding && *user_encoding) ? user_encoding : type_encoding;

  generic_printstr (stream, type, string, length, encoding, force_ellipses,
		    '"', 1, options);
}

/* Obtain a C string from the inferior storing it in a newly allocated
   buffer in BUFFER, which should be freed by the caller.  If the in-
   and out-parameter *LENGTH is specified at -1, the string is read
   until a null character of the appropriate width is found, otherwise
   the string is read to the length of characters specified.  The size
   of a character is determined by the length of the target type of
   the pointer or array.

   If VALUE is an array with a known length, and *LENGTH is -1,
   the function will not read past the end of the array.  However, any
   declared size of the array is ignored if *LENGTH > 0.

   On completion, *LENGTH will be set to the size of the string read in
   characters.  (If a length of -1 is specified, the length returned
   will not include the null character).  CHARSET is always set to the
   target charset.  */

void
c_get_string (struct value *value, gdb::unique_xmalloc_ptr<gdb_byte> *buffer,
	      int *length, struct type **char_type,
	      const char **charset)
{
  int err, width;
  unsigned int fetchlimit;
  struct type *type = check_typedef (value->type ());
  struct type *element_type = type->target_type ();
  int req_length = *length;
  enum bfd_endian byte_order
    = type_byte_order (type);

  if (element_type == NULL)
    goto error;

  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->num_fields () == 1
	  && type->field (0).type ()->code () == TYPE_CODE_RANGE)
	{
	  LONGEST low_bound, high_bound;

	  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_CODE_PTR)
    fetchlimit = UINT_MAX;
  else
    /* We work only with arrays and pointers.  */
    goto error;

  if (! c_textual_element_type (element_type, 0))
    goto error;
  classify_type (element_type, element_type->arch (), charset);
  width = element_type->length ();

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

     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 () == not_lval
       || value->lval () == lval_internalvar
       || type->code () == TYPE_CODE_ARRAY)
      && fetchlimit != UINT_MAX
      && (*length < 0 || *length <= fetchlimit))
    {
      int i;
      const gdb_byte *contents = value->contents ().data ();

      /* If a length is specified, use that.  */
      if (*length >= 0)
	i  = *length;
      else
	/* Otherwise, look for a null character.  */
	for (i = 0; i < fetchlimit; i++)
	  if (extract_unsigned_integer (contents + i * width,
					width, byte_order) == 0)
	    break;

      /* I is now either a user-defined length, the number of non-null
	 characters, or FETCHLIMIT.  */
      *length = i * width;
      buffer->reset ((gdb_byte *) xmalloc (*length));
      memcpy (buffer->get (), contents, *length);
      err = 0;
    }
  else
    {
      /* 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 () != lval_memory)
	    error (_("Attempt to take address of value "
		     "not located in memory."));
	  addr = value->address ();
	}
      else
	addr = value_as_address (value);

      /* Prior to the fix for PR 16196 read_string would ignore fetchlimit
	 if length > 0.  The old "broken" behavior is the behavior we want:
	 The caller may want to fetch 100 bytes from a variable length array
	 implemented using the common idiom of having an array of length 1 at
	 the end of a struct.  In this case we want to ignore the declared
	 size of the array.  However, it's counterintuitive to implement that
	 behavior in read_string: what does fetchlimit otherwise mean if
	 length > 0.  Therefore we implement the behavior we want here:
	 If *length > 0, don't specify a fetchlimit.  This preserves the
	 previous behavior.  We could move this check above where we know
	 whether the array is declared with a fixed size, but we only want
	 to apply this behavior when calling read_string.  PR 16286.  */
      if (*length > 0)
	fetchlimit = UINT_MAX;

      err = target_read_string (addr, *length, width, fetchlimit,
				buffer, length);
      if (err != 0)
	memory_error (TARGET_XFER_E_IO, addr);
    }

  /* If the LENGTH is specified at -1, we want to return the string
     length up to the terminating null character.  If an actual length
     was specified, we want to return the length of exactly what was
     read.  */
  if (req_length == -1)
    /* If the last character is null, subtract it from LENGTH.  */
    if (*length > 0
	&& extract_unsigned_integer (buffer->get () + *length - width,
				     width, byte_order) == 0)
      *length -= width;

  /* The read_string function will return the number of bytes read.
     If length returned from read_string was > 0, return the number of
     characters read by dividing the number of bytes by width.  */
  if (*length != 0)
     *length = *length / width;

  *char_type = element_type;

  return;

 error:
  {
    std::string type_str = type_to_string (type);
    if (!type_str.empty ())
      {
	error (_("Trying to read string with inappropriate type `%s'."),
	       type_str.c_str ());
      }
    else
      error (_("Trying to read string with inappropriate type."));
  }
}


/* Evaluating C and C++ expressions.  */

/* Convert a UCN.  The digits of the UCN start at P and extend no
   farther than LIMIT.  DEST_CHARSET is the name of the character set
   into which the UCN should be converted.  The results are written to
   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 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 && c_isxdigit (*p); ++i, ++p)
    result = (result << 4) + fromhex (*p);

  for (i = 3; i >= 0; --i)
    {
      data[i] = result & 0xff;
      result >>= 8;
    }

  convert_between_encodings ("UTF-32BE", dest_charset, data,
			     4, 4, output, translit_none);

  return p;
}

/* Emit a character, VALUE, which was specified numerically, to
   OUTPUT.  TYPE is the target character type.  */

static void
emit_numeric_character (struct type *type, unsigned long value,
			struct obstack *output)
{
  gdb_byte *buffer;

  buffer = (gdb_byte *) alloca (type->length ());
  pack_long (buffer, type, value);
  obstack_grow (output, buffer, type->length ());
}

/* Convert an octal escape sequence.  TYPE is the target character
   type.  The digits of the escape sequence begin at P and extend no
   farther than LIMIT.  The result is written to OUTPUT.  Returns a
   pointer to just after the final digit of the escape sequence.  */

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 && c_isdigit (*p) && *p != '8' && *p != '9';
       ++i)
    {
      value = 8 * value + fromhex (*p);
      ++p;
    }

  emit_numeric_character (type, value, output);

  return p;
}

/* Convert a hex escape sequence.  TYPE is the target character type.
   The digits of the escape sequence begin at P and extend no farther
   than LIMIT.  The result is written to OUTPUT.  Returns a pointer to
   just after the final digit of the escape sequence.  */

static const char *
convert_hex (struct type *type, const char *p,
	     const char *limit, struct obstack *output)
{
  unsigned long value = 0;

  while (p < limit && c_isxdigit (*p))
    {
      value = 16 * value + fromhex (*p);
      ++p;
    }

  emit_numeric_character (type, value, output);

  return p;
}

/* Convert an escape sequence to a target format.  TYPE is the target
   character type to use, and DEST_CHARSET is the name of the target
   character set.  The backslash of the escape sequence is at *P, and
   the escape sequence will not extend past LIMIT.  The results are
   written to OUTPUT.  Returns a pointer to just past the final
   character of the escape sequence.  */

static const char *
convert_escape (struct type *type, const char *dest_charset,
		const char *p, const char *limit, struct obstack *output)
{
  auto advance = [&] ()
    {
      ++p;
      if (p == limit)
	error (_("Malformed escape sequence"));
    };

  /* Skip the backslash.  */
  advance ();

  switch (*p)
    {
    case '\\':
      /* Convert the backslash itself.  This is probably overkill but
	 it doesn't hurt to do the full conversion.  */
      convert_between_encodings (host_charset (), dest_charset,
				 (const gdb_byte *) p, 1, 1,
				 output, translit_none);
      ++p;
      break;

    case 'x':
      advance ();
      if (!c_isxdigit (*p))
	error (_("\\x used with no following hex digits."));
      p = convert_hex (type, p, limit, output);
      break;

    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
      p = convert_octal (type, p, limit, output);
      break;

    case 'u':
    case 'U':
      {
	int length = *p == 'u' ? 4 : 8;

	advance ();
	if (!c_isxdigit (*p))
	  error (_("\\u used with no following hex digits"));
	p = convert_ucn (p, limit, dest_charset, output, length);
      }
    }

  return p;
}

/* Given a single string from a (C-specific) OP_STRING list, convert
   it to a target string, handling escape sequences specially.  The
   output is written to OUTPUT.  DATA is the input string, which has
   length LEN.  DEST_CHARSET is the name of the target character set,
   and TYPE is the type of target character to use.  */

static void
parse_one_string (struct obstack *output, const char *data, int len,
		  const char *dest_charset, struct type *type)
{
  const char *limit;

  limit = data + len;

  while (data < limit)
    {
      const char *p = data;

      /* Look for next escape, or the end of the input.  */
      while (p < limit && *p != '\\')
	++p;
      /* If we saw a run of characters, convert them all.  */
      if (p > data)
	convert_between_encodings (host_charset (), dest_charset,
				   (const gdb_byte *) data, p - data, 1,
				   output, translit_none);
      /* If we saw an escape, convert it.  */
      if (p < limit)
	p = convert_escape (type, dest_charset, p, limit, output);
      data = p;
    }
}

namespace expr
{

value *
c_string_operation::evaluate (struct type *expect_type,
			      struct expression *exp,
			      enum noside noside)
{
  struct type *type;
  struct value *result;
  c_string_type dest_type;
  const char *dest_charset;
  int satisfy_expected = 0;

  auto_obstack output;

  dest_type = std::get<0> (m_storage);

  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, "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 (_("unhandled c_string_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 (expect_type->target_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 ())
	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 element_size = type->length ();

      if (satisfy_expected)
	{
	  LONGEST low_bound, high_bound;

	  if (!get_discrete_bounds (expect_type->index_type (),
				    &low_bound, &high_bound))
	    {
	      low_bound = 0;
	      high_bound = (expect_type->length () / element_size) - 1;
	    }
	  if (obstack_object_size (&output) / element_size
	      > (high_bound - low_bound + 1))
	    error (_("Too many array elements"));

	  result = value::allocate (expect_type);
	  memcpy (result->contents_raw ().data (), obstack_base (&output),
		  obstack_object_size (&output));
	  /* Write the terminating character.  */
	  memset (result->contents_raw ().data () + obstack_object_size (&output),
		  0, element_size);
	}
      else
	result = value_cstring ((const gdb_byte *) obstack_base (&output),
				obstack_object_size (&output) / element_size,
				type);
    }
  return result;
}

} /* namespace expr */


/* 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 = 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 ();
	return (type->length () > 0
		&& array_target_type->length () > 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 ();
	return c_textual_element_type (element_type, 0);
      }
    default:
      break;
    }

  return false;
}



/* See c-lang.h.  */

gdb::unique_xmalloc_ptr<char>
c_canonicalize_name (const char *name)
{
  if (strchr (name, ' ') != nullptr
      || streq (name, "signed")
      || streq (name, "unsigned"))
    return cp_canonicalize_string (name);
  return nullptr;
}



void
c_language_arch_info (struct gdbarch *gdbarch,
		      struct language_arch_info *lai)
{
  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_decfloat);
  add (builtin->builtin_decdouble);
  add (builtin->builtin_declong);

  lai->set_string_char_type (builtin->builtin_char);
  lai->set_bool_type (builtin->builtin_int);
}

/* Class representing the C language.  */

class c_language : public language_defn
{
public:
  c_language ()
    : language_defn (language_c)
  { /* 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" };
    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.  */

  bool can_print_type_offsets () const override
  {
    return true;
  }

  /* 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, la_language, 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; }
};

/* 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
{
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 char *get_digit_separator () const override
  { return "\'"; }

  /* 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,
					domain_search_flags flags)
    const override
  {
    return cp_lookup_transparent_type (name, flags);
  }

  /* 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,
	gdb::unique_xmalloc_ptr<char> *demangled) const override
  {
    *demangled = gdb_demangle (mangled, DMGL_PARAMS | DMGL_ANSI);
    return *demangled != NULL;
  }

  /* See language.h.  */

  gdb::unique_xmalloc_ptr<char> demangle_symbol (const char *mangled,
						 int options) const override
  {
    return gdb_demangle (mangled, options);
  }

  /* See language.h.  */

  bool can_print_type_offsets () const override
  {
    return true;
  }

  /* 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, la_language, flags);
  }

  /* See language.h.  */

  CORE_ADDR skip_trampoline (const frame_info_ptr &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_local
       (const char *scope,
	const char *name,
	const struct block *block,
	const domain_search_flags domain) const override
  {
    return cp_lookup_symbol_imports (scope, name, block, domain);
  }

  /* See language.h.  */

  struct block_symbol lookup_symbol_nonlocal
	(const char *name, const struct block *block,
	 const domain_search_flags 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);
  }
};

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

  bool can_print_type_offsets () const override
  {
    return true;
  }

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

class minimal_language : public language_defn
{
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.  */

  bool can_print_type_offsets () const override
  {
    return true;
  }

  /* 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, la_language, 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;
