X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Fc-lang.c;h=768963529544ceb9f40b4254565dbccda9c2c946;hb=95086e1e54a726a0d7671d70640bc76e4fddf198;hp=c919f02fa7215c2bd25621eb5eccc696ea4bf91f;hpb=621821900289e9ef3472dc430d6fcf4d55b301e2;p=binutils-gdb.git diff --git a/gdb/c-lang.c b/gdb/c-lang.c index c919f02fa72..76896352954 100644 --- a/gdb/c-lang.c +++ b/gdb/c-lang.c @@ -1,6 +1,6 @@ /* C language support routines for GDB, the GNU debugger. - Copyright (C) 1992-2020 Free Software Foundation, Inc. + Copyright (C) 1992-2022 Free Software Foundation, Inc. This file is part of GDB. @@ -32,10 +32,12 @@ #include "demangle.h" #include "cp-abi.h" #include "cp-support.h" -#include "gdb_obstack.h" +#include "gdbsupport/gdb_obstack.h" #include #include "gdbcore.h" #include "gdbarch.h" +#include "compile/compile-internal.h" +#include "c-exp.h" /* Given a C string type, STR_TYPE, return the corresponding target character set name. */ @@ -84,9 +86,9 @@ classify_type (struct type *elttype, struct gdbarch *gdbarch, that would do the wrong thing. */ while (elttype) { - const char *name = TYPE_NAME (elttype); + const char *name = elttype->name (); - if (TYPE_CODE (elttype) == TYPE_CODE_CHAR || !name) + if (name == nullptr) { result = C_CHAR; goto done; @@ -110,7 +112,7 @@ classify_type (struct type *elttype, struct gdbarch *gdbarch, goto done; } - if (TYPE_CODE (elttype) != TYPE_CODE_TYPEDEF) + if (elttype->code () != TYPE_CODE_TYPEDEF) break; /* Call for side effects. */ @@ -147,34 +149,37 @@ c_emit_char (int c, struct type *type, { const char *encoding; - classify_type (type, get_type_arch (type), &encoding); + classify_type (type, type->arch (), &encoding); generic_emit_char (c, type, stream, quoter, encoding); } +/* See language.h. */ + void -c_printchar (int c, struct type *type, struct ui_file *stream) +language_defn::printchar (int c, struct type *type, + struct ui_file * stream) const { c_string_type str_type; - str_type = classify_type (type, get_type_arch (type), NULL); + str_type = classify_type (type, type->arch (), NULL); switch (str_type) { case C_CHAR: break; case C_WIDE_CHAR: - fputc_filtered ('L', stream); + gdb_putc ('L', stream); break; case C_CHAR_16: - fputc_filtered ('u', stream); + gdb_putc ('u', stream); break; case C_CHAR_32: - fputc_filtered ('U', stream); + gdb_putc ('U', stream); break; } - fputc_filtered ('\'', stream); - LA_EMIT_CHAR (c, type, stream, '\''); - fputc_filtered ('\'', stream); + gdb_putc ('\'', stream); + emitchar (c, type, stream, '\''); + gdb_putc ('\'', stream); } /* Print the character string STRING, printing at most LENGTH @@ -194,20 +199,20 @@ c_printstr (struct ui_file *stream, struct type *type, const char *type_encoding; const char *encoding; - str_type = (classify_type (type, get_type_arch (type), &type_encoding) + str_type = (classify_type (type, type->arch (), &type_encoding) & ~C_CHAR); switch (str_type) { case C_STRING: break; case C_WIDE_STRING: - fputs_filtered ("L", stream); + gdb_puts ("L", stream); break; case C_STRING_16: - fputs_filtered ("u", stream); + gdb_puts ("u", stream); break; case C_STRING_32: - fputs_filtered ("U", stream); + gdb_puts ("U", stream); break; } @@ -250,23 +255,23 @@ c_get_string (struct value *value, gdb::unique_xmalloc_ptr *buffer, if (element_type == NULL) goto error; - if (TYPE_CODE (type) == TYPE_CODE_ARRAY) + 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_NFIELDS (type) == 1 - && TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_RANGE) + if (type->num_fields () == 1 + && type->field (0).type ()->code () == TYPE_CODE_RANGE) { LONGEST low_bound, high_bound; - get_discrete_bounds (TYPE_FIELD_TYPE (type, 0), + 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) == TYPE_CODE_PTR) + else if (type->code () == TYPE_CODE_PTR) fetchlimit = UINT_MAX; else /* We work only with arrays and pointers. */ @@ -274,7 +279,7 @@ c_get_string (struct value *value, gdb::unique_xmalloc_ptr *buffer, if (! c_textual_element_type (element_type, 0)) goto error; - classify_type (element_type, get_type_arch (element_type), charset); + classify_type (element_type, element_type->arch (), charset); width = TYPE_LENGTH (element_type); /* If the string lives in GDB's memory instead of the inferior's, @@ -292,12 +297,12 @@ c_get_string (struct value *value, gdb::unique_xmalloc_ptr *buffer, avoids running off the end of the value's contents. */ if ((VALUE_LVAL (value) == not_lval || VALUE_LVAL (value) == lval_internalvar - || TYPE_CODE (type) == TYPE_CODE_ARRAY) + || type->code () == TYPE_CODE_ARRAY) && fetchlimit != UINT_MAX && (*length < 0 || *length <= fetchlimit)) { int i; - const gdb_byte *contents = value_contents (value); + const gdb_byte *contents = value_contents (value).data (); /* If a length is specified, use that. */ if (*length >= 0) @@ -322,7 +327,7 @@ c_get_string (struct value *value, gdb::unique_xmalloc_ptr *buffer, c_style_arrays is false, so we handle that specially here. */ CORE_ADDR addr; - if (TYPE_CODE (type) == TYPE_CODE_ARRAY) + if (type->code () == TYPE_CODE_ARRAY) { if (VALUE_LVAL (value) != lval_memory) error (_("Attempt to take address of value " @@ -347,8 +352,8 @@ c_get_string (struct value *value, gdb::unique_xmalloc_ptr *buffer, if (*length > 0) fetchlimit = UINT_MAX; - err = read_string (addr, *length, width, fetchlimit, - byte_order, buffer, length); + err = target_read_string (addr, *length, width, fetchlimit, + buffer, length); if (err != 0) memory_error (TARGET_XFER_E_IO, addr); } @@ -396,8 +401,8 @@ c_get_string (struct value *value, gdb::unique_xmalloc_ptr *buffer, 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 char * -convert_ucn (char *p, char *limit, const char *dest_charset, +static const char * +convert_ucn (const char *p, const char *limit, const char *dest_charset, struct obstack *output, int length) { unsigned long result = 0; @@ -405,7 +410,7 @@ convert_ucn (char *p, char *limit, const char *dest_charset, int i; for (i = 0; i < length && p < limit && ISXDIGIT (*p); ++i, ++p) - result = (result << 4) + host_hex_value (*p); + result = (result << 4) + fromhex (*p); for (i = 3; i >= 0; --i) { @@ -438,9 +443,9 @@ emit_numeric_character (struct type *type, unsigned long value, farther than LIMIT. The result is written to OUTPUT. Returns a pointer to just after the final digit of the escape sequence. */ -static char * -convert_octal (struct type *type, char *p, - char *limit, struct obstack *output) +static const char * +convert_octal (struct type *type, const char *p, + const char *limit, struct obstack *output) { int i; unsigned long value = 0; @@ -449,7 +454,7 @@ convert_octal (struct type *type, char *p, i < 3 && p < limit && ISDIGIT (*p) && *p != '8' && *p != '9'; ++i) { - value = 8 * value + host_hex_value (*p); + value = 8 * value + fromhex (*p); ++p; } @@ -463,15 +468,15 @@ convert_octal (struct type *type, char *p, than LIMIT. The result is written to OUTPUT. Returns a pointer to just after the final digit of the escape sequence. */ -static char * -convert_hex (struct type *type, char *p, - char *limit, struct obstack *output) +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 + host_hex_value (*p); + value = 16 * value + fromhex (*p); ++p; } @@ -494,9 +499,9 @@ convert_hex (struct type *type, char *p, written to OUTPUT. Returns a pointer to just past the final character of the escape sequence. */ -static char * +static const char * convert_escape (struct type *type, const char *dest_charset, - char *p, char *limit, struct obstack *output) + const char *p, const char *limit, struct obstack *output) { /* Skip the backslash. */ ADVANCE; @@ -548,16 +553,16 @@ convert_escape (struct type *type, const char *dest_charset, and TYPE is the type of target character to use. */ static void -parse_one_string (struct obstack *output, char *data, int len, +parse_one_string (struct obstack *output, const char *data, int len, const char *dest_charset, struct type *type) { - char *limit; + const char *limit; limit = data + len; while (data < limit) { - char *p = data; + const char *p = data; /* Look for next escape, or the end of the input. */ while (p < limit && *p != '\\') @@ -565,7 +570,7 @@ parse_one_string (struct obstack *output, char *data, int len, /* If we saw a run of characters, convert them all. */ if (p > data) convert_between_encodings (host_charset (), dest_charset, - (gdb_byte *) data, p - data, 1, + (const gdb_byte *) data, p - data, 1, output, translit_none); /* If we saw an escape, convert it. */ if (p < limit) @@ -574,181 +579,129 @@ parse_one_string (struct obstack *output, char *data, int len, } } -/* Expression evaluator for the C language family. Most operations - are delegated to evaluate_subexp_standard; see that function for a - description of the arguments. */ +namespace expr +{ -struct value * -evaluate_subexp_c (struct type *expect_type, struct expression *exp, - int *pos, enum noside noside) +value * +c_string_operation::evaluate (struct type *expect_type, + struct expression *exp, + enum noside noside) { - enum exp_opcode op = exp->elts[*pos].opcode; + struct type *type; + struct value *result; + c_string_type dest_type; + const char *dest_charset; + int satisfy_expected = 0; + + auto_obstack output; - switch (op) + dest_type = std::get<0> (m_storage); + + switch (dest_type & ~C_CHAR) { - case OP_STRING: - { - int oplen, limit; - struct type *type; - struct value *result; - c_string_type dest_type; - const char *dest_charset; - int satisfy_expected = 0; - - auto_obstack output; - - ++*pos; - oplen = longest_to_int (exp->elts[*pos].longconst); - - ++*pos; - limit = *pos + BYTES_TO_EXP_ELEM (oplen + 1); - dest_type = ((enum c_string_type_values) - longest_to_int (exp->elts[*pos].longconst)); - 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 (__FILE__, __LINE__, _("unhandled c_string_type")); - } - - /* Ensure TYPE_LENGTH is valid for TYPE. */ - check_typedef (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 && TYPE_CODE (expect_type) == TYPE_CODE_ARRAY) - { - struct type *element_type - = check_typedef (TYPE_TARGET_TYPE (expect_type)); - - if (TYPE_CODE (element_type) == TYPE_CODE_INT - || TYPE_CODE (element_type) == TYPE_CODE_CHAR) - { - type = element_type; - satisfy_expected = 1; - } - } - - dest_charset = charset_for_string_type (dest_type, exp->gdbarch); - - ++*pos; - while (*pos < limit) - { - int len; - - len = longest_to_int (exp->elts[*pos].longconst); - - ++*pos; - if (noside != EVAL_SKIP) - parse_one_string (&output, &exp->elts[*pos].string, len, - dest_charset, type); - *pos += BYTES_TO_EXP_ELEM (len); - } - - /* Skip the trailing length and opcode. */ - *pos += 2; - - if (noside == EVAL_SKIP) - { - /* Return a dummy value of the appropriate type. */ - if (expect_type != NULL) - result = allocate_value (expect_type); - else if ((dest_type & C_CHAR) != 0) - result = allocate_value (type); - else - result = value_cstring ("", 0, type); - return result; - } - - if ((dest_type & C_CHAR) != 0) - { - LONGEST value; - - if (obstack_object_size (&output) != TYPE_LENGTH (type)) - 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 i; - - /* Write the terminating character. */ - for (i = 0; i < TYPE_LENGTH (type); ++i) - obstack_1grow (&output, 0); - - if (satisfy_expected) - { - LONGEST low_bound, high_bound; - int element_size = TYPE_LENGTH (type); - - if (get_discrete_bounds (TYPE_INDEX_TYPE (expect_type), - &low_bound, &high_bound) < 0) - { - low_bound = 0; - high_bound = (TYPE_LENGTH (expect_type) / element_size) - 1; - } - if (obstack_object_size (&output) / element_size - > (high_bound - low_bound + 1)) - error (_("Too many array elements")); - - result = allocate_value (expect_type); - memcpy (value_contents_raw (result), obstack_base (&output), - obstack_object_size (&output)); - } - else - result = value_cstring ((const char *) obstack_base (&output), - obstack_object_size (&output), - type); - } - return result; - } + case C_STRING: + type = language_string_char_type (exp->language_defn, + exp->gdbarch); break; - - default: + 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 (__FILE__, __LINE__, _("unhandled c_string_type")); } - return evaluate_subexp_standard (expect_type, exp, pos, noside); -} - -/* la_watch_location_expression for C. */ -gdb::unique_xmalloc_ptr -c_watch_location_expression (struct type *type, CORE_ADDR addr) -{ - type = check_typedef (TYPE_TARGET_TYPE (check_typedef (type))); - std::string name = type_to_string (type); - return gdb::unique_xmalloc_ptr - (xstrprintf ("* (%s *) %s", name.c_str (), core_addr_to_string (addr))); + /* Ensure TYPE_LENGTH is valid for TYPE. */ + check_typedef (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 (TYPE_TARGET_TYPE (expect_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 (type)) + 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 i; + + /* Write the terminating character. */ + for (i = 0; i < TYPE_LENGTH (type); ++i) + obstack_1grow (&output, 0); + + if (satisfy_expected) + { + LONGEST low_bound, high_bound; + int element_size = TYPE_LENGTH (type); + + if (!get_discrete_bounds (expect_type->index_type (), + &low_bound, &high_bound)) + { + low_bound = 0; + high_bound = (TYPE_LENGTH (expect_type) / element_size) - 1; + } + if (obstack_object_size (&output) / element_size + > (high_bound - low_bound + 1)) + error (_("Too many array elements")); + + result = allocate_value (expect_type); + memcpy (value_contents_raw (result).data (), obstack_base (&output), + obstack_object_size (&output)); + } + else + result = value_cstring ((const char *) obstack_base (&output), + obstack_object_size (&output), + 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) == TYPE_CODE_REF) + while (type->code () == TYPE_CODE_REF) { type = TYPE_TARGET_TYPE (type); type = check_typedef (type); } - switch (TYPE_CODE (type)) + switch (type->code ()) { case TYPE_CODE_ARRAY: { @@ -773,68 +726,6 @@ c_is_string_type_p (struct type *type) } -/* Table mapping opcodes into strings for printing operators - and precedences of the operators. */ - -const struct op_print c_op_print_tab[] = -{ - {",", BINOP_COMMA, PREC_COMMA, 0}, - {"=", BINOP_ASSIGN, PREC_ASSIGN, 1}, - {"||", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0}, - {"&&", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0}, - {"|", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0}, - {"^", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0}, - {"&", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0}, - {"==", BINOP_EQUAL, PREC_EQUAL, 0}, - {"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0}, - {"<=", BINOP_LEQ, PREC_ORDER, 0}, - {">=", BINOP_GEQ, PREC_ORDER, 0}, - {">", BINOP_GTR, PREC_ORDER, 0}, - {"<", BINOP_LESS, PREC_ORDER, 0}, - {">>", BINOP_RSH, PREC_SHIFT, 0}, - {"<<", BINOP_LSH, PREC_SHIFT, 0}, - {"+", BINOP_ADD, PREC_ADD, 0}, - {"-", BINOP_SUB, PREC_ADD, 0}, - {"*", BINOP_MUL, PREC_MUL, 0}, - {"/", BINOP_DIV, PREC_MUL, 0}, - {"%", BINOP_REM, PREC_MUL, 0}, - {"@", BINOP_REPEAT, PREC_REPEAT, 0}, - {"+", UNOP_PLUS, PREC_PREFIX, 0}, - {"-", UNOP_NEG, PREC_PREFIX, 0}, - {"!", UNOP_LOGICAL_NOT, PREC_PREFIX, 0}, - {"~", UNOP_COMPLEMENT, PREC_PREFIX, 0}, - {"*", UNOP_IND, PREC_PREFIX, 0}, - {"&", UNOP_ADDR, PREC_PREFIX, 0}, - {"sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0}, - {"alignof ", UNOP_ALIGNOF, PREC_PREFIX, 0}, - {"++", UNOP_PREINCREMENT, PREC_PREFIX, 0}, - {"--", UNOP_PREDECREMENT, PREC_PREFIX, 0}, - {NULL, OP_NULL, PREC_PREFIX, 0} -}; - -enum c_primitive_types { - c_primitive_type_int, - c_primitive_type_long, - c_primitive_type_short, - c_primitive_type_char, - c_primitive_type_float, - c_primitive_type_double, - c_primitive_type_void, - c_primitive_type_long_long, - c_primitive_type_signed_char, - c_primitive_type_unsigned_char, - c_primitive_type_unsigned_short, - c_primitive_type_unsigned_int, - c_primitive_type_unsigned_long, - c_primitive_type_unsigned_long_long, - c_primitive_type_long_double, - c_primitive_type_complex, - c_primitive_type_double_complex, - c_primitive_type_decfloat, - c_primitive_type_decdouble, - c_primitive_type_declong, - nr_c_primitive_types -}; void c_language_arch_info (struct gdbarch *gdbarch, @@ -842,351 +733,404 @@ c_language_arch_info (struct gdbarch *gdbarch, { const struct builtin_type *builtin = builtin_type (gdbarch); - lai->string_char_type = builtin->builtin_char; - lai->primitive_type_vector - = GDBARCH_OBSTACK_CALLOC (gdbarch, nr_c_primitive_types + 1, - struct type *); - lai->primitive_type_vector [c_primitive_type_int] = builtin->builtin_int; - lai->primitive_type_vector [c_primitive_type_long] = builtin->builtin_long; - lai->primitive_type_vector [c_primitive_type_short] = builtin->builtin_short; - lai->primitive_type_vector [c_primitive_type_char] = builtin->builtin_char; - lai->primitive_type_vector [c_primitive_type_float] = builtin->builtin_float; - lai->primitive_type_vector [c_primitive_type_double] = builtin->builtin_double; - lai->primitive_type_vector [c_primitive_type_void] = builtin->builtin_void; - lai->primitive_type_vector [c_primitive_type_long_long] = builtin->builtin_long_long; - lai->primitive_type_vector [c_primitive_type_signed_char] = builtin->builtin_signed_char; - lai->primitive_type_vector [c_primitive_type_unsigned_char] = builtin->builtin_unsigned_char; - lai->primitive_type_vector [c_primitive_type_unsigned_short] = builtin->builtin_unsigned_short; - lai->primitive_type_vector [c_primitive_type_unsigned_int] = builtin->builtin_unsigned_int; - lai->primitive_type_vector [c_primitive_type_unsigned_long] = builtin->builtin_unsigned_long; - lai->primitive_type_vector [c_primitive_type_unsigned_long_long] = builtin->builtin_unsigned_long_long; - lai->primitive_type_vector [c_primitive_type_long_double] = builtin->builtin_long_double; - lai->primitive_type_vector [c_primitive_type_complex] = builtin->builtin_complex; - lai->primitive_type_vector [c_primitive_type_double_complex] = builtin->builtin_double_complex; - lai->primitive_type_vector [c_primitive_type_decfloat] = builtin->builtin_decfloat; - lai->primitive_type_vector [c_primitive_type_decdouble] = builtin->builtin_decdouble; - lai->primitive_type_vector [c_primitive_type_declong] = builtin->builtin_declong; - - lai->bool_type_default = builtin->builtin_int; + /* 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); } -const struct exp_descriptor exp_descriptor_c = -{ - print_subexp_standard, - operator_length_standard, - operator_check_standard, - op_name_standard, - dump_subexp_body_standard, - evaluate_subexp_c -}; +/* Class representing the C language. */ -static const char *c_extensions[] = +class c_language : public language_defn { - ".c", NULL -}; +public: + c_language () + : language_defn (language_c) + { /* Nothing. */ } -extern const struct language_defn c_language_defn = -{ - "c", /* Language name */ - "C", - language_c, - range_check_off, - case_sensitive_on, - array_row_major, - macro_expansion_c, - c_extensions, - &exp_descriptor_c, - c_parse, - null_post_parser, - c_printchar, /* Print a character constant */ - c_printstr, /* Function to print string constant */ - c_emit_char, /* Print a single char */ - c_print_type, /* Print a type using appropriate syntax */ - c_print_typedef, /* Print a typedef using appropriate syntax */ - c_val_print, /* Print a value using appropriate syntax */ - c_value_print_inner, /* la_value_print_inner */ - c_value_print, /* Print a top-level value */ - default_read_var_value, /* la_read_var_value */ - NULL, /* Language specific skip_trampoline */ - NULL, /* name_of_this */ - true, /* la_store_sym_names_in_linkage_form_p */ - basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ - basic_lookup_transparent_type,/* lookup_transparent_type */ - NULL, /* Language specific symbol demangler */ - NULL, - NULL, /* Language specific - class_name_from_physname */ - c_op_print_tab, /* expression operators for printing */ - 1, /* c-style arrays */ - 0, /* String lower bound */ - default_word_break_characters, - default_collect_symbol_completion_matches, - c_language_arch_info, - default_print_array_index, - default_pass_by_reference, - c_watch_location_expression, - NULL, /* la_get_symbol_name_matcher */ - iterate_over_symbols, - default_search_name_hash, - &c_varobj_ops, - c_get_compile_context, - c_compute_program, - c_is_string_type_p, - "{...}" /* la_struct_too_deep_ellipsis */ -}; + /* See language.h. */ -enum cplus_primitive_types { - cplus_primitive_type_int, - cplus_primitive_type_long, - cplus_primitive_type_short, - cplus_primitive_type_char, - cplus_primitive_type_float, - cplus_primitive_type_double, - cplus_primitive_type_void, - cplus_primitive_type_long_long, - cplus_primitive_type_signed_char, - cplus_primitive_type_unsigned_char, - cplus_primitive_type_unsigned_short, - cplus_primitive_type_unsigned_int, - cplus_primitive_type_unsigned_long, - cplus_primitive_type_unsigned_long_long, - cplus_primitive_type_long_double, - cplus_primitive_type_complex, - cplus_primitive_type_double_complex, - cplus_primitive_type_bool, - cplus_primitive_type_decfloat, - cplus_primitive_type_decdouble, - cplus_primitive_type_declong, - cplus_primitive_type_char16_t, - cplus_primitive_type_char32_t, - cplus_primitive_type_wchar_t, - nr_cplus_primitive_types -}; + const char *name () const override + { return "c"; } -static void -cplus_language_arch_info (struct gdbarch *gdbarch, - struct language_arch_info *lai) -{ - const struct builtin_type *builtin = builtin_type (gdbarch); + /* See language.h. */ - lai->string_char_type = builtin->builtin_char; - lai->primitive_type_vector - = GDBARCH_OBSTACK_CALLOC (gdbarch, nr_cplus_primitive_types + 1, - struct type *); - lai->primitive_type_vector [cplus_primitive_type_int] - = builtin->builtin_int; - lai->primitive_type_vector [cplus_primitive_type_long] - = builtin->builtin_long; - lai->primitive_type_vector [cplus_primitive_type_short] - = builtin->builtin_short; - lai->primitive_type_vector [cplus_primitive_type_char] - = builtin->builtin_char; - lai->primitive_type_vector [cplus_primitive_type_float] - = builtin->builtin_float; - lai->primitive_type_vector [cplus_primitive_type_double] - = builtin->builtin_double; - lai->primitive_type_vector [cplus_primitive_type_void] - = builtin->builtin_void; - lai->primitive_type_vector [cplus_primitive_type_long_long] - = builtin->builtin_long_long; - lai->primitive_type_vector [cplus_primitive_type_signed_char] - = builtin->builtin_signed_char; - lai->primitive_type_vector [cplus_primitive_type_unsigned_char] - = builtin->builtin_unsigned_char; - lai->primitive_type_vector [cplus_primitive_type_unsigned_short] - = builtin->builtin_unsigned_short; - lai->primitive_type_vector [cplus_primitive_type_unsigned_int] - = builtin->builtin_unsigned_int; - lai->primitive_type_vector [cplus_primitive_type_unsigned_long] - = builtin->builtin_unsigned_long; - lai->primitive_type_vector [cplus_primitive_type_unsigned_long_long] - = builtin->builtin_unsigned_long_long; - lai->primitive_type_vector [cplus_primitive_type_long_double] - = builtin->builtin_long_double; - lai->primitive_type_vector [cplus_primitive_type_complex] - = builtin->builtin_complex; - lai->primitive_type_vector [cplus_primitive_type_double_complex] - = builtin->builtin_double_complex; - lai->primitive_type_vector [cplus_primitive_type_bool] - = builtin->builtin_bool; - lai->primitive_type_vector [cplus_primitive_type_decfloat] - = builtin->builtin_decfloat; - lai->primitive_type_vector [cplus_primitive_type_decdouble] - = builtin->builtin_decdouble; - lai->primitive_type_vector [cplus_primitive_type_declong] - = builtin->builtin_declong; - lai->primitive_type_vector [cplus_primitive_type_char16_t] - = builtin->builtin_char16; - lai->primitive_type_vector [cplus_primitive_type_char32_t] - = builtin->builtin_char32; - lai->primitive_type_vector [cplus_primitive_type_wchar_t] - = builtin->builtin_wchar; - - lai->bool_type_symbol = "bool"; - lai->bool_type_default = builtin->builtin_bool; -} + const char *natural_name () const override + { return "C"; } -static const char *cplus_extensions[] = -{ - ".C", ".cc", ".cp", ".cpp", ".cxx", ".c++", NULL -}; + /* See language.h. */ -extern const struct language_defn cplus_language_defn = -{ - "c++", /* Language name */ - "C++", - language_cplus, - range_check_off, - case_sensitive_on, - array_row_major, - macro_expansion_c, - cplus_extensions, - &exp_descriptor_c, - c_parse, - null_post_parser, - c_printchar, /* Print a character constant */ - c_printstr, /* Function to print string constant */ - c_emit_char, /* Print a single char */ - c_print_type, /* Print a type using appropriate syntax */ - c_print_typedef, /* Print a typedef using appropriate syntax */ - c_val_print, /* Print a value using appropriate syntax */ - c_value_print_inner, /* la_value_print_inner */ - c_value_print, /* Print a top-level value */ - default_read_var_value, /* la_read_var_value */ - cplus_skip_trampoline, /* Language specific skip_trampoline */ - "this", /* name_of_this */ - false, /* la_store_sym_names_in_linkage_form_p */ - cp_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ - cp_lookup_transparent_type, /* lookup_transparent_type */ - gdb_demangle, /* Language specific symbol demangler */ - gdb_sniff_from_mangled_name, - cp_class_name_from_physname, /* Language specific - class_name_from_physname */ - c_op_print_tab, /* expression operators for printing */ - 1, /* c-style arrays */ - 0, /* String lower bound */ - default_word_break_characters, - default_collect_symbol_completion_matches, - cplus_language_arch_info, - default_print_array_index, - cp_pass_by_reference, - c_watch_location_expression, - cp_get_symbol_name_matcher, - iterate_over_symbols, - cp_search_name_hash, - &cplus_varobj_ops, - cplus_get_compile_context, - cplus_compute_program, - c_is_string_type_p, - "{...}" /* la_struct_too_deep_ellipsis */ + const std::vector &filename_extensions () const override + { + static const std::vector 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 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. */ + + 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; } }; -static const char *asm_extensions[] = +/* 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 { - ".s", ".sx", ".S", NULL +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 std::vector &filename_extensions () const override + { + static const std::vector 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 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 *demangled) const override + { + *demangled = gdb_demangle (mangled, DMGL_PARAMS | DMGL_ANSI); + return *demangled != NULL; + } + + /* See language.h. */ + + gdb::unique_xmalloc_ptr demangle_symbol (const char *mangled, + int options) const override + { + return gdb_demangle (mangled, options); + } + + /* 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 (struct frame_info *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); + } }; -extern const struct language_defn asm_language_defn = +/* 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 { - "asm", /* Language name */ - "assembly", - language_asm, - range_check_off, - case_sensitive_on, - array_row_major, - macro_expansion_c, - asm_extensions, - &exp_descriptor_c, - c_parse, - null_post_parser, - c_printchar, /* Print a character constant */ - c_printstr, /* Function to print string constant */ - c_emit_char, /* Print a single char */ - c_print_type, /* Print a type using appropriate syntax */ - c_print_typedef, /* Print a typedef using appropriate syntax */ - c_val_print, /* Print a value using appropriate syntax */ - c_value_print_inner, /* la_value_print_inner */ - c_value_print, /* Print a top-level value */ - default_read_var_value, /* la_read_var_value */ - NULL, /* Language specific skip_trampoline */ - NULL, /* name_of_this */ - true, /* la_store_sym_names_in_linkage_form_p */ - basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ - basic_lookup_transparent_type,/* lookup_transparent_type */ - NULL, /* Language specific symbol demangler */ - NULL, - NULL, /* Language specific - class_name_from_physname */ - c_op_print_tab, /* expression operators for printing */ - 1, /* c-style arrays */ - 0, /* String lower bound */ - default_word_break_characters, - default_collect_symbol_completion_matches, - c_language_arch_info, /* FIXME: la_language_arch_info. */ - default_print_array_index, - default_pass_by_reference, - c_watch_location_expression, - NULL, /* la_get_symbol_name_matcher */ - iterate_over_symbols, - default_search_name_hash, - &default_varobj_ops, - NULL, - NULL, - c_is_string_type_p, - "{...}" /* la_struct_too_deep_ellipsis */ +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 &filename_extensions () const override + { + static const std::vector 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. */ + + 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 following language_defn 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 +/* 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. */ -extern const struct language_defn minimal_language_defn = +class minimal_language : public language_defn { - "minimal", /* Language name */ - "Minimal", - language_minimal, - range_check_off, - case_sensitive_on, - array_row_major, - macro_expansion_c, - NULL, - &exp_descriptor_c, - c_parse, - null_post_parser, - c_printchar, /* Print a character constant */ - c_printstr, /* Function to print string constant */ - c_emit_char, /* Print a single char */ - c_print_type, /* Print a type using appropriate syntax */ - c_print_typedef, /* Print a typedef using appropriate syntax */ - c_val_print, /* Print a value using appropriate syntax */ - c_value_print_inner, /* la_value_print_inner */ - c_value_print, /* Print a top-level value */ - default_read_var_value, /* la_read_var_value */ - NULL, /* Language specific skip_trampoline */ - NULL, /* name_of_this */ - true, /* la_store_sym_names_in_linkage_form_p */ - basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ - basic_lookup_transparent_type,/* lookup_transparent_type */ - NULL, /* Language specific symbol demangler */ - NULL, - NULL, /* Language specific - class_name_from_physname */ - c_op_print_tab, /* expression operators for printing */ - 1, /* c-style arrays */ - 0, /* String lower bound */ - default_word_break_characters, - default_collect_symbol_completion_matches, - c_language_arch_info, - default_print_array_index, - default_pass_by_reference, - c_watch_location_expression, - NULL, /* la_get_symbol_name_matcher */ - iterate_over_symbols, - default_search_name_hash, - &default_varobj_ops, - NULL, - NULL, - c_is_string_type_p, - "{...}" /* la_struct_too_deep_ellipsis */ +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. */ + + 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;