]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/gdbtypes.c
Automatic date update in version.in
[thirdparty/binutils-gdb.git] / gdb / gdbtypes.c
index 7ba62df474eb0813bb821b588013970b9ff25d13..d89df9f7409a003cd04f059bf4ab84399d7b74fd 100644 (file)
@@ -1,6 +1,6 @@
 /* Support routines for manipulating internal types for GDB.
 
-   Copyright (C) 1992-2018 Free Software Foundation, Inc.
+   Copyright (C) 1992-2020 Free Software Foundation, Inc.
 
    Contributed by Cygnus Support, using pieces from other GDB modules.
 
@@ -36,7 +36,7 @@
 #include "hashtab.h"
 #include "cp-support.h"
 #include "bcache.h"
-#include "dwarf2loc.h"
+#include "dwarf2/loc.h"
 #include "gdbcore.h"
 #include "floatformat.h"
 
@@ -60,6 +60,7 @@ const struct rank VOID_PTR_CONVERSION_BADNESS = {2,0};
 const struct rank BOOL_CONVERSION_BADNESS = {3,0};
 const struct rank BASE_CONVERSION_BADNESS = {2,0};
 const struct rank REFERENCE_CONVERSION_BADNESS = {2,0};
+const struct rank REFERENCE_SEE_THROUGH_BADNESS = {0,1};
 const struct rank NULL_POINTER_CONVERSION_BADNESS = {2,0};
 const struct rank NS_POINTER_CONVERSION_BADNESS = {10,0};
 const struct rank NS_INTEGER_POINTER_CONVERSION_BADNESS = {3,0};
@@ -116,16 +117,15 @@ const struct floatformat *floatformats_ibm_long_double[BFD_ENDIAN_UNKNOWN] = {
 
 /* Should opaque types be resolved?  */
 
-static int opaque_type_resolution = 1;
+static bool opaque_type_resolution = true;
 
-/* A flag to enable printing of debugging information of C++
-   overloading.  */
+/* See gdbtypes.h.  */
 
 unsigned int overload_debug = 0;
 
 /* A flag to enable strict type checking.  */
 
-static int strict_type_checking = 1;
+static bool strict_type_checking = true;
 
 /* A function to show whether opaque types are resolved.  */
 
@@ -233,10 +233,19 @@ alloc_type_copy (const struct type *type)
 struct gdbarch *
 get_type_arch (const struct type *type)
 {
+  struct gdbarch *arch;
+
   if (TYPE_OBJFILE_OWNED (type))
-    return get_objfile_arch (TYPE_OWNER (type).objfile);
+    arch = get_objfile_arch (TYPE_OWNER (type).objfile);
   else
-    return TYPE_OWNER (type).gdbarch;
+    arch = TYPE_OWNER (type).gdbarch;
+
+  /* The ARCH can be NULL if TYPE is associated with neither an objfile nor
+     a gdbarch, however, this is very rare, and even then, in most cases
+     that get_type_arch is called, we assume that a non-NULL value is
+     returned.  */
+  gdb_assert (arch != NULL);
+  return arch;
 }
 
 /* See gdbtypes.h.  */
@@ -277,7 +286,7 @@ alloc_type_instance (struct type *oldtype)
   /* Allocate the structure.  */
 
   if (! TYPE_OBJFILE_OWNED (oldtype))
-    type = XCNEW (struct type);
+    type = GDBARCH_OBSTACK_ZALLOC (get_type_arch (oldtype), struct type);
   else
     type = OBSTACK_ZALLOC (&TYPE_OBJFILE (oldtype)->objfile_obstack,
                           struct type);
@@ -565,7 +574,8 @@ lookup_function_type_with_arguments (struct type *type,
    return the integer flag defined in gdbtypes.h.  */
 
 int
-address_space_name_to_int (struct gdbarch *gdbarch, char *space_identifier)
+address_space_name_to_int (struct gdbarch *gdbarch,
+                          const char *space_identifier)
 {
   int type_flags;
 
@@ -858,14 +868,59 @@ 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)
+         && FIELD_EQ (bias));
+
+#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. */
 
 struct type *
 create_range_type (struct type *result_type, struct type *index_type,
                   const struct dynamic_prop *low_bound,
-                  const struct dynamic_prop *high_bound)
+                  const struct dynamic_prop *high_bound,
+                  LONGEST bias)
 {
+  /* The INDEX_TYPE should be a type capable of holding the upper and lower
+     bounds, as such a zero sized, or void type makes no sense.  */
+  gdb_assert (TYPE_CODE (index_type) != TYPE_CODE_VOID);
+  gdb_assert (TYPE_LENGTH (index_type) > 0);
+
   if (result_type == NULL)
     result_type = alloc_type_copy (index_type);
   TYPE_CODE (result_type) = TYPE_CODE_RANGE;
@@ -879,6 +934,11 @@ create_range_type (struct type *result_type, struct type *index_type,
     TYPE_ZALLOC (result_type, sizeof (struct range_bounds));
   TYPE_RANGE_DATA (result_type)->low = *low_bound;
   TYPE_RANGE_DATA (result_type)->high = *high_bound;
+  TYPE_RANGE_DATA (result_type)->bias = bias;
+
+  /* Initialize the stride to be a constant, the value will already be zero
+     thanks to the use of TYPE_ZALLOC above.  */
+  TYPE_RANGE_DATA (result_type)->stride.kind = PROP_CONST;
 
   if (low_bound->kind == PROP_CONST && low_bound->data.const_val >= 0)
     TYPE_UNSIGNED (result_type) = 1;
@@ -890,9 +950,35 @@ create_range_type (struct type *result_type, struct type *index_type,
   if (high_bound->kind == PROP_CONST && high_bound->data.const_val < 0)
     TYPE_UNSIGNED (result_type) = 0;
 
+  TYPE_ENDIANITY_NOT_DEFAULT (result_type)
+    = TYPE_ENDIANITY_NOT_DEFAULT (index_type);
+
+  return result_type;
+}
+
+/* See gdbtypes.h.  */
+
+struct type *
+create_range_type_with_stride (struct type *result_type,
+                              struct type *index_type,
+                              const struct dynamic_prop *low_bound,
+                              const struct dynamic_prop *high_bound,
+                              LONGEST bias,
+                              const struct dynamic_prop *stride,
+                              bool byte_stride_p)
+{
+  result_type = create_range_type (result_type, index_type, low_bound,
+                                  high_bound, bias);
+
+  gdb_assert (stride != nullptr);
+  TYPE_RANGE_DATA (result_type)->stride = *stride;
+  TYPE_RANGE_DATA (result_type)->flag_is_byte_stride = byte_stride_p;
+
   return result_type;
 }
 
+
+
 /* Create a range type using either a blank type supplied in
    RESULT_TYPE, or creating a new type, inheriting the objfile from
    INDEX_TYPE.
@@ -915,7 +1001,7 @@ create_static_range_type (struct type *result_type, struct type *index_type,
   high.kind = PROP_CONST;
   high.data.const_val = high_bound;
 
-  result_type = create_range_type (result_type, index_type, &low, &high);
+  result_type = create_range_type (result_type, index_type, &low, &high, 0);
 
   return result_type;
 }
@@ -923,11 +1009,14 @@ create_static_range_type (struct type *result_type, struct type *index_type,
 /* Predicate tests whether BOUNDS are static.  Returns 1 if all bounds values
    are static, otherwise returns 0.  */
 
-static int
+static bool
 has_static_range (const struct range_bounds *bounds)
 {
+  /* If the range doesn't have a defined stride then its stride field will
+     be initialized to the constant 0.  */
   return (bounds->low.kind == PROP_CONST
-         && bounds->high.kind == PROP_CONST);
+         && bounds->high.kind == PROP_CONST
+         && bounds->stride.kind == PROP_CONST);
 }
 
 
@@ -986,7 +1075,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
@@ -1134,6 +1223,15 @@ create_array_type_with_stride (struct type *result_type,
          && !type_not_allocated (result_type)))
     {
       LONGEST low_bound, high_bound;
+      int stride;
+
+      /* If the array itself doesn't provide a stride value then take
+        whatever stride the range provides.  Don't update BIT_STRIDE as
+        we don't want to place the stride value from the range into this
+        arrays bit size field.  */
+      stride = bit_stride;
+      if (stride == 0)
+       stride = TYPE_BIT_STRIDE (range_type);
 
       if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
        low_bound = high_bound = 0;
@@ -1143,9 +1241,18 @@ create_array_type_with_stride (struct type *result_type,
         In such cases, the array length should be zero.  */
       if (high_bound < low_bound)
        TYPE_LENGTH (result_type) = 0;
-      else if (bit_stride > 0)
-       TYPE_LENGTH (result_type) =
-         (bit_stride * (high_bound - low_bound + 1) + 7) / 8;
+      else if (stride != 0)
+       {
+         /* Ensure that the type length is always positive, even in the
+            case where (for example in Fortran) we have a negative
+            stride.  It is possible to have a single element array with a
+            negative stride in Fortran (this doesn't mean anything
+            special, it's still just a single element array) so do
+            consider that case when touching this code.  */
+         LONGEST element_count = std::abs (high_bound - low_bound + 1);
+         TYPE_LENGTH (result_type)
+           = ((std::abs (stride) * element_count) + 7) / 8;
+       }
       else
        TYPE_LENGTH (result_type) =
          TYPE_LENGTH (element_type) * (high_bound - low_bound + 1);
@@ -1166,8 +1273,7 @@ create_array_type_with_stride (struct type *result_type,
     (struct field *) TYPE_ZALLOC (result_type, sizeof (struct field));
   TYPE_INDEX_TYPE (result_type) = range_type;
   if (byte_stride_prop != NULL)
-    add_dyn_prop (DYN_PROP_BYTE_STRIDE, *byte_stride_prop, result_type,
-                 TYPE_OBJFILE (result_type));
+    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;
 
@@ -1194,10 +1300,15 @@ 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);
 }
@@ -1421,22 +1532,7 @@ smash_to_method_type (struct type *type, struct type *self_type,
   TYPE_LENGTH (type) = 1;      /* In practice, this is never needed.  */
 }
 
-/* Return a typename for a struct/union/enum type without "struct ",
-   "union ", or "enum ".  If the type has a NULL name, return NULL.  */
-
-const char *
-type_name_no_tag (const struct type *type)
-{
-  if (TYPE_TAG_NAME (type) != NULL)
-    return TYPE_TAG_NAME (type);
-
-  /* Is there code which expects this to return the name if there is
-     no tag name?  My guess is that this is mainly used for C++ in
-     cases where the two will always be the same.  */
-  return TYPE_NAME (type);
-}
-
-/* A wrapper of type_name_no_tag which calls error if the type is anonymous.
+/* A wrapper of TYPE_NAME which calls error if the type is anonymous.
    Since GCC PR debug/47510 DWARF provides associated information to detect the
    anonymous class linkage name from its typedef.
 
@@ -1444,7 +1540,7 @@ type_name_no_tag (const struct type *type)
    apply it itself.  */
 
 const char *
-type_name_no_tag_or_error (struct type *type)
+type_name_or_error (struct type *type)
 {
   struct type *saved_type = type;
   const char *name;
@@ -1452,11 +1548,11 @@ type_name_no_tag_or_error (struct type *type)
 
   type = check_typedef (type);
 
-  name = type_name_no_tag (type);
+  name = TYPE_NAME (type);
   if (name != NULL)
     return name;
 
-  name = type_name_no_tag (saved_type);
+  name = TYPE_NAME (saved_type);
   objfile = TYPE_OBJFILE (saved_type);
   error (_("Invalid anonymous type %s [in module %s], GCC PR debug/47510 bug?"),
         name ? name : "<anonymous>",
@@ -1469,7 +1565,7 @@ type_name_no_tag_or_error (struct type *type)
 
 struct type *
 lookup_typename (const struct language_defn *language,
-                struct gdbarch *gdbarch, const char *name,
+                const char *name,
                 const struct block *block, int noerr)
 {
   struct symbol *sym;
@@ -1486,29 +1582,28 @@ lookup_typename (const struct language_defn *language,
 
 struct type *
 lookup_unsigned_typename (const struct language_defn *language,
-                         struct gdbarch *gdbarch, const char *name)
+                         const char *name)
 {
   char *uns = (char *) alloca (strlen (name) + 10);
 
   strcpy (uns, "unsigned ");
   strcpy (uns + 9, name);
-  return lookup_typename (language, gdbarch, uns, (struct block *) NULL, 0);
+  return lookup_typename (language, uns, NULL, 0);
 }
 
 struct type *
-lookup_signed_typename (const struct language_defn *language,
-                       struct gdbarch *gdbarch, const char *name)
+lookup_signed_typename (const struct language_defn *language, const char *name)
 {
   struct type *t;
   char *uns = (char *) alloca (strlen (name) + 8);
 
   strcpy (uns, "signed ");
   strcpy (uns + 7, name);
-  t = lookup_typename (language, gdbarch, uns, (struct block *) NULL, 1);
+  t = lookup_typename (language, uns, NULL, 1);
   /* If we don't find "signed FOO" just try again with plain "FOO".  */
   if (t != NULL)
     return t;
-  return lookup_typename (language, gdbarch, name, (struct block *) NULL, 0);
+  return lookup_typename (language, name, NULL, 0);
 }
 
 /* Lookup a structure type named "struct NAME",
@@ -1582,7 +1677,7 @@ lookup_enum (const char *name, const struct block *block)
    visible in lexical block BLOCK.  */
 
 struct type *
-lookup_template_type (char *name, struct type *type, 
+lookup_template_type (const char *name, struct type *type, 
                      const struct block *block)
 {
   struct symbol *sym;
@@ -1608,20 +1703,10 @@ lookup_template_type (char *name, struct type *type,
   return (SYMBOL_TYPE (sym));
 }
 
-/* Given a type TYPE, lookup the type of the component of type named
-   NAME.
-
-   TYPE can be either a struct or union, or a pointer or reference to
-   a struct or union.  If it is a pointer or reference, its target
-   type is automatically used.  Thus '.' and '->' are interchangable,
-   as specified for the definitions of the expression element types
-   STRUCTOP_STRUCT and STRUCTOP_PTR.
-
-   If NOERR is nonzero, return zero if NAME is not suitably defined.
-   If NAME is the name of a baseclass type, return that type.  */
+/* See gdbtypes.h.  */
 
-struct type *
-lookup_struct_elt_type (struct type *type, const char *name, int noerr)
+struct_elt
+lookup_struct_elt (struct type *type, const char *name, int noerr)
 {
   int i;
 
@@ -1642,59 +1727,53 @@ lookup_struct_elt_type (struct type *type, const char *name, int noerr)
             type_name.c_str ());
     }
 
-#if 0
-  /* FIXME: This change put in by Michael seems incorrect for the case
-     where the structure tag name is the same as the member name.
-     I.e. when doing "ptype bell->bar" for "struct foo { int bar; int
-     foo; } bell;" Disabled by fnf.  */
-  {
-    char *type_name;
-
-    type_name = type_name_no_tag (type);
-    if (type_name != NULL && strcmp (type_name, name) == 0)
-      return type;
-  }
-#endif
-
   for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--)
     {
       const char *t_field_name = TYPE_FIELD_NAME (type, i);
 
       if (t_field_name && (strcmp_iw (t_field_name, name) == 0))
        {
-         return TYPE_FIELD_TYPE (type, i);
+         return {&TYPE_FIELD (type, i), TYPE_FIELD_BITPOS (type, i)};
        }
      else if (!t_field_name || *t_field_name == '\0')
        {
-         struct type *subtype 
-           = lookup_struct_elt_type (TYPE_FIELD_TYPE (type, i), name, 1);
-
-         if (subtype != NULL)
-           return subtype;
+         struct_elt elt
+           = lookup_struct_elt (TYPE_FIELD_TYPE (type, i), name, 1);
+         if (elt.field != NULL)
+           {
+             elt.offset += TYPE_FIELD_BITPOS (type, i);
+             return elt;
+           }
        }
     }
 
   /* OK, it's not in this class.  Recursively check the baseclasses.  */
   for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
     {
-      struct type *t;
-
-      t = lookup_struct_elt_type (TYPE_BASECLASS (type, i), name, 1);
-      if (t != NULL)
-       {
-         return t;
-       }
+      struct_elt elt = lookup_struct_elt (TYPE_BASECLASS (type, i), name, 1);
+      if (elt.field != NULL)
+       return elt;
     }
 
   if (noerr)
-    {
-      return NULL;
-    }
+    return {nullptr, 0};
 
   std::string type_name = type_to_string (type);
   error (_("Type %s has no component named %s."), type_name.c_str (), name);
 }
 
+/* See gdbtypes.h.  */
+
+struct type *
+lookup_struct_elt_type (struct type *type, const char *name, int noerr)
+{
+  struct_elt elt = lookup_struct_elt (type, name, noerr);
+  if (elt.field != NULL)
+    return FIELD_TYPE (*elt.field);
+  else
+    return NULL;
+}
+
 /* Store in *MAX the largest number representable by unsigned integer type
    TYPE.  */
 
@@ -1845,7 +1924,7 @@ 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
@@ -1900,6 +1979,9 @@ is_dynamic_type_internal (struct type *type, int top_level)
                || is_dynamic_type_internal (TYPE_TARGET_TYPE (type), 0));
       }
 
+    case TYPE_CODE_STRING:
+      /* Strings are very much like an array of characters, and can be
+        treated as one here.  */
     case TYPE_CODE_ARRAY:
       {
        gdb_assert (TYPE_NFIELDS (type) == 1);
@@ -1954,7 +2036,7 @@ resolve_dynamic_range (struct type *dyn_range_type,
   CORE_ADDR value;
   struct type *static_range_type, *static_target_type;
   const struct dynamic_prop *prop;
-  struct dynamic_prop low_bound, high_bound;
+  struct dynamic_prop low_bound, high_bound, stride;
 
   gdb_assert (TYPE_CODE (dyn_range_type) == TYPE_CODE_RANGE);
 
@@ -1986,23 +2068,48 @@ resolve_dynamic_range (struct type *dyn_range_type,
       high_bound.data.const_val = 0;
     }
 
+  bool byte_stride_p = TYPE_RANGE_DATA (dyn_range_type)->flag_is_byte_stride;
+  prop = &TYPE_RANGE_DATA (dyn_range_type)->stride;
+  if (dwarf2_evaluate_property (prop, NULL, addr_stack, &value))
+    {
+      stride.kind = PROP_CONST;
+      stride.data.const_val = value;
+
+      /* If we have a bit stride that is not an exact number of bytes then
+        I really don't think this is going to work with current GDB, the
+        array indexing code in GDB seems to be pretty heavily tied to byte
+        offsets right now.  Assuming 8 bits in a byte.  */
+      struct gdbarch *gdbarch = get_type_arch (dyn_range_type);
+      int unit_size = gdbarch_addressable_memory_unit_size (gdbarch);
+      if (!byte_stride_p && (value % (unit_size * 8)) != 0)
+       error (_("bit strides that are not a multiple of the byte size "
+                "are currently not supported"));
+    }
+  else
+    {
+      stride.kind = PROP_UNDEFINED;
+      stride.data.const_val = 0;
+      byte_stride_p = true;
+    }
+
   static_target_type
     = resolve_dynamic_type_internal (TYPE_TARGET_TYPE (dyn_range_type),
                                     addr_stack, 0);
-  static_range_type = create_range_type (copy_type (dyn_range_type),
-                                        static_target_type,
-                                        &low_bound, &high_bound);
+  LONGEST bias = TYPE_RANGE_DATA (dyn_range_type)->bias;
+  static_range_type = create_range_type_with_stride
+    (copy_type (dyn_range_type), static_target_type,
+     &low_bound, &high_bound, bias, &stride, byte_stride_p);
   TYPE_RANGE_DATA (static_range_type)->flag_bound_evaluated = 1;
   return static_range_type;
 }
 
-/* Resolves dynamic bound values of an array type TYPE to static ones.
-   ADDR_STACK is a stack of struct property_addr_info to be used
-   if needed during the dynamic resolution.  */
+/* Resolves dynamic bound values of an array or string type TYPE to static
+   ones.  ADDR_STACK is a stack of struct property_addr_info to be used if
+   needed during the dynamic resolution.  */
 
 static struct type *
-resolve_dynamic_array (struct type *type,
-                      struct property_addr_info *addr_stack)
+resolve_dynamic_array_or_string (struct type *type,
+                                struct property_addr_info *addr_stack)
 {
   CORE_ADDR value;
   struct type *elt_type;
@@ -2011,7 +2118,10 @@ resolve_dynamic_array (struct type *type,
   struct dynamic_prop *prop;
   unsigned int bit_stride = 0;
 
-  gdb_assert (TYPE_CODE (type) == TYPE_CODE_ARRAY);
+  /* For dynamic type resolution strings can be treated like arrays of
+     characters.  */
+  gdb_assert (TYPE_CODE (type) == TYPE_CODE_ARRAY
+             || TYPE_CODE (type) == TYPE_CODE_STRING);
 
   type = copy_type (type);
 
@@ -2037,17 +2147,14 @@ resolve_dynamic_array (struct type *type,
   ary_dim = check_typedef (TYPE_TARGET_TYPE (elt_type));
 
   if (ary_dim != NULL && TYPE_CODE (ary_dim) == TYPE_CODE_ARRAY)
-    elt_type = resolve_dynamic_array (ary_dim, addr_stack);
+    elt_type = resolve_dynamic_array_or_string (ary_dim, addr_stack);
   else
     elt_type = TYPE_TARGET_TYPE (type);
 
   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)
+      if (dwarf2_evaluate_property (prop, NULL, addr_stack, &value))
        {
          remove_dyn_prop (DYN_PROP_BYTE_STRIDE, type);
          bit_stride = (unsigned int) (value * 8);
@@ -2243,8 +2350,11 @@ resolve_dynamic_type_internal (struct type *type,
            break;
          }
 
+       case TYPE_CODE_STRING:
+         /* Strings are very much like an array of characters, and can be
+            treated as one here.  */
        case TYPE_CODE_ARRAY:
-         resolved_type = resolve_dynamic_array (type, addr_stack);
+         resolved_type = resolve_dynamic_array_or_string (type, addr_stack);
          break;
 
        case TYPE_CODE_RANGE:
@@ -2305,13 +2415,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);
@@ -2401,11 +2512,9 @@ check_typedef (struct type *type)
          if (currently_reading_symtab)
            return make_qualified_type (type, instance_flags, NULL);
 
-         name = type_name_no_tag (type);
-         /* FIXME: shouldn't we separately check the TYPE_NAME and
-            the TYPE_TAG_NAME, and look in STRUCT_DOMAIN and/or
-            VAR_DOMAIN as appropriate?  (this code was written before
-            TYPE_NAME and TYPE_TAG_NAME were separate).  */
+         name = TYPE_NAME (type);
+         /* FIXME: shouldn't we look in STRUCT_DOMAIN and/or
+            VAR_DOMAIN as appropriate?  */
          if (name == NULL)
            {
              stub_noname_complaint ();
@@ -2456,7 +2565,7 @@ check_typedef (struct type *type)
       && opaque_type_resolution 
       && !currently_reading_symtab)
     {
-      const char *name = type_name_no_tag (type);
+      const char *name = TYPE_NAME (type);
       struct type *newtype;
 
       if (name == NULL)
@@ -2490,11 +2599,9 @@ check_typedef (struct type *type)
      types.  */
   else if (TYPE_STUB (type) && !currently_reading_symtab)
     {
-      const char *name = type_name_no_tag (type);
-      /* FIXME: shouldn't we separately check the TYPE_NAME and the
-         TYPE_TAG_NAME, and look in STRUCT_DOMAIN and/or VAR_DOMAIN
-         as appropriate?  (this code was written before TYPE_NAME and
-         TYPE_TAG_NAME were separate).  */
+      const char *name = TYPE_NAME (type);
+      /* FIXME: shouldn't we look in STRUCT_DOMAIN and/or VAR_DOMAIN
+         as appropriate?  */
       struct symbol *sym;
 
       if (name == NULL)
@@ -2554,15 +2661,14 @@ safe_parse_type (struct gdbarch *gdbarch, char *p, int length)
   gdb_stderr = &null_stream;
 
   /* Call parse_and_eval_type() without fear of longjmp()s.  */
-  TRY
+  try
     {
       type = parse_and_eval_type (p, length);
     }
-  CATCH (except, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &except)
     {
       type = builtin_type (gdbarch)->builtin_void;
     }
-  END_CATCH
 
   /* Stop suppressing error messages.  */
   gdb_stderr = saved_gdb_stderr;
@@ -2703,41 +2809,15 @@ check_stub_method_group (struct type *type, int method_id)
 {
   int len = TYPE_FN_FIELDLIST_LENGTH (type, method_id);
   struct fn_field *f = TYPE_FN_FIELDLIST1 (type, method_id);
-  int j, found_stub = 0;
-
-  for (j = 0; j < len; j++)
-    if (TYPE_FN_FIELD_STUB (f, j))
-      {
-       found_stub = 1;
-       check_stub_method (type, method_id, j);
-      }
-
-  /* GNU v3 methods with incorrect names were corrected when we read
-     in type information, because it was cheaper to do it then.  The
-     only GNU v2 methods with incorrect method names are operators and
-     destructors; destructors were also corrected when we read in type
-     information.
 
-     Therefore the only thing we need to handle here are v2 operator
-     names.  */
-  if (found_stub && !startswith (TYPE_FN_FIELD_PHYSNAME (f, 0), "_Z"))
+  for (int j = 0; j < len; j++)
     {
-      int ret;
-      char dem_opname[256];
-
-      ret = cplus_demangle_opname (TYPE_FN_FIELDLIST_NAME (type, 
-                                                          method_id),
-                                  dem_opname, DMGL_ANSI);
-      if (!ret)
-       ret = cplus_demangle_opname (TYPE_FN_FIELDLIST_NAME (type, 
-                                                            method_id),
-                                    dem_opname, 0);
-      if (ret)
-       TYPE_FN_FIELDLIST_NAME (type, method_id) = xstrdup (dem_opname);
+      if (TYPE_FN_FIELD_STUB (f, j))
+       check_stub_method (type, method_id, j);
     }
 }
 
-/* Ensure it is in .rodata (if available) by workarounding GCC PR 44690.  */
+/* Ensure it is in .rodata (if available) by working around GCC PR 44690.  */
 const struct cplus_struct_type cplus_struct_default = { };
 
 void
@@ -2908,15 +2988,22 @@ init_boolean_type (struct objfile *objfile,
 /* Allocate a TYPE_CODE_FLT type structure associated with OBJFILE.
    BIT is the type size in bits; if BIT equals -1, the size is
    determined by the floatformat.  NAME is the type name.  Set the
-   TYPE_FLOATFORMAT from FLOATFORMATS.  */
+   TYPE_FLOATFORMAT from FLOATFORMATS.  BYTE_ORDER is the byte order
+   to use.  If it is BFD_ENDIAN_UNKNOWN (the default), then the byte
+   order of the objfile's architecture is used.  */
 
 struct type *
 init_float_type (struct objfile *objfile,
                 int bit, const char *name,
-                const struct floatformat **floatformats)
+                const struct floatformat **floatformats,
+                enum bfd_endian byte_order)
 {
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
-  const struct floatformat *fmt = floatformats[gdbarch_byte_order (gdbarch)];
+  if (byte_order == BFD_ENDIAN_UNKNOWN)
+    {
+      struct gdbarch *gdbarch = get_objfile_arch (objfile);
+      byte_order = gdbarch_byte_order (gdbarch);
+    }
+  const struct floatformat *fmt = floatformats[byte_order];
   struct type *t;
 
   bit = verify_floatformat (bit, fmt);
@@ -2970,6 +3057,131 @@ 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)
+{
+  /* Check alignment provided in the debug information.  */
+  unsigned raw_align = type_raw_align (type);
+  if (raw_align != 0)
+    return raw_align;
+
+  /* Allow the architecture to provide an alignment.  */
+  struct gdbarch *arch = get_type_arch (type);
+  ULONGEST align = gdbarch_type_align (arch, type);
+  if (align != 0)
+    return align;
+
+  switch (TYPE_CODE (type))
+    {
+    case TYPE_CODE_PTR:
+    case TYPE_CODE_FUNC:
+    case TYPE_CODE_FLAGS:
+    case TYPE_CODE_INT:
+    case TYPE_CODE_RANGE:
+    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:
+    case TYPE_CODE_METHODPTR:
+    case TYPE_CODE_MEMBERPTR:
+      align = type_length_units (check_typedef (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:
+      {
+       int number_of_non_static_fields = 0;
+       for (unsigned i = 0; i < TYPE_NFIELDS (type); ++i)
+         {
+           if (!field_is_static (&TYPE_FIELD (type, i)))
+             {
+               number_of_non_static_fields++;
+               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;
+             }
+         }
+       /* A struct with no fields, or with only static fields has an
+          alignment of 1.  */
+       if (number_of_non_static_fields == 0)
+         align = 1;
+      }
+      break;
+
+    case TYPE_CODE_SET:
+    case TYPE_CODE_STRING:
+      /* Not sure what to do here, and these can't appear in C or C++
+        anyway.  */
+      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.  */
 
@@ -3223,6 +3435,26 @@ is_unique_ancestor (struct type *base, struct value *val)
                                    value_address (val), val) == 1;
 }
 
+/* See gdbtypes.h.  */
+
+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 (byteorder == BFD_ENDIAN_BIG)
+        return BFD_ENDIAN_LITTLE;
+      else
+       {
+         gdb_assert (byteorder == BFD_ENDIAN_LITTLE);
+         return BFD_ENDIAN_BIG;
+       }
+    }
+
+  return byteorder;
+}
+
 \f
 /* Overload resolution.  */
 
@@ -3271,21 +3503,21 @@ compare_ranks (struct rank a, struct rank b)
    3 => A is worse than B  */
 
 int
-compare_badness (struct badness_vector *a, struct badness_vector *b)
+compare_badness (const badness_vector &a, const badness_vector &b)
 {
   int i;
   int tmp;
   short found_pos = 0;         /* any positives in c? */
   short found_neg = 0;         /* any negatives in c? */
 
-  /* differing lengths => incomparable */
-  if (a->length != b->length)
+  /* differing sizes => incomparable */
+  if (a.size () != b.size ())
     return 1;
 
   /* Subtract b from a */
-  for (i = 0; i < a->length; i++)
+  for (i = 0; i < a.size (); i++)
     {
-      tmp = compare_ranks (b->rank[i], a->rank[i]);
+      tmp = compare_ranks (b[i], a[i]);
       if (tmp > 0)
        found_pos = 1;
       else if (tmp < 0)
@@ -3309,21 +3541,17 @@ compare_badness (struct badness_vector *a, struct badness_vector *b)
     }
 }
 
-/* Rank a function by comparing its parameter types (PARMS, length
-   NPARMS), to the types of an argument list (ARGS, length NARGS).
-   Return a pointer to a badness vector.  This has NARGS + 1
-   entries.  */
+/* Rank a function by comparing its parameter types (PARMS), to the
+   types of an argument list (ARGS).  Return the badness vector.  This
+   has ARGS.size() + 1 entries.  */
 
-struct badness_vector *
-rank_function (struct type **parms, int nparms, 
-              struct value **args, int nargs)
+badness_vector
+rank_function (gdb::array_view<type *> parms,
+              gdb::array_view<value *> args)
 {
-  int i;
-  struct badness_vector *bv = XNEW (struct badness_vector);
-  int min_len = nparms < nargs ? nparms : nargs;
-
-  bv->length = nargs + 1;      /* add 1 for the length-match rank.  */
-  bv->rank = XNEWVEC (struct rank, nargs + 1);
+  /* add 1 for the length-match rank.  */
+  badness_vector bv;
+  bv.reserve (1 + args.size ());
 
   /* First compare the lengths of the supplied lists.
      If there is a mismatch, set it to a high value.  */
@@ -3332,18 +3560,20 @@ rank_function (struct type **parms, int nparms,
      arguments and ellipsis parameter lists, we should consider those
      and rank the length-match more finely.  */
 
-  LENGTH_MATCH (bv) = (nargs != nparms)
-                     ? LENGTH_MISMATCH_BADNESS
-                     : EXACT_MATCH_BADNESS;
+  bv.push_back ((args.size () != parms.size ())
+               ? LENGTH_MISMATCH_BADNESS
+               : EXACT_MATCH_BADNESS);
 
   /* Now rank all the parameters of the candidate function.  */
-  for (i = 1; i <= min_len; i++)
-    bv->rank[i] = rank_one_type (parms[i - 1], value_type (args[i - 1]),
-                                args[i - 1]);
+  size_t min_len = std::min (parms.size (), args.size ());
+
+  for (size_t i = 0; i < min_len; i++)
+    bv.push_back (rank_one_type (parms[i], value_type (args[i]),
+                                args[i]));
 
   /* If more arguments than parameters, add dummy entries.  */
-  for (i = min_len + 1; i <= nargs; i++)
-    bv->rank[i] = TOO_FEW_PARAMS_BADNESS;
+  for (size_t i = min_len; i < args.size (); i++)
+    bv.push_back (TOO_FEW_PARAMS_BADNESS);
 
   return bv;
 }
@@ -3386,10 +3616,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.  */
@@ -3397,7 +3627,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)
@@ -3408,7 +3638,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
@@ -3425,11 +3655,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.  */
@@ -3438,83 +3668,82 @@ 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)
       || TYPE_UNSIGNED (type1) != TYPE_UNSIGNED (type2)
       || TYPE_NOSIGN (type1) != TYPE_NOSIGN (type2)
+      || TYPE_ENDIANITY_NOT_DEFAULT (type1) != TYPE_ENDIANITY_NOT_DEFAULT (type2)
       || TYPE_VARARGS (type1) != TYPE_VARARGS (type2)
       || TYPE_VECTOR (type1) != TYPE_VECTOR (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;
   if (!compare_maybe_null_strings (TYPE_NAME (type1), TYPE_NAME (type2)))
-    return 0;
+    return false;
+  if (!compare_maybe_null_strings (TYPE_NAME (type1), TYPE_NAME (type2)))
+    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
     {
@@ -3524,34 +3753,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:
              {
@@ -3562,7 +3790,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:
@@ -3571,103 +3799,68 @@ 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,
-                     struct bcache *cache)
+static bool
+check_types_worklist (std::vector<type_equality_entry> *worklist,
+                     gdb::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.  */
-      bcache_full (&entry, sizeof (entry), cache, &added);
+      cache->insert (&entry, sizeof (entry), &added);
       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;
-  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;
-
-  cache = bcache_xmalloc (NULL, NULL);
-
-  entry.type1 = type1;
-  entry.type2 = type2;
-  VEC_safe_push (type_equality_entry_d, worklist, &entry);
-
-  /* check_types_worklist calls several nested helper functions, some
-     of which can raise a GDB exception, so we just check and rethrow
-     here.  If there is a GDB exception, a comparison is not capable
-     (or trusted), so exit.  */
-  TRY
-    {
-      result = check_types_worklist (&worklist, cache);
-    }
-  CATCH (ex, RETURN_MASK_ALL)
-    {
-      except = ex;
-    }
-  END_CATCH
+    return true;
 
-  bcache_xfree (cache);
-  VEC_free (type_equality_entry_d, worklist);
-
-  /* Rethrow if there was a problem.  */
-  if (except.reason < 0)
-    throw_exception (except);
-
-  return result;
+  gdb::bcache cache (nullptr, nullptr);
+  worklist.emplace_back (type1, type2);
+  return check_types_worklist (&worklist, &cache);
 }
 
 /* Allocated status of type TYPE.  Return zero if type TYPE is allocated.
@@ -3693,51 +3886,435 @@ type_not_associated (const struct type *type)
   return (prop && TYPE_DYN_PROP_KIND (prop) == PROP_CONST
          && !TYPE_DYN_PROP_ADDR (prop));
 }
-\f
-/* Compare one type (PARM) for compatibility with another (ARG).
- * PARM is intended to be the parameter type of a function; and
- * ARG is the supplied argument's type.  This function tests if
- * the latter can be converted to the former.
- * VALUE is the argument's value or NULL if none (or called recursively)
- *
- * Return 0 if they are identical types;
- * Otherwise, return an integer which corresponds to how compatible
- * PARM is to ARG.  The higher the return value, the worse the match.
- * Generally the "bad" conversions are all uniformly assigned a 100.  */
 
-struct rank
-rank_one_type (struct type *parm, struct type *arg, struct value *value)
+/* rank_one_type helper for when PARM's type code is TYPE_CODE_PTR.  */
+
+static struct rank
+rank_one_type_parm_ptr (struct type *parm, struct type *arg, struct value *value)
 {
   struct rank rank = {0,0};
 
-  /* Resolve typedefs */
-  if (TYPE_CODE (parm) == TYPE_CODE_TYPEDEF)
-    parm = check_typedef (parm);
-  if (TYPE_CODE (arg) == TYPE_CODE_TYPEDEF)
-    arg = check_typedef (arg);
-
-  if (TYPE_IS_REFERENCE (parm) && value != NULL)
+  switch (TYPE_CODE (arg))
     {
-      if (VALUE_LVAL (value) == not_lval)
-       {
-         /* Rvalues should preferably bind to rvalue references or const
-            lvalue references.  */
-         if (TYPE_CODE (parm) == TYPE_CODE_RVALUE_REF)
-           rank.subrank = REFERENCE_CONVERSION_RVALUE;
-         else if (TYPE_CONST (TYPE_TARGET_TYPE (parm)))
-           rank.subrank = REFERENCE_CONVERSION_CONST_LVALUE;
-         else
+    case TYPE_CODE_PTR:
+
+      /* Allowed pointer conversions are:
+        (a) pointer to void-pointer conversion.  */
+      if (TYPE_CODE (TYPE_TARGET_TYPE (parm)) == TYPE_CODE_VOID)
+       return VOID_PTR_CONVERSION_BADNESS;
+
+      /* (b) pointer to ancestor-pointer conversion.  */
+      rank.subrank = distance_to_ancestor (TYPE_TARGET_TYPE (parm),
+                                          TYPE_TARGET_TYPE (arg),
+                                          0);
+      if (rank.subrank >= 0)
+       return sum_ranks (BASE_PTR_CONVERSION_BADNESS, rank);
+
+      return INCOMPATIBLE_TYPE_BADNESS;
+    case TYPE_CODE_ARRAY:
+      {
+       struct type *t1 = TYPE_TARGET_TYPE (parm);
+       struct type *t2 = TYPE_TARGET_TYPE (arg);
+
+       if (types_equal (t1, t2))
+         {
+           /* Make sure they are CV equal.  */
+           if (TYPE_CONST (t1) != TYPE_CONST (t2))
+             rank.subrank |= CV_CONVERSION_CONST;
+           if (TYPE_VOLATILE (t1) != TYPE_VOLATILE (t2))
+             rank.subrank |= CV_CONVERSION_VOLATILE;
+           if (rank.subrank != 0)
+             return sum_ranks (CV_CONVERSION_BADNESS, rank);
+           return EXACT_MATCH_BADNESS;
+         }
+       return INCOMPATIBLE_TYPE_BADNESS;
+      }
+    case TYPE_CODE_FUNC:
+      return rank_one_type (TYPE_TARGET_TYPE (parm), arg, NULL);
+    case TYPE_CODE_INT:
+      if (value != NULL && TYPE_CODE (value_type (value)) == TYPE_CODE_INT)
+       {
+         if (value_as_long (value) == 0)
+           {
+             /* Null pointer conversion: allow it to be cast to a pointer.
+                [4.10.1 of C++ standard draft n3290]  */
+             return NULL_POINTER_CONVERSION_BADNESS;
+           }
+         else
+           {
+             /* If type checking is disabled, allow the conversion.  */
+             if (!strict_type_checking)
+               return NS_INTEGER_POINTER_CONVERSION_BADNESS;
+           }
+       }
+      /* fall through  */
+    case TYPE_CODE_ENUM:
+    case TYPE_CODE_FLAGS:
+    case TYPE_CODE_CHAR:
+    case TYPE_CODE_RANGE:
+    case TYPE_CODE_BOOL:
+    default:
+      return INCOMPATIBLE_TYPE_BADNESS;
+    }
+}
+
+/* rank_one_type helper for when PARM's type code is TYPE_CODE_ARRAY.  */
+
+static struct rank
+rank_one_type_parm_array (struct type *parm, struct type *arg, struct value *value)
+{
+  switch (TYPE_CODE (arg))
+    {
+    case TYPE_CODE_PTR:
+    case TYPE_CODE_ARRAY:
+      return rank_one_type (TYPE_TARGET_TYPE (parm),
+                           TYPE_TARGET_TYPE (arg), NULL);
+    default:
+      return INCOMPATIBLE_TYPE_BADNESS;
+    }
+}
+
+/* rank_one_type helper for when PARM's type code is TYPE_CODE_FUNC.  */
+
+static struct rank
+rank_one_type_parm_func (struct type *parm, struct type *arg, struct value *value)
+{
+  switch (TYPE_CODE (arg))
+    {
+    case TYPE_CODE_PTR:        /* funcptr -> func */
+      return rank_one_type (parm, TYPE_TARGET_TYPE (arg), NULL);
+    default:
+      return INCOMPATIBLE_TYPE_BADNESS;
+    }
+}
+
+/* rank_one_type helper for when PARM's type code is TYPE_CODE_INT.  */
+
+static struct rank
+rank_one_type_parm_int (struct type *parm, struct type *arg, struct value *value)
+{
+  switch (TYPE_CODE (arg))
+    {
+    case TYPE_CODE_INT:
+      if (TYPE_LENGTH (arg) == TYPE_LENGTH (parm))
+       {
+         /* Deal with signed, unsigned, and plain chars and
+            signed and unsigned ints.  */
+         if (TYPE_NOSIGN (parm))
+           {
+             /* This case only for character types.  */
+             if (TYPE_NOSIGN (arg))
+               return EXACT_MATCH_BADNESS;     /* plain char -> plain char */
+             else              /* signed/unsigned char -> plain char */
+               return INTEGER_CONVERSION_BADNESS;
+           }
+         else if (TYPE_UNSIGNED (parm))
+           {
+             if (TYPE_UNSIGNED (arg))
+               {
+                 /* unsigned int -> unsigned int, or
+                    unsigned long -> unsigned long */
+                 if (integer_types_same_name_p (TYPE_NAME (parm),
+                                                TYPE_NAME (arg)))
+                   return EXACT_MATCH_BADNESS;
+                 else if (integer_types_same_name_p (TYPE_NAME (arg),
+                                                     "int")
+                          && integer_types_same_name_p (TYPE_NAME (parm),
+                                                        "long"))
+                   /* unsigned int -> unsigned long */
+                   return INTEGER_PROMOTION_BADNESS;
+                 else
+                   /* unsigned long -> unsigned int */
+                   return INTEGER_CONVERSION_BADNESS;
+               }
+             else
+               {
+                 if (integer_types_same_name_p (TYPE_NAME (arg),
+                                                "long")
+                     && integer_types_same_name_p (TYPE_NAME (parm),
+                                                   "int"))
+                   /* signed long -> unsigned int */
+                   return INTEGER_CONVERSION_BADNESS;
+                 else
+                   /* signed int/long -> unsigned int/long */
+                   return INTEGER_CONVERSION_BADNESS;
+               }
+           }
+         else if (!TYPE_NOSIGN (arg) && !TYPE_UNSIGNED (arg))
+           {
+             if (integer_types_same_name_p (TYPE_NAME (parm),
+                                            TYPE_NAME (arg)))
+               return EXACT_MATCH_BADNESS;
+             else if (integer_types_same_name_p (TYPE_NAME (arg),
+                                                 "int")
+                      && integer_types_same_name_p (TYPE_NAME (parm),
+                                                    "long"))
+               return INTEGER_PROMOTION_BADNESS;
+             else
+               return INTEGER_CONVERSION_BADNESS;
+           }
+         else
+           return INTEGER_CONVERSION_BADNESS;
+       }
+      else if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm))
+       return INTEGER_PROMOTION_BADNESS;
+      else
+       return INTEGER_CONVERSION_BADNESS;
+    case TYPE_CODE_ENUM:
+    case TYPE_CODE_FLAGS:
+    case TYPE_CODE_CHAR:
+    case TYPE_CODE_RANGE:
+    case TYPE_CODE_BOOL:
+      if (TYPE_DECLARED_CLASS (arg))
+       return INCOMPATIBLE_TYPE_BADNESS;
+      return INTEGER_PROMOTION_BADNESS;
+    case TYPE_CODE_FLT:
+      return INT_FLOAT_CONVERSION_BADNESS;
+    case TYPE_CODE_PTR:
+      return NS_POINTER_CONVERSION_BADNESS;
+    default:
+      return INCOMPATIBLE_TYPE_BADNESS;
+    }
+}
+
+/* rank_one_type helper for when PARM's type code is TYPE_CODE_ENUM.  */
+
+static struct rank
+rank_one_type_parm_enum (struct type *parm, struct type *arg, struct value *value)
+{
+  switch (TYPE_CODE (arg))
+    {
+    case TYPE_CODE_INT:
+    case TYPE_CODE_CHAR:
+    case TYPE_CODE_RANGE:
+    case TYPE_CODE_BOOL:
+    case TYPE_CODE_ENUM:
+      if (TYPE_DECLARED_CLASS (parm) || TYPE_DECLARED_CLASS (arg))
+       return INCOMPATIBLE_TYPE_BADNESS;
+      return INTEGER_CONVERSION_BADNESS;
+    case TYPE_CODE_FLT:
+      return INT_FLOAT_CONVERSION_BADNESS;
+    default:
+      return INCOMPATIBLE_TYPE_BADNESS;
+    }
+}
+
+/* rank_one_type helper for when PARM's type code is TYPE_CODE_CHAR.  */
+
+static struct rank
+rank_one_type_parm_char (struct type *parm, struct type *arg, struct value *value)
+{
+  switch (TYPE_CODE (arg))
+    {
+    case TYPE_CODE_RANGE:
+    case TYPE_CODE_BOOL:
+    case TYPE_CODE_ENUM:
+      if (TYPE_DECLARED_CLASS (arg))
+       return INCOMPATIBLE_TYPE_BADNESS;
+      return INTEGER_CONVERSION_BADNESS;
+    case TYPE_CODE_FLT:
+      return INT_FLOAT_CONVERSION_BADNESS;
+    case TYPE_CODE_INT:
+      if (TYPE_LENGTH (arg) > TYPE_LENGTH (parm))
+       return INTEGER_CONVERSION_BADNESS;
+      else if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm))
+       return INTEGER_PROMOTION_BADNESS;
+      /* fall through */
+    case TYPE_CODE_CHAR:
+      /* Deal with signed, unsigned, and plain chars for C++ and
+        with int cases falling through from previous case.  */
+      if (TYPE_NOSIGN (parm))
+       {
+         if (TYPE_NOSIGN (arg))
+           return EXACT_MATCH_BADNESS;
+         else
+           return INTEGER_CONVERSION_BADNESS;
+       }
+      else if (TYPE_UNSIGNED (parm))
+       {
+         if (TYPE_UNSIGNED (arg))
+           return EXACT_MATCH_BADNESS;
+         else
+           return INTEGER_PROMOTION_BADNESS;
+       }
+      else if (!TYPE_NOSIGN (arg) && !TYPE_UNSIGNED (arg))
+       return EXACT_MATCH_BADNESS;
+      else
+       return INTEGER_CONVERSION_BADNESS;
+    default:
+      return INCOMPATIBLE_TYPE_BADNESS;
+    }
+}
+
+/* rank_one_type helper for when PARM's type code is TYPE_CODE_RANGE.  */
+
+static struct rank
+rank_one_type_parm_range (struct type *parm, struct type *arg, struct value *value)
+{
+  switch (TYPE_CODE (arg))
+    {
+    case TYPE_CODE_INT:
+    case TYPE_CODE_CHAR:
+    case TYPE_CODE_RANGE:
+    case TYPE_CODE_BOOL:
+    case TYPE_CODE_ENUM:
+      return INTEGER_CONVERSION_BADNESS;
+    case TYPE_CODE_FLT:
+      return INT_FLOAT_CONVERSION_BADNESS;
+    default:
+      return INCOMPATIBLE_TYPE_BADNESS;
+    }
+}
+
+/* rank_one_type helper for when PARM's type code is TYPE_CODE_BOOL.  */
+
+static struct rank
+rank_one_type_parm_bool (struct type *parm, struct type *arg, struct value *value)
+{
+  switch (TYPE_CODE (arg))
+    {
+      /* n3290 draft, section 4.12.1 (conv.bool):
+
+        "A prvalue of arithmetic, unscoped enumeration, pointer, or
+        pointer to member type can be converted to a prvalue of type
+        bool.  A zero value, null pointer value, or null member pointer
+        value is converted to false; any other value is converted to
+        true.  A prvalue of type std::nullptr_t can be converted to a
+        prvalue of type bool; the resulting value is false."  */
+    case TYPE_CODE_INT:
+    case TYPE_CODE_CHAR:
+    case TYPE_CODE_ENUM:
+    case TYPE_CODE_FLT:
+    case TYPE_CODE_MEMBERPTR:
+    case TYPE_CODE_PTR:
+      return BOOL_CONVERSION_BADNESS;
+    case TYPE_CODE_RANGE:
+      return INCOMPATIBLE_TYPE_BADNESS;
+    case TYPE_CODE_BOOL:
+      return EXACT_MATCH_BADNESS;
+    default:
+      return INCOMPATIBLE_TYPE_BADNESS;
+    }
+}
+
+/* rank_one_type helper for when PARM's type code is TYPE_CODE_FLOAT.  */
+
+static struct rank
+rank_one_type_parm_float (struct type *parm, struct type *arg, struct value *value)
+{
+  switch (TYPE_CODE (arg))
+    {
+    case TYPE_CODE_FLT:
+      if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm))
+       return FLOAT_PROMOTION_BADNESS;
+      else if (TYPE_LENGTH (arg) == TYPE_LENGTH (parm))
+       return EXACT_MATCH_BADNESS;
+      else
+       return FLOAT_CONVERSION_BADNESS;
+    case TYPE_CODE_INT:
+    case TYPE_CODE_BOOL:
+    case TYPE_CODE_ENUM:
+    case TYPE_CODE_RANGE:
+    case TYPE_CODE_CHAR:
+      return INT_FLOAT_CONVERSION_BADNESS;
+    default:
+      return INCOMPATIBLE_TYPE_BADNESS;
+    }
+}
+
+/* rank_one_type helper for when PARM's type code is TYPE_CODE_COMPLEX.  */
+
+static struct rank
+rank_one_type_parm_complex (struct type *parm, struct type *arg, struct value *value)
+{
+  switch (TYPE_CODE (arg))
+    {          /* Strictly not needed for C++, but...  */
+    case TYPE_CODE_FLT:
+      return FLOAT_PROMOTION_BADNESS;
+    case TYPE_CODE_COMPLEX:
+      return EXACT_MATCH_BADNESS;
+    default:
+      return INCOMPATIBLE_TYPE_BADNESS;
+    }
+}
+
+/* rank_one_type helper for when PARM's type code is TYPE_CODE_STRUCT.  */
+
+static struct rank
+rank_one_type_parm_struct (struct type *parm, struct type *arg, struct value *value)
+{
+  struct rank rank = {0, 0};
+
+  switch (TYPE_CODE (arg))
+    {
+    case TYPE_CODE_STRUCT:
+      /* Check for derivation */
+      rank.subrank = distance_to_ancestor (parm, arg, 0);
+      if (rank.subrank >= 0)
+       return sum_ranks (BASE_CONVERSION_BADNESS, rank);
+      /* fall through */
+    default:
+      return INCOMPATIBLE_TYPE_BADNESS;
+    }
+}
+
+/* rank_one_type helper for when PARM's type code is TYPE_CODE_SET.  */
+
+static struct rank
+rank_one_type_parm_set (struct type *parm, struct type *arg, struct value *value)
+{
+  switch (TYPE_CODE (arg))
+    {
+      /* Not in C++ */
+    case TYPE_CODE_SET:
+      return rank_one_type (TYPE_FIELD_TYPE (parm, 0),
+                           TYPE_FIELD_TYPE (arg, 0), NULL);
+    default:
+      return INCOMPATIBLE_TYPE_BADNESS;
+    }
+}
+
+/* Compare one type (PARM) for compatibility with another (ARG).
+ * PARM is intended to be the parameter type of a function; and
+ * ARG is the supplied argument's type.  This function tests if
+ * the latter can be converted to the former.
+ * VALUE is the argument's value or NULL if none (or called recursively)
+ *
+ * Return 0 if they are identical types;
+ * Otherwise, return an integer which corresponds to how compatible
+ * PARM is to ARG.  The higher the return value, the worse the match.
+ * Generally the "bad" conversions are all uniformly assigned a 100.  */
+
+struct rank
+rank_one_type (struct type *parm, struct type *arg, struct value *value)
+{
+  struct rank rank = {0,0};
+
+  /* Resolve typedefs */
+  if (TYPE_CODE (parm) == TYPE_CODE_TYPEDEF)
+    parm = check_typedef (parm);
+  if (TYPE_CODE (arg) == TYPE_CODE_TYPEDEF)
+    arg = check_typedef (arg);
+
+  if (TYPE_IS_REFERENCE (parm) && value != NULL)
+    {
+      if (VALUE_LVAL (value) == not_lval)
+       {
+         /* Rvalues should preferably bind to rvalue references or const
+            lvalue references.  */
+         if (TYPE_CODE (parm) == TYPE_CODE_RVALUE_REF)
+           rank.subrank = REFERENCE_CONVERSION_RVALUE;
+         else if (TYPE_CONST (TYPE_TARGET_TYPE (parm)))
+           rank.subrank = REFERENCE_CONVERSION_CONST_LVALUE;
+         else
            return INCOMPATIBLE_TYPE_BADNESS;
          return sum_ranks (rank, REFERENCE_CONVERSION_BADNESS);
        }
       else
        {
-         /* Lvalues should prefer lvalue overloads.  */
+         /* It's illegal to pass an lvalue as an rvalue.  */
          if (TYPE_CODE (parm) == TYPE_CODE_RVALUE_REF)
-           {
-             rank.subrank = REFERENCE_CONVERSION_RVALUE;
-             return sum_ranks (rank, REFERENCE_CONVERSION_BADNESS);
-           }
+           return INCOMPATIBLE_TYPE_BADNESS;
        }
     }
 
@@ -3768,10 +4345,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_CONVERSION_BADNESS));
+                       REFERENCE_SEE_THROUGH_BADNESS));
   if (TYPE_IS_REFERENCE (parm))
     return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm), arg, NULL),
-                       REFERENCE_CONVERSION_BADNESS));
+                       REFERENCE_SEE_THROUGH_BADNESS));
   if (overload_debug)
   /* Debugging only.  */
     fprintf_filtered (gdb_stderr, 
@@ -3784,358 +4361,29 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value)
   switch (TYPE_CODE (parm))
     {
     case TYPE_CODE_PTR:
-      switch (TYPE_CODE (arg))
-       {
-       case TYPE_CODE_PTR:
-
-         /* Allowed pointer conversions are:
-            (a) pointer to void-pointer conversion.  */
-         if (TYPE_CODE (TYPE_TARGET_TYPE (parm)) == TYPE_CODE_VOID)
-           return VOID_PTR_CONVERSION_BADNESS;
-
-         /* (b) pointer to ancestor-pointer conversion.  */
-         rank.subrank = distance_to_ancestor (TYPE_TARGET_TYPE (parm),
-                                              TYPE_TARGET_TYPE (arg),
-                                              0);
-         if (rank.subrank >= 0)
-           return sum_ranks (BASE_PTR_CONVERSION_BADNESS, rank);
-
-         return INCOMPATIBLE_TYPE_BADNESS;
-       case TYPE_CODE_ARRAY:
-         {
-           struct type *t1 = TYPE_TARGET_TYPE (parm);
-           struct type *t2 = TYPE_TARGET_TYPE (arg);
-
-           if (types_equal (t1, t2))
-             {
-               /* Make sure they are CV equal.  */
-               if (TYPE_CONST (t1) != TYPE_CONST (t2))
-                 rank.subrank |= CV_CONVERSION_CONST;
-               if (TYPE_VOLATILE (t1) != TYPE_VOLATILE (t2))
-                 rank.subrank |= CV_CONVERSION_VOLATILE;
-               if (rank.subrank != 0)
-                 return sum_ranks (CV_CONVERSION_BADNESS, rank);
-               return EXACT_MATCH_BADNESS;
-             }
-           return INCOMPATIBLE_TYPE_BADNESS;
-         }
-       case TYPE_CODE_FUNC:
-         return rank_one_type (TYPE_TARGET_TYPE (parm), arg, NULL);
-       case TYPE_CODE_INT:
-         if (value != NULL && TYPE_CODE (value_type (value)) == TYPE_CODE_INT)
-           {
-             if (value_as_long (value) == 0)
-               {
-                 /* Null pointer conversion: allow it to be cast to a pointer.
-                    [4.10.1 of C++ standard draft n3290]  */
-                 return NULL_POINTER_CONVERSION_BADNESS;
-               }
-             else
-               {
-                 /* If type checking is disabled, allow the conversion.  */
-                 if (!strict_type_checking)
-                   return NS_INTEGER_POINTER_CONVERSION_BADNESS;
-               }
-           }
-         /* fall through  */
-       case TYPE_CODE_ENUM:
-       case TYPE_CODE_FLAGS:
-       case TYPE_CODE_CHAR:
-       case TYPE_CODE_RANGE:
-       case TYPE_CODE_BOOL:
-       default:
-         return INCOMPATIBLE_TYPE_BADNESS;
-       }
+      return rank_one_type_parm_ptr (parm, arg, value);
     case TYPE_CODE_ARRAY:
-      switch (TYPE_CODE (arg))
-       {
-       case TYPE_CODE_PTR:
-       case TYPE_CODE_ARRAY:
-         return rank_one_type (TYPE_TARGET_TYPE (parm), 
-                               TYPE_TARGET_TYPE (arg), NULL);
-       default:
-         return INCOMPATIBLE_TYPE_BADNESS;
-       }
+      return rank_one_type_parm_array (parm, arg, value);
     case TYPE_CODE_FUNC:
-      switch (TYPE_CODE (arg))
-       {
-       case TYPE_CODE_PTR:     /* funcptr -> func */
-         return rank_one_type (parm, TYPE_TARGET_TYPE (arg), NULL);
-       default:
-         return INCOMPATIBLE_TYPE_BADNESS;
-       }
+      return rank_one_type_parm_func (parm, arg, value);
     case TYPE_CODE_INT:
-      switch (TYPE_CODE (arg))
-       {
-       case TYPE_CODE_INT:
-         if (TYPE_LENGTH (arg) == TYPE_LENGTH (parm))
-           {
-             /* Deal with signed, unsigned, and plain chars and
-                signed and unsigned ints.  */
-             if (TYPE_NOSIGN (parm))
-               {
-                 /* This case only for character types.  */
-                 if (TYPE_NOSIGN (arg))
-                   return EXACT_MATCH_BADNESS; /* plain char -> plain char */
-                 else          /* signed/unsigned char -> plain char */
-                   return INTEGER_CONVERSION_BADNESS;
-               }
-             else if (TYPE_UNSIGNED (parm))
-               {
-                 if (TYPE_UNSIGNED (arg))
-                   {
-                     /* unsigned int -> unsigned int, or 
-                        unsigned long -> unsigned long */
-                     if (integer_types_same_name_p (TYPE_NAME (parm), 
-                                                    TYPE_NAME (arg)))
-                       return EXACT_MATCH_BADNESS;
-                     else if (integer_types_same_name_p (TYPE_NAME (arg), 
-                                                         "int")
-                              && integer_types_same_name_p (TYPE_NAME (parm),
-                                                            "long"))
-                       /* unsigned int -> unsigned long */
-                       return INTEGER_PROMOTION_BADNESS;
-                     else
-                       /* unsigned long -> unsigned int */
-                       return INTEGER_CONVERSION_BADNESS;
-                   }
-                 else
-                   {
-                     if (integer_types_same_name_p (TYPE_NAME (arg), 
-                                                    "long")
-                         && integer_types_same_name_p (TYPE_NAME (parm), 
-                                                       "int"))
-                       /* signed long -> unsigned int */
-                       return INTEGER_CONVERSION_BADNESS;
-                     else
-                       /* signed int/long -> unsigned int/long */
-                       return INTEGER_CONVERSION_BADNESS;
-                   }
-               }
-             else if (!TYPE_NOSIGN (arg) && !TYPE_UNSIGNED (arg))
-               {
-                 if (integer_types_same_name_p (TYPE_NAME (parm), 
-                                                TYPE_NAME (arg)))
-                   return EXACT_MATCH_BADNESS;
-                 else if (integer_types_same_name_p (TYPE_NAME (arg), 
-                                                     "int")
-                          && integer_types_same_name_p (TYPE_NAME (parm), 
-                                                        "long"))
-                   return INTEGER_PROMOTION_BADNESS;
-                 else
-                   return INTEGER_CONVERSION_BADNESS;
-               }
-             else
-               return INTEGER_CONVERSION_BADNESS;
-           }
-         else if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm))
-           return INTEGER_PROMOTION_BADNESS;
-         else
-           return INTEGER_CONVERSION_BADNESS;
-       case TYPE_CODE_ENUM:
-       case TYPE_CODE_FLAGS:
-       case TYPE_CODE_CHAR:
-       case TYPE_CODE_RANGE:
-       case TYPE_CODE_BOOL:
-         if (TYPE_DECLARED_CLASS (arg))
-           return INCOMPATIBLE_TYPE_BADNESS;
-         return INTEGER_PROMOTION_BADNESS;
-       case TYPE_CODE_FLT:
-         return INT_FLOAT_CONVERSION_BADNESS;
-       case TYPE_CODE_PTR:
-         return NS_POINTER_CONVERSION_BADNESS;
-       default:
-         return INCOMPATIBLE_TYPE_BADNESS;
-       }
-      break;
+      return rank_one_type_parm_int (parm, arg, value);
     case TYPE_CODE_ENUM:
-      switch (TYPE_CODE (arg))
-       {
-       case TYPE_CODE_INT:
-       case TYPE_CODE_CHAR:
-       case TYPE_CODE_RANGE:
-       case TYPE_CODE_BOOL:
-       case TYPE_CODE_ENUM:
-         if (TYPE_DECLARED_CLASS (parm) || TYPE_DECLARED_CLASS (arg))
-           return INCOMPATIBLE_TYPE_BADNESS;
-         return INTEGER_CONVERSION_BADNESS;
-       case TYPE_CODE_FLT:
-         return INT_FLOAT_CONVERSION_BADNESS;
-       default:
-         return INCOMPATIBLE_TYPE_BADNESS;
-       }
-      break;
+      return rank_one_type_parm_enum (parm, arg, value);
     case TYPE_CODE_CHAR:
-      switch (TYPE_CODE (arg))
-       {
-       case TYPE_CODE_RANGE:
-       case TYPE_CODE_BOOL:
-       case TYPE_CODE_ENUM:
-         if (TYPE_DECLARED_CLASS (arg))
-           return INCOMPATIBLE_TYPE_BADNESS;
-         return INTEGER_CONVERSION_BADNESS;
-       case TYPE_CODE_FLT:
-         return INT_FLOAT_CONVERSION_BADNESS;
-       case TYPE_CODE_INT:
-         if (TYPE_LENGTH (arg) > TYPE_LENGTH (parm))
-           return INTEGER_CONVERSION_BADNESS;
-         else if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm))
-           return INTEGER_PROMOTION_BADNESS;
-         /* >>> !! else fall through !! <<< */
-       case TYPE_CODE_CHAR:
-         /* Deal with signed, unsigned, and plain chars for C++ and
-            with int cases falling through from previous case.  */
-         if (TYPE_NOSIGN (parm))
-           {
-             if (TYPE_NOSIGN (arg))
-               return EXACT_MATCH_BADNESS;
-             else
-               return INTEGER_CONVERSION_BADNESS;
-           }
-         else if (TYPE_UNSIGNED (parm))
-           {
-             if (TYPE_UNSIGNED (arg))
-               return EXACT_MATCH_BADNESS;
-             else
-               return INTEGER_PROMOTION_BADNESS;
-           }
-         else if (!TYPE_NOSIGN (arg) && !TYPE_UNSIGNED (arg))
-           return EXACT_MATCH_BADNESS;
-         else
-           return INTEGER_CONVERSION_BADNESS;
-       default:
-         return INCOMPATIBLE_TYPE_BADNESS;
-       }
-      break;
+      return rank_one_type_parm_char (parm, arg, value);
     case TYPE_CODE_RANGE:
-      switch (TYPE_CODE (arg))
-       {
-       case TYPE_CODE_INT:
-       case TYPE_CODE_CHAR:
-       case TYPE_CODE_RANGE:
-       case TYPE_CODE_BOOL:
-       case TYPE_CODE_ENUM:
-         return INTEGER_CONVERSION_BADNESS;
-       case TYPE_CODE_FLT:
-         return INT_FLOAT_CONVERSION_BADNESS;
-       default:
-         return INCOMPATIBLE_TYPE_BADNESS;
-       }
-      break;
+      return rank_one_type_parm_range (parm, arg, value);
     case TYPE_CODE_BOOL:
-      switch (TYPE_CODE (arg))
-       {
-         /* n3290 draft, section 4.12.1 (conv.bool):
-
-            "A prvalue of arithmetic, unscoped enumeration, pointer, or
-            pointer to member type can be converted to a prvalue of type
-            bool.  A zero value, null pointer value, or null member pointer
-            value is converted to false; any other value is converted to
-            true.  A prvalue of type std::nullptr_t can be converted to a
-            prvalue of type bool; the resulting value is false."  */
-       case TYPE_CODE_INT:
-       case TYPE_CODE_CHAR:
-       case TYPE_CODE_ENUM:
-       case TYPE_CODE_FLT:
-       case TYPE_CODE_MEMBERPTR:
-       case TYPE_CODE_PTR:
-         return BOOL_CONVERSION_BADNESS;
-       case TYPE_CODE_RANGE:
-         return INCOMPATIBLE_TYPE_BADNESS;
-       case TYPE_CODE_BOOL:
-         return EXACT_MATCH_BADNESS;
-       default:
-         return INCOMPATIBLE_TYPE_BADNESS;
-       }
-      break;
+      return rank_one_type_parm_bool (parm, arg, value);
     case TYPE_CODE_FLT:
-      switch (TYPE_CODE (arg))
-       {
-       case TYPE_CODE_FLT:
-         if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm))
-           return FLOAT_PROMOTION_BADNESS;
-         else if (TYPE_LENGTH (arg) == TYPE_LENGTH (parm))
-           return EXACT_MATCH_BADNESS;
-         else
-           return FLOAT_CONVERSION_BADNESS;
-       case TYPE_CODE_INT:
-       case TYPE_CODE_BOOL:
-       case TYPE_CODE_ENUM:
-       case TYPE_CODE_RANGE:
-       case TYPE_CODE_CHAR:
-         return INT_FLOAT_CONVERSION_BADNESS;
-       default:
-         return INCOMPATIBLE_TYPE_BADNESS;
-       }
-      break;
+      return rank_one_type_parm_float (parm, arg, value);
     case TYPE_CODE_COMPLEX:
-      switch (TYPE_CODE (arg))
-       {               /* Strictly not needed for C++, but...  */
-       case TYPE_CODE_FLT:
-         return FLOAT_PROMOTION_BADNESS;
-       case TYPE_CODE_COMPLEX:
-         return EXACT_MATCH_BADNESS;
-       default:
-         return INCOMPATIBLE_TYPE_BADNESS;
-       }
-      break;
+      return rank_one_type_parm_complex (parm, arg, value);
     case TYPE_CODE_STRUCT:
-      switch (TYPE_CODE (arg))
-       {
-       case TYPE_CODE_STRUCT:
-         /* Check for derivation */
-         rank.subrank = distance_to_ancestor (parm, arg, 0);
-         if (rank.subrank >= 0)
-           return sum_ranks (BASE_CONVERSION_BADNESS, rank);
-         /* else fall through */
-       default:
-         return INCOMPATIBLE_TYPE_BADNESS;
-       }
-      break;
-    case TYPE_CODE_UNION:
-      switch (TYPE_CODE (arg))
-       {
-       case TYPE_CODE_UNION:
-       default:
-         return INCOMPATIBLE_TYPE_BADNESS;
-       }
-      break;
-    case TYPE_CODE_MEMBERPTR:
-      switch (TYPE_CODE (arg))
-       {
-       default:
-         return INCOMPATIBLE_TYPE_BADNESS;
-       }
-      break;
-    case TYPE_CODE_METHOD:
-      switch (TYPE_CODE (arg))
-       {
-
-       default:
-         return INCOMPATIBLE_TYPE_BADNESS;
-       }
-      break;
-    case TYPE_CODE_REF:
-      switch (TYPE_CODE (arg))
-       {
-
-       default:
-         return INCOMPATIBLE_TYPE_BADNESS;
-       }
-
-      break;
+      return rank_one_type_parm_struct (parm, arg, value);
     case TYPE_CODE_SET:
-      switch (TYPE_CODE (arg))
-       {
-         /* Not in C++ */
-       case TYPE_CODE_SET:
-         return rank_one_type (TYPE_FIELD_TYPE (parm, 0), 
-                               TYPE_FIELD_TYPE (arg, 0), NULL);
-       default:
-         return INCOMPATIBLE_TYPE_BADNESS;
-       }
-      break;
-    case TYPE_CODE_VOID:
+      return rank_one_type_parm_set (parm, arg, value);
     default:
       return INCOMPATIBLE_TYPE_BADNESS;
     }                          /* switch (TYPE_CODE (arg)) */
@@ -4255,6 +4503,10 @@ dump_fn_fieldlists (struct type *type, int spaces)
                            TYPE_FN_FIELD_PROTECTED (f, overload_idx));
          printfi_filtered (spaces + 8, "is_stub %d\n",
                            TYPE_FN_FIELD_STUB (f, overload_idx));
+         printfi_filtered (spaces + 8, "defaulted %d\n",
+                           TYPE_FN_FIELD_DEFAULTED (f, overload_idx));
+         printfi_filtered (spaces + 8, "is_deleted %d\n",
+                           TYPE_FN_FIELD_DELETED (f, overload_idx));
          printfi_filtered (spaces + 8, "voffset %u\n",
                            TYPE_FN_FIELD_VOFFSET (f, overload_idx));
        }
@@ -4318,6 +4570,9 @@ print_cplus_stuff (struct type *type, int spaces)
     {
       dump_fn_fieldlists (type, spaces);
     }
+
+  printfi_filtered (spaces, "calling_convention %d\n",
+                   TYPE_CPLUS_CALLING_CONVENTION (type));
 }
 
 /* Print the contents of the TYPE's type_specific union, assuming that
@@ -4377,10 +4632,6 @@ recursive_dump_type (struct type *type, int spaces)
                    TYPE_NAME (type) ? TYPE_NAME (type) : "<NULL>");
   gdb_print_host_address (TYPE_NAME (type), gdb_stdout);
   printf_filtered (")\n");
-  printfi_filtered (spaces, "tagname '%s' (",
-                   TYPE_TAG_NAME (type) ? TYPE_TAG_NAME (type) : "<NULL>");
-  gdb_print_host_address (TYPE_TAG_NAME (type), gdb_stdout);
-  printf_filtered (")\n");
   printfi_filtered (spaces, "code 0x%x ", TYPE_CODE (type));
   switch (TYPE_CODE (type))
     {
@@ -4461,7 +4712,7 @@ recursive_dump_type (struct type *type, int spaces)
       break;
     }
   puts_filtered ("\n");
-  printfi_filtered (spaces, "length %d\n", TYPE_LENGTH (type));
+  printfi_filtered (spaces, "length %s\n", pulongest (TYPE_LENGTH (type)));
   if (TYPE_OBJFILE_OWNED (type))
     {
       printfi_filtered (spaces, "objfile ");
@@ -4534,6 +4785,10 @@ recursive_dump_type (struct type *type, int spaces)
     {
       puts_filtered (" TYPE_NOSIGN");
     }
+  if (TYPE_ENDIANITY_NOT_DEFAULT (type))
+    {
+      puts_filtered (" TYPE_ENDIANITY_NOT_DEFAULT");
+    }
   if (TYPE_STUB (type))
     {
       puts_filtered (" TYPE_STUB");
@@ -4657,9 +4912,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
@@ -4727,7 +4986,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;
 
@@ -4738,7 +4996,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;
@@ -4747,9 +5006,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
@@ -4760,8 +5019,6 @@ copy_type_recursive (struct objfile *objfile,
 
   if (TYPE_NAME (type))
     TYPE_NAME (new_type) = xstrdup (TYPE_NAME (type));
-  if (TYPE_TAG_NAME (type))
-    TYPE_TAG_NAME (new_type) = xstrdup (TYPE_TAG_NAME (type));
 
   TYPE_INSTANCE_FLAGS (new_type) = TYPE_INSTANCE_FLAGS (type);
   TYPE_LENGTH (new_type) = TYPE_LENGTH (type);
@@ -4772,7 +5029,8 @@ copy_type_recursive (struct objfile *objfile,
       int i, nfields;
 
       nfields = TYPE_NFIELDS (type);
-      TYPE_FIELDS (new_type) = XCNEWVEC (struct field, nfields);
+      TYPE_FIELDS (new_type) = (struct field *)
+        TYPE_ZALLOC (new_type, nfields * sizeof (struct field));
       for (i = 0; i < nfields; i++)
        {
          TYPE_FIELD_ARTIFICIAL (new_type, i) = 
@@ -4815,7 +5073,8 @@ copy_type_recursive (struct objfile *objfile,
   /* For range types, copy the bounds information.  */
   if (TYPE_CODE (type) == TYPE_CODE_RANGE)
     {
-      TYPE_RANGE_DATA (new_type) = XNEW (struct range_bounds);
+      TYPE_RANGE_DATA (new_type) = (struct range_bounds *)
+        TYPE_ALLOC (new_type, sizeof (struct range_bounds));
       *TYPE_RANGE_DATA (new_type) = *TYPE_RANGE_DATA (type);
     }
 
@@ -5099,7 +5358,7 @@ arch_composite_type (struct gdbarch *gdbarch, const char *name,
 
   gdb_assert (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION);
   t = arch_type (gdbarch, code, 0, NULL);
-  TYPE_TAG_NAME (t) = name;
+  TYPE_NAME (t) = name;
   INIT_CPLUS_SPECIFIC (t);
   return t;
 }
@@ -5225,6 +5484,9 @@ gdbtypes_post_init (struct gdbarch *gdbarch)
   builtin_type->builtin_unsigned_long_long
     = arch_integer_type (gdbarch, gdbarch_long_long_bit (gdbarch),
                         1, "unsigned long long");
+  builtin_type->builtin_half
+    = arch_float_type (gdbarch, gdbarch_half_bit (gdbarch),
+                      "half", gdbarch_half_format (gdbarch));
   builtin_type->builtin_float
     = arch_float_type (gdbarch, gdbarch_float_bit (gdbarch),
                       "float", gdbarch_float_format (gdbarch));
@@ -5271,6 +5533,10 @@ gdbtypes_post_init (struct gdbarch *gdbarch)
     = arch_integer_type (gdbarch, 16, 0, "int16_t");
   builtin_type->builtin_uint16
     = arch_integer_type (gdbarch, 16, 1, "uint16_t");
+  builtin_type->builtin_int24
+    = arch_integer_type (gdbarch, 24, 0, "int24_t");
+  builtin_type->builtin_uint24
+    = arch_integer_type (gdbarch, 24, 1, "uint24_t");
   builtin_type->builtin_int32
     = arch_integer_type (gdbarch, 32, 0, "int32_t");
   builtin_type->builtin_uint32
@@ -5320,14 +5586,15 @@ gdbtypes_post_init (struct gdbarch *gdbarch)
 /* This set of objfile-based types is intended to be used by symbol
    readers as basic types.  */
 
-static const struct objfile_data *objfile_type_data;
+static const struct objfile_key<struct objfile_type,
+                               gdb::noop_deleter<struct objfile_type>>
+  objfile_type_data;
 
 const struct objfile_type *
 objfile_type (struct objfile *objfile)
 {
   struct gdbarch *gdbarch;
-  struct objfile_type *objfile_type
-    = (struct objfile_type *) objfile_data (objfile, objfile_type_data);
+  struct objfile_type *objfile_type = objfile_type_data.get (objfile);
 
   if (objfile_type)
     return objfile_type;
@@ -5397,10 +5664,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),
@@ -5436,15 +5699,15 @@ objfile_type (struct objfile *objfile)
     = init_integer_type (objfile, gdbarch_addr_bit (gdbarch), 1,
                         "__CORE_ADDR");
 
-  set_objfile_data (objfile, objfile_type_data, objfile_type);
+  objfile_type_data.set (objfile, objfile_type);
   return objfile_type;
 }
 
+void _initialize_gdbtypes ();
 void
-_initialize_gdbtypes (void)
+_initialize_gdbtypes ()
 {
   gdbtypes_data = gdbarch_data_register_post_init (gdbtypes_post_init);
-  objfile_type_data = register_objfile_data ();
 
   add_setshow_zuinteger_cmd ("overload", no_class, &overload_debug,
                             _("Set debugging of C++ overloading."),