/* 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 <ctype.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 && 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 && 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 && 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 (!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 (!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;
