diff options
author | Tom Tromey <tromey@adacore.com> | 2022-03-09 14:34:22 -0700 |
---|---|---|
committer | Tom Tromey <tromey@adacore.com> | 2022-03-16 09:28:13 -0600 |
commit | b1b9c4115ed04876813a40c0051636c0ad916993 (patch) | |
tree | 8f03d73466e7988072b42d9342e08001753675ef /gdb/ada-lang.c | |
parent | a73c128df6e149c36940240f2b2198f9732ab6c7 (diff) | |
download | gdb-b1b9c4115ed04876813a40c0051636c0ad916993.zip gdb-b1b9c4115ed04876813a40c0051636c0ad916993.tar.gz gdb-b1b9c4115ed04876813a40c0051636c0ad916993.tar.bz2 |
Reimplement array concatenation for Ada and D
This started as a patch to implement string concatenation for Ada.
However, while working on this, I looked at how this code could
possibly be called. It turns out there are only two users of
concat_operation: Ada and D. So, in addition to implementing this for
Ada, this patch rewrites value_concat, removing the odd "concatenate
or repeat" semantics, which were completely unused. As Ada and D both
seem to represent strings using TYPE_CODE_ARRAY, this removes the
TYPE_CODE_STRING code from there as well.
Diffstat (limited to 'gdb/ada-lang.c')
-rw-r--r-- | gdb/ada-lang.c | 58 |
1 files changed, 57 insertions, 1 deletions
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index f097ad4..0f772fd 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -10552,6 +10552,17 @@ convert_char_literal (struct type *type, LONGEST val) return val; } +value * +ada_char_operation::evaluate (struct type *expect_type, + struct expression *exp, + enum noside noside) +{ + value *result = long_const_operation::evaluate (expect_type, exp, noside); + if (expect_type != nullptr) + result = ada_value_cast (expect_type, result); + return result; +} + /* See ada-exp.h. */ operation_up @@ -10572,7 +10583,7 @@ ada_char_operation::replace (operation_up &&owner, = convert_char_literal (context_type, std::get<1> (m_storage)); } - return make_operation<ada_wrapped_operation> (std::move (result)); + return result; } value * @@ -10663,6 +10674,51 @@ ada_string_operation::evaluate (struct type *expect_type, } value * +ada_concat_operation::evaluate (struct type *expect_type, + struct expression *exp, + enum noside noside) +{ + /* If one side is a literal, evaluate the other side first so that + the expected type can be set properly. */ + const operation_up &lhs_expr = std::get<0> (m_storage); + const operation_up &rhs_expr = std::get<1> (m_storage); + + value *lhs, *rhs; + if (dynamic_cast<ada_string_operation *> (lhs_expr.get ()) != nullptr) + { + rhs = rhs_expr->evaluate (nullptr, exp, noside); + lhs = lhs_expr->evaluate (value_type (rhs), exp, noside); + } + else if (dynamic_cast<ada_char_operation *> (lhs_expr.get ()) != nullptr) + { + rhs = rhs_expr->evaluate (nullptr, exp, noside); + struct type *rhs_type = check_typedef (value_type (rhs)); + struct type *elt_type = nullptr; + if (rhs_type->code () == TYPE_CODE_ARRAY) + elt_type = TYPE_TARGET_TYPE (rhs_type); + lhs = lhs_expr->evaluate (elt_type, exp, noside); + } + else if (dynamic_cast<ada_string_operation *> (rhs_expr.get ()) != nullptr) + { + lhs = lhs_expr->evaluate (nullptr, exp, noside); + rhs = rhs_expr->evaluate (value_type (lhs), exp, noside); + } + else if (dynamic_cast<ada_char_operation *> (rhs_expr.get ()) != nullptr) + { + lhs = lhs_expr->evaluate (nullptr, exp, noside); + struct type *lhs_type = check_typedef (value_type (lhs)); + struct type *elt_type = nullptr; + if (lhs_type->code () == TYPE_CODE_ARRAY) + elt_type = TYPE_TARGET_TYPE (lhs_type); + rhs = rhs_expr->evaluate (elt_type, exp, noside); + } + else + return concat_operation::evaluate (expect_type, exp, noside); + + return value_concat (lhs, rhs); +} + +value * ada_qual_operation::evaluate (struct type *expect_type, struct expression *exp, enum noside noside) |