type0->dyn_prop (DYN_PROP_BYTE_STRIDE),
                               TYPE_FIELD_BITSIZE (type0, 0));
   int base_low =  ada_discrete_type_low_bound (type0->index_type ());
-  LONGEST base_low_pos, low_pos;
+  gdb::optional<LONGEST> base_low_pos, low_pos;
   CORE_ADDR base;
 
-  if (!discrete_position (base_index_type, low, &low_pos)
-      || !discrete_position (base_index_type, base_low, &base_low_pos))
+  low_pos = discrete_position (base_index_type, low);
+  base_low_pos = discrete_position (base_index_type, base_low);
+
+  if (!low_pos.has_value () || !base_low_pos.has_value ())
     {
       warning (_("unable to get positions in slice, use bounds instead"));
       low_pos = low;
   if (stride == 0)
     stride = TYPE_LENGTH (TYPE_TARGET_TYPE (type0));
 
-  base = value_as_address (array_ptr) + (low_pos - base_low_pos) * stride;
+  base = value_as_address (array_ptr) + (*low_pos - *base_low_pos) * stride;
   return value_at_lazy (slice_type, base);
 }
 
                              (NULL, TYPE_TARGET_TYPE (type), index_type,
                               type->dyn_prop (DYN_PROP_BYTE_STRIDE),
                               TYPE_FIELD_BITSIZE (type, 0));
-  LONGEST low_pos, high_pos;
+  gdb::optional<LONGEST> low_pos, high_pos;
+
 
-  if (!discrete_position (base_index_type, low, &low_pos)
-      || !discrete_position (base_index_type, high, &high_pos))
+  low_pos = discrete_position (base_index_type, low);
+  high_pos = discrete_position (base_index_type, high);
+
+  if (!low_pos.has_value () || !high_pos.has_value ())
     {
       warning (_("unable to get positions in slice, use bounds instead"));
       low_pos = low;
     }
 
   return value_cast (slice_type,
-                    value_slice (array, low, high_pos - low_pos + 1));
+                    value_slice (array, low, *high_pos - *low_pos + 1));
 }
 
 /* If type is a record type in the form of a standard GNAT array
 {
   struct value *val = coerce_ref (arg);
   struct type *type = value_type (val);
-  LONGEST result;
 
   if (!discrete_type_p (type))
     error (_("'POS only defined on discrete types"));
 
-  if (!discrete_position (type, value_as_long (val), &result))
+  gdb::optional<LONGEST> result = discrete_position (type, value_as_long (val));
+  if (!result.has_value ())
     error (_("enumeration value is invalid: can't find 'POS"));
 
-  return result;
+  return *result;
 }
 
 static struct value *
 
 
       if (TYPE_TARGET_TYPE (type)->code () == TYPE_CODE_ENUM)
        {
-         if (!discrete_position (TYPE_TARGET_TYPE (type), *lowp, lowp)
-             || ! discrete_position (TYPE_TARGET_TYPE (type), *highp, highp))
+         gdb::optional<LONGEST> low_pos
+           = discrete_position (TYPE_TARGET_TYPE (type), *lowp);
+
+         if (!low_pos.has_value ())
+           return 0;
+
+         *lowp = *low_pos;
+
+         gdb::optional<LONGEST> high_pos
+           = discrete_position (TYPE_TARGET_TYPE (type), *highp);
+
+         if (!high_pos.has_value ())
            return 0;
+
+         *highp = *high_pos;
        }
       return 1;
     case TYPE_CODE_ENUM:
    in which case the value of POS is unmodified.
 */
 
-int
-discrete_position (struct type *type, LONGEST val, LONGEST *pos)
+gdb::optional<LONGEST>
+discrete_position (struct type *type, LONGEST val)
 {
   if (type->code () == TYPE_CODE_RANGE)
     type = TYPE_TARGET_TYPE (type);
       for (i = 0; i < type->num_fields (); i += 1)
        {
          if (val == TYPE_FIELD_ENUMVAL (type, i))
-           {
-             *pos = i;
-             return 1;
-           }
+           return i;
        }
+
       /* Invalid enumeration value.  */
-      return 0;
+      return {};
     }
   else
-    {
-      *pos = val;
-      return 1;
-    }
+    return val;
 }
 
 /* If the array TYPE has static bounds calculate and update its
 
 
 #include "hashtab.h"
 #include "gdbsupport/array-view.h"
+#include "gdbsupport/gdb_optional.h"
 #include "gdbsupport/offset-type.h"
 #include "gdbsupport/enum-flags.h"
 #include "gdbsupport/underlying.h"
 extern bool get_array_bounds (struct type *type, LONGEST *low_bound,
                              LONGEST *high_bound);
 
-extern int discrete_position (struct type *type, LONGEST val, LONGEST *pos);
+extern gdb::optional<LONGEST> discrete_position (struct type *type,
+                                                LONGEST val);
 
 extern int class_types_same_p (const struct type *, const struct type *);