X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fgdbtypes.c;h=73d445361dd1028695447e141a6bcabb3a2422b5;hb=412294daf8786fd9060059b8be7fc59a35e13922;hp=5e5db2776b16424491da44427a104239d64fea9a;hpb=d7e747318f4d04af033f16325f9b6d74f67079ec;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 5e5db2776b..73d445361d 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -38,6 +38,7 @@ #include "bcache.h" #include "dwarf2loc.h" #include "gdbcore.h" +#include "floatformat.h" /* Initialize BADNESS constants. */ @@ -51,6 +52,7 @@ const struct rank EXACT_MATCH_BADNESS = {0,0}; const struct rank INTEGER_PROMOTION_BADNESS = {1,0}; const struct rank FLOAT_PROMOTION_BADNESS = {1,0}; const struct rank BASE_PTR_CONVERSION_BADNESS = {1,0}; +const struct rank CV_CONVERSION_BADNESS = {1, 0}; const struct rank INTEGER_CONVERSION_BADNESS = {2,0}; const struct rank FLOAT_CONVERSION_BADNESS = {2,0}; const struct rank INT_FLOAT_CONVERSION_BADNESS = {2,0}; @@ -384,15 +386,21 @@ lookup_pointer_type (struct type *type) /* Lookup a C++ `reference' to a type TYPE. TYPEPTR, if nonzero, points to a pointer to memory where the reference type should be stored. If *TYPEPTR is zero, update it to point to the reference - type we return. We allocate new memory if needed. */ + type we return. We allocate new memory if needed. REFCODE denotes + the kind of reference type to lookup (lvalue or rvalue reference). */ struct type * -make_reference_type (struct type *type, struct type **typeptr) +make_reference_type (struct type *type, struct type **typeptr, + enum type_code refcode) { struct type *ntype; /* New type */ + struct type **reftype; struct type *chain; - ntype = TYPE_REFERENCE_TYPE (type); + gdb_assert (refcode == TYPE_CODE_REF || refcode == TYPE_CODE_RVALUE_REF); + + ntype = (refcode == TYPE_CODE_REF ? TYPE_REFERENCE_TYPE (type) + : TYPE_RVALUE_REFERENCE_TYPE (type)); if (ntype) { @@ -421,7 +429,10 @@ make_reference_type (struct type *type, struct type **typeptr) } TYPE_TARGET_TYPE (ntype) = type; - TYPE_REFERENCE_TYPE (type) = ntype; + reftype = (refcode == TYPE_CODE_REF ? &TYPE_REFERENCE_TYPE (type) + : &TYPE_RVALUE_REFERENCE_TYPE (type)); + + *reftype = ntype; /* FIXME! Assume the machine has only one representation for references, and that it matches the (only) representation for @@ -429,10 +440,9 @@ make_reference_type (struct type *type, struct type **typeptr) TYPE_LENGTH (ntype) = gdbarch_ptr_bit (get_type_arch (type)) / TARGET_CHAR_BIT; - TYPE_CODE (ntype) = TYPE_CODE_REF; + TYPE_CODE (ntype) = refcode; - if (!TYPE_REFERENCE_TYPE (type)) /* Remember it, if don't have one. */ - TYPE_REFERENCE_TYPE (type) = ntype; + *reftype = ntype; /* Update the length of all the other variants of this type. */ chain = TYPE_CHAIN (ntype); @@ -449,9 +459,25 @@ make_reference_type (struct type *type, struct type **typeptr) details. */ struct type * -lookup_reference_type (struct type *type) +lookup_reference_type (struct type *type, enum type_code refcode) { - return make_reference_type (type, (struct type **) 0); + return make_reference_type (type, (struct type **) 0, refcode); +} + +/* Lookup the lvalue reference type for the type TYPE. */ + +struct type * +lookup_lvalue_reference_type (struct type *type) +{ + return lookup_reference_type (type, TYPE_CODE_REF); +} + +/* Lookup the rvalue reference type for the type TYPE. */ + +struct type * +lookup_rvalue_reference_type (struct type *type) +{ + return lookup_reference_type (type, TYPE_CODE_RVALUE_REF); } /* Lookup a function type that returns type TYPE. TYPEPTR, if @@ -522,6 +548,8 @@ lookup_function_type_with_arguments (struct type *type, gdb_assert (nparams == 0); TYPE_PROTOTYPED (fn) = 1; } + else + TYPE_PROTOTYPED (fn) = 1; } TYPE_NFIELDS (fn) = nparams; @@ -2707,22 +2735,30 @@ set_type_code (struct type *type, enum type_code code) determined by the floatformat. Returns size to be used. */ static int -verify_floatformat (int bit, const struct floatformat **floatformats) +verify_floatformat (int bit, const struct floatformat *floatformat) { - gdb_assert (floatformats != NULL); - gdb_assert (floatformats[0] != NULL && floatformats[1] != NULL); + gdb_assert (floatformat != NULL); if (bit == -1) - bit = floatformats[0]->totalsize; - gdb_assert (bit >= 0); + bit = floatformat->totalsize; - size_t len = bit / TARGET_CHAR_BIT; - gdb_assert (len >= floatformat_totalsize_bytes (floatformats[0])); - gdb_assert (len >= floatformat_totalsize_bytes (floatformats[1])); + gdb_assert (bit >= 0); + gdb_assert (bit >= floatformat->totalsize); return bit; } +/* Return the floating-point format for a floating-point variable of + type TYPE. */ + +const struct floatformat * +floatformat_from_type (const struct type *type) +{ + gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT); + gdb_assert (TYPE_FLOATFORMAT (type)); + return TYPE_FLOATFORMAT (type); +} + /* Helper function to initialize the standard scalar types. If NAME is non-NULL, then it is used to initialize the type name. @@ -2730,19 +2766,30 @@ verify_floatformat (int bit, const struct floatformat **floatformats) least as long as OBJFILE. */ struct type * -init_type (struct objfile *objfile, enum type_code code, int length, +init_type (struct objfile *objfile, enum type_code code, int bit, const char *name) { struct type *type; type = alloc_type (objfile); set_type_code (type, code); - TYPE_LENGTH (type) = length; + gdb_assert ((bit % TARGET_CHAR_BIT) == 0); + TYPE_LENGTH (type) = bit / TARGET_CHAR_BIT; TYPE_NAME (type) = name; return type; } +/* Allocate a TYPE_CODE_ERROR type structure associated with OBJFILE, + to use with variables that have no debug info. NAME is the type + name. */ + +static struct type * +init_nodebug_var_type (struct objfile *objfile, const char *name) +{ + return init_type (objfile, TYPE_CODE_ERROR, 0, name); +} + /* Allocate a TYPE_CODE_INT type structure associated with OBJFILE. BIT is the type size in bits. If UNSIGNED_P is non-zero, set the type's TYPE_UNSIGNED flag. NAME is the type name. */ @@ -2753,7 +2800,7 @@ init_integer_type (struct objfile *objfile, { struct type *t; - t = init_type (objfile, TYPE_CODE_INT, bit / TARGET_CHAR_BIT, name); + t = init_type (objfile, TYPE_CODE_INT, bit, name); if (unsigned_p) TYPE_UNSIGNED (t) = 1; @@ -2770,7 +2817,7 @@ init_character_type (struct objfile *objfile, { struct type *t; - t = init_type (objfile, TYPE_CODE_CHAR, bit / TARGET_CHAR_BIT, name); + t = init_type (objfile, TYPE_CODE_CHAR, bit, name); if (unsigned_p) TYPE_UNSIGNED (t) = 1; @@ -2787,7 +2834,7 @@ init_boolean_type (struct objfile *objfile, { struct type *t; - t = init_type (objfile, TYPE_CODE_BOOL, bit / TARGET_CHAR_BIT, name); + t = init_type (objfile, TYPE_CODE_BOOL, bit, name); if (unsigned_p) TYPE_UNSIGNED (t) = 1; @@ -2804,11 +2851,13 @@ init_float_type (struct objfile *objfile, int bit, const char *name, const struct floatformat **floatformats) { + struct gdbarch *gdbarch = get_objfile_arch (objfile); + const struct floatformat *fmt = floatformats[gdbarch_byte_order (gdbarch)]; struct type *t; - bit = verify_floatformat (bit, floatformats); - t = init_type (objfile, TYPE_CODE_FLT, bit / TARGET_CHAR_BIT, name); - TYPE_FLOATFORMAT (t) = floatformats; + bit = verify_floatformat (bit, fmt); + t = init_type (objfile, TYPE_CODE_FLT, bit, name); + TYPE_FLOATFORMAT (t) = fmt; return t; } @@ -2821,7 +2870,7 @@ init_decfloat_type (struct objfile *objfile, int bit, const char *name) { struct type *t; - t = init_type (objfile, TYPE_CODE_DECFLOAT, bit / TARGET_CHAR_BIT, name); + t = init_type (objfile, TYPE_CODE_DECFLOAT, bit, name); return t; } @@ -2835,7 +2884,7 @@ init_complex_type (struct objfile *objfile, struct type *t; t = init_type (objfile, TYPE_CODE_COMPLEX, - 2 * TYPE_LENGTH (target_type), name); + 2 * TYPE_LENGTH (target_type) * TARGET_CHAR_BIT, name); TYPE_TARGET_TYPE (t) = target_type; return t; } @@ -2851,7 +2900,7 @@ init_pointer_type (struct objfile *objfile, { struct type *t; - t = init_type (objfile, TYPE_CODE_PTR, bit / TARGET_CHAR_BIT, name); + t = init_type (objfile, TYPE_CODE_PTR, bit, name); TYPE_TARGET_TYPE (t) = target_type; TYPE_UNSIGNED (t) = 1; return t; @@ -3587,21 +3636,66 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value) { struct rank rank = {0,0}; - if (types_equal (parm, arg)) - return EXACT_MATCH_BADNESS; - /* Resolve typedefs */ if (TYPE_CODE (parm) == TYPE_CODE_TYPEDEF) parm = check_typedef (parm); if (TYPE_CODE (arg) == TYPE_CODE_TYPEDEF) arg = check_typedef (arg); + if (TYPE_IS_REFERENCE (parm) && value != NULL) + { + if (VALUE_LVAL (value) == not_lval) + { + /* Rvalues should preferably bind to rvalue references or const + lvalue references. */ + if (TYPE_CODE (parm) == TYPE_CODE_RVALUE_REF) + rank.subrank = REFERENCE_CONVERSION_RVALUE; + else if (TYPE_CONST (TYPE_TARGET_TYPE (parm))) + rank.subrank = REFERENCE_CONVERSION_CONST_LVALUE; + else + return INCOMPATIBLE_TYPE_BADNESS; + return sum_ranks (rank, REFERENCE_CONVERSION_BADNESS); + } + else + { + /* Lvalues should prefer lvalue overloads. */ + if (TYPE_CODE (parm) == TYPE_CODE_RVALUE_REF) + { + rank.subrank = REFERENCE_CONVERSION_RVALUE; + return sum_ranks (rank, REFERENCE_CONVERSION_BADNESS); + } + } + } + + if (types_equal (parm, arg)) + { + struct type *t1 = parm; + struct type *t2 = arg; + + /* For pointers and references, compare target type. */ + if (TYPE_CODE (parm) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (parm)) + { + t1 = TYPE_TARGET_TYPE (parm); + t2 = TYPE_TARGET_TYPE (arg); + } + + /* Make sure they are CV equal, too. */ + 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; + } + /* See through references, since we can almost make non-references references. */ - if (TYPE_CODE (arg) == TYPE_CODE_REF) + + if (TYPE_IS_REFERENCE (arg)) return (sum_ranks (rank_one_type (parm, TYPE_TARGET_TYPE (arg), NULL), REFERENCE_CONVERSION_BADNESS)); - if (TYPE_CODE (parm) == TYPE_CODE_REF) + if (TYPE_IS_REFERENCE (parm)) return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm), arg, NULL), REFERENCE_CONVERSION_BADNESS)); if (overload_debug) @@ -3634,10 +3728,23 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value) return INCOMPATIBLE_TYPE_BADNESS; case TYPE_CODE_ARRAY: - if (types_equal (TYPE_TARGET_TYPE (parm), - TYPE_TARGET_TYPE (arg))) - return EXACT_MATCH_BADNESS; - return INCOMPATIBLE_TYPE_BADNESS; + { + 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: @@ -4361,10 +4468,6 @@ recursive_dump_type (struct type *type, int spaces) { puts_filtered (" TYPE_TARGET_STUB"); } - if (TYPE_STATIC (type)) - { - puts_filtered (" TYPE_STATIC"); - } if (TYPE_PROTOTYPED (type)) { puts_filtered (" TYPE_PROTOTYPED"); @@ -4452,26 +4555,11 @@ recursive_dump_type (struct type *type, int spaces) case TYPE_SPECIFIC_FLOATFORMAT: printfi_filtered (spaces, "floatformat "); - if (TYPE_FLOATFORMAT (type) == NULL) + if (TYPE_FLOATFORMAT (type) == NULL + || TYPE_FLOATFORMAT (type)->name == 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 (TYPE_FLOATFORMAT (type)->name); puts_filtered ("\n"); break; @@ -4740,13 +4828,14 @@ copy_type (const struct type *type) struct type * arch_type (struct gdbarch *gdbarch, - enum type_code code, int length, const char *name) + enum type_code code, int bit, const char *name) { struct type *type; type = alloc_type_arch (gdbarch); set_type_code (type, code); - TYPE_LENGTH (type) = length; + gdb_assert ((bit % TARGET_CHAR_BIT) == 0); + TYPE_LENGTH (type) = bit / TARGET_CHAR_BIT; if (name) TYPE_NAME (type) = gdbarch_obstack_strdup (gdbarch, name); @@ -4764,7 +4853,7 @@ arch_integer_type (struct gdbarch *gdbarch, { struct type *t; - t = arch_type (gdbarch, TYPE_CODE_INT, bit / TARGET_CHAR_BIT, name); + t = arch_type (gdbarch, TYPE_CODE_INT, bit, name); if (unsigned_p) TYPE_UNSIGNED (t) = 1; @@ -4781,7 +4870,7 @@ arch_character_type (struct gdbarch *gdbarch, { struct type *t; - t = arch_type (gdbarch, TYPE_CODE_CHAR, bit / TARGET_CHAR_BIT, name); + t = arch_type (gdbarch, TYPE_CODE_CHAR, bit, name); if (unsigned_p) TYPE_UNSIGNED (t) = 1; @@ -4798,7 +4887,7 @@ arch_boolean_type (struct gdbarch *gdbarch, { struct type *t; - t = arch_type (gdbarch, TYPE_CODE_BOOL, bit / TARGET_CHAR_BIT, name); + t = arch_type (gdbarch, TYPE_CODE_BOOL, bit, name); if (unsigned_p) TYPE_UNSIGNED (t) = 1; @@ -4815,11 +4904,12 @@ arch_float_type (struct gdbarch *gdbarch, int bit, const char *name, const struct floatformat **floatformats) { + const struct floatformat *fmt = floatformats[gdbarch_byte_order (gdbarch)]; struct type *t; - bit = verify_floatformat (bit, floatformats); - t = arch_type (gdbarch, TYPE_CODE_FLT, bit / TARGET_CHAR_BIT, name); - TYPE_FLOATFORMAT (t) = floatformats; + bit = verify_floatformat (bit, fmt); + t = arch_type (gdbarch, TYPE_CODE_FLT, bit, name); + TYPE_FLOATFORMAT (t) = fmt; return t; } @@ -4832,7 +4922,7 @@ arch_decfloat_type (struct gdbarch *gdbarch, int bit, const char *name) { struct type *t; - t = arch_type (gdbarch, TYPE_CODE_DECFLOAT, bit / TARGET_CHAR_BIT, name); + t = arch_type (gdbarch, TYPE_CODE_DECFLOAT, bit, name); return t; } @@ -4846,7 +4936,7 @@ arch_complex_type (struct gdbarch *gdbarch, struct type *t; t = arch_type (gdbarch, TYPE_CODE_COMPLEX, - 2 * TYPE_LENGTH (target_type), name); + 2 * TYPE_LENGTH (target_type) * TARGET_CHAR_BIT, name); TYPE_TARGET_TYPE (t) = target_type; return t; } @@ -4862,27 +4952,26 @@ arch_pointer_type (struct gdbarch *gdbarch, { struct type *t; - t = arch_type (gdbarch, TYPE_CODE_PTR, bit / TARGET_CHAR_BIT, name); + t = arch_type (gdbarch, TYPE_CODE_PTR, bit, name); TYPE_TARGET_TYPE (t) = target_type; TYPE_UNSIGNED (t) = 1; return t; } /* Allocate a TYPE_CODE_FLAGS type structure associated with GDBARCH. - NAME is the type name. LENGTH is the size of the flag word in bytes. */ + NAME is the type name. BIT is the size of the flag word in bits. */ struct type * -arch_flags_type (struct gdbarch *gdbarch, const char *name, int length) +arch_flags_type (struct gdbarch *gdbarch, const char *name, int bit) { - int max_nfields = length * TARGET_CHAR_BIT; struct type *type; - type = arch_type (gdbarch, TYPE_CODE_FLAGS, length, name); + type = arch_type (gdbarch, TYPE_CODE_FLAGS, bit, name); TYPE_UNSIGNED (type) = 1; TYPE_NFIELDS (type) = 0; /* Pre-allocate enough space assuming every field is one bit. */ TYPE_FIELDS (type) - = (struct field *) TYPE_ZALLOC (type, max_nfields * sizeof (struct field)); + = (struct field *) TYPE_ZALLOC (type, bit * sizeof (struct field)); return type; } @@ -5027,7 +5116,7 @@ gdbtypes_post_init (struct gdbarch *gdbarch) /* Basic types. */ builtin_type->builtin_void - = arch_type (gdbarch, TYPE_CODE_VOID, 1, "void"); + = arch_type (gdbarch, TYPE_CODE_VOID, TARGET_CHAR_BIT, "void"); builtin_type->builtin_char = arch_integer_type (gdbarch, TARGET_CHAR_BIT, !gdbarch_char_signed (gdbarch), "char"); @@ -5078,9 +5167,9 @@ gdbtypes_post_init (struct gdbarch *gdbarch) = arch_complex_type (gdbarch, "double complex", builtin_type->builtin_double); builtin_type->builtin_string - = arch_type (gdbarch, TYPE_CODE_STRING, 1, "string"); + = arch_type (gdbarch, TYPE_CODE_STRING, TARGET_CHAR_BIT, "string"); builtin_type->builtin_bool - = arch_type (gdbarch, TYPE_CODE_BOOL, 1, "bool"); + = arch_type (gdbarch, TYPE_CODE_BOOL, TARGET_CHAR_BIT, "bool"); /* The following three are about decimal floating point types, which are 32-bits, 64-bits and 128-bits respectively. */ @@ -5127,10 +5216,12 @@ gdbtypes_post_init (struct gdbarch *gdbarch) /* Wide character types. */ builtin_type->builtin_char16 - = arch_integer_type (gdbarch, 16, 0, "char16_t"); + = arch_integer_type (gdbarch, 16, 1, "char16_t"); builtin_type->builtin_char32 - = arch_integer_type (gdbarch, 32, 0, "char32_t"); - + = arch_integer_type (gdbarch, 32, 1, "char32_t"); + builtin_type->builtin_wchar + = arch_integer_type (gdbarch, gdbarch_wchar_bit (gdbarch), + !gdbarch_wchar_signed (gdbarch), "wchar_t"); /* Default data/code pointer types. */ builtin_type->builtin_data_ptr @@ -5175,7 +5266,7 @@ objfile_type (struct objfile *objfile) /* Basic types. */ objfile_type->builtin_void - = init_type (objfile, TYPE_CODE_VOID, 1, "void"); + = init_type (objfile, TYPE_CODE_VOID, TARGET_CHAR_BIT, "void"); objfile_type->builtin_char = init_integer_type (objfile, TARGET_CHAR_BIT, !gdbarch_char_signed (gdbarch), "char"); @@ -5227,29 +5318,26 @@ objfile_type (struct objfile *objfile) /* The following set of types is used for symbols with no debug information. */ objfile_type->nodebug_text_symbol - = init_type (objfile, TYPE_CODE_FUNC, 1, + = init_type (objfile, TYPE_CODE_FUNC, TARGET_CHAR_BIT, ""); - TYPE_TARGET_TYPE (objfile_type->nodebug_text_symbol) - = objfile_type->builtin_int; objfile_type->nodebug_text_gnu_ifunc_symbol - = init_type (objfile, TYPE_CODE_FUNC, 1, + = init_type (objfile, TYPE_CODE_FUNC, TARGET_CHAR_BIT, ""); + /* Ifunc resolvers return a function address. */ TYPE_TARGET_TYPE (objfile_type->nodebug_text_gnu_ifunc_symbol) - = objfile_type->nodebug_text_symbol; + = init_integer_type (objfile, gdbarch_addr_bit (gdbarch), 1, + "__IFUNC_RESOLVER_RET"); TYPE_GNU_IFUNC (objfile_type->nodebug_text_gnu_ifunc_symbol) = 1; objfile_type->nodebug_got_plt_symbol = init_pointer_type (objfile, gdbarch_addr_bit (gdbarch), "", objfile_type->nodebug_text_symbol); objfile_type->nodebug_data_symbol - = init_integer_type (objfile, gdbarch_int_bit (gdbarch), 0, - ""); + = init_nodebug_var_type (objfile, ""); objfile_type->nodebug_unknown_symbol - = init_integer_type (objfile, TARGET_CHAR_BIT, 0, - ""); + = init_nodebug_var_type (objfile, ""); objfile_type->nodebug_tls_symbol - = init_integer_type (objfile, gdbarch_int_bit (gdbarch), 0, - ""); + = init_nodebug_var_type (objfile, ""); /* NOTE: on some targets, addresses and pointers are not necessarily the same. @@ -5278,8 +5366,6 @@ objfile_type (struct objfile *objfile) return objfile_type; } -extern initialize_file_ftype _initialize_gdbtypes; - void _initialize_gdbtypes (void) {