diff options
author | Tom Tromey <tom@tromey.com> | 2021-03-08 07:27:57 -0700 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2021-03-08 07:28:17 -0700 |
commit | 72d0a71134f9a7e4725d6ac490e1323cf7aa6ec2 (patch) | |
tree | ad06048ae5e4a24d076b710f8545586d5a813388 /gdb/c-lang.c | |
parent | 9186293fd6bd4c3a4855c7aa62ad2ab1734077e6 (diff) | |
download | gdb-72d0a71134f9a7e4725d6ac490e1323cf7aa6ec2.zip gdb-72d0a71134f9a7e4725d6ac490e1323cf7aa6ec2.tar.gz gdb-72d0a71134f9a7e4725d6ac490e1323cf7aa6ec2.tar.bz2 |
Add c-exp.h and c_string_operation
This adds the new file c-exp.h, where C operation classes will be
declared. The first such class, c_string_operation, is also added
here.
gdb/ChangeLog
2021-03-08 Tom Tromey <tom@tromey.com>
* c-lang.c (c_string_operation::evaluate): New method.
* c-exp.h: New file.
Diffstat (limited to 'gdb/c-lang.c')
-rw-r--r-- | gdb/c-lang.c | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/gdb/c-lang.c b/gdb/c-lang.c index 16ff3c7..d191d07 100644 --- a/gdb/c-lang.c +++ b/gdb/c-lang.c @@ -37,6 +37,7 @@ #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. */ @@ -728,6 +729,131 @@ evaluate_subexp_c (struct type *expect_type, struct expression *exp, } return evaluate_subexp_standard (expect_type, exp, pos, noside); } + +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 (__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); + + if (noside != EVAL_SKIP) + { + for (const std::string &item : std::get<1> (m_storage)) + parse_one_string (&output, item.c_str (), item.size (), + dest_charset, type); + } + + 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; +} + +} /* namespace expr */ + /* See c-lang.h. */ |