| /* C language support routines for GDB, the GNU debugger. | 
 |  | 
 |    Copyright (C) 1992-2023 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 "defs.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" behaviour is the behaviour 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 | 
 | 	 behaviour in read_string: what does fetchlimit otherwise mean if | 
 | 	 length > 0.  Therefore we implement the behaviour we want here: | 
 | 	 If *length > 0, don't specify a fetchlimit.  This preserves the | 
 | 	 previous behaviour.  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 behaviour 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.  */ | 
 |   std::unique_ptr<compile_instance> get_compile_instance () const override | 
 |   { | 
 |     return c_get_compile_context (); | 
 |   } | 
 |  | 
 |   /* See language.h.  */ | 
 |   std::string compute_program (compile_instance *inst, | 
 | 			       const char *input, | 
 | 			       struct gdbarch *gdbarch, | 
 | 			       const struct block *expr_block, | 
 | 			       CORE_ADDR expr_pc) const override | 
 |   { | 
 |     return c_compute_program (inst, input, gdbarch, expr_block, expr_pc); | 
 |   } | 
 |  | 
 |   /* See language.h.  */ | 
 |  | 
 |   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) const override | 
 |   { | 
 |     return cp_lookup_transparent_type (name); | 
 |   } | 
 |  | 
 |   /* See language.h.  */ | 
 |   std::unique_ptr<compile_instance> get_compile_instance () const override | 
 |   { | 
 |     return cplus_get_compile_context (); | 
 |   } | 
 |  | 
 |   /* See language.h.  */ | 
 |   std::string compute_program (compile_instance *inst, | 
 | 			       const char *input, | 
 | 			       struct gdbarch *gdbarch, | 
 | 			       const struct block *expr_block, | 
 | 			       CORE_ADDR expr_pc) const override | 
 |   { | 
 |     return cplus_compute_program (inst, input, gdbarch, expr_block, expr_pc); | 
 |   } | 
 |  | 
 |   /* See language.h.  */ | 
 |   unsigned int search_name_hash (const char *name) const override | 
 |   { | 
 |     return cp_search_name_hash (name); | 
 |   } | 
 |  | 
 |   /* See language.h.  */ | 
 |   bool sniff_from_mangled_name | 
 |        (const char *mangled, | 
 | 	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_nonlocal | 
 | 	(const char *name, const struct block *block, | 
 | 	 const domain_enum domain) const override | 
 |   { | 
 |     return cp_lookup_symbol_nonlocal (this, name, block, domain); | 
 |   } | 
 |  | 
 |   /* See language.h.  */ | 
 |  | 
 |   const char *name_of_this () const override | 
 |   { return "this"; } | 
 |  | 
 |   /* See language.h.  */ | 
 |  | 
 |   enum macro_expansion macro_expansion () const override | 
 |   { return macro_expansion_c; } | 
 |  | 
 |   /* See language.h.  */ | 
 |  | 
 |   const struct lang_varobj_ops *varobj_ops () const override | 
 |   { return &cplus_varobj_ops; } | 
 |  | 
 | protected: | 
 |  | 
 |   /* See language.h.  */ | 
 |  | 
 |   symbol_name_matcher_ftype *get_symbol_name_matcher_inner | 
 | 	(const lookup_name_info &lookup_name) const override | 
 |   { | 
 |     return cp_get_symbol_name_matcher (lookup_name); | 
 |   } | 
 | }; | 
 |  | 
 | /* 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; |