Blame SOURCES/gdb-rhbz1964167-convert-enum-range_type.patch

4a80f0
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
4a80f0
From: Kevin Buettner <kevinb@redhat.com>
4a80f0
Date: Mon, 24 May 2021 17:10:28 -0700
4a80f0
Subject: gdb-rhbz1964167-convert-enum-range_type.patch
4a80f0
4a80f0
;; [fortran] Backport Andrew Burgess's commit which changes enum
4a80f0
;; range_type into a bit field enum.
4a80f0
4a80f0
gdb: Convert enum range_type to a bit field enum
4a80f0
4a80f0
The expression range_type enum represents the following ideas:
4a80f0
4a80f0
  - Lower bound is set to default,
4a80f0
  - Upper bound is set to default,
4a80f0
  - Upper bound is exclusive.
4a80f0
4a80f0
There are currently 6 entries in the enum to represent the combination
4a80f0
of all those ideas.
4a80f0
4a80f0
In a future commit I'd like to add stride information to the range,
4a80f0
this could in theory appear with any of the existing enum entries, so
4a80f0
this would take us to 12 enum entries.
4a80f0
4a80f0
This feels like its getting a little out of hand, so in this commit I
4a80f0
switch the range_type enum over to being a flags style enum.  There's
4a80f0
one entry to represent no flags being set, then 3 flags to represent
4a80f0
the 3 ideas above.  Adding stride information will require adding only
4a80f0
one more enum flag.
4a80f0
4a80f0
I've then gone through and updated the code to handle this change.
4a80f0
4a80f0
There should be no user visible changes after this commit.
4a80f0
4a80f0
gdb/ChangeLog:
4a80f0
4a80f0
	* expprint.c (print_subexp_standard): Update to reflect changes to
4a80f0
	enum range_type.
4a80f0
	(dump_subexp_body_standard): Likewise.
4a80f0
	* expression.h (enum range_type): Convert to a bit field enum, and
4a80f0
	make the enum unsigned.
4a80f0
	* f-exp.y (subrange): Update to reflect changes to enum
4a80f0
	range_type.
4a80f0
	* f-lang.c (value_f90_subarray): Likewise.
4a80f0
	* parse.c (operator_length_standard): Likewise.
4a80f0
	* rust-exp.y (rust_parser::convert_ast_to_expression): Likewise.
4a80f0
	* rust-lang.c (rust_range): Likewise.
4a80f0
	(rust_compute_range): Likewise.
4a80f0
	(rust_subscript): Likewise.
4a80f0
4a80f0
diff --git a/gdb/expprint.c b/gdb/expprint.c
4a80f0
--- a/gdb/expprint.c
4a80f0
+++ b/gdb/expprint.c
4a80f0
@@ -584,17 +584,13 @@ print_subexp_standard (struct expression *exp, int *pos,
4a80f0
 	  longest_to_int (exp->elts[pc + 1].longconst);
4a80f0
 	*pos += 2;
4a80f0
 
4a80f0
-	if (range_type == NONE_BOUND_DEFAULT_EXCLUSIVE
4a80f0
-	    || range_type == LOW_BOUND_DEFAULT_EXCLUSIVE)
4a80f0
+	if (range_type & RANGE_HIGH_BOUND_EXCLUSIVE)
4a80f0
 	  fputs_filtered ("EXCLUSIVE_", stream);
4a80f0
 	fputs_filtered ("RANGE(", stream);
4a80f0
-	if (range_type == HIGH_BOUND_DEFAULT
4a80f0
-	    || range_type == NONE_BOUND_DEFAULT
4a80f0
-	    || range_type == NONE_BOUND_DEFAULT_EXCLUSIVE)
4a80f0
+	if (!(range_type & RANGE_LOW_BOUND_DEFAULT))
4a80f0
 	  print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
4a80f0
 	fputs_filtered ("..", stream);
4a80f0
-	if (range_type == LOW_BOUND_DEFAULT
4a80f0
-	    || range_type == NONE_BOUND_DEFAULT)
4a80f0
+	if (!(range_type & RANGE_HIGH_BOUND_DEFAULT))
4a80f0
 	  print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
4a80f0
 	fputs_filtered (")", stream);
4a80f0
 	return;
4a80f0
@@ -1114,36 +1110,19 @@ dump_subexp_body_standard (struct expression *exp,
4a80f0
 	  longest_to_int (exp->elts[elt].longconst);
4a80f0
 	elt += 2;
4a80f0
 
4a80f0
-	switch (range_type)
4a80f0
-	  {
4a80f0
-	  case BOTH_BOUND_DEFAULT:
4a80f0
-	    fputs_filtered ("Range '..'", stream);
4a80f0
-	    break;
4a80f0
-	  case LOW_BOUND_DEFAULT:
4a80f0
-	    fputs_filtered ("Range '..EXP'", stream);
4a80f0
-	    break;
4a80f0
-	  case LOW_BOUND_DEFAULT_EXCLUSIVE:
4a80f0
-	    fputs_filtered ("ExclusiveRange '..EXP'", stream);
4a80f0
-	    break;
4a80f0
-	  case HIGH_BOUND_DEFAULT:
4a80f0
-	    fputs_filtered ("Range 'EXP..'", stream);
4a80f0
-	    break;
4a80f0
-	  case NONE_BOUND_DEFAULT:
4a80f0
-	    fputs_filtered ("Range 'EXP..EXP'", stream);
4a80f0
-	    break;
4a80f0
-	  case NONE_BOUND_DEFAULT_EXCLUSIVE:
4a80f0
-	    fputs_filtered ("ExclusiveRange 'EXP..EXP'", stream);
4a80f0
-	    break;
4a80f0
-	  default:
4a80f0
-	    fputs_filtered ("Invalid Range!", stream);
4a80f0
-	    break;
4a80f0
-	  }
4a80f0
+	if (range_type & RANGE_HIGH_BOUND_EXCLUSIVE)
4a80f0
+	  fputs_filtered ("Exclusive", stream);
4a80f0
+	fputs_filtered ("Range '", stream);
4a80f0
+	if (!(range_type & RANGE_LOW_BOUND_DEFAULT))
4a80f0
+	  fputs_filtered ("EXP", stream);
4a80f0
+	fputs_filtered ("..", stream);
4a80f0
+	if (!(range_type & RANGE_HIGH_BOUND_DEFAULT))
4a80f0
+	  fputs_filtered ("EXP", stream);
4a80f0
+	fputs_filtered ("'", stream);
4a80f0
 
4a80f0
-	if (range_type == HIGH_BOUND_DEFAULT
4a80f0
-	    || range_type == NONE_BOUND_DEFAULT)
4a80f0
+	if (!(range_type & RANGE_LOW_BOUND_DEFAULT))
4a80f0
 	  elt = dump_subexp (exp, stream, elt);
4a80f0
-	if (range_type == LOW_BOUND_DEFAULT
4a80f0
-	    || range_type == NONE_BOUND_DEFAULT)
4a80f0
+	if (!(range_type & RANGE_HIGH_BOUND_DEFAULT))
4a80f0
 	  elt = dump_subexp (exp, stream, elt);
4a80f0
       }
4a80f0
       break;
4a80f0
diff --git a/gdb/expression.h b/gdb/expression.h
4a80f0
--- a/gdb/expression.h
4a80f0
+++ b/gdb/expression.h
4a80f0
@@ -185,22 +185,22 @@ extern void dump_prefix_expression (struct expression *, struct ui_file *);
4a80f0
    or inclusive.  So we have six sorts of subrange.  This enumeration
4a80f0
    type is to identify this.  */
4a80f0
 
4a80f0
-enum range_type
4a80f0
+enum range_type : unsigned
4a80f0
 {
4a80f0
-  /* Neither the low nor the high bound was given -- so this refers to
4a80f0
-     the entire available range.  */
4a80f0
-  BOTH_BOUND_DEFAULT,
4a80f0
-  /* The low bound was not given and the high bound is inclusive.  */
4a80f0
-  LOW_BOUND_DEFAULT,
4a80f0
-  /* The high bound was not given and the low bound in inclusive.  */
4a80f0
-  HIGH_BOUND_DEFAULT,
4a80f0
-  /* Both bounds were given and both are inclusive.  */
4a80f0
-  NONE_BOUND_DEFAULT,
4a80f0
-  /* The low bound was not given and the high bound is exclusive.  */
4a80f0
-  NONE_BOUND_DEFAULT_EXCLUSIVE,
4a80f0
-  /* Both bounds were given.  The low bound is inclusive and the high
4a80f0
-     bound is exclusive.  */
4a80f0
-  LOW_BOUND_DEFAULT_EXCLUSIVE,
4a80f0
+  /* This is a standard range.  Both the lower and upper bounds are
4a80f0
+     defined, and the bounds are inclusive.  */
4a80f0
+  RANGE_STANDARD = 0,
4a80f0
+
4a80f0
+  /* The low bound was not given.  */
4a80f0
+  RANGE_LOW_BOUND_DEFAULT = 1 << 0,
4a80f0
+
4a80f0
+  /* The high bound was not given.  */
4a80f0
+  RANGE_HIGH_BOUND_DEFAULT = 1 << 1,
4a80f0
+
4a80f0
+  /* The high bound of this range is exclusive.  */
4a80f0
+  RANGE_HIGH_BOUND_EXCLUSIVE = 1 << 2,
4a80f0
 };
4a80f0
 
4a80f0
+DEF_ENUM_FLAGS_TYPE (enum range_type, range_types);
4a80f0
+
4a80f0
 #endif /* !defined (EXPRESSION_H) */
4a80f0
diff --git a/gdb/f-exp.y b/gdb/f-exp.y
4a80f0
--- a/gdb/f-exp.y
4a80f0
+++ b/gdb/f-exp.y
4a80f0
@@ -287,26 +287,30 @@ arglist	:	arglist ',' exp   %prec ABOVE_COMMA
4a80f0
 /* There are four sorts of subrange types in F90.  */
4a80f0
 
4a80f0
 subrange:	exp ':' exp	%prec ABOVE_COMMA
4a80f0
-			{ write_exp_elt_opcode (pstate, OP_RANGE); 
4a80f0
-			  write_exp_elt_longcst (pstate, NONE_BOUND_DEFAULT);
4a80f0
+			{ write_exp_elt_opcode (pstate, OP_RANGE);
4a80f0
+			  write_exp_elt_longcst (pstate, RANGE_STANDARD);
4a80f0
 			  write_exp_elt_opcode (pstate, OP_RANGE); }
4a80f0
 	;
4a80f0
 
4a80f0
 subrange:	exp ':'	%prec ABOVE_COMMA
4a80f0
 			{ write_exp_elt_opcode (pstate, OP_RANGE);
4a80f0
-			  write_exp_elt_longcst (pstate, HIGH_BOUND_DEFAULT);
4a80f0
+			  write_exp_elt_longcst (pstate,
4a80f0
+						 RANGE_HIGH_BOUND_DEFAULT);
4a80f0
 			  write_exp_elt_opcode (pstate, OP_RANGE); }
4a80f0
 	;
4a80f0
 
4a80f0
 subrange:	':' exp	%prec ABOVE_COMMA
4a80f0
 			{ write_exp_elt_opcode (pstate, OP_RANGE);
4a80f0
-			  write_exp_elt_longcst (pstate, LOW_BOUND_DEFAULT);
4a80f0
+			  write_exp_elt_longcst (pstate,
4a80f0
+						 RANGE_LOW_BOUND_DEFAULT);
4a80f0
 			  write_exp_elt_opcode (pstate, OP_RANGE); }
4a80f0
 	;
4a80f0
 
4a80f0
 subrange:	':'	%prec ABOVE_COMMA
4a80f0
 			{ write_exp_elt_opcode (pstate, OP_RANGE);
4a80f0
-			  write_exp_elt_longcst (pstate, BOTH_BOUND_DEFAULT);
4a80f0
+			  write_exp_elt_longcst (pstate,
4a80f0
+						 (RANGE_LOW_BOUND_DEFAULT
4a80f0
+						  | RANGE_HIGH_BOUND_DEFAULT));
4a80f0
 			  write_exp_elt_opcode (pstate, OP_RANGE); }
4a80f0
 	;
4a80f0
 
4a80f0
diff --git a/gdb/f-lang.c b/gdb/f-lang.c
4a80f0
--- a/gdb/f-lang.c
4a80f0
+++ b/gdb/f-lang.c
4a80f0
@@ -131,12 +131,12 @@ value_f90_subarray (struct value *array,
4a80f0
 
4a80f0
   *pos += 3;
4a80f0
 
4a80f0
-  if (range_type == LOW_BOUND_DEFAULT || range_type == BOTH_BOUND_DEFAULT)
4a80f0
+  if (range_type & RANGE_LOW_BOUND_DEFAULT)
4a80f0
     low_bound = range->bounds ()->low.const_val ();
4a80f0
   else
4a80f0
     low_bound = value_as_long (evaluate_subexp (nullptr, exp, pos, noside));
4a80f0
 
4a80f0
-  if (range_type == HIGH_BOUND_DEFAULT || range_type == BOTH_BOUND_DEFAULT)
4a80f0
+  if (range_type & RANGE_HIGH_BOUND_DEFAULT)
4a80f0
     high_bound = range->bounds ()->high.const_val ();
4a80f0
   else
4a80f0
     high_bound = value_as_long (evaluate_subexp (nullptr, exp, pos, noside));
4a80f0
diff --git a/gdb/parse.c b/gdb/parse.c
4a80f0
--- a/gdb/parse.c
4a80f0
+++ b/gdb/parse.c
4a80f0
@@ -921,21 +921,13 @@ operator_length_standard (const struct expression *expr, int endpos,
4a80f0
       range_type = (enum range_type)
4a80f0
 	longest_to_int (expr->elts[endpos - 2].longconst);
4a80f0
 
4a80f0
-      switch (range_type)
4a80f0
-	{
4a80f0
-	case LOW_BOUND_DEFAULT:
4a80f0
-	case LOW_BOUND_DEFAULT_EXCLUSIVE:
4a80f0
-	case HIGH_BOUND_DEFAULT:
4a80f0
-	  args = 1;
4a80f0
-	  break;
4a80f0
-	case BOTH_BOUND_DEFAULT:
4a80f0
-	  args = 0;
4a80f0
-	  break;
4a80f0
-	case NONE_BOUND_DEFAULT:
4a80f0
-	case NONE_BOUND_DEFAULT_EXCLUSIVE:
4a80f0
-	  args = 2;
4a80f0
-	  break;
4a80f0
-	}
4a80f0
+      /* Assume the range has 2 arguments (low bound and high bound), then
4a80f0
+	 reduce the argument count if any bounds are set to default.  */
4a80f0
+      args = 2;
4a80f0
+      if (range_type & RANGE_LOW_BOUND_DEFAULT)
4a80f0
+	--args;
4a80f0
+      if (range_type & RANGE_HIGH_BOUND_DEFAULT)
4a80f0
+	--args;
4a80f0
 
4a80f0
       break;
4a80f0
 
4a80f0
diff --git a/gdb/rust-exp.y b/gdb/rust-exp.y
4a80f0
--- a/gdb/rust-exp.y
4a80f0
+++ b/gdb/rust-exp.y
4a80f0
@@ -2492,24 +2492,29 @@ rust_parser::convert_ast_to_expression (const struct rust_op *operation,
4a80f0
 
4a80f0
     case OP_RANGE:
4a80f0
       {
4a80f0
-	enum range_type kind = BOTH_BOUND_DEFAULT;
4a80f0
+	enum range_type kind = (RANGE_HIGH_BOUND_DEFAULT
4a80f0
+				| RANGE_LOW_BOUND_DEFAULT);
4a80f0
 
4a80f0
 	if (operation->left.op != NULL)
4a80f0
 	  {
4a80f0
 	    convert_ast_to_expression (operation->left.op, top);
4a80f0
-	    kind = HIGH_BOUND_DEFAULT;
4a80f0
+	    kind &= ~RANGE_LOW_BOUND_DEFAULT;
4a80f0
 	  }
4a80f0
 	if (operation->right.op != NULL)
4a80f0
 	  {
4a80f0
 	    convert_ast_to_expression (operation->right.op, top);
4a80f0
-	    if (kind == BOTH_BOUND_DEFAULT)
4a80f0
-	      kind = (operation->inclusive
4a80f0
-		      ? LOW_BOUND_DEFAULT : LOW_BOUND_DEFAULT_EXCLUSIVE);
4a80f0
+	    if (kind == (RANGE_HIGH_BOUND_DEFAULT | RANGE_LOW_BOUND_DEFAULT))
4a80f0
+	      {
4a80f0
+		kind = RANGE_LOW_BOUND_DEFAULT;
4a80f0
+		if (!operation->inclusive)
4a80f0
+		  kind |= RANGE_HIGH_BOUND_EXCLUSIVE;
4a80f0
+	      }
4a80f0
 	    else
4a80f0
 	      {
4a80f0
-		gdb_assert (kind == HIGH_BOUND_DEFAULT);
4a80f0
-		kind = (operation->inclusive
4a80f0
-			? NONE_BOUND_DEFAULT : NONE_BOUND_DEFAULT_EXCLUSIVE);
4a80f0
+		gdb_assert (kind == RANGE_HIGH_BOUND_DEFAULT);
4a80f0
+		kind = RANGE_STANDARD;
4a80f0
+		if (!operation->inclusive)
4a80f0
+		  kind |= RANGE_HIGH_BOUND_EXCLUSIVE;
4a80f0
 	      }
4a80f0
 	  }
4a80f0
 	else
4a80f0
diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c
4a80f0
--- a/gdb/rust-lang.c
4a80f0
+++ b/gdb/rust-lang.c
4a80f0
@@ -1082,13 +1082,11 @@ rust_range (struct expression *exp, int *pos, enum noside noside)
4a80f0
   kind = (enum range_type) longest_to_int (exp->elts[*pos + 1].longconst);
4a80f0
   *pos += 3;
4a80f0
 
4a80f0
-  if (kind == HIGH_BOUND_DEFAULT || kind == NONE_BOUND_DEFAULT
4a80f0
-      || kind == NONE_BOUND_DEFAULT_EXCLUSIVE)
4a80f0
+  if (!(kind & RANGE_LOW_BOUND_DEFAULT))
4a80f0
     low = evaluate_subexp (nullptr, exp, pos, noside);
4a80f0
-  if (kind == LOW_BOUND_DEFAULT || kind == LOW_BOUND_DEFAULT_EXCLUSIVE
4a80f0
-      || kind == NONE_BOUND_DEFAULT || kind == NONE_BOUND_DEFAULT_EXCLUSIVE)
4a80f0
+  if (!(kind & RANGE_HIGH_BOUND_DEFAULT))
4a80f0
     high = evaluate_subexp (nullptr, exp, pos, noside);
4a80f0
-  bool inclusive = (kind == NONE_BOUND_DEFAULT || kind == LOW_BOUND_DEFAULT);
4a80f0
+  bool inclusive = !(kind & RANGE_HIGH_BOUND_EXCLUSIVE);
4a80f0
 
4a80f0
   if (noside == EVAL_SKIP)
4a80f0
     return value_from_longest (builtin_type (exp->gdbarch)->builtin_int, 1);
4a80f0
@@ -1171,13 +1169,13 @@ rust_range (struct expression *exp, int *pos, enum noside noside)
4a80f0
 static void
4a80f0
 rust_compute_range (struct type *type, struct value *range,
4a80f0
 		    LONGEST *low, LONGEST *high,
4a80f0
-		    enum range_type *kind)
4a80f0
+		    range_types *kind)
4a80f0
 {
4a80f0
   int i;
4a80f0
 
4a80f0
   *low = 0;
4a80f0
   *high = 0;
4a80f0
-  *kind = BOTH_BOUND_DEFAULT;
4a80f0
+  *kind = RANGE_LOW_BOUND_DEFAULT | RANGE_HIGH_BOUND_DEFAULT;
4a80f0
 
4a80f0
   if (type->num_fields () == 0)
4a80f0
     return;
4a80f0
@@ -1185,15 +1183,15 @@ rust_compute_range (struct type *type, struct value *range,
4a80f0
   i = 0;
4a80f0
   if (strcmp (TYPE_FIELD_NAME (type, 0), "start") == 0)
4a80f0
     {
4a80f0
-      *kind = HIGH_BOUND_DEFAULT;
4a80f0
+      *kind = RANGE_HIGH_BOUND_DEFAULT;
4a80f0
       *low = value_as_long (value_field (range, 0));
4a80f0
       ++i;
4a80f0
     }
4a80f0
   if (type->num_fields () > i
4a80f0
       && strcmp (TYPE_FIELD_NAME (type, i), "end") == 0)
4a80f0
     {
4a80f0
-      *kind = (*kind == BOTH_BOUND_DEFAULT
4a80f0
-	       ? LOW_BOUND_DEFAULT : NONE_BOUND_DEFAULT);
4a80f0
+      *kind = (*kind == (RANGE_LOW_BOUND_DEFAULT | RANGE_HIGH_BOUND_DEFAULT)
4a80f0
+	       ? RANGE_LOW_BOUND_DEFAULT : RANGE_STANDARD);
4a80f0
       *high = value_as_long (value_field (range, i));
4a80f0
 
4a80f0
       if (rust_inclusive_range_type_p (type))
4a80f0
@@ -1211,7 +1209,7 @@ rust_subscript (struct expression *exp, int *pos, enum noside noside,
4a80f0
   struct type *rhstype;
4a80f0
   LONGEST low, high_bound;
4a80f0
   /* Initialized to appease the compiler.  */
4a80f0
-  enum range_type kind = BOTH_BOUND_DEFAULT;
4a80f0
+  range_types kind = RANGE_LOW_BOUND_DEFAULT | RANGE_HIGH_BOUND_DEFAULT;
4a80f0
   LONGEST high = 0;
4a80f0
   int want_slice = 0;
4a80f0
 
4a80f0
@@ -1308,8 +1306,7 @@ rust_subscript (struct expression *exp, int *pos, enum noside noside,
4a80f0
       else
4a80f0
 	error (_("Cannot subscript non-array type"));
4a80f0
 
4a80f0
-      if (want_slice
4a80f0
-	  && (kind == BOTH_BOUND_DEFAULT || kind == LOW_BOUND_DEFAULT))
4a80f0
+      if (want_slice && (kind & RANGE_LOW_BOUND_DEFAULT))
4a80f0
 	low = low_bound;
4a80f0
       if (low < 0)
4a80f0
 	error (_("Index less than zero"));
4a80f0
@@ -1327,7 +1324,7 @@ rust_subscript (struct expression *exp, int *pos, enum noside noside,
4a80f0
 	  CORE_ADDR addr;
4a80f0
 	  struct value *addrval, *tem;
4a80f0
 
4a80f0
-	  if (kind == BOTH_BOUND_DEFAULT || kind == HIGH_BOUND_DEFAULT)
4a80f0
+	  if (kind & RANGE_HIGH_BOUND_DEFAULT)
4a80f0
 	    high = high_bound;
4a80f0
 	  if (high < 0)
4a80f0
 	    error (_("High index less than zero"));