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

   Copyright (C) 1992-2024 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;
}

#define ADVANCE					\
  do {						\
    ++p;					\
    if (p == limit)				\
      error (_("Malformed escape sequence"));	\
  } while (0)

/* 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)
{
  /* Skip the backslash.  */
  ADVANCE;

  switch (*p)
    {
    case '\\':
      obstack_1grow (output, '\\');
      ++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;
