[v3,066/206] Split out ada_ternop_slice

Message ID 20210220201609.838264-67-tom@tromey.com
State New
Headers show
Series
  • Refactor expressions
Related show

Commit Message

Tom Tromey Feb. 20, 2021, 8:13 p.m.
This splits TERNOP_SLICE into a new function for future use.

gdb/ChangeLog
2021-02-20  Tom Tromey  <tom@tromey.com>

	* ada-lang.c (ada_ternop_slice): New function.
	(ada_evaluate_subexp): Use it.
---
 gdb/ChangeLog  |   5 ++
 gdb/ada-lang.c | 153 +++++++++++++++++++++++++++----------------------
 2 files changed, 88 insertions(+), 70 deletions(-)

-- 
2.26.2

Patch

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 28f6d27f2c1..11343304fff 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -10282,6 +10282,87 @@  ada_equal_binop (struct type *expect_type,
   return value_from_longest (type, (LONGEST) tem);
 }
 
+/* A helper function for TERNOP_SLICE.  */
+
+static value *
+ada_ternop_slice (struct expression *exp,
+		  enum noside noside,
+		  struct value *array, struct value *low_bound_val,
+		  struct value *high_bound_val)
+{
+  LONGEST low_bound;
+  LONGEST high_bound;
+
+  low_bound_val = coerce_ref (low_bound_val);
+  high_bound_val = coerce_ref (high_bound_val);
+  low_bound = value_as_long (low_bound_val);
+  high_bound = value_as_long (high_bound_val);
+
+  /* If this is a reference to an aligner type, then remove all
+     the aligners.  */
+  if (value_type (array)->code () == TYPE_CODE_REF
+      && ada_is_aligner_type (TYPE_TARGET_TYPE (value_type (array))))
+    TYPE_TARGET_TYPE (value_type (array)) =
+      ada_aligned_type (TYPE_TARGET_TYPE (value_type (array)));
+
+  if (ada_is_any_packed_array_type (value_type (array)))
+    error (_("cannot slice a packed array"));
+
+  /* If this is a reference to an array or an array lvalue,
+     convert to a pointer.  */
+  if (value_type (array)->code () == TYPE_CODE_REF
+      || (value_type (array)->code () == TYPE_CODE_ARRAY
+	  && VALUE_LVAL (array) == lval_memory))
+    array = value_addr (array);
+
+  if (noside == EVAL_AVOID_SIDE_EFFECTS
+      && ada_is_array_descriptor_type (ada_check_typedef
+				       (value_type (array))))
+    return empty_array (ada_type_of_array (array, 0), low_bound,
+			high_bound);
+
+  array = ada_coerce_to_simple_array_ptr (array);
+
+  /* If we have more than one level of pointer indirection,
+     dereference the value until we get only one level.  */
+  while (value_type (array)->code () == TYPE_CODE_PTR
+	 && (TYPE_TARGET_TYPE (value_type (array))->code ()
+	     == TYPE_CODE_PTR))
+    array = value_ind (array);
+
+  /* Make sure we really do have an array type before going further,
+     to avoid a SEGV when trying to get the index type or the target
+     type later down the road if the debug info generated by
+     the compiler is incorrect or incomplete.  */
+  if (!ada_is_simple_array_type (value_type (array)))
+    error (_("cannot take slice of non-array"));
+
+  if (ada_check_typedef (value_type (array))->code ()
+      == TYPE_CODE_PTR)
+    {
+      struct type *type0 = ada_check_typedef (value_type (array));
+
+      if (high_bound < low_bound || noside == EVAL_AVOID_SIDE_EFFECTS)
+	return empty_array (TYPE_TARGET_TYPE (type0), low_bound, high_bound);
+      else
+	{
+	  struct type *arr_type0 =
+	    to_fixed_array_type (TYPE_TARGET_TYPE (type0), NULL, 1);
+
+	  return ada_value_slice_from_ptr (array, arr_type0,
+					   longest_to_int (low_bound),
+					   longest_to_int (high_bound));
+	}
+    }
+  else if (noside == EVAL_AVOID_SIDE_EFFECTS)
+    return array;
+  else if (high_bound < low_bound)
+    return empty_array (value_type (array), low_bound, high_bound);
+  else
+    return ada_value_slice (array, longest_to_int (low_bound),
+			    longest_to_int (high_bound));
+}
+
 /* Implement the evaluate_exp routine in the exp_descriptor structure
    for the Ada language.  */
 
@@ -10743,80 +10824,12 @@  ada_evaluate_subexp (struct type *expect_type, struct expression *exp,
 	  = evaluate_subexp (nullptr, exp, pos, noside);
 	struct value *high_bound_val
 	  = evaluate_subexp (nullptr, exp, pos, noside);
-	LONGEST low_bound;
-	LONGEST high_bound;
-
-	low_bound_val = coerce_ref (low_bound_val);
-	high_bound_val = coerce_ref (high_bound_val);
-	low_bound = value_as_long (low_bound_val);
-	high_bound = value_as_long (high_bound_val);
 
 	if (noside == EVAL_SKIP)
 	  goto nosideret;
 
-	/* If this is a reference to an aligner type, then remove all
-	   the aligners.  */
-	if (value_type (array)->code () == TYPE_CODE_REF
-	    && ada_is_aligner_type (TYPE_TARGET_TYPE (value_type (array))))
-	  TYPE_TARGET_TYPE (value_type (array)) =
-	    ada_aligned_type (TYPE_TARGET_TYPE (value_type (array)));
-
-	if (ada_is_any_packed_array_type (value_type (array)))
-	  error (_("cannot slice a packed array"));
-
-	/* If this is a reference to an array or an array lvalue,
-	   convert to a pointer.  */
-	if (value_type (array)->code () == TYPE_CODE_REF
-	    || (value_type (array)->code () == TYPE_CODE_ARRAY
-		&& VALUE_LVAL (array) == lval_memory))
-	  array = value_addr (array);
-
-	if (noside == EVAL_AVOID_SIDE_EFFECTS
-	    && ada_is_array_descriptor_type (ada_check_typedef
-					     (value_type (array))))
-	  return empty_array (ada_type_of_array (array, 0), low_bound,
-			      high_bound);
-
-	array = ada_coerce_to_simple_array_ptr (array);
-
-	/* If we have more than one level of pointer indirection,
-	   dereference the value until we get only one level.  */
-	while (value_type (array)->code () == TYPE_CODE_PTR
-	       && (TYPE_TARGET_TYPE (value_type (array))->code ()
-		     == TYPE_CODE_PTR))
-	  array = value_ind (array);
-
-	/* Make sure we really do have an array type before going further,
-	   to avoid a SEGV when trying to get the index type or the target
-	   type later down the road if the debug info generated by
-	   the compiler is incorrect or incomplete.  */
-	if (!ada_is_simple_array_type (value_type (array)))
-	  error (_("cannot take slice of non-array"));
-
-	if (ada_check_typedef (value_type (array))->code ()
-	    == TYPE_CODE_PTR)
-	  {
-	    struct type *type0 = ada_check_typedef (value_type (array));
-
-	    if (high_bound < low_bound || noside == EVAL_AVOID_SIDE_EFFECTS)
-	      return empty_array (TYPE_TARGET_TYPE (type0), low_bound, high_bound);
-	    else
-	      {
-		struct type *arr_type0 =
-		  to_fixed_array_type (TYPE_TARGET_TYPE (type0), NULL, 1);
-
-		return ada_value_slice_from_ptr (array, arr_type0,
-						 longest_to_int (low_bound),
-						 longest_to_int (high_bound));
-	      }
-	  }
-	else if (noside == EVAL_AVOID_SIDE_EFFECTS)
-	  return array;
-	else if (high_bound < low_bound)
-	  return empty_array (value_type (array), low_bound, high_bound);
-	else
-	  return ada_value_slice (array, longest_to_int (low_bound),
-				  longest_to_int (high_bound));
+	return ada_ternop_slice (exp, noside, array, low_bound_val,
+				 high_bound_val);
       }
 
     case UNOP_IN_RANGE: