Copy comments from gdbarch.sh to gdbarch.h. Fix a number of K&R params.
[deliverable/binutils-gdb.git] / gdb / gdbtypes.c
index dfb98acb971e069eab48bd33a953c4d7e26bc5da..3fee0cfc64d6a958f7ae9c43da39ee021a2ac561 100644 (file)
@@ -1,25 +1,26 @@
 /* Support routines for manipulating internal types for GDB.
-   Copyright (C) 1992 Free Software Foundation, Inc.
+   Copyright (C) 1992, 93, 94, 95, 96, 1998 Free Software Foundation, Inc.
    Contributed by Cygnus Support, using pieces from other GDB modules.
 
-This file is part of GDB.
+   This file is part of GDB.
 
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
 
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #include "defs.h"
-#include <string.h>
+#include "gdb_string.h"
 #include "bfd.h"
 #include "symtab.h"
 #include "symfile.h"
@@ -30,14 +31,77 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "target.h"
 #include "value.h"
 #include "demangle.h"
+#include "complaints.h"
+#include "gdbcmd.h"
+#include "wrapper.h"
+
+/* These variables point to the objects
+   representing the predefined C data types.  */
+
+struct type *builtin_type_void;
+struct type *builtin_type_char;
+struct type *builtin_type_true_char;
+struct type *builtin_type_short;
+struct type *builtin_type_int;
+struct type *builtin_type_long;
+struct type *builtin_type_long_long;
+struct type *builtin_type_signed_char;
+struct type *builtin_type_unsigned_char;
+struct type *builtin_type_unsigned_short;
+struct type *builtin_type_unsigned_int;
+struct type *builtin_type_unsigned_long;
+struct type *builtin_type_unsigned_long_long;
+struct type *builtin_type_float;
+struct type *builtin_type_double;
+struct type *builtin_type_long_double;
+struct type *builtin_type_complex;
+struct type *builtin_type_double_complex;
+struct type *builtin_type_string;
+struct type *builtin_type_int8;
+struct type *builtin_type_uint8;
+struct type *builtin_type_int16;
+struct type *builtin_type_uint16;
+struct type *builtin_type_int32;
+struct type *builtin_type_uint32;
+struct type *builtin_type_int64;
+struct type *builtin_type_uint64;
+struct type *builtin_type_bool;
+struct type *builtin_type_v4sf;
+struct type *builtin_type_v4si;
+struct type *builtin_type_v8qi;
+struct type *builtin_type_v4hi;
+struct type *builtin_type_v2si;
+struct type *builtin_type_ptr;
+struct type *builtin_type_CORE_ADDR;
+struct type *builtin_type_bfd_vma;
+
+int opaque_type_resolution = 1;
+int overload_debug = 0;
+
+struct extra
+  {
+    char str[128];
+    int len;
+  };                           /* maximum extention is 128! FIXME */
+
+static void add_name (struct extra *, char *);
+static void add_mangled_type (struct extra *, struct type *);
+#if 0
+static void cfront_mangle_name (struct type *, int, int);
+#endif
+static void print_bit_vector (B_TYPE *, int);
+static void print_arg_types (struct type **, int);
+static void dump_fn_fieldlists (struct type *, int);
+static void print_cplus_stuff (struct type *, int);
+static void virtual_base_list_aux (struct type *dclass);
+
 
 /* Alloc a new type structure and fill it with some defaults.  If
    OBJFILE is non-NULL, then allocate the space for the type structure
    in that objfile's type_obstack. */
 
 struct type *
-alloc_type (objfile)
-     struct objfile *objfile;
+alloc_type (struct objfile *objfile)
 {
   register struct type *type;
 
@@ -45,12 +109,13 @@ alloc_type (objfile)
 
   if (objfile == NULL)
     {
-      type  = (struct type *) xmalloc (sizeof (struct type));
+      type = (struct type *) xmalloc (sizeof (struct type));
     }
   else
     {
-      type  = (struct type *) obstack_alloc (&objfile -> type_obstack,
-                                            sizeof (struct type));
+      type = (struct type *) obstack_alloc (&objfile->type_obstack,
+                                           sizeof (struct type));
+      OBJSTAT (objfile, n_types++);
     }
   memset ((char *) type, 0, sizeof (struct type));
 
@@ -59,6 +124,7 @@ alloc_type (objfile)
   TYPE_CODE (type) = TYPE_CODE_UNDEF;
   TYPE_OBJFILE (type) = objfile;
   TYPE_VPTR_FIELDNO (type) = -1;
+  TYPE_CV_TYPE (type) = type;  /* chain back to itself */
 
   return (type);
 }
@@ -69,23 +135,23 @@ alloc_type (objfile)
    We allocate new memory if needed.  */
 
 struct type *
-make_pointer_type (type, typeptr)
-     struct type *type;
-     struct type **typeptr;
+make_pointer_type (struct type *type, struct type **typeptr)
 {
-  register struct type *ntype;         /* New type */
+  register struct type *ntype; /* New type */
   struct objfile *objfile;
 
   ntype = TYPE_POINTER_TYPE (type);
 
-  if (ntype) 
-    if (typeptr == 0)          
-      return ntype;    /* Don't care about alloc, and have new type.  */
-    else if (*typeptr == 0)
-      {
-       *typeptr = ntype;       /* Tracking alloc, and we have new type.  */
-       return ntype;
-      }
+  if (ntype)
+    {
+      if (typeptr == 0)
+       return ntype;           /* Don't care about alloc, and have new type.  */
+      else if (*typeptr == 0)
+       {
+         *typeptr = ntype;     /* Tracking alloc, and we have new type.  */
+         return ntype;
+       }
+    }
 
   if (typeptr == 0 || *typeptr == 0)   /* We'll need to allocate one.  */
     {
@@ -93,7 +159,8 @@ make_pointer_type (type, typeptr)
       if (typeptr)
        *typeptr = ntype;
     }
-  else                         /* We have storage, but need to reset it.  */
+  else
+    /* We have storage, but need to reset it.  */
     {
       ntype = *typeptr;
       objfile = TYPE_OBJFILE (ntype);
@@ -109,9 +176,11 @@ make_pointer_type (type, typeptr)
   TYPE_LENGTH (ntype) = TARGET_PTR_BIT / TARGET_CHAR_BIT;
   TYPE_CODE (ntype) = TYPE_CODE_PTR;
 
-  /* pointers are unsigned */
+  /* Mark pointers as unsigned.  The target converts between pointers
+     and addresses (CORE_ADDRs) using POINTER_TO_ADDRESS() and
+     ADDRESS_TO_POINTER(). */
   TYPE_FLAGS (ntype) |= TYPE_FLAG_UNSIGNED;
-  
+
   if (!TYPE_POINTER_TYPE (type))       /* Remember it, if don't have one.  */
     TYPE_POINTER_TYPE (type) = ntype;
 
@@ -122,10 +191,9 @@ make_pointer_type (type, typeptr)
    May need to construct such a type if this is the first use.  */
 
 struct type *
-lookup_pointer_type (type)
-     struct type *type;
+lookup_pointer_type (struct type *type)
 {
-  return make_pointer_type (type, (struct type **)0);
+  return make_pointer_type (type, (struct type **) 0);
 }
 
 /* Lookup a C++ `reference' to a type TYPE.  TYPEPTR, if nonzero, points
@@ -134,23 +202,23 @@ lookup_pointer_type (type)
    We allocate new memory if needed.  */
 
 struct type *
-make_reference_type (type, typeptr)
-     struct type *type;
-     struct type **typeptr;
+make_reference_type (struct type *type, struct type **typeptr)
 {
-  register struct type *ntype;         /* New type */
+  register struct type *ntype; /* New type */
   struct objfile *objfile;
 
   ntype = TYPE_REFERENCE_TYPE (type);
 
-  if (ntype) 
-    if (typeptr == 0)          
-      return ntype;    /* Don't care about alloc, and have new type.  */
-    else if (*typeptr == 0)
-      {
-       *typeptr = ntype;       /* Tracking alloc, and we have new type.  */
-       return ntype;
-      }
+  if (ntype)
+    {
+      if (typeptr == 0)
+       return ntype;           /* Don't care about alloc, and have new type.  */
+      else if (*typeptr == 0)
+       {
+         *typeptr = ntype;     /* Tracking alloc, and we have new type.  */
+         return ntype;
+       }
+    }
 
   if (typeptr == 0 || *typeptr == 0)   /* We'll need to allocate one.  */
     {
@@ -158,7 +226,8 @@ make_reference_type (type, typeptr)
       if (typeptr)
        *typeptr = ntype;
     }
-  else                         /* We have storage, but need to reset it.  */
+  else
+    /* We have storage, but need to reset it.  */
     {
       ntype = *typeptr;
       objfile = TYPE_OBJFILE (ntype);
@@ -174,7 +243,7 @@ make_reference_type (type, typeptr)
 
   TYPE_LENGTH (ntype) = TARGET_PTR_BIT / TARGET_CHAR_BIT;
   TYPE_CODE (ntype) = TYPE_CODE_REF;
-  
+
   if (!TYPE_REFERENCE_TYPE (type))     /* Remember it, if don't have one.  */
     TYPE_REFERENCE_TYPE (type) = ntype;
 
@@ -184,10 +253,9 @@ make_reference_type (type, typeptr)
 /* Same as above, but caller doesn't care about memory allocation details.  */
 
 struct type *
-lookup_reference_type (type)
-     struct type *type;
+lookup_reference_type (struct type *type)
 {
-  return make_reference_type (type, (struct type **)0);
+  return make_reference_type (type, (struct type **) 0);
 }
 
 /* Lookup a function type that returns type TYPE.  TYPEPTR, if nonzero, points
@@ -196,31 +264,19 @@ lookup_reference_type (type)
    We allocate new memory if needed.  */
 
 struct type *
-make_function_type (type, typeptr)
-     struct type *type;
-     struct type **typeptr;
+make_function_type (struct type *type, struct type **typeptr)
 {
-  register struct type *ntype;         /* New type */
+  register struct type *ntype; /* New type */
   struct objfile *objfile;
 
-  ntype = TYPE_FUNCTION_TYPE (type);
-
-  if (ntype) 
-    if (typeptr == 0)          
-      return ntype;    /* Don't care about alloc, and have new type.  */
-    else if (*typeptr == 0)
-      {
-       *typeptr = ntype;       /* Tracking alloc, and we have new type.  */
-       return ntype;
-      }
-
   if (typeptr == 0 || *typeptr == 0)   /* We'll need to allocate one.  */
     {
       ntype = alloc_type (TYPE_OBJFILE (type));
       if (typeptr)
        *typeptr = ntype;
     }
-  else                         /* We have storage, but need to reset it.  */
+  else
+    /* We have storage, but need to reset it.  */
     {
       ntype = *typeptr;
       objfile = TYPE_OBJFILE (ntype);
@@ -229,13 +285,9 @@ make_function_type (type, typeptr)
     }
 
   TYPE_TARGET_TYPE (ntype) = type;
-  TYPE_FUNCTION_TYPE (type) = ntype;
 
   TYPE_LENGTH (ntype) = 1;
   TYPE_CODE (ntype) = TYPE_CODE_FUNC;
-  
-  if (!TYPE_FUNCTION_TYPE (type))      /* Remember it, if don't have one.  */
-    TYPE_FUNCTION_TYPE (type) = ntype;
 
   return ntype;
 }
@@ -245,21 +297,98 @@ make_function_type (type, typeptr)
    May need to construct such a type if this is the first use.  */
 
 struct type *
-lookup_function_type (type)
-     struct type *type;
+lookup_function_type (struct type *type)
+{
+  return make_function_type (type, (struct type **) 0);
+}
+
+
+/* Make a "c-v" variant of a type -- a type that is identical to the
+   one supplied except that it may have const or volatile attributes
+   CNST is a flag for setting the const attribute
+   VOLTL is a flag for setting the volatile attribute
+   TYPE is the base type whose variant we are creating.
+   TYPEPTR, if nonzero, points
+   to a pointer to memory where the reference type should be stored.
+   If *TYPEPTR is zero, update it to point to the reference type we return.
+   We allocate new memory if needed.  */
+
+struct type *
+make_cv_type (int cnst, int voltl, struct type *type, struct type **typeptr)
 {
-  return make_function_type (type, (struct type **)0);
+  register struct type *ntype; /* New type */
+  register struct type *tmp_type = type;       /* tmp type */
+  struct objfile *objfile;
+
+  ntype = TYPE_CV_TYPE (type);
+
+  while (ntype != type)
+    {
+      if ((TYPE_CONST (ntype) == cnst) &&
+         (TYPE_VOLATILE (ntype) == voltl))
+       {
+         if (typeptr == 0)
+           return ntype;
+         else if (*typeptr == 0)
+           {
+             *typeptr = ntype; /* Tracking alloc, and we have new type.  */
+             return ntype;
+           }
+       }
+      tmp_type = ntype;
+      ntype = TYPE_CV_TYPE (ntype);
+    }
+
+  if (typeptr == 0 || *typeptr == 0)   /* We'll need to allocate one.  */
+    {
+      ntype = alloc_type (TYPE_OBJFILE (type));
+      if (typeptr)
+       *typeptr = ntype;
+    }
+  else
+    /* We have storage, but need to reset it.  */
+    {
+      ntype = *typeptr;
+      objfile = TYPE_OBJFILE (ntype);
+      /* memset ((char *) ntype, 0, sizeof (struct type)); */
+      TYPE_OBJFILE (ntype) = objfile;
+    }
+
+  /* Copy original type */
+  memcpy ((char *) ntype, (char *) type, sizeof (struct type));
+  /* But zero out fields that shouldn't be copied */
+  TYPE_POINTER_TYPE (ntype) = (struct type *) 0;       /* Need new pointer kind */
+  TYPE_REFERENCE_TYPE (ntype) = (struct type *) 0;     /* Need new referene kind */
+  /* Note: TYPE_TARGET_TYPE can be left as is */
+
+  /* Set flags appropriately */
+  if (cnst)
+    TYPE_FLAGS (ntype) |= TYPE_FLAG_CONST;
+  else
+    TYPE_FLAGS (ntype) &= ~TYPE_FLAG_CONST;
+
+  if (voltl)
+    TYPE_FLAGS (ntype) |= TYPE_FLAG_VOLATILE;
+  else
+    TYPE_FLAGS (ntype) &= ~TYPE_FLAG_VOLATILE;
+
+  /* Fix the chain of cv variants */
+  TYPE_CV_TYPE (ntype) = type;
+  TYPE_CV_TYPE (tmp_type) = ntype;
+
+  return ntype;
 }
 
+
+
+
 /* Implement direct support for MEMBER_TYPE in GNU C++.
    May need to construct such a type if this is the first use.
    The TYPE is the type of the member.  The DOMAIN is the type
    of the aggregate that the member belongs to.  */
 
 struct type *
-lookup_member_type (type, domain)
-     struct type *type;
-     struct type *domain;
+lookup_member_type (struct type *type, struct type *domain)
 {
   register struct type *mtype;
 
@@ -275,8 +404,7 @@ lookup_member_type (type, domain)
    This always returns a fresh type.   */
 
 struct type *
-allocate_stub_method (type)
-     struct type *type;
+allocate_stub_method (struct type *type)
 {
   struct type *mtype;
 
@@ -290,56 +418,242 @@ allocate_stub_method (type)
   return (mtype);
 }
 
-/* Create an array type.  Elements will be of type TYPE, and there will
-   be NUM of them.
+/* Create a range type using either a blank type supplied in RESULT_TYPE,
+   or creating a new type, inheriting the objfile from INDEX_TYPE.
+
+   Indices will be of type INDEX_TYPE, and will range from LOW_BOUND to
+   HIGH_BOUND, inclusive.
 
-   Eventually this should be extended to take two more arguments which
-   specify the bounds of the array and the type of the index.
-   It should also be changed to be a "lookup" function, with the
-   appropriate data structures added to the type field.
-   Then read array type should call here.  */
+   FIXME:  Maybe we should check the TYPE_CODE of RESULT_TYPE to make
+   sure it is TYPE_CODE_UNDEF before we bash it into a range type? */
 
 struct type *
-create_array_type (element_type, number)
-     struct type *element_type;
-     int number;
+create_range_type (struct type *result_type, struct type *index_type,
+                  int low_bound, int high_bound)
+{
+  if (result_type == NULL)
+    {
+      result_type = alloc_type (TYPE_OBJFILE (index_type));
+    }
+  TYPE_CODE (result_type) = TYPE_CODE_RANGE;
+  TYPE_TARGET_TYPE (result_type) = index_type;
+  if (TYPE_FLAGS (index_type) & TYPE_FLAG_STUB)
+    TYPE_FLAGS (result_type) |= TYPE_FLAG_TARGET_STUB;
+  else
+    TYPE_LENGTH (result_type) = TYPE_LENGTH (check_typedef (index_type));
+  TYPE_NFIELDS (result_type) = 2;
+  TYPE_FIELDS (result_type) = (struct field *)
+    TYPE_ALLOC (result_type, 2 * sizeof (struct field));
+  memset (TYPE_FIELDS (result_type), 0, 2 * sizeof (struct field));
+  TYPE_FIELD_BITPOS (result_type, 0) = low_bound;
+  TYPE_FIELD_BITPOS (result_type, 1) = high_bound;
+  TYPE_FIELD_TYPE (result_type, 0) = builtin_type_int; /* FIXME */
+  TYPE_FIELD_TYPE (result_type, 1) = builtin_type_int; /* FIXME */
+
+  if (low_bound >= 0)
+    TYPE_FLAGS (result_type) |= TYPE_FLAG_UNSIGNED;
+
+  return (result_type);
+}
+
+/* Set *LOWP and *HIGHP to the lower and upper bounds of discrete type TYPE.
+   Return 1 of type is a range type, 0 if it is discrete (and bounds
+   will fit in LONGEST), or -1 otherwise. */
+
+int
+get_discrete_bounds (struct type *type, LONGEST *lowp, LONGEST *highp)
 {
-  struct type *result_type;
-  struct type *range_type;
+  CHECK_TYPEDEF (type);
+  switch (TYPE_CODE (type))
+    {
+    case TYPE_CODE_RANGE:
+      *lowp = TYPE_LOW_BOUND (type);
+      *highp = TYPE_HIGH_BOUND (type);
+      return 1;
+    case TYPE_CODE_ENUM:
+      if (TYPE_NFIELDS (type) > 0)
+       {
+         /* The enums may not be sorted by value, so search all
+            entries */
+         int i;
+
+         *lowp = *highp = TYPE_FIELD_BITPOS (type, 0);
+         for (i = 0; i < TYPE_NFIELDS (type); i++)
+           {
+             if (TYPE_FIELD_BITPOS (type, i) < *lowp)
+               *lowp = TYPE_FIELD_BITPOS (type, i);
+             if (TYPE_FIELD_BITPOS (type, i) > *highp)
+               *highp = TYPE_FIELD_BITPOS (type, i);
+           }
+
+         /* Set unsigned indicator if warranted. */
+         if (*lowp >= 0)
+           {
+             TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED;
+           }
+       }
+      else
+       {
+         *lowp = 0;
+         *highp = -1;
+       }
+      return 0;
+    case TYPE_CODE_BOOL:
+      *lowp = 0;
+      *highp = 1;
+      return 0;
+    case TYPE_CODE_INT:
+      if (TYPE_LENGTH (type) > sizeof (LONGEST))       /* Too big */
+       return -1;
+      if (!TYPE_UNSIGNED (type))
+       {
+         *lowp = -(1 << (TYPE_LENGTH (type) * TARGET_CHAR_BIT - 1));
+         *highp = -*lowp - 1;
+         return 0;
+       }
+      /* ... fall through for unsigned ints ... */
+    case TYPE_CODE_CHAR:
+      *lowp = 0;
+      /* This round-about calculation is to avoid shifting by
+         TYPE_LENGTH (type) * TARGET_CHAR_BIT, which will not work
+         if TYPE_LENGTH (type) == sizeof (LONGEST). */
+      *highp = 1 << (TYPE_LENGTH (type) * TARGET_CHAR_BIT - 1);
+      *highp = (*highp - 1) | *highp;
+      return 0;
+    default:
+      return -1;
+    }
+}
+
+/* Create an array type using either a blank type supplied in RESULT_TYPE,
+   or creating a new type, inheriting the objfile from RANGE_TYPE.
+
+   Elements will be of type ELEMENT_TYPE, the indices will be of type
+   RANGE_TYPE.
 
-  result_type = alloc_type (TYPE_OBJFILE (element_type));
+   FIXME:  Maybe we should check the TYPE_CODE of RESULT_TYPE to make
+   sure it is TYPE_CODE_UNDEF before we bash it into an array type? */
 
+struct type *
+create_array_type (struct type *result_type, struct type *element_type,
+                  struct type *range_type)
+{
+  LONGEST low_bound, high_bound;
+
+  if (result_type == NULL)
+    {
+      result_type = alloc_type (TYPE_OBJFILE (range_type));
+    }
   TYPE_CODE (result_type) = TYPE_CODE_ARRAY;
   TYPE_TARGET_TYPE (result_type) = element_type;
-  TYPE_LENGTH (result_type) = number * TYPE_LENGTH (element_type);
+  if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
+    low_bound = high_bound = 0;
+  CHECK_TYPEDEF (element_type);
+  TYPE_LENGTH (result_type) =
+    TYPE_LENGTH (element_type) * (high_bound - low_bound + 1);
   TYPE_NFIELDS (result_type) = 1;
-  TYPE_FIELDS (result_type) = (struct field *)
-    TYPE_ALLOC (result_type, sizeof (struct field));
-
-  {
-    /* Create range type.  */
-    range_type = alloc_type (TYPE_OBJFILE (result_type));
-    TYPE_CODE (range_type) = TYPE_CODE_RANGE;
-    TYPE_TARGET_TYPE (range_type) = builtin_type_int;  /* FIXME */
-
-    /* This should never be needed.  */
-    TYPE_LENGTH (range_type) = sizeof (int);
-
-    TYPE_NFIELDS (range_type) = 2;
-    TYPE_FIELDS (range_type) = (struct field *)
-      TYPE_ALLOC (range_type, 2 * sizeof (struct field));
-    TYPE_FIELD_BITPOS (range_type, 0) = 0; /* FIXME */
-    TYPE_FIELD_BITPOS (range_type, 1) = number-1; /* FIXME */
-    TYPE_FIELD_TYPE (range_type, 0) = builtin_type_int; /* FIXME */
-    TYPE_FIELD_TYPE (range_type, 1) = builtin_type_int; /* FIXME */
-  }
+  TYPE_FIELDS (result_type) =
+    (struct field *) TYPE_ALLOC (result_type, sizeof (struct field));
+  memset (TYPE_FIELDS (result_type), 0, sizeof (struct field));
   TYPE_FIELD_TYPE (result_type, 0) = range_type;
   TYPE_VPTR_FIELDNO (result_type) = -1;
 
+  /* TYPE_FLAG_TARGET_STUB will take care of zero length arrays */
+  if (TYPE_LENGTH (result_type) == 0)
+    TYPE_FLAGS (result_type) |= TYPE_FLAG_TARGET_STUB;
+
+  return (result_type);
+}
+
+/* Create a string type using either a blank type supplied in RESULT_TYPE,
+   or creating a new type.  String types are similar enough to array of
+   char types that we can use create_array_type to build the basic type
+   and then bash it into a string type.
+
+   For fixed length strings, the range type contains 0 as the lower
+   bound and the length of the string minus one as the upper bound.
+
+   FIXME:  Maybe we should check the TYPE_CODE of RESULT_TYPE to make
+   sure it is TYPE_CODE_UNDEF before we bash it into a string type? */
+
+struct type *
+create_string_type (struct type *result_type, struct type *range_type)
+{
+  result_type = create_array_type (result_type,
+                                  *current_language->string_char_type,
+                                  range_type);
+  TYPE_CODE (result_type) = TYPE_CODE_STRING;
+  return (result_type);
+}
+
+struct type *
+create_set_type (struct type *result_type, struct type *domain_type)
+{
+  LONGEST low_bound, high_bound, bit_length;
+  if (result_type == NULL)
+    {
+      result_type = alloc_type (TYPE_OBJFILE (domain_type));
+    }
+  TYPE_CODE (result_type) = TYPE_CODE_SET;
+  TYPE_NFIELDS (result_type) = 1;
+  TYPE_FIELDS (result_type) = (struct field *)
+    TYPE_ALLOC (result_type, 1 * sizeof (struct field));
+  memset (TYPE_FIELDS (result_type), 0, sizeof (struct field));
+
+  if (!(TYPE_FLAGS (domain_type) & TYPE_FLAG_STUB))
+    {
+      if (get_discrete_bounds (domain_type, &low_bound, &high_bound) < 0)
+       low_bound = high_bound = 0;
+      bit_length = high_bound - low_bound + 1;
+      TYPE_LENGTH (result_type)
+       = (bit_length + TARGET_CHAR_BIT - 1) / TARGET_CHAR_BIT;
+    }
+  TYPE_FIELD_TYPE (result_type, 0) = domain_type;
+
+  if (low_bound >= 0)
+    TYPE_FLAGS (result_type) |= TYPE_FLAG_UNSIGNED;
+
   return (result_type);
 }
 
 
+/* Construct and return a type of the form:
+       struct NAME { ELT_TYPE ELT_NAME[N]; }
+   We use these types for SIMD registers.  For example, the type of
+   the SSE registers on the late x86-family processors is:
+       struct __builtin_v4sf { float f[4]; }
+   built by the function call:
+       init_simd_type ("__builtin_v4sf", builtin_type_float, "f", 4)
+   The type returned is a permanent type, allocated using malloc; it
+   doesn't live in any objfile's obstack.  */
+static struct type *
+init_simd_type (char *name,
+               struct type *elt_type,
+               char *elt_name,
+               int n)
+{
+  struct type *t;
+  struct field *f;
+
+  /* Build the field structure.  */
+  f = xmalloc (sizeof (*f));
+  memset (f, 0, sizeof (*f));
+  f->loc.bitpos = 0;
+  f->type = create_array_type (0, elt_type,
+                              create_range_type (0, builtin_type_int,
+                                                 0, n-1));
+  f->name = elt_name;
+
+  /* Build a struct type with that field.  */
+  t = init_type (TYPE_CODE_STRUCT, n * TYPE_LENGTH (elt_type), 0, 0, 0);
+  t->nfields = 1;
+  t->fields = f;
+  t->tag_name = name;
+
+  return t;
+}
+
+
 /* Smash TYPE to be a type of members of DOMAIN with type TO_TYPE. 
    A MEMBER is a wierd thing -- it amounts to a typed offset into
    a struct, e.g. "an int at offset 8".  A MEMBER TYPE doesn't
@@ -351,10 +665,8 @@ create_array_type (element_type, number)
    allocated.  */
 
 void
-smash_to_member_type (type, domain, to_type)
-     struct type *type;
-     struct type *domain;
-     struct type *to_type;
+smash_to_member_type (struct type *type, struct type *domain,
+                     struct type *to_type)
 {
   struct objfile *objfile;
 
@@ -376,11 +688,8 @@ smash_to_member_type (type, domain, to_type)
    allocated.  */
 
 void
-smash_to_method_type (type, domain, to_type, args)
-     struct type *type;
-     struct type *domain;
-     struct type *to_type;
-     struct type **args;
+smash_to_method_type (struct type *type, struct type *domain,
+                     struct type *to_type, struct type **args)
 {
   struct objfile *objfile;
 
@@ -395,62 +704,37 @@ smash_to_method_type (type, domain, to_type, args)
   TYPE_CODE (type) = TYPE_CODE_METHOD;
 }
 
-/* Return a typename for a struct/union/enum type
-   without the tag qualifier.  If the type has a NULL name,
-   NULL is returned.  */
+/* Return a typename for a struct/union/enum type without "struct ",
+   "union ", or "enum ".  If the type has a NULL name, return NULL.  */
 
 char *
-type_name_no_tag (type)
-     register const struct type *type;
+type_name_no_tag (register const struct type *type)
 {
-  register char *name;
+  if (TYPE_TAG_NAME (type) != NULL)
+    return TYPE_TAG_NAME (type);
 
-  if ((name = TYPE_NAME (type)) != NULL)
-    {
-      switch (TYPE_CODE (type))
-       {
-         case TYPE_CODE_STRUCT:
-           if(!strncmp (name, "struct ", 7))
-             {
-               name += 7;
-             }
-           break;
-         case TYPE_CODE_UNION:
-           if(!strncmp (name, "union ", 6))
-             {
-               name += 6;
-             }
-           break;
-         case TYPE_CODE_ENUM:
-           if(!strncmp (name, "enum ", 5))
-             {
-               name += 5;
-             }
-           break;
-         default:              /* To avoid -Wall warnings */
-           break;
-       }
-    }
-  return (name);
+  /* 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);
 }
 
 /* Lookup a primitive type named NAME. 
-   Return zero if NAME is not a primitive type.*/
+   Return zero if NAME is not a primitive type. */
 
 struct type *
-lookup_primitive_typename (name)
-     char *name;
+lookup_primitive_typename (char *name)
 {
-   struct type ** const *p;
-
-   for (p = current_language -> la_builtin_type_vector; *p != NULL; p++)
-     {
-       if (!strcmp ((**p) -> name, name))
-        {
-          return (**p);
-        }
-     }
-   return (NULL); 
+  struct type **const *p;
+
+  for (p = current_language->la_builtin_type_vector; *p != NULL; p++)
+    {
+      if (STREQ ((**p)->name, name))
+       {
+         return (**p);
+       }
+    }
+  return (NULL);
 }
 
 /* Lookup a typedef or primitive type named NAME,
@@ -458,10 +742,7 @@ lookup_primitive_typename (name)
    If NOERR is nonzero, return zero if NAME is not suitably defined.  */
 
 struct type *
-lookup_typename (name, block, noerr)
-     char *name;
-     struct block *block;
-     int noerr;
+lookup_typename (char *name, struct block *block, int noerr)
 {
   register struct symbol *sym;
   register struct type *tmp;
@@ -487,8 +768,7 @@ lookup_typename (name, block, noerr)
 }
 
 struct type *
-lookup_unsigned_typename (name)
-     char *name;
+lookup_unsigned_typename (char *name)
 {
   char *uns = alloca (strlen (name) + 10);
 
@@ -498,8 +778,7 @@ lookup_unsigned_typename (name)
 }
 
 struct type *
-lookup_signed_typename (name)
-     char *name;
+lookup_signed_typename (char *name)
 {
   struct type *t;
   char *uns = alloca (strlen (name) + 8);
@@ -517,9 +796,7 @@ lookup_signed_typename (name)
    visible in lexical block BLOCK.  */
 
 struct type *
-lookup_struct (name, block)
-     char *name;
-     struct block *block;
+lookup_struct (char *name, struct block *block)
 {
   register struct symbol *sym;
 
@@ -541,37 +818,43 @@ lookup_struct (name, block)
    visible in lexical block BLOCK.  */
 
 struct type *
-lookup_union (name, block)
-     char *name;
-     struct block *block;
+lookup_union (char *name, struct block *block)
 {
   register struct symbol *sym;
+  struct type *t;
 
   sym = lookup_symbol (name, block, STRUCT_NAMESPACE, 0,
                       (struct symtab **) NULL);
 
   if (sym == NULL)
-    {
-      error ("No union type named %s.", name);
-    }
-  if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_UNION)
-    {
-      error ("This context has class, struct or enum %s, not a union.", name);
-    }
-  return (SYMBOL_TYPE (sym));
+    error ("No union type named %s.", name);
+
+  t = SYMBOL_TYPE (sym);
+
+  if (TYPE_CODE (t) == TYPE_CODE_UNION)
+    return (t);
+
+  /* C++ unions may come out with TYPE_CODE_CLASS, but we look at
+   * a further "declared_type" field to discover it is really a union.
+   */
+  if (HAVE_CPLUS_STRUCT (t))
+    if (TYPE_DECLARED_TYPE (t) == DECLARED_TYPE_UNION)
+      return (t);
+
+  /* If we get here, it's not a union */
+  error ("This context has class, struct or enum %s, not a union.", name);
 }
 
+
 /* Lookup an enum type named "enum NAME",
    visible in lexical block BLOCK.  */
 
 struct type *
-lookup_enum (name, block)
-     char *name;
-     struct block *block;
+lookup_enum (char *name, struct block *block)
 {
   register struct symbol *sym;
 
-  sym = lookup_symbol (name, block, STRUCT_NAMESPACE, 0, 
+  sym = lookup_symbol (name, block, STRUCT_NAMESPACE, 0,
                       (struct symtab **) NULL);
   if (sym == NULL)
     {
@@ -588,19 +871,16 @@ lookup_enum (name, block)
    visible in lexical block BLOCK.  */
 
 struct type *
-lookup_template_type (name, type, block)
-     char *name;
-     struct type *type;
-     struct block *block;
+lookup_template_type (char *name, struct type *type, struct block *block)
 {
   struct symbol *sym;
-  char *nam = (char*) alloca(strlen(name) + strlen(type->name) + 4);
+  char *nam = (char *) alloca (strlen (name) + strlen (type->name) + 4);
   strcpy (nam, name);
   strcat (nam, "<");
   strcat (nam, type->name);
-  strcat (nam, " >");  /* FIXME, extra space still introduced in gcc? */
+  strcat (nam, " >");          /* FIXME, extra space still introduced in gcc? */
 
-  sym = lookup_symbol (nam, block, VAR_NAMESPACE, 0, (struct symtab **)NULL);
+  sym = lookup_symbol (nam, block, VAR_NAMESPACE, 0, (struct symtab **) NULL);
 
   if (sym == NULL)
     {
@@ -613,39 +893,59 @@ lookup_template_type (name, type, block)
   return (SYMBOL_TYPE (sym));
 }
 
-/* Given a type TYPE, lookup the type of the component of type named
-   NAME.  
-   If NOERR is nonzero, return zero if NAME is not suitably defined.  */
+/* 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.  */
 
 struct type *
-lookup_struct_elt_type (type, name, noerr)
-     struct type *type;
-     char *name;
-    int noerr;
+lookup_struct_elt_type (struct type *type, char *name, int noerr)
 {
   int i;
 
-  if (TYPE_CODE (type) == TYPE_CODE_PTR ||
-      TYPE_CODE (type) == TYPE_CODE_REF)
+  for (;;)
+    {
+      CHECK_TYPEDEF (type);
+      if (TYPE_CODE (type) != TYPE_CODE_PTR
+         && TYPE_CODE (type) != TYPE_CODE_REF)
+       break;
       type = TYPE_TARGET_TYPE (type);
+    }
 
   if (TYPE_CODE (type) != TYPE_CODE_STRUCT &&
       TYPE_CODE (type) != TYPE_CODE_UNION)
     {
       target_terminal_ours ();
-      fflush (stdout);
-      fprintf (stderr, "Type ");
-      type_print (type, "", stderr, -1);
+      gdb_flush (gdb_stdout);
+      fprintf_unfiltered (gdb_stderr, "Type ");
+      type_print (type, "", gdb_stderr, -1);
       error (" is not a structure or union type.");
     }
 
-  check_stub_type (type);
+#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 *typename;
+
+    typename = type_name_no_tag (type);
+    if (typename != NULL && STREQ (typename, name))
+      return type;
+  }
+#endif
 
   for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--)
     {
       char *t_field_name = TYPE_FIELD_NAME (type, i);
 
-      if (t_field_name && !strcmp (t_field_name, name))
+      if (t_field_name && (strcmp_iw (t_field_name, name) == 0))
        {
          return TYPE_FIELD_TYPE (type, i);
        }
@@ -656,7 +956,7 @@ lookup_struct_elt_type (type, name, noerr)
     {
       struct type *t;
 
-      t = lookup_struct_elt_type (TYPE_BASECLASS (type, i), name, 0);
+      t = lookup_struct_elt_type (TYPE_BASECLASS (type, i), name, noerr);
       if (t != NULL)
        {
          return t;
@@ -667,28 +967,36 @@ lookup_struct_elt_type (type, name, noerr)
     {
       return NULL;
     }
-  
+
   target_terminal_ours ();
-  fflush (stdout);
-  fprintf (stderr, "Type ");
-  type_print (type, "", stderr, -1);
-  fprintf (stderr, " has no component named ");
-  fputs_filtered (name, stderr);
+  gdb_flush (gdb_stdout);
+  fprintf_unfiltered (gdb_stderr, "Type ");
+  type_print (type, "", gdb_stderr, -1);
+  fprintf_unfiltered (gdb_stderr, " has no component named ");
+  fputs_filtered (name, gdb_stderr);
   error (".");
-  return (struct type *)-1;    /* For lint */
+  return (struct type *) -1;   /* For lint */
 }
 
-/* This function is really horrible, but to avoid it, there would need
-   to be more filling in of forward references.  */
+/* If possible, make the vptr_fieldno and vptr_basetype fields of TYPE
+   valid.  Callers should be aware that in some cases (for example,
+   the type or one of its baseclasses is a stub type and we are
+   debugging a .o file), this function will not be able to find the virtual
+   function table pointer, and vptr_fieldno will remain -1 and vptr_basetype
+   will remain NULL.  */
 
 void
-fill_in_vptr_fieldno (type)
-     struct type *type;
+fill_in_vptr_fieldno (struct type *type)
 {
+  CHECK_TYPEDEF (type);
+
   if (TYPE_VPTR_FIELDNO (type) < 0)
     {
       int i;
-      for (i = 1; i < TYPE_N_BASECLASSES (type); i++)
+
+      /* We must start at zero in case the first (and only) baseclass is
+         virtual (and hence we cannot share the table pointer).  */
+      for (i = 0; i < TYPE_N_BASECLASSES (type); i++)
        {
          fill_in_vptr_fieldno (TYPE_BASECLASS (type, i));
          if (TYPE_VPTR_FIELDNO (TYPE_BASECLASS (type, i)) >= 0)
@@ -703,121 +1011,462 @@ fill_in_vptr_fieldno (type)
     }
 }
 
+/* Find the method and field indices for the destructor in class type T.
+   Return 1 if the destructor was found, otherwise, return 0.  */
+
+int
+get_destructor_fn_field (struct type *t, int *method_indexp, int *field_indexp)
+{
+  int i;
+
+  for (i = 0; i < TYPE_NFN_FIELDS (t); i++)
+    {
+      int j;
+      struct fn_field *f = TYPE_FN_FIELDLIST1 (t, i);
+
+      for (j = 0; j < TYPE_FN_FIELDLIST_LENGTH (t, i); j++)
+       {
+         if (DESTRUCTOR_PREFIX_P (TYPE_FN_FIELD_PHYSNAME (f, j)))
+           {
+             *method_indexp = i;
+             *field_indexp = j;
+             return 1;
+           }
+       }
+    }
+  return 0;
+}
+
 /* Added by Bryan Boreham, Kewill, Sun Sep 17 18:07:17 1989.
 
    If this is a stubbed struct (i.e. declared as struct foo *), see if
    we can find a full definition in some other file. If so, copy this
-   definition, so we can use it in future.  If not, set a flag so we 
-   don't waste too much time in future.  (FIXME, this doesn't seem
-   to be happening...)
+   definition, so we can use it in future.  There used to be a comment (but
+   not any code) that if we don't find a full definition, we'd set a flag
+   so we don't spend time in the future checking the same type.  That would
+   be a mistake, though--we might load in more symbols which contain a
+   full definition for the type.
 
    This used to be coded as a macro, but I don't think it is called 
-   often enough to merit such treatment.
-*/
+   often enough to merit such treatment.  */
 
 struct complaint stub_noname_complaint =
-  {"stub type has NULL name", 0, 0};
+{"stub type has NULL name", 0, 0};
 
-void 
-check_stub_type (type)
-     struct type *type;
+struct type *
+check_typedef (register struct type *type)
 {
-  if (TYPE_FLAGS(type) & TYPE_FLAG_STUB)
+  struct type *orig_type = type;
+  while (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
+    {
+      if (!TYPE_TARGET_TYPE (type))
+       {
+         char *name;
+         struct symbol *sym;
+
+         /* It is dangerous to call lookup_symbol if we are currently
+            reading a symtab.  Infinite recursion is one danger. */
+         if (currently_reading_symtab)
+           return type;
+
+         name = type_name_no_tag (type);
+         /* FIXME: shouldn't we separately check the TYPE_NAME and the
+            TYPE_TAG_NAME, and look in STRUCT_NAMESPACE and/or VAR_NAMESPACE
+            as appropriate?  (this code was written before TYPE_NAME and
+            TYPE_TAG_NAME were separate).  */
+         if (name == NULL)
+           {
+             complain (&stub_noname_complaint);
+             return type;
+           }
+         sym = lookup_symbol (name, 0, STRUCT_NAMESPACE, 0,
+                              (struct symtab **) NULL);
+         if (sym)
+           TYPE_TARGET_TYPE (type) = SYMBOL_TYPE (sym);
+         else
+           TYPE_TARGET_TYPE (type) = alloc_type (NULL);        /* TYPE_CODE_UNDEF */
+       }
+      type = TYPE_TARGET_TYPE (type);
+    }
+
+  /* If this is a struct/class/union with no fields, then check whether a
+     full definition exists somewhere else.  This is for systems where a
+     type definition with no fields is issued for such types, instead of
+     identifying them as stub types in the first place */
+
+  if (TYPE_IS_OPAQUE (type) && opaque_type_resolution && !currently_reading_symtab)
+    {
+      char *name = type_name_no_tag (type);
+      struct type *newtype;
+      if (name == NULL)
+       {
+         complain (&stub_noname_complaint);
+         return type;
+       }
+      newtype = lookup_transparent_type (name);
+      if (newtype)
+       {
+         memcpy ((char *) type, (char *) newtype, sizeof (struct type));
+       }
+    }
+  /* Otherwise, rely on the stub flag being set for opaque/stubbed types */
+  else if ((TYPE_FLAGS (type) & TYPE_FLAG_STUB) && !currently_reading_symtab)
     {
-      char* name = type_name_no_tag (type);
+      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_NAMESPACE and/or VAR_NAMESPACE
+         as appropriate?  (this code was written before TYPE_NAME and
+         TYPE_TAG_NAME were separate).  */
       struct symbol *sym;
       if (name == NULL)
        {
-         complain (&stub_noname_complaint, 0);
-         return;
+         complain (&stub_noname_complaint);
+         return type;
        }
-      sym = lookup_symbol (name, 0, STRUCT_NAMESPACE, 0, 
-                          (struct symtab **) NULL);
+      sym = lookup_symbol (name, 0, STRUCT_NAMESPACE, 0, (struct symtab **) NULL);
       if (sym)
        {
-         memcpy ((char *)type, (char *)SYMBOL_TYPE(sym), sizeof (struct type));
+         memcpy ((char *) type, (char *) SYMBOL_TYPE (sym), sizeof (struct type));
        }
     }
-}
-
-/* Ugly hack to convert method stubs into method types.
-
-   He ain't kiddin'.  This demangles the name of the method into a string
-   including argument types, parses out each argument type, generates
-   a string casting a zero to that type, evaluates the string, and stuffs
-   the resulting type into an argtype vector!!!  Then it knows the type
-   of the whole function (including argument types for overloading),
-   which info used to be in the stab's but was removed to hack back
-   the space required for them.  */
-
-void
-check_stub_method (type, i, j)
-     struct type *type;
-     int i;
-     int j;
-{
-  struct fn_field *f;
-  char *mangled_name = gdb_mangle_name (type, i, j);
-  char *demangled_name = cplus_demangle (mangled_name,
-                                        DMGL_PARAMS | DMGL_ANSI);
-  char *argtypetext, *p;
-  int depth = 0, argcount = 1;
-  struct type **argtypes;
-  struct type *mtype;
 
-  if (demangled_name == NULL)
+  if (TYPE_FLAGS (type) & TYPE_FLAG_TARGET_STUB)
     {
-      error ("Internal: Cannot demangle mangled name `%s'.", mangled_name);
-    }
+      struct type *range_type;
+      struct type *target_type = check_typedef (TYPE_TARGET_TYPE (type));
 
-  /* Now, read in the parameters that define this type.  */
-  argtypetext = strchr (demangled_name, '(') + 1;
-  p = argtypetext;
-  while (*p)
-    {
-      if (*p == '(')
+      if (TYPE_FLAGS (target_type) & (TYPE_FLAG_STUB | TYPE_FLAG_TARGET_STUB))
        {
-         depth += 1;
        }
-      else if (*p == ')')
+      else if (TYPE_CODE (type) == TYPE_CODE_ARRAY
+              && TYPE_NFIELDS (type) == 1
+              && (TYPE_CODE (range_type = TYPE_FIELD_TYPE (type, 0))
+                  == TYPE_CODE_RANGE))
        {
-         depth -= 1;
+         /* Now recompute the length of the array type, based on its
+            number of elements and the target type's length.  */
+         TYPE_LENGTH (type) =
+           ((TYPE_FIELD_BITPOS (range_type, 1)
+             - TYPE_FIELD_BITPOS (range_type, 0)
+             + 1)
+            * TYPE_LENGTH (target_type));
+         TYPE_FLAGS (type) &= ~TYPE_FLAG_TARGET_STUB;
        }
-      else if (*p == ',' && depth == 0)
+      else if (TYPE_CODE (type) == TYPE_CODE_RANGE)
        {
-         argcount += 1;
+         TYPE_LENGTH (type) = TYPE_LENGTH (target_type);
+         TYPE_FLAGS (type) &= ~TYPE_FLAG_TARGET_STUB;
        }
-
-      p += 1;
     }
+  /* Cache TYPE_LENGTH for future use. */
+  TYPE_LENGTH (orig_type) = TYPE_LENGTH (type);
+  return type;
+}
 
-  /* We need two more slots: one for the THIS pointer, and one for the
-     NULL [...] or void [end of arglist].  */
+/* New code added to support parsing of Cfront stabs strings */
+#include <ctype.h>
+#define INIT_EXTRA { pextras->len=0; pextras->str[0]='\0'; }
+#define ADD_EXTRA(c) { pextras->str[pextras->len++]=c; }
 
-  argtypes = (struct type **)
-    TYPE_ALLOC (type, (argcount + 2) * sizeof (struct type *));
-  p = argtypetext;
-  argtypes[0] = lookup_pointer_type (type);
-  argcount = 1;
+static void
+add_name (struct extra *pextras, char *n)
+{
+  int nlen;
+
+  if ((nlen = (n ? strlen (n) : 0)) == 0)
+    return;
+  sprintf (pextras->str + pextras->len, "%d%s", nlen, n);
+  pextras->len = strlen (pextras->str);
+}
+
+static void
+add_mangled_type (struct extra *pextras, struct type *t)
+{
+  enum type_code tcode;
+  int tlen, tflags;
+  char *tname;
 
-  if (*p != ')')                       /* () means no args, skip while */
+  tcode = TYPE_CODE (t);
+  tlen = TYPE_LENGTH (t);
+  tflags = TYPE_FLAGS (t);
+  tname = TYPE_NAME (t);
+  /* args of "..." seem to get mangled as "e" */
+
+  switch (tcode)
     {
-      depth = 0;
-      while (*p)
+    case TYPE_CODE_INT:
+      if (tflags == 1)
+       ADD_EXTRA ('U');
+      switch (tlen)
        {
-         if (depth <= 0 && (*p == ',' || *p == ')'))
-           {
-             argtypes[argcount] =
-                 parse_and_eval_type (argtypetext, p - argtypetext);
-             argcount += 1;
-             argtypetext = p + 1;
+       case 1:
+         ADD_EXTRA ('c');
+         break;
+       case 2:
+         ADD_EXTRA ('s');
+         break;
+       case 4:
+         {
+           char *pname;
+           if ((pname = strrchr (tname, 'l'), pname) && !strcmp (pname, "long"))
+             {
+               ADD_EXTRA ('l');
+             }
+           else
+             {
+               ADD_EXTRA ('i');
+             }
+         }
+         break;
+       default:
+         {
+
+           static struct complaint msg =
+           {"Bad int type code length x%x\n", 0, 0};
+
+           complain (&msg, tlen);
+
+         }
+       }
+      break;
+    case TYPE_CODE_FLT:
+      switch (tlen)
+       {
+       case 4:
+         ADD_EXTRA ('f');
+         break;
+       case 8:
+         ADD_EXTRA ('d');
+         break;
+       case 16:
+         ADD_EXTRA ('r');
+         break;
+       default:
+         {
+           static struct complaint msg =
+           {"Bad float type code length x%x\n", 0, 0};
+           complain (&msg, tlen);
+         }
+       }
+      break;
+    case TYPE_CODE_REF:
+      ADD_EXTRA ('R');
+      /* followed by what it's a ref to */
+      break;
+    case TYPE_CODE_PTR:
+      ADD_EXTRA ('P');
+      /* followed by what it's a ptr to */
+      break;
+    case TYPE_CODE_TYPEDEF:
+      {
+       static struct complaint msg =
+       {"Typedefs in overloaded functions not yet supported\n", 0, 0};
+       complain (&msg);
+      }
+      /* followed by type bytes & name */
+      break;
+    case TYPE_CODE_FUNC:
+      ADD_EXTRA ('F');
+      /* followed by func's arg '_' & ret types */
+      break;
+    case TYPE_CODE_VOID:
+      ADD_EXTRA ('v');
+      break;
+    case TYPE_CODE_METHOD:
+      ADD_EXTRA ('M');
+      /* followed by name of class and func's arg '_' & ret types */
+      add_name (pextras, tname);
+      ADD_EXTRA ('F');         /* then mangle function */
+      break;
+    case TYPE_CODE_STRUCT:     /* C struct */
+    case TYPE_CODE_UNION:      /* C union */
+    case TYPE_CODE_ENUM:       /* Enumeration type */
+      /* followed by name of type */
+      add_name (pextras, tname);
+      break;
+
+      /* errors possible types/not supported */
+    case TYPE_CODE_CHAR:
+    case TYPE_CODE_ARRAY:      /* Array type */
+    case TYPE_CODE_MEMBER:     /* Member type */
+    case TYPE_CODE_BOOL:
+    case TYPE_CODE_COMPLEX:    /* Complex float */
+    case TYPE_CODE_UNDEF:
+    case TYPE_CODE_SET:        /* Pascal sets */
+    case TYPE_CODE_RANGE:
+    case TYPE_CODE_STRING:
+    case TYPE_CODE_BITSTRING:
+    case TYPE_CODE_ERROR:
+    default:
+      {
+       static struct complaint msg =
+       {"Unknown type code x%x\n", 0, 0};
+       complain (&msg, tcode);
+      }
+    }
+  if (t->target_type)
+    add_mangled_type (pextras, t->target_type);
+}
+
+#if 0
+void
+cfront_mangle_name (struct type *type, int i, int j)
+{
+  struct fn_field *f;
+  char *mangled_name = gdb_mangle_name (type, i, j);
+
+  f = TYPE_FN_FIELDLIST1 (type, i);    /* moved from below */
+
+  /* kludge to support cfront methods - gdb expects to find "F" for 
+     ARM_mangled names, so when we mangle, we have to add it here */
+  if (ARM_DEMANGLING)
+    {
+      int k;
+      char *arm_mangled_name;
+      struct fn_field *method = &f[j];
+      char *field_name = TYPE_FN_FIELDLIST_NAME (type, i);
+      char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
+      char *newname = type_name_no_tag (type);
+
+      struct type *ftype = TYPE_FN_FIELD_TYPE (f, j);
+      int nargs = TYPE_NFIELDS (ftype);                /* number of args */
+      struct extra extras, *pextras = &extras;
+      INIT_EXTRA
+
+       if (TYPE_FN_FIELD_STATIC_P (f, j))      /* j for sublist within this list */
+       ADD_EXTRA ('S')
+         ADD_EXTRA ('F')
+       /* add args here! */
+         if (nargs <= 1)       /* no args besides this */
+         ADD_EXTRA ('v')
+           else
+         {
+           for (k = 1; k < nargs; k++)
+             {
+               struct type *t;
+               t = TYPE_FIELD_TYPE (ftype, k);
+               add_mangled_type (pextras, t);
+             }
+         }
+      ADD_EXTRA ('\0')
+       printf ("add_mangled_type: %s\n", extras.str);  /* FIXME */
+      arm_mangled_name = malloc (strlen (mangled_name) + extras.len);
+      sprintf (arm_mangled_name, "%s%s", mangled_name, extras.str);
+      free (mangled_name);
+      mangled_name = arm_mangled_name;
+    }
+}
+#endif /* 0 */
+
+#undef ADD_EXTRA
+/* End of new code added to support parsing of Cfront stabs strings */
+
+/* Parse a type expression in the string [P..P+LENGTH).  If an error occurs,
+   silently return builtin_type_void. */
+
+struct type *
+safe_parse_type (char *p, int length)
+{
+  struct ui_file *saved_gdb_stderr;
+  struct type *type;
+
+  /* Suppress error messages. */
+  saved_gdb_stderr = gdb_stderr;
+  gdb_stderr = ui_file_new ();
+
+  /* Call parse_and_eval_type() without fear of longjmp()s. */
+  if (!gdb_parse_and_eval_type (p, length, &type))
+    type = builtin_type_void;
+
+  /* Stop suppressing error messages. */
+  ui_file_delete (gdb_stderr);
+  gdb_stderr = saved_gdb_stderr;
+
+  return type;
+}
+
+/* Ugly hack to convert method stubs into method types.
+
+   He ain't kiddin'.  This demangles the name of the method into a string
+   including argument types, parses out each argument type, generates
+   a string casting a zero to that type, evaluates the string, and stuffs
+   the resulting type into an argtype vector!!!  Then it knows the type
+   of the whole function (including argument types for overloading),
+   which info used to be in the stab's but was removed to hack back
+   the space required for them.  */
+
+void
+check_stub_method (struct type *type, int method_id, int signature_id)
+{
+  struct fn_field *f;
+  char *mangled_name = gdb_mangle_name (type, method_id, signature_id);
+  char *demangled_name = cplus_demangle (mangled_name,
+                                        DMGL_PARAMS | DMGL_ANSI);
+  char *argtypetext, *p;
+  int depth = 0, argcount = 1;
+  struct type **argtypes;
+  struct type *mtype;
+
+  /* Make sure we got back a function string that we can use.  */
+  if (demangled_name)
+    p = strchr (demangled_name, '(');
+
+  if (demangled_name == NULL || p == NULL)
+    error ("Internal: Cannot demangle mangled name `%s'.", mangled_name);
+
+  /* Now, read in the parameters that define this type.  */
+  p += 1;
+  argtypetext = p;
+  while (*p)
+    {
+      if (*p == '(' || *p == '<')
+       {
+         depth += 1;
+       }
+      else if (*p == ')' || *p == '>')
+       {
+         depth -= 1;
+       }
+      else if (*p == ',' && depth == 0)
+       {
+         argcount += 1;
+       }
+
+      p += 1;
+    }
+
+  /* We need two more slots: one for the THIS pointer, and one for the
+     NULL [...] or void [end of arglist].  */
+
+  argtypes = (struct type **)
+    TYPE_ALLOC (type, (argcount + 2) * sizeof (struct type *));
+  p = argtypetext;
+  /* FIXME: This is wrong for static member functions.  */
+  argtypes[0] = lookup_pointer_type (type);
+  argcount = 1;
+
+  if (*p != ')')               /* () means no args, skip while */
+    {
+      depth = 0;
+      while (*p)
+       {
+         if (depth <= 0 && (*p == ',' || *p == ')'))
+           {
+             /* Avoid parsing of ellipsis, they will be handled below.  */
+             if (strncmp (argtypetext, "...", p - argtypetext) != 0)
+               {
+                 argtypes[argcount] =
+                   safe_parse_type (argtypetext, p - argtypetext);
+                 argcount += 1;
+               }
+             argtypetext = p + 1;
            }
 
-         if (*p == '(')
+         if (*p == '(' || *p == '<')
            {
              depth += 1;
            }
-         else if (*p == ')')
+         else if (*p == ')' || *p == '>')
            {
              depth -= 1;
            }
@@ -826,39 +1475,39 @@ check_stub_method (type, i, j)
        }
     }
 
-  if (p[-2] != '.')                    /* Not '...' */
+  if (p[-2] != '.')            /* Not '...' */
     {
       argtypes[argcount] = builtin_type_void;  /* List terminator */
     }
   else
     {
-      argtypes[argcount] = NULL;               /* Ellist terminator */
+      argtypes[argcount] = NULL;       /* Ellist terminator */
     }
 
   free (demangled_name);
 
-  f = TYPE_FN_FIELDLIST1 (type, i);
-  TYPE_FN_FIELD_PHYSNAME (f, j) = mangled_name;
+  f = TYPE_FN_FIELDLIST1 (type, method_id);
+
+  TYPE_FN_FIELD_PHYSNAME (f, signature_id) = mangled_name;
 
   /* Now update the old "stub" type into a real type.  */
-  mtype = TYPE_FN_FIELD_TYPE (f, j);
+  mtype = TYPE_FN_FIELD_TYPE (f, signature_id);
   TYPE_DOMAIN_TYPE (mtype) = type;
   TYPE_ARG_TYPES (mtype) = argtypes;
   TYPE_FLAGS (mtype) &= ~TYPE_FLAG_STUB;
-  TYPE_FN_FIELD_STUB (f, j) = 0;
+  TYPE_FN_FIELD_STUB (f, signature_id) = 0;
 }
 
-struct cplus_struct_type cplus_struct_default;
+const struct cplus_struct_type cplus_struct_default;
 
 void
-allocate_cplus_struct_type (type)
-     struct type *type;
+allocate_cplus_struct_type (struct type *type)
 {
   if (!HAVE_CPLUS_STRUCT (type))
     {
       TYPE_CPLUS_SPECIFIC (type) = (struct cplus_struct_type *)
        TYPE_ALLOC (type, sizeof (struct cplus_struct_type));
-      *(TYPE_CPLUS_SPECIFIC(type)) = cplus_struct_default;
+      *(TYPE_CPLUS_SPECIFIC (type)) = cplus_struct_default;
     }
 }
 
@@ -870,12 +1519,8 @@ allocate_cplus_struct_type (type)
    in particular, where init_type is called with a NULL value for NAME). */
 
 struct type *
-init_type (code, length, flags, name, objfile)
-     enum type_code code;
-     int length;
-     int flags;
-     char *name;
-     struct objfile *objfile;
+init_type (enum type_code code, int length, int flags, char *name,
+          struct objfile *objfile)
 {
   register struct type *type;
 
@@ -886,7 +1531,7 @@ init_type (code, length, flags, name, objfile)
   if ((name != NULL) && (objfile != NULL))
     {
       TYPE_NAME (type) =
-       obsavestring (name, strlen (name), &objfile -> type_obstack);
+       obsavestring (name, strlen (name), &objfile->type_obstack);
     }
   else
     {
@@ -924,9 +1569,7 @@ init_type (code, length, flags, name, objfile)
 
 
 struct type *
-lookup_fundamental_type (objfile, typeid)
-     struct objfile *objfile;
-     int typeid;
+lookup_fundamental_type (struct objfile *objfile, int typeid)
 {
   register struct type **typep;
   register int nbytes;
@@ -938,19 +1581,20 @@ lookup_fundamental_type (objfile, typeid)
 
   /* If this is the first time we need a fundamental type for this objfile
      then we need to initialize the vector of type pointers. */
-  
-  if (objfile -> fundamental_types == NULL)
+
+  if (objfile->fundamental_types == NULL)
     {
       nbytes = FT_NUM_MEMBERS * sizeof (struct type *);
-      objfile -> fundamental_types = (struct type **)
-       obstack_alloc (&objfile -> type_obstack, nbytes);
-      memset ((char *) objfile -> fundamental_types, 0, nbytes);
+      objfile->fundamental_types = (struct type **)
+       obstack_alloc (&objfile->type_obstack, nbytes);
+      memset ((char *) objfile->fundamental_types, 0, nbytes);
+      OBJSTAT (objfile, n_types += FT_NUM_MEMBERS);
     }
 
   /* Look for this particular type in the fundamental type vector.  If one is
      not found, create and install one appropriate for the current language. */
 
-  typep = objfile -> fundamental_types + typeid;
+  typep = objfile->fundamental_types + typeid;
   if (*typep == NULL)
     {
       *typep = create_fundamental_type (objfile, typeid);
@@ -959,12 +1603,825 @@ lookup_fundamental_type (objfile, typeid)
   return (*typep);
 }
 
-#if MAINTENANCE_CMDS
+int
+can_dereference (struct type *t)
+{
+  /* FIXME: Should we return true for references as well as pointers?  */
+  CHECK_TYPEDEF (t);
+  return
+    (t != NULL
+     && TYPE_CODE (t) == TYPE_CODE_PTR
+     && TYPE_CODE (TYPE_TARGET_TYPE (t)) != TYPE_CODE_VOID);
+}
+
+int
+is_integral_type (struct type *t)
+{
+  CHECK_TYPEDEF (t);
+  return
+    ((t != NULL)
+     && ((TYPE_CODE (t) == TYPE_CODE_INT)
+        || (TYPE_CODE (t) == TYPE_CODE_ENUM)
+        || (TYPE_CODE (t) == TYPE_CODE_CHAR)
+        || (TYPE_CODE (t) == TYPE_CODE_RANGE)
+        || (TYPE_CODE (t) == TYPE_CODE_BOOL)));
+}
+
+/* Chill varying string and arrays are represented as follows:
+
+   struct { int __var_length; ELEMENT_TYPE[MAX_SIZE] __var_data};
+
+   Return true if TYPE is such a Chill varying type. */
+
+int
+chill_varying_type (struct type *type)
+{
+  if (TYPE_CODE (type) != TYPE_CODE_STRUCT
+      || TYPE_NFIELDS (type) != 2
+      || strcmp (TYPE_FIELD_NAME (type, 0), "__var_length") != 0)
+    return 0;
+  return 1;
+}
+
+/* Check whether BASE is an ancestor or base class or DCLASS 
+   Return 1 if so, and 0 if not.
+   Note: callers may want to check for identity of the types before
+   calling this function -- identical types are considered to satisfy
+   the ancestor relationship even if they're identical */
+
+int
+is_ancestor (struct type *base, struct type *dclass)
+{
+  int i;
+
+  CHECK_TYPEDEF (base);
+  CHECK_TYPEDEF (dclass);
+
+  if (base == dclass)
+    return 1;
+  if (TYPE_NAME (base) && TYPE_NAME (dclass) &&
+      !strcmp (TYPE_NAME (base), TYPE_NAME (dclass)))
+    return 1;
+
+  for (i = 0; i < TYPE_N_BASECLASSES (dclass); i++)
+    if (is_ancestor (base, TYPE_BASECLASS (dclass, i)))
+      return 1;
+
+  return 0;
+}
+
+
+
+/* See whether DCLASS has a virtual table.  This routine is aimed at
+   the HP/Taligent ANSI C++ runtime model, and may not work with other
+   runtime models.  Return 1 => Yes, 0 => No.  */
+
+int
+has_vtable (struct type *dclass)
+{
+  /* In the HP ANSI C++ runtime model, a class has a vtable only if it
+     has virtual functions or virtual bases.  */
+
+  register int i;
+
+  if (TYPE_CODE (dclass) != TYPE_CODE_CLASS)
+    return 0;
+
+  /* First check for the presence of virtual bases */
+  if (TYPE_FIELD_VIRTUAL_BITS (dclass))
+    for (i = 0; i < TYPE_N_BASECLASSES (dclass); i++)
+      if (B_TST (TYPE_FIELD_VIRTUAL_BITS (dclass), i))
+       return 1;
+
+  /* Next check for virtual functions */
+  if (TYPE_FN_FIELDLISTS (dclass))
+    for (i = 0; i < TYPE_NFN_FIELDS (dclass); i++)
+      if (TYPE_FN_FIELD_VIRTUAL_P (TYPE_FN_FIELDLIST1 (dclass, i), 0))
+       return 1;
+
+  /* Recurse on non-virtual bases to see if any of them needs a vtable */
+  if (TYPE_FIELD_VIRTUAL_BITS (dclass))
+    for (i = 0; i < TYPE_N_BASECLASSES (dclass); i++)
+      if ((!B_TST (TYPE_FIELD_VIRTUAL_BITS (dclass), i)) &&
+         (has_vtable (TYPE_FIELD_TYPE (dclass, i))))
+       return 1;
+
+  /* Well, maybe we don't need a virtual table */
+  return 0;
+}
+
+/* Return a pointer to the "primary base class" of DCLASS.
+
+   A NULL return indicates that DCLASS has no primary base, or that it
+   couldn't be found (insufficient information).
+
+   This routine is aimed at the HP/Taligent ANSI C++ runtime model,
+   and may not work with other runtime models.  */
+
+struct type *
+primary_base_class (struct type *dclass)
+{
+  /* In HP ANSI C++'s runtime model, a "primary base class" of a class
+     is the first directly inherited, non-virtual base class that
+     requires a virtual table */
+
+  register int i;
+
+  if (TYPE_CODE (dclass) != TYPE_CODE_CLASS)
+    return NULL;
+
+  for (i = 0; i < TYPE_N_BASECLASSES (dclass); i++)
+    if (!TYPE_FIELD_VIRTUAL (dclass, i) &&
+       has_vtable (TYPE_FIELD_TYPE (dclass, i)))
+      return TYPE_FIELD_TYPE (dclass, i);
+
+  return NULL;
+}
+
+/* Global manipulated by virtual_base_list[_aux]() */
+
+static struct vbase *current_vbase_list = NULL;
+
+/* Return a pointer to a null-terminated list of struct vbase
+   items. The vbasetype pointer of each item in the list points to the
+   type information for a virtual base of the argument DCLASS.
+
+   Helper function for virtual_base_list(). 
+   Note: the list goes backward, right-to-left. virtual_base_list()
+   copies the items out in reverse order.  */
 
 static void
-print_bit_vector (bits, nbits)
-     B_TYPE *bits;
-     int nbits;
+virtual_base_list_aux (struct type *dclass)
+{
+  struct vbase *tmp_vbase;
+  register int i;
+
+  if (TYPE_CODE (dclass) != TYPE_CODE_CLASS)
+    return;
+
+  for (i = 0; i < TYPE_N_BASECLASSES (dclass); i++)
+    {
+      /* Recurse on this ancestor, first */
+      virtual_base_list_aux (TYPE_FIELD_TYPE (dclass, i));
+
+      /* If this current base is itself virtual, add it to the list */
+      if (BASETYPE_VIA_VIRTUAL (dclass, i))
+       {
+         struct type *basetype = TYPE_FIELD_TYPE (dclass, i);
+
+         /* Check if base already recorded */
+         tmp_vbase = current_vbase_list;
+         while (tmp_vbase)
+           {
+             if (tmp_vbase->vbasetype == basetype)
+               break;          /* found it */
+             tmp_vbase = tmp_vbase->next;
+           }
+
+         if (!tmp_vbase)       /* normal exit from loop */
+           {
+             /* Allocate new item for this virtual base */
+             tmp_vbase = (struct vbase *) xmalloc (sizeof (struct vbase));
+
+             /* Stick it on at the end of the list */
+             tmp_vbase->vbasetype = basetype;
+             tmp_vbase->next = current_vbase_list;
+             current_vbase_list = tmp_vbase;
+           }
+       }                       /* if virtual */
+    }                          /* for loop over bases */
+}
+
+
+/* Compute the list of virtual bases in the right order.  Virtual
+   bases are laid out in the object's memory area in order of their
+   occurrence in a depth-first, left-to-right search through the
+   ancestors.
+
+   Argument DCLASS is the type whose virtual bases are required.
+   Return value is the address of a null-terminated array of pointers
+   to struct type items.
+
+   This routine is aimed at the HP/Taligent ANSI C++ runtime model,
+   and may not work with other runtime models.
+
+   This routine merely hands off the argument to virtual_base_list_aux()
+   and then copies the result into an array to save space.  */
+
+struct type **
+virtual_base_list (struct type *dclass)
+{
+  register struct vbase *tmp_vbase;
+  register struct vbase *tmp_vbase_2;
+  register int i;
+  int count;
+  struct type **vbase_array;
+
+  current_vbase_list = NULL;
+  virtual_base_list_aux (dclass);
+
+  for (i = 0, tmp_vbase = current_vbase_list; tmp_vbase != NULL; i++, tmp_vbase = tmp_vbase->next)
+    /* no body */ ;
+
+  count = i;
+
+  vbase_array = (struct type **) xmalloc ((count + 1) * sizeof (struct type *));
+
+  for (i = count - 1, tmp_vbase = current_vbase_list; i >= 0; i--, tmp_vbase = tmp_vbase->next)
+    vbase_array[i] = tmp_vbase->vbasetype;
+
+  /* Get rid of constructed chain */
+  tmp_vbase_2 = tmp_vbase = current_vbase_list;
+  while (tmp_vbase)
+    {
+      tmp_vbase = tmp_vbase->next;
+      free (tmp_vbase_2);
+      tmp_vbase_2 = tmp_vbase;
+    }
+
+  vbase_array[count] = NULL;
+  return vbase_array;
+}
+
+/* Return the length of the virtual base list of the type DCLASS.  */
+
+int
+virtual_base_list_length (struct type *dclass)
+{
+  register int i;
+  register struct vbase *tmp_vbase;
+
+  current_vbase_list = NULL;
+  virtual_base_list_aux (dclass);
+
+  for (i = 0, tmp_vbase = current_vbase_list; tmp_vbase != NULL; i++, tmp_vbase = tmp_vbase->next)
+    /* no body */ ;
+  return i;
+}
+
+/* Return the number of elements of the virtual base list of the type
+   DCLASS, ignoring those appearing in the primary base (and its
+   primary base, recursively).  */
+
+int
+virtual_base_list_length_skip_primaries (struct type *dclass)
+{
+  register int i;
+  register struct vbase *tmp_vbase;
+  struct type *primary;
+
+  primary = TYPE_RUNTIME_PTR (dclass) ? TYPE_PRIMARY_BASE (dclass) : NULL;
+
+  if (!primary)
+    return virtual_base_list_length (dclass);
+
+  current_vbase_list = NULL;
+  virtual_base_list_aux (dclass);
+
+  for (i = 0, tmp_vbase = current_vbase_list; tmp_vbase != NULL; tmp_vbase = tmp_vbase->next)
+    {
+      if (virtual_base_index (tmp_vbase->vbasetype, primary) >= 0)
+       continue;
+      i++;
+    }
+  return i;
+}
+
+
+/* Return the index (position) of type BASE, which is a virtual base
+   class of DCLASS, in the latter's virtual base list.  A return of -1
+   indicates "not found" or a problem.  */
+
+int
+virtual_base_index (struct type *base, struct type *dclass)
+{
+  register struct type *vbase;
+  register int i;
+
+  if ((TYPE_CODE (dclass) != TYPE_CODE_CLASS) ||
+      (TYPE_CODE (base) != TYPE_CODE_CLASS))
+    return -1;
+
+  i = 0;
+  vbase = TYPE_VIRTUAL_BASE_LIST (dclass)[0];
+  while (vbase)
+    {
+      if (vbase == base)
+       break;
+      vbase = TYPE_VIRTUAL_BASE_LIST (dclass)[++i];
+    }
+
+  return vbase ? i : -1;
+}
+
+
+
+/* Return the index (position) of type BASE, which is a virtual base
+   class of DCLASS, in the latter's virtual base list. Skip over all
+   bases that may appear in the virtual base list of the primary base
+   class of DCLASS (recursively).  A return of -1 indicates "not
+   found" or a problem.  */
+
+int
+virtual_base_index_skip_primaries (struct type *base, struct type *dclass)
+{
+  register struct type *vbase;
+  register int i, j;
+  struct type *primary;
+
+  if ((TYPE_CODE (dclass) != TYPE_CODE_CLASS) ||
+      (TYPE_CODE (base) != TYPE_CODE_CLASS))
+    return -1;
+
+  primary = TYPE_RUNTIME_PTR (dclass) ? TYPE_PRIMARY_BASE (dclass) : NULL;
+
+  j = -1;
+  i = 0;
+  vbase = TYPE_VIRTUAL_BASE_LIST (dclass)[0];
+  while (vbase)
+    {
+      if (!primary || (virtual_base_index_skip_primaries (vbase, primary) < 0))
+       j++;
+      if (vbase == base)
+       break;
+      vbase = TYPE_VIRTUAL_BASE_LIST (dclass)[++i];
+    }
+
+  return vbase ? j : -1;
+}
+
+/* Return position of a derived class DCLASS in the list of
+ * primary bases starting with the remotest ancestor.
+ * Position returned is 0-based. */
+
+int
+class_index_in_primary_list (struct type *dclass)
+{
+  struct type *pbc;            /* primary base class */
+
+  /* Simply recurse on primary base */
+  pbc = TYPE_PRIMARY_BASE (dclass);
+  if (pbc)
+    return 1 + class_index_in_primary_list (pbc);
+  else
+    return 0;
+}
+
+/* Return a count of the number of virtual functions a type has.
+ * This includes all the virtual functions it inherits from its
+ * base classes too.
+ */
+
+/* pai: FIXME This doesn't do the right thing: count redefined virtual
+ * functions only once (latest redefinition)
+ */
+
+int
+count_virtual_fns (struct type *dclass)
+{
+  int fn, oi;                  /* function and overloaded instance indices */
+  int vfuncs;                  /* count to return */
+
+  /* recurse on bases that can share virtual table */
+  struct type *pbc = primary_base_class (dclass);
+  if (pbc)
+    vfuncs = count_virtual_fns (pbc);
+
+  for (fn = 0; fn < TYPE_NFN_FIELDS (dclass); fn++)
+    for (oi = 0; oi < TYPE_FN_FIELDLIST_LENGTH (dclass, fn); oi++)
+      if (TYPE_FN_FIELD_VIRTUAL_P (TYPE_FN_FIELDLIST1 (dclass, fn), oi))
+       vfuncs++;
+
+  return vfuncs;
+}
+\f
+
+
+/* Functions for overload resolution begin here */
+
+/* Compare two badness vectors A and B and return the result.
+ * 0 => A and B are identical
+ * 1 => A and B are incomparable
+ * 2 => A is better than B
+ * 3 => A is worse than B */
+
+int
+compare_badness (struct badness_vector *a, struct 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)
+    return 1;
+
+  /* Subtract b from a */
+  for (i = 0; i < a->length; i++)
+    {
+      tmp = a->rank[i] - b->rank[i];
+      if (tmp > 0)
+       found_pos = 1;
+      else if (tmp < 0)
+       found_neg = 1;
+    }
+
+  if (found_pos)
+    {
+      if (found_neg)
+       return 1;               /* incomparable */
+      else
+       return 3;               /* A > B */
+    }
+  else
+    /* no positives */
+    {
+      if (found_neg)
+       return 2;               /* A < B */
+      else
+       return 0;               /* A == 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. */
+
+struct badness_vector *
+rank_function (struct type **parms, int nparms, struct type **args, int nargs)
+{
+  int i;
+  struct badness_vector *bv;
+  int min_len = nparms < nargs ? nparms : nargs;
+
+  bv = xmalloc (sizeof (struct badness_vector));
+  bv->length = nargs + 1;      /* add 1 for the length-match rank */
+  bv->rank = xmalloc ((nargs + 1) * sizeof (int));
+
+  /* First compare the lengths of the supplied lists.
+   * If there is a mismatch, set it to a high value. */
+
+  /* pai/1997-06-03 FIXME: when we have debug info about default
+   * arguments and ellipsis parameter lists, we should consider those
+   * and rank the length-match more finely. */
+
+  LENGTH_MATCH (bv) = (nargs != nparms) ? LENGTH_MISMATCH_BADNESS : 0;
+
+  /* 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], args[i-1]);
+
+  /* If more arguments than parameters, add dummy entries */
+  for (i = min_len + 1; i <= nargs; i++)
+    bv->rank[i] = TOO_FEW_PARAMS_BADNESS;
+
+  return bv;
+}
+
+/* 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.
+ *
+ * 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 */
+
+int
+rank_one_type (struct type *parm, struct type *arg)
+{
+  /* Identical type pointers */
+  /* However, this still doesn't catch all cases of same type for arg
+   * and param. The reason is that builtin types are different from
+   * the same ones constructed from the object. */
+  if (parm == arg)
+    return 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);
+
+  /*
+     Well, damnit, if the names are exactly the same,
+     i'll say they are exactly the same. This happens when we generate
+     method stubs. The types won't point to the same address, but they
+     really are the same.
+  */
+
+  if (TYPE_NAME (parm) && TYPE_NAME (arg) &&
+      !strcmp (TYPE_NAME (parm), TYPE_NAME (arg)))
+      return 0;
+
+  /* Check if identical after resolving typedefs */
+  if (parm == arg)
+    return 0;
+
+  /* See through references, since we can almost make non-references
+     references. */
+  if (TYPE_CODE (arg) == TYPE_CODE_REF)
+    return (rank_one_type (parm, TYPE_TARGET_TYPE (arg))
+           + REFERENCE_CONVERSION_BADNESS);
+  if (TYPE_CODE (parm) == TYPE_CODE_REF)
+    return (rank_one_type (TYPE_TARGET_TYPE (parm), arg)
+           + REFERENCE_CONVERSION_BADNESS);
+  if (overload_debug)
+  /* Debugging only. */
+    fprintf_filtered (gdb_stderr,"------ Arg is %s [%d], parm is %s [%d]\n",
+        TYPE_NAME (arg), TYPE_CODE (arg), TYPE_NAME (parm), TYPE_CODE (parm));
+
+  /* x -> y means arg of type x being supplied for parameter of type y */
+
+  switch (TYPE_CODE (parm))
+    {
+    case TYPE_CODE_PTR:
+      switch (TYPE_CODE (arg))
+       {
+       case TYPE_CODE_PTR:
+         if (TYPE_CODE (TYPE_TARGET_TYPE (parm)) == TYPE_CODE_VOID)
+           return VOID_PTR_CONVERSION_BADNESS;
+         else
+           return rank_one_type (TYPE_TARGET_TYPE (parm), TYPE_TARGET_TYPE (arg));
+       case TYPE_CODE_ARRAY:
+         return rank_one_type (TYPE_TARGET_TYPE (parm), TYPE_TARGET_TYPE (arg));
+       case TYPE_CODE_FUNC:
+         return rank_one_type (TYPE_TARGET_TYPE (parm), arg);
+       case TYPE_CODE_INT:
+       case TYPE_CODE_ENUM:
+       case TYPE_CODE_CHAR:
+       case TYPE_CODE_RANGE:
+       case TYPE_CODE_BOOL:
+         return POINTER_CONVERSION_BADNESS;
+       default:
+         return INCOMPATIBLE_TYPE_BADNESS;
+       }
+    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));
+       default:
+         return INCOMPATIBLE_TYPE_BADNESS;
+       }
+    case TYPE_CODE_FUNC:
+      switch (TYPE_CODE (arg))
+       {
+       case TYPE_CODE_PTR:     /* funcptr -> func */
+         return rank_one_type (parm, TYPE_TARGET_TYPE (arg));
+       default:
+         return INCOMPATIBLE_TYPE_BADNESS;
+       }
+    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))        /* plain char -> plain char */
+                   return 0;
+                 else
+                   return INTEGER_COERCION_BADNESS;    /* signed/unsigned char -> plain char */
+               }
+             else if (TYPE_UNSIGNED (parm))
+               {
+                 if (TYPE_UNSIGNED (arg))
+                   {
+                     if (!strcmp_iw (TYPE_NAME (parm), TYPE_NAME (arg)))
+                       return 0;       /* unsigned int -> unsigned int, or unsigned long -> unsigned long */
+                     else if (!strcmp_iw (TYPE_NAME (arg), "int") && !strcmp_iw (TYPE_NAME (parm), "long"))
+                       return INTEGER_PROMOTION_BADNESS;       /* unsigned int -> unsigned long */
+                     else
+                       return INTEGER_COERCION_BADNESS;        /* unsigned long -> unsigned int */
+                   }
+                 else
+                   {
+                     if (!strcmp_iw (TYPE_NAME (arg), "long") && !strcmp_iw (TYPE_NAME (parm), "int"))
+                       return INTEGER_COERCION_BADNESS;        /* signed long -> unsigned int */
+                     else
+                       return INTEGER_CONVERSION_BADNESS;      /* signed int/long -> unsigned int/long */
+                   }
+               }
+             else if (!TYPE_NOSIGN (arg) && !TYPE_UNSIGNED (arg))
+               {
+                 if (!strcmp_iw (TYPE_NAME (parm), TYPE_NAME (arg)))
+                   return 0;
+                 else if (!strcmp_iw (TYPE_NAME (arg), "int") && !strcmp_iw (TYPE_NAME (parm), "long"))
+                   return INTEGER_PROMOTION_BADNESS;
+                 else
+                   return INTEGER_COERCION_BADNESS;
+               }
+             else
+               return INTEGER_COERCION_BADNESS;
+           }
+         else if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm))
+           return INTEGER_PROMOTION_BADNESS;
+         else
+           return INTEGER_COERCION_BADNESS;
+       case TYPE_CODE_ENUM:
+       case TYPE_CODE_CHAR:
+       case TYPE_CODE_RANGE:
+       case TYPE_CODE_BOOL:
+         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;
+    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:
+         return INTEGER_COERCION_BADNESS;
+       case TYPE_CODE_FLT:
+         return INT_FLOAT_CONVERSION_BADNESS;
+       default:
+         return INCOMPATIBLE_TYPE_BADNESS;
+       }
+      break;
+    case TYPE_CODE_CHAR:
+      switch (TYPE_CODE (arg))
+       {
+       case TYPE_CODE_RANGE:
+       case TYPE_CODE_BOOL:
+       case TYPE_CODE_ENUM:
+         return INTEGER_COERCION_BADNESS;
+       case TYPE_CODE_FLT:
+         return INT_FLOAT_CONVERSION_BADNESS;
+       case TYPE_CODE_INT:
+         if (TYPE_LENGTH (arg) > TYPE_LENGTH (parm))
+           return INTEGER_COERCION_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 0;
+             else
+               return INTEGER_COERCION_BADNESS;
+           }
+         else if (TYPE_UNSIGNED (parm))
+           {
+             if (TYPE_UNSIGNED (arg))
+               return 0;
+             else
+               return INTEGER_PROMOTION_BADNESS;
+           }
+         else if (!TYPE_NOSIGN (arg) && !TYPE_UNSIGNED (arg))
+           return 0;
+         else
+           return INTEGER_COERCION_BADNESS;
+       default:
+         return INCOMPATIBLE_TYPE_BADNESS;
+       }
+      break;
+    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_COERCION_BADNESS;
+       case TYPE_CODE_FLT:
+         return INT_FLOAT_CONVERSION_BADNESS;
+       default:
+         return INCOMPATIBLE_TYPE_BADNESS;
+       }
+      break;
+    case TYPE_CODE_BOOL:
+      switch (TYPE_CODE (arg))
+       {
+       case TYPE_CODE_INT:
+       case TYPE_CODE_CHAR:
+       case TYPE_CODE_RANGE:
+       case TYPE_CODE_ENUM:
+       case TYPE_CODE_FLT:
+       case TYPE_CODE_PTR:
+         return BOOLEAN_CONVERSION_BADNESS;
+       case TYPE_CODE_BOOL:
+         return 0;
+       default:
+         return INCOMPATIBLE_TYPE_BADNESS;
+       }
+      break;
+    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 0;
+         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;
+    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 0;
+       default:
+         return INCOMPATIBLE_TYPE_BADNESS;
+       }
+      break;
+    case TYPE_CODE_STRUCT:
+      /* currently same as TYPE_CODE_CLASS */
+      switch (TYPE_CODE (arg))
+       {
+       case TYPE_CODE_STRUCT:
+         /* Check for derivation */
+         if (is_ancestor (parm, arg))
+           return BASE_CONVERSION_BADNESS;
+         /* 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_MEMBER:
+      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;
+    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));
+       default:
+         return INCOMPATIBLE_TYPE_BADNESS;
+       }
+      break;
+    case TYPE_CODE_VOID:
+    default:
+      return INCOMPATIBLE_TYPE_BADNESS;
+    }                          /* switch (TYPE_CODE (arg)) */
+}
+
+
+/* End of functions for overload resolution */
+
+static void
+print_bit_vector (B_TYPE *bits, int nbits)
 {
   int bitno;
 
@@ -992,16 +2449,14 @@ print_bit_vector (bits, nbits)
    include it since we may get into a infinitely recursive situation. */
 
 static void
-print_arg_types (args, spaces)
-     struct type **args;
-     int spaces;
+print_arg_types (struct type **args, int spaces)
 {
   if (args != NULL)
     {
       while (*args != NULL)
        {
          recursive_dump_type (*args, spaces + 2);
-         if ((*args++) -> code == TYPE_CODE_VOID)
+         if ((*args++)->code == TYPE_CODE_VOID)
            {
              break;
            }
@@ -1010,41 +2465,52 @@ print_arg_types (args, spaces)
 }
 
 static void
-dump_fn_fieldlists (type, spaces)
-     struct type *type;
-     int spaces;
+dump_fn_fieldlists (struct type *type, int spaces)
 {
   int method_idx;
   int overload_idx;
   struct fn_field *f;
 
-  printfi_filtered (spaces, "fn_fieldlists 0x%x\n",
-                   TYPE_FN_FIELDLISTS (type));
+  printfi_filtered (spaces, "fn_fieldlists ");
+  gdb_print_host_address (TYPE_FN_FIELDLISTS (type), gdb_stdout);
+  printf_filtered ("\n");
   for (method_idx = 0; method_idx < TYPE_NFN_FIELDS (type); method_idx++)
     {
       f = TYPE_FN_FIELDLIST1 (type, method_idx);
-      printfi_filtered (spaces + 2, "[%d] name '%s' (0x%x) length %d\n",
+      printfi_filtered (spaces + 2, "[%d] name '%s' (",
                        method_idx,
-                       TYPE_FN_FIELDLIST_NAME (type, method_idx),
-                       TYPE_FN_FIELDLIST_NAME (type, method_idx),
-                       TYPE_FN_FIELDLIST_LENGTH (type, method_idx));
+                       TYPE_FN_FIELDLIST_NAME (type, method_idx));
+      gdb_print_host_address (TYPE_FN_FIELDLIST_NAME (type, method_idx),
+                             gdb_stdout);
+      printf_filtered (") length %d\n",
+                      TYPE_FN_FIELDLIST_LENGTH (type, method_idx));
       for (overload_idx = 0;
           overload_idx < TYPE_FN_FIELDLIST_LENGTH (type, method_idx);
           overload_idx++)
        {
-         printfi_filtered (spaces + 4, "[%d] physname '%s' (0x%x)\n",
+         printfi_filtered (spaces + 4, "[%d] physname '%s' (",
                            overload_idx,
-                           TYPE_FN_FIELD_PHYSNAME (f, overload_idx),
                            TYPE_FN_FIELD_PHYSNAME (f, overload_idx));
-         printfi_filtered (spaces + 8, "type 0x%x\n",
-                           TYPE_FN_FIELD_TYPE (f, overload_idx));
+         gdb_print_host_address (TYPE_FN_FIELD_PHYSNAME (f, overload_idx),
+                                 gdb_stdout);
+         printf_filtered (")\n");
+         printfi_filtered (spaces + 8, "type ");
+         gdb_print_host_address (TYPE_FN_FIELD_TYPE (f, overload_idx), gdb_stdout);
+         printf_filtered ("\n");
+
          recursive_dump_type (TYPE_FN_FIELD_TYPE (f, overload_idx),
                               spaces + 8 + 2);
-         printfi_filtered (spaces + 8, "args 0x%x\n",
-                           TYPE_FN_FIELD_ARGS (f, overload_idx));
+
+         printfi_filtered (spaces + 8, "args ");
+         gdb_print_host_address (TYPE_FN_FIELD_ARGS (f, overload_idx), gdb_stdout);
+         printf_filtered ("\n");
+
          print_arg_types (TYPE_FN_FIELD_ARGS (f, overload_idx), spaces);
-         printfi_filtered (spaces + 8, "fcontext 0x%x\n",
-                           TYPE_FN_FIELD_FCONTEXT (f, overload_idx));
+         printfi_filtered (spaces + 8, "fcontext ");
+         gdb_print_host_address (TYPE_FN_FIELD_FCONTEXT (f, overload_idx),
+                                 gdb_stdout);
+         printf_filtered ("\n");
+
          printfi_filtered (spaces + 8, "is_const %d\n",
                            TYPE_FN_FIELD_CONST (f, overload_idx));
          printfi_filtered (spaces + 8, "is_volatile %d\n",
@@ -1062,12 +2528,8 @@ dump_fn_fieldlists (type, spaces)
 }
 
 static void
-print_cplus_stuff (type, spaces)
-     struct type *type;
-     int spaces;
+print_cplus_stuff (struct type *type, int spaces)
 {
-  int bitno;
-
   printfi_filtered (spaces, "n_baseclasses %d\n",
                    TYPE_N_BASECLASSES (type));
   printfi_filtered (spaces, "nfn_fields %d\n",
@@ -1076,9 +2538,11 @@ print_cplus_stuff (type, spaces)
                    TYPE_NFN_FIELDS_TOTAL (type));
   if (TYPE_N_BASECLASSES (type) > 0)
     {
-      printfi_filtered (spaces, "virtual_field_bits (%d bits at *0x%x)",
-                       TYPE_N_BASECLASSES (type),
-                       TYPE_FIELD_VIRTUAL_BITS (type));
+      printfi_filtered (spaces, "virtual_field_bits (%d bits at *",
+                       TYPE_N_BASECLASSES (type));
+      gdb_print_host_address (TYPE_FIELD_VIRTUAL_BITS (type), gdb_stdout);
+      printf_filtered (")");
+
       print_bit_vector (TYPE_FIELD_VIRTUAL_BITS (type),
                        TYPE_N_BASECLASSES (type));
       puts_filtered ("\n");
@@ -1087,18 +2551,20 @@ print_cplus_stuff (type, spaces)
     {
       if (TYPE_FIELD_PRIVATE_BITS (type) != NULL)
        {
-         printfi_filtered (spaces, "private_field_bits (%d bits at *0x%x)",
-                           TYPE_NFIELDS (type),
-                           TYPE_FIELD_PRIVATE_BITS (type));
+         printfi_filtered (spaces, "private_field_bits (%d bits at *",
+                           TYPE_NFIELDS (type));
+         gdb_print_host_address (TYPE_FIELD_PRIVATE_BITS (type), gdb_stdout);
+         printf_filtered (")");
          print_bit_vector (TYPE_FIELD_PRIVATE_BITS (type),
                            TYPE_NFIELDS (type));
          puts_filtered ("\n");
        }
       if (TYPE_FIELD_PROTECTED_BITS (type) != NULL)
        {
-         printfi_filtered (spaces, "protected_field_bits (%d bits at *0x%x)",
-                           TYPE_NFIELDS (type),
-                           TYPE_FIELD_PROTECTED_BITS (type));
+         printfi_filtered (spaces, "protected_field_bits (%d bits at *",
+                           TYPE_NFIELDS (type));
+         gdb_print_host_address (TYPE_FIELD_PROTECTED_BITS (type), gdb_stdout);
+         printf_filtered (")");
          print_bit_vector (TYPE_FIELD_PROTECTED_BITS (type),
                            TYPE_NFIELDS (type));
          puts_filtered ("\n");
@@ -1110,128 +2576,172 @@ print_cplus_stuff (type, spaces)
     }
 }
 
+static struct obstack dont_print_type_obstack;
+
 void
-recursive_dump_type (type, spaces)
-     struct type *type;
-     int spaces;
+recursive_dump_type (struct type *type, int spaces)
 {
   int idx;
 
-  printfi_filtered (spaces, "type node 0x%x\n", type);
-  printfi_filtered (spaces, "name '%s' (0x%x)\n", TYPE_NAME (type),
+  if (spaces == 0)
+    obstack_begin (&dont_print_type_obstack, 0);
+
+  if (TYPE_NFIELDS (type) > 0
+      || (TYPE_CPLUS_SPECIFIC (type) && TYPE_NFN_FIELDS (type) > 0))
+    {
+      struct type **first_dont_print
+      = (struct type **) obstack_base (&dont_print_type_obstack);
+
+      int i = (struct type **) obstack_next_free (&dont_print_type_obstack)
+      - first_dont_print;
+
+      while (--i >= 0)
+       {
+         if (type == first_dont_print[i])
+           {
+             printfi_filtered (spaces, "type node ");
+             gdb_print_host_address (type, gdb_stdout);
+             printf_filtered (" <same as already seen type>\n");
+             return;
+           }
+       }
+
+      obstack_ptr_grow (&dont_print_type_obstack, type);
+    }
+
+  printfi_filtered (spaces, "type node ");
+  gdb_print_host_address (type, gdb_stdout);
+  printf_filtered ("\n");
+  printfi_filtered (spaces, "name '%s' (",
                    TYPE_NAME (type) ? TYPE_NAME (type) : "<NULL>");
+  gdb_print_host_address (TYPE_NAME (type), gdb_stdout);
+  printf_filtered (")\n");
+  if (TYPE_TAG_NAME (type) != NULL)
+    {
+      printfi_filtered (spaces, "tagname '%s' (",
+                       TYPE_TAG_NAME (type));
+      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))
     {
-      case TYPE_CODE_UNDEF:
-        printf_filtered ("(TYPE_CODE_UNDEF)");
-       break;
-      case TYPE_CODE_PTR:
-       printf_filtered ("(TYPE_CODE_PTR)");
-       break;
-      case TYPE_CODE_ARRAY:
-       printf_filtered ("(TYPE_CODE_ARRAY)");
-       break;
-      case TYPE_CODE_STRUCT:
-       printf_filtered ("(TYPE_CODE_STRUCT)");
-       break;
-      case TYPE_CODE_UNION:
-       printf_filtered ("(TYPE_CODE_UNION)");
-       break;
-      case TYPE_CODE_ENUM:
-       printf_filtered ("(TYPE_CODE_ENUM)");
-       break;
-      case TYPE_CODE_FUNC:
-       printf_filtered ("(TYPE_CODE_FUNC)");
-       break;
-      case TYPE_CODE_INT:
-       printf_filtered ("(TYPE_CODE_INT)");
-       break;
-      case TYPE_CODE_FLT:
-       printf_filtered ("(TYPE_CODE_FLT)");
-       break;
-      case TYPE_CODE_VOID:
-       printf_filtered ("(TYPE_CODE_VOID)");
-       break;
-      case TYPE_CODE_SET:
-       printf_filtered ("(TYPE_CODE_SET)");
-       break;
-      case TYPE_CODE_RANGE:
-       printf_filtered ("(TYPE_CODE_RANGE)");
-       break;
-      case TYPE_CODE_PASCAL_ARRAY:
-       printf_filtered ("(TYPE_CODE_PASCAL_ARRAY)");
-       break;
-      case TYPE_CODE_ERROR:
-       printf_filtered ("(TYPE_CODE_ERROR)");
-       break;
-      case TYPE_CODE_MEMBER:
-       printf_filtered ("(TYPE_CODE_MEMBER)");
-       break;
-      case TYPE_CODE_METHOD:
-       printf_filtered ("(TYPE_CODE_METHOD)");
-       break;
-      case TYPE_CODE_REF:
-       printf_filtered ("(TYPE_CODE_REF)");
-       break;
-      case TYPE_CODE_CHAR:
-       printf_filtered ("(TYPE_CODE_CHAR)");
-       break;
-      case TYPE_CODE_BOOL:
-       printf_filtered ("(TYPE_CODE_BOOL)");
-       break;
-      default:
-       printf_filtered ("(UNKNOWN TYPE CODE)");
-       break;
+    case TYPE_CODE_UNDEF:
+      printf_filtered ("(TYPE_CODE_UNDEF)");
+      break;
+    case TYPE_CODE_PTR:
+      printf_filtered ("(TYPE_CODE_PTR)");
+      break;
+    case TYPE_CODE_ARRAY:
+      printf_filtered ("(TYPE_CODE_ARRAY)");
+      break;
+    case TYPE_CODE_STRUCT:
+      printf_filtered ("(TYPE_CODE_STRUCT)");
+      break;
+    case TYPE_CODE_UNION:
+      printf_filtered ("(TYPE_CODE_UNION)");
+      break;
+    case TYPE_CODE_ENUM:
+      printf_filtered ("(TYPE_CODE_ENUM)");
+      break;
+    case TYPE_CODE_FUNC:
+      printf_filtered ("(TYPE_CODE_FUNC)");
+      break;
+    case TYPE_CODE_INT:
+      printf_filtered ("(TYPE_CODE_INT)");
+      break;
+    case TYPE_CODE_FLT:
+      printf_filtered ("(TYPE_CODE_FLT)");
+      break;
+    case TYPE_CODE_VOID:
+      printf_filtered ("(TYPE_CODE_VOID)");
+      break;
+    case TYPE_CODE_SET:
+      printf_filtered ("(TYPE_CODE_SET)");
+      break;
+    case TYPE_CODE_RANGE:
+      printf_filtered ("(TYPE_CODE_RANGE)");
+      break;
+    case TYPE_CODE_STRING:
+      printf_filtered ("(TYPE_CODE_STRING)");
+      break;
+    case TYPE_CODE_ERROR:
+      printf_filtered ("(TYPE_CODE_ERROR)");
+      break;
+    case TYPE_CODE_MEMBER:
+      printf_filtered ("(TYPE_CODE_MEMBER)");
+      break;
+    case TYPE_CODE_METHOD:
+      printf_filtered ("(TYPE_CODE_METHOD)");
+      break;
+    case TYPE_CODE_REF:
+      printf_filtered ("(TYPE_CODE_REF)");
+      break;
+    case TYPE_CODE_CHAR:
+      printf_filtered ("(TYPE_CODE_CHAR)");
+      break;
+    case TYPE_CODE_BOOL:
+      printf_filtered ("(TYPE_CODE_BOOL)");
+      break;
+    case TYPE_CODE_TYPEDEF:
+      printf_filtered ("(TYPE_CODE_TYPEDEF)");
+      break;
+    default:
+      printf_filtered ("(UNKNOWN TYPE CODE)");
+      break;
     }
   puts_filtered ("\n");
   printfi_filtered (spaces, "length %d\n", TYPE_LENGTH (type));
-  printfi_filtered (spaces, "objfile 0x%x\n", TYPE_OBJFILE (type));
-  printfi_filtered (spaces, "target_type 0x%x\n", TYPE_TARGET_TYPE (type));
+  printfi_filtered (spaces, "objfile ");
+  gdb_print_host_address (TYPE_OBJFILE (type), gdb_stdout);
+  printf_filtered ("\n");
+  printfi_filtered (spaces, "target_type ");
+  gdb_print_host_address (TYPE_TARGET_TYPE (type), gdb_stdout);
+  printf_filtered ("\n");
   if (TYPE_TARGET_TYPE (type) != NULL)
     {
       recursive_dump_type (TYPE_TARGET_TYPE (type), spaces + 2);
     }
-  printfi_filtered (spaces, "pointer_type 0x%x\n",
-                   TYPE_POINTER_TYPE (type));
-  printfi_filtered (spaces, "reference_type 0x%x\n",
-                   TYPE_REFERENCE_TYPE (type));
-  printfi_filtered (spaces, "function_type 0x%x\n",
-                   TYPE_FUNCTION_TYPE (type));
+  printfi_filtered (spaces, "pointer_type ");
+  gdb_print_host_address (TYPE_POINTER_TYPE (type), gdb_stdout);
+  printf_filtered ("\n");
+  printfi_filtered (spaces, "reference_type ");
+  gdb_print_host_address (TYPE_REFERENCE_TYPE (type), gdb_stdout);
+  printf_filtered ("\n");
   printfi_filtered (spaces, "flags 0x%x", TYPE_FLAGS (type));
   if (TYPE_FLAGS (type) & TYPE_FLAG_UNSIGNED)
     {
       puts_filtered (" TYPE_FLAG_UNSIGNED");
     }
-  if (TYPE_FLAGS (type) & TYPE_FLAG_SIGNED)
-    {
-      puts_filtered (" TYPE_FLAG_SIGNED");
-    }
   if (TYPE_FLAGS (type) & TYPE_FLAG_STUB)
     {
       puts_filtered (" TYPE_FLAG_STUB");
     }
   puts_filtered ("\n");
-  printfi_filtered (spaces, "nfields %d 0x%x\n", TYPE_NFIELDS (type),
-                   TYPE_FIELDS (type));
+  printfi_filtered (spaces, "nfields %d ", TYPE_NFIELDS (type));
+  gdb_print_host_address (TYPE_FIELDS (type), gdb_stdout);
+  puts_filtered ("\n");
   for (idx = 0; idx < TYPE_NFIELDS (type); idx++)
     {
       printfi_filtered (spaces + 2,
-                       "[%d] bitpos %d bitsize %d type 0x%x name '%s' (0x%x)\n",
+                       "[%d] bitpos %d bitsize %d type ",
                        idx, TYPE_FIELD_BITPOS (type, idx),
-                       TYPE_FIELD_BITSIZE (type, idx),
-                       TYPE_FIELD_TYPE (type, idx),
-                       TYPE_FIELD_NAME (type, idx),
-                       TYPE_FIELD_NAME (type, idx) != NULL
-                         ? TYPE_FIELD_NAME (type, idx)
-                         : "<NULL>");
+                       TYPE_FIELD_BITSIZE (type, idx));
+      gdb_print_host_address (TYPE_FIELD_TYPE (type, idx), gdb_stdout);
+      printf_filtered (" name '%s' (",
+                      TYPE_FIELD_NAME (type, idx) != NULL
+                      ? TYPE_FIELD_NAME (type, idx)
+                      : "<NULL>");
+      gdb_print_host_address (TYPE_FIELD_NAME (type, idx), gdb_stdout);
+      printf_filtered (")\n");
       if (TYPE_FIELD_TYPE (type, idx) != NULL)
        {
          recursive_dump_type (TYPE_FIELD_TYPE (type, idx), spaces + 4);
        }
     }
-  printfi_filtered (spaces, "vptr_basetype 0x%x\n",
-                   TYPE_VPTR_BASETYPE (type));
+  printfi_filtered (spaces, "vptr_basetype ");
+  gdb_print_host_address (TYPE_VPTR_BASETYPE (type), gdb_stdout);
+  puts_filtered ("\n");
   if (TYPE_VPTR_BASETYPE (type) != NULL)
     {
       recursive_dump_type (TYPE_VPTR_BASETYPE (type), spaces + 2);
@@ -1239,32 +2749,246 @@ recursive_dump_type (type, spaces)
   printfi_filtered (spaces, "vptr_fieldno %d\n", TYPE_VPTR_FIELDNO (type));
   switch (TYPE_CODE (type))
     {
-      case TYPE_CODE_METHOD:
-      case TYPE_CODE_FUNC:
-       printfi_filtered (spaces, "arg_types 0x%x\n", TYPE_ARG_TYPES (type));
-       print_arg_types (TYPE_ARG_TYPES (type), spaces);
-       break;
-
-      case TYPE_CODE_STRUCT:
-       printfi_filtered (spaces, "cplus_stuff 0x%x\n",
-                         TYPE_CPLUS_SPECIFIC (type));
-       print_cplus_stuff (type, spaces);
-       break;
+    case TYPE_CODE_METHOD:
+    case TYPE_CODE_FUNC:
+      printfi_filtered (spaces, "arg_types ");
+      gdb_print_host_address (TYPE_ARG_TYPES (type), gdb_stdout);
+      puts_filtered ("\n");
+      print_arg_types (TYPE_ARG_TYPES (type), spaces);
+      break;
 
-      default:
-       /* We have to pick one of the union types to be able print and test
-          the value.  Pick cplus_struct_type, even though we know it isn't
-          any particular one. */
-       printfi_filtered (spaces, "type_specific 0x%x",
-                         TYPE_CPLUS_SPECIFIC (type));
-       if (TYPE_CPLUS_SPECIFIC (type) != NULL)
-         {
-           printf_filtered (" (unknown data form)");
-         }
-       printf_filtered ("\n");
-       break;
+    case TYPE_CODE_STRUCT:
+      printfi_filtered (spaces, "cplus_stuff ");
+      gdb_print_host_address (TYPE_CPLUS_SPECIFIC (type), gdb_stdout);
+      puts_filtered ("\n");
+      print_cplus_stuff (type, spaces);
+      break;
+
+    default:
+      /* We have to pick one of the union types to be able print and test
+         the value.  Pick cplus_struct_type, even though we know it isn't
+         any particular one. */
+      printfi_filtered (spaces, "type_specific ");
+      gdb_print_host_address (TYPE_CPLUS_SPECIFIC (type), gdb_stdout);
+      if (TYPE_CPLUS_SPECIFIC (type) != NULL)
+       {
+         printf_filtered (" (unknown data form)");
+       }
+      printf_filtered ("\n");
+      break;
 
     }
+  if (spaces == 0)
+    obstack_free (&dont_print_type_obstack, NULL);
 }
 
-#endif /* MAINTENANCE_CMDS */
+static void build_gdbtypes (void);
+static void
+build_gdbtypes (void)
+{
+  builtin_type_void =
+    init_type (TYPE_CODE_VOID, 1,
+              0,
+              "void", (struct objfile *) NULL);
+  builtin_type_char =
+    init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+              0,
+              "char", (struct objfile *) NULL);
+  TYPE_FLAGS (builtin_type_char) |= TYPE_FLAG_NOSIGN;
+  builtin_type_true_char =
+    init_type (TYPE_CODE_CHAR, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+              0,
+              "true character", (struct objfile *) NULL);
+  builtin_type_signed_char =
+    init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+              0,
+              "signed char", (struct objfile *) NULL);
+  builtin_type_unsigned_char =
+    init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+              TYPE_FLAG_UNSIGNED,
+              "unsigned char", (struct objfile *) NULL);
+  builtin_type_short =
+    init_type (TYPE_CODE_INT, TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+              0,
+              "short", (struct objfile *) NULL);
+  builtin_type_unsigned_short =
+    init_type (TYPE_CODE_INT, TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+              TYPE_FLAG_UNSIGNED,
+              "unsigned short", (struct objfile *) NULL);
+  builtin_type_int =
+    init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
+              0,
+              "int", (struct objfile *) NULL);
+  builtin_type_unsigned_int =
+    init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
+              TYPE_FLAG_UNSIGNED,
+              "unsigned int", (struct objfile *) NULL);
+  builtin_type_long =
+    init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT,
+              0,
+              "long", (struct objfile *) NULL);
+  builtin_type_unsigned_long =
+    init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT,
+              TYPE_FLAG_UNSIGNED,
+              "unsigned long", (struct objfile *) NULL);
+  builtin_type_long_long =
+    init_type (TYPE_CODE_INT, TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+              0,
+              "long long", (struct objfile *) NULL);
+  builtin_type_unsigned_long_long =
+    init_type (TYPE_CODE_INT, TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+              TYPE_FLAG_UNSIGNED,
+              "unsigned long long", (struct objfile *) NULL);
+  builtin_type_float =
+    init_type (TYPE_CODE_FLT, TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
+              0,
+              "float", (struct objfile *) NULL);
+  builtin_type_double =
+    init_type (TYPE_CODE_FLT, TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+              0,
+              "double", (struct objfile *) NULL);
+  builtin_type_long_double =
+    init_type (TYPE_CODE_FLT, TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
+              0,
+              "long double", (struct objfile *) NULL);
+  builtin_type_complex =
+    init_type (TYPE_CODE_COMPLEX, 2 * TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
+              0,
+              "complex", (struct objfile *) NULL);
+  TYPE_TARGET_TYPE (builtin_type_complex) = builtin_type_float;
+  builtin_type_double_complex =
+    init_type (TYPE_CODE_COMPLEX, 2 * TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+              0,
+              "double complex", (struct objfile *) NULL);
+  TYPE_TARGET_TYPE (builtin_type_double_complex) = builtin_type_double;
+  builtin_type_string =
+    init_type (TYPE_CODE_STRING, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+              0,
+              "string", (struct objfile *) NULL);
+  builtin_type_int8 =
+    init_type (TYPE_CODE_INT, 8 / 8,
+              0,
+              "int8_t", (struct objfile *) NULL);
+  builtin_type_uint8 =
+    init_type (TYPE_CODE_INT, 8 / 8,
+              TYPE_FLAG_UNSIGNED,
+              "uint8_t", (struct objfile *) NULL);
+  builtin_type_int16 =
+    init_type (TYPE_CODE_INT, 16 / 8,
+              0,
+              "int16_t", (struct objfile *) NULL);
+  builtin_type_uint16 =
+    init_type (TYPE_CODE_INT, 16 / 8,
+              TYPE_FLAG_UNSIGNED,
+              "uint16_t", (struct objfile *) NULL);
+  builtin_type_int32 =
+    init_type (TYPE_CODE_INT, 32 / 8,
+              0,
+              "int32_t", (struct objfile *) NULL);
+  builtin_type_uint32 =
+    init_type (TYPE_CODE_INT, 32 / 8,
+              TYPE_FLAG_UNSIGNED,
+              "uint32_t", (struct objfile *) NULL);
+  builtin_type_int64 =
+    init_type (TYPE_CODE_INT, 64 / 8,
+              0,
+              "int64_t", (struct objfile *) NULL);
+  builtin_type_uint64 =
+    init_type (TYPE_CODE_INT, 64 / 8,
+              TYPE_FLAG_UNSIGNED,
+              "uint64_t", (struct objfile *) NULL);
+  builtin_type_bool =
+    init_type (TYPE_CODE_BOOL, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+              0,
+              "bool", (struct objfile *) NULL);
+
+  /* Add user knob for controlling resolution of opaque types */
+  add_show_from_set
+    (add_set_cmd ("opaque-type-resolution", class_support, var_boolean, (char *) &opaque_type_resolution,
+                 "Set resolution of opaque struct/class/union types (if set before loading symbols).",
+                 &setlist),
+     &showlist);
+  opaque_type_resolution = 1;
+
+
+  /* Build SIMD types.  */
+  builtin_type_v4sf
+    = init_simd_type ("__builtin_v4sf", builtin_type_float, "f", 4);
+  builtin_type_v4si
+    = init_simd_type ("__builtin_v4si", builtin_type_int32, "f", 4);
+  builtin_type_v8qi
+    = init_simd_type ("__builtin_v8qi", builtin_type_int8, "f", 8);
+  builtin_type_v4hi
+    = init_simd_type ("__builtin_v4hi", builtin_type_int16, "f", 4);
+  builtin_type_v2si
+    = init_simd_type ("__builtin_v2si", builtin_type_int32, "f", 2);
+
+  /* Pointer/Address types. */
+  /* NOTE: At present there is no way of differentiating between at
+     target address and the target C language pointer type type even
+     though the two can be different (cf d10v) */
+  builtin_type_ptr = make_pointer_type (builtin_type_void, NULL);
+  builtin_type_CORE_ADDR =
+    init_type (TYPE_CODE_INT, TARGET_PTR_BIT / 8,
+              TYPE_FLAG_UNSIGNED,
+              "__CORE_ADDR", (struct objfile *) NULL);
+  builtin_type_bfd_vma =
+    init_type (TYPE_CODE_INT, TARGET_BFD_VMA_BIT / 8,
+              TYPE_FLAG_UNSIGNED,
+              "__bfd_vma", (struct objfile *) NULL);
+}
+
+
+extern void _initialize_gdbtypes (void);
+void
+_initialize_gdbtypes (void)
+{
+  struct cmd_list_element *c;
+  build_gdbtypes ();
+
+  /* FIXME - For the moment, handle types by swapping them in and out.
+     Should be using the per-architecture data-pointer and a large
+     struct. */
+  register_gdbarch_swap (&builtin_type_void, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_char, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_short, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_int, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_long, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_long_long, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_signed_char, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_unsigned_char, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_unsigned_short, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_unsigned_int, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_unsigned_long, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_unsigned_long_long, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_float, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_double, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_long_double, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_complex, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_double_complex, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_string, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_int8, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_uint8, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_int16, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_uint16, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_int32, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_uint32, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_int64, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_uint64, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_v4sf, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_v4si, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_v8qi, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_v4hi, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_v2si, sizeof (struct type *), NULL);
+  REGISTER_GDBARCH_SWAP (builtin_type_ptr);
+  REGISTER_GDBARCH_SWAP (builtin_type_CORE_ADDR);
+  REGISTER_GDBARCH_SWAP (builtin_type_bfd_vma);
+  register_gdbarch_swap (NULL, 0, build_gdbtypes);
+
+  add_show_from_set (
+                    add_set_cmd ("overload", no_class, var_zinteger, (char *) &overload_debug,
+                                 "Set debugging of C++ overloading.\n\
+                         When enabled, ranking of the functions\n\
+                         is displayed.", &setdebuglist),
+                    &showdebuglist);
+}
This page took 0.059262 seconds and 4 git commands to generate.