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

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