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

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