Add support for printing value of DWARF-based fixed-point type objects
[deliverable/binutils-gdb.git] / gdb / gdbtypes.c
index 075363000b4fb8091717b7bd174cc8f3178233f9..2f92887b3cfcd81c554ac0fa10f9de7c1cc95ce0 100644 (file)
@@ -40,6 +40,7 @@
 #include "gdbcore.h"
 #include "floatformat.h"
 #include <algorithm>
+#include "gmp-utils.h"
 
 /* Initialize BADNESS constants.  */
 
@@ -405,7 +406,7 @@ lookup_pointer_type (struct type *type)
 
 struct type *
 make_reference_type (struct type *type, struct type **typeptr,
-                      enum type_code refcode)
+                     enum type_code refcode)
 {
   struct type *ntype;  /* New type */
   struct type **reftype;
@@ -414,7 +415,7 @@ make_reference_type (struct type *type, struct type **typeptr,
   gdb_assert (refcode == TYPE_CODE_REF || refcode == TYPE_CODE_RVALUE_REF);
 
   ntype = (refcode == TYPE_CODE_REF ? TYPE_REFERENCE_TYPE (type)
-           : TYPE_RVALUE_REFERENCE_TYPE (type));
+          : TYPE_RVALUE_REFERENCE_TYPE (type));
 
   if (ntype)
     {
@@ -444,7 +445,7 @@ make_reference_type (struct type *type, struct type **typeptr,
 
   TYPE_TARGET_TYPE (ntype) = type;
   reftype = (refcode == TYPE_CODE_REF ? &TYPE_REFERENCE_TYPE (type)
-             : &TYPE_RVALUE_REFERENCE_TYPE (type));
+            : &TYPE_RVALUE_REFERENCE_TYPE (type));
 
   *reftype = ntype;
 
@@ -552,7 +553,7 @@ lookup_function_type_with_arguments (struct type *type,
       if (param_types[nparams - 1] == NULL)
        {
          --nparams;
-         TYPE_VARARGS (fn) = 1;
+         fn->set_has_varargs (true);
        }
       else if (check_typedef (param_types[nparams - 1])->code ()
               == TYPE_CODE_VOID)
@@ -575,14 +576,14 @@ lookup_function_type_with_arguments (struct type *type,
   return fn;
 }
 
-/* Identify address space identifier by name --
-   return the integer flag defined in gdbtypes.h.  */
+/* Identify address space identifier by name -- return a
+   type_instance_flags.  */
 
-int
-address_space_name_to_int (struct gdbarch *gdbarch,
-                          const char *space_identifier)
+type_instance_flags
+address_space_name_to_type_instance_flags (struct gdbarch *gdbarch,
+                                          const char *space_identifier)
 {
-  int type_flags;
+  type_instance_flags type_flags;
 
   /* Check for known address space delimiters.  */
   if (!strcmp (space_identifier, "code"))
@@ -590,7 +591,7 @@ address_space_name_to_int (struct gdbarch *gdbarch,
   else if (!strcmp (space_identifier, "data"))
     return TYPE_INSTANCE_FLAG_DATA_SPACE;
   else if (gdbarch_address_class_name_to_type_flags_p (gdbarch)
-           && gdbarch_address_class_name_to_type_flags (gdbarch,
+          && gdbarch_address_class_name_to_type_flags (gdbarch,
                                                        space_identifier,
                                                        &type_flags))
     return type_flags;
@@ -598,18 +599,19 @@ address_space_name_to_int (struct gdbarch *gdbarch,
     error (_("Unknown address space specifier: \"%s\""), space_identifier);
 }
 
-/* Identify address space identifier by integer flag as defined in 
-   gdbtypes.h -- return the string version of the adress space name.  */
+/* Identify address space identifier by type_instance_flags and return
+   the string version of the adress space name.  */
 
 const char *
-address_space_int_to_name (struct gdbarch *gdbarch, int space_flag)
+address_space_type_instance_flags_to_name (struct gdbarch *gdbarch,
+                                          type_instance_flags space_flag)
 {
   if (space_flag & TYPE_INSTANCE_FLAG_CODE_SPACE)
     return "code";
   else if (space_flag & TYPE_INSTANCE_FLAG_DATA_SPACE)
     return "data";
   else if ((space_flag & TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL)
-           && gdbarch_address_class_type_flags_to_name_p (gdbarch))
+          && gdbarch_address_class_type_flags_to_name_p (gdbarch))
     return gdbarch_address_class_type_flags_to_name (gdbarch, space_flag);
   else
     return NULL;
@@ -621,7 +623,7 @@ address_space_int_to_name (struct gdbarch *gdbarch, int space_flag)
    STORAGE must be in the same obstack as TYPE.  */
 
 static struct type *
-make_qualified_type (struct type *type, int new_flags,
+make_qualified_type (struct type *type, type_instance_flags new_flags,
                     struct type *storage)
 {
   struct type *ntype;
@@ -629,7 +631,7 @@ make_qualified_type (struct type *type, int new_flags,
   ntype = type;
   do
     {
-      if (TYPE_INSTANCE_FLAGS (ntype) == new_flags)
+      if (ntype->instance_flags () == new_flags)
        return ntype;
       ntype = TYPE_CHAIN (ntype);
     }
@@ -661,7 +663,7 @@ make_qualified_type (struct type *type, int new_flags,
   TYPE_CHAIN (type) = ntype;
 
   /* Now set the instance flags and return the new type.  */
-  TYPE_INSTANCE_FLAGS (ntype) = new_flags;
+  ntype->set_instance_flags (new_flags);
 
   /* Set length of new type to that of the original type.  */
   TYPE_LENGTH (ntype) = TYPE_LENGTH (type);
@@ -679,13 +681,14 @@ make_qualified_type (struct type *type, int new_flags,
    representations.  */
 
 struct type *
-make_type_with_address_space (struct type *type, int space_flag)
+make_type_with_address_space (struct type *type,
+                             type_instance_flags space_flag)
 {
-  int new_flags = ((TYPE_INSTANCE_FLAGS (type)
-                   & ~(TYPE_INSTANCE_FLAG_CODE_SPACE
-                       | TYPE_INSTANCE_FLAG_DATA_SPACE
-                       | TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL))
-                  | space_flag);
+  type_instance_flags new_flags = ((type->instance_flags ()
+                                   & ~(TYPE_INSTANCE_FLAG_CODE_SPACE
+                                       | TYPE_INSTANCE_FLAG_DATA_SPACE
+                                       | TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL))
+                                  | space_flag);
 
   return make_qualified_type (type, new_flags, NULL);
 }
@@ -709,9 +712,9 @@ make_cv_type (int cnst, int voltl,
 {
   struct type *ntype;  /* New type */
 
-  int new_flags = (TYPE_INSTANCE_FLAGS (type)
-                  & ~(TYPE_INSTANCE_FLAG_CONST 
-                      | TYPE_INSTANCE_FLAG_VOLATILE));
+  type_instance_flags new_flags = (type->instance_flags ()
+                                  & ~(TYPE_INSTANCE_FLAG_CONST
+                                      | TYPE_INSTANCE_FLAG_VOLATILE));
 
   if (cnst)
     new_flags |= TYPE_INSTANCE_FLAG_CONST;
@@ -751,7 +754,7 @@ struct type *
 make_restrict_type (struct type *type)
 {
   return make_qualified_type (type,
-                             (TYPE_INSTANCE_FLAGS (type)
+                             (type->instance_flags ()
                               | TYPE_INSTANCE_FLAG_RESTRICT),
                              NULL);
 }
@@ -762,7 +765,7 @@ struct type *
 make_unqualified_type (struct type *type)
 {
   return make_qualified_type (type,
-                             (TYPE_INSTANCE_FLAGS (type)
+                             (type->instance_flags ()
                               & ~(TYPE_INSTANCE_FLAG_CONST
                                   | TYPE_INSTANCE_FLAG_VOLATILE
                                   | TYPE_INSTANCE_FLAG_RESTRICT)),
@@ -775,7 +778,7 @@ struct type *
 make_atomic_type (struct type *type)
 {
   return make_qualified_type (type,
-                             (TYPE_INSTANCE_FLAGS (type)
+                             (type->instance_flags ()
                               | TYPE_INSTANCE_FLAG_ATOMIC),
                              NULL);
 }
@@ -823,7 +826,7 @@ replace_type (struct type *ntype, struct type *type)
 
   /* Assert that the two types have equivalent instance qualifiers.
      This should be true for at least all of our debug readers.  */
-  gdb_assert (TYPE_INSTANCE_FLAGS (ntype) == TYPE_INSTANCE_FLAGS (type));
+  gdb_assert (ntype->instance_flags () == type->instance_flags ());
 }
 
 /* Implement direct support for MEMBER_TYPE in GNU C++.
@@ -948,9 +951,17 @@ create_range_type (struct type *result_type, struct type *index_type,
 
   result_type->set_bounds (bounds);
 
-  if (low_bound->kind () == PROP_CONST && low_bound->const_val () >= 0)
+  if (index_type->code () == TYPE_CODE_FIXED_POINT)
+    result_type->set_is_unsigned (index_type->is_unsigned ());
+  /* Note that the signed-ness of a range type can't simply be copied
+     from the underlying type.  Consider a case where the underlying
+     type is 'int', but the range type can hold 0..65535, and where
+     the range is further specified to fit into 16 bits.  In this
+     case, if we copy the underlying type's sign, then reading some
+     range values will cause an unwanted sign extension.  So, we have
+     some heuristics here instead.  */
+  else if (low_bound->kind () == PROP_CONST && low_bound->const_val () >= 0)
     result_type->set_is_unsigned (true);
-
   /* Ada allows the declaration of range types whose upper bound is
      less than the lower bound, so checking the lower bound is not
      enough.  Make sure we do not mark a range type whose upper bound
@@ -958,8 +969,8 @@ create_range_type (struct type *result_type, struct type *index_type,
   if (high_bound->kind () == PROP_CONST && high_bound->const_val () < 0)
     result_type->set_is_unsigned (false);
 
-  TYPE_ENDIANITY_NOT_DEFAULT (result_type)
-    = TYPE_ENDIANITY_NOT_DEFAULT (index_type);
+  result_type->set_endianity_is_not_default
+    (index_type->endianity_is_not_default ());
 
   return result_type;
 }
@@ -1040,7 +1051,7 @@ get_discrete_bounds (struct type *type, LONGEST *lowp, LONGEST *highp)
     {
     case TYPE_CODE_RANGE:
       /* This function currently only works for ranges with two defined,
-         constant bounds.  */
+        constant bounds.  */
       if (type->bounds ()->low.kind () != PROP_CONST
          || type->bounds ()->high.kind () != PROP_CONST)
        return -1;
@@ -1098,8 +1109,8 @@ get_discrete_bounds (struct type *type, LONGEST *lowp, LONGEST *highp)
     case TYPE_CODE_CHAR:
       *lowp = 0;
       /* This round-about calculation is to avoid shifting by
-         TYPE_LENGTH (type) * TARGET_CHAR_BIT, which will not work
-         if TYPE_LENGTH (type) == sizeof (LONGEST).  */
+        TYPE_LENGTH (type) * TARGET_CHAR_BIT, which will not work
+        if TYPE_LENGTH (type) == sizeof (LONGEST).  */
       *highp = 1 << (TYPE_LENGTH (type) * TARGET_CHAR_BIT - 1);
       *highp = (*highp - 1) | *highp;
       return 0;
@@ -1164,13 +1175,13 @@ discrete_position (struct type *type, LONGEST val, LONGEST *pos)
       int i;
 
       for (i = 0; i < type->num_fields (); i += 1)
-        {
-          if (val == TYPE_FIELD_ENUMVAL (type, i))
+       {
+         if (val == TYPE_FIELD_ENUMVAL (type, i))
            {
              *pos = i;
              return 1;
            }
-        }
+       }
       /* Invalid enumeration value.  */
       return 0;
     }
@@ -1233,6 +1244,20 @@ update_static_array_size (struct type *type)
        TYPE_LENGTH (type) =
          TYPE_LENGTH (element_type) * (high_bound - low_bound + 1);
 
+      /* If this array's element is itself an array with a bit stride,
+        then we want to update this array's bit stride to reflect the
+        size of the sub-array.  Otherwise, we'll end up using the
+        wrong size when trying to find elements of the outer
+        array.  */
+      if (element_type->code () == TYPE_CODE_ARRAY
+         && TYPE_LENGTH (element_type) != 0
+         && TYPE_FIELD_BITSIZE (element_type, 0) != 0
+         && get_array_bounds (element_type, &low_bound, &high_bound) >= 0
+         && high_bound >= low_bound)
+       TYPE_FIELD_BITSIZE (type, 0)
+         = ((high_bound - low_bound + 1)
+            * TYPE_FIELD_BITSIZE (element_type, 0));
+
       return true;
     }
 
@@ -1297,11 +1322,11 @@ create_array_type_with_stride (struct type *result_type,
   if (!update_static_array_size (result_type))
     {
       /* This type is dynamic and its length needs to be computed
-         on demand.  In the meantime, avoid leaving the TYPE_LENGTH
-         undefined by setting it to zero.  Although we are not expected
-         to trust TYPE_LENGTH in this case, setting the size to zero
-         allows us to avoid allocating objects of random sizes in case
-         we accidently do.  */
+        on demand.  In the meantime, avoid leaving the TYPE_LENGTH
+        undefined by setting it to zero.  Although we are not expected
+        to trust TYPE_LENGTH in this case, setting the size to zero
+        allows us to avoid allocating objects of random sizes in case
+        we accidently do.  */
       TYPE_LENGTH (result_type) = 0;
     }
 
@@ -1412,7 +1437,6 @@ void
 make_vector_type (struct type *array_type)
 {
   struct type *inner_array, *elt_type;
-  int flags;
 
   /* Find the innermost array type, in case the array is
      multi-dimensional.  */
@@ -1423,12 +1447,13 @@ make_vector_type (struct type *array_type)
   elt_type = TYPE_TARGET_TYPE (inner_array);
   if (elt_type->code () == TYPE_CODE_INT)
     {
-      flags = TYPE_INSTANCE_FLAGS (elt_type) | TYPE_INSTANCE_FLAG_NOTTEXT;
+      type_instance_flags flags
+       = elt_type->instance_flags () | TYPE_INSTANCE_FLAG_NOTTEXT;
       elt_type = make_qualified_type (elt_type, flags, NULL);
       TYPE_TARGET_TYPE (inner_array) = elt_type;
     }
 
-  TYPE_VECTOR (array_type) = 1;
+  array_type->set_is_vector (true);
 }
 
 struct type *
@@ -1556,7 +1581,7 @@ smash_to_method_type (struct type *type, struct type *self_type,
   type->set_fields (args);
   type->set_num_fields (nargs);
   if (varargs)
-    TYPE_VARARGS (type) = 1;
+    type->set_has_varargs (true);
   TYPE_LENGTH (type) = 1;      /* In practice, this is never needed.  */
 }
 
@@ -1915,7 +1940,7 @@ get_vptr_fieldno (struct type *type, struct type **basetypep)
       int i;
 
       /* We must start at zero in case the first (and only) baseclass
-         is virtual (and hence we cannot share the table pointer).  */
+        is virtual (and hence we cannot share the table pointer).  */
       for (i = 0; i < TYPE_N_BASECLASSES (type); i++)
        {
          struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i));
@@ -2206,7 +2231,7 @@ resolve_dynamic_array_or_string (struct type *type,
     bit_stride = TYPE_FIELD_BITSIZE (type, 0);
 
   return create_array_type_with_stride (type, elt_type, range_type, NULL,
-                                        bit_stride);
+                                       bit_stride);
 }
 
 /* Resolve dynamic bounds of members of the union TYPE to static
@@ -2647,7 +2672,7 @@ type::dyn_prop (dynamic_prop_node_kind prop_kind) const
   while (node != NULL)
     {
       if (node->prop_kind == prop_kind)
-        return &node->prop;
+       return &node->prop;
       node = node->next;
     }
   return NULL;
@@ -2734,12 +2759,13 @@ struct type *
 check_typedef (struct type *type)
 {
   struct type *orig_type = type;
-  /* While we're removing typedefs, we don't want to lose qualifiers.
-     E.g., const/volatile.  */
-  int instance_flags = TYPE_INSTANCE_FLAGS (type);
 
   gdb_assert (type);
 
+  /* While we're removing typedefs, we don't want to lose qualifiers.
+     E.g., const/volatile.  */
+  type_instance_flags instance_flags = type->instance_flags ();
+
   while (type->code () == TYPE_CODE_TYPEDEF)
     {
       if (!TYPE_TARGET_TYPE (type))
@@ -2780,10 +2806,13 @@ check_typedef (struct type *type)
         outer cast in a chain of casting win), instead of assuming
         "it can't happen".  */
       {
-       const int ALL_SPACES = (TYPE_INSTANCE_FLAG_CODE_SPACE
-                               | TYPE_INSTANCE_FLAG_DATA_SPACE);
-       const int ALL_CLASSES = TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL;
-       int new_instance_flags = TYPE_INSTANCE_FLAGS (type);
+       const type_instance_flags ALL_SPACES
+         = (TYPE_INSTANCE_FLAG_CODE_SPACE
+            | TYPE_INSTANCE_FLAG_DATA_SPACE);
+       const type_instance_flags ALL_CLASSES
+         = TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL;
+
+       type_instance_flags new_instance_flags = type->instance_flags ();
 
        /* Treat code vs data spaces and address classes separately.  */
        if ((instance_flags & ALL_SPACES) != 0)
@@ -2828,9 +2857,7 @@ check_typedef (struct type *type)
             move over any other types NEWTYPE refers to, which could
             be an unbounded amount of stuff.  */
          if (TYPE_OBJFILE (newtype) == TYPE_OBJFILE (type))
-           type = make_qualified_type (newtype,
-                                       TYPE_INSTANCE_FLAGS (type),
-                                       type);
+           type = make_qualified_type (newtype, type->instance_flags (), type);
          else
            type = newtype;
        }
@@ -2841,7 +2868,7 @@ check_typedef (struct type *type)
     {
       const char *name = type->name ();
       /* FIXME: shouldn't we look in STRUCT_DOMAIN and/or VAR_DOMAIN
-         as appropriate?  */
+        as appropriate?  */
       struct symbol *sym;
 
       if (name == NULL)
@@ -2851,17 +2878,16 @@ check_typedef (struct type *type)
        }
       sym = lookup_symbol (name, 0, STRUCT_DOMAIN, 0).symbol;
       if (sym)
-        {
-          /* Same as above for opaque types, we can replace the stub
-             with the complete type only if they are in the same
-             objfile.  */
+       {
+         /* Same as above for opaque types, we can replace the stub
+            with the complete type only if they are in the same
+            objfile.  */
          if (TYPE_OBJFILE (SYMBOL_TYPE (sym)) == TYPE_OBJFILE (type))
-            type = make_qualified_type (SYMBOL_TYPE (sym),
-                                       TYPE_INSTANCE_FLAGS (type),
-                                       type);
+           type = make_qualified_type (SYMBOL_TYPE (sym),
+                                       type->instance_flags (), type);
          else
            type = SYMBOL_TYPE (sym);
-        }
+       }
     }
 
   if (type->target_is_stub ())
@@ -3001,7 +3027,7 @@ check_stub_method (struct type *type, int method_id, int signature_id)
          if (depth <= 0 && (*p == ',' || *p == ')'))
            {
              /* Avoid parsing of ellipsis, they will be handled below.
-                Also avoid ``void'' as above.  */
+                Also avoid ``void'' as above.  */
              if (strncmp (argtypetext, "...", p - argtypetext) != 0
                  && strncmp (argtypetext, "void", p - argtypetext) != 0)
                {
@@ -3106,14 +3132,17 @@ set_type_code (struct type *type, enum type_code code)
       case TYPE_CODE_STRUCT:
       case TYPE_CODE_UNION:
       case TYPE_CODE_NAMESPACE:
-        INIT_CPLUS_SPECIFIC (type);
-        break;
+       INIT_CPLUS_SPECIFIC (type);
+       break;
       case TYPE_CODE_FLT:
-        TYPE_SPECIFIC_FIELD (type) = TYPE_SPECIFIC_FLOATFORMAT;
-        break;
+       TYPE_SPECIFIC_FIELD (type) = TYPE_SPECIFIC_FLOATFORMAT;
+       break;
       case TYPE_CODE_FUNC:
        INIT_FUNC_SPECIFIC (type);
         break;
+      case TYPE_CODE_FIXED_POINT:
+       INIT_FIXED_POINT_SPECIFIC (type);
+       break;
     }
 }
 
@@ -3191,6 +3220,10 @@ init_integer_type (struct objfile *objfile,
   if (unsigned_p)
     t->set_is_unsigned (true);
 
+  TYPE_SPECIFIC_FIELD (t) = TYPE_SPECIFIC_INT;
+  TYPE_MAIN_TYPE (t)->type_specific.int_stuff.bit_size = bit;
+  TYPE_MAIN_TYPE (t)->type_specific.int_stuff.bit_offset = 0;
+
   return t;
 }
 
@@ -3225,6 +3258,10 @@ init_boolean_type (struct objfile *objfile,
   if (unsigned_p)
     t->set_is_unsigned (true);
 
+  TYPE_SPECIFIC_FIELD (t) = TYPE_SPECIFIC_INT;
+  TYPE_MAIN_TYPE (t)->type_specific.int_stuff.bit_size = bit;
+  TYPE_MAIN_TYPE (t)->type_specific.int_stuff.bit_offset = 0;
+
   return t;
 }
 
@@ -3281,7 +3318,7 @@ init_complex_type (const char *name, struct type *target_type)
 
   if (TYPE_MAIN_TYPE (target_type)->flds_bnds.complex_type == nullptr)
     {
-      if (name == nullptr)
+      if (name == nullptr && target_type->name () != nullptr)
        {
          char *new_name
            = (char *) TYPE_ALLOC (target_type,
@@ -3321,6 +3358,24 @@ init_pointer_type (struct objfile *objfile,
   return t;
 }
 
+/* Allocate a TYPE_CODE_FIXED_POINT type structure associated with OBJFILE.
+   BIT is the pointer type size in bits.
+   UNSIGNED_P should be nonzero if the type is unsigned.
+   NAME is the type name.  */
+
+struct type *
+init_fixed_point_type (struct objfile *objfile,
+                      int bit, int unsigned_p, const char *name)
+{
+  struct type *t;
+
+  t = init_type (objfile, TYPE_CODE_FIXED_POINT, bit, name);
+  if (unsigned_p)
+    t->set_is_unsigned (true);
+
+  return t;
+}
+
 /* See gdbtypes.h.  */
 
 unsigned
@@ -3467,6 +3522,7 @@ is_integral_type (struct type *t)
   t = check_typedef (t);
   return
     ((t != NULL)
+     && !is_fixed_point_type (t)
      && ((t->code () == TYPE_CODE_INT)
         || (t->code () == TYPE_CODE_ENUM)
         || (t->code () == TYPE_CODE_FLAGS)
@@ -3492,6 +3548,9 @@ is_scalar_type (struct type *type)
 {
   type = check_typedef (type);
 
+  if (is_fixed_point_type (type))
+    return 0; /* Implemented as a scalar, but more like a floating point.  */
+
   switch (type->code ())
     {
     case TYPE_CODE_ARRAY:
@@ -3552,7 +3611,7 @@ int
 class_or_union_p (const struct type *t)
 {
   return (t->code () == TYPE_CODE_STRUCT
-          || t->code () == TYPE_CODE_UNION);
+         || t->code () == TYPE_CODE_UNION);
 }
 
 /* A helper function which returns true if types A and B represent the
@@ -3705,10 +3764,10 @@ enum bfd_endian
 type_byte_order (const struct type *type)
 {
   bfd_endian byteorder = gdbarch_byte_order (get_type_arch (type));
-  if (TYPE_ENDIANITY_NOT_DEFAULT (type))
+  if (type->endianity_is_not_default ())
     {
       if (byteorder == BFD_ENDIAN_BIG)
-        return BFD_ENDIAN_LITTLE;
+       return BFD_ENDIAN_LITTLE;
       else
        {
          gdb_assert (byteorder == BFD_ENDIAN_LITTLE);
@@ -3910,7 +3969,7 @@ types_equal (struct type *a, struct type *b)
   if (a->code () == TYPE_CODE_PTR
       || a->code () == TYPE_CODE_REF)
     return types_equal (TYPE_TARGET_TYPE (a),
-                        TYPE_TARGET_TYPE (b));
+                       TYPE_TARGET_TYPE (b));
 
   /* Well, damnit, if the names are exactly the same, I'll say they
      are exactly the same.  This happens when we generate method
@@ -3991,11 +4050,11 @@ check_types_equal (struct type *type1, struct type *type2,
       || TYPE_LENGTH (type1) != TYPE_LENGTH (type2)
       || type1->is_unsigned () != type2->is_unsigned ()
       || type1->has_no_signedness () != type2->has_no_signedness ()
-      || TYPE_ENDIANITY_NOT_DEFAULT (type1) != TYPE_ENDIANITY_NOT_DEFAULT (type2)
-      || TYPE_VARARGS (type1) != TYPE_VARARGS (type2)
-      || TYPE_VECTOR (type1) != TYPE_VECTOR (type2)
+      || type1->endianity_is_not_default () != type2->endianity_is_not_default ()
+      || type1->has_varargs () != type2->has_varargs ()
+      || type1->is_vector () != type2->is_vector ()
       || TYPE_NOTTEXT (type1) != TYPE_NOTTEXT (type2)
-      || TYPE_INSTANCE_FLAGS (type1) != TYPE_INSTANCE_FLAGS (type2)
+      || type1->instance_flags () != type2->instance_flags ()
       || type1->num_fields () != type2->num_fields ())
     return false;
 
@@ -4122,7 +4181,7 @@ types_deeply_equal (struct type *type1, struct type *type2)
   if (type1 == type2)
     return true;
 
-  gdb::bcache cache (nullptr, nullptr);
+  gdb::bcache cache;
   worklist.emplace_back (type1, type2);
   return check_types_worklist (&worklist, &cache);
 }
@@ -4609,10 +4668,10 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value)
 
   if (TYPE_IS_REFERENCE (arg))
     return (sum_ranks (rank_one_type (parm, TYPE_TARGET_TYPE (arg), NULL),
-                       REFERENCE_SEE_THROUGH_BADNESS));
+                      REFERENCE_SEE_THROUGH_BADNESS));
   if (TYPE_IS_REFERENCE (parm))
     return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm), arg, NULL),
-                       REFERENCE_SEE_THROUGH_BADNESS));
+                      REFERENCE_SEE_THROUGH_BADNESS));
   if (overload_debug)
   /* Debugging only.  */
     fprintf_filtered (gdb_stderr,
@@ -4856,6 +4915,16 @@ print_gnat_stuff (struct type *type, int spaces)
     }
 }
 
+/* Print the contents of the TYPE's type_specific union, assuming that
+   its type-specific kind is TYPE_SPECIFIC_FIXED_POINT.  */
+
+static void
+print_fixed_point_type_info (struct type *type, int spaces)
+{
+  printfi_filtered (spaces + 2, "scaling factor: %s\n",
+                   fixed_point_scaling_factor (type).str ().get ());
+}
+
 static struct obstack dont_print_type_obstack;
 
 /* Print the dynamic_prop PROP.  */
@@ -4994,6 +5063,9 @@ recursive_dump_type (struct type *type, int spaces)
     case TYPE_CODE_NAMESPACE:
       printf_filtered ("(TYPE_CODE_NAMESPACE)");
       break;
+    case TYPE_CODE_FIXED_POINT:
+      printf_filtered ("(TYPE_CODE_FIXED_POINT)");
+      break;
     default:
       printf_filtered ("(UNKNOWN TYPE CODE)");
       break;
@@ -5028,7 +5100,7 @@ recursive_dump_type (struct type *type, int spaces)
   gdb_print_host_address (TYPE_CHAIN (type), gdb_stdout);
   printf_filtered ("\n");
   printfi_filtered (spaces, "instance_flags 0x%x", 
-                   TYPE_INSTANCE_FLAGS (type));
+                   (unsigned) type->instance_flags ());
   if (TYPE_CONST (type))
     {
       puts_filtered (" TYPE_CONST");
@@ -5072,7 +5144,7 @@ recursive_dump_type (struct type *type, int spaces)
     {
       puts_filtered (" TYPE_NOSIGN");
     }
-  if (TYPE_ENDIANITY_NOT_DEFAULT (type))
+  if (type->endianity_is_not_default ())
     {
       puts_filtered (" TYPE_ENDIANITY_NOT_DEFAULT");
     }
@@ -5084,26 +5156,26 @@ recursive_dump_type (struct type *type, int spaces)
     {
       puts_filtered (" TYPE_TARGET_STUB");
     }
-  if (TYPE_PROTOTYPED (type))
+  if (type->is_prototyped ())
     {
       puts_filtered (" TYPE_PROTOTYPED");
     }
-  if (TYPE_VARARGS (type))
+  if (type->has_varargs ())
     {
       puts_filtered (" TYPE_VARARGS");
     }
   /* This is used for things like AltiVec registers on ppc.  Gcc emits
      an attribute for the array type, which tells whether or not we
      have a vector, instead of a regular array.  */
-  if (TYPE_VECTOR (type))
+  if (type->is_vector ())
     {
       puts_filtered (" TYPE_VECTOR");
     }
-  if (TYPE_FIXED_INSTANCE (type))
+  if (type->is_fixed_instance ())
     {
       puts_filtered (" TYPE_FIXED_INSTANCE");
     }
-  if (TYPE_STUB_SUPPORTED (type))
+  if (type->stub_is_supported ())
     {
       puts_filtered (" TYPE_STUB_SUPPORTED");
     }
@@ -5176,7 +5248,7 @@ recursive_dump_type (struct type *type, int spaces)
 
       case TYPE_SPECIFIC_FUNC:
        printfi_filtered (spaces, "calling_convention %d\n",
-                          TYPE_CALLING_CONVENTION (type));
+                         TYPE_CALLING_CONVENTION (type));
        /* tail_call_list is not printed.  */
        break;
 
@@ -5185,6 +5257,22 @@ recursive_dump_type (struct type *type, int spaces)
        gdb_print_host_address (TYPE_SELF_TYPE (type), gdb_stdout);
        puts_filtered ("\n");
        break;
+
+      case TYPE_SPECIFIC_FIXED_POINT:
+       printfi_filtered (spaces, "fixed_point_info ");
+       print_fixed_point_type_info (type, spaces);
+       puts_filtered ("\n");
+       break;
+
+    case TYPE_SPECIFIC_INT:
+      if (type->bit_size_differs_p ())
+       {
+         unsigned bit_size = type->bit_size ();
+         unsigned bit_off = type->bit_offset ();
+         printfi_filtered (spaces, " bit size = %u, bit offset = %u\n",
+                           bit_size, bit_off);
+       }
+      break;
     }
 
   if (spaces == 0)
@@ -5224,13 +5312,13 @@ type_pair_eq (const void *item_lhs, const void *item_rhs)
    types without duplicates.  We use OBJFILE's obstack, because
    OBJFILE is about to be deleted.  */
 
-htab_t
+htab_up
 create_copied_types_hash (struct objfile *objfile)
 {
-  return htab_create_alloc_ex (1, type_pair_hash, type_pair_eq,
-                              NULL, &objfile->objfile_obstack,
-                              hashtab_obstack_allocate,
-                              dummy_obstack_deallocate);
+  return htab_up (htab_create_alloc_ex (1, type_pair_hash, type_pair_eq,
+                                       NULL, &objfile->objfile_obstack,
+                                       hashtab_obstack_allocate,
+                                       dummy_obstack_deallocate));
 }
 
 /* Recursively copy (deep copy) a dynamic attribute list of a type.  */
@@ -5302,7 +5390,7 @@ copy_type_recursive (struct objfile *objfile,
   if (type->name ())
     new_type->set_name (xstrdup (type->name ()));
 
-  TYPE_INSTANCE_FLAGS (new_type) = TYPE_INSTANCE_FLAGS (type);
+  new_type->set_instance_flags (type->instance_flags ());
   TYPE_LENGTH (new_type) = TYPE_LENGTH (type);
 
   /* Copy the fields.  */
@@ -5358,7 +5446,7 @@ copy_type_recursive (struct objfile *objfile,
   if (type->code () == TYPE_CODE_RANGE)
     {
       range_bounds *bounds
-        = ((struct range_bounds *) TYPE_ALLOC
+       = ((struct range_bounds *) TYPE_ALLOC
           (new_type, sizeof (struct range_bounds)));
 
       *bounds = *type->bounds ();
@@ -5408,6 +5496,17 @@ copy_type_recursive (struct objfile *objfile,
                          copy_type_recursive (objfile, TYPE_SELF_TYPE (type),
                                               copied_types));
       break;
+    case TYPE_SPECIFIC_FIXED_POINT:
+      INIT_FIXED_POINT_SPECIFIC (new_type);
+      TYPE_FIXED_POINT_INFO (new_type)->scaling_factor
+       = TYPE_FIXED_POINT_INFO (type)->scaling_factor;
+      break;
+    case TYPE_SPECIFIC_INT:
+      TYPE_SPECIFIC_FIELD (new_type) = TYPE_SPECIFIC_INT;
+      TYPE_MAIN_TYPE (new_type)->type_specific.int_stuff
+       = TYPE_MAIN_TYPE (type)->type_specific.int_stuff;
+      break;
+
     default:
       gdb_assert_not_reached ("bad type_specific_kind");
     }
@@ -5429,7 +5528,7 @@ copy_type (const struct type *type)
   gdb_assert (TYPE_OBJFILE_OWNED (type));
 
   new_type = alloc_type_copy (type);
-  TYPE_INSTANCE_FLAGS (new_type) = TYPE_INSTANCE_FLAGS (type);
+  new_type->set_instance_flags (type->instance_flags ());
   TYPE_LENGTH (new_type) = TYPE_LENGTH (type);
   memcpy (TYPE_MAIN_TYPE (new_type), TYPE_MAIN_TYPE (type),
          sizeof (struct main_type));
@@ -5705,6 +5804,85 @@ append_composite_type_field (struct type *t, const char *name,
   append_composite_type_field_aligned (t, name, field, 0);
 }
 
+\f
+
+/* We manage the lifetimes of fixed_point_type_info objects by
+   attaching them to the objfile.  Currently, these objects are
+   modified during construction, and GMP does not provide a way to
+   hash the contents of an mpq_t; so it's a bit of a pain to hash-cons
+   them.  If we did do this, they could be moved to the per-BFD and
+   shared across objfiles.  */
+typedef std::vector<std::unique_ptr<fixed_point_type_info>>
+    fixed_point_type_storage;
+
+/* Key used for managing the storage of fixed-point type info.  */
+static const struct objfile_key<fixed_point_type_storage>
+    fixed_point_objfile_key;
+
+/* See gdbtypes.h.  */
+
+fixed_point_type_info *
+allocate_fixed_point_type_info (struct type *type)
+{
+  std::unique_ptr<fixed_point_type_info> up (new fixed_point_type_info);
+  fixed_point_type_info *result;
+
+  if (TYPE_OBJFILE_OWNED (type))
+    {
+      fixed_point_type_storage *storage
+       = fixed_point_objfile_key.get (TYPE_OBJFILE (type));
+      if (storage == nullptr)
+       storage = fixed_point_objfile_key.emplace (TYPE_OBJFILE (type));
+      result = up.get ();
+      storage->push_back (std::move (up));
+    }
+  else
+    {
+      /* We just leak the memory, because that's what we do generally
+        for non-objfile-attached types.  */
+      result = up.release ();
+    }
+
+  return result;
+}
+
+/* See gdbtypes.h.  */
+
+bool
+is_fixed_point_type (struct type *type)
+{
+  while (check_typedef (type)->code () == TYPE_CODE_RANGE)
+    type = TYPE_TARGET_TYPE (check_typedef (type));
+  type = check_typedef (type);
+
+  return type->code () == TYPE_CODE_FIXED_POINT;
+}
+
+/* See gdbtypes.h.  */
+
+struct type *
+fixed_point_type_base_type (struct type *type)
+{
+  while (check_typedef (type)->code () == TYPE_CODE_RANGE)
+    type = TYPE_TARGET_TYPE (check_typedef (type));
+  type = check_typedef (type);
+
+  gdb_assert (type->code () == TYPE_CODE_FIXED_POINT);
+  return type;
+}
+
+/* See gdbtypes.h.  */
+
+const gdb_mpq &
+fixed_point_scaling_factor (struct type *type)
+{
+  type = fixed_point_type_base_type (type);
+
+  return TYPE_FIXED_POINT_INFO (type)->scaling_factor;
+}
+
+\f
+
 static struct gdbarch_data *gdbtypes_data;
 
 const struct builtin_type *
@@ -5822,10 +6000,14 @@ gdbtypes_post_init (struct gdbarch *gdbarch)
     = arch_integer_type (gdbarch, 128, 0, "int128_t");
   builtin_type->builtin_uint128
     = arch_integer_type (gdbarch, 128, 1, "uint128_t");
-  TYPE_INSTANCE_FLAGS (builtin_type->builtin_int8) |=
-    TYPE_INSTANCE_FLAG_NOTTEXT;
-  TYPE_INSTANCE_FLAGS (builtin_type->builtin_uint8) |=
-    TYPE_INSTANCE_FLAG_NOTTEXT;
+
+  builtin_type->builtin_int8->set_instance_flags
+    (builtin_type->builtin_int8->instance_flags ()
+     | TYPE_INSTANCE_FLAG_NOTTEXT);
+
+  builtin_type->builtin_uint8->set_instance_flags
+    (builtin_type->builtin_uint8->instance_flags ()
+     | TYPE_INSTANCE_FLAG_NOTTEXT);
 
   /* Wide character types.  */
   builtin_type->builtin_char16
@@ -5934,10 +6116,12 @@ objfile_type (struct objfile *objfile)
   objfile_type->nodebug_text_symbol
     = init_type (objfile, TYPE_CODE_FUNC, TARGET_CHAR_BIT,
                 "<text variable, no debug info>");
+
   objfile_type->nodebug_text_gnu_ifunc_symbol
     = init_type (objfile, TYPE_CODE_FUNC, TARGET_CHAR_BIT,
                 "<text gnu-indirect-function variable, no debug info>");
-  TYPE_GNU_IFUNC (objfile_type->nodebug_text_gnu_ifunc_symbol) = 1;
+  objfile_type->nodebug_text_gnu_ifunc_symbol->set_is_gnu_ifunc (true);
+
   objfile_type->nodebug_got_plt_symbol
     = init_pointer_type (objfile, gdbarch_addr_bit (gdbarch),
                         "<text from jump slot in .got.plt, no debug info>",
This page took 0.049408 seconds and 4 git commands to generate.