aboutsummaryrefslogtreecommitdiff
path: root/gdb/ada-lang.c
diff options
context:
space:
mode:
authorTom Tromey <tromey@adacore.com>2022-03-09 14:34:22 -0700
committerTom Tromey <tromey@adacore.com>2022-03-16 09:28:13 -0600
commitb1b9c4115ed04876813a40c0051636c0ad916993 (patch)
tree8f03d73466e7988072b42d9342e08001753675ef /gdb/ada-lang.c
parenta73c128df6e149c36940240f2b2198f9732ab6c7 (diff)
downloadgdb-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.c58
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)