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