/* Support routines for manipulating internal types for GDB.
- Copyright (C) 1992, 93, 94, 95, 96, 1998 Free Software Foundation, Inc.
+
+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002,
+ 2003, 2004, 2005, 2006, 2007, 2008, 2009 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 3 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include "gdb_string.h"
#include "demangle.h"
#include "complaints.h"
#include "gdbcmd.h"
+#include "wrapper.h"
+#include "cp-abi.h"
+#include "gdb_assert.h"
+#include "hashtab.h"
+
+
+/* Floatformat pairs. */
+const struct floatformat *floatformats_ieee_single[BFD_ENDIAN_UNKNOWN] = {
+ &floatformat_ieee_single_big,
+ &floatformat_ieee_single_little
+};
+const struct floatformat *floatformats_ieee_double[BFD_ENDIAN_UNKNOWN] = {
+ &floatformat_ieee_double_big,
+ &floatformat_ieee_double_little
+};
+const struct floatformat *floatformats_ieee_double_littlebyte_bigword[BFD_ENDIAN_UNKNOWN] = {
+ &floatformat_ieee_double_big,
+ &floatformat_ieee_double_littlebyte_bigword
+};
+const struct floatformat *floatformats_i387_ext[BFD_ENDIAN_UNKNOWN] = {
+ &floatformat_i387_ext,
+ &floatformat_i387_ext
+};
+const struct floatformat *floatformats_m68881_ext[BFD_ENDIAN_UNKNOWN] = {
+ &floatformat_m68881_ext,
+ &floatformat_m68881_ext
+};
+const struct floatformat *floatformats_arm_ext[BFD_ENDIAN_UNKNOWN] = {
+ &floatformat_arm_ext_big,
+ &floatformat_arm_ext_littlebyte_bigword
+};
+const struct floatformat *floatformats_ia64_spill[BFD_ENDIAN_UNKNOWN] = {
+ &floatformat_ia64_spill_big,
+ &floatformat_ia64_spill_little
+};
+const struct floatformat *floatformats_ia64_quad[BFD_ENDIAN_UNKNOWN] = {
+ &floatformat_ia64_quad_big,
+ &floatformat_ia64_quad_little
+};
+const struct floatformat *floatformats_vax_f[BFD_ENDIAN_UNKNOWN] = {
+ &floatformat_vax_f,
+ &floatformat_vax_f
+};
+const struct floatformat *floatformats_vax_d[BFD_ENDIAN_UNKNOWN] = {
+ &floatformat_vax_d,
+ &floatformat_vax_d
+};
+const struct floatformat *floatformats_ibm_long_double[BFD_ENDIAN_UNKNOWN] = {
+ &floatformat_ibm_long_double,
+ &floatformat_ibm_long_double
+};
-/* 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;
int opaque_type_resolution = 1;
+static void
+show_opaque_type_resolution (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c,
+ const char *value)
+{
+ fprintf_filtered (file, _("\
+Resolution of opaque struct/class/union types (if set before loading symbols) is %s.\n"),
+ value);
+}
+int overload_debug = 0;
+static void
+show_overload_debug (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("Debugging of C++ overloading is %s.\n"),
+ value);
+}
-struct extra { char str[128]; int len; }; /* maximum extention is 128! FIXME */
+struct extra
+ {
+ char str[128];
+ int len;
+ }; /* Maximum extension is 128! FIXME */
-static void add_name PARAMS ((struct extra *, char *));
-static void add_mangled_type PARAMS ((struct extra *, struct type *));
-#if 0
-static void cfront_mangle_name PARAMS ((struct type *, int, int));
-#endif
-static void print_bit_vector PARAMS ((B_TYPE *, int));
-static void print_arg_types PARAMS ((struct type **, int));
-static void dump_fn_fieldlists PARAMS ((struct type *, int));
-static void print_cplus_stuff PARAMS ((struct type *, int));
-static void virtual_base_list_aux PARAMS ((struct type *dclass));
+static void print_bit_vector (B_TYPE *, int);
+static void print_arg_types (struct field *, int, int);
+static void dump_fn_fieldlists (struct type *, int);
+static void print_cplus_stuff (struct type *, int);
-/* 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. */
+/* Allocate a new OBJFILE-associated type structure and fill it
+ with some defaults. Space for the type structure is allocated
+ on the objfile's objfile_obstack. */
struct type *
-alloc_type (objfile)
- struct objfile *objfile;
+alloc_type (struct objfile *objfile)
{
- register struct type *type;
+ struct type *type;
- /* Alloc the structure and start off with all fields zeroed. */
+ gdb_assert (objfile != NULL);
- if (objfile == NULL)
- {
- type = (struct type *) xmalloc (sizeof (struct type));
- }
- else
- {
- type = (struct type *) obstack_alloc (&objfile -> type_obstack,
- sizeof (struct type));
- OBJSTAT (objfile, n_types++);
- }
- memset ((char *) type, 0, sizeof (struct type));
+ /* Alloc the structure and start off with all fields zeroed. */
+ type = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct type);
+ TYPE_MAIN_TYPE (type) = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ struct main_type);
+ OBJSTAT (objfile, n_types++);
+
+ TYPE_OBJFILE_OWNED (type) = 1;
+ TYPE_OWNER (type).objfile = objfile;
+
+ /* Initialize the fields that might not be zero. */
+
+ TYPE_CODE (type) = TYPE_CODE_UNDEF;
+ TYPE_VPTR_FIELDNO (type) = -1;
+ TYPE_CHAIN (type) = type; /* Chain back to itself. */
+
+ return type;
+}
+
+/* Allocate a new GDBARCH-associated type structure and fill it
+ with some defaults. Space for the type structure is allocated
+ on the heap. */
+
+struct type *
+alloc_type_arch (struct gdbarch *gdbarch)
+{
+ struct type *type;
+
+ gdb_assert (gdbarch != NULL);
+
+ /* Alloc the structure and start off with all fields zeroed. */
+
+ type = XZALLOC (struct type);
+ TYPE_MAIN_TYPE (type) = XZALLOC (struct main_type);
+
+ TYPE_OBJFILE_OWNED (type) = 0;
+ TYPE_OWNER (type).gdbarch = gdbarch;
- /* Initialize the fields that might not be zero. */
+ /* Initialize the fields that might not be zero. */
TYPE_CODE (type) = TYPE_CODE_UNDEF;
- TYPE_OBJFILE (type) = objfile;
TYPE_VPTR_FIELDNO (type) = -1;
- TYPE_CV_TYPE (type) = type; /* chain back to itself */
+ TYPE_CHAIN (type) = type; /* Chain back to itself. */
+
+ return type;
+}
+
+/* If TYPE is objfile-associated, allocate a new type structure
+ associated with the same objfile. If TYPE is gdbarch-associated,
+ allocate a new type structure associated with the same gdbarch. */
+
+struct type *
+alloc_type_copy (const struct type *type)
+{
+ if (TYPE_OBJFILE_OWNED (type))
+ return alloc_type (TYPE_OWNER (type).objfile);
+ else
+ return alloc_type_arch (TYPE_OWNER (type).gdbarch);
+}
+
+/* If TYPE is gdbarch-associated, return that architecture.
+ If TYPE is objfile-associated, return that objfile's architecture. */
+
+struct gdbarch *
+get_type_arch (const struct type *type)
+{
+ if (TYPE_OBJFILE_OWNED (type))
+ return get_objfile_arch (TYPE_OWNER (type).objfile);
+ else
+ return TYPE_OWNER (type).gdbarch;
+}
+
+
+/* Alloc a new type instance structure, fill it with some defaults,
+ and point it at OLDTYPE. Allocate the new type instance from the
+ same place as OLDTYPE. */
+
+static struct type *
+alloc_type_instance (struct type *oldtype)
+{
+ struct type *type;
+
+ /* Allocate the structure. */
+
+ if (! TYPE_OBJFILE_OWNED (oldtype))
+ type = XZALLOC (struct type);
+ else
+ type = OBSTACK_ZALLOC (&TYPE_OBJFILE (oldtype)->objfile_obstack,
+ struct type);
+
+ TYPE_MAIN_TYPE (type) = TYPE_MAIN_TYPE (oldtype);
+
+ TYPE_CHAIN (type) = type; /* Chain back to itself for now. */
+
+ return type;
+}
+
+/* Clear all remnants of the previous type at TYPE, in preparation for
+ replacing it with something else. Preserve owner information. */
+static void
+smash_type (struct type *type)
+{
+ int objfile_owned = TYPE_OBJFILE_OWNED (type);
+ union type_owner owner = TYPE_OWNER (type);
+
+ memset (TYPE_MAIN_TYPE (type), 0, sizeof (struct main_type));
+
+ /* Restore owner information. */
+ TYPE_OBJFILE_OWNED (type) = objfile_owned;
+ TYPE_OWNER (type) = owner;
+
+ /* For now, delete the rings. */
+ TYPE_CHAIN (type) = type;
- return (type);
+ /* For now, leave the pointer/reference types alone. */
}
/* Lookup a pointer to a type TYPE. TYPEPTR, if nonzero, points
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 */
- struct objfile *objfile;
+ struct type *ntype; /* New type */
+ struct type *chain;
ntype = TYPE_POINTER_TYPE (type);
- if (ntype)
+ if (ntype)
{
- if (typeptr == 0)
- return ntype; /* Don't care about alloc, and have new type. */
+ 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. */
+ {
+ *typeptr = ntype; /* Tracking alloc, and have new type. */
return ntype;
- }
+ }
}
if (typeptr == 0 || *typeptr == 0) /* We'll need to allocate one. */
{
- ntype = alloc_type (TYPE_OBJFILE (type));
+ ntype = alloc_type_copy (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);
- memset ((char *) ntype, 0, sizeof (struct type));
- TYPE_OBJFILE (ntype) = objfile;
+ chain = TYPE_CHAIN (ntype);
+ smash_type (ntype);
+ TYPE_CHAIN (ntype) = chain;
}
TYPE_TARGET_TYPE (ntype) = type;
TYPE_POINTER_TYPE (type) = ntype;
- /* FIXME! Assume the machine has only one representation for pointers! */
+ /* FIXME! Assume the machine has only one representation for
+ pointers! */
- TYPE_LENGTH (ntype) = TARGET_PTR_BIT / TARGET_CHAR_BIT;
+ TYPE_LENGTH (ntype)
+ = gdbarch_ptr_bit (get_type_arch (type)) / TARGET_CHAR_BIT;
TYPE_CODE (ntype) = TYPE_CODE_PTR;
- /* pointers are unsigned */
- TYPE_FLAGS (ntype) |= TYPE_FLAG_UNSIGNED;
-
+ /* Mark pointers as unsigned. The target converts between pointers
+ and addresses (CORE_ADDRs) using gdbarch_pointer_to_address and
+ gdbarch_address_to_pointer. */
+ TYPE_UNSIGNED (ntype) = 1;
+
if (!TYPE_POINTER_TYPE (type)) /* Remember it, if don't have one. */
TYPE_POINTER_TYPE (type) = ntype;
+ /* Update the length of all the other variants of this type. */
+ chain = TYPE_CHAIN (ntype);
+ while (chain != ntype)
+ {
+ TYPE_LENGTH (chain) = TYPE_LENGTH (ntype);
+ chain = TYPE_CHAIN (chain);
+ }
+
return ntype;
}
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
- 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. */
+/* Lookup a C++ `reference' to a type TYPE. 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_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 */
- struct objfile *objfile;
+ struct type *ntype; /* New type */
+ struct type *chain;
ntype = TYPE_REFERENCE_TYPE (type);
- if (ntype)
+ if (ntype)
{
- if (typeptr == 0)
- return ntype; /* Don't care about alloc, and have new type. */
+ 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. */
+ {
+ *typeptr = ntype; /* Tracking alloc, and have new type. */
return ntype;
- }
+ }
}
if (typeptr == 0 || *typeptr == 0) /* We'll need to allocate one. */
{
- ntype = alloc_type (TYPE_OBJFILE (type));
+ ntype = alloc_type_copy (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);
- memset ((char *) ntype, 0, sizeof (struct type));
- TYPE_OBJFILE (ntype) = objfile;
+ chain = TYPE_CHAIN (ntype);
+ smash_type (ntype);
+ TYPE_CHAIN (ntype) = chain;
}
TYPE_TARGET_TYPE (ntype) = type;
TYPE_REFERENCE_TYPE (type) = ntype;
- /* FIXME! Assume the machine has only one representation for references,
- and that it matches the (only) representation for pointers! */
+ /* FIXME! Assume the machine has only one representation for
+ references, and that it matches the (only) representation for
+ pointers! */
- TYPE_LENGTH (ntype) = TARGET_PTR_BIT / TARGET_CHAR_BIT;
+ TYPE_LENGTH (ntype) =
+ gdbarch_ptr_bit (get_type_arch (type)) / 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;
+ /* Update the length of all the other variants of this type. */
+ chain = TYPE_CHAIN (ntype);
+ while (chain != ntype)
+ {
+ TYPE_LENGTH (chain) = TYPE_LENGTH (ntype);
+ chain = TYPE_CHAIN (chain);
+ }
+
return ntype;
}
-/* Same as above, but caller doesn't care about memory allocation details. */
+/* 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
- to a pointer to memory where the function type should be stored.
- If *TYPEPTR is zero, update it to point to the function type we return.
- We allocate new memory if needed. */
+/* Lookup a function type that returns type TYPE. TYPEPTR, if
+ nonzero, points to a pointer to memory where the function type
+ should be stored. If *TYPEPTR is zero, update it to point to the
+ function type we return. 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 */
- struct objfile *objfile;
+ struct type *ntype; /* New type */
if (typeptr == 0 || *typeptr == 0) /* We'll need to allocate one. */
{
- ntype = alloc_type (TYPE_OBJFILE (type));
+ ntype = alloc_type_copy (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);
- memset ((char *) ntype, 0, sizeof (struct type));
- TYPE_OBJFILE (ntype) = objfile;
+ smash_type (ntype);
}
TYPE_TARGET_TYPE (ntype) = type;
TYPE_LENGTH (ntype) = 1;
TYPE_CODE (ntype) = TYPE_CODE_FUNC;
-
+
return ntype;
}
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);
+}
+
+/* Identify address space identifier by name --
+ return the integer flag defined in gdbtypes.h. */
+extern int
+address_space_name_to_int (struct gdbarch *gdbarch, char *space_identifier)
+{
+ int type_flags;
+ /* Check for known address space delimiters. */
+ if (!strcmp (space_identifier, "code"))
+ return TYPE_INSTANCE_FLAG_CODE_SPACE;
+ else if (!strcmp (space_identifier, "data"))
+ return TYPE_INSTANCE_FLAG_DATA_SPACE;
+ else if (gdbarch_address_class_name_to_type_flags_p (gdbarch)
+ && gdbarch_address_class_name_to_type_flags (gdbarch,
+ space_identifier,
+ &type_flags))
+ return type_flags;
+ else
+ error (_("Unknown address space specifier: \"%s\""), space_identifier);
+}
+
+/* Identify address space identifier by integer flag as defined in
+ gdbtypes.h -- return the string version of the adress space name. */
+
+const char *
+address_space_int_to_name (struct gdbarch *gdbarch, int space_flag)
+{
+ if (space_flag & TYPE_INSTANCE_FLAG_CODE_SPACE)
+ return "code";
+ else if (space_flag & TYPE_INSTANCE_FLAG_DATA_SPACE)
+ return "data";
+ else if ((space_flag & TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL)
+ && gdbarch_address_class_type_flags_to_name_p (gdbarch))
+ return gdbarch_address_class_type_flags_to_name (gdbarch, space_flag);
+ else
+ return NULL;
+}
+
+/* Create a new type with instance flags NEW_FLAGS, based on TYPE.
+
+ If STORAGE is non-NULL, create the new type instance there.
+ STORAGE must be in the same obstack as TYPE. */
+
+static struct type *
+make_qualified_type (struct type *type, int new_flags,
+ struct type *storage)
{
- return make_function_type (type, (struct type **)0);
+ struct type *ntype;
+
+ ntype = type;
+ do
+ {
+ if (TYPE_INSTANCE_FLAGS (ntype) == new_flags)
+ return ntype;
+ ntype = TYPE_CHAIN (ntype);
+ }
+ while (ntype != type);
+
+ /* Create a new type instance. */
+ if (storage == NULL)
+ ntype = alloc_type_instance (type);
+ else
+ {
+ /* If STORAGE was provided, it had better be in the same objfile
+ as TYPE. Otherwise, we can't link it into TYPE's cv chain:
+ if one objfile is freed and the other kept, we'd have
+ dangling pointers. */
+ gdb_assert (TYPE_OBJFILE (type) == TYPE_OBJFILE (storage));
+
+ ntype = storage;
+ TYPE_MAIN_TYPE (ntype) = TYPE_MAIN_TYPE (type);
+ TYPE_CHAIN (ntype) = ntype;
+ }
+
+ /* Pointers or references to the original type are not relevant to
+ the new type. */
+ TYPE_POINTER_TYPE (ntype) = (struct type *) 0;
+ TYPE_REFERENCE_TYPE (ntype) = (struct type *) 0;
+
+ /* Chain the new qualified type to the old type. */
+ TYPE_CHAIN (ntype) = TYPE_CHAIN (type);
+ TYPE_CHAIN (type) = ntype;
+
+ /* Now set the instance flags and return the new type. */
+ TYPE_INSTANCE_FLAGS (ntype) = new_flags;
+
+ /* Set length of new type to that of the original type. */
+ TYPE_LENGTH (ntype) = TYPE_LENGTH (type);
+
+ return ntype;
}
+/* Make an address-space-delimited variant of a type -- a type that
+ is identical to the one supplied except that it has an address
+ space attribute attached to it (such as "code" or "data").
+
+ The space attributes "code" and "data" are for Harvard
+ architectures. The address space attributes are for architectures
+ which have alternately sized pointers or pointers with alternate
+ representations. */
+
+struct type *
+make_type_with_address_space (struct type *type, int space_flag)
+{
+ struct type *ntype;
+ int new_flags = ((TYPE_INSTANCE_FLAGS (type)
+ & ~(TYPE_INSTANCE_FLAG_CODE_SPACE
+ | TYPE_INSTANCE_FLAG_DATA_SPACE
+ | TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL))
+ | space_flag);
+
+ return make_qualified_type (type, new_flags, NULL);
+}
/* 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. */
+ If TYPEPTR and *TYPEPTR are non-zero, then *TYPEPTR points to
+ storage to hold the new qualified type; *TYPEPTR and TYPE must be
+ in the same objfile. Otherwise, allocate fresh memory for the new
+ type whereever TYPE lives. If TYPEPTR is non-zero, set it to the
+ new type we construct. */
struct type *
-make_cv_type (cnst, voltl, type, typeptr)
- int cnst;
- int voltl;
- struct type *type;
- struct type **typeptr;
-{
- register struct type *ntype; /* New type */
- register struct type *tmp_type = type; /* tmp type */
+make_cv_type (int cnst, int voltl,
+ struct type *type,
+ struct type **typeptr)
+{
+ struct type *ntype; /* New type */
+ struct type *tmp_type = type; /* tmp type */
struct objfile *objfile;
- ntype = TYPE_CV_TYPE (type);
+ int new_flags = (TYPE_INSTANCE_FLAGS (type)
+ & ~(TYPE_INSTANCE_FLAG_CONST | TYPE_INSTANCE_FLAG_VOLATILE));
- 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 (cnst)
+ new_flags |= TYPE_INSTANCE_FLAG_CONST;
- 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. */
+ if (voltl)
+ new_flags |= TYPE_INSTANCE_FLAG_VOLATILE;
+
+ if (typeptr && *typeptr != NULL)
{
- ntype = *typeptr;
- objfile = TYPE_OBJFILE (ntype);
- /* memset ((char *) ntype, 0, sizeof (struct type)); */
- TYPE_OBJFILE (ntype) = objfile;
+ /* TYPE and *TYPEPTR must be in the same objfile. We can't have
+ a C-V variant chain that threads across objfiles: if one
+ objfile gets freed, then the other has a broken C-V chain.
+
+ This code used to try to copy over the main type from TYPE to
+ *TYPEPTR if they were in different objfiles, but that's
+ wrong, too: TYPE may have a field list or member function
+ lists, which refer to types of their own, etc. etc. The
+ whole shebang would need to be copied over recursively; you
+ can't have inter-objfile pointers. The only thing to do is
+ to leave stub types as stub types, and look them up afresh by
+ name each time you encounter them. */
+ gdb_assert (TYPE_OBJFILE (*typeptr) == TYPE_OBJFILE (type));
}
+
+ ntype = make_qualified_type (type, new_flags,
+ typeptr ? *typeptr : NULL);
- /* 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 */
+ if (typeptr != NULL)
+ *typeptr = ntype;
- /* Set flags appropriately */
- if (cnst)
- TYPE_FLAGS (ntype) |= TYPE_FLAG_CONST;
- else
- TYPE_FLAGS (ntype) &= ~TYPE_FLAG_CONST;
+ return ntype;
+}
- if (voltl)
- TYPE_FLAGS (ntype) |= TYPE_FLAG_VOLATILE;
- else
- TYPE_FLAGS (ntype) &= ~TYPE_FLAG_VOLATILE;
+/* Replace the contents of ntype with the type *type. This changes the
+ contents, rather than the pointer for TYPE_MAIN_TYPE (ntype); thus
+ the changes are propogated to all types in the TYPE_CHAIN.
- /* Fix the chain of cv variants */
- TYPE_CV_TYPE (ntype) = type;
- TYPE_CV_TYPE (tmp_type) = ntype;
+ In order to build recursive types, it's inevitable that we'll need
+ to update types in place --- but this sort of indiscriminate
+ smashing is ugly, and needs to be replaced with something more
+ controlled. TYPE_MAIN_TYPE is a step in this direction; it's not
+ clear if more steps are needed. */
+void
+replace_type (struct type *ntype, struct type *type)
+{
+ struct type *chain;
- return ntype;
-}
+ /* These two types had better be in the same objfile. Otherwise,
+ the assignment of one type's main type structure to the other
+ will produce a type with references to objects (names; field
+ lists; etc.) allocated on an objfile other than its own. */
+ gdb_assert (TYPE_OBJFILE (ntype) == TYPE_OBJFILE (ntype));
+ *TYPE_MAIN_TYPE (ntype) = *TYPE_MAIN_TYPE (type);
+ /* The type length is not a part of the main type. Update it for
+ each type on the variant chain. */
+ chain = ntype;
+ do
+ {
+ /* Assert that this element of the chain has no address-class bits
+ set in its flags. Such type variants might have type lengths
+ which are supposed to be different from the non-address-class
+ variants. This assertion shouldn't ever be triggered because
+ symbol readers which do construct address-class variants don't
+ call replace_type(). */
+ gdb_assert (TYPE_ADDRESS_CLASS_ALL (chain) == 0);
+
+ TYPE_LENGTH (chain) = TYPE_LENGTH (type);
+ chain = TYPE_CHAIN (chain);
+ }
+ while (ntype != chain);
+ /* Assert that the two types have equivalent instance qualifiers.
+ This should be true for at least all of our debug readers. */
+ gdb_assert (TYPE_INSTANCE_FLAGS (ntype) == TYPE_INSTANCE_FLAGS (type));
+}
/* Implement direct support for MEMBER_TYPE in GNU C++.
May need to construct such a type if this is the first use.
of the aggregate that the member belongs to. */
struct type *
-lookup_member_type (type, domain)
- struct type *type;
- struct type *domain;
+lookup_memberptr_type (struct type *type, struct type *domain)
{
- register struct type *mtype;
+ struct type *mtype;
- mtype = alloc_type (TYPE_OBJFILE (type));
- smash_to_member_type (mtype, domain, type);
- return (mtype);
+ mtype = alloc_type_copy (type);
+ smash_to_memberptr_type (mtype, domain, type);
+ return mtype;
}
-/* Allocate a stub method whose return type is TYPE.
- This apparently happens for speed of symbol reading, since parsing
- out the arguments to the method is cpu-intensive, the way we are doing
- it. So, we will fill in arguments later.
- This always returns a fresh type. */
+/* Return a pointer-to-method type, for a method of type TO_TYPE. */
struct type *
-allocate_stub_method (type)
- struct type *type;
+lookup_methodptr_type (struct type *to_type)
{
struct type *mtype;
- mtype = alloc_type (TYPE_OBJFILE (type));
- TYPE_TARGET_TYPE (mtype) = type;
- /* _DOMAIN_TYPE (mtype) = unknown yet */
- /* _ARG_TYPES (mtype) = unknown yet */
- TYPE_FLAGS (mtype) = TYPE_FLAG_STUB;
+ mtype = alloc_type_copy (to_type);
+ TYPE_TARGET_TYPE (mtype) = to_type;
+ TYPE_DOMAIN_TYPE (mtype) = TYPE_DOMAIN_TYPE (to_type);
+ TYPE_LENGTH (mtype) = cplus_method_ptr_size (to_type);
+ TYPE_CODE (mtype) = TYPE_CODE_METHODPTR;
+ return mtype;
+}
+
+/* Allocate a stub method whose return type is TYPE. This apparently
+ happens for speed of symbol reading, since parsing out the
+ arguments to the method is cpu-intensive, the way we are doing it.
+ So, we will fill in arguments later. This always returns a fresh
+ type. */
+
+struct type *
+allocate_stub_method (struct type *type)
+{
+ struct type *mtype;
+
+ mtype = alloc_type_copy (type);
TYPE_CODE (mtype) = TYPE_CODE_METHOD;
TYPE_LENGTH (mtype) = 1;
- return (mtype);
+ TYPE_STUB (mtype) = 1;
+ TYPE_TARGET_TYPE (mtype) = type;
+ /* _DOMAIN_TYPE (mtype) = unknown yet */
+ return mtype;
}
-/* Create a range type using either a blank type supplied in RESULT_TYPE,
- or creating a new type, inheriting the objfile from INDEX_TYPE.
+/* Create a range type using either a blank type supplied in
+ RESULT_TYPE, or creating a new type, inheriting the objfile from
+ INDEX_TYPE.
- Indices will be of type INDEX_TYPE, and will range from LOW_BOUND to
- HIGH_BOUND, inclusive.
+ Indices will be of type INDEX_TYPE, and will range from LOW_BOUND
+ to HIGH_BOUND, inclusive.
- 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? */
+ 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_range_type (result_type, index_type, low_bound, high_bound)
- struct type *result_type;
- struct type *index_type;
- int low_bound;
- int high_bound;
+create_range_type (struct type *result_type, struct type *index_type,
+ LONGEST low_bound, LONGEST high_bound)
{
if (result_type == NULL)
- {
- result_type = alloc_type (TYPE_OBJFILE (index_type));
- }
+ result_type = alloc_type_copy (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;
+ if (TYPE_STUB (index_type))
+ TYPE_TARGET_STUB (result_type) = 1;
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 */
+ TYPE_RANGE_DATA (result_type) = (struct range_bounds *)
+ TYPE_ZALLOC (result_type, sizeof (struct range_bounds));
+ TYPE_LOW_BOUND (result_type) = low_bound;
+ TYPE_HIGH_BOUND (result_type) = high_bound;
- if(low_bound >= 0)
- TYPE_FLAGS (result_type) |= TYPE_FLAG_UNSIGNED;
+ if (low_bound >= 0)
+ TYPE_UNSIGNED (result_type) = 1;
- return (result_type);
+ 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. */
+/* Set *LOWP and *HIGHP to the lower and upper bounds of discrete type
+ TYPE. Return 1 if type is a range type, 0 if it is discrete (and
+ bounds will fit in LONGEST), or -1 otherwise. */
int
-get_discrete_bounds (type, lowp, highp)
- struct type *type;
- LONGEST *lowp, *highp;
+get_discrete_bounds (struct type *type, LONGEST *lowp, LONGEST *highp)
{
CHECK_TYPEDEF (type);
switch (TYPE_CODE (type))
*highp = TYPE_FIELD_BITPOS (type, i);
}
- /* Set unsigned indicator if warranted. */
- if(*lowp >= 0)
+ /* Set unsigned indicator if warranted. */
+ if (*lowp >= 0)
{
- TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED;
+ TYPE_UNSIGNED (type) = 1;
}
}
else
*highp = 1;
return 0;
case TYPE_CODE_INT:
- if (TYPE_LENGTH (type) > sizeof (LONGEST)) /* Too big */
+ if (TYPE_LENGTH (type) > sizeof (LONGEST)) /* Too big */
return -1;
if (!TYPE_UNSIGNED (type))
{
- *lowp = - (1 << (TYPE_LENGTH (type) * TARGET_CHAR_BIT - 1));
+ *lowp = -(1 << (TYPE_LENGTH (type) * TARGET_CHAR_BIT - 1));
*highp = -*lowp - 1;
return 0;
}
- /* ... fall through for unsigned ints ... */
+ /* ... 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). */
+ 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;
}
}
-/* Create an array type using either a blank type supplied in RESULT_TYPE,
- or creating a new type, inheriting the objfile from RANGE_TYPE.
+/* 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.
- 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? */
+ 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 (result_type, element_type, range_type)
- struct type *result_type;
- struct type *element_type;
- struct type *range_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));
- }
+ result_type = alloc_type_copy (range_type);
+
TYPE_CODE (result_type) = TYPE_CODE_ARRAY;
TYPE_TARGET_TYPE (result_type) = 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);
+ /* Be careful when setting the array length. Ada arrays can be
+ empty arrays with the high_bound being smaller than the low_bound.
+ In such cases, the array length should be zero. */
+ if (high_bound < low_bound)
+ TYPE_LENGTH (result_type) = 0;
+ else
+ 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));
- memset (TYPE_FIELDS (result_type), 0, sizeof (struct field));
- TYPE_FIELD_TYPE (result_type, 0) = range_type;
+ (struct field *) TYPE_ZALLOC (result_type, sizeof (struct field));
+ TYPE_INDEX_TYPE (result_type) = 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;
+ TYPE_TARGET_STUB (result_type) = 1;
+
+ return result_type;
+}
- return (result_type);
+struct type *
+lookup_array_range_type (struct type *element_type,
+ int low_bound, int high_bound)
+{
+ struct gdbarch *gdbarch = get_type_arch (element_type);
+ struct type *index_type = builtin_type (gdbarch)->builtin_int;
+ struct type *range_type
+ = create_range_type (NULL, index_type, low_bound, high_bound);
+ return create_array_type (NULL, element_type, range_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.
+/* 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? */
+ 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 (result_type, range_type)
- struct type *result_type;
- struct type *range_type;
+create_string_type (struct type *result_type,
+ struct type *string_char_type,
+ struct type *range_type)
{
result_type = create_array_type (result_type,
- *current_language->string_char_type,
+ string_char_type,
range_type);
TYPE_CODE (result_type) = TYPE_CODE_STRING;
- return (result_type);
+ return result_type;
+}
+
+struct type *
+lookup_string_range_type (struct type *string_char_type,
+ int low_bound, int high_bound)
+{
+ struct type *result_type;
+ result_type = lookup_array_range_type (string_char_type,
+ low_bound, high_bound);
+ TYPE_CODE (result_type) = TYPE_CODE_STRING;
+ return result_type;
}
struct type *
-create_set_type (result_type, domain_type)
- struct type *result_type;
- struct type *domain_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));
- }
+ result_type = alloc_type_copy (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));
+ TYPE_FIELDS (result_type) = TYPE_ZALLOC (result_type, sizeof (struct field));
- if (! (TYPE_FLAGS (domain_type) & TYPE_FLAG_STUB))
+ if (!TYPE_STUB (domain_type))
{
+ LONGEST low_bound, high_bound, bit_length;
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;
+ if (low_bound >= 0)
+ TYPE_UNSIGNED (result_type) = 1;
}
TYPE_FIELD_TYPE (result_type, 0) = domain_type;
- if(low_bound >= 0)
- TYPE_FLAGS (result_type) |= TYPE_FLAG_UNSIGNED;
+ return result_type;
+}
+
+/* Convert ARRAY_TYPE to a vector type. This may modify ARRAY_TYPE
+ and any array types nested inside it. */
+
+void
+make_vector_type (struct type *array_type)
+{
+ struct type *inner_array, *elt_type;
+ int flags;
+
+ /* Find the innermost array type, in case the array is
+ multi-dimensional. */
+ inner_array = array_type;
+ while (TYPE_CODE (TYPE_TARGET_TYPE (inner_array)) == TYPE_CODE_ARRAY)
+ inner_array = TYPE_TARGET_TYPE (inner_array);
+
+ elt_type = TYPE_TARGET_TYPE (inner_array);
+ if (TYPE_CODE (elt_type) == TYPE_CODE_INT)
+ {
+ flags = TYPE_INSTANCE_FLAGS (elt_type) | TYPE_FLAG_NOTTEXT;
+ elt_type = make_qualified_type (elt_type, flags, NULL);
+ TYPE_TARGET_TYPE (inner_array) = elt_type;
+ }
+
+ TYPE_VECTOR (array_type) = 1;
+}
- return (result_type);
+struct type *
+init_vector_type (struct type *elt_type, int n)
+{
+ struct type *array_type;
+ array_type = lookup_array_range_type (elt_type, 0, n - 1);
+ make_vector_type (array_type);
+ return array_type;
}
-/* 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
- include the offset (that's the value of the MEMBER itself), but does
- include the structure type into which it points (for some reason).
+/* Smash TYPE to be a type of pointers to members of DOMAIN with type
+ TO_TYPE. A member pointer 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 include the offset (that's the value of the MEMBER
+ itself), but does include the structure type into which it points
+ (for some reason).
- When "smashing" the type, we preserve the objfile that the
- old type pointed to, since we aren't changing where the type is actually
+ When "smashing" the type, we preserve the objfile that the old type
+ pointed to, since we aren't changing where the type is actually
allocated. */
void
-smash_to_member_type (type, domain, to_type)
- struct type *type;
- struct type *domain;
- struct type *to_type;
+smash_to_memberptr_type (struct type *type, struct type *domain,
+ struct type *to_type)
{
- struct objfile *objfile;
-
- objfile = TYPE_OBJFILE (type);
-
- memset ((char *) type, 0, sizeof (struct type));
- TYPE_OBJFILE (type) = objfile;
+ smash_type (type);
TYPE_TARGET_TYPE (type) = to_type;
TYPE_DOMAIN_TYPE (type) = domain;
- TYPE_LENGTH (type) = 1; /* In practice, this is never needed. */
- TYPE_CODE (type) = TYPE_CODE_MEMBER;
+ /* Assume that a data member pointer is the same size as a normal
+ pointer. */
+ TYPE_LENGTH (type)
+ = gdbarch_ptr_bit (get_type_arch (to_type)) / TARGET_CHAR_BIT;
+ TYPE_CODE (type) = TYPE_CODE_MEMBERPTR;
}
/* Smash TYPE to be a type of method of DOMAIN with type TO_TYPE.
METHOD just means `function that gets an extra "this" argument'.
- When "smashing" the type, we preserve the objfile that the
- old type pointed to, since we aren't changing where the type is actually
+ When "smashing" the type, we preserve the objfile that the old type
+ pointed to, since we aren't changing where the type is actually
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 field *args,
+ int nargs, int varargs)
{
- struct objfile *objfile;
-
- objfile = TYPE_OBJFILE (type);
-
- memset ((char *) type, 0, sizeof (struct type));
- TYPE_OBJFILE (type) = objfile;
+ smash_type (type);
TYPE_TARGET_TYPE (type) = to_type;
TYPE_DOMAIN_TYPE (type) = domain;
- TYPE_ARG_TYPES (type) = args;
+ TYPE_FIELDS (type) = args;
+ TYPE_NFIELDS (type) = nargs;
+ if (varargs)
+ TYPE_VARARGS (type) = 1;
TYPE_LENGTH (type) = 1; /* In practice, this is never needed. */
TYPE_CODE (type) = TYPE_CODE_METHOD;
}
"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 (const struct type *type)
{
if (TYPE_TAG_NAME (type) != NULL)
return TYPE_TAG_NAME (type);
- /* Is there code which expects this to return the name if there is no
- tag name? My guess is that this is mainly used for C++ in cases where
- the two will always be the same. */
+ /* 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.*/
-
-struct type *
-lookup_primitive_typename (name)
- char *name;
-{
- 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,
- visible in lexical block BLOCK.
- If NOERR is nonzero, return zero if NAME is not suitably defined. */
+/* Lookup a typedef or primitive type named NAME, visible in lexical
+ block BLOCK. 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 (const struct language_defn *language,
+ struct gdbarch *gdbarch, char *name,
+ struct block *block, int noerr)
{
- register struct symbol *sym;
- register struct type *tmp;
+ struct symbol *sym;
+ struct type *tmp;
- sym = lookup_symbol (name, block, VAR_NAMESPACE, 0, (struct symtab **) NULL);
+ sym = lookup_symbol (name, block, VAR_DOMAIN, 0);
if (sym == NULL || SYMBOL_CLASS (sym) != LOC_TYPEDEF)
{
- tmp = lookup_primitive_typename (name);
+ tmp = language_lookup_primitive_type_by_name (language, gdbarch, name);
if (tmp)
{
- return (tmp);
+ return tmp;
}
else if (!tmp && noerr)
{
- return (NULL);
+ return NULL;
}
else
{
- error ("No type named %s.", name);
+ error (_("No type named %s."), name);
}
}
return (SYMBOL_TYPE (sym));
}
struct type *
-lookup_unsigned_typename (name)
- char *name;
+lookup_unsigned_typename (const struct language_defn *language,
+ struct gdbarch *gdbarch, char *name)
{
char *uns = alloca (strlen (name) + 10);
strcpy (uns, "unsigned ");
strcpy (uns + 9, name);
- return (lookup_typename (uns, (struct block *) NULL, 0));
+ return lookup_typename (language, gdbarch, uns, (struct block *) NULL, 0);
}
struct type *
-lookup_signed_typename (name)
- char *name;
+lookup_signed_typename (const struct language_defn *language,
+ struct gdbarch *gdbarch, char *name)
{
struct type *t;
char *uns = alloca (strlen (name) + 8);
strcpy (uns, "signed ");
strcpy (uns + 7, name);
- t = lookup_typename (uns, (struct block *) NULL, 1);
- /* If we don't find "signed FOO" just try again with plain "FOO". */
+ t = lookup_typename (language, gdbarch, uns, (struct block *) NULL, 1);
+ /* If we don't find "signed FOO" just try again with plain "FOO". */
if (t != NULL)
return t;
- return lookup_typename (name, (struct block *) NULL, 0);
+ return lookup_typename (language, gdbarch, name, (struct block *) NULL, 0);
}
/* Lookup a structure type named "struct 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;
+ struct symbol *sym;
- sym = lookup_symbol (name, block, STRUCT_NAMESPACE, 0,
- (struct symtab **) NULL);
+ sym = lookup_symbol (name, block, STRUCT_DOMAIN, 0);
if (sym == NULL)
{
- error ("No struct type named %s.", name);
+ error (_("No struct type named %s."), name);
}
if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_STRUCT)
{
- error ("This context has class, union or enum %s, not a struct.", name);
+ error (_("This context has class, union or enum %s, not a struct."),
+ name);
}
return (SYMBOL_TYPE (sym));
}
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;
+ struct symbol *sym;
+ struct type *t;
- sym = lookup_symbol (name, block, STRUCT_NAMESPACE, 0,
- (struct symtab **) NULL);
+ sym = lookup_symbol (name, block, STRUCT_DOMAIN, 0);
if (sym == NULL)
- error ("No union type named %s.", name);
+ error (_("No union type named %s."), name);
- t = SYMBOL_TYPE(sym);
+ t = SYMBOL_TYPE (sym);
if (TYPE_CODE (t) == TYPE_CODE_UNION)
- return (t);
+ 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 (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);
+ /* If we get here, it's not a union. */
+ error (_("This context has class, struct or enum %s, not a union."),
+ 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;
+ struct symbol *sym;
- sym = lookup_symbol (name, block, STRUCT_NAMESPACE, 0,
- (struct symtab **) NULL);
+ sym = lookup_symbol (name, block, STRUCT_DOMAIN, 0);
if (sym == NULL)
{
- error ("No enum type named %s.", name);
+ error (_("No enum type named %s."), name);
}
if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_ENUM)
{
- error ("This context has class, struct or union %s, not an enum.", name);
+ error (_("This context has class, struct or union %s, not an enum."),
+ name);
}
return (SYMBOL_TYPE (sym));
}
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 (type)) + 4);
strcpy (nam, name);
strcat (nam, "<");
- strcat (nam, type->name);
+ strcat (nam, TYPE_NAME (type));
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_DOMAIN, 0);
if (sym == NULL)
{
- error ("No template type named %s.", name);
+ error (_("No template type named %s."), name);
}
if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_STRUCT)
{
- error ("This context has class, union or enum %s, not a struct.", name);
+ error (_("This context has class, union or enum %s, not a struct."),
+ name);
}
return (SYMBOL_TYPE (sym));
}
-/* Given a type TYPE, lookup the type of the component of type named NAME.
+/* 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.
+ 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;
type = TYPE_TARGET_TYPE (type);
}
- if (TYPE_CODE (type) != TYPE_CODE_STRUCT &&
- TYPE_CODE (type) != TYPE_CODE_UNION)
+ if (TYPE_CODE (type) != TYPE_CODE_STRUCT
+ && TYPE_CODE (type) != TYPE_CODE_UNION)
{
target_terminal_ours ();
gdb_flush (gdb_stdout);
fprintf_unfiltered (gdb_stderr, "Type ");
type_print (type, "", gdb_stderr, -1);
- error (" is not a structure or union type.");
+ error (_(" is not a structure or union 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. */
+ /* 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))
+ if (typename != NULL && strcmp (typename, name) == 0)
return type;
}
#endif
{
char *t_field_name = TYPE_FIELD_NAME (type, i);
- if (t_field_name && STREQ (t_field_name, name))
+ if (t_field_name && (strcmp_iw (t_field_name, name) == 0))
{
return TYPE_FIELD_TYPE (type, i);
}
{
struct type *t;
- t = lookup_struct_elt_type (TYPE_BASECLASS (type, i), name, noerr);
+ t = lookup_struct_elt_type (TYPE_BASECLASS (type, i), name, 1);
if (t != NULL)
{
return t;
{
return NULL;
}
-
+
target_terminal_ours ();
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 */
+ error (("."));
+ return (struct type *) -1; /* For lint */
}
-/* If possible, make the vptr_fieldno and vptr_basetype fields of TYPE
- valid. Callers should be aware that in some cases (for example,
+/* Lookup the vptr basetype/fieldno values for TYPE.
+ If found store vptr_basetype in *BASETYPEP if non-NULL, and return
+ vptr_fieldno. Also, if found and basetype is from the same objfile,
+ cache the results.
+ If not found, return -1 and ignore BASETYPEP.
+ 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. */
+ debugging a .o file, or the compiler uses DWARF-2 and is not GCC),
+ 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 or incomplete. */
-void
-fill_in_vptr_fieldno (type)
- struct type *type;
+int
+get_vptr_fieldno (struct type *type, struct type **basetypep)
{
CHECK_TYPEDEF (type);
{
int i;
- /* We must start at zero in case the first (and only) baseclass is
- virtual (and hence we cannot share the table pointer). */
+ /* 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)
+ struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i));
+ int fieldno;
+ struct type *basetype;
+
+ fieldno = get_vptr_fieldno (baseclass, &basetype);
+ if (fieldno >= 0)
{
- TYPE_VPTR_FIELDNO (type)
- = TYPE_VPTR_FIELDNO (TYPE_BASECLASS (type, i));
- TYPE_VPTR_BASETYPE (type)
- = TYPE_VPTR_BASETYPE (TYPE_BASECLASS (type, i));
- break;
+ /* If the type comes from a different objfile we can't cache
+ it, it may have a different lifetime. PR 2384 */
+ if (TYPE_OBJFILE (type) == TYPE_OBJFILE (basetype))
+ {
+ TYPE_VPTR_FIELDNO (type) = fieldno;
+ TYPE_VPTR_BASETYPE (type) = basetype;
+ }
+ if (basetypep)
+ *basetypep = basetype;
+ return fieldno;
}
}
+
+ /* Not found. */
+ return -1;
+ }
+ else
+ {
+ if (basetypep)
+ *basetypep = TYPE_VPTR_BASETYPE (type);
+ return TYPE_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 (t, method_indexp, field_indexp)
- struct type *t;
- int *method_indexp;
- int *field_indexp;
+static void
+stub_noname_complaint (void)
{
- 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;
+ complaint (&symfile_complaints, _("stub type has NULL name"));
}
/* 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. 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.
+ 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. */
-struct complaint stub_noname_complaint =
- {"stub type has NULL name", 0, 0};
+/* Find the real type of TYPE. This function returns the real type,
+ after removing all layers of typedefs and completing opaque or stub
+ types. Completion changes the TYPE argument, but stripping of
+ typedefs does not. */
struct type *
-check_typedef (type)
- register struct type *type;
+check_typedef (struct type *type)
{
struct type *orig_type = type;
+ int is_const, is_volatile;
+
+ gdb_assert (type);
+
while (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
{
if (!TYPE_TARGET_TYPE (type))
{
- char* name;
+ char *name;
struct symbol *sym;
/* It is dangerous to call lookup_symbol if we are currently
- reading a symtab. Infinite recursion is one danger. */
+ 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). */
+ /* FIXME: shouldn't we separately check the TYPE_NAME and
+ the TYPE_TAG_NAME, and look in STRUCT_DOMAIN and/or
+ VAR_DOMAIN as appropriate? (this code was written before
+ TYPE_NAME and TYPE_TAG_NAME were separate). */
if (name == NULL)
{
- complain (&stub_noname_complaint);
+ stub_noname_complaint ();
return type;
}
- sym = lookup_symbol (name, 0, STRUCT_NAMESPACE, 0,
- (struct symtab **) NULL);
+ sym = lookup_symbol (name, 0, STRUCT_DOMAIN, 0);
if (sym)
TYPE_TARGET_TYPE (type) = SYMBOL_TYPE (sym);
- else
- TYPE_TARGET_TYPE (type) = alloc_type (NULL); /* TYPE_CODE_UNDEF */
+ else /* TYPE_CODE_UNDEF */
+ TYPE_TARGET_TYPE (type) = alloc_type_arch (get_type_arch (type));
}
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)
+ is_const = TYPE_CONST (type);
+ is_volatile = TYPE_VOLATILE (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;
+ char *name = type_name_no_tag (type);
+ struct type *newtype;
if (name == NULL)
{
- complain (&stub_noname_complaint);
+ stub_noname_complaint ();
return type;
}
newtype = lookup_transparent_type (name);
+
if (newtype)
{
- memcpy ((char *) type, (char *) newtype, sizeof (struct type));
+ /* If the resolved type and the stub are in the same
+ objfile, then replace the stub type with the real deal.
+ But if they're in separate objfiles, leave the stub
+ alone; we'll just look up the transparent type every time
+ we call check_typedef. We can't create pointers between
+ types allocated to different objfiles, since they may
+ have different lifetimes. Trying to copy NEWTYPE over to
+ TYPE's objfile is pointless, too, since you'll have to
+ move over any other types NEWTYPE refers to, which could
+ be an unbounded amount of stuff. */
+ if (TYPE_OBJFILE (newtype) == TYPE_OBJFILE (type))
+ make_cv_type (is_const, is_volatile, newtype, &type);
+ else
+ type = newtype;
}
}
- /* Otherwise, rely on the stub flag being set for opaque/stubbed types */
- else if ((TYPE_FLAGS(type) & TYPE_FLAG_STUB) && ! currently_reading_symtab)
+ /* Otherwise, rely on the stub flag being set for opaque/stubbed
+ types. */
+ else if (TYPE_STUB (type) && !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). */
+ TYPE_TAG_NAME, and look in STRUCT_DOMAIN and/or VAR_DOMAIN
+ as appropriate? (this code was written before TYPE_NAME and
+ TYPE_TAG_NAME were separate). */
struct symbol *sym;
if (name == NULL)
{
- complain (&stub_noname_complaint);
+ stub_noname_complaint ();
return type;
}
- sym = lookup_symbol (name, 0, STRUCT_NAMESPACE, 0, (struct symtab **) NULL);
+ sym = lookup_symbol (name, 0, STRUCT_DOMAIN, 0);
if (sym)
- {
- memcpy ((char *)type, (char *)SYMBOL_TYPE(sym), sizeof (struct type));
- }
+ {
+ /* Same as above for opaque types, we can replace the stub
+ with the complete type only if they are int the same
+ objfile. */
+ if (TYPE_OBJFILE (SYMBOL_TYPE(sym)) == TYPE_OBJFILE (type))
+ make_cv_type (is_const, is_volatile,
+ SYMBOL_TYPE (sym), &type);
+ else
+ type = SYMBOL_TYPE (sym);
+ }
}
- if (TYPE_FLAGS (type) & TYPE_FLAG_TARGET_STUB)
+ if (TYPE_TARGET_STUB (type))
{
struct type *range_type;
struct type *target_type = check_typedef (TYPE_TARGET_TYPE (type));
- if (TYPE_FLAGS (target_type) & (TYPE_FLAG_STUB | TYPE_FLAG_TARGET_STUB))
- { }
+ if (TYPE_STUB (target_type) || TYPE_TARGET_STUB (target_type))
+ {
+ /* Empty. */
+ }
else if (TYPE_CODE (type) == TYPE_CODE_ARRAY
&& TYPE_NFIELDS (type) == 1
- && (TYPE_CODE (range_type = TYPE_FIELD_TYPE (type, 0))
+ && (TYPE_CODE (range_type = TYPE_INDEX_TYPE (type))
== TYPE_CODE_RANGE))
{
/* 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;
+ number of elements and the target type's length.
+ Watch out for Ada null Ada arrays where the high bound
+ is smaller than the low bound. */
+ const LONGEST low_bound = TYPE_LOW_BOUND (range_type);
+ const LONGEST high_bound = TYPE_HIGH_BOUND (range_type);
+ ULONGEST len;
+
+ if (high_bound < low_bound)
+ len = 0;
+ else {
+ /* For now, we conservatively take the array length to be 0
+ if its length exceeds UINT_MAX. The code below assumes
+ that for x < 0, (ULONGEST) x == -x + ULONGEST_MAX + 1,
+ which is technically not guaranteed by C, but is usually true
+ (because it would be true if x were unsigned with its
+ high-order bit on). It uses the fact that
+ high_bound-low_bound is always representable in
+ ULONGEST and that if high_bound-low_bound+1 overflows,
+ it overflows to 0. We must change these tests if we
+ decide to increase the representation of TYPE_LENGTH
+ from unsigned int to ULONGEST. */
+ ULONGEST ulow = low_bound, uhigh = high_bound;
+ ULONGEST tlen = TYPE_LENGTH (target_type);
+
+ len = tlen * (uhigh - ulow + 1);
+ if (tlen == 0 || (len / tlen - 1 + ulow) != uhigh
+ || len > UINT_MAX)
+ len = 0;
+ }
+ TYPE_LENGTH (type) = len;
+ TYPE_TARGET_STUB (type) = 0;
}
else if (TYPE_CODE (type) == TYPE_CODE_RANGE)
{
TYPE_LENGTH (type) = TYPE_LENGTH (target_type);
- TYPE_FLAGS (type) &= ~TYPE_FLAG_TARGET_STUB;
+ TYPE_TARGET_STUB (type) = 0;
}
}
- /* Cache TYPE_LENGTH for future use. */
+ /* Cache TYPE_LENGTH for future use. */
TYPE_LENGTH (orig_type) = TYPE_LENGTH (type);
return type;
}
-/* 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; }
-
-static void
-add_name(pextras,n)
- 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(pextras,t)
- struct extra * pextras;
- struct type * t;
-{
- enum type_code tcode;
- int tlen, tflags;
- char * tname;
-
- 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)
- {
- case TYPE_CODE_INT:
- if (tflags==1)
- ADD_EXTRA('U');
- switch (tlen)
- {
- 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;
+/* Parse a type expression in the string [P..P+LENGTH). If an error
+ occurs, silently return a void type. */
- /* 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);
-}
+static struct type *
+safe_parse_type (struct gdbarch *gdbarch, char *p, int length)
+{
+ struct ui_file *saved_gdb_stderr;
+ struct type *type;
-#if 0
-void
-cfront_mangle_name(type, i, j)
- 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 */
+ /* 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 (gdbarch)->builtin_void;
+
+ /* Stop suppressing error messages. */
+ ui_file_delete (gdb_stderr);
+ gdb_stderr = saved_gdb_stderr;
-#undef ADD_EXTRA
-/* End of new code added to support parsing of Cfront stabs strings */
+ 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. */
+ 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, method_id, signature_id)
- struct type *type;
- int method_id;
- int signature_id;
+static void
+check_stub_method (struct type *type, int method_id, int signature_id)
{
+ struct gdbarch *gdbarch = get_type_arch (type);
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 field *argtypes;
struct type *mtype;
/* Make sure we got back a function string that we can use. */
if (demangled_name)
p = strchr (demangled_name, '(');
+ else
+ p = NULL;
if (demangled_name == NULL || p == NULL)
- error ("Internal: Cannot demangle mangled name `%s'.", mangled_name);
+ 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 == '(')
+ if (*p == '(' || *p == '<')
{
depth += 1;
}
- else if (*p == ')')
+ else if (*p == ')' || *p == '>')
{
depth -= 1;
}
p += 1;
}
- /* We need two more slots: one for the THIS pointer, and one for the
- NULL [...] or void [end of arglist]. */
+ /* If we read one argument and it was ``void'', don't count it. */
+ if (strncmp (argtypetext, "(void)", 6) == 0)
+ argcount -= 1;
+
+ /* We need one extra slot, for the THIS pointer. */
- argtypes = (struct type **)
- TYPE_ALLOC (type, (argcount + 2) * sizeof (struct type *));
+ argtypes = (struct field *)
+ TYPE_ALLOC (type, (argcount + 1) * sizeof (struct field));
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 */
+ /* Add THIS pointer for non-static methods. */
+ f = TYPE_FN_FIELDLIST1 (type, method_id);
+ if (TYPE_FN_FIELD_STATIC_P (f, signature_id))
+ argcount = 0;
+ else
+ {
+ argtypes[0].type = 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)
+ /* Avoid parsing of ellipsis, they will be handled below.
+ Also avoid ``void'' as above. */
+ if (strncmp (argtypetext, "...", p - argtypetext) != 0
+ && strncmp (argtypetext, "void", p - argtypetext) != 0)
{
- argtypes[argcount] =
- parse_and_eval_type (argtypetext, p - argtypetext);
+ argtypes[argcount].type =
+ safe_parse_type (gdbarch, argtypetext, p - argtypetext);
argcount += 1;
}
argtypetext = p + 1;
}
- if (*p == '(')
+ if (*p == '(' || *p == '<')
{
depth += 1;
}
- else if (*p == ')')
+ else if (*p == ')' || *p == '>')
{
depth -= 1;
}
}
}
- if (p[-2] != '.') /* Not '...' */
- {
- argtypes[argcount] = builtin_type_void; /* List terminator */
- }
- else
- {
- argtypes[argcount] = NULL; /* Ellist terminator */
- }
-
- free (demangled_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, signature_id);
TYPE_DOMAIN_TYPE (mtype) = type;
- TYPE_ARG_TYPES (mtype) = argtypes;
- TYPE_FLAGS (mtype) &= ~TYPE_FLAG_STUB;
+ TYPE_FIELDS (mtype) = argtypes;
+ TYPE_NFIELDS (mtype) = argcount;
+ TYPE_STUB (mtype) = 0;
TYPE_FN_FIELD_STUB (f, signature_id) = 0;
+ if (p[-2] == '.')
+ TYPE_VARARGS (mtype) = 1;
+
+ xfree (demangled_name);
+}
+
+/* This is the external interface to check_stub_method, above. This
+ function unstubs all of the signatures for TYPE's METHOD_ID method
+ name. After calling this function TYPE_FN_FIELD_STUB will be
+ cleared for each signature and TYPE_FN_FIELDLIST_NAME will be
+ correct.
+
+ This function unfortunately can not die until stabs do. */
+
+void
+check_stub_method_group (struct type *type, int method_id)
+{
+ int len = TYPE_FN_FIELDLIST_LENGTH (type, method_id);
+ struct fn_field *f = TYPE_FN_FIELDLIST1 (type, method_id);
+ int j, found_stub = 0;
+
+ for (j = 0; j < len; j++)
+ if (TYPE_FN_FIELD_STUB (f, j))
+ {
+ found_stub = 1;
+ check_stub_method (type, method_id, j);
+ }
+
+ /* GNU v3 methods with incorrect names were corrected when we read
+ in type information, because it was cheaper to do it then. The
+ only GNU v2 methods with incorrect method names are operators and
+ destructors; destructors were also corrected when we read in type
+ information.
+
+ Therefore the only thing we need to handle here are v2 operator
+ names. */
+ if (found_stub && strncmp (TYPE_FN_FIELD_PHYSNAME (f, 0), "_Z", 2) != 0)
+ {
+ int ret;
+ char dem_opname[256];
+
+ ret = cplus_demangle_opname (TYPE_FN_FIELDLIST_NAME (type,
+ method_id),
+ dem_opname, DMGL_ANSI);
+ if (!ret)
+ ret = cplus_demangle_opname (TYPE_FN_FIELDLIST_NAME (type,
+ method_id),
+ dem_opname, 0);
+ if (ret)
+ TYPE_FN_FIELDLIST_NAME (type, method_id) = xstrdup (dem_opname);
+ }
}
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;
}
}
/* Helper function to initialize the standard scalar types.
- If NAME is non-NULL and OBJFILE is non-NULL, then we make a copy
- of the string pointed to by name in the type_obstack for that objfile,
- and initialize the type name to that copy. There are places (mipsread.c
- in particular, where init_type is called with a NULL value for NAME). */
+ If NAME is non-NULL, then we make a copy of the string pointed
+ to by name in the objfile_obstack for that objfile, and initialize
+ the type name to that copy. There are places (mipsread.c 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;
+ struct type *type;
type = alloc_type (objfile);
TYPE_CODE (type) = code;
TYPE_LENGTH (type) = length;
- TYPE_FLAGS (type) |= flags;
- if ((name != NULL) && (objfile != NULL))
- {
- TYPE_NAME (type) =
- obsavestring (name, strlen (name), &objfile -> type_obstack);
- }
- else
- {
- TYPE_NAME (type) = name;
- }
-
- /* C++ fancies. */
-
- if (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION)
- {
- INIT_CPLUS_SPECIFIC (type);
- }
- return (type);
-}
-
-/* Look up a fundamental type for the specified objfile.
- May need to construct such a type if this is the first use.
- Some object file formats (ELF, COFF, etc) do not define fundamental
- types such as "int" or "double". Others (stabs for example), do
- define fundamental types.
-
- For the formats which don't provide fundamental types, gdb can create
- such types, using defaults reasonable for the current language and
- the current target machine.
-
- NOTE: This routine is obsolescent. Each debugging format reader
- should manage it's own fundamental types, either creating them from
- suitable defaults or reading them from the debugging information,
- whichever is appropriate. The DWARF reader has already been
- fixed to do this. Once the other readers are fixed, this routine
- will go away. Also note that fundamental types should be managed
- on a compilation unit basis in a multi-language environment, not
- on a linkage unit basis as is done here. */
-
-
-struct type *
-lookup_fundamental_type (objfile, typeid)
- struct objfile *objfile;
- int typeid;
-{
- register struct type **typep;
- register int nbytes;
-
- if (typeid < 0 || typeid >= FT_NUM_MEMBERS)
- {
- error ("internal error - invalid fundamental type id %d", typeid);
- }
+ gdb_assert (!(flags & (TYPE_FLAG_MIN - 1)));
+ if (flags & TYPE_FLAG_UNSIGNED)
+ TYPE_UNSIGNED (type) = 1;
+ if (flags & TYPE_FLAG_NOSIGN)
+ TYPE_NOSIGN (type) = 1;
+ if (flags & TYPE_FLAG_STUB)
+ TYPE_STUB (type) = 1;
+ if (flags & TYPE_FLAG_TARGET_STUB)
+ TYPE_TARGET_STUB (type) = 1;
+ if (flags & TYPE_FLAG_STATIC)
+ TYPE_STATIC (type) = 1;
+ if (flags & TYPE_FLAG_PROTOTYPED)
+ TYPE_PROTOTYPED (type) = 1;
+ if (flags & TYPE_FLAG_INCOMPLETE)
+ TYPE_INCOMPLETE (type) = 1;
+ if (flags & TYPE_FLAG_VARARGS)
+ TYPE_VARARGS (type) = 1;
+ if (flags & TYPE_FLAG_VECTOR)
+ TYPE_VECTOR (type) = 1;
+ if (flags & TYPE_FLAG_STUB_SUPPORTED)
+ TYPE_STUB_SUPPORTED (type) = 1;
+ if (flags & TYPE_FLAG_NOTTEXT)
+ TYPE_NOTTEXT (type) = 1;
+ if (flags & TYPE_FLAG_FIXED_INSTANCE)
+ TYPE_FIXED_INSTANCE (type) = 1;
+
+ if (name)
+ TYPE_NAME (type) = obsavestring (name, strlen (name),
+ &objfile->objfile_obstack);
- /* 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)
- {
- 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);
- OBJSTAT (objfile, n_types += FT_NUM_MEMBERS);
- }
+ /* C++ fancies. */
- /* Look for this particular type in the fundamental type vector. If one is
- not found, create and install one appropriate for the current language. */
+ if (name && strcmp (name, "char") == 0)
+ TYPE_NOSIGN (type) = 1;
- typep = objfile -> fundamental_types + typeid;
- if (*typep == NULL)
+ if (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION
+ || code == TYPE_CODE_NAMESPACE)
{
- *typep = create_fundamental_type (objfile, typeid);
+ INIT_CPLUS_SPECIFIC (type);
}
-
- return (*typep);
+ return type;
}
int
-can_dereference (t)
- struct type *t;
+can_dereference (struct type *t)
{
- /* FIXME: Should we return true for references as well as pointers? */
+ /* FIXME: Should we return true for references as well as
+ pointers? */
CHECK_TYPEDEF (t);
return
(t != NULL
&& TYPE_CODE (TYPE_TARGET_TYPE (t)) != TYPE_CODE_VOID);
}
-/* 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 (type)
- struct type *type;
+is_integral_type (struct type *t)
{
- 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_TYPEDEF (t);
+ return
+ ((t != NULL)
+ && ((TYPE_CODE (t) == TYPE_CODE_INT)
+ || (TYPE_CODE (t) == TYPE_CODE_ENUM)
+ || (TYPE_CODE (t) == TYPE_CODE_FLAGS)
+ || (TYPE_CODE (t) == TYPE_CODE_CHAR)
+ || (TYPE_CODE (t) == TYPE_CODE_RANGE)
+ || (TYPE_CODE (t) == TYPE_CODE_BOOL)));
}
/* 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 */
+ the ancestor relationship even if they're identical. */
int
-is_ancestor (base, dclass)
- struct type * base;
- struct type * dclass;
+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 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 (dclass)
- 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 (dclass)
- 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
-virtual_base_list_aux (dclass)
- 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 (dclass)
- 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 (dclass)
- 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 (dclass)
- 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(base, dclass)
- 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(base, dclass)
- 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 (dclass)
- 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 (dclass)
- struct type * dclass;
-{
- int base; /* index for base classes */
- 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 */
+ 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 (a, b)
- struct badness_vector * a;
- struct badness_vector * b;
+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 */
+ 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++)
+ /* Subtract b from a */
+ for (i = 0; i < a->length; i++)
{
tmp = a->rank[i] - b->rank[i];
if (tmp > 0)
- found_pos = 1;
+ found_pos = 1;
else if (tmp < 0)
- found_neg = 1;
+ found_neg = 1;
}
if (found_pos)
{
if (found_neg)
- return 1; /* incomparable */
+ return 1; /* incomparable */
else
- return 3; /* A > B */
+ return 3; /* A > B */
}
- else /* no positives */
+ else
+ /* no positives */
{
if (found_neg)
- return 2; /* A < B */
+ return 2; /* A < B */
else
- return 0; /* A == B */
+ 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. */
+/* 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 (parms, nparms, args, nargs)
- struct type ** parms;
- int nparms;
- struct type ** args;
- int nargs;
+rank_function (struct type **parms, int nparms,
+ struct type **args, int nargs)
{
int i;
- struct badness_vector * bv;
+ 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->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. */
-
+ 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. */
+ 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++)
+ 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++)
+ /* 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 the names of two integer types, assuming that any sign
+ qualifiers have been checked already. We do it this way because
+ there may be an "int" in the name of one of the types. */
+
+static int
+integer_types_same_name_p (const char *first, const char *second)
+{
+ int first_p, second_p;
+
+ /* If both are shorts, return 1; if neither is a short, keep
+ checking. */
+ first_p = (strstr (first, "short") != NULL);
+ second_p = (strstr (second, "short") != NULL);
+ if (first_p && second_p)
+ return 1;
+ if (first_p || second_p)
+ return 0;
+
+ /* Likewise for long. */
+ first_p = (strstr (first, "long") != NULL);
+ second_p = (strstr (second, "long") != NULL);
+ if (first_p && second_p)
+ return 1;
+ if (first_p || second_p)
+ return 0;
+
+ /* Likewise for char. */
+ first_p = (strstr (first, "char") != NULL);
+ second_p = (strstr (second, "char") != NULL);
+ if (first_p && second_p)
+ return 1;
+ if (first_p || second_p)
+ return 0;
+
+ /* They must both be ints. */
+ return 1;
+}
+
/* 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
*
* 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 */
+ * 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 (parm, arg)
- struct type * parm;
- struct type * arg;
+rank_one_type (struct type *parm, struct type *arg)
{
- /* Identical type pointers */
+ /* 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. */
+ and param. The reason is that builtin types are different from
+ the same ones constructed from the object. */
if (parm == arg)
return 0;
if (TYPE_CODE (arg) == TYPE_CODE_TYPEDEF)
arg = check_typedef (arg);
- /* Check if identical after resolving typedefs */
+ /*
+ 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;
-#if 0
- /* Debugging only */
- printf("------ Arg is %s [%d], parm is %s [%d]\n",
- TYPE_NAME (arg), TYPE_CODE (arg), TYPE_NAME (parm), TYPE_CODE (parm));
-#endif
+ /* 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 (TYPE_NAME (parm), TYPE_NAME (arg)))
- return 0; /* unsigned int -> unsigned int, or unsigned long -> unsigned long */
- else if (!strcmp (TYPE_NAME (arg), "int") && !strcmp (TYPE_NAME (parm), "long"))
- return INTEGER_PROMOTION_BADNESS; /* unsigned int -> unsigned long */
- else
- return INTEGER_COERCION_BADNESS; /* unsigned long -> unsigned int */
- }
- else
- {
- if (!strcmp (TYPE_NAME (arg), "long") && !strcmp (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 (TYPE_NAME (parm), TYPE_NAME (arg)))
- return 0;
- else if (!strcmp (TYPE_NAME (arg), "int") && !strcmp (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 (bits, nbits)
- B_TYPE *bits;
- int nbits;
-{
- int bitno;
-
- for (bitno = 0; bitno < nbits; bitno++)
- {
- if ((bitno % 8) == 0)
+ case TYPE_CODE_PTR:
+ switch (TYPE_CODE (arg))
{
- puts_filtered (" ");
+ case TYPE_CODE_PTR:
+ if (TYPE_CODE (TYPE_TARGET_TYPE (parm)) == TYPE_CODE_VOID
+ && TYPE_CODE (TYPE_TARGET_TYPE (arg)) != 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_FLAGS:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_BOOL:
+ return POINTER_CONVERSION_BADNESS;
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
}
- if (B_TST (bits, bitno))
+ case TYPE_CODE_ARRAY:
+ switch (TYPE_CODE (arg))
{
- printf_filtered ("1");
+ 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;
}
- else
+ case TYPE_CODE_FUNC:
+ switch (TYPE_CODE (arg))
{
- printf_filtered ("0");
+ case TYPE_CODE_PTR: /* funcptr -> func */
+ return rank_one_type (parm, TYPE_TARGET_TYPE (arg));
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
}
- }
-}
-
-/* The args list is a strange beast. It is either terminated by a NULL
- pointer for varargs functions, or by a pointer to a TYPE_CODE_VOID
- type for normal fixed argcount functions. (FIXME someday)
- Also note the first arg should be the "this" pointer, we may not want to
- include it since we may get into a infinitely recursive situation. */
-
+ case TYPE_CODE_INT:
+ switch (TYPE_CODE (arg))
+ {
+ case TYPE_CODE_INT:
+ if (TYPE_LENGTH (arg) == TYPE_LENGTH (parm))
+ {
+ /* Deal with signed, unsigned, and plain chars and
+ signed and unsigned ints. */
+ if (TYPE_NOSIGN (parm))
+ {
+ /* This case only for character types */
+ if (TYPE_NOSIGN (arg))
+ return 0; /* plain char -> plain char */
+ else /* signed/unsigned char -> plain char */
+ return INTEGER_CONVERSION_BADNESS;
+ }
+ else if (TYPE_UNSIGNED (parm))
+ {
+ if (TYPE_UNSIGNED (arg))
+ {
+ /* unsigned int -> unsigned int, or
+ unsigned long -> unsigned long */
+ if (integer_types_same_name_p (TYPE_NAME (parm),
+ TYPE_NAME (arg)))
+ return 0;
+ else if (integer_types_same_name_p (TYPE_NAME (arg),
+ "int")
+ && integer_types_same_name_p (TYPE_NAME (parm),
+ "long"))
+ return INTEGER_PROMOTION_BADNESS; /* unsigned int -> unsigned long */
+ else
+ return INTEGER_CONVERSION_BADNESS; /* unsigned long -> unsigned int */
+ }
+ else
+ {
+ if (integer_types_same_name_p (TYPE_NAME (arg),
+ "long")
+ && integer_types_same_name_p (TYPE_NAME (parm),
+ "int"))
+ return INTEGER_CONVERSION_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 (integer_types_same_name_p (TYPE_NAME (parm),
+ TYPE_NAME (arg)))
+ return 0;
+ else if (integer_types_same_name_p (TYPE_NAME (arg),
+ "int")
+ && integer_types_same_name_p (TYPE_NAME (parm),
+ "long"))
+ return INTEGER_PROMOTION_BADNESS;
+ else
+ return INTEGER_CONVERSION_BADNESS;
+ }
+ else
+ return INTEGER_CONVERSION_BADNESS;
+ }
+ else if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm))
+ return INTEGER_PROMOTION_BADNESS;
+ else
+ return INTEGER_CONVERSION_BADNESS;
+ case TYPE_CODE_ENUM:
+ case TYPE_CODE_FLAGS:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_BOOL:
+ 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_CONVERSION_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_CONVERSION_BADNESS;
+ case TYPE_CODE_FLT:
+ return INT_FLOAT_CONVERSION_BADNESS;
+ case TYPE_CODE_INT:
+ if (TYPE_LENGTH (arg) > TYPE_LENGTH (parm))
+ return INTEGER_CONVERSION_BADNESS;
+ else if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm))
+ return INTEGER_PROMOTION_BADNESS;
+ /* >>> !! else fall through !! <<< */
+ case TYPE_CODE_CHAR:
+ /* Deal with signed, unsigned, and plain chars for C++ and
+ with int cases falling through from previous case. */
+ if (TYPE_NOSIGN (parm))
+ {
+ if (TYPE_NOSIGN (arg))
+ return 0;
+ else
+ return INTEGER_CONVERSION_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_CONVERSION_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_CONVERSION_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_MEMBERPTR:
+ switch (TYPE_CODE (arg))
+ {
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ break;
+ case TYPE_CODE_METHOD:
+ switch (TYPE_CODE (arg))
+ {
+
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ break;
+ case TYPE_CODE_REF:
+ switch (TYPE_CODE (arg))
+ {
+
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+
+ break;
+ 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_arg_types (args, spaces)
- struct type **args;
- int spaces;
+print_bit_vector (B_TYPE *bits, int nbits)
{
- if (args != NULL)
+ int bitno;
+
+ for (bitno = 0; bitno < nbits; bitno++)
{
- while (*args != NULL)
+ if ((bitno % 8) == 0)
{
- recursive_dump_type (*args, spaces + 2);
- if ((*args++) -> code == TYPE_CODE_VOID)
- {
- break;
- }
+ puts_filtered (" ");
}
+ if (B_TST (bits, bitno))
+ printf_filtered (("1"));
+ else
+ printf_filtered (("0"));
+ }
+}
+
+/* Note the first arg should be the "this" pointer, we may not want to
+ include it since we may get into a infinitely recursive
+ situation. */
+
+static void
+print_arg_types (struct field *args, int nargs, int spaces)
+{
+ if (args != NULL)
+ {
+ int i;
+
+ for (i = 0; i < nargs; i++)
+ recursive_dump_type (args[i].type, spaces + 2);
}
}
+int
+field_is_static (struct field *f)
+{
+ /* "static" fields are the fields whose location is not relative
+ to the address of the enclosing struct. It would be nice to
+ have a dedicated flag that would be set for static fields when
+ the type is being created. But in practice, checking the field
+ loc_kind should give us an accurate answer (at least as long as
+ we assume that DWARF block locations are not going to be used
+ for static fields). FIXME? */
+ return (FIELD_LOC_KIND (*f) == FIELD_LOC_KIND_PHYSNAME
+ || FIELD_LOC_KIND (*f) == FIELD_LOC_KIND_PHYSADDR);
+}
+
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 ");
- gdb_print_address (TYPE_FN_FIELDLISTS (type), gdb_stdout);
+ 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++)
{
printfi_filtered (spaces + 2, "[%d] name '%s' (",
method_idx,
TYPE_FN_FIELDLIST_NAME (type, method_idx));
- gdb_print_address (TYPE_FN_FIELDLIST_NAME (type, method_idx),
- gdb_stdout);
- printf_filtered (") length %d\n",
+ 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);
printfi_filtered (spaces + 4, "[%d] physname '%s' (",
overload_idx,
TYPE_FN_FIELD_PHYSNAME (f, overload_idx));
- gdb_print_address (TYPE_FN_FIELD_PHYSNAME (f, overload_idx),
- gdb_stdout);
+ gdb_print_host_address (TYPE_FN_FIELD_PHYSNAME (f, overload_idx),
+ gdb_stdout);
printf_filtered (")\n");
printfi_filtered (spaces + 8, "type ");
- gdb_print_address (TYPE_FN_FIELD_TYPE (f, overload_idx), gdb_stdout);
+ 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 ");
- gdb_print_address (TYPE_FN_FIELD_ARGS (f, overload_idx), gdb_stdout);
+ 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);
+ print_arg_types (TYPE_FN_FIELD_ARGS (f, overload_idx),
+ TYPE_NFIELDS (TYPE_FN_FIELD_TYPE (f,
+ overload_idx)),
+ spaces);
printfi_filtered (spaces + 8, "fcontext ");
- gdb_print_address (TYPE_FN_FIELD_FCONTEXT (f, overload_idx),
- gdb_stdout);
+ gdb_print_host_address (TYPE_FN_FIELD_FCONTEXT (f, overload_idx),
+ gdb_stdout);
printf_filtered ("\n");
printfi_filtered (spaces + 8, "is_const %d\n",
}
static void
-print_cplus_stuff (type, spaces)
- struct type *type;
- int spaces;
+print_cplus_stuff (struct type *type, int spaces)
{
printfi_filtered (spaces, "n_baseclasses %d\n",
TYPE_N_BASECLASSES (type));
{
printfi_filtered (spaces, "virtual_field_bits (%d bits at *",
TYPE_N_BASECLASSES (type));
- gdb_print_address (TYPE_FIELD_VIRTUAL_BITS (type), gdb_stdout);
+ gdb_print_host_address (TYPE_FIELD_VIRTUAL_BITS (type),
+ gdb_stdout);
printf_filtered (")");
print_bit_vector (TYPE_FIELD_VIRTUAL_BITS (type),
{
if (TYPE_FIELD_PRIVATE_BITS (type) != NULL)
{
- printfi_filtered (spaces, "private_field_bits (%d bits at *",
+ printfi_filtered (spaces,
+ "private_field_bits (%d bits at *",
TYPE_NFIELDS (type));
- gdb_print_address (TYPE_FIELD_PRIVATE_BITS (type), gdb_stdout);
+ gdb_print_host_address (TYPE_FIELD_PRIVATE_BITS (type),
+ gdb_stdout);
printf_filtered (")");
print_bit_vector (TYPE_FIELD_PRIVATE_BITS (type),
TYPE_NFIELDS (type));
}
if (TYPE_FIELD_PROTECTED_BITS (type) != NULL)
{
- printfi_filtered (spaces, "protected_field_bits (%d bits at *",
+ printfi_filtered (spaces,
+ "protected_field_bits (%d bits at *",
TYPE_NFIELDS (type));
- gdb_print_address (TYPE_FIELD_PROTECTED_BITS (type), gdb_stdout);
+ gdb_print_host_address (TYPE_FIELD_PROTECTED_BITS (type),
+ gdb_stdout);
printf_filtered (")");
print_bit_vector (TYPE_FIELD_PROTECTED_BITS (type),
TYPE_NFIELDS (type));
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;
|| (TYPE_CPLUS_SPECIFIC (type) && TYPE_NFN_FIELDS (type) > 0))
{
struct type **first_dont_print
- = (struct type **)obstack_base (&dont_print_type_obstack);
+ = (struct type **) obstack_base (&dont_print_type_obstack);
- int i = (struct type **)obstack_next_free (&dont_print_type_obstack)
- - first_dont_print;
+ 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_address (type, gdb_stdout);
- printf_filtered (" <same as already seen type>\n");
+ gdb_print_host_address (type, gdb_stdout);
+ printf_filtered (_(" <same as already seen type>\n"));
return;
}
}
}
printfi_filtered (spaces, "type node ");
- gdb_print_address (type, gdb_stdout);
+ gdb_print_host_address (type, gdb_stdout);
printf_filtered ("\n");
printfi_filtered (spaces, "name '%s' (",
TYPE_NAME (type) ? TYPE_NAME (type) : "<NULL>");
- gdb_print_address (TYPE_NAME (type), gdb_stdout);
+ gdb_print_host_address (TYPE_NAME (type), gdb_stdout);
+ printf_filtered (")\n");
+ printfi_filtered (spaces, "tagname '%s' (",
+ TYPE_TAG_NAME (type) ? TYPE_TAG_NAME (type) : "<NULL>");
+ gdb_print_host_address (TYPE_TAG_NAME (type), gdb_stdout);
printf_filtered (")\n");
- if (TYPE_TAG_NAME (type) != NULL)
- {
- printfi_filtered (spaces, "tagname '%s' (",
- TYPE_TAG_NAME (type));
- gdb_print_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_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;
+ 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_FLAGS:
+ printf_filtered ("(TYPE_CODE_FLAGS)");
+ 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_BITSTRING:
+ printf_filtered ("(TYPE_CODE_BITSTRING)");
+ break;
+ case TYPE_CODE_ERROR:
+ printf_filtered ("(TYPE_CODE_ERROR)");
+ break;
+ case TYPE_CODE_MEMBERPTR:
+ printf_filtered ("(TYPE_CODE_MEMBERPTR)");
+ break;
+ case TYPE_CODE_METHODPTR:
+ printf_filtered ("(TYPE_CODE_METHODPTR)");
+ 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_COMPLEX:
+ printf_filtered ("(TYPE_CODE_COMPLEX)");
+ break;
+ case TYPE_CODE_TYPEDEF:
+ printf_filtered ("(TYPE_CODE_TYPEDEF)");
+ break;
+ case TYPE_CODE_TEMPLATE:
+ printf_filtered ("(TYPE_CODE_TEMPLATE)");
+ break;
+ case TYPE_CODE_TEMPLATE_ARG:
+ printf_filtered ("(TYPE_CODE_TEMPLATE_ARG)");
+ break;
+ case TYPE_CODE_NAMESPACE:
+ printf_filtered ("(TYPE_CODE_NAMESPACE)");
+ break;
+ default:
+ printf_filtered ("(UNKNOWN TYPE CODE)");
+ break;
}
puts_filtered ("\n");
printfi_filtered (spaces, "length %d\n", TYPE_LENGTH (type));
- printfi_filtered (spaces, "objfile ");
- gdb_print_address (TYPE_OBJFILE (type), gdb_stdout);
+ if (TYPE_OBJFILE_OWNED (type))
+ {
+ printfi_filtered (spaces, "objfile ");
+ gdb_print_host_address (TYPE_OWNER (type).objfile, gdb_stdout);
+ }
+ else
+ {
+ printfi_filtered (spaces, "gdbarch ");
+ gdb_print_host_address (TYPE_OWNER (type).gdbarch, gdb_stdout);
+ }
printf_filtered ("\n");
printfi_filtered (spaces, "target_type ");
- gdb_print_address (TYPE_TARGET_TYPE (type), gdb_stdout);
+ 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 ");
- gdb_print_address (TYPE_POINTER_TYPE (type), gdb_stdout);
+ gdb_print_host_address (TYPE_POINTER_TYPE (type), gdb_stdout);
printf_filtered ("\n");
printfi_filtered (spaces, "reference_type ");
- gdb_print_address (TYPE_REFERENCE_TYPE (type), gdb_stdout);
+ 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)
+ printfi_filtered (spaces, "type_chain ");
+ gdb_print_host_address (TYPE_CHAIN (type), gdb_stdout);
+ printf_filtered ("\n");
+ printfi_filtered (spaces, "instance_flags 0x%x",
+ TYPE_INSTANCE_FLAGS (type));
+ if (TYPE_CONST (type))
+ {
+ puts_filtered (" TYPE_FLAG_CONST");
+ }
+ if (TYPE_VOLATILE (type))
+ {
+ puts_filtered (" TYPE_FLAG_VOLATILE");
+ }
+ if (TYPE_CODE_SPACE (type))
+ {
+ puts_filtered (" TYPE_FLAG_CODE_SPACE");
+ }
+ if (TYPE_DATA_SPACE (type))
+ {
+ puts_filtered (" TYPE_FLAG_DATA_SPACE");
+ }
+ if (TYPE_ADDRESS_CLASS_1 (type))
+ {
+ puts_filtered (" TYPE_FLAG_ADDRESS_CLASS_1");
+ }
+ if (TYPE_ADDRESS_CLASS_2 (type))
+ {
+ puts_filtered (" TYPE_FLAG_ADDRESS_CLASS_2");
+ }
+ puts_filtered ("\n");
+
+ printfi_filtered (spaces, "flags");
+ if (TYPE_UNSIGNED (type))
{
puts_filtered (" TYPE_FLAG_UNSIGNED");
}
- if (TYPE_FLAGS (type) & TYPE_FLAG_STUB)
+ if (TYPE_NOSIGN (type))
+ {
+ puts_filtered (" TYPE_FLAG_NOSIGN");
+ }
+ if (TYPE_STUB (type))
{
puts_filtered (" TYPE_FLAG_STUB");
}
+ if (TYPE_TARGET_STUB (type))
+ {
+ puts_filtered (" TYPE_FLAG_TARGET_STUB");
+ }
+ if (TYPE_STATIC (type))
+ {
+ puts_filtered (" TYPE_FLAG_STATIC");
+ }
+ if (TYPE_PROTOTYPED (type))
+ {
+ puts_filtered (" TYPE_FLAG_PROTOTYPED");
+ }
+ if (TYPE_INCOMPLETE (type))
+ {
+ puts_filtered (" TYPE_FLAG_INCOMPLETE");
+ }
+ if (TYPE_VARARGS (type))
+ {
+ puts_filtered (" TYPE_FLAG_VARARGS");
+ }
+ /* This is used for things like AltiVec registers on ppc. Gcc emits
+ an attribute for the array type, which tells whether or not we
+ have a vector, instead of a regular array. */
+ if (TYPE_VECTOR (type))
+ {
+ puts_filtered (" TYPE_FLAG_VECTOR");
+ }
+ if (TYPE_FIXED_INSTANCE (type))
+ {
+ puts_filtered (" TYPE_FIXED_INSTANCE");
+ }
+ if (TYPE_STUB_SUPPORTED (type))
+ {
+ puts_filtered (" TYPE_STUB_SUPPORTED");
+ }
+ if (TYPE_NOTTEXT (type))
+ {
+ puts_filtered (" TYPE_NOTTEXT");
+ }
puts_filtered ("\n");
printfi_filtered (spaces, "nfields %d ", TYPE_NFIELDS (type));
- gdb_print_address (TYPE_FIELDS (type), gdb_stdout);
+ gdb_print_host_address (TYPE_FIELDS (type), gdb_stdout);
puts_filtered ("\n");
for (idx = 0; idx < TYPE_NFIELDS (type); idx++)
{
"[%d] bitpos %d bitsize %d type ",
idx, TYPE_FIELD_BITPOS (type, idx),
TYPE_FIELD_BITSIZE (type, idx));
- gdb_print_address (TYPE_FIELD_TYPE (type, idx), gdb_stdout);
+ 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_address (TYPE_FIELD_NAME (type, idx), gdb_stdout);
+ 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);
}
}
+ if (TYPE_CODE (type) == TYPE_CODE_RANGE)
+ {
+ printfi_filtered (spaces, "low %s%s high %s%s\n",
+ plongest (TYPE_LOW_BOUND (type)),
+ TYPE_LOW_BOUND_UNDEFINED (type) ? " (undefined)" : "",
+ plongest (TYPE_HIGH_BOUND (type)),
+ TYPE_HIGH_BOUND_UNDEFINED (type) ? " (undefined)" : "");
+ }
printfi_filtered (spaces, "vptr_basetype ");
- gdb_print_address (TYPE_VPTR_BASETYPE (type), gdb_stdout);
+ 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);
}
- printfi_filtered (spaces, "vptr_fieldno %d\n", TYPE_VPTR_FIELDNO (type));
+ 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 ");
- gdb_print_address (TYPE_ARG_TYPES (type), gdb_stdout);
- puts_filtered ("\n");
- print_arg_types (TYPE_ARG_TYPES (type), spaces);
- 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;
- case TYPE_CODE_STRUCT:
- printfi_filtered (spaces, "cplus_stuff ");
- gdb_print_address (TYPE_CPLUS_SPECIFIC (type), gdb_stdout);
- puts_filtered ("\n");
- print_cplus_stuff (type, spaces);
- break;
+ case TYPE_CODE_FLT:
+ printfi_filtered (spaces, "floatformat ");
+ if (TYPE_FLOATFORMAT (type) == NULL)
+ puts_filtered ("(null)");
+ else
+ {
+ puts_filtered ("{ ");
+ if (TYPE_FLOATFORMAT (type)[0] == NULL
+ || TYPE_FLOATFORMAT (type)[0]->name == NULL)
+ puts_filtered ("(null)");
+ else
+ puts_filtered (TYPE_FLOATFORMAT (type)[0]->name);
- 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_address (TYPE_CPLUS_SPECIFIC (type), gdb_stdout);
- if (TYPE_CPLUS_SPECIFIC (type) != NULL)
- {
- printf_filtered (" (unknown data form)");
- }
- printf_filtered ("\n");
- break;
+ puts_filtered (", ");
+ if (TYPE_FLOATFORMAT (type)[1] == NULL
+ || TYPE_FLOATFORMAT (type)[1]->name == NULL)
+ puts_filtered ("(null)");
+ else
+ puts_filtered (TYPE_FLOATFORMAT (type)[1]->name);
+
+ puts_filtered (" }");
+ }
+ puts_filtered ("\n");
+ 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);
}
-static void build_gdbtypes PARAMS ((void));
-static void
-build_gdbtypes ()
-{
- 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;
-
-}
-
-
-extern void _initialize_gdbtypes PARAMS ((void));
+/* Trivial helpers for the libiberty hash table, for mapping one
+ type to another. */
+
+struct type_pair
+{
+ struct type *old, *new;
+};
+
+static hashval_t
+type_pair_hash (const void *item)
+{
+ const struct type_pair *pair = item;
+ return htab_hash_pointer (pair->old);
+}
+
+static int
+type_pair_eq (const void *item_lhs, const void *item_rhs)
+{
+ const struct type_pair *lhs = item_lhs, *rhs = item_rhs;
+ return lhs->old == rhs->old;
+}
+
+/* Allocate the hash table used by copy_type_recursive to walk
+ types without duplicates. We use OBJFILE's obstack, because
+ OBJFILE is about to be deleted. */
+
+htab_t
+create_copied_types_hash (struct objfile *objfile)
+{
+ return htab_create_alloc_ex (1, type_pair_hash, type_pair_eq,
+ NULL, &objfile->objfile_obstack,
+ hashtab_obstack_allocate,
+ dummy_obstack_deallocate);
+}
+
+/* Recursively copy (deep copy) TYPE, if it is associated with
+ OBJFILE. Return a new type allocated using malloc, a saved type if
+ we have already visited TYPE (using COPIED_TYPES), or TYPE if it is
+ not associated with OBJFILE. */
+
+struct type *
+copy_type_recursive (struct objfile *objfile,
+ struct type *type,
+ htab_t copied_types)
+{
+ struct type_pair *stored, pair;
+ void **slot;
+ struct type *new_type;
+
+ if (! TYPE_OBJFILE_OWNED (type))
+ return type;
+
+ /* This type shouldn't be pointing to any types in other objfiles;
+ if it did, the type might disappear unexpectedly. */
+ gdb_assert (TYPE_OBJFILE (type) == objfile);
+
+ pair.old = type;
+ slot = htab_find_slot (copied_types, &pair, INSERT);
+ if (*slot != NULL)
+ return ((struct type_pair *) *slot)->new;
+
+ new_type = alloc_type_arch (get_type_arch (type));
+
+ /* We must add the new type to the hash table immediately, in case
+ we encounter this type again during a recursive call below. */
+ stored = obstack_alloc (&objfile->objfile_obstack, sizeof (struct type_pair));
+ stored->old = type;
+ stored->new = new_type;
+ *slot = stored;
+
+ /* Copy the common fields of types. For the main type, we simply
+ copy the entire thing and then update specific fields as needed. */
+ *TYPE_MAIN_TYPE (new_type) = *TYPE_MAIN_TYPE (type);
+ TYPE_OBJFILE_OWNED (new_type) = 0;
+ TYPE_OWNER (new_type).gdbarch = get_type_arch (type);
+
+ if (TYPE_NAME (type))
+ TYPE_NAME (new_type) = xstrdup (TYPE_NAME (type));
+ if (TYPE_TAG_NAME (type))
+ TYPE_TAG_NAME (new_type) = xstrdup (TYPE_TAG_NAME (type));
+
+ TYPE_INSTANCE_FLAGS (new_type) = TYPE_INSTANCE_FLAGS (type);
+ TYPE_LENGTH (new_type) = TYPE_LENGTH (type);
+
+ /* Copy the fields. */
+ if (TYPE_NFIELDS (type))
+ {
+ int i, nfields;
+
+ nfields = TYPE_NFIELDS (type);
+ TYPE_FIELDS (new_type) = XCALLOC (nfields, struct field);
+ for (i = 0; i < nfields; i++)
+ {
+ TYPE_FIELD_ARTIFICIAL (new_type, i) =
+ TYPE_FIELD_ARTIFICIAL (type, i);
+ TYPE_FIELD_BITSIZE (new_type, i) = TYPE_FIELD_BITSIZE (type, i);
+ if (TYPE_FIELD_TYPE (type, i))
+ TYPE_FIELD_TYPE (new_type, i)
+ = copy_type_recursive (objfile, TYPE_FIELD_TYPE (type, i),
+ copied_types);
+ if (TYPE_FIELD_NAME (type, i))
+ TYPE_FIELD_NAME (new_type, i) =
+ xstrdup (TYPE_FIELD_NAME (type, i));
+ switch (TYPE_FIELD_LOC_KIND (type, i))
+ {
+ case FIELD_LOC_KIND_BITPOS:
+ SET_FIELD_BITPOS (TYPE_FIELD (new_type, i),
+ TYPE_FIELD_BITPOS (type, i));
+ break;
+ case FIELD_LOC_KIND_PHYSADDR:
+ SET_FIELD_PHYSADDR (TYPE_FIELD (new_type, i),
+ TYPE_FIELD_STATIC_PHYSADDR (type, i));
+ break;
+ case FIELD_LOC_KIND_PHYSNAME:
+ SET_FIELD_PHYSNAME (TYPE_FIELD (new_type, i),
+ xstrdup (TYPE_FIELD_STATIC_PHYSNAME (type,
+ i)));
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ _("Unexpected type field location kind: %d"),
+ TYPE_FIELD_LOC_KIND (type, i));
+ }
+ }
+ }
+
+ /* For range types, copy the bounds information. */
+ if (TYPE_CODE (type) == TYPE_CODE_RANGE)
+ {
+ TYPE_RANGE_DATA (new_type) = xmalloc (sizeof (struct range_bounds));
+ *TYPE_RANGE_DATA (new_type) = *TYPE_RANGE_DATA (type);
+ }
+
+ /* Copy pointers to other types. */
+ if (TYPE_TARGET_TYPE (type))
+ TYPE_TARGET_TYPE (new_type) =
+ copy_type_recursive (objfile,
+ TYPE_TARGET_TYPE (type),
+ copied_types);
+ if (TYPE_VPTR_BASETYPE (type))
+ TYPE_VPTR_BASETYPE (new_type) =
+ copy_type_recursive (objfile,
+ TYPE_VPTR_BASETYPE (type),
+ copied_types);
+ /* Maybe copy the type_specific bits.
+
+ NOTE drow/2005-12-09: We do not copy the C++-specific bits like
+ base classes and methods. There's no fundamental reason why we
+ can't, but at the moment it is not needed. */
+
+ if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ TYPE_FLOATFORMAT (new_type) = TYPE_FLOATFORMAT (type);
+ else if (TYPE_CODE (type) == TYPE_CODE_STRUCT
+ || TYPE_CODE (type) == TYPE_CODE_UNION
+ || TYPE_CODE (type) == TYPE_CODE_TEMPLATE
+ || TYPE_CODE (type) == TYPE_CODE_NAMESPACE)
+ INIT_CPLUS_SPECIFIC (new_type);
+
+ return new_type;
+}
+
+/* Make a copy of the given TYPE, except that the pointer & reference
+ types are not preserved.
+
+ This function assumes that the given type has an associated objfile.
+ This objfile is used to allocate the new type. */
+
+struct type *
+copy_type (const struct type *type)
+{
+ struct type *new_type;
+
+ gdb_assert (TYPE_OBJFILE_OWNED (type));
+
+ new_type = alloc_type_copy (type);
+ TYPE_INSTANCE_FLAGS (new_type) = TYPE_INSTANCE_FLAGS (type);
+ TYPE_LENGTH (new_type) = TYPE_LENGTH (type);
+ memcpy (TYPE_MAIN_TYPE (new_type), TYPE_MAIN_TYPE (type),
+ sizeof (struct main_type));
+
+ return new_type;
+}
+
+
+/* Helper functions to initialize architecture-specific types. */
+
+/* Allocate a type structure associated with GDBARCH and set its
+ CODE, LENGTH, and NAME fields. */
+struct type *
+arch_type (struct gdbarch *gdbarch,
+ enum type_code code, int length, char *name)
+{
+ struct type *type;
+
+ type = alloc_type_arch (gdbarch);
+ TYPE_CODE (type) = code;
+ TYPE_LENGTH (type) = length;
+
+ if (name)
+ TYPE_NAME (type) = xstrdup (name);
+
+ return type;
+}
+
+/* Allocate a TYPE_CODE_INT type structure associated with GDBARCH.
+ BIT is the type size in bits. If UNSIGNED_P is non-zero, set
+ the type's TYPE_UNSIGNED flag. NAME is the type name. */
+struct type *
+arch_integer_type (struct gdbarch *gdbarch,
+ int bit, int unsigned_p, char *name)
+{
+ struct type *t;
+
+ t = arch_type (gdbarch, TYPE_CODE_INT, bit / TARGET_CHAR_BIT, name);
+ if (unsigned_p)
+ TYPE_UNSIGNED (t) = 1;
+ if (name && strcmp (name, "char") == 0)
+ TYPE_NOSIGN (t) = 1;
+
+ return t;
+}
+
+/* Allocate a TYPE_CODE_CHAR type structure associated with GDBARCH.
+ BIT is the type size in bits. If UNSIGNED_P is non-zero, set
+ the type's TYPE_UNSIGNED flag. NAME is the type name. */
+struct type *
+arch_character_type (struct gdbarch *gdbarch,
+ int bit, int unsigned_p, char *name)
+{
+ struct type *t;
+
+ t = arch_type (gdbarch, TYPE_CODE_CHAR, bit / TARGET_CHAR_BIT, name);
+ if (unsigned_p)
+ TYPE_UNSIGNED (t) = 1;
+
+ return t;
+}
+
+/* Allocate a TYPE_CODE_BOOL type structure associated with GDBARCH.
+ BIT is the type size in bits. If UNSIGNED_P is non-zero, set
+ the type's TYPE_UNSIGNED flag. NAME is the type name. */
+struct type *
+arch_boolean_type (struct gdbarch *gdbarch,
+ int bit, int unsigned_p, char *name)
+{
+ struct type *t;
+
+ t = arch_type (gdbarch, TYPE_CODE_BOOL, bit / TARGET_CHAR_BIT, name);
+ if (unsigned_p)
+ TYPE_UNSIGNED (t) = 1;
+
+ return t;
+}
+
+/* Allocate a TYPE_CODE_FLT type structure associated with GDBARCH.
+ BIT is the type size in bits; if BIT equals -1, the size is
+ determined by the floatformat. NAME is the type name. Set the
+ TYPE_FLOATFORMAT from FLOATFORMATS. */
+struct type *
+arch_float_type (struct gdbarch *gdbarch,
+ int bit, char *name, const struct floatformat **floatformats)
+{
+ struct type *t;
+
+ if (bit == -1)
+ {
+ gdb_assert (floatformats != NULL);
+ gdb_assert (floatformats[0] != NULL && floatformats[1] != NULL);
+ bit = floatformats[0]->totalsize;
+ }
+ gdb_assert (bit >= 0);
+
+ t = arch_type (gdbarch, TYPE_CODE_FLT, bit / TARGET_CHAR_BIT, name);
+ TYPE_FLOATFORMAT (t) = floatformats;
+ return t;
+}
+
+/* Allocate a TYPE_CODE_COMPLEX type structure associated with GDBARCH.
+ NAME is the type name. TARGET_TYPE is the component float type. */
+struct type *
+arch_complex_type (struct gdbarch *gdbarch,
+ char *name, struct type *target_type)
+{
+ struct type *t;
+ t = arch_type (gdbarch, TYPE_CODE_COMPLEX,
+ 2 * TYPE_LENGTH (target_type), name);
+ TYPE_TARGET_TYPE (t) = target_type;
+ return t;
+}
+
+/* Allocate a TYPE_CODE_FLAGS type structure associated with GDBARCH.
+ NAME is the type name. LENGTH is the number of flag bits. */
+struct type *
+arch_flags_type (struct gdbarch *gdbarch, char *name, int length)
+{
+ int nfields = length * TARGET_CHAR_BIT;
+ struct type *type;
+
+ type = arch_type (gdbarch, TYPE_CODE_FLAGS, length, name);
+ TYPE_UNSIGNED (type) = 1;
+ TYPE_NFIELDS (type) = nfields;
+ TYPE_FIELDS (type) = TYPE_ZALLOC (type, nfields * sizeof (struct field));
+
+ return type;
+}
+
+/* Add field to TYPE_CODE_FLAGS type TYPE to indicate the bit at
+ position BITPOS is called NAME. */
void
-_initialize_gdbtypes ()
-{
- 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 (NULL, 0, build_gdbtypes);
+append_flags_type_flag (struct type *type, int bitpos, char *name)
+{
+ gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLAGS);
+ gdb_assert (bitpos < TYPE_NFIELDS (type));
+ gdb_assert (bitpos >= 0);
+
+ if (name)
+ {
+ TYPE_FIELD_NAME (type, bitpos) = xstrdup (name);
+ TYPE_FIELD_BITPOS (type, bitpos) = bitpos;
+ }
+ else
+ {
+ /* Don't show this field to the user. */
+ TYPE_FIELD_BITPOS (type, bitpos) = -1;
+ }
+}
+
+/* Allocate a TYPE_CODE_STRUCT or TYPE_CODE_UNION type structure (as
+ specified by CODE) associated with GDBARCH. NAME is the type name. */
+struct type *
+arch_composite_type (struct gdbarch *gdbarch, char *name, enum type_code code)
+{
+ struct type *t;
+ gdb_assert (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION);
+ t = arch_type (gdbarch, code, 0, NULL);
+ TYPE_TAG_NAME (t) = name;
+ INIT_CPLUS_SPECIFIC (t);
+ return t;
+}
+
+/* Add new field with name NAME and type FIELD to composite type T.
+ ALIGNMENT (if non-zero) specifies the minimum field alignment. */
+void
+append_composite_type_field_aligned (struct type *t, char *name,
+ struct type *field, int alignment)
+{
+ struct field *f;
+ TYPE_NFIELDS (t) = TYPE_NFIELDS (t) + 1;
+ TYPE_FIELDS (t) = xrealloc (TYPE_FIELDS (t),
+ sizeof (struct field) * TYPE_NFIELDS (t));
+ f = &(TYPE_FIELDS (t)[TYPE_NFIELDS (t) - 1]);
+ memset (f, 0, sizeof f[0]);
+ FIELD_TYPE (f[0]) = field;
+ FIELD_NAME (f[0]) = name;
+ if (TYPE_CODE (t) == TYPE_CODE_UNION)
+ {
+ if (TYPE_LENGTH (t) < TYPE_LENGTH (field))
+ TYPE_LENGTH (t) = TYPE_LENGTH (field);
+ }
+ else if (TYPE_CODE (t) == TYPE_CODE_STRUCT)
+ {
+ TYPE_LENGTH (t) = TYPE_LENGTH (t) + TYPE_LENGTH (field);
+ if (TYPE_NFIELDS (t) > 1)
+ {
+ FIELD_BITPOS (f[0]) = (FIELD_BITPOS (f[-1])
+ + (TYPE_LENGTH (FIELD_TYPE (f[-1]))
+ * TARGET_CHAR_BIT));
+
+ if (alignment)
+ {
+ int left = FIELD_BITPOS (f[0]) % (alignment * TARGET_CHAR_BIT);
+ if (left)
+ {
+ FIELD_BITPOS (f[0]) += left;
+ TYPE_LENGTH (t) += left / TARGET_CHAR_BIT;
+ }
+ }
+ }
+ }
+}
+
+/* Add new field with name NAME and type FIELD to composite type T. */
+void
+append_composite_type_field (struct type *t, char *name,
+ struct type *field)
+{
+ append_composite_type_field_aligned (t, name, field, 0);
+}
+
+
+static struct gdbarch_data *gdbtypes_data;
+
+const struct builtin_type *
+builtin_type (struct gdbarch *gdbarch)
+{
+ return gdbarch_data (gdbarch, gdbtypes_data);
+}
+
+static void *
+gdbtypes_post_init (struct gdbarch *gdbarch)
+{
+ struct builtin_type *builtin_type
+ = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct builtin_type);
+
+ /* Basic types. */
+ builtin_type->builtin_void
+ = arch_type (gdbarch, TYPE_CODE_VOID, 1, "void");
+ builtin_type->builtin_char
+ = arch_integer_type (gdbarch, TARGET_CHAR_BIT,
+ !gdbarch_char_signed (gdbarch), "char");
+ builtin_type->builtin_signed_char
+ = arch_integer_type (gdbarch, TARGET_CHAR_BIT,
+ 0, "signed char");
+ builtin_type->builtin_unsigned_char
+ = arch_integer_type (gdbarch, TARGET_CHAR_BIT,
+ 1, "unsigned char");
+ builtin_type->builtin_short
+ = arch_integer_type (gdbarch, gdbarch_short_bit (gdbarch),
+ 0, "short");
+ builtin_type->builtin_unsigned_short
+ = arch_integer_type (gdbarch, gdbarch_short_bit (gdbarch),
+ 1, "unsigned short");
+ builtin_type->builtin_int
+ = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch),
+ 0, "int");
+ builtin_type->builtin_unsigned_int
+ = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch),
+ 1, "unsigned int");
+ builtin_type->builtin_long
+ = arch_integer_type (gdbarch, gdbarch_long_bit (gdbarch),
+ 0, "long");
+ builtin_type->builtin_unsigned_long
+ = arch_integer_type (gdbarch, gdbarch_long_bit (gdbarch),
+ 1, "unsigned long");
+ builtin_type->builtin_long_long
+ = arch_integer_type (gdbarch, gdbarch_long_long_bit (gdbarch),
+ 0, "long long");
+ builtin_type->builtin_unsigned_long_long
+ = arch_integer_type (gdbarch, gdbarch_long_long_bit (gdbarch),
+ 1, "unsigned long long");
+ builtin_type->builtin_float
+ = arch_float_type (gdbarch, gdbarch_float_bit (gdbarch),
+ "float", gdbarch_float_format (gdbarch));
+ builtin_type->builtin_double
+ = arch_float_type (gdbarch, gdbarch_double_bit (gdbarch),
+ "double", gdbarch_double_format (gdbarch));
+ builtin_type->builtin_long_double
+ = arch_float_type (gdbarch, gdbarch_long_double_bit (gdbarch),
+ "long double", gdbarch_long_double_format (gdbarch));
+ builtin_type->builtin_complex
+ = arch_complex_type (gdbarch, "complex",
+ builtin_type->builtin_float);
+ builtin_type->builtin_double_complex
+ = arch_complex_type (gdbarch, "double complex",
+ builtin_type->builtin_double);
+ builtin_type->builtin_string
+ = arch_type (gdbarch, TYPE_CODE_STRING, 1, "string");
+ builtin_type->builtin_bool
+ = arch_type (gdbarch, TYPE_CODE_BOOL, 1, "bool");
+
+ /* The following three are about decimal floating point types, which
+ are 32-bits, 64-bits and 128-bits respectively. */
+ builtin_type->builtin_decfloat
+ = arch_type (gdbarch, TYPE_CODE_DECFLOAT, 32 / 8, "_Decimal32");
+ builtin_type->builtin_decdouble
+ = arch_type (gdbarch, TYPE_CODE_DECFLOAT, 64 / 8, "_Decimal64");
+ builtin_type->builtin_declong
+ = arch_type (gdbarch, TYPE_CODE_DECFLOAT, 128 / 8, "_Decimal128");
+
+ /* "True" character types. */
+ builtin_type->builtin_true_char
+ = arch_character_type (gdbarch, TARGET_CHAR_BIT, 0, "true character");
+ builtin_type->builtin_true_unsigned_char
+ = arch_character_type (gdbarch, TARGET_CHAR_BIT, 1, "true character");
+
+ /* Fixed-size integer types. */
+ builtin_type->builtin_int0
+ = arch_integer_type (gdbarch, 0, 0, "int0_t");
+ builtin_type->builtin_int8
+ = arch_integer_type (gdbarch, 8, 0, "int8_t");
+ builtin_type->builtin_uint8
+ = arch_integer_type (gdbarch, 8, 1, "uint8_t");
+ builtin_type->builtin_int16
+ = arch_integer_type (gdbarch, 16, 0, "int16_t");
+ builtin_type->builtin_uint16
+ = arch_integer_type (gdbarch, 16, 1, "uint16_t");
+ builtin_type->builtin_int32
+ = arch_integer_type (gdbarch, 32, 0, "int32_t");
+ builtin_type->builtin_uint32
+ = arch_integer_type (gdbarch, 32, 1, "uint32_t");
+ builtin_type->builtin_int64
+ = arch_integer_type (gdbarch, 64, 0, "int64_t");
+ builtin_type->builtin_uint64
+ = arch_integer_type (gdbarch, 64, 1, "uint64_t");
+ builtin_type->builtin_int128
+ = arch_integer_type (gdbarch, 128, 0, "int128_t");
+ builtin_type->builtin_uint128
+ = arch_integer_type (gdbarch, 128, 1, "uint128_t");
+ TYPE_NOTTEXT (builtin_type->builtin_int8) = 1;
+ TYPE_NOTTEXT (builtin_type->builtin_uint8) = 1;
+
+ /* Default data/code pointer types. */
+ builtin_type->builtin_data_ptr
+ = lookup_pointer_type (builtin_type->builtin_void);
+ builtin_type->builtin_func_ptr
+ = lookup_pointer_type (lookup_function_type (builtin_type->builtin_void));
+
+ /* This type represents a GDB internal function. */
+ builtin_type->internal_fn
+ = arch_type (gdbarch, TYPE_CODE_INTERNAL_FUNCTION, 0,
+ "<internal function>");
+
+ return builtin_type;
+}
+
+
+/* This set of objfile-based types is intended to be used by symbol
+ readers as basic types. */
+
+static const struct objfile_data *objfile_type_data;
+
+const struct objfile_type *
+objfile_type (struct objfile *objfile)
+{
+ struct gdbarch *gdbarch;
+ struct objfile_type *objfile_type
+ = objfile_data (objfile, objfile_type_data);
+
+ if (objfile_type)
+ return objfile_type;
+
+ objfile_type = OBSTACK_CALLOC (&objfile->objfile_obstack,
+ 1, struct objfile_type);
+
+ /* Use the objfile architecture to determine basic type properties. */
+ gdbarch = get_objfile_arch (objfile);
+
+ /* Basic types. */
+ objfile_type->builtin_void
+ = init_type (TYPE_CODE_VOID, 1,
+ 0,
+ "void", objfile);
+
+ objfile_type->builtin_char
+ = init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ (TYPE_FLAG_NOSIGN
+ | (gdbarch_char_signed (gdbarch) ? 0 : TYPE_FLAG_UNSIGNED)),
+ "char", objfile);
+ objfile_type->builtin_signed_char
+ = init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ 0,
+ "signed char", objfile);
+ objfile_type->builtin_unsigned_char
+ = init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED,
+ "unsigned char", objfile);
+ objfile_type->builtin_short
+ = init_type (TYPE_CODE_INT,
+ gdbarch_short_bit (gdbarch) / TARGET_CHAR_BIT,
+ 0, "short", objfile);
+ objfile_type->builtin_unsigned_short
+ = init_type (TYPE_CODE_INT,
+ gdbarch_short_bit (gdbarch) / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED, "unsigned short", objfile);
+ objfile_type->builtin_int
+ = init_type (TYPE_CODE_INT,
+ gdbarch_int_bit (gdbarch) / TARGET_CHAR_BIT,
+ 0, "int", objfile);
+ objfile_type->builtin_unsigned_int
+ = init_type (TYPE_CODE_INT,
+ gdbarch_int_bit (gdbarch) / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED, "unsigned int", objfile);
+ objfile_type->builtin_long
+ = init_type (TYPE_CODE_INT,
+ gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT,
+ 0, "long", objfile);
+ objfile_type->builtin_unsigned_long
+ = init_type (TYPE_CODE_INT,
+ gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED, "unsigned long", objfile);
+ objfile_type->builtin_long_long
+ = init_type (TYPE_CODE_INT,
+ gdbarch_long_long_bit (gdbarch) / TARGET_CHAR_BIT,
+ 0, "long long", objfile);
+ objfile_type->builtin_unsigned_long_long
+ = init_type (TYPE_CODE_INT,
+ gdbarch_long_long_bit (gdbarch) / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED, "unsigned long long", objfile);
+
+ objfile_type->builtin_float
+ = init_type (TYPE_CODE_FLT,
+ gdbarch_float_bit (gdbarch) / TARGET_CHAR_BIT,
+ 0, "float", objfile);
+ TYPE_FLOATFORMAT (objfile_type->builtin_float)
+ = gdbarch_float_format (gdbarch);
+ objfile_type->builtin_double
+ = init_type (TYPE_CODE_FLT,
+ gdbarch_double_bit (gdbarch) / TARGET_CHAR_BIT,
+ 0, "double", objfile);
+ TYPE_FLOATFORMAT (objfile_type->builtin_double)
+ = gdbarch_double_format (gdbarch);
+ objfile_type->builtin_long_double
+ = init_type (TYPE_CODE_FLT,
+ gdbarch_long_double_bit (gdbarch) / TARGET_CHAR_BIT,
+ 0, "long double", objfile);
+ TYPE_FLOATFORMAT (objfile_type->builtin_long_double)
+ = gdbarch_long_double_format (gdbarch);
+
+ /* This type represents a type that was unrecognized in symbol read-in. */
+ objfile_type->builtin_error
+ = init_type (TYPE_CODE_ERROR, 0, 0, "<unknown type>", objfile);
+
+ /* The following set of types is used for symbols with no
+ debug information. */
+ objfile_type->nodebug_text_symbol
+ = init_type (TYPE_CODE_FUNC, 1, 0,
+ "<text variable, no debug info>", objfile);
+ TYPE_TARGET_TYPE (objfile_type->nodebug_text_symbol)
+ = objfile_type->builtin_int;
+ objfile_type->nodebug_data_symbol
+ = init_type (TYPE_CODE_INT,
+ gdbarch_int_bit (gdbarch) / HOST_CHAR_BIT, 0,
+ "<data variable, no debug info>", objfile);
+ objfile_type->nodebug_unknown_symbol
+ = init_type (TYPE_CODE_INT, 1, 0,
+ "<variable (not text or data), no debug info>", objfile);
+ objfile_type->nodebug_tls_symbol
+ = init_type (TYPE_CODE_INT,
+ gdbarch_int_bit (gdbarch) / HOST_CHAR_BIT, 0,
+ "<thread local variable, no debug info>", objfile);
+
+ /* NOTE: on some targets, addresses and pointers are not necessarily
+ the same --- for example, on the D10V, pointers are 16 bits long,
+ but addresses are 32 bits long. See doc/gdbint.texinfo,
+ ``Pointers Are Not Always Addresses''.
+
+ The upshot is:
+ - gdb's `struct type' always describes the target's
+ representation.
+ - gdb's `struct value' objects should always hold values in
+ target form.
+ - gdb's CORE_ADDR values are addresses in the unified virtual
+ address space that the assembler and linker work with. Thus,
+ since target_read_memory takes a CORE_ADDR as an argument, it
+ can access any memory on the target, even if the processor has
+ separate code and data address spaces.
+
+ So, for example:
+ - If v is a value holding a D10V code pointer, its contents are
+ in target form: a big-endian address left-shifted two bits.
+ - If p is a D10V pointer type, TYPE_LENGTH (p) == 2, just as
+ sizeof (void *) == 2 on the target.
+
+ In this context, objfile_type->builtin_core_addr is a bit odd:
+ it's a target type for a value the target will never see. It's
+ only used to hold the values of (typeless) linker symbols, which
+ are indeed in the unified virtual address space. */
+
+ objfile_type->builtin_core_addr
+ = init_type (TYPE_CODE_INT,
+ gdbarch_addr_bit (gdbarch) / 8,
+ TYPE_FLAG_UNSIGNED, "__CORE_ADDR", objfile);
+
+ set_objfile_data (objfile, objfile_type_data, objfile_type);
+ return objfile_type;
+}
+
+
+extern void _initialize_gdbtypes (void);
+void
+_initialize_gdbtypes (void)
+{
+ gdbtypes_data = gdbarch_data_register_post_init (gdbtypes_post_init);
+ objfile_type_data = register_objfile_data ();
+
+ add_setshow_zinteger_cmd ("overload", no_class, &overload_debug, _("\
+Set debugging of C++ overloading."), _("\
+Show debugging of C++ overloading."), _("\
+When enabled, ranking of the functions is displayed."),
+ NULL,
+ show_overload_debug,
+ &setdebuglist, &showdebuglist);
+
+ /* Add user knob for controlling resolution of opaque types. */
+ add_setshow_boolean_cmd ("opaque-type-resolution", class_support,
+ &opaque_type_resolution, _("\
+Set resolution of opaque struct/class/union types (if set before loading symbols)."), _("\
+Show resolution of opaque struct/class/union types (if set before loading symbols)."), NULL,
+ NULL,
+ show_opaque_type_resolution,
+ &setlist, &showlist);
}