X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fgdbtypes.c;h=f43983a072aecc0b80ae44166c8eb944ddb31434;hb=053cb41bd346a104eefeda533bc1388812e7fdf6;hp=f2fed5f5481d1b67a76d9fa4fa3fedce99983ece;hpb=ee3a7b7f0d021019dd51b6c86375aaa399f63f13;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index f2fed5f548..f43983a072 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -1,6 +1,8 @@ /* Support routines for manipulating internal types for GDB. - Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000 - Free Software Foundation, Inc. + + Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, + 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + Contributed by Cygnus Support, using pieces from other GDB modules. This file is part of GDB. @@ -17,8 +19,8 @@ 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. */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ #include "defs.h" #include "gdb_string.h" @@ -36,6 +38,8 @@ #include "gdbcmd.h" #include "wrapper.h" #include "cp-abi.h" +#include "gdb_assert.h" +#include "hashtab.h" /* These variables point to the objects representing the predefined C data types. */ @@ -59,6 +63,7 @@ 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_int0; struct type *builtin_type_int8; struct type *builtin_type_uint8; struct type *builtin_type_int16; @@ -67,19 +72,105 @@ struct type *builtin_type_int32; struct type *builtin_type_uint32; struct type *builtin_type_int64; struct type *builtin_type_uint64; +struct type *builtin_type_int128; +struct type *builtin_type_uint128; struct type *builtin_type_bool; + +/* 128 bit long vector types */ +struct type *builtin_type_v2_double; +struct type *builtin_type_v4_float; +struct type *builtin_type_v2_int64; +struct type *builtin_type_v4_int32; +struct type *builtin_type_v8_int16; +struct type *builtin_type_v16_int8; +/* 64 bit long vector types */ +struct type *builtin_type_v2_float; +struct type *builtin_type_v2_int32; +struct type *builtin_type_v4_int16; +struct type *builtin_type_v8_int8; + struct type *builtin_type_v4sf; struct type *builtin_type_v4si; +struct type *builtin_type_v16qi; struct type *builtin_type_v8qi; +struct type *builtin_type_v8hi; struct type *builtin_type_v4hi; struct type *builtin_type_v2si; -struct type *builtin_type_ptr; +struct type *builtin_type_vec64; +struct type *builtin_type_vec128; + +/* 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 +}; + +struct type *builtin_type_ieee_single; +struct type *builtin_type_ieee_double; +struct type *builtin_type_i387_ext; +struct type *builtin_type_m68881_ext; +struct type *builtin_type_arm_ext; +struct type *builtin_type_ia64_spill; +struct type *builtin_type_ia64_quad; + +struct type *builtin_type_void_data_ptr; struct type *builtin_type_void_func_ptr; struct type *builtin_type_CORE_ADDR; struct type *builtin_type_bfd_vma; 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 { @@ -87,13 +178,8 @@ struct extra int len; }; /* maximum extension is 128! FIXME */ -static void add_name (struct extra *, char *); -static void add_mangled_type (struct extra *, struct type *); -#if 0 -static void cfront_mangle_name (struct type *, int, int); -#endif static void print_bit_vector (B_TYPE *, int); -static void print_arg_types (struct type **, int); +static void print_arg_types (struct field *, int, int); static void dump_fn_fieldlists (struct type *, int); static void print_cplus_stuff (struct type *, int); static void virtual_base_list_aux (struct type *dclass); @@ -101,37 +187,85 @@ static void virtual_base_list_aux (struct type *dclass); /* Alloc a new type structure and fill it with some defaults. If OBJFILE is non-NULL, then allocate the space for the type structure - in that objfile's type_obstack. */ + in that objfile's objfile_obstack. Otherwise allocate the new type structure + by xmalloc () (for permanent types). */ struct type * alloc_type (struct objfile *objfile) { - register struct type *type; + struct type *type; /* Alloc the structure and start off with all fields zeroed. */ if (objfile == NULL) { - type = (struct type *) xmalloc (sizeof (struct type)); + type = xmalloc (sizeof (struct type)); + memset (type, 0, sizeof (struct type)); + TYPE_MAIN_TYPE (type) = xmalloc (sizeof (struct main_type)); } else { - type = (struct type *) obstack_alloc (&objfile->type_obstack, - sizeof (struct type)); + type = obstack_alloc (&objfile->objfile_obstack, + sizeof (struct type)); + memset (type, 0, sizeof (struct type)); + TYPE_MAIN_TYPE (type) = obstack_alloc (&objfile->objfile_obstack, + sizeof (struct main_type)); OBJSTAT (objfile, n_types++); } - memset ((char *) type, 0, sizeof (struct type)); + memset (TYPE_MAIN_TYPE (type), 0, sizeof (struct main_type)); /* 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); +} + +/* 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 (oldtype) == NULL) + { + type = xmalloc (sizeof (struct type)); + memset (type, 0, sizeof (struct type)); + } + else + { + type = obstack_alloc (&TYPE_OBJFILE (oldtype)->objfile_obstack, + sizeof (struct type)); + memset (type, 0, sizeof (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. */ +static void +smash_type (struct type *type) +{ + memset (TYPE_MAIN_TYPE (type), 0, sizeof (struct main_type)); + + /* For now, delete the rings. */ + TYPE_CHAIN (type) = type; + + /* For now, leave the pointer/reference types alone. */ +} + /* Lookup a pointer to a type TYPE. TYPEPTR, if nonzero, points to a pointer to memory where the pointer type should be stored. If *TYPEPTR is zero, update it to point to the pointer type we return. @@ -140,8 +274,9 @@ alloc_type (struct objfile *objfile) struct type * make_pointer_type (struct type *type, struct type **typeptr) { - register struct type *ntype; /* New type */ + struct type *ntype; /* New type */ struct objfile *objfile; + struct type *chain; ntype = TYPE_POINTER_TYPE (type); @@ -167,7 +302,9 @@ make_pointer_type (struct type *type, struct type **typeptr) { ntype = *typeptr; objfile = TYPE_OBJFILE (ntype); - memset ((char *) ntype, 0, sizeof (struct type)); + chain = TYPE_CHAIN (ntype); + smash_type (ntype); + TYPE_CHAIN (ntype) = chain; TYPE_OBJFILE (ntype) = objfile; } @@ -187,6 +324,14 @@ make_pointer_type (struct type *type, struct type **typeptr) 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; } @@ -207,7 +352,7 @@ lookup_pointer_type (struct type *type) struct type * make_reference_type (struct type *type, struct type **typeptr) { - register struct type *ntype; /* New type */ + struct type *ntype; /* New type */ struct objfile *objfile; ntype = TYPE_REFERENCE_TYPE (type); @@ -234,7 +379,7 @@ make_reference_type (struct type *type, struct type **typeptr) { ntype = *typeptr; objfile = TYPE_OBJFILE (ntype); - memset ((char *) ntype, 0, sizeof (struct type)); + smash_type (ntype); TYPE_OBJFILE (ntype) = objfile; } @@ -269,7 +414,7 @@ lookup_reference_type (struct type *type) struct type * make_function_type (struct type *type, struct type **typeptr) { - register struct type *ntype; /* New type */ + struct type *ntype; /* New type */ struct objfile *objfile; if (typeptr == 0 || *typeptr == 0) /* We'll need to allocate one. */ @@ -283,7 +428,7 @@ make_function_type (struct type *type, struct type **typeptr) { ntype = *typeptr; objfile = TYPE_OBJFILE (ntype); - memset ((char *) ntype, 0, sizeof (struct type)); + smash_type (ntype); TYPE_OBJFILE (ntype) = objfile; } @@ -305,85 +450,211 @@ 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 (char *space_identifier) +{ + struct gdbarch *gdbarch = current_gdbarch; + int type_flags; + /* Check for known address space delimiters. */ + if (!strcmp (space_identifier, "code")) + return TYPE_FLAG_CODE_SPACE; + else if (!strcmp (space_identifier, "data")) + return TYPE_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 (int space_flag) +{ + struct gdbarch *gdbarch = current_gdbarch; + if (space_flag & TYPE_FLAG_CODE_SPACE) + return "code"; + else if (space_flag & TYPE_FLAG_DATA_SPACE) + return "data"; + else if ((space_flag & TYPE_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) +{ + 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_FLAG_CODE_SPACE | TYPE_FLAG_DATA_SPACE + | TYPE_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 (int cnst, int voltl, struct type *type, struct type **typeptr) { - register struct type *ntype; /* New type */ - register struct type *tmp_type = type; /* tmp type */ + struct type *ntype; /* New type */ + struct type *tmp_type = type; /* tmp type */ struct objfile *objfile; - ntype = TYPE_CV_TYPE (type); - - while (ntype != type) - { - if ((TYPE_CONST (ntype) == cnst) && - (TYPE_VOLATILE (ntype) == voltl)) - { - if (typeptr == 0) - return ntype; - else if (*typeptr == 0) - { - *typeptr = ntype; /* Tracking alloc, and we have new type. */ - return ntype; - } - } - tmp_type = ntype; - ntype = TYPE_CV_TYPE (ntype); - } - - if (typeptr == 0 || *typeptr == 0) /* We'll need to allocate one. */ - { - ntype = alloc_type (TYPE_OBJFILE (type)); - if (typeptr) - *typeptr = ntype; - } - else - /* We have storage, but need to reset it. */ - { - ntype = *typeptr; - objfile = TYPE_OBJFILE (ntype); - /* memset ((char *) ntype, 0, sizeof (struct type)); */ - TYPE_OBJFILE (ntype) = objfile; - } - - /* Copy original type */ - memcpy ((char *) ntype, (char *) type, sizeof (struct type)); - /* But zero out fields that shouldn't be copied */ - TYPE_POINTER_TYPE (ntype) = (struct type *) 0; /* Need new pointer kind */ - TYPE_REFERENCE_TYPE (ntype) = (struct type *) 0; /* Need new referene kind */ - /* Note: TYPE_TARGET_TYPE can be left as is */ + int new_flags = (TYPE_INSTANCE_FLAGS (type) + & ~(TYPE_FLAG_CONST | TYPE_FLAG_VOLATILE)); - /* Set flags appropriately */ if (cnst) - TYPE_FLAGS (ntype) |= TYPE_FLAG_CONST; - else - TYPE_FLAGS (ntype) &= ~TYPE_FLAG_CONST; + new_flags |= TYPE_FLAG_CONST; if (voltl) - TYPE_FLAGS (ntype) |= TYPE_FLAG_VOLATILE; - else - TYPE_FLAGS (ntype) &= ~TYPE_FLAG_VOLATILE; + new_flags |= TYPE_FLAG_VOLATILE; + + if (typeptr && *typeptr != NULL) + { + /* 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. - /* Fix the chain of cv variants */ - TYPE_CV_TYPE (ntype) = type; - TYPE_CV_TYPE (tmp_type) = ntype; + 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); + + if (typeptr != NULL) + *typeptr = ntype; return ntype; } +/* 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. - + 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; + + /* 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. @@ -391,15 +662,30 @@ make_cv_type (int cnst, int voltl, struct type *type, struct type **typeptr) of the aggregate that the member belongs to. */ struct type * -lookup_member_type (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); + smash_to_memberptr_type (mtype, domain, type); return (mtype); } +/* Return a pointer-to-method type, for a method of type TO_TYPE. */ + +struct type * +lookup_methodptr_type (struct type *to_type) +{ + struct type *mtype; + + mtype = alloc_type (TYPE_OBJFILE (to_type)); + TYPE_TARGET_TYPE (mtype) = to_type; + TYPE_DOMAIN_TYPE (mtype) = TYPE_DOMAIN_TYPE (to_type); + TYPE_LENGTH (mtype) = cplus_method_ptr_size (); + 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 @@ -411,13 +697,10 @@ allocate_stub_method (struct type *type) { struct type *mtype; - mtype = alloc_type (TYPE_OBJFILE (type)); + mtype = init_type (TYPE_CODE_METHOD, 1, TYPE_FLAG_STUB, NULL, + TYPE_OBJFILE (type)); TYPE_TARGET_TYPE (mtype) = type; /* _DOMAIN_TYPE (mtype) = unknown yet */ - /* _ARG_TYPES (mtype) = unknown yet */ - TYPE_FLAGS (mtype) = TYPE_FLAG_STUB; - TYPE_CODE (mtype) = TYPE_CODE_METHOD; - TYPE_LENGTH (mtype) = 1; return (mtype); } @@ -440,7 +723,7 @@ create_range_type (struct type *result_type, struct type *index_type, } TYPE_CODE (result_type) = TYPE_CODE_RANGE; TYPE_TARGET_TYPE (result_type) = index_type; - if (TYPE_FLAGS (index_type) & TYPE_FLAG_STUB) + if (TYPE_STUB (index_type)) TYPE_FLAGS (result_type) |= TYPE_FLAG_TARGET_STUB; else TYPE_LENGTH (result_type) = TYPE_LENGTH (check_typedef (index_type)); @@ -460,7 +743,7 @@ create_range_type (struct type *result_type, struct type *index_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 + Return 1 if type is a range type, 0 if it is discrete (and bounds will fit in LONGEST), or -1 otherwise. */ int @@ -582,8 +865,12 @@ create_array_type (struct type *result_type, struct type *element_type, struct type * create_string_type (struct type *result_type, struct type *range_type) { + struct type *string_char_type; + + string_char_type = language_string_char_type (current_language, + current_gdbarch); 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); @@ -603,7 +890,7 @@ create_set_type (struct type *result_type, struct type *domain_type) TYPE_ALLOC (result_type, 1 * sizeof (struct field)); memset (TYPE_FIELDS (result_type), 0, sizeof (struct field)); - if (!(TYPE_FLAGS (domain_type) & TYPE_FLAG_STUB)) + if (!TYPE_STUB (domain_type)) { if (get_discrete_bounds (domain_type, &low_bound, &high_bound) < 0) low_bound = high_bound = 0; @@ -619,6 +906,38 @@ create_set_type (struct type *result_type, struct type *domain_type) return (result_type); } +void +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; + } +} + +struct type * +init_flags_type (char *name, int length) +{ + int nfields = length * TARGET_CHAR_BIT; + struct type *type; + + type = init_type (TYPE_CODE_FLAGS, length, TYPE_FLAG_UNSIGNED, name, NULL); + TYPE_NFIELDS (type) = nfields; + TYPE_FIELDS (type) = TYPE_ALLOC (type, nfields * sizeof (struct field)); + memset (TYPE_FIELDS (type), 0, nfields * sizeof (struct field)); + + return type; +} /* Construct and return a type of the form: struct NAME { ELT_TYPE ELT_NAME[N]; } @@ -635,52 +954,116 @@ init_simd_type (char *name, char *elt_name, int n) { + struct type *simd_type; + struct type *array_type; + + simd_type = init_composite_type (name, TYPE_CODE_STRUCT); + array_type = create_array_type (0, elt_type, + create_range_type (0, builtin_type_int, + 0, n-1)); + append_composite_type_field (simd_type, elt_name, array_type); + return simd_type; +} + +static struct type * +init_vector_type (struct type *elt_type, int n) +{ + struct type *array_type; + + array_type = create_array_type (0, elt_type, + create_range_type (0, builtin_type_int, + 0, n-1)); + TYPE_FLAGS (array_type) |= TYPE_FLAG_VECTOR; + return array_type; +} + +static struct type * +build_builtin_type_vec64 (void) +{ + /* Construct a type for the 64 bit registers. The type we're + building is this: */ +#if 0 + union __gdb_builtin_type_vec64 + { + int64_t uint64; + float v2_float[2]; + int32_t v2_int32[2]; + int16_t v4_int16[4]; + int8_t v8_int8[8]; + }; +#endif + struct type *t; - struct field *f; - /* Build the field structure. */ - f = xmalloc (sizeof (*f)); - memset (f, 0, sizeof (*f)); - f->loc.bitpos = 0; - f->type = create_array_type (0, elt_type, - create_range_type (0, builtin_type_int, - 0, n-1)); - f->name = elt_name; - - /* Build a struct type with that field. */ - t = init_type (TYPE_CODE_STRUCT, n * TYPE_LENGTH (elt_type), 0, 0, 0); - t->nfields = 1; - t->fields = f; - t->tag_name = name; + t = init_composite_type ("__gdb_builtin_type_vec64", TYPE_CODE_UNION); + append_composite_type_field (t, "uint64", builtin_type_int64); + append_composite_type_field (t, "v2_float", builtin_type_v2_float); + append_composite_type_field (t, "v2_int32", builtin_type_v2_int32); + append_composite_type_field (t, "v4_int16", builtin_type_v4_int16); + append_composite_type_field (t, "v8_int8", builtin_type_v8_int8); + TYPE_FLAGS (t) |= TYPE_FLAG_VECTOR; + TYPE_NAME (t) = "builtin_type_vec64"; return t; } +static struct type * +build_builtin_type_vec128 (void) +{ + /* Construct a type for the 128 bit registers. The type we're + building is this: */ +#if 0 + union __gdb_builtin_type_vec128 + { + int128_t uint128; + float v4_float[4]; + int32_t v4_int32[4]; + int16_t v8_int16[8]; + int8_t v16_int8[16]; + }; +#endif + + struct type *t; + + t = init_composite_type ("__gdb_builtin_type_vec128", TYPE_CODE_UNION); + append_composite_type_field (t, "uint128", builtin_type_int128); + append_composite_type_field (t, "v4_float", builtin_type_v4_float); + append_composite_type_field (t, "v4_int32", builtin_type_v4_int32); + append_composite_type_field (t, "v8_int16", builtin_type_v8_int16); + append_composite_type_field (t, "v16_int8", builtin_type_v16_int8); + + TYPE_FLAGS (t) |= TYPE_FLAG_VECTOR; + TYPE_NAME (t) = "builtin_type_vec128"; + return t; +} -/* Smash TYPE to be a type of members of DOMAIN with type TO_TYPE. - A MEMBER is a wierd thing -- it amounts to a typed offset into - a struct, e.g. "an int at offset 8". A MEMBER TYPE doesn't - 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 allocated. */ void -smash_to_member_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)); + smash_type (type); TYPE_OBJFILE (type) = objfile; 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) = TARGET_PTR_BIT / TARGET_CHAR_BIT; + TYPE_CODE (type) = TYPE_CODE_MEMBERPTR; } /* Smash TYPE to be a type of method of DOMAIN with type TO_TYPE. @@ -692,17 +1075,21 @@ smash_to_member_type (struct type *type, struct type *domain, void smash_to_method_type (struct type *type, struct type *domain, - struct type *to_type, struct type **args) + 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)); + smash_type (type); TYPE_OBJFILE (type) = objfile; 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_FLAGS (type) |= TYPE_FLAG_VARARGS; TYPE_LENGTH (type) = 1; /* In practice, this is never needed. */ TYPE_CODE (type) = TYPE_CODE_METHOD; } @@ -711,7 +1098,7 @@ smash_to_method_type (struct type *type, struct type *domain, "union ", or "enum ". If the type has a NULL name, return NULL. */ char * -type_name_no_tag (register const struct type *type) +type_name_no_tag (const struct type *type) { if (TYPE_TAG_NAME (type) != NULL) return TYPE_TAG_NAME (type); @@ -722,24 +1109,6 @@ type_name_no_tag (register const struct type *type) return TYPE_NAME (type); } -/* Lookup a primitive type named NAME. - Return zero if NAME is not a primitive type. */ - -struct type * -lookup_primitive_typename (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. */ @@ -747,13 +1116,15 @@ lookup_primitive_typename (char *name) struct type * lookup_typename (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, (struct symtab **) NULL); if (sym == NULL || SYMBOL_CLASS (sym) != LOC_TYPEDEF) { - tmp = lookup_primitive_typename (name); + tmp = language_lookup_primitive_type_by_name (current_language, + current_gdbarch, + name); if (tmp) { return (tmp); @@ -764,7 +1135,7 @@ lookup_typename (char *name, struct block *block, int noerr) } else { - error ("No type named %s.", name); + error (_("No type named %s."), name); } } return (SYMBOL_TYPE (sym)); @@ -801,18 +1172,18 @@ lookup_signed_typename (char *name) struct type * lookup_struct (char *name, struct block *block) { - register struct symbol *sym; + struct symbol *sym; - sym = lookup_symbol (name, block, STRUCT_NAMESPACE, 0, + sym = lookup_symbol (name, block, STRUCT_DOMAIN, 0, (struct symtab **) NULL); 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)); } @@ -823,14 +1194,14 @@ lookup_struct (char *name, struct block *block) struct type * lookup_union (char *name, struct block *block) { - register struct symbol *sym; + struct symbol *sym; struct type *t; - sym = lookup_symbol (name, block, STRUCT_NAMESPACE, 0, + sym = lookup_symbol (name, block, STRUCT_DOMAIN, 0, (struct symtab **) NULL); if (sym == NULL) - error ("No union type named %s.", name); + error (_("No union type named %s."), name); t = SYMBOL_TYPE (sym); @@ -845,7 +1216,7 @@ lookup_union (char *name, struct block *block) return (t); /* If we get here, it's not a union */ - error ("This context has class, struct or enum %s, not a union.", name); + error (_("This context has class, struct or enum %s, not a union."), name); } @@ -855,17 +1226,17 @@ lookup_union (char *name, struct block *block) struct type * lookup_enum (char *name, struct block *block) { - register struct symbol *sym; + struct symbol *sym; - sym = lookup_symbol (name, block, STRUCT_NAMESPACE, 0, + sym = lookup_symbol (name, block, STRUCT_DOMAIN, 0, (struct symtab **) NULL); 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)); } @@ -877,21 +1248,21 @@ struct type * 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, (struct symtab **) NULL); 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)); } @@ -927,7 +1298,7 @@ lookup_struct_elt_type (struct type *type, char *name, int noerr) 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 @@ -939,7 +1310,7 @@ lookup_struct_elt_type (struct type *type, char *name, int noerr) char *typename; typename = type_name_no_tag (type); - if (typename != NULL && STREQ (typename, name)) + if (typename != NULL && strcmp (typename, name) == 0) return type; } #endif @@ -959,7 +1330,7 @@ lookup_struct_elt_type (struct type *type, char *name, int noerr) { 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; @@ -977,7 +1348,7 @@ lookup_struct_elt_type (struct type *type, char *name, int noerr) type_print (type, "", gdb_stderr, -1); fprintf_unfiltered (gdb_stderr, " has no component named "); fputs_filtered (name, gdb_stderr); - error ("."); + error ((".")); return (struct type *) -1; /* For lint */ } @@ -1001,13 +1372,12 @@ fill_in_vptr_fieldno (struct type *type) 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)); + fill_in_vptr_fieldno (baseclass); + if (TYPE_VPTR_FIELDNO (baseclass) >= 0) { - TYPE_VPTR_FIELDNO (type) - = TYPE_VPTR_FIELDNO (TYPE_BASECLASS (type, i)); - TYPE_VPTR_BASETYPE (type) - = TYPE_VPTR_BASETYPE (TYPE_BASECLASS (type, i)); + TYPE_VPTR_FIELDNO (type) = TYPE_VPTR_FIELDNO (baseclass); + TYPE_VPTR_BASETYPE (type) = TYPE_VPTR_BASETYPE (baseclass); break; } } @@ -1040,6 +1410,12 @@ get_destructor_fn_field (struct type *t, int *method_indexp, int *field_indexp) return 0; } +static void +stub_noname_complaint (void) +{ + 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 @@ -1053,13 +1429,17 @@ get_destructor_fn_field (struct type *t, int *method_indexp, int *field_indexp) 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 (register struct type *type) +check_typedef (struct type *type) { struct type *orig_type = type; + int is_const, is_volatile; + while (TYPE_CODE (type) == TYPE_CODE_TYPEDEF) { if (!TYPE_TARGET_TYPE (type)) @@ -1074,15 +1454,15 @@ check_typedef (register struct type *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 + 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, + sym = lookup_symbol (name, 0, STRUCT_DOMAIN, 0, (struct symtab **) NULL); if (sym) TYPE_TARGET_TYPE (type) = SYMBOL_TYPE (sym); @@ -1092,6 +1472,9 @@ check_typedef (register struct type *type) type = TYPE_TARGET_TYPE (type); } + 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 @@ -1103,42 +1486,62 @@ check_typedef (register struct type *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) + else if (TYPE_STUB (type) && !currently_reading_symtab) { 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 + 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, (struct symtab **) NULL); 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)) { } else if (TYPE_CODE (type) == TYPE_CODE_ARRAY @@ -1166,206 +1569,10 @@ check_typedef (register struct type *type) return type; } -/* New code added to support parsing of Cfront stabs strings */ -#define INIT_EXTRA { pextras->len=0; pextras->str[0]='\0'; } -#define ADD_EXTRA(c) { pextras->str[pextras->len++]=c; } - -static void -add_name (struct extra *pextras, char *n) -{ - int nlen; - - if ((nlen = (n ? strlen (n) : 0)) == 0) - return; - sprintf (pextras->str + pextras->len, "%d%s", nlen, n); - pextras->len = strlen (pextras->str); -} - -static void -add_mangled_type (struct extra *pextras, struct type *t) -{ - enum type_code tcode; - int tlen, tflags; - char *tname; - - 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; - - /* errors possible types/not supported */ - case TYPE_CODE_CHAR: - case TYPE_CODE_ARRAY: /* Array type */ - case TYPE_CODE_MEMBER: /* Member type */ - case TYPE_CODE_BOOL: - case TYPE_CODE_COMPLEX: /* Complex float */ - case TYPE_CODE_UNDEF: - case TYPE_CODE_SET: /* Pascal sets */ - case TYPE_CODE_RANGE: - case TYPE_CODE_STRING: - case TYPE_CODE_BITSTRING: - case TYPE_CODE_ERROR: - default: - { - static struct complaint msg = - {"Unknown type code x%x\n", 0, 0}; - complain (&msg, tcode); - } - } - if (t->target_type) - add_mangled_type (pextras, t->target_type); -} - -#if 0 -void -cfront_mangle_name (struct type *type, int i, int j) -{ - struct fn_field *f; - char *mangled_name = gdb_mangle_name (type, i, j); - - f = TYPE_FN_FIELDLIST1 (type, i); /* moved from below */ - - /* kludge to support cfront methods - gdb expects to find "F" for - ARM_mangled names, so when we mangle, we have to add it here */ - if (ARM_DEMANGLING) - { - int k; - char *arm_mangled_name; - struct fn_field *method = &f[j]; - char *field_name = TYPE_FN_FIELDLIST_NAME (type, i); - char *physname = TYPE_FN_FIELD_PHYSNAME (f, j); - char *newname = type_name_no_tag (type); - - struct type *ftype = TYPE_FN_FIELD_TYPE (f, j); - int nargs = TYPE_NFIELDS (ftype); /* number of args */ - struct extra extras, *pextras = &extras; - INIT_EXTRA - - if (TYPE_FN_FIELD_STATIC_P (f, j)) /* j for sublist within this list */ - ADD_EXTRA ('S') - ADD_EXTRA ('F') - /* add args here! */ - if (nargs <= 1) /* no args besides this */ - ADD_EXTRA ('v') - else - { - for (k = 1; k < nargs; k++) - { - struct type *t; - t = TYPE_FIELD_TYPE (ftype, k); - add_mangled_type (pextras, t); - } - } - ADD_EXTRA ('\0') - printf ("add_mangled_type: %s\n", extras.str); /* FIXME */ - xasprintf (&arm_mangled_name, "%s%s", mangled_name, extras.str); - xfree (mangled_name); - mangled_name = arm_mangled_name; - } -} -#endif /* 0 */ - -#undef ADD_EXTRA -/* End of new code added to support parsing of Cfront stabs strings */ - /* Parse a type expression in the string [P..P+LENGTH). If an error occurs, silently return builtin_type_void. */ -struct type * +static struct type * safe_parse_type (char *p, int length) { struct ui_file *saved_gdb_stderr; @@ -1396,7 +1603,7 @@ safe_parse_type (char *p, int length) which info used to be in the stab's but was removed to hack back the space required for them. */ -void +static void check_stub_method (struct type *type, int method_id, int signature_id) { struct fn_field *f; @@ -1405,7 +1612,7 @@ check_stub_method (struct type *type, int method_id, int signature_id) 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. */ @@ -1415,7 +1622,7 @@ check_stub_method (struct type *type, int method_id, int signature_id) 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; @@ -1438,15 +1645,25 @@ check_stub_method (struct type *type, int method_id, int signature_id) 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; + + /* 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 */ { @@ -1455,10 +1672,12 @@ check_stub_method (struct type *type, int method_id, int signature_id) { if (depth <= 0 && (*p == ',' || *p == ')')) { - /* Avoid parsing of ellipsis, they will be handled below. */ - 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] = + argtypes[argcount].type = safe_parse_type (argtypetext, p - argtypetext); argcount += 1; } @@ -1478,27 +1697,62 @@ check_stub_method (struct type *type, int method_id, int signature_id) } } - if (p[-2] != '.') /* Not '...' */ - { - argtypes[argcount] = builtin_type_void; /* List terminator */ - } - else - { - argtypes[argcount] = NULL; /* Ellist terminator */ - } - - xfree (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_FIELDS (mtype) = argtypes; + TYPE_NFIELDS (mtype) = argcount; TYPE_FLAGS (mtype) &= ~TYPE_FLAG_STUB; TYPE_FN_FIELD_STUB (f, signature_id) = 0; + if (p[-2] == '.') + TYPE_FLAGS (mtype) |= TYPE_FLAG_VARARGS; + + 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; @@ -1517,7 +1771,7 @@ allocate_cplus_struct_type (struct type *type) /* 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, + 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). */ @@ -1525,7 +1779,7 @@ struct type * 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; @@ -1534,7 +1788,7 @@ init_type (enum type_code code, int length, int flags, char *name, if ((name != NULL) && (objfile != NULL)) { TYPE_NAME (type) = - obsavestring (name, strlen (name), &objfile->type_obstack); + obsavestring (name, strlen (name), &objfile->objfile_obstack); } else { @@ -1543,13 +1797,59 @@ init_type (enum type_code code, int length, int flags, char *name, /* C++ fancies. */ - if (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION) + if (name && strcmp (name, "char") == 0) + TYPE_FLAGS (type) |= TYPE_FLAG_NOSIGN; + + if (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION + || code == TYPE_CODE_NAMESPACE) { INIT_CPLUS_SPECIFIC (type); } return (type); } +/* Helper function. Create an empty composite type. */ + +struct type * +init_composite_type (char *name, enum type_code code) +{ + struct type *t; + gdb_assert (code == TYPE_CODE_STRUCT + || code == TYPE_CODE_UNION); + t = init_type (code, 0, 0, NULL, NULL); + TYPE_TAG_NAME (t) = name; + return t; +} + +/* Helper function. Append a field to a composite type. */ + +void +append_composite_type_field (struct type *t, char *name, struct type *field) +{ + 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) * TARGET_CHAR_BIT); + } + } +} + /* Look up a fundamental type for the specified objfile. May need to construct such a type if this is the first use. @@ -1574,12 +1874,12 @@ init_type (enum type_code code, int length, int flags, char *name, struct type * lookup_fundamental_type (struct objfile *objfile, int typeid) { - register struct type **typep; - register int nbytes; + struct type **typep; + int nbytes; if (typeid < 0 || typeid >= FT_NUM_MEMBERS) { - error ("internal error - invalid fundamental type id %d", typeid); + error (_("internal error - invalid fundamental type id %d"), typeid); } /* If this is the first time we need a fundamental type for this objfile @@ -1589,7 +1889,7 @@ lookup_fundamental_type (struct objfile *objfile, int typeid) { nbytes = FT_NUM_MEMBERS * sizeof (struct type *); objfile->fundamental_types = (struct type **) - obstack_alloc (&objfile->type_obstack, nbytes); + obstack_alloc (&objfile->objfile_obstack, nbytes); memset ((char *) objfile->fundamental_types, 0, nbytes); OBJSTAT (objfile, n_types += FT_NUM_MEMBERS); } @@ -1625,27 +1925,12 @@ is_integral_type (struct type *t) ((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))); } -/* Chill varying string and arrays are represented as follows: - - struct { int __var_length; ELEMENT_TYPE[MAX_SIZE] __var_data}; - - Return true if TYPE is such a Chill varying type. */ - -int -chill_varying_type (struct type *type) -{ - if (TYPE_CODE (type) != TYPE_CODE_STRUCT - || TYPE_NFIELDS (type) != 2 - || strcmp (TYPE_FIELD_NAME (type, 0), "__var_length") != 0) - return 0; - return 1; -} - /* Check whether BASE is an ancestor or base class or DCLASS Return 1 if so, and 0 if not. Note: callers may want to check for identity of the types before @@ -1685,7 +1970,7 @@ has_vtable (struct type *dclass) /* In the HP ANSI C++ runtime model, a class has a vtable only if it has virtual functions or virtual bases. */ - register int i; + int i; if (TYPE_CODE (dclass) != TYPE_CODE_CLASS) return 0; @@ -1728,7 +2013,7 @@ primary_base_class (struct type *dclass) is the first directly inherited, non-virtual base class that requires a virtual table */ - register int i; + int i; if (TYPE_CODE (dclass) != TYPE_CODE_CLASS) return NULL; @@ -1757,7 +2042,7 @@ static void virtual_base_list_aux (struct type *dclass) { struct vbase *tmp_vbase; - register int i; + int i; if (TYPE_CODE (dclass) != TYPE_CODE_CLASS) return; @@ -1814,9 +2099,9 @@ virtual_base_list_aux (struct type *dclass) struct type ** virtual_base_list (struct type *dclass) { - register struct vbase *tmp_vbase; - register struct vbase *tmp_vbase_2; - register int i; + struct vbase *tmp_vbase; + struct vbase *tmp_vbase_2; + int i; int count; struct type **vbase_array; @@ -1851,8 +2136,8 @@ virtual_base_list (struct type *dclass) int virtual_base_list_length (struct type *dclass) { - register int i; - register struct vbase *tmp_vbase; + int i; + struct vbase *tmp_vbase; current_vbase_list = NULL; virtual_base_list_aux (dclass); @@ -1869,8 +2154,8 @@ virtual_base_list_length (struct type *dclass) int virtual_base_list_length_skip_primaries (struct type *dclass) { - register int i; - register struct vbase *tmp_vbase; + int i; + struct vbase *tmp_vbase; struct type *primary; primary = TYPE_RUNTIME_PTR (dclass) ? TYPE_PRIMARY_BASE (dclass) : NULL; @@ -1898,8 +2183,8 @@ virtual_base_list_length_skip_primaries (struct type *dclass) int virtual_base_index (struct type *base, struct type *dclass) { - register struct type *vbase; - register int i; + struct type *vbase; + int i; if ((TYPE_CODE (dclass) != TYPE_CODE_CLASS) || (TYPE_CODE (base) != TYPE_CODE_CLASS)) @@ -1928,8 +2213,8 @@ virtual_base_index (struct type *base, struct type *dclass) int virtual_base_index_skip_primaries (struct type *base, struct type *dclass) { - register struct type *vbase; - register int i, j; + struct type *vbase; + int i, j; struct type *primary; if ((TYPE_CODE (dclass) != TYPE_CODE_CLASS) || @@ -2084,6 +2369,43 @@ rank_function (struct type **parms, int nparms, struct type **args, int nargs) 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 @@ -2156,6 +2478,7 @@ rank_one_type (struct type *parm, struct type *arg) 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: @@ -2194,44 +2517,49 @@ rank_one_type (struct type *parm, struct type *arg) if (TYPE_NOSIGN (arg)) /* plain char -> plain char */ return 0; else - return INTEGER_COERCION_BADNESS; /* signed/unsigned char -> plain char */ + return INTEGER_CONVERSION_BADNESS; /* signed/unsigned char -> plain char */ } else if (TYPE_UNSIGNED (parm)) { if (TYPE_UNSIGNED (arg)) { - if (!strcmp_iw (TYPE_NAME (parm), TYPE_NAME (arg))) - return 0; /* unsigned int -> unsigned int, or unsigned long -> unsigned long */ - else if (!strcmp_iw (TYPE_NAME (arg), "int") && !strcmp_iw (TYPE_NAME (parm), "long")) + /* 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_COERCION_BADNESS; /* unsigned long -> unsigned int */ + return INTEGER_CONVERSION_BADNESS; /* unsigned long -> unsigned int */ } else { - if (!strcmp_iw (TYPE_NAME (arg), "long") && !strcmp_iw (TYPE_NAME (parm), "int")) - return INTEGER_COERCION_BADNESS; /* signed long -> unsigned int */ + 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 (!strcmp_iw (TYPE_NAME (parm), TYPE_NAME (arg))) + if (integer_types_same_name_p (TYPE_NAME (parm), TYPE_NAME (arg))) return 0; - else if (!strcmp_iw (TYPE_NAME (arg), "int") && !strcmp_iw (TYPE_NAME (parm), "long")) + 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_COERCION_BADNESS; + return INTEGER_CONVERSION_BADNESS; } else - return INTEGER_COERCION_BADNESS; + return INTEGER_CONVERSION_BADNESS; } else if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm)) return INTEGER_PROMOTION_BADNESS; else - return INTEGER_COERCION_BADNESS; + return INTEGER_CONVERSION_BADNESS; case TYPE_CODE_ENUM: + case TYPE_CODE_FLAGS: case TYPE_CODE_CHAR: case TYPE_CODE_RANGE: case TYPE_CODE_BOOL: @@ -2252,7 +2580,7 @@ rank_one_type (struct type *parm, struct type *arg) case TYPE_CODE_RANGE: case TYPE_CODE_BOOL: case TYPE_CODE_ENUM: - return INTEGER_COERCION_BADNESS; + return INTEGER_CONVERSION_BADNESS; case TYPE_CODE_FLT: return INT_FLOAT_CONVERSION_BADNESS; default: @@ -2265,12 +2593,12 @@ rank_one_type (struct type *parm, struct type *arg) case TYPE_CODE_RANGE: case TYPE_CODE_BOOL: case TYPE_CODE_ENUM: - return INTEGER_COERCION_BADNESS; + return INTEGER_CONVERSION_BADNESS; case TYPE_CODE_FLT: return INT_FLOAT_CONVERSION_BADNESS; case TYPE_CODE_INT: if (TYPE_LENGTH (arg) > TYPE_LENGTH (parm)) - return INTEGER_COERCION_BADNESS; + return INTEGER_CONVERSION_BADNESS; else if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm)) return INTEGER_PROMOTION_BADNESS; /* >>> !! else fall through !! <<< */ @@ -2282,7 +2610,7 @@ rank_one_type (struct type *parm, struct type *arg) if (TYPE_NOSIGN (arg)) return 0; else - return INTEGER_COERCION_BADNESS; + return INTEGER_CONVERSION_BADNESS; } else if (TYPE_UNSIGNED (parm)) { @@ -2294,7 +2622,7 @@ rank_one_type (struct type *parm, struct type *arg) else if (!TYPE_NOSIGN (arg) && !TYPE_UNSIGNED (arg)) return 0; else - return INTEGER_COERCION_BADNESS; + return INTEGER_CONVERSION_BADNESS; default: return INCOMPATIBLE_TYPE_BADNESS; } @@ -2307,7 +2635,7 @@ rank_one_type (struct type *parm, struct type *arg) case TYPE_CODE_RANGE: case TYPE_CODE_BOOL: case TYPE_CODE_ENUM: - return INTEGER_COERCION_BADNESS; + return INTEGER_CONVERSION_BADNESS; case TYPE_CODE_FLT: return INT_FLOAT_CONVERSION_BADNESS; default: @@ -2382,7 +2710,7 @@ rank_one_type (struct type *parm, struct type *arg) return INCOMPATIBLE_TYPE_BADNESS; } break; - case TYPE_CODE_MEMBER: + case TYPE_CODE_MEMBERPTR: switch (TYPE_CODE (arg)) { default: @@ -2437,35 +2765,24 @@ print_bit_vector (B_TYPE *bits, int nbits) puts_filtered (" "); } if (B_TST (bits, bitno)) - { - printf_filtered ("1"); - } + printf_filtered (("1")); else - { - printf_filtered ("0"); - } + printf_filtered (("0")); } } -/* 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. */ +/* 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 type **args, int spaces) +print_arg_types (struct field *args, int nargs, int spaces) { if (args != NULL) { - while (*args != NULL) - { - recursive_dump_type (*args, spaces + 2); - if ((*args++)->code == TYPE_CODE_VOID) - { - break; - } - } + int i; + + for (i = 0; i < nargs; i++) + recursive_dump_type (args[i].type, spaces + 2); } } @@ -2487,7 +2804,7 @@ dump_fn_fieldlists (struct type *type, int spaces) TYPE_FN_FIELDLIST_NAME (type, method_idx)); gdb_print_host_address (TYPE_FN_FIELDLIST_NAME (type, method_idx), gdb_stdout); - printf_filtered (") length %d\n", + 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); @@ -2510,7 +2827,9 @@ dump_fn_fieldlists (struct type *type, int spaces) 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_host_address (TYPE_FN_FIELD_FCONTEXT (f, overload_idx), gdb_stdout); @@ -2581,6 +2900,35 @@ print_cplus_stuff (struct type *type, int spaces) } } +static void +print_bound_type (int bt) +{ + switch (bt) + { + case BOUND_CANNOT_BE_DETERMINED: + printf_filtered ("(BOUND_CANNOT_BE_DETERMINED)"); + break; + case BOUND_BY_REF_ON_STACK: + printf_filtered ("(BOUND_BY_REF_ON_STACK)"); + break; + case BOUND_BY_VALUE_ON_STACK: + printf_filtered ("(BOUND_BY_VALUE_ON_STACK)"); + break; + case BOUND_BY_REF_IN_REG: + printf_filtered ("(BOUND_BY_REF_IN_REG)"); + break; + case BOUND_BY_VALUE_IN_REG: + printf_filtered ("(BOUND_BY_VALUE_IN_REG)"); + break; + case BOUND_SIMPLE: + printf_filtered ("(BOUND_SIMPLE)"); + break; + default: + printf_filtered (_("(unknown bound type)")); + break; + } +} + static struct obstack dont_print_type_obstack; void @@ -2606,7 +2954,7 @@ recursive_dump_type (struct type *type, int spaces) { printfi_filtered (spaces, "type node "); gdb_print_host_address (type, gdb_stdout); - printf_filtered (" \n"); + printf_filtered (_(" \n")); return; } } @@ -2621,13 +2969,10 @@ recursive_dump_type (struct type *type, int spaces) TYPE_NAME (type) ? TYPE_NAME (type) : ""); gdb_print_host_address (TYPE_NAME (type), gdb_stdout); printf_filtered (")\n"); - if (TYPE_TAG_NAME (type) != NULL) - { - printfi_filtered (spaces, "tagname '%s' (", - TYPE_TAG_NAME (type)); - gdb_print_host_address (TYPE_TAG_NAME (type), gdb_stdout); - printf_filtered (")\n"); - } + printfi_filtered (spaces, "tagname '%s' (", + TYPE_TAG_NAME (type) ? TYPE_TAG_NAME (type) : ""); + gdb_print_host_address (TYPE_TAG_NAME (type), gdb_stdout); + printf_filtered (")\n"); printfi_filtered (spaces, "code 0x%x ", TYPE_CODE (type)); switch (TYPE_CODE (type)) { @@ -2649,6 +2994,9 @@ recursive_dump_type (struct type *type, int spaces) 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; @@ -2670,11 +3018,17 @@ recursive_dump_type (struct type *type, int spaces) 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_MEMBER: - printf_filtered ("(TYPE_CODE_MEMBER)"); + 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)"); @@ -2688,15 +3042,35 @@ recursive_dump_type (struct type *type, int spaces) 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, "upper_bound_type 0x%x ", + TYPE_ARRAY_UPPER_BOUND_TYPE (type)); + print_bound_type (TYPE_ARRAY_UPPER_BOUND_TYPE (type)); + puts_filtered ("\n"); + printfi_filtered (spaces, "lower_bound_type 0x%x ", + TYPE_ARRAY_LOWER_BOUND_TYPE (type)); + print_bound_type (TYPE_ARRAY_LOWER_BOUND_TYPE (type)); + puts_filtered ("\n"); printfi_filtered (spaces, "objfile "); gdb_print_host_address (TYPE_OBJFILE (type), gdb_stdout); printf_filtered ("\n"); @@ -2713,15 +3087,75 @@ recursive_dump_type (struct type *type, int spaces) printfi_filtered (spaces, "reference_type "); gdb_print_host_address (TYPE_REFERENCE_TYPE (type), gdb_stdout); printf_filtered ("\n"); + 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 0x%x", TYPE_FLAGS (type)); - if (TYPE_FLAGS (type) & TYPE_FLAG_UNSIGNED) + 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"); + } puts_filtered ("\n"); printfi_filtered (spaces, "nfields %d ", TYPE_NFIELDS (type)); gdb_print_host_address (TYPE_FIELDS (type), gdb_stdout); @@ -2754,14 +3188,6 @@ recursive_dump_type (struct type *type, int spaces) printfi_filtered (spaces, "vptr_fieldno %d\n", TYPE_VPTR_FIELDNO (type)); switch (TYPE_CODE (type)) { - case TYPE_CODE_METHOD: - case TYPE_CODE_FUNC: - printfi_filtered (spaces, "arg_types "); - gdb_print_host_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); @@ -2769,6 +3195,31 @@ recursive_dump_type (struct type *type, int spaces) 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); + + 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 @@ -2777,7 +3228,7 @@ recursive_dump_type (struct type *type, int spaces) gdb_print_host_address (TYPE_CPLUS_SPECIFIC (type), gdb_stdout); if (TYPE_CPLUS_SPECIFIC (type) != NULL) { - printf_filtered (" (unknown data form)"); + printf_filtered (_(" (unknown data form)")); } printf_filtered ("\n"); break; @@ -2787,7 +3238,165 @@ recursive_dump_type (struct type *type, int spaces) obstack_free (&dont_print_type_obstack, NULL); } -static void build_gdbtypes (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 (type) == NULL) + 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 (NULL); + + /* We must add the new type to the hash table immediately, in case + we encounter this type again during a recursive call below. */ + stored = xmalloc (sizeof (struct type_pair)); + stored->old = type; + stored->new = new_type; + *slot = stored; + + /* Copy the common fields of types. */ + TYPE_CODE (new_type) = TYPE_CODE (type); + TYPE_ARRAY_UPPER_BOUND_TYPE (new_type) = TYPE_ARRAY_UPPER_BOUND_TYPE (type); + TYPE_ARRAY_LOWER_BOUND_TYPE (new_type) = TYPE_ARRAY_LOWER_BOUND_TYPE (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_FLAGS (new_type) = TYPE_FLAGS (type); + TYPE_VPTR_FIELDNO (new_type) = TYPE_VPTR_FIELDNO (type); + + TYPE_INSTANCE_FLAGS (new_type) = TYPE_INSTANCE_FLAGS (type); + TYPE_LENGTH (new_type) = TYPE_LENGTH (type); + + /* Copy the fields. */ + TYPE_NFIELDS (new_type) = TYPE_NFIELDS (type); + if (TYPE_NFIELDS (type)) + { + int i, nfields; + + nfields = TYPE_NFIELDS (type); + TYPE_FIELDS (new_type) = xmalloc (sizeof (struct field) * nfields); + 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)); + if (TYPE_FIELD_STATIC_HAS_ADDR (type, i)) + SET_FIELD_PHYSADDR (TYPE_FIELD (new_type, i), + TYPE_FIELD_STATIC_PHYSADDR (type, i)); + else if (TYPE_FIELD_STATIC (type, i)) + SET_FIELD_PHYSNAME (TYPE_FIELD (new_type, i), + xstrdup (TYPE_FIELD_STATIC_PHYSNAME (type, i))); + else + { + TYPE_FIELD_BITPOS (new_type, i) = TYPE_FIELD_BITPOS (type, i); + TYPE_FIELD_STATIC_KIND (new_type, i) = 0; + } + } + } + + /* 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; +} + +static struct type * +build_flt (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 = init_type (TYPE_CODE_FLT, bit / TARGET_CHAR_BIT, 0, name, NULL); + TYPE_FLOATFORMAT (t) = floatformats; + return t; +} + static void build_gdbtypes (void) { @@ -2797,9 +3406,9 @@ build_gdbtypes (void) "void", (struct objfile *) NULL); builtin_type_char = init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT, - 0, + (TYPE_FLAG_NOSIGN + | (TARGET_CHAR_SIGNED ? 0 : TYPE_FLAG_UNSIGNED)), "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, @@ -2844,18 +3453,14 @@ build_gdbtypes (void) 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_float = build_flt (TARGET_FLOAT_BIT, "float", + TARGET_FLOAT_FORMAT); + builtin_type_double = build_flt (TARGET_DOUBLE_BIT, "double", + TARGET_DOUBLE_FORMAT); + builtin_type_long_double = build_flt (TARGET_LONG_DOUBLE_BIT, "long double", + TARGET_LONG_DOUBLE_FORMAT); + builtin_type_complex = init_type (TYPE_CODE_COMPLEX, 2 * TARGET_FLOAT_BIT / TARGET_CHAR_BIT, 0, @@ -2870,64 +3475,54 @@ build_gdbtypes (void) 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); + 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); opaque_type_resolution = 1; - /* Build SIMD types. */ builtin_type_v4sf = init_simd_type ("__builtin_v4sf", builtin_type_float, "f", 4); builtin_type_v4si = init_simd_type ("__builtin_v4si", builtin_type_int32, "f", 4); + builtin_type_v16qi + = init_simd_type ("__builtin_v16qi", builtin_type_int8, "f", 16); builtin_type_v8qi = init_simd_type ("__builtin_v8qi", builtin_type_int8, "f", 8); + builtin_type_v8hi + = init_simd_type ("__builtin_v8hi", builtin_type_int16, "f", 8); builtin_type_v4hi = init_simd_type ("__builtin_v4hi", builtin_type_int16, "f", 4); builtin_type_v2si = init_simd_type ("__builtin_v2si", builtin_type_int32, "f", 2); + /* 128 bit vectors. */ + builtin_type_v2_double = init_vector_type (builtin_type_double, 2); + builtin_type_v4_float = init_vector_type (builtin_type_float, 4); + builtin_type_v2_int64 = init_vector_type (builtin_type_int64, 2); + builtin_type_v4_int32 = init_vector_type (builtin_type_int32, 4); + builtin_type_v8_int16 = init_vector_type (builtin_type_int16, 8); + builtin_type_v16_int8 = init_vector_type (builtin_type_int8, 16); + /* 64 bit vectors. */ + builtin_type_v2_float = init_vector_type (builtin_type_float, 2); + builtin_type_v2_int32 = init_vector_type (builtin_type_int32, 2); + builtin_type_v4_int16 = init_vector_type (builtin_type_int16, 4); + builtin_type_v8_int8 = init_vector_type (builtin_type_int8, 8); + + /* Vector types. */ + builtin_type_vec64 = build_builtin_type_vec64 (); + builtin_type_vec128 = build_builtin_type_vec128 (); + /* Pointer/Address types. */ /* NOTE: on some targets, addresses and pointers are not necessarily @@ -2956,7 +3551,7 @@ build_gdbtypes (void) 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. */ - builtin_type_ptr = make_pointer_type (builtin_type_void, NULL); + builtin_type_void_data_ptr = make_pointer_type (builtin_type_void, NULL); builtin_type_void_func_ptr = lookup_pointer_type (lookup_function_type (builtin_type_void)); builtin_type_CORE_ADDR = @@ -2969,58 +3564,285 @@ build_gdbtypes (void) "__bfd_vma", (struct objfile *) NULL); } +static struct gdbarch_data *gdbtypes_data; + +const struct builtin_type * +builtin_type (struct gdbarch *gdbarch) +{ + return gdbarch_data (gdbarch, gdbtypes_data); +} + + +static struct type * +build_complex (int bit, char *name, struct type *target_type) +{ + struct type *t; + if (bit <= 0 || target_type == builtin_type_error) + { + gdb_assert (builtin_type_error != NULL); + return builtin_type_error; + } + t = init_type (TYPE_CODE_COMPLEX, 2 * bit / TARGET_CHAR_BIT, + 0, name, (struct objfile *) NULL); + TYPE_TARGET_TYPE (t) = target_type; + return t; +} + +static void * +gdbtypes_post_init (struct gdbarch *gdbarch) +{ + struct builtin_type *builtin_type + = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct builtin_type); + + builtin_type->builtin_void = + init_type (TYPE_CODE_VOID, 1, + 0, + "void", (struct objfile *) NULL); + builtin_type->builtin_char = + init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT, + (TYPE_FLAG_NOSIGN + | (TARGET_CHAR_SIGNED ? 0 : TYPE_FLAG_UNSIGNED)), + "char", (struct objfile *) NULL); + builtin_type->builtin_true_char = + init_type (TYPE_CODE_CHAR, TARGET_CHAR_BIT / TARGET_CHAR_BIT, + 0, + "true character", (struct objfile *) NULL); + builtin_type->builtin_signed_char = + init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT, + 0, + "signed char", (struct objfile *) NULL); + builtin_type->builtin_unsigned_char = + init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT, + TYPE_FLAG_UNSIGNED, + "unsigned char", (struct objfile *) NULL); + builtin_type->builtin_short = + init_type (TYPE_CODE_INT, TARGET_SHORT_BIT / TARGET_CHAR_BIT, + 0, + "short", (struct objfile *) NULL); + builtin_type->builtin_unsigned_short = + init_type (TYPE_CODE_INT, TARGET_SHORT_BIT / TARGET_CHAR_BIT, + TYPE_FLAG_UNSIGNED, + "unsigned short", (struct objfile *) NULL); + builtin_type->builtin_int = + init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT, + 0, + "int", (struct objfile *) NULL); + builtin_type->builtin_unsigned_int = + init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT, + TYPE_FLAG_UNSIGNED, + "unsigned int", (struct objfile *) NULL); + builtin_type->builtin_long = + init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT, + 0, + "long", (struct objfile *) NULL); + builtin_type->builtin_unsigned_long = + init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT, + TYPE_FLAG_UNSIGNED, + "unsigned long", (struct objfile *) NULL); + builtin_type->builtin_long_long = + init_type (TYPE_CODE_INT, TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT, + 0, + "long long", (struct objfile *) NULL); + builtin_type->builtin_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->builtin_float + = build_flt (gdbarch_float_bit (gdbarch), "float", + gdbarch_float_format (gdbarch)); + builtin_type->builtin_double + = build_flt (gdbarch_double_bit (gdbarch), "double", + gdbarch_double_format (gdbarch)); + builtin_type->builtin_long_double + = build_flt (gdbarch_long_double_bit (gdbarch), "long double", + gdbarch_long_double_format (gdbarch)); + builtin_type->builtin_complex + = build_complex (gdbarch_float_bit (gdbarch), "complex", + builtin_type->builtin_float); + builtin_type->builtin_double_complex + = build_complex (gdbarch_double_bit (gdbarch), "double complex", + builtin_type->builtin_double); + builtin_type->builtin_string = + init_type (TYPE_CODE_STRING, TARGET_CHAR_BIT / TARGET_CHAR_BIT, + 0, + "string", (struct objfile *) NULL); + builtin_type->builtin_bool = + init_type (TYPE_CODE_BOOL, TARGET_CHAR_BIT / TARGET_CHAR_BIT, + 0, + "bool", (struct objfile *) NULL); + + /* Pointer/Address types. */ + + /* 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, builtin_type->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. */ + builtin_type->builtin_data_ptr + = make_pointer_type (builtin_type->builtin_void, NULL); + builtin_type->builtin_func_ptr + = lookup_pointer_type (lookup_function_type (builtin_type->builtin_void)); + builtin_type->builtin_core_addr = + init_type (TYPE_CODE_INT, TARGET_ADDR_BIT / 8, + TYPE_FLAG_UNSIGNED, + "__CORE_ADDR", (struct objfile *) NULL); + + return builtin_type; +} extern void _initialize_gdbtypes (void); void _initialize_gdbtypes (void) { struct cmd_list_element *c; + + /* FIXME: Why don't the following types need to be arch-swapped? + See the comment at the top of the calls to + DEPRECATED_REGISTER_GDBARCH_SWAP below. */ + builtin_type_int0 = + init_type (TYPE_CODE_INT, 0 / 8, + 0, + "int0_t", (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_int128 = + init_type (TYPE_CODE_INT, 128 / 8, + 0, + "int128_t", (struct objfile *) NULL); + builtin_type_uint128 = + init_type (TYPE_CODE_INT, 128 / 8, + TYPE_FLAG_UNSIGNED, + "uint128_t", (struct objfile *) NULL); + build_gdbtypes (); + gdbtypes_data = gdbarch_data_register_post_init (gdbtypes_post_init); + /* FIXME - For the moment, handle types by swapping them in and out. Should be using the per-architecture data-pointer and a large - struct. */ - register_gdbarch_swap (&builtin_type_void, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_char, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_short, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_int, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_long, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_long_long, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_signed_char, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_unsigned_char, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_unsigned_short, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_unsigned_int, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_unsigned_long, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_unsigned_long_long, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_float, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_double, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_long_double, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_complex, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_double_complex, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_string, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_int8, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_uint8, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_int16, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_uint16, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_int32, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_uint32, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_int64, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_uint64, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_v4sf, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_v4si, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_v8qi, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_v4hi, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_v2si, sizeof (struct type *), NULL); - REGISTER_GDBARCH_SWAP (builtin_type_ptr); - REGISTER_GDBARCH_SWAP (builtin_type_void_func_ptr); - REGISTER_GDBARCH_SWAP (builtin_type_CORE_ADDR); - REGISTER_GDBARCH_SWAP (builtin_type_bfd_vma); - register_gdbarch_swap (NULL, 0, build_gdbtypes); - - add_show_from_set ( - add_set_cmd ("overload", no_class, var_zinteger, (char *) &overload_debug, - "Set debugging of C++ overloading.\n\ - When enabled, ranking of the functions\n\ - is displayed.", &setdebuglist), - &showdebuglist); + struct. + + Note that any type T that we might create a 'T *' type for must + be arch-swapped: we cache a type's 'T *' type in the pointer_type + field, so if we change architectures but don't swap T, then + lookup_pointer_type will start handing out pointer types made for + a different architecture. */ + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_void); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_char); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_short); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_int); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_long); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_long_long); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_signed_char); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_unsigned_char); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_unsigned_short); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_unsigned_int); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_unsigned_long); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_unsigned_long_long); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_float); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_double); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_long_double); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_complex); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_double_complex); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_string); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v4sf); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v4si); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v16qi); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v8qi); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v8hi); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v4hi); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v2si); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v2_double); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v4_float); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v2_int64); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v4_int32); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v8_int16); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v16_int8); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v2_float); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v2_int32); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v8_int8); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v4_int16); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_vec128); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_void_data_ptr); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_void_func_ptr); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_CORE_ADDR); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_bfd_vma); + deprecated_register_gdbarch_swap (NULL, 0, build_gdbtypes); + + /* Note: These types do not need to be swapped - they are target + neutral. FIXME: Are you sure? See the comment above the calls + to DEPRECATED_REGISTER_GDBARCH_SWAP above. */ + builtin_type_ieee_single + = build_flt (-1, "builtin_type_ieee_single", floatformats_ieee_single); + builtin_type_ieee_double + = build_flt (-1, "builtin_type_ieee_double", floatformats_ieee_double); + builtin_type_i387_ext + = build_flt (-1, "builtin_type_i387_ext", floatformats_i387_ext); + builtin_type_m68881_ext + = build_flt (-1, "builtin_type_m68881_ext", floatformats_m68881_ext); + builtin_type_arm_ext + = build_flt (-1, "builtin_type_arm_ext", floatformats_arm_ext); + builtin_type_ia64_spill + = build_flt (-1, "builtin_type_ia64_spill", floatformats_ia64_spill); + builtin_type_ia64_quad + = build_flt (-1, "builtin_type_ia64_quad", floatformats_ia64_quad); + + 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); }