Run a few more binutils tests non-native
[deliverable/binutils-gdb.git] / gdb / gdbtypes.c
index 96b86104ad58d32c93ff7c3ddaf5aadc39bc6967..3d75c210d0bbb1066f8e44bc6a2e22201054f3d6 100644 (file)
@@ -858,6 +858,44 @@ allocate_stub_method (struct type *type)
   return mtype;
 }
 
+/* See gdbtypes.h.  */
+
+bool
+operator== (const dynamic_prop &l, const dynamic_prop &r)
+{
+  if (l.kind != r.kind)
+    return false;
+
+  switch (l.kind)
+    {
+    case PROP_UNDEFINED:
+      return true;
+    case PROP_CONST:
+      return l.data.const_val == r.data.const_val;
+    case PROP_ADDR_OFFSET:
+    case PROP_LOCEXPR:
+    case PROP_LOCLIST:
+      return l.data.baton == r.data.baton;
+    }
+
+  gdb_assert_not_reached ("unhandled dynamic_prop kind");
+}
+
+/* See gdbtypes.h.  */
+
+bool
+operator== (const range_bounds &l, const range_bounds &r)
+{
+#define FIELD_EQ(FIELD) (l.FIELD == r.FIELD)
+
+  return (FIELD_EQ (low)
+         && FIELD_EQ (high)
+         && FIELD_EQ (flag_upper_bound_is_count)
+         && FIELD_EQ (flag_bound_evaluated));
+
+#undef FIELD_EQ
+}
+
 /* Create a range type with a dynamic range from LOW_BOUND to
    HIGH_BOUND, inclusive.  See create_range_type for further details. */
 
@@ -986,7 +1024,7 @@ get_discrete_bounds (struct type *type, LONGEST *lowp, LONGEST *highp)
          *highp = -*lowp - 1;
          return 0;
        }
-      /* ... fall through for unsigned ints ...  */
+      /* fall through */
     case TYPE_CODE_CHAR:
       *lowp = 0;
       /* This round-about calculation is to avoid shifting by
@@ -1090,6 +1128,14 @@ discrete_position (struct type *type, LONGEST val, LONGEST *pos)
    Elements will be of type ELEMENT_TYPE, the indices will be of type
    RANGE_TYPE.
 
+   BYTE_STRIDE_PROP, when not NULL, provides the array's byte stride.
+   This byte stride property is added to the resulting array type
+   as a DYN_PROP_BYTE_STRIDE.  As a consequence, the BYTE_STRIDE_PROP
+   argument can only be used to create types that are objfile-owned
+   (see add_dyn_prop), meaning that either this function must be called
+   with an objfile-owned RESULT_TYPE, or an objfile-owned RANGE_TYPE.
+
+   BIT_STRIDE is taken into account only when BYTE_STRIDE_PROP is NULL.
    If BIT_STRIDE is not zero, build a packed array type whose element
    size is BIT_STRIDE.  Otherwise, ignore this parameter.
 
@@ -1101,14 +1147,27 @@ struct type *
 create_array_type_with_stride (struct type *result_type,
                               struct type *element_type,
                               struct type *range_type,
+                              struct dynamic_prop *byte_stride_prop,
                               unsigned int bit_stride)
 {
+  if (byte_stride_prop != NULL
+      && byte_stride_prop->kind == PROP_CONST)
+    {
+      /* The byte stride is actually not dynamic.  Pretend we were
+        called with bit_stride set instead of byte_stride_prop.
+        This will give us the same result type, while avoiding
+        the need to handle this as a special case.  */
+      bit_stride = byte_stride_prop->data.const_val * 8;
+      byte_stride_prop = NULL;
+    }
+
   if (result_type == NULL)
     result_type = alloc_type_copy (range_type);
 
   TYPE_CODE (result_type) = TYPE_CODE_ARRAY;
   TYPE_TARGET_TYPE (result_type) = element_type;
-  if (has_static_range (TYPE_RANGE_DATA (range_type))
+  if (byte_stride_prop == NULL
+      && has_static_range (TYPE_RANGE_DATA (range_type))
       && (!type_not_associated (result_type)
          && !type_not_allocated (result_type)))
     {
@@ -1144,7 +1203,9 @@ create_array_type_with_stride (struct type *result_type,
   TYPE_FIELDS (result_type) =
     (struct field *) TYPE_ZALLOC (result_type, sizeof (struct field));
   TYPE_INDEX_TYPE (result_type) = range_type;
-  if (bit_stride > 0)
+  if (byte_stride_prop != NULL)
+    add_dyn_prop (DYN_PROP_BYTE_STRIDE, *byte_stride_prop, result_type);
+  else if (bit_stride > 0)
     TYPE_FIELD_BITSIZE (result_type, 0) = bit_stride;
 
   /* TYPE_TARGET_STUB will take care of zero length arrays.  */
@@ -1163,17 +1224,22 @@ create_array_type (struct type *result_type,
                   struct type *range_type)
 {
   return create_array_type_with_stride (result_type, element_type,
-                                       range_type, 0);
+                                       range_type, NULL, 0);
 }
 
 struct type *
 lookup_array_range_type (struct type *element_type,
                         LONGEST low_bound, LONGEST high_bound)
 {
-  struct gdbarch *gdbarch = get_type_arch (element_type);
-  struct type *index_type = builtin_type (gdbarch)->builtin_int;
-  struct type *range_type
-    = create_static_range_type (NULL, index_type, low_bound, high_bound);
+  struct type *index_type;
+  struct type *range_type;
+
+  if (TYPE_OBJFILE_OWNED (element_type))
+    index_type = objfile_type (TYPE_OWNER (element_type).objfile)->builtin_int;
+  else
+    index_type = builtin_type (get_type_arch (element_type))->builtin_int;
+  range_type = create_static_range_type (NULL, index_type,
+                                        low_bound, high_bound);
 
   return create_array_type (NULL, element_type, range_type);
 }
@@ -1821,7 +1887,18 @@ get_vptr_fieldno (struct type *type, struct type **basetypep)
 static void
 stub_noname_complaint (void)
 {
-  complaint (&symfile_complaints, _("stub type has NULL name"));
+  complaint (_("stub type has NULL name"));
+}
+
+/* Return nonzero if TYPE has a DYN_PROP_BYTE_STRIDE dynamic property
+   attached to it, and that property has a non-constant value.  */
+
+static int
+array_type_has_dynamic_stride (struct type *type)
+{
+  struct dynamic_prop *prop = get_dyn_prop (DYN_PROP_BYTE_STRIDE, type);
+
+  return (prop != NULL && prop->kind != PROP_CONST);
 }
 
 /* Worker for is_dynamic_type.  */
@@ -1869,11 +1946,16 @@ is_dynamic_type_internal (struct type *type, int top_level)
       {
        gdb_assert (TYPE_NFIELDS (type) == 1);
 
-       /* The array is dynamic if either the bounds are dynamic,
-          or the elements it contains have a dynamic contents.  */
+       /* The array is dynamic if either the bounds are dynamic...  */
        if (is_dynamic_type_internal (TYPE_INDEX_TYPE (type), 0))
          return 1;
-       return is_dynamic_type_internal (TYPE_TARGET_TYPE (type), 0);
+       /* ... or the elements it contains have a dynamic contents...  */
+       if (is_dynamic_type_internal (TYPE_TARGET_TYPE (type), 0))
+         return 1;
+       /* ... or if it has a dynamic stride...  */
+       if (array_type_has_dynamic_stride (type))
+         return 1;
+       return 0;
       }
 
     case TYPE_CODE_STRUCT:
@@ -1969,6 +2051,7 @@ resolve_dynamic_array (struct type *type,
   struct type *range_type;
   struct type *ary_dim;
   struct dynamic_prop *prop;
+  unsigned int bit_stride = 0;
 
   gdb_assert (TYPE_CODE (type) == TYPE_CODE_ARRAY);
 
@@ -2000,8 +2083,31 @@ resolve_dynamic_array (struct type *type,
   else
     elt_type = TYPE_TARGET_TYPE (type);
 
-  return create_array_type_with_stride (type, elt_type, range_type,
-                                        TYPE_FIELD_BITSIZE (type, 0));
+  prop = get_dyn_prop (DYN_PROP_BYTE_STRIDE, type);
+  if (prop != NULL)
+    {
+      int prop_eval_ok
+       = dwarf2_evaluate_property (prop, NULL, addr_stack, &value);
+
+      if (prop_eval_ok)
+       {
+         remove_dyn_prop (DYN_PROP_BYTE_STRIDE, type);
+         bit_stride = (unsigned int) (value * 8);
+       }
+      else
+       {
+         /* Could be a bug in our code, but it could also happen
+            if the DWARF info is not correct.  Issue a warning,
+            and assume no byte/bit stride (leave bit_stride = 0).  */
+         warning (_("cannot determine array stride for type %s"),
+                  TYPE_NAME (type) ? TYPE_NAME (type) : "<no name>");
+       }
+    }
+  else
+    bit_stride = TYPE_FIELD_BITSIZE (type, 0);
+
+  return create_array_type_with_stride (type, elt_type, range_type, NULL,
+                                        bit_stride);
 }
 
 /* Resolve dynamic bounds of members of the union TYPE to static
@@ -2241,13 +2347,14 @@ get_dyn_prop (enum dynamic_prop_node_kind prop_kind, const struct type *type)
 
 void
 add_dyn_prop (enum dynamic_prop_node_kind prop_kind, struct dynamic_prop prop,
-              struct type *type, struct objfile *objfile)
+              struct type *type)
 {
   struct dynamic_prop_list *temp;
 
   gdb_assert (TYPE_OBJFILE_OWNED (type));
 
-  temp = XOBNEW (&objfile->objfile_obstack, struct dynamic_prop_list);
+  temp = XOBNEW (&TYPE_OBJFILE (type)->objfile_obstack,
+                struct dynamic_prop_list);
   temp->prop_kind = prop_kind;
   temp->prop = prop;
   temp->next = TYPE_DYN_PROP_LIST (type);
@@ -2906,6 +3013,128 @@ init_pointer_type (struct objfile *objfile,
   return t;
 }
 
+/* See gdbtypes.h.  */
+
+unsigned
+type_raw_align (struct type *type)
+{
+  if (type->align_log2 != 0)
+    return 1 << (type->align_log2 - 1);
+  return 0;
+}
+
+/* See gdbtypes.h.  */
+
+unsigned
+type_align (struct type *type)
+{
+  unsigned raw_align = type_raw_align (type);
+  if (raw_align != 0)
+    return raw_align;
+
+  ULONGEST align = 0;
+  switch (TYPE_CODE (type))
+    {
+    case TYPE_CODE_PTR:
+    case TYPE_CODE_FUNC:
+    case TYPE_CODE_FLAGS:
+    case TYPE_CODE_INT:
+    case TYPE_CODE_FLT:
+    case TYPE_CODE_ENUM:
+    case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
+    case TYPE_CODE_CHAR:
+    case TYPE_CODE_BOOL:
+    case TYPE_CODE_DECFLOAT:
+      {
+       struct gdbarch *arch = get_type_arch (type);
+       align = gdbarch_type_align (arch, type);
+      }
+      break;
+
+    case TYPE_CODE_ARRAY:
+    case TYPE_CODE_COMPLEX:
+    case TYPE_CODE_TYPEDEF:
+      align = type_align (TYPE_TARGET_TYPE (type));
+      break;
+
+    case TYPE_CODE_STRUCT:
+    case TYPE_CODE_UNION:
+      {
+       if (TYPE_NFIELDS (type) == 0)
+         {
+           /* An empty struct has alignment 1.  */
+           align = 1;
+           break;
+         }
+       for (unsigned i = 0; i < TYPE_NFIELDS (type); ++i)
+         {
+           ULONGEST f_align = type_align (TYPE_FIELD_TYPE (type, i));
+           if (f_align == 0)
+             {
+               /* Don't pretend we know something we don't.  */
+               align = 0;
+               break;
+             }
+           if (f_align > align)
+             align = f_align;
+         }
+      }
+      break;
+
+    case TYPE_CODE_SET:
+    case TYPE_CODE_RANGE:
+    case TYPE_CODE_STRING:
+      /* Not sure what to do here, and these can't appear in C or C++
+        anyway.  */
+      break;
+
+    case TYPE_CODE_METHODPTR:
+    case TYPE_CODE_MEMBERPTR:
+      align = TYPE_LENGTH (type);
+      break;
+
+    case TYPE_CODE_VOID:
+      align = 1;
+      break;
+
+    case TYPE_CODE_ERROR:
+    case TYPE_CODE_METHOD:
+    default:
+      break;
+    }
+
+  if ((align & (align - 1)) != 0)
+    {
+      /* Not a power of 2, so pass.  */
+      align = 0;
+    }
+
+  return align;
+}
+
+/* See gdbtypes.h.  */
+
+bool
+set_type_align (struct type *type, ULONGEST align)
+{
+  /* Must be a power of 2.  Zero is ok.  */
+  gdb_assert ((align & (align - 1)) == 0);
+
+  unsigned result = 0;
+  while (align != 0)
+    {
+      ++result;
+      align >>= 1;
+    }
+
+  if (result >= (1 << TYPE_ALIGN_BITS))
+    return false;
+
+  type->align_log2 = result;
+  return true;
+}
+
 \f
 /* Queries on types.  */
 
@@ -3322,10 +3551,10 @@ integer_types_same_name_p (const char *first, const char *second)
   return 1;
 }
 
-/* Compares type A to type B returns 1 if the represent the same type
-   0 otherwise.  */
+/* Compares type A to type B.  Returns true if they represent the same
+   type, false otherwise.  */
 
-int
+bool
 types_equal (struct type *a, struct type *b)
 {
   /* Identical type pointers.  */
@@ -3333,7 +3562,7 @@ types_equal (struct type *a, struct type *b)
      and a.  The reason is that builtin types are different from
      the same ones constructed from the object.  */
   if (a == b)
-    return 1;
+    return true;
 
   /* Resolve typedefs */
   if (TYPE_CODE (a) == TYPE_CODE_TYPEDEF)
@@ -3344,7 +3573,7 @@ types_equal (struct type *a, struct type *b)
   /* If after resolving typedefs a and b are not of the same type
      code then they are not equal.  */
   if (TYPE_CODE (a) != TYPE_CODE (b))
-    return 0;
+    return false;
 
   /* If a and b are both pointers types or both reference types then
      they are equal of the same type iff the objects they refer to are
@@ -3361,11 +3590,11 @@ types_equal (struct type *a, struct type *b)
 
   if (TYPE_NAME (a) && TYPE_NAME (b)
       && strcmp (TYPE_NAME (a), TYPE_NAME (b)) == 0)
-    return 1;
+    return true;
 
   /* Check if identical after resolving typedefs.  */
   if (a == b)
-    return 1;
+    return true;
 
   /* Two function types are equal if their argument and return types
      are equal.  */
@@ -3374,60 +3603,60 @@ types_equal (struct type *a, struct type *b)
       int i;
 
       if (TYPE_NFIELDS (a) != TYPE_NFIELDS (b))
-       return 0;
+       return false;
       
       if (!types_equal (TYPE_TARGET_TYPE (a), TYPE_TARGET_TYPE (b)))
-       return 0;
+       return false;
 
       for (i = 0; i < TYPE_NFIELDS (a); ++i)
        if (!types_equal (TYPE_FIELD_TYPE (a, i), TYPE_FIELD_TYPE (b, i)))
-         return 0;
+         return false;
 
-      return 1;
+      return true;
     }
 
-  return 0;
+  return false;
 }
 \f
 /* Deep comparison of types.  */
 
 /* An entry in the type-equality bcache.  */
 
-typedef struct type_equality_entry
+struct type_equality_entry
 {
-  struct type *type1, *type2;
-} type_equality_entry_d;
+  type_equality_entry (struct type *t1, struct type *t2)
+    : type1 (t1),
+      type2 (t2)
+  {
+  }
 
-DEF_VEC_O (type_equality_entry_d);
+  struct type *type1, *type2;
+};
 
-/* A helper function to compare two strings.  Returns 1 if they are
-   the same, 0 otherwise.  Handles NULLs properly.  */
+/* A helper function to compare two strings.  Returns true if they are
+   the same, false otherwise.  Handles NULLs properly.  */
 
-static int
+static bool
 compare_maybe_null_strings (const char *s, const char *t)
 {
-  if (s == NULL && t != NULL)
-    return 0;
-  else if (s != NULL && t == NULL)
-    return 0;
-  else if (s == NULL && t== NULL)
-    return 1;
+  if (s == NULL || t == NULL)
+    return s == t;
   return strcmp (s, t) == 0;
 }
 
 /* A helper function for check_types_worklist that checks two types for
-   "deep" equality.  Returns non-zero if the types are considered the
-   same, zero otherwise.  */
+   "deep" equality.  Returns true if the types are considered the
+   same, false otherwise.  */
 
-static int
+static bool
 check_types_equal (struct type *type1, struct type *type2,
-                  VEC (type_equality_entry_d) **worklist)
+                  std::vector<type_equality_entry> *worklist)
 {
   type1 = check_typedef (type1);
   type2 = check_typedef (type2);
 
   if (type1 == type2)
-    return 1;
+    return true;
 
   if (TYPE_CODE (type1) != TYPE_CODE (type2)
       || TYPE_LENGTH (type1) != TYPE_LENGTH (type2)
@@ -3438,19 +3667,18 @@ check_types_equal (struct type *type1, struct type *type2,
       || TYPE_NOTTEXT (type1) != TYPE_NOTTEXT (type2)
       || TYPE_INSTANCE_FLAGS (type1) != TYPE_INSTANCE_FLAGS (type2)
       || TYPE_NFIELDS (type1) != TYPE_NFIELDS (type2))
-    return 0;
+    return false;
 
   if (!compare_maybe_null_strings (TYPE_TAG_NAME (type1),
                                   TYPE_TAG_NAME (type2)))
-    return 0;
+    return false;
   if (!compare_maybe_null_strings (TYPE_NAME (type1), TYPE_NAME (type2)))
-    return 0;
+    return false;
 
   if (TYPE_CODE (type1) == TYPE_CODE_RANGE)
     {
-      if (memcmp (TYPE_RANGE_DATA (type1), TYPE_RANGE_DATA (type2),
-                 sizeof (*TYPE_RANGE_DATA (type1))) != 0)
-       return 0;
+      if (*TYPE_RANGE_DATA (type1) != *TYPE_RANGE_DATA (type2))
+       return false;
     }
   else
     {
@@ -3460,34 +3688,33 @@ check_types_equal (struct type *type1, struct type *type2,
        {
          const struct field *field1 = &TYPE_FIELD (type1, i);
          const struct field *field2 = &TYPE_FIELD (type2, i);
-         struct type_equality_entry entry;
 
          if (FIELD_ARTIFICIAL (*field1) != FIELD_ARTIFICIAL (*field2)
              || FIELD_BITSIZE (*field1) != FIELD_BITSIZE (*field2)
              || FIELD_LOC_KIND (*field1) != FIELD_LOC_KIND (*field2))
-           return 0;
+           return false;
          if (!compare_maybe_null_strings (FIELD_NAME (*field1),
                                           FIELD_NAME (*field2)))
-           return 0;
+           return false;
          switch (FIELD_LOC_KIND (*field1))
            {
            case FIELD_LOC_KIND_BITPOS:
              if (FIELD_BITPOS (*field1) != FIELD_BITPOS (*field2))
-               return 0;
+               return false;
              break;
            case FIELD_LOC_KIND_ENUMVAL:
              if (FIELD_ENUMVAL (*field1) != FIELD_ENUMVAL (*field2))
-               return 0;
+               return false;
              break;
            case FIELD_LOC_KIND_PHYSADDR:
              if (FIELD_STATIC_PHYSADDR (*field1)
                  != FIELD_STATIC_PHYSADDR (*field2))
-               return 0;
+               return false;
              break;
            case FIELD_LOC_KIND_PHYSNAME:
              if (!compare_maybe_null_strings (FIELD_STATIC_PHYSNAME (*field1),
                                               FIELD_STATIC_PHYSNAME (*field2)))
-               return 0;
+               return false;
              break;
            case FIELD_LOC_KIND_DWARF_BLOCK:
              {
@@ -3498,7 +3725,7 @@ check_types_equal (struct type *type1, struct type *type2,
                if (block1->per_cu != block2->per_cu
                    || block1->size != block2->size
                    || memcmp (block1->data, block2->data, block1->size) != 0)
-                 return 0;
+                 return false;
              }
              break;
            default:
@@ -3507,43 +3734,37 @@ check_types_equal (struct type *type1, struct type *type2,
                              FIELD_LOC_KIND (*field1));
            }
 
-         entry.type1 = FIELD_TYPE (*field1);
-         entry.type2 = FIELD_TYPE (*field2);
-         VEC_safe_push (type_equality_entry_d, *worklist, &entry);
+         worklist->emplace_back (FIELD_TYPE (*field1), FIELD_TYPE (*field2));
        }
     }
 
   if (TYPE_TARGET_TYPE (type1) != NULL)
     {
-      struct type_equality_entry entry;
-
       if (TYPE_TARGET_TYPE (type2) == NULL)
-       return 0;
+       return false;
 
-      entry.type1 = TYPE_TARGET_TYPE (type1);
-      entry.type2 = TYPE_TARGET_TYPE (type2);
-      VEC_safe_push (type_equality_entry_d, *worklist, &entry);
+      worklist->emplace_back (TYPE_TARGET_TYPE (type1),
+                             TYPE_TARGET_TYPE (type2));
     }
   else if (TYPE_TARGET_TYPE (type2) != NULL)
-    return 0;
+    return false;
 
-  return 1;
+  return true;
 }
 
-/* Check types on a worklist for equality.  Returns zero if any pair
-   is not equal, non-zero if they are all considered equal.  */
+/* Check types on a worklist for equality.  Returns false if any pair
+   is not equal, true if they are all considered equal.  */
 
-static int
-check_types_worklist (VEC (type_equality_entry_d) **worklist,
+static bool
+check_types_worklist (std::vector<type_equality_entry> *worklist,
                      struct bcache *cache)
 {
-  while (!VEC_empty (type_equality_entry_d, *worklist))
+  while (!worklist->empty ())
     {
-      struct type_equality_entry entry;
       int added;
 
-      entry = *VEC_last (type_equality_entry_d, *worklist);
-      VEC_pop (type_equality_entry_d, *worklist);
+      struct type_equality_entry entry = std::move (worklist->back ());
+      worklist->pop_back ();
 
       /* If the type pair has already been visited, we know it is
         ok.  */
@@ -3551,36 +3772,33 @@ check_types_worklist (VEC (type_equality_entry_d) **worklist,
       if (!added)
        continue;
 
-      if (check_types_equal (entry.type1, entry.type2, worklist) == 0)
-       return 0;
+      if (!check_types_equal (entry.type1, entry.type2, worklist))
+       return false;
     }
 
-  return 1;
+  return true;
 }
 
-/* Return non-zero if types TYPE1 and TYPE2 are equal, as determined by a
-   "deep comparison".  Otherwise return zero.  */
+/* Return true if types TYPE1 and TYPE2 are equal, as determined by a
+   "deep comparison".  Otherwise return false.  */
 
-int
+bool
 types_deeply_equal (struct type *type1, struct type *type2)
 {
   struct gdb_exception except = exception_none;
-  int result = 0;
+  bool result = false;
   struct bcache *cache;
-  VEC (type_equality_entry_d) *worklist = NULL;
-  struct type_equality_entry entry;
+  std::vector<type_equality_entry> worklist;
 
   gdb_assert (type1 != NULL && type2 != NULL);
 
   /* Early exit for the simple case.  */
   if (type1 == type2)
-    return 1;
+    return true;
 
   cache = bcache_xmalloc (NULL, NULL);
 
-  entry.type1 = type1;
-  entry.type2 = type2;
-  VEC_safe_push (type_equality_entry_d, worklist, &entry);
+  worklist.emplace_back (type1, type2);
 
   /* check_types_worklist calls several nested helper functions, some
      of which can raise a GDB exception, so we just check and rethrow
@@ -3597,7 +3815,6 @@ types_deeply_equal (struct type *type1, struct type *type2)
   END_CATCH
 
   bcache_xfree (cache);
-  VEC_free (type_equality_entry_d, worklist);
 
   /* Rethrow if there was a problem.  */
   if (except.reason < 0)
@@ -3917,7 +4134,7 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value)
            return INTEGER_CONVERSION_BADNESS;
          else if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm))
            return INTEGER_PROMOTION_BADNESS;
-         /* >>> !! else fall through !! <<< */
+         /* fall through */
        case TYPE_CODE_CHAR:
          /* Deal with signed, unsigned, and plain chars for C++ and
             with int cases falling through from previous case.  */
@@ -4023,7 +4240,7 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value)
          rank.subrank = distance_to_ancestor (parm, arg, 0);
          if (rank.subrank >= 0)
            return sum_ranks (BASE_CONVERSION_BADNESS, rank);
-         /* else fall through */
+         /* fall through */
        default:
          return INCOMPATIBLE_TYPE_BADNESS;
        }
@@ -4593,9 +4810,13 @@ recursive_dump_type (struct type *type, int spaces)
 /* Trivial helpers for the libiberty hash table, for mapping one
    type to another.  */
 
-struct type_pair
+struct type_pair : public allocate_on_obstack
 {
-  struct type *old, *newobj;
+  type_pair (struct type *old_, struct type *newobj_)
+    : old (old_), newobj (newobj_)
+  {}
+
+  struct type * const old, * const newobj;
 };
 
 static hashval_t
@@ -4663,7 +4884,6 @@ copy_type_recursive (struct objfile *objfile,
                     struct type *type,
                     htab_t copied_types)
 {
-  struct type_pair *stored, pair;
   void **slot;
   struct type *new_type;
 
@@ -4674,7 +4894,8 @@ copy_type_recursive (struct objfile *objfile,
      if it did, the type might disappear unexpectedly.  */
   gdb_assert (TYPE_OBJFILE (type) == objfile);
 
-  pair.old = type;
+  struct type_pair pair (type, nullptr);
+
   slot = htab_find_slot (copied_types, &pair, INSERT);
   if (*slot != NULL)
     return ((struct type_pair *) *slot)->newobj;
@@ -4683,9 +4904,9 @@ copy_type_recursive (struct objfile *objfile,
 
   /* We must add the new type to the hash table immediately, in case
      we encounter this type again during a recursive call below.  */
-  stored = XOBNEW (&objfile->objfile_obstack, struct type_pair);
-  stored->old = type;
-  stored->newobj = new_type;
+  struct type_pair *stored
+    = new (&objfile->objfile_obstack) struct type_pair (type, new_type);
+
   *slot = stored;
 
   /* Copy the common fields of types.  For the main type, we simply
@@ -5333,10 +5554,6 @@ objfile_type (struct objfile *objfile)
   objfile_type->nodebug_text_gnu_ifunc_symbol
     = init_type (objfile, TYPE_CODE_FUNC, TARGET_CHAR_BIT,
                 "<text gnu-indirect-function variable, no debug info>");
-  /* Ifunc resolvers return a function address.  */
-  TYPE_TARGET_TYPE (objfile_type->nodebug_text_gnu_ifunc_symbol)
-    = init_integer_type (objfile, gdbarch_addr_bit (gdbarch), 1,
-                        "__IFUNC_RESOLVER_RET");
   TYPE_GNU_IFUNC (objfile_type->nodebug_text_gnu_ifunc_symbol) = 1;
   objfile_type->nodebug_got_plt_symbol
     = init_pointer_type (objfile, gdbarch_addr_bit (gdbarch),
This page took 0.0381010000000001 seconds and 4 git commands to generate.