X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Fc-lang.c;h=1f7cac7bef14d61876e6adf873fbd092a179ef8b;hb=ea764154c27a11619ba764a4c92f395ba5007234;hp=a028d10e2bffd986cfcb709633ec1757d7fccaa7;hpb=c5ee319e6cc7a02d35871896e8205e1f782fbc00;p=binutils-gdb.git diff --git a/gdb/c-lang.c b/gdb/c-lang.c index a028d10e2bf..1f7cac7bef1 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,12 +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" - -class compile_instance; +#include "compile/compile-internal.h" +#include "c-exp.h" /* Given a C string type, STR_TYPE, return the corresponding target character set name. */ @@ -88,7 +88,7 @@ classify_type (struct type *elttype, struct gdbarch *gdbarch, { const char *name = elttype->name (); - if (elttype->code () == TYPE_CODE_CHAR || !name) + if (name == nullptr) { result = C_CHAR; goto done; @@ -149,7 +149,7 @@ 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); } @@ -161,7 +161,7 @@ language_defn::printchar (int c, struct type *type, { 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: @@ -178,7 +178,7 @@ language_defn::printchar (int c, struct type *type, } fputc_filtered ('\'', stream); - LA_EMIT_CHAR (c, type, stream, '\''); + emitchar (c, type, stream, '\''); fputc_filtered ('\'', stream); } @@ -199,7 +199,7 @@ 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) { @@ -279,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, @@ -302,7 +302,7 @@ c_get_string (struct value *value, gdb::unique_xmalloc_ptr *buffer, && (*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) @@ -410,7 +410,7 @@ convert_ucn (const char *p, const 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) { @@ -454,7 +454,7 @@ convert_octal (struct type *type, const 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; } @@ -476,7 +476,7 @@ convert_hex (struct type *type, const char *p, while (p < limit && ISXDIGIT (*p)) { - value = 16 * value + host_hex_value (*p); + value = 16 * value + fromhex (*p); ++p; } @@ -579,156 +579,115 @@ parse_one_string (struct obstack *output, const 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 && 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); - - ++*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 (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), 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")); + } + + /* 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 evaluate_subexp_standard (expect_type, exp, pos, noside); + return result; } + +} /* namespace expr */ + /* See c-lang.h. */ @@ -766,45 +725,6 @@ c_is_string_type_p (struct type *type) return false; } - -/* 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} -}; void @@ -844,15 +764,6 @@ c_language_arch_info (struct gdbarch *gdbarch, lai->set_bool_type (builtin->builtin_int); } -const struct exp_descriptor exp_descriptor_c = -{ - print_subexp_standard, - operator_length_standard, - operator_check_standard, - dump_subexp_body_standard, - evaluate_subexp_c -}; - /* Class representing the C language. */ class c_language : public language_defn @@ -888,7 +799,7 @@ public: } /* See language.h. */ - compile_instance *get_compile_instance () const override + std::unique_ptr get_compile_instance () const override { return c_get_compile_context (); } @@ -921,16 +832,6 @@ public: enum macro_expansion macro_expansion () const override { return macro_expansion_c; } - - /* See language.h. */ - - const struct exp_descriptor *expression_ops () const override - { return &exp_descriptor_c; } - - /* See language.h. */ - - const struct op_print *opcode_print_table () const override - { return c_op_print_tab; } }; /* Single instance of the C language class. */ @@ -1021,7 +922,7 @@ public: } /* See language.h. */ - compile_instance *get_compile_instance () const override + std::unique_ptr get_compile_instance () const override { return cplus_get_compile_context (); } @@ -1043,8 +944,9 @@ public: } /* See language.h. */ - bool sniff_from_mangled_name (const char *mangled, - char **demangled) const override + 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; @@ -1052,7 +954,8 @@ public: /* See language.h. */ - char *demangle_symbol (const char *mangled, int options) const override + gdb::unique_xmalloc_ptr demangle_symbol (const char *mangled, + int options) const override { return gdb_demangle (mangled, options); } @@ -1105,16 +1008,6 @@ public: const struct lang_varobj_ops *varobj_ops () const override { return &cplus_varobj_ops; } - /* See language.h. */ - - const struct exp_descriptor *expression_ops () const override - { return &exp_descriptor_c; } - - /* See language.h. */ - - const struct op_print *opcode_print_table () const override - { return c_op_print_tab; } - protected: /* See language.h. */ @@ -1185,16 +1078,6 @@ public: enum macro_expansion macro_expansion () const override { return macro_expansion_c; } - - /* See language.h. */ - - const struct exp_descriptor *expression_ops () const override - { return &exp_descriptor_c; } - - /* See language.h. */ - - const struct op_print *opcode_print_table () const override - { return c_op_print_tab; } }; /* The single instance of the ASM language class. */ @@ -1247,16 +1130,6 @@ public: enum macro_expansion macro_expansion () const override { return macro_expansion_c; } - - /* See language.h. */ - - const struct exp_descriptor *expression_ops () const override - { return &exp_descriptor_c; } - - /* See language.h. */ - - const struct op_print *opcode_print_table () const override - { return c_op_print_tab; } }; /* The single instance of the minimal language class. */