X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fgdbtypes.c;h=b1e03d1643c512c2d65404286cf4b1534259d498;hb=11a8b1641e310f3d47173125b62ee2e2147e74f3;hp=4160d996de5f8d019edd7c7b6d3562fae5cdb2fb;hpb=6b1747cd135ff9859fceb6043179b1ef94363996;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 4160d996de..b1e03d1643 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -1,6 +1,6 @@ /* Support routines for manipulating internal types for GDB. - Copyright (C) 1992-2018 Free Software Foundation, Inc. + Copyright (C) 1992-2019 Free Software Foundation, Inc. Contributed by Cygnus Support, using pieces from other GDB modules. @@ -116,16 +116,15 @@ const struct floatformat *floatformats_ibm_long_double[BFD_ENDIAN_UNKNOWN] = { /* Should opaque types be resolved? */ -static int opaque_type_resolution = 1; +static bool opaque_type_resolution = true; -/* A flag to enable printing of debugging information of C++ - overloading. */ +/* See gdbtypes.h. */ unsigned int overload_debug = 0; /* A flag to enable strict type checking. */ -static int strict_type_checking = 1; +static bool strict_type_checking = true; /* A function to show whether opaque types are resolved. */ @@ -574,7 +573,8 @@ lookup_function_type_with_arguments (struct type *type, return the integer flag defined in gdbtypes.h. */ int -address_space_name_to_int (struct gdbarch *gdbarch, char *space_identifier) +address_space_name_to_int (struct gdbarch *gdbarch, + const char *space_identifier) { int type_flags; @@ -900,7 +900,8 @@ operator== (const range_bounds &l, const range_bounds &r) return (FIELD_EQ (low) && FIELD_EQ (high) && FIELD_EQ (flag_upper_bound_is_count) - && FIELD_EQ (flag_bound_evaluated)); + && FIELD_EQ (flag_bound_evaluated) + && FIELD_EQ (bias)); #undef FIELD_EQ } @@ -911,8 +912,14 @@ operator== (const range_bounds &l, const range_bounds &r) struct type * create_range_type (struct type *result_type, struct type *index_type, const struct dynamic_prop *low_bound, - const struct dynamic_prop *high_bound) + const struct dynamic_prop *high_bound, + LONGEST bias) { + /* The INDEX_TYPE should be a type capable of holding the upper and lower + bounds, as such a zero sized, or void type makes no sense. */ + gdb_assert (TYPE_CODE (index_type) != TYPE_CODE_VOID); + gdb_assert (TYPE_LENGTH (index_type) > 0); + if (result_type == NULL) result_type = alloc_type_copy (index_type); TYPE_CODE (result_type) = TYPE_CODE_RANGE; @@ -926,6 +933,11 @@ create_range_type (struct type *result_type, struct type *index_type, TYPE_ZALLOC (result_type, sizeof (struct range_bounds)); TYPE_RANGE_DATA (result_type)->low = *low_bound; TYPE_RANGE_DATA (result_type)->high = *high_bound; + TYPE_RANGE_DATA (result_type)->bias = bias; + + /* Initialize the stride to be a constant, the value will already be zero + thanks to the use of TYPE_ZALLOC above. */ + TYPE_RANGE_DATA (result_type)->stride.kind = PROP_CONST; if (low_bound->kind == PROP_CONST && low_bound->data.const_val >= 0) TYPE_UNSIGNED (result_type) = 1; @@ -940,6 +952,29 @@ create_range_type (struct type *result_type, struct type *index_type, return result_type; } +/* See gdbtypes.h. */ + +struct type * +create_range_type_with_stride (struct type *result_type, + struct type *index_type, + const struct dynamic_prop *low_bound, + const struct dynamic_prop *high_bound, + LONGEST bias, + const struct dynamic_prop *stride, + bool byte_stride_p) +{ + result_type = create_range_type (result_type, index_type, low_bound, + high_bound, bias); + + gdb_assert (stride != nullptr); + TYPE_RANGE_DATA (result_type)->stride = *stride; + TYPE_RANGE_DATA (result_type)->flag_is_byte_stride = byte_stride_p; + + return result_type; +} + + + /* Create a range type using either a blank type supplied in RESULT_TYPE, or creating a new type, inheriting the objfile from INDEX_TYPE. @@ -962,7 +997,7 @@ create_static_range_type (struct type *result_type, struct type *index_type, high.kind = PROP_CONST; high.data.const_val = high_bound; - result_type = create_range_type (result_type, index_type, &low, &high); + result_type = create_range_type (result_type, index_type, &low, &high, 0); return result_type; } @@ -970,11 +1005,14 @@ create_static_range_type (struct type *result_type, struct type *index_type, /* Predicate tests whether BOUNDS are static. Returns 1 if all bounds values are static, otherwise returns 0. */ -static int +static bool has_static_range (const struct range_bounds *bounds) { + /* If the range doesn't have a defined stride then its stride field will + be initialized to the constant 0. */ return (bounds->low.kind == PROP_CONST - && bounds->high.kind == PROP_CONST); + && bounds->high.kind == PROP_CONST + && bounds->stride.kind == PROP_CONST); } @@ -1181,6 +1219,15 @@ create_array_type_with_stride (struct type *result_type, && !type_not_allocated (result_type))) { LONGEST low_bound, high_bound; + unsigned int stride; + + /* If the array itself doesn't provide a stride value then take + whatever stride the range provides. Don't update BIT_STRIDE as + we don't want to place the stride value from the range into this + arrays bit size field. */ + stride = bit_stride; + if (stride == 0) + stride = TYPE_BIT_STRIDE (range_type); if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0) low_bound = high_bound = 0; @@ -1190,9 +1237,9 @@ create_array_type_with_stride (struct type *result_type, In such cases, the array length should be zero. */ if (high_bound < low_bound) TYPE_LENGTH (result_type) = 0; - else if (bit_stride > 0) + else if (stride > 0) TYPE_LENGTH (result_type) = - (bit_stride * (high_bound - low_bound + 1) + 7) / 8; + (stride * (high_bound - low_bound + 1) + 7) / 8; else TYPE_LENGTH (result_type) = TYPE_LENGTH (element_type) * (high_bound - low_bound + 1); @@ -1528,7 +1575,7 @@ lookup_unsigned_typename (const struct language_defn *language, strcpy (uns, "unsigned "); strcpy (uns + 9, name); - return lookup_typename (language, gdbarch, uns, (struct block *) NULL, 0); + return lookup_typename (language, gdbarch, uns, NULL, 0); } struct type * @@ -1540,11 +1587,11 @@ lookup_signed_typename (const struct language_defn *language, strcpy (uns, "signed "); strcpy (uns + 7, name); - t = lookup_typename (language, gdbarch, uns, (struct block *) NULL, 1); + t = lookup_typename (language, gdbarch, uns, NULL, 1); /* If we don't find "signed FOO" just try again with plain "FOO". */ if (t != NULL) return t; - return lookup_typename (language, gdbarch, name, (struct block *) NULL, 0); + return lookup_typename (language, gdbarch, name, NULL, 0); } /* Lookup a structure type named "struct NAME", @@ -1618,7 +1665,7 @@ lookup_enum (const char *name, const struct block *block) visible in lexical block BLOCK. */ struct type * -lookup_template_type (char *name, struct type *type, +lookup_template_type (const char *name, struct type *type, const struct block *block) { struct symbol *sym; @@ -1644,20 +1691,10 @@ lookup_template_type (char *name, struct type *type, return (SYMBOL_TYPE (sym)); } -/* Given a type TYPE, lookup the type of the component of type named - NAME. - - TYPE can be either a struct or union, or a pointer or reference to - a struct or union. If it is a pointer or reference, its target - type is automatically used. Thus '.' and '->' are interchangable, - as specified for the definitions of the expression element types - STRUCTOP_STRUCT and STRUCTOP_PTR. - - If NOERR is nonzero, return zero if NAME is not suitably defined. - If NAME is the name of a baseclass type, return that type. */ +/* See gdbtypes.h. */ -struct type * -lookup_struct_elt_type (struct type *type, const char *name, int noerr) +struct_elt +lookup_struct_elt (struct type *type, const char *name, int noerr) { int i; @@ -1678,59 +1715,53 @@ lookup_struct_elt_type (struct type *type, const char *name, int noerr) type_name.c_str ()); } -#if 0 - /* FIXME: This change put in by Michael seems incorrect for the case - where the structure tag name is the same as the member name. - I.e. when doing "ptype bell->bar" for "struct foo { int bar; int - foo; } bell;" Disabled by fnf. */ - { - char *type_name; - - type_name = TYPE_NAME (type); - if (type_name != NULL && strcmp (type_name, name) == 0) - return type; - } -#endif - for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--) { const char *t_field_name = TYPE_FIELD_NAME (type, i); if (t_field_name && (strcmp_iw (t_field_name, name) == 0)) { - return TYPE_FIELD_TYPE (type, i); + return {&TYPE_FIELD (type, i), TYPE_FIELD_BITPOS (type, i)}; } else if (!t_field_name || *t_field_name == '\0') { - struct type *subtype - = lookup_struct_elt_type (TYPE_FIELD_TYPE (type, i), name, 1); - - if (subtype != NULL) - return subtype; + struct_elt elt + = lookup_struct_elt (TYPE_FIELD_TYPE (type, i), name, 1); + if (elt.field != NULL) + { + elt.offset += TYPE_FIELD_BITPOS (type, i); + return elt; + } } } /* OK, it's not in this class. Recursively check the baseclasses. */ for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--) { - struct type *t; - - t = lookup_struct_elt_type (TYPE_BASECLASS (type, i), name, 1); - if (t != NULL) - { - return t; - } + struct_elt elt = lookup_struct_elt (TYPE_BASECLASS (type, i), name, 1); + if (elt.field != NULL) + return elt; } if (noerr) - { - return NULL; - } + return {nullptr, 0}; std::string type_name = type_to_string (type); error (_("Type %s has no component named %s."), type_name.c_str (), name); } +/* See gdbtypes.h. */ + +struct type * +lookup_struct_elt_type (struct type *type, const char *name, int noerr) +{ + struct_elt elt = lookup_struct_elt (type, name, noerr); + if (elt.field != NULL) + return FIELD_TYPE (*elt.field); + else + return NULL; +} + /* Store in *MAX the largest number representable by unsigned integer type TYPE. */ @@ -1990,7 +2021,7 @@ resolve_dynamic_range (struct type *dyn_range_type, CORE_ADDR value; struct type *static_range_type, *static_target_type; const struct dynamic_prop *prop; - struct dynamic_prop low_bound, high_bound; + struct dynamic_prop low_bound, high_bound, stride; gdb_assert (TYPE_CODE (dyn_range_type) == TYPE_CODE_RANGE); @@ -2022,12 +2053,37 @@ resolve_dynamic_range (struct type *dyn_range_type, high_bound.data.const_val = 0; } + bool byte_stride_p = TYPE_RANGE_DATA (dyn_range_type)->flag_is_byte_stride; + prop = &TYPE_RANGE_DATA (dyn_range_type)->stride; + if (dwarf2_evaluate_property (prop, NULL, addr_stack, &value)) + { + stride.kind = PROP_CONST; + stride.data.const_val = value; + + /* If we have a bit stride that is not an exact number of bytes then + I really don't think this is going to work with current GDB, the + array indexing code in GDB seems to be pretty heavily tied to byte + offsets right now. Assuming 8 bits in a byte. */ + struct gdbarch *gdbarch = get_type_arch (dyn_range_type); + int unit_size = gdbarch_addressable_memory_unit_size (gdbarch); + if (!byte_stride_p && (value % (unit_size * 8)) != 0) + error (_("bit strides that are not a multiple of the byte size " + "are currently not supported")); + } + else + { + stride.kind = PROP_UNDEFINED; + stride.data.const_val = 0; + byte_stride_p = true; + } + static_target_type = resolve_dynamic_type_internal (TYPE_TARGET_TYPE (dyn_range_type), addr_stack, 0); - static_range_type = create_range_type (copy_type (dyn_range_type), - static_target_type, - &low_bound, &high_bound); + LONGEST bias = TYPE_RANGE_DATA (dyn_range_type)->bias; + static_range_type = create_range_type_with_stride + (copy_type (dyn_range_type), static_target_type, + &low_bound, &high_bound, bias, &stride, byte_stride_p); TYPE_RANGE_DATA (static_range_type)->flag_bound_evaluated = 1; return static_range_type; } @@ -2080,10 +2136,7 @@ resolve_dynamic_array (struct type *type, prop = get_dyn_prop (DYN_PROP_BYTE_STRIDE, type); if (prop != NULL) { - int prop_eval_ok - = dwarf2_evaluate_property (prop, NULL, addr_stack, &value); - - if (prop_eval_ok) + if (dwarf2_evaluate_property (prop, NULL, addr_stack, &value)) { remove_dyn_prop (DYN_PROP_BYTE_STRIDE, type); bit_stride = (unsigned int) (value * 8); @@ -2587,15 +2640,14 @@ safe_parse_type (struct gdbarch *gdbarch, char *p, int length) gdb_stderr = &null_stream; /* Call parse_and_eval_type() without fear of longjmp()s. */ - TRY + try { type = parse_and_eval_type (p, length); } - CATCH (except, RETURN_MASK_ERROR) + catch (const gdb_exception_error &except) { type = builtin_type (gdbarch)->builtin_void; } - END_CATCH /* Stop suppressing error messages. */ gdb_stderr = saved_gdb_stderr; @@ -2736,41 +2788,15 @@ check_stub_method_group (struct type *type, int method_id) { int len = TYPE_FN_FIELDLIST_LENGTH (type, method_id); struct fn_field *f = TYPE_FN_FIELDLIST1 (type, method_id); - int j, found_stub = 0; - - for (j = 0; j < len; j++) - if (TYPE_FN_FIELD_STUB (f, j)) - { - found_stub = 1; - check_stub_method (type, method_id, j); - } - - /* GNU v3 methods with incorrect names were corrected when we read - in type information, because it was cheaper to do it then. The - only GNU v2 methods with incorrect method names are operators and - destructors; destructors were also corrected when we read in type - information. - Therefore the only thing we need to handle here are v2 operator - names. */ - if (found_stub && !startswith (TYPE_FN_FIELD_PHYSNAME (f, 0), "_Z")) + for (int j = 0; j < len; j++) { - int ret; - char dem_opname[256]; - - ret = cplus_demangle_opname (TYPE_FN_FIELDLIST_NAME (type, - method_id), - dem_opname, DMGL_ANSI); - if (!ret) - ret = cplus_demangle_opname (TYPE_FN_FIELDLIST_NAME (type, - method_id), - dem_opname, 0); - if (ret) - TYPE_FN_FIELDLIST_NAME (type, method_id) = xstrdup (dem_opname); + if (TYPE_FN_FIELD_STUB (f, j)) + check_stub_method (type, method_id, j); } } -/* Ensure it is in .rodata (if available) by workarounding GCC PR 44690. */ +/* Ensure it is in .rodata (if available) by working around GCC PR 44690. */ const struct cplus_struct_type cplus_struct_default = { }; void @@ -3018,17 +3044,24 @@ type_raw_align (struct type *type) unsigned type_align (struct type *type) { + /* Check alignment provided in the debug information. */ unsigned raw_align = type_raw_align (type); if (raw_align != 0) return raw_align; - ULONGEST align = 0; + /* Allow the architecture to provide an alignment. */ + struct gdbarch *arch = get_type_arch (type); + ULONGEST align = gdbarch_type_align (arch, type); + if (align != 0) + return align; + switch (TYPE_CODE (type)) { case TYPE_CODE_PTR: case TYPE_CODE_FUNC: case TYPE_CODE_FLAGS: case TYPE_CODE_INT: + case TYPE_CODE_RANGE: case TYPE_CODE_FLT: case TYPE_CODE_ENUM: case TYPE_CODE_REF: @@ -3036,10 +3069,9 @@ type_align (struct type *type) case TYPE_CODE_CHAR: case TYPE_CODE_BOOL: case TYPE_CODE_DECFLOAT: - { - struct gdbarch *arch = get_type_arch (type); - align = gdbarch_type_align (arch, type); - } + case TYPE_CODE_METHODPTR: + case TYPE_CODE_MEMBERPTR: + align = type_length_units (check_typedef (type)); break; case TYPE_CODE_ARRAY: @@ -3051,39 +3083,36 @@ type_align (struct type *type) case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: { - if (TYPE_NFIELDS (type) == 0) - { - /* An empty struct has alignment 1. */ - align = 1; - break; - } + int number_of_non_static_fields = 0; for (unsigned i = 0; i < TYPE_NFIELDS (type); ++i) { - ULONGEST f_align = type_align (TYPE_FIELD_TYPE (type, i)); - if (f_align == 0) + if (!field_is_static (&TYPE_FIELD (type, i))) { - /* Don't pretend we know something we don't. */ - align = 0; - break; + number_of_non_static_fields++; + ULONGEST f_align = type_align (TYPE_FIELD_TYPE (type, i)); + if (f_align == 0) + { + /* Don't pretend we know something we don't. */ + align = 0; + break; + } + if (f_align > align) + align = f_align; } - if (f_align > align) - align = f_align; } + /* A struct with no fields, or with only static fields has an + alignment of 1. */ + if (number_of_non_static_fields == 0) + align = 1; } break; case TYPE_CODE_SET: - case TYPE_CODE_RANGE: case TYPE_CODE_STRING: /* Not sure what to do here, and these can't appear in C or C++ anyway. */ break; - case TYPE_CODE_METHODPTR: - case TYPE_CODE_MEMBERPTR: - align = type_length_units (type); - break; - case TYPE_CODE_VOID: align = 1; break; @@ -3426,21 +3455,21 @@ compare_ranks (struct rank a, struct rank b) 3 => A is worse than B */ int -compare_badness (struct badness_vector *a, struct badness_vector *b) +compare_badness (const badness_vector &a, const badness_vector &b) { int i; int tmp; short found_pos = 0; /* any positives in c? */ short found_neg = 0; /* any negatives in c? */ - /* differing lengths => incomparable */ - if (a->length != b->length) + /* differing sizes => incomparable */ + if (a.size () != b.size ()) return 1; /* Subtract b from a */ - for (i = 0; i < a->length; i++) + for (i = 0; i < a.size (); i++) { - tmp = compare_ranks (b->rank[i], a->rank[i]); + tmp = compare_ranks (b[i], a[i]); if (tmp > 0) found_pos = 1; else if (tmp < 0) @@ -3465,19 +3494,16 @@ compare_badness (struct badness_vector *a, struct badness_vector *b) } /* Rank a function by comparing its parameter types (PARMS), to the - types of an argument list (ARGS). Return a pointer to a badness - vector. This has ARGS.size() + 1 entries. */ + types of an argument list (ARGS). Return the badness vector. This + has ARGS.size() + 1 entries. */ -struct badness_vector * +badness_vector rank_function (gdb::array_view parms, gdb::array_view args) { - int i; - struct badness_vector *bv = XNEW (struct badness_vector); - size_t min_len = std::min (parms.size (), args.size ()); - - bv->length = args.size () + 1; /* add 1 for the length-match rank. */ - bv->rank = XNEWVEC (struct rank, args.size () + 1); + /* add 1 for the length-match rank. */ + badness_vector bv; + bv.reserve (1 + args.size ()); /* First compare the lengths of the supplied lists. If there is a mismatch, set it to a high value. */ @@ -3486,18 +3512,20 @@ rank_function (gdb::array_view parms, arguments and ellipsis parameter lists, we should consider those and rank the length-match more finely. */ - LENGTH_MATCH (bv) = (args.size () != parms.size ()) - ? LENGTH_MISMATCH_BADNESS - : EXACT_MATCH_BADNESS; + bv.push_back ((args.size () != parms.size ()) + ? LENGTH_MISMATCH_BADNESS + : EXACT_MATCH_BADNESS); /* Now rank all the parameters of the candidate function. */ - for (i = 1; i <= min_len; i++) - bv->rank[i] = rank_one_type (parms[i - 1], value_type (args[i - 1]), - args[i - 1]); + size_t min_len = std::min (parms.size (), args.size ()); + + for (size_t i = 0; i < min_len; i++) + bv.push_back (rank_one_type (parms[i], value_type (args[i]), + args[i])); /* If more arguments than parameters, add dummy entries. */ - for (i = min_len + 1; i <= args.size (); i++) - bv->rank[i] = TOO_FEW_PARAMS_BADNESS; + for (size_t i = min_len; i < args.size (); i++) + bv.push_back (TOO_FEW_PARAMS_BADNESS); return bv; } @@ -3651,6 +3679,7 @@ check_types_equal (struct type *type1, struct type *type2, || TYPE_LENGTH (type1) != TYPE_LENGTH (type2) || TYPE_UNSIGNED (type1) != TYPE_UNSIGNED (type2) || TYPE_NOSIGN (type1) != TYPE_NOSIGN (type2) + || TYPE_ENDIANITY_NOT_DEFAULT (type1) != TYPE_ENDIANITY_NOT_DEFAULT (type2) || TYPE_VARARGS (type1) != TYPE_VARARGS (type2) || TYPE_VECTOR (type1) != TYPE_VECTOR (type2) || TYPE_NOTTEXT (type1) != TYPE_NOTTEXT (type2) @@ -3756,7 +3785,7 @@ check_types_worklist (std::vector *worklist, /* If the type pair has already been visited, we know it is ok. */ - bcache_full (&entry, sizeof (entry), cache, &added); + cache->insert (&entry, sizeof (entry), &added); if (!added) continue; @@ -3773,9 +3802,6 @@ check_types_worklist (std::vector *worklist, bool types_deeply_equal (struct type *type1, struct type *type2) { - struct gdb_exception except = exception_none; - bool result = false; - struct bcache *cache; std::vector worklist; gdb_assert (type1 != NULL && type2 != NULL); @@ -3784,31 +3810,9 @@ types_deeply_equal (struct type *type1, struct type *type2) if (type1 == type2) return true; - cache = bcache_xmalloc (NULL, NULL); - + struct bcache cache (nullptr, nullptr); worklist.emplace_back (type1, type2); - - /* check_types_worklist calls several nested helper functions, some - of which can raise a GDB exception, so we just check and rethrow - here. If there is a GDB exception, a comparison is not capable - (or trusted), so exit. */ - TRY - { - result = check_types_worklist (&worklist, cache); - } - CATCH (ex, RETURN_MASK_ALL) - { - except = ex; - } - END_CATCH - - bcache_xfree (cache); - - /* Rethrow if there was a problem. */ - if (except.reason < 0) - throw_exception (except); - - return result; + return check_types_worklist (&worklist, &cache); } /* Allocated status of type TYPE. Return zero if type TYPE is allocated. @@ -3834,7 +3838,394 @@ type_not_associated (const struct type *type) return (prop && TYPE_DYN_PROP_KIND (prop) == PROP_CONST && !TYPE_DYN_PROP_ADDR (prop)); } - + +/* rank_one_type helper for when PARM's type code is TYPE_CODE_PTR. */ + +static struct rank +rank_one_type_parm_ptr (struct type *parm, struct type *arg, struct value *value) +{ + struct rank rank = {0,0}; + + switch (TYPE_CODE (arg)) + { + case TYPE_CODE_PTR: + + /* Allowed pointer conversions are: + (a) pointer to void-pointer conversion. */ + if (TYPE_CODE (TYPE_TARGET_TYPE (parm)) == TYPE_CODE_VOID) + return VOID_PTR_CONVERSION_BADNESS; + + /* (b) pointer to ancestor-pointer conversion. */ + rank.subrank = distance_to_ancestor (TYPE_TARGET_TYPE (parm), + TYPE_TARGET_TYPE (arg), + 0); + if (rank.subrank >= 0) + return sum_ranks (BASE_PTR_CONVERSION_BADNESS, rank); + + return INCOMPATIBLE_TYPE_BADNESS; + case TYPE_CODE_ARRAY: + { + struct type *t1 = TYPE_TARGET_TYPE (parm); + struct type *t2 = TYPE_TARGET_TYPE (arg); + + if (types_equal (t1, t2)) + { + /* Make sure they are CV equal. */ + if (TYPE_CONST (t1) != TYPE_CONST (t2)) + rank.subrank |= CV_CONVERSION_CONST; + if (TYPE_VOLATILE (t1) != TYPE_VOLATILE (t2)) + rank.subrank |= CV_CONVERSION_VOLATILE; + if (rank.subrank != 0) + return sum_ranks (CV_CONVERSION_BADNESS, rank); + return EXACT_MATCH_BADNESS; + } + return INCOMPATIBLE_TYPE_BADNESS; + } + case TYPE_CODE_FUNC: + return rank_one_type (TYPE_TARGET_TYPE (parm), arg, NULL); + case TYPE_CODE_INT: + if (value != NULL && TYPE_CODE (value_type (value)) == TYPE_CODE_INT) + { + if (value_as_long (value) == 0) + { + /* Null pointer conversion: allow it to be cast to a pointer. + [4.10.1 of C++ standard draft n3290] */ + return NULL_POINTER_CONVERSION_BADNESS; + } + else + { + /* If type checking is disabled, allow the conversion. */ + if (!strict_type_checking) + return NS_INTEGER_POINTER_CONVERSION_BADNESS; + } + } + /* fall through */ + case TYPE_CODE_ENUM: + case TYPE_CODE_FLAGS: + case TYPE_CODE_CHAR: + case TYPE_CODE_RANGE: + case TYPE_CODE_BOOL: + default: + return INCOMPATIBLE_TYPE_BADNESS; + } +} + +/* rank_one_type helper for when PARM's type code is TYPE_CODE_ARRAY. */ + +static struct rank +rank_one_type_parm_array (struct type *parm, struct type *arg, struct value *value) +{ + switch (TYPE_CODE (arg)) + { + case TYPE_CODE_PTR: + case TYPE_CODE_ARRAY: + return rank_one_type (TYPE_TARGET_TYPE (parm), + TYPE_TARGET_TYPE (arg), NULL); + default: + return INCOMPATIBLE_TYPE_BADNESS; + } +} + +/* rank_one_type helper for when PARM's type code is TYPE_CODE_FUNC. */ + +static struct rank +rank_one_type_parm_func (struct type *parm, struct type *arg, struct value *value) +{ + switch (TYPE_CODE (arg)) + { + case TYPE_CODE_PTR: /* funcptr -> func */ + return rank_one_type (parm, TYPE_TARGET_TYPE (arg), NULL); + default: + return INCOMPATIBLE_TYPE_BADNESS; + } +} + +/* rank_one_type helper for when PARM's type code is TYPE_CODE_INT. */ + +static struct rank +rank_one_type_parm_int (struct type *parm, struct type *arg, struct value *value) +{ + switch (TYPE_CODE (arg)) + { + case TYPE_CODE_INT: + if (TYPE_LENGTH (arg) == TYPE_LENGTH (parm)) + { + /* Deal with signed, unsigned, and plain chars and + signed and unsigned ints. */ + if (TYPE_NOSIGN (parm)) + { + /* This case only for character types. */ + if (TYPE_NOSIGN (arg)) + return EXACT_MATCH_BADNESS; /* plain char -> plain char */ + else /* signed/unsigned char -> plain char */ + return INTEGER_CONVERSION_BADNESS; + } + else if (TYPE_UNSIGNED (parm)) + { + if (TYPE_UNSIGNED (arg)) + { + /* unsigned int -> unsigned int, or + unsigned long -> unsigned long */ + if (integer_types_same_name_p (TYPE_NAME (parm), + TYPE_NAME (arg))) + return EXACT_MATCH_BADNESS; + else if (integer_types_same_name_p (TYPE_NAME (arg), + "int") + && integer_types_same_name_p (TYPE_NAME (parm), + "long")) + /* unsigned int -> unsigned long */ + return INTEGER_PROMOTION_BADNESS; + else + /* unsigned long -> unsigned int */ + return INTEGER_CONVERSION_BADNESS; + } + else + { + if (integer_types_same_name_p (TYPE_NAME (arg), + "long") + && integer_types_same_name_p (TYPE_NAME (parm), + "int")) + /* signed long -> unsigned int */ + return INTEGER_CONVERSION_BADNESS; + else + /* signed int/long -> unsigned int/long */ + return INTEGER_CONVERSION_BADNESS; + } + } + else if (!TYPE_NOSIGN (arg) && !TYPE_UNSIGNED (arg)) + { + if (integer_types_same_name_p (TYPE_NAME (parm), + TYPE_NAME (arg))) + return EXACT_MATCH_BADNESS; + else if (integer_types_same_name_p (TYPE_NAME (arg), + "int") + && integer_types_same_name_p (TYPE_NAME (parm), + "long")) + return INTEGER_PROMOTION_BADNESS; + else + return INTEGER_CONVERSION_BADNESS; + } + else + return INTEGER_CONVERSION_BADNESS; + } + else if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm)) + return INTEGER_PROMOTION_BADNESS; + else + return INTEGER_CONVERSION_BADNESS; + case TYPE_CODE_ENUM: + case TYPE_CODE_FLAGS: + case TYPE_CODE_CHAR: + case TYPE_CODE_RANGE: + case TYPE_CODE_BOOL: + if (TYPE_DECLARED_CLASS (arg)) + return INCOMPATIBLE_TYPE_BADNESS; + return INTEGER_PROMOTION_BADNESS; + case TYPE_CODE_FLT: + return INT_FLOAT_CONVERSION_BADNESS; + case TYPE_CODE_PTR: + return NS_POINTER_CONVERSION_BADNESS; + default: + return INCOMPATIBLE_TYPE_BADNESS; + } +} + +/* rank_one_type helper for when PARM's type code is TYPE_CODE_ENUM. */ + +static struct rank +rank_one_type_parm_enum (struct type *parm, struct type *arg, struct value *value) +{ + switch (TYPE_CODE (arg)) + { + case TYPE_CODE_INT: + case TYPE_CODE_CHAR: + case TYPE_CODE_RANGE: + case TYPE_CODE_BOOL: + case TYPE_CODE_ENUM: + if (TYPE_DECLARED_CLASS (parm) || TYPE_DECLARED_CLASS (arg)) + return INCOMPATIBLE_TYPE_BADNESS; + return INTEGER_CONVERSION_BADNESS; + case TYPE_CODE_FLT: + return INT_FLOAT_CONVERSION_BADNESS; + default: + return INCOMPATIBLE_TYPE_BADNESS; + } +} + +/* rank_one_type helper for when PARM's type code is TYPE_CODE_CHAR. */ + +static struct rank +rank_one_type_parm_char (struct type *parm, struct type *arg, struct value *value) +{ + switch (TYPE_CODE (arg)) + { + case TYPE_CODE_RANGE: + case TYPE_CODE_BOOL: + case TYPE_CODE_ENUM: + if (TYPE_DECLARED_CLASS (arg)) + return INCOMPATIBLE_TYPE_BADNESS; + return INTEGER_CONVERSION_BADNESS; + case TYPE_CODE_FLT: + return INT_FLOAT_CONVERSION_BADNESS; + case TYPE_CODE_INT: + if (TYPE_LENGTH (arg) > TYPE_LENGTH (parm)) + return INTEGER_CONVERSION_BADNESS; + else if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm)) + return INTEGER_PROMOTION_BADNESS; + /* fall through */ + case TYPE_CODE_CHAR: + /* Deal with signed, unsigned, and plain chars for C++ and + with int cases falling through from previous case. */ + if (TYPE_NOSIGN (parm)) + { + if (TYPE_NOSIGN (arg)) + return EXACT_MATCH_BADNESS; + else + return INTEGER_CONVERSION_BADNESS; + } + else if (TYPE_UNSIGNED (parm)) + { + if (TYPE_UNSIGNED (arg)) + return EXACT_MATCH_BADNESS; + else + return INTEGER_PROMOTION_BADNESS; + } + else if (!TYPE_NOSIGN (arg) && !TYPE_UNSIGNED (arg)) + return EXACT_MATCH_BADNESS; + else + return INTEGER_CONVERSION_BADNESS; + default: + return INCOMPATIBLE_TYPE_BADNESS; + } +} + +/* rank_one_type helper for when PARM's type code is TYPE_CODE_RANGE. */ + +static struct rank +rank_one_type_parm_range (struct type *parm, struct type *arg, struct value *value) +{ + switch (TYPE_CODE (arg)) + { + case TYPE_CODE_INT: + case TYPE_CODE_CHAR: + case TYPE_CODE_RANGE: + case TYPE_CODE_BOOL: + case TYPE_CODE_ENUM: + return INTEGER_CONVERSION_BADNESS; + case TYPE_CODE_FLT: + return INT_FLOAT_CONVERSION_BADNESS; + default: + return INCOMPATIBLE_TYPE_BADNESS; + } +} + +/* rank_one_type helper for when PARM's type code is TYPE_CODE_BOOL. */ + +static struct rank +rank_one_type_parm_bool (struct type *parm, struct type *arg, struct value *value) +{ + switch (TYPE_CODE (arg)) + { + /* n3290 draft, section 4.12.1 (conv.bool): + + "A prvalue of arithmetic, unscoped enumeration, pointer, or + pointer to member type can be converted to a prvalue of type + bool. A zero value, null pointer value, or null member pointer + value is converted to false; any other value is converted to + true. A prvalue of type std::nullptr_t can be converted to a + prvalue of type bool; the resulting value is false." */ + case TYPE_CODE_INT: + case TYPE_CODE_CHAR: + case TYPE_CODE_ENUM: + case TYPE_CODE_FLT: + case TYPE_CODE_MEMBERPTR: + case TYPE_CODE_PTR: + return BOOL_CONVERSION_BADNESS; + case TYPE_CODE_RANGE: + return INCOMPATIBLE_TYPE_BADNESS; + case TYPE_CODE_BOOL: + return EXACT_MATCH_BADNESS; + default: + return INCOMPATIBLE_TYPE_BADNESS; + } +} + +/* rank_one_type helper for when PARM's type code is TYPE_CODE_FLOAT. */ + +static struct rank +rank_one_type_parm_float (struct type *parm, struct type *arg, struct value *value) +{ + switch (TYPE_CODE (arg)) + { + case TYPE_CODE_FLT: + if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm)) + return FLOAT_PROMOTION_BADNESS; + else if (TYPE_LENGTH (arg) == TYPE_LENGTH (parm)) + return EXACT_MATCH_BADNESS; + else + return FLOAT_CONVERSION_BADNESS; + case TYPE_CODE_INT: + case TYPE_CODE_BOOL: + case TYPE_CODE_ENUM: + case TYPE_CODE_RANGE: + case TYPE_CODE_CHAR: + return INT_FLOAT_CONVERSION_BADNESS; + default: + return INCOMPATIBLE_TYPE_BADNESS; + } +} + +/* rank_one_type helper for when PARM's type code is TYPE_CODE_COMPLEX. */ + +static struct rank +rank_one_type_parm_complex (struct type *parm, struct type *arg, struct value *value) +{ + switch (TYPE_CODE (arg)) + { /* Strictly not needed for C++, but... */ + case TYPE_CODE_FLT: + return FLOAT_PROMOTION_BADNESS; + case TYPE_CODE_COMPLEX: + return EXACT_MATCH_BADNESS; + default: + return INCOMPATIBLE_TYPE_BADNESS; + } +} + +/* rank_one_type helper for when PARM's type code is TYPE_CODE_STRUCT. */ + +static struct rank +rank_one_type_parm_struct (struct type *parm, struct type *arg, struct value *value) +{ + struct rank rank = {0, 0}; + + switch (TYPE_CODE (arg)) + { + case TYPE_CODE_STRUCT: + /* Check for derivation */ + rank.subrank = distance_to_ancestor (parm, arg, 0); + if (rank.subrank >= 0) + return sum_ranks (BASE_CONVERSION_BADNESS, rank); + /* fall through */ + default: + return INCOMPATIBLE_TYPE_BADNESS; + } +} + +/* rank_one_type helper for when PARM's type code is TYPE_CODE_SET. */ + +static struct rank +rank_one_type_parm_set (struct type *parm, struct type *arg, struct value *value) +{ + switch (TYPE_CODE (arg)) + { + /* Not in C++ */ + case TYPE_CODE_SET: + return rank_one_type (TYPE_FIELD_TYPE (parm, 0), + TYPE_FIELD_TYPE (arg, 0), NULL); + default: + return INCOMPATIBLE_TYPE_BADNESS; + } +} + /* Compare one type (PARM) for compatibility with another (ARG). * PARM is intended to be the parameter type of a function; and * ARG is the supplied argument's type. This function tests if @@ -3925,358 +4316,29 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value) switch (TYPE_CODE (parm)) { case TYPE_CODE_PTR: - switch (TYPE_CODE (arg)) - { - case TYPE_CODE_PTR: - - /* Allowed pointer conversions are: - (a) pointer to void-pointer conversion. */ - if (TYPE_CODE (TYPE_TARGET_TYPE (parm)) == TYPE_CODE_VOID) - return VOID_PTR_CONVERSION_BADNESS; - - /* (b) pointer to ancestor-pointer conversion. */ - rank.subrank = distance_to_ancestor (TYPE_TARGET_TYPE (parm), - TYPE_TARGET_TYPE (arg), - 0); - if (rank.subrank >= 0) - return sum_ranks (BASE_PTR_CONVERSION_BADNESS, rank); - - return INCOMPATIBLE_TYPE_BADNESS; - case TYPE_CODE_ARRAY: - { - struct type *t1 = TYPE_TARGET_TYPE (parm); - struct type *t2 = TYPE_TARGET_TYPE (arg); - - if (types_equal (t1, t2)) - { - /* Make sure they are CV equal. */ - if (TYPE_CONST (t1) != TYPE_CONST (t2)) - rank.subrank |= CV_CONVERSION_CONST; - if (TYPE_VOLATILE (t1) != TYPE_VOLATILE (t2)) - rank.subrank |= CV_CONVERSION_VOLATILE; - if (rank.subrank != 0) - return sum_ranks (CV_CONVERSION_BADNESS, rank); - return EXACT_MATCH_BADNESS; - } - return INCOMPATIBLE_TYPE_BADNESS; - } - case TYPE_CODE_FUNC: - return rank_one_type (TYPE_TARGET_TYPE (parm), arg, NULL); - case TYPE_CODE_INT: - if (value != NULL && TYPE_CODE (value_type (value)) == TYPE_CODE_INT) - { - if (value_as_long (value) == 0) - { - /* Null pointer conversion: allow it to be cast to a pointer. - [4.10.1 of C++ standard draft n3290] */ - return NULL_POINTER_CONVERSION_BADNESS; - } - else - { - /* If type checking is disabled, allow the conversion. */ - if (!strict_type_checking) - return NS_INTEGER_POINTER_CONVERSION_BADNESS; - } - } - /* fall through */ - case TYPE_CODE_ENUM: - case TYPE_CODE_FLAGS: - case TYPE_CODE_CHAR: - case TYPE_CODE_RANGE: - case TYPE_CODE_BOOL: - default: - return INCOMPATIBLE_TYPE_BADNESS; - } + return rank_one_type_parm_ptr (parm, arg, value); case TYPE_CODE_ARRAY: - switch (TYPE_CODE (arg)) - { - case TYPE_CODE_PTR: - case TYPE_CODE_ARRAY: - return rank_one_type (TYPE_TARGET_TYPE (parm), - TYPE_TARGET_TYPE (arg), NULL); - default: - return INCOMPATIBLE_TYPE_BADNESS; - } + return rank_one_type_parm_array (parm, arg, value); case TYPE_CODE_FUNC: - switch (TYPE_CODE (arg)) - { - case TYPE_CODE_PTR: /* funcptr -> func */ - return rank_one_type (parm, TYPE_TARGET_TYPE (arg), NULL); - default: - return INCOMPATIBLE_TYPE_BADNESS; - } + return rank_one_type_parm_func (parm, arg, value); case TYPE_CODE_INT: - switch (TYPE_CODE (arg)) - { - case TYPE_CODE_INT: - if (TYPE_LENGTH (arg) == TYPE_LENGTH (parm)) - { - /* Deal with signed, unsigned, and plain chars and - signed and unsigned ints. */ - if (TYPE_NOSIGN (parm)) - { - /* This case only for character types. */ - if (TYPE_NOSIGN (arg)) - return EXACT_MATCH_BADNESS; /* plain char -> plain char */ - else /* signed/unsigned char -> plain char */ - return INTEGER_CONVERSION_BADNESS; - } - else if (TYPE_UNSIGNED (parm)) - { - if (TYPE_UNSIGNED (arg)) - { - /* unsigned int -> unsigned int, or - unsigned long -> unsigned long */ - if (integer_types_same_name_p (TYPE_NAME (parm), - TYPE_NAME (arg))) - return EXACT_MATCH_BADNESS; - else if (integer_types_same_name_p (TYPE_NAME (arg), - "int") - && integer_types_same_name_p (TYPE_NAME (parm), - "long")) - /* unsigned int -> unsigned long */ - return INTEGER_PROMOTION_BADNESS; - else - /* unsigned long -> unsigned int */ - return INTEGER_CONVERSION_BADNESS; - } - else - { - if (integer_types_same_name_p (TYPE_NAME (arg), - "long") - && integer_types_same_name_p (TYPE_NAME (parm), - "int")) - /* signed long -> unsigned int */ - return INTEGER_CONVERSION_BADNESS; - else - /* signed int/long -> unsigned int/long */ - return INTEGER_CONVERSION_BADNESS; - } - } - else if (!TYPE_NOSIGN (arg) && !TYPE_UNSIGNED (arg)) - { - if (integer_types_same_name_p (TYPE_NAME (parm), - TYPE_NAME (arg))) - return EXACT_MATCH_BADNESS; - else if (integer_types_same_name_p (TYPE_NAME (arg), - "int") - && integer_types_same_name_p (TYPE_NAME (parm), - "long")) - return INTEGER_PROMOTION_BADNESS; - else - return INTEGER_CONVERSION_BADNESS; - } - else - return INTEGER_CONVERSION_BADNESS; - } - else if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm)) - return INTEGER_PROMOTION_BADNESS; - else - return INTEGER_CONVERSION_BADNESS; - case TYPE_CODE_ENUM: - case TYPE_CODE_FLAGS: - case TYPE_CODE_CHAR: - case TYPE_CODE_RANGE: - case TYPE_CODE_BOOL: - if (TYPE_DECLARED_CLASS (arg)) - return INCOMPATIBLE_TYPE_BADNESS; - return INTEGER_PROMOTION_BADNESS; - case TYPE_CODE_FLT: - return INT_FLOAT_CONVERSION_BADNESS; - case TYPE_CODE_PTR: - return NS_POINTER_CONVERSION_BADNESS; - default: - return INCOMPATIBLE_TYPE_BADNESS; - } - break; + return rank_one_type_parm_int (parm, arg, value); case TYPE_CODE_ENUM: - switch (TYPE_CODE (arg)) - { - case TYPE_CODE_INT: - case TYPE_CODE_CHAR: - case TYPE_CODE_RANGE: - case TYPE_CODE_BOOL: - case TYPE_CODE_ENUM: - if (TYPE_DECLARED_CLASS (parm) || TYPE_DECLARED_CLASS (arg)) - return INCOMPATIBLE_TYPE_BADNESS; - return INTEGER_CONVERSION_BADNESS; - case TYPE_CODE_FLT: - return INT_FLOAT_CONVERSION_BADNESS; - default: - return INCOMPATIBLE_TYPE_BADNESS; - } - break; + return rank_one_type_parm_enum (parm, arg, value); case TYPE_CODE_CHAR: - switch (TYPE_CODE (arg)) - { - case TYPE_CODE_RANGE: - case TYPE_CODE_BOOL: - case TYPE_CODE_ENUM: - if (TYPE_DECLARED_CLASS (arg)) - return INCOMPATIBLE_TYPE_BADNESS; - return INTEGER_CONVERSION_BADNESS; - case TYPE_CODE_FLT: - return INT_FLOAT_CONVERSION_BADNESS; - case TYPE_CODE_INT: - if (TYPE_LENGTH (arg) > TYPE_LENGTH (parm)) - return INTEGER_CONVERSION_BADNESS; - else if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm)) - return INTEGER_PROMOTION_BADNESS; - /* fall through */ - case TYPE_CODE_CHAR: - /* Deal with signed, unsigned, and plain chars for C++ and - with int cases falling through from previous case. */ - if (TYPE_NOSIGN (parm)) - { - if (TYPE_NOSIGN (arg)) - return EXACT_MATCH_BADNESS; - else - return INTEGER_CONVERSION_BADNESS; - } - else if (TYPE_UNSIGNED (parm)) - { - if (TYPE_UNSIGNED (arg)) - return EXACT_MATCH_BADNESS; - else - return INTEGER_PROMOTION_BADNESS; - } - else if (!TYPE_NOSIGN (arg) && !TYPE_UNSIGNED (arg)) - return EXACT_MATCH_BADNESS; - else - return INTEGER_CONVERSION_BADNESS; - default: - return INCOMPATIBLE_TYPE_BADNESS; - } - break; + return rank_one_type_parm_char (parm, arg, value); case TYPE_CODE_RANGE: - switch (TYPE_CODE (arg)) - { - case TYPE_CODE_INT: - case TYPE_CODE_CHAR: - case TYPE_CODE_RANGE: - case TYPE_CODE_BOOL: - case TYPE_CODE_ENUM: - return INTEGER_CONVERSION_BADNESS; - case TYPE_CODE_FLT: - return INT_FLOAT_CONVERSION_BADNESS; - default: - return INCOMPATIBLE_TYPE_BADNESS; - } - break; + return rank_one_type_parm_range (parm, arg, value); case TYPE_CODE_BOOL: - switch (TYPE_CODE (arg)) - { - /* n3290 draft, section 4.12.1 (conv.bool): - - "A prvalue of arithmetic, unscoped enumeration, pointer, or - pointer to member type can be converted to a prvalue of type - bool. A zero value, null pointer value, or null member pointer - value is converted to false; any other value is converted to - true. A prvalue of type std::nullptr_t can be converted to a - prvalue of type bool; the resulting value is false." */ - case TYPE_CODE_INT: - case TYPE_CODE_CHAR: - case TYPE_CODE_ENUM: - case TYPE_CODE_FLT: - case TYPE_CODE_MEMBERPTR: - case TYPE_CODE_PTR: - return BOOL_CONVERSION_BADNESS; - case TYPE_CODE_RANGE: - return INCOMPATIBLE_TYPE_BADNESS; - case TYPE_CODE_BOOL: - return EXACT_MATCH_BADNESS; - default: - return INCOMPATIBLE_TYPE_BADNESS; - } - break; + return rank_one_type_parm_bool (parm, arg, value); case TYPE_CODE_FLT: - switch (TYPE_CODE (arg)) - { - case TYPE_CODE_FLT: - if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm)) - return FLOAT_PROMOTION_BADNESS; - else if (TYPE_LENGTH (arg) == TYPE_LENGTH (parm)) - return EXACT_MATCH_BADNESS; - else - return FLOAT_CONVERSION_BADNESS; - case TYPE_CODE_INT: - case TYPE_CODE_BOOL: - case TYPE_CODE_ENUM: - case TYPE_CODE_RANGE: - case TYPE_CODE_CHAR: - return INT_FLOAT_CONVERSION_BADNESS; - default: - return INCOMPATIBLE_TYPE_BADNESS; - } - break; + return rank_one_type_parm_float (parm, arg, value); case TYPE_CODE_COMPLEX: - switch (TYPE_CODE (arg)) - { /* Strictly not needed for C++, but... */ - case TYPE_CODE_FLT: - return FLOAT_PROMOTION_BADNESS; - case TYPE_CODE_COMPLEX: - return EXACT_MATCH_BADNESS; - default: - return INCOMPATIBLE_TYPE_BADNESS; - } - break; + return rank_one_type_parm_complex (parm, arg, value); case TYPE_CODE_STRUCT: - switch (TYPE_CODE (arg)) - { - case TYPE_CODE_STRUCT: - /* Check for derivation */ - rank.subrank = distance_to_ancestor (parm, arg, 0); - if (rank.subrank >= 0) - return sum_ranks (BASE_CONVERSION_BADNESS, rank); - /* fall through */ - default: - return INCOMPATIBLE_TYPE_BADNESS; - } - break; - case TYPE_CODE_UNION: - switch (TYPE_CODE (arg)) - { - case TYPE_CODE_UNION: - default: - return INCOMPATIBLE_TYPE_BADNESS; - } - break; - case TYPE_CODE_MEMBERPTR: - switch (TYPE_CODE (arg)) - { - default: - return INCOMPATIBLE_TYPE_BADNESS; - } - break; - case TYPE_CODE_METHOD: - switch (TYPE_CODE (arg)) - { - - default: - return INCOMPATIBLE_TYPE_BADNESS; - } - break; - case TYPE_CODE_REF: - switch (TYPE_CODE (arg)) - { - - default: - return INCOMPATIBLE_TYPE_BADNESS; - } - - break; + return rank_one_type_parm_struct (parm, arg, value); case TYPE_CODE_SET: - switch (TYPE_CODE (arg)) - { - /* Not in C++ */ - case TYPE_CODE_SET: - return rank_one_type (TYPE_FIELD_TYPE (parm, 0), - TYPE_FIELD_TYPE (arg, 0), NULL); - default: - return INCOMPATIBLE_TYPE_BADNESS; - } - break; - case TYPE_CODE_VOID: + return rank_one_type_parm_set (parm, arg, value); default: return INCOMPATIBLE_TYPE_BADNESS; } /* switch (TYPE_CODE (arg)) */ @@ -4598,7 +4660,7 @@ recursive_dump_type (struct type *type, int spaces) break; } puts_filtered ("\n"); - printfi_filtered (spaces, "length %d\n", TYPE_LENGTH (type)); + printfi_filtered (spaces, "length %s\n", pulongest (TYPE_LENGTH (type))); if (TYPE_OBJFILE_OWNED (type)) { printfi_filtered (spaces, "objfile "); @@ -4671,6 +4733,10 @@ recursive_dump_type (struct type *type, int spaces) { puts_filtered (" TYPE_NOSIGN"); } + if (TYPE_ENDIANITY_NOT_DEFAULT (type)) + { + puts_filtered (" TYPE_ENDIANITY_NOT_DEFAULT"); + } if (TYPE_STUB (type)) { puts_filtered (" TYPE_STUB"); @@ -5366,6 +5432,9 @@ gdbtypes_post_init (struct gdbarch *gdbarch) builtin_type->builtin_unsigned_long_long = arch_integer_type (gdbarch, gdbarch_long_long_bit (gdbarch), 1, "unsigned long long"); + builtin_type->builtin_half + = arch_float_type (gdbarch, gdbarch_half_bit (gdbarch), + "half", gdbarch_half_format (gdbarch)); builtin_type->builtin_float = arch_float_type (gdbarch, gdbarch_float_bit (gdbarch), "float", gdbarch_float_format (gdbarch)); @@ -5465,14 +5534,15 @@ gdbtypes_post_init (struct gdbarch *gdbarch) /* This set of objfile-based types is intended to be used by symbol readers as basic types. */ -static const struct objfile_data *objfile_type_data; +static const struct objfile_key> + objfile_type_data; const struct objfile_type * objfile_type (struct objfile *objfile) { struct gdbarch *gdbarch; - struct objfile_type *objfile_type - = (struct objfile_type *) objfile_data (objfile, objfile_type_data); + struct objfile_type *objfile_type = objfile_type_data.get (objfile); if (objfile_type) return objfile_type; @@ -5577,7 +5647,7 @@ objfile_type (struct objfile *objfile) = init_integer_type (objfile, gdbarch_addr_bit (gdbarch), 1, "__CORE_ADDR"); - set_objfile_data (objfile, objfile_type_data, objfile_type); + objfile_type_data.set (objfile, objfile_type); return objfile_type; } @@ -5585,7 +5655,6 @@ void _initialize_gdbtypes (void) { gdbtypes_data = gdbarch_data_register_post_init (gdbtypes_post_init); - objfile_type_data = register_objfile_data (); add_setshow_zuinteger_cmd ("overload", no_class, &overload_debug, _("Set debugging of C++ overloading."), @@ -5616,3 +5685,21 @@ _initialize_gdbtypes (void) show_strict_type_checking, &setchecklist, &showchecklist); } + +/* See gdbtypes.h. */ +enum bfd_endian +type_byte_order (const struct type *type) +{ + bfd_endian byteorder = gdbarch_byte_order (get_type_arch (type)); + if (TYPE_ENDIANITY_NOT_DEFAULT (type)) + { + if (byteorder == BFD_ENDIAN_BIG) + return BFD_ENDIAN_LITTLE; + else if (byteorder == BFD_ENDIAN_LITTLE) + return BFD_ENDIAN_BIG; + else + return BFD_ENDIAN_UNKNOWN; + } + + return byteorder; +}