+2020-10-22  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+       * expprint.c (print_subexp_standard): Update to reflect changes to
+       enum range_type.
+       (dump_subexp_body_standard): Likewise.
+       * expression.h (enum range_type): Convert to a bit field enum, and
+       make the enum unsigned.
+       * f-exp.y (subrange): Update to reflect changes to enum
+       range_type.
+       * f-lang.c (value_f90_subarray): Likewise.
+       * parse.c (operator_length_standard): Likewise.
+       * rust-exp.y (rust_parser::convert_ast_to_expression): Likewise.
+       * rust-lang.c (rust_range): Likewise.
+       (rust_compute_range): Likewise.
+       (rust_subscript): Likewise.
+
 2020-10-21  Simon Marchi  <simon.marchi@efficios.com>
 
        * infrun.c (displaced_step_in_progress_thread): Fix comment.
 
          longest_to_int (exp->elts[pc + 1].longconst);
        *pos += 2;
 
-       if (range_type == NONE_BOUND_DEFAULT_EXCLUSIVE
-           || range_type == LOW_BOUND_DEFAULT_EXCLUSIVE)
+       if (range_type & RANGE_HIGH_BOUND_EXCLUSIVE)
          fputs_filtered ("EXCLUSIVE_", stream);
        fputs_filtered ("RANGE(", stream);
-       if (range_type == HIGH_BOUND_DEFAULT
-           || range_type == NONE_BOUND_DEFAULT
-           || range_type == NONE_BOUND_DEFAULT_EXCLUSIVE)
+       if (!(range_type & RANGE_LOW_BOUND_DEFAULT))
          print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
        fputs_filtered ("..", stream);
-       if (range_type == LOW_BOUND_DEFAULT
-           || range_type == NONE_BOUND_DEFAULT)
+       if (!(range_type & RANGE_HIGH_BOUND_DEFAULT))
          print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
        fputs_filtered (")", stream);
        return;
          longest_to_int (exp->elts[elt].longconst);
        elt += 2;
 
-       switch (range_type)
-         {
-         case BOTH_BOUND_DEFAULT:
-           fputs_filtered ("Range '..'", stream);
-           break;
-         case LOW_BOUND_DEFAULT:
-           fputs_filtered ("Range '..EXP'", stream);
-           break;
-         case LOW_BOUND_DEFAULT_EXCLUSIVE:
-           fputs_filtered ("ExclusiveRange '..EXP'", stream);
-           break;
-         case HIGH_BOUND_DEFAULT:
-           fputs_filtered ("Range 'EXP..'", stream);
-           break;
-         case NONE_BOUND_DEFAULT:
-           fputs_filtered ("Range 'EXP..EXP'", stream);
-           break;
-         case NONE_BOUND_DEFAULT_EXCLUSIVE:
-           fputs_filtered ("ExclusiveRange 'EXP..EXP'", stream);
-           break;
-         default:
-           fputs_filtered ("Invalid Range!", stream);
-           break;
-         }
+       if (range_type & RANGE_HIGH_BOUND_EXCLUSIVE)
+         fputs_filtered ("Exclusive", stream);
+       fputs_filtered ("Range '", stream);
+       if (!(range_type & RANGE_LOW_BOUND_DEFAULT))
+         fputs_filtered ("EXP", stream);
+       fputs_filtered ("..", stream);
+       if (!(range_type & RANGE_HIGH_BOUND_DEFAULT))
+         fputs_filtered ("EXP", stream);
+       fputs_filtered ("'", stream);
 
-       if (range_type == HIGH_BOUND_DEFAULT
-           || range_type == NONE_BOUND_DEFAULT)
+       if (!(range_type & RANGE_LOW_BOUND_DEFAULT))
          elt = dump_subexp (exp, stream, elt);
-       if (range_type == LOW_BOUND_DEFAULT
-           || range_type == NONE_BOUND_DEFAULT)
+       if (!(range_type & RANGE_HIGH_BOUND_DEFAULT))
          elt = dump_subexp (exp, stream, elt);
       }
       break;
 
    or inclusive.  So we have six sorts of subrange.  This enumeration
    type is to identify this.  */
 
-enum range_type
+enum range_type : unsigned
 {
-  /* Neither the low nor the high bound was given -- so this refers to
-     the entire available range.  */
-  BOTH_BOUND_DEFAULT,
-  /* The low bound was not given and the high bound is inclusive.  */
-  LOW_BOUND_DEFAULT,
-  /* The high bound was not given and the low bound in inclusive.  */
-  HIGH_BOUND_DEFAULT,
-  /* Both bounds were given and both are inclusive.  */
-  NONE_BOUND_DEFAULT,
-  /* The low bound was not given and the high bound is exclusive.  */
-  NONE_BOUND_DEFAULT_EXCLUSIVE,
-  /* Both bounds were given.  The low bound is inclusive and the high
-     bound is exclusive.  */
-  LOW_BOUND_DEFAULT_EXCLUSIVE,
+  /* This is a standard range.  Both the lower and upper bounds are
+     defined, and the bounds are inclusive.  */
+  RANGE_STANDARD = 0,
+
+  /* The low bound was not given.  */
+  RANGE_LOW_BOUND_DEFAULT = 1 << 0,
+
+  /* The high bound was not given.  */
+  RANGE_HIGH_BOUND_DEFAULT = 1 << 1,
+
+  /* The high bound of this range is exclusive.  */
+  RANGE_HIGH_BOUND_EXCLUSIVE = 1 << 2,
 };
 
+DEF_ENUM_FLAGS_TYPE (enum range_type, range_types);
+
 #endif /* !defined (EXPRESSION_H) */
 
 /* There are four sorts of subrange types in F90.  */
 
 subrange:      exp ':' exp     %prec ABOVE_COMMA
-                       { write_exp_elt_opcode (pstate, OP_RANGE); 
-                         write_exp_elt_longcst (pstate, NONE_BOUND_DEFAULT);
+                       { write_exp_elt_opcode (pstate, OP_RANGE);
+                         write_exp_elt_longcst (pstate, RANGE_STANDARD);
                          write_exp_elt_opcode (pstate, OP_RANGE); }
        ;
 
 subrange:      exp ':' %prec ABOVE_COMMA
                        { write_exp_elt_opcode (pstate, OP_RANGE);
-                         write_exp_elt_longcst (pstate, HIGH_BOUND_DEFAULT);
+                         write_exp_elt_longcst (pstate,
+                                                RANGE_HIGH_BOUND_DEFAULT);
                          write_exp_elt_opcode (pstate, OP_RANGE); }
        ;
 
 subrange:      ':' exp %prec ABOVE_COMMA
                        { write_exp_elt_opcode (pstate, OP_RANGE);
-                         write_exp_elt_longcst (pstate, LOW_BOUND_DEFAULT);
+                         write_exp_elt_longcst (pstate,
+                                                RANGE_LOW_BOUND_DEFAULT);
                          write_exp_elt_opcode (pstate, OP_RANGE); }
        ;
 
 subrange:      ':'     %prec ABOVE_COMMA
                        { write_exp_elt_opcode (pstate, OP_RANGE);
-                         write_exp_elt_longcst (pstate, BOTH_BOUND_DEFAULT);
+                         write_exp_elt_longcst (pstate,
+                                                (RANGE_LOW_BOUND_DEFAULT
+                                                 | RANGE_HIGH_BOUND_DEFAULT));
                          write_exp_elt_opcode (pstate, OP_RANGE); }
        ;
 
 
 
   *pos += 3;
 
-  if (range_type == LOW_BOUND_DEFAULT || range_type == BOTH_BOUND_DEFAULT)
+  if (range_type & RANGE_LOW_BOUND_DEFAULT)
     low_bound = range->bounds ()->low.const_val ();
   else
     low_bound = value_as_long (evaluate_subexp (nullptr, exp, pos, noside));
 
-  if (range_type == HIGH_BOUND_DEFAULT || range_type == BOTH_BOUND_DEFAULT)
+  if (range_type & RANGE_HIGH_BOUND_DEFAULT)
     high_bound = range->bounds ()->high.const_val ();
   else
     high_bound = value_as_long (evaluate_subexp (nullptr, exp, pos, noside));
 
       range_type = (enum range_type)
        longest_to_int (expr->elts[endpos - 2].longconst);
 
-      switch (range_type)
-       {
-       case LOW_BOUND_DEFAULT:
-       case LOW_BOUND_DEFAULT_EXCLUSIVE:
-       case HIGH_BOUND_DEFAULT:
-         args = 1;
-         break;
-       case BOTH_BOUND_DEFAULT:
-         args = 0;
-         break;
-       case NONE_BOUND_DEFAULT:
-       case NONE_BOUND_DEFAULT_EXCLUSIVE:
-         args = 2;
-         break;
-       }
+      /* Assume the range has 2 arguments (low bound and high bound), then
+        reduce the argument count if any bounds are set to default.  */
+      args = 2;
+      if (range_type & RANGE_LOW_BOUND_DEFAULT)
+       --args;
+      if (range_type & RANGE_HIGH_BOUND_DEFAULT)
+       --args;
 
       break;
 
 
 
     case OP_RANGE:
       {
-       enum range_type kind = BOTH_BOUND_DEFAULT;
+       enum range_type kind = (RANGE_HIGH_BOUND_DEFAULT
+                               | RANGE_LOW_BOUND_DEFAULT);
 
        if (operation->left.op != NULL)
          {
            convert_ast_to_expression (operation->left.op, top);
-           kind = HIGH_BOUND_DEFAULT;
+           kind &= ~RANGE_LOW_BOUND_DEFAULT;
          }
        if (operation->right.op != NULL)
          {
            convert_ast_to_expression (operation->right.op, top);
-           if (kind == BOTH_BOUND_DEFAULT)
-             kind = (operation->inclusive
-                     ? LOW_BOUND_DEFAULT : LOW_BOUND_DEFAULT_EXCLUSIVE);
+           if (kind == (RANGE_HIGH_BOUND_DEFAULT | RANGE_LOW_BOUND_DEFAULT))
+             {
+               kind = RANGE_LOW_BOUND_DEFAULT;
+               if (!operation->inclusive)
+                 kind |= RANGE_HIGH_BOUND_EXCLUSIVE;
+             }
            else
              {
-               gdb_assert (kind == HIGH_BOUND_DEFAULT);
-               kind = (operation->inclusive
-                       ? NONE_BOUND_DEFAULT : NONE_BOUND_DEFAULT_EXCLUSIVE);
+               gdb_assert (kind == RANGE_HIGH_BOUND_DEFAULT);
+               kind = RANGE_STANDARD;
+               if (!operation->inclusive)
+                 kind |= RANGE_HIGH_BOUND_EXCLUSIVE;
              }
          }
        else
 
   kind = (enum range_type) longest_to_int (exp->elts[*pos + 1].longconst);
   *pos += 3;
 
-  if (kind == HIGH_BOUND_DEFAULT || kind == NONE_BOUND_DEFAULT
-      || kind == NONE_BOUND_DEFAULT_EXCLUSIVE)
+  if (!(kind & RANGE_LOW_BOUND_DEFAULT))
     low = evaluate_subexp (nullptr, exp, pos, noside);
-  if (kind == LOW_BOUND_DEFAULT || kind == LOW_BOUND_DEFAULT_EXCLUSIVE
-      || kind == NONE_BOUND_DEFAULT || kind == NONE_BOUND_DEFAULT_EXCLUSIVE)
+  if (!(kind & RANGE_HIGH_BOUND_DEFAULT))
     high = evaluate_subexp (nullptr, exp, pos, noside);
-  bool inclusive = (kind == NONE_BOUND_DEFAULT || kind == LOW_BOUND_DEFAULT);
+  bool inclusive = !(kind & RANGE_HIGH_BOUND_EXCLUSIVE);
 
   if (noside == EVAL_SKIP)
     return value_from_longest (builtin_type (exp->gdbarch)->builtin_int, 1);
 static void
 rust_compute_range (struct type *type, struct value *range,
                    LONGEST *low, LONGEST *high,
-                   enum range_type *kind)
+                   range_types *kind)
 {
   int i;
 
   *low = 0;
   *high = 0;
-  *kind = BOTH_BOUND_DEFAULT;
+  *kind = RANGE_LOW_BOUND_DEFAULT | RANGE_HIGH_BOUND_DEFAULT;
 
   if (type->num_fields () == 0)
     return;
   i = 0;
   if (strcmp (TYPE_FIELD_NAME (type, 0), "start") == 0)
     {
-      *kind = HIGH_BOUND_DEFAULT;
+      *kind = RANGE_HIGH_BOUND_DEFAULT;
       *low = value_as_long (value_field (range, 0));
       ++i;
     }
   if (type->num_fields () > i
       && strcmp (TYPE_FIELD_NAME (type, i), "end") == 0)
     {
-      *kind = (*kind == BOTH_BOUND_DEFAULT
-              ? LOW_BOUND_DEFAULT : NONE_BOUND_DEFAULT);
+      *kind = (*kind == (RANGE_LOW_BOUND_DEFAULT | RANGE_HIGH_BOUND_DEFAULT)
+              ? RANGE_LOW_BOUND_DEFAULT : RANGE_STANDARD);
       *high = value_as_long (value_field (range, i));
 
       if (rust_inclusive_range_type_p (type))
   struct type *rhstype;
   LONGEST low, high_bound;
   /* Initialized to appease the compiler.  */
-  enum range_type kind = BOTH_BOUND_DEFAULT;
+  range_types kind = RANGE_LOW_BOUND_DEFAULT | RANGE_HIGH_BOUND_DEFAULT;
   LONGEST high = 0;
   int want_slice = 0;
 
       else
        error (_("Cannot subscript non-array type"));
 
-      if (want_slice
-         && (kind == BOTH_BOUND_DEFAULT || kind == LOW_BOUND_DEFAULT))
+      if (want_slice && (kind & RANGE_LOW_BOUND_DEFAULT))
        low = low_bound;
       if (low < 0)
        error (_("Index less than zero"));
          CORE_ADDR addr;
          struct value *addrval, *tem;
 
-         if (kind == BOTH_BOUND_DEFAULT || kind == HIGH_BOUND_DEFAULT)
+         if (kind & RANGE_HIGH_BOUND_DEFAULT)
            high = high_bound;
          if (high < 0)
            error (_("High index less than zero"));