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

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