From ae6ae97502b183d0cdb9c298a60fa05240f230bf Mon Sep 17 00:00:00 2001 From: Doug Evans Date: Sat, 31 Jan 2015 21:40:57 -0800 Subject: [PATCH] Move vptr_{fieldno,basetype} out of main_type, and update everything accordingly. Every type has to pay the price in memory usage for their presence. The proper place for them is in the type_specific field which exists for this purpose. gdb/ChangeLog: * dwarf2read.c (process_structure_scope): Update setting of TYPE_VPTR_BASETYPE, TYPE_VPTR_FIELDNO. * gdbtypes.c (internal_type_vptr_fieldno): New function. (set_type_vptr_fieldno): New function. (internal_type_vptr_basetype): New function. (set_type_vptr_basetype): New function. (get_vptr_fieldno): Update setting of TYPE_VPTR_FIELDNO, TYPE_VPTR_BASETYPE. (allocate_cplus_struct_type): Initialize vptr_fieldno. (recursive_dump_type): Printing of vptr_fieldno, vptr_basetype ... (print_cplus_stuff): ... moved here. (copy_type_recursive): Don't copy TYPE_VPTR_BASETYPE. * gdbtypes.h (struct main_type): Members vptr_fieldno, vptr_basetype moved to ... (struct cplus_struct_type): ... here. All uses updated. (TYPE_VPTR_FIELDNO, TYPE_VPTR_BASETYPE): Rewrite. (internal_type_vptr_fieldno, set_type_vptr_fieldno): Declare. (internal_type_vptr_basetype, set_type_vptr_basetype): Declare. * stabsread.c (read_tilde_fields): Update setting of TYPE_VPTR_FIELDNO, TYPE_VPTR_BASETYPE. gdb/testsuite/ChangeLog: * gdb.base/maint.exp : Update expected output. --- gdb/ChangeLog | 23 +++++++++++ gdb/dwarf2read.c | 10 ++--- gdb/eval.c | 1 - gdb/gdb-gdb.py | 1 - gdb/gdbtypes.c | 82 ++++++++++++++++++++++++++++++---------- gdb/gdbtypes.h | 50 +++++++++++++----------- gdb/stabsread.c | 6 +-- gdb/testsuite/ChangeLog | 4 ++ gdb/testsuite/gdb.base/maint.exp | 2 +- 9 files changed, 126 insertions(+), 53 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index f2d739e..b089ba2 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,28 @@ 2015-01-31 Doug Evans + * dwarf2read.c (process_structure_scope): Update setting of + TYPE_VPTR_BASETYPE, TYPE_VPTR_FIELDNO. + * gdbtypes.c (internal_type_vptr_fieldno): New function. + (set_type_vptr_fieldno): New function. + (internal_type_vptr_basetype): New function. + (set_type_vptr_basetype): New function. + (get_vptr_fieldno): Update setting of TYPE_VPTR_FIELDNO, + TYPE_VPTR_BASETYPE. + (allocate_cplus_struct_type): Initialize vptr_fieldno. + (recursive_dump_type): Printing of vptr_fieldno, vptr_basetype ... + (print_cplus_stuff): ... moved here. + (copy_type_recursive): Don't copy TYPE_VPTR_BASETYPE. + * gdbtypes.h (struct main_type): Members vptr_fieldno, vptr_basetype + moved to ... + (struct cplus_struct_type): ... here. All uses updated. + (TYPE_VPTR_FIELDNO, TYPE_VPTR_BASETYPE): Rewrite. + (internal_type_vptr_fieldno, set_type_vptr_fieldno): Declare. + (internal_type_vptr_basetype, set_type_vptr_basetype): Declare. + * stabsread.c (read_tilde_fields): Update setting of + TYPE_VPTR_FIELDNO, TYPE_VPTR_BASETYPE. + +2015-01-31 Doug Evans + * cp-valprint.c (cp_find_class_member): Rename parameter domain_p to self_p. (cp_print_class_member): Rename local domain to self_type. diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 36248f5..0d8026f 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -13255,7 +13255,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) { struct type *t = die_containing_type (die, cu); - TYPE_VPTR_BASETYPE (type) = t; + set_type_vptr_basetype (type, t); if (type == t) { int i; @@ -13269,7 +13269,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) if (is_vtable_name (fieldname, cu)) { - TYPE_VPTR_FIELDNO (type) = i; + set_type_vptr_fieldno (type, i); break; } } @@ -13284,7 +13284,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) } else { - TYPE_VPTR_FIELDNO (type) = TYPE_VPTR_FIELDNO (t); + set_type_vptr_fieldno (type, TYPE_VPTR_FIELDNO (t)); } } else if (cu->producer @@ -13303,8 +13303,8 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) { if (strcmp (TYPE_FIELD_NAME (type, i), "__vfp") == 0) { - TYPE_VPTR_FIELDNO (type) = i; - TYPE_VPTR_BASETYPE (type) = type; + set_type_vptr_fieldno (type, i); + set_type_vptr_basetype (type, type); break; } } diff --git a/gdb/eval.c b/gdb/eval.c index e6ab662..bb2a0da 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -664,7 +664,6 @@ make_params (int num_types, struct type **param_types) TYPE_MAIN_TYPE (type) = XCNEW (struct main_type); TYPE_LENGTH (type) = 1; TYPE_CODE (type) = TYPE_CODE_METHOD; - TYPE_VPTR_FIELDNO (type) = -1; TYPE_CHAIN (type) = type; if (num_types > 0) { diff --git a/gdb/gdb-gdb.py b/gdb/gdb-gdb.py index 5cc045b..61493b6 100644 --- a/gdb/gdb-gdb.py +++ b/gdb/gdb-gdb.py @@ -226,7 +226,6 @@ class StructMainTypePrettyPrinter: fields.append("flags = [%s]" % self.flags_to_string()) fields.append("owner = %s" % self.owner_to_string()) fields.append("target_type = %s" % self.val['target_type']) - fields.append("vptr_basetype = %s" % self.val['vptr_basetype']) if self.val['nfields'] > 0: for fieldno in range(self.val['nfields']): fields.append(self.struct_field_img(fieldno)) diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 0e72e1b..140fc6f 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -180,7 +180,6 @@ alloc_type (struct objfile *objfile) /* Initialize the fields that might not be zero. */ TYPE_CODE (type) = TYPE_CODE_UNDEF; - TYPE_VPTR_FIELDNO (type) = -1; TYPE_CHAIN (type) = type; /* Chain back to itself. */ return type; @@ -208,7 +207,6 @@ alloc_type_arch (struct gdbarch *gdbarch) /* Initialize the fields that might not be zero. */ TYPE_CODE (type) = TYPE_CODE_UNDEF; - TYPE_VPTR_FIELDNO (type) = -1; TYPE_CHAIN (type) = type; /* Chain back to itself. */ return type; @@ -1054,7 +1052,6 @@ create_array_type_with_stride (struct type *result_type, TYPE_FIELDS (result_type) = (struct field *) TYPE_ZALLOC (result_type, sizeof (struct field)); TYPE_INDEX_TYPE (result_type) = range_type; - TYPE_VPTR_FIELDNO (result_type) = -1; if (bit_stride > 0) TYPE_FIELD_BITSIZE (result_type, 0) = bit_stride; @@ -1614,6 +1611,59 @@ get_signed_type_minmax (struct type *type, LONGEST *min, LONGEST *max) *max = ((ULONGEST) 1 << (n - 1)) - 1; } +/* Internal routine called by TYPE_VPTR_FIELDNO to return the value of + cplus_stuff.vptr_fieldno. + + cplus_stuff is initialized to cplus_struct_default which does not + set vptr_fieldno to -1 for portability reasons (IWBN to use C99 + designated initializers). We cope with that here. */ + +int +internal_type_vptr_fieldno (struct type *type) +{ + gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT + || TYPE_CODE (type) == TYPE_CODE_UNION); + if (!HAVE_CPLUS_STRUCT (type)) + return -1; + return TYPE_RAW_CPLUS_SPECIFIC (type)->vptr_fieldno; +} + +/* Set the value of cplus_stuff.vptr_fieldno. */ + +void +set_type_vptr_fieldno (struct type *type, int fieldno) +{ + gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT + || TYPE_CODE (type) == TYPE_CODE_UNION); + if (!HAVE_CPLUS_STRUCT (type)) + ALLOCATE_CPLUS_STRUCT_TYPE (type); + TYPE_RAW_CPLUS_SPECIFIC (type)->vptr_fieldno = fieldno; +} + +/* Internal routine called by TYPE_VPTR_BASETYPE to return the value of + cplus_stuff.vptr_basetype. */ + +struct type * +internal_type_vptr_basetype (struct type *type) +{ + gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT + || TYPE_CODE (type) == TYPE_CODE_UNION); + gdb_assert (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_CPLUS_STUFF); + return TYPE_RAW_CPLUS_SPECIFIC (type)->vptr_basetype; +} + +/* Set the value of cplus_stuff.vptr_basetype. */ + +void +set_type_vptr_basetype (struct type *type, struct type *basetype) +{ + gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT + || TYPE_CODE (type) == TYPE_CODE_UNION); + if (!HAVE_CPLUS_STRUCT (type)) + ALLOCATE_CPLUS_STRUCT_TYPE (type); + TYPE_RAW_CPLUS_SPECIFIC (type)->vptr_basetype = basetype; +} + /* Lookup the vptr basetype/fieldno values for TYPE. If found store vptr_basetype in *BASETYPEP if non-NULL, and return vptr_fieldno. Also, if found and basetype is from the same objfile, @@ -1650,8 +1700,8 @@ get_vptr_fieldno (struct type *type, struct type **basetypep) it, it may have a different lifetime. PR 2384 */ if (TYPE_OBJFILE (type) == TYPE_OBJFILE (basetype)) { - TYPE_VPTR_FIELDNO (type) = fieldno; - TYPE_VPTR_BASETYPE (type) = basetype; + set_type_vptr_fieldno (type, fieldno); + set_type_vptr_basetype (type, basetype); } if (basetypep) *basetypep = basetype; @@ -2433,6 +2483,7 @@ allocate_cplus_struct_type (struct type *type) TYPE_RAW_CPLUS_SPECIFIC (type) = (struct cplus_struct_type *) TYPE_ALLOC (type, sizeof (struct cplus_struct_type)); *(TYPE_RAW_CPLUS_SPECIFIC (type)) = cplus_struct_default; + set_type_vptr_fieldno (type, -1); } const struct gnat_aux_type gnat_aux_default = @@ -3712,6 +3763,13 @@ dump_fn_fieldlists (struct type *type, int spaces) static void print_cplus_stuff (struct type *type, int spaces) { + printfi_filtered (spaces, "vptr_fieldno %d\n", TYPE_VPTR_FIELDNO (type)); + printfi_filtered (spaces, "vptr_basetype "); + gdb_print_host_address (TYPE_VPTR_BASETYPE (type), gdb_stdout); + puts_filtered ("\n"); + if (TYPE_VPTR_BASETYPE (type) != NULL) + recursive_dump_type (TYPE_VPTR_BASETYPE (type), spaces + 2); + printfi_filtered (spaces, "n_baseclasses %d\n", TYPE_N_BASECLASSES (type)); printfi_filtered (spaces, "nfn_fields %d\n", @@ -4044,15 +4102,6 @@ recursive_dump_type (struct type *type, int spaces) TYPE_HIGH_BOUND_UNDEFINED (type) ? " (undefined)" : ""); } - printfi_filtered (spaces, "vptr_basetype "); - gdb_print_host_address (TYPE_VPTR_BASETYPE (type), gdb_stdout); - puts_filtered ("\n"); - if (TYPE_VPTR_BASETYPE (type) != NULL) - { - recursive_dump_type (TYPE_VPTR_BASETYPE (type), spaces + 2); - } - printfi_filtered (spaces, "vptr_fieldno %d\n", - TYPE_VPTR_FIELDNO (type)); switch (TYPE_SPECIFIC_FIELD (type)) { @@ -4268,11 +4317,6 @@ copy_type_recursive (struct objfile *objfile, 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. diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index 50ffef3..7ca44f0 100644 --- a/gdb/gdbtypes.h +++ b/gdb/gdbtypes.h @@ -507,19 +507,6 @@ struct main_type short nfields; - /* * Field number of the virtual function table pointer in - VPTR_BASETYPE. If -1, we were unable to find the virtual - function table pointer in initial symbol reading, and - get_vptr_fieldno should be called to find it if possible. - get_vptr_fieldno will update this field if possible. Otherwise - the value is left at -1. - - Unused if this type does not have virtual functions. - - This field appears at this location because it packs nicely here. */ - - short vptr_fieldno; - /* * Name of this type, or NULL if none. This is used for printing only, except by poorly designed C++ @@ -676,14 +663,6 @@ struct main_type } flds_bnds; - /* * For types with virtual functions (TYPE_CODE_STRUCT), - VPTR_BASETYPE is the base class which defined the virtual - function table pointer. - - Unused otherwise. */ - - struct type *vptr_basetype; - /* * Slot to point to additional language-specific fields of this type. */ @@ -806,6 +785,22 @@ struct cplus_struct_type short n_baseclasses; + /* * Field number of the virtual function table pointer in VPTR_BASETYPE. + All access to this field must be through TYPE_VPTR_FIELDNO as one + thing it does is check whether the field has been initialized. + Initially TYPE_RAW_CPLUS_SPECIFIC has the value of cplus_struct_default, + which for portability reasons doesn't initialize this field. + TYPE_VPTR_FIELDNO returns -1 for this case. + + If -1, we were unable to find the virtual function table pointer in + initial symbol reading, and get_vptr_fieldno should be called to find + it if possible. get_vptr_fieldno will update this field if possible. + Otherwise the value is left at -1. + + Unused if this type does not have virtual functions. */ + + short vptr_fieldno; + /* * Number of methods with unique names. All overloaded methods with the same name count only once. */ @@ -827,6 +822,10 @@ struct cplus_struct_type unsigned int is_java : 1; + /* * The base class which defined the virtual function table pointer. */ + + struct type *vptr_basetype; + /* * For derived classes, the number of base classes is given by n_baseclasses and virtual_field_bits is a bit vector containing one bit per base class. If the base class is virtual, the @@ -1243,8 +1242,13 @@ extern void allocate_gnat_aux_type (struct type *); extern struct type *internal_type_self_type (struct type *); extern void set_type_self_type (struct type *, struct type *); -#define TYPE_VPTR_BASETYPE(thistype) TYPE_MAIN_TYPE(thistype)->vptr_basetype -#define TYPE_VPTR_FIELDNO(thistype) TYPE_MAIN_TYPE(thistype)->vptr_fieldno +extern int internal_type_vptr_fieldno (struct type *); +extern void set_type_vptr_fieldno (struct type *, int); +extern struct type *internal_type_vptr_basetype (struct type *); +extern void set_type_vptr_basetype (struct type *, struct type *); +#define TYPE_VPTR_FIELDNO(thistype) internal_type_vptr_fieldno (thistype) +#define TYPE_VPTR_BASETYPE(thistype) internal_type_vptr_basetype (thistype) + #define TYPE_NFN_FIELDS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->nfn_fields #define TYPE_SPECIFIC_FIELD(thistype) \ TYPE_MAIN_TYPE(thistype)->type_specific_field diff --git a/gdb/stabsread.c b/gdb/stabsread.c index 423c442..2a160c5 100644 --- a/gdb/stabsread.c +++ b/gdb/stabsread.c @@ -3267,7 +3267,7 @@ read_tilde_fields (struct field_info *fip, char **pp, struct type *type, return 0; } - TYPE_VPTR_BASETYPE (type) = t; + set_type_vptr_basetype (type, t); if (type == t) /* Our own class provides vtbl ptr. */ { for (i = TYPE_NFIELDS (t) - 1; @@ -3279,7 +3279,7 @@ read_tilde_fields (struct field_info *fip, char **pp, struct type *type, if (!strncmp (name, vptr_name, sizeof (vptr_name) - 2) && is_cplus_marker (name[sizeof (vptr_name) - 2])) { - TYPE_VPTR_FIELDNO (type) = i; + set_type_vptr_fieldno (type, i); goto gotit; } } @@ -3292,7 +3292,7 @@ read_tilde_fields (struct field_info *fip, char **pp, struct type *type, } else { - TYPE_VPTR_FIELDNO (type) = TYPE_VPTR_FIELDNO (t); + set_type_vptr_fieldno (type, TYPE_VPTR_FIELDNO (t)); } gotit: diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 08c951c..2657987 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2015-01-31 Doug Evans + + * gdb.base/maint.exp : Update expected output. + 2015-01-31 Gary Benson * gdb.base/completion.exp: Disable completion limiting for diff --git a/gdb/testsuite/gdb.base/maint.exp b/gdb/testsuite/gdb.base/maint.exp index e203207..f444018 100644 --- a/gdb/testsuite/gdb.base/maint.exp +++ b/gdb/testsuite/gdb.base/maint.exp @@ -359,7 +359,7 @@ gdb_expect { set msg "maint print type" gdb_test_multiple "maint print type argc" $msg { - -re "type node $hex\r\nname .int. \\($hex\\)\r\ntagname .. \\($hex\\)\r\ncode $hex \\(TYPE_CODE_INT\\)\r\nlength \[24\]\r\nobjfile $hex\r\ntarget_type $hex\r\npointer_type $hex\r\nreference_type $hex\r\ntype_chain $hex\r\ninstance_flags $hex\r\nflags\r\nnfields 0 $hex\r\nvptr_basetype $hex\r\nvptr_fieldno -1\r\n$gdb_prompt $" { + -re "type node $hex\r\nname .int. \\($hex\\)\r\ntagname .. \\($hex\\)\r\ncode $hex \\(TYPE_CODE_INT\\)\r\nlength \[24\]\r\nobjfile $hex\r\ntarget_type $hex\r\npointer_type $hex\r\nreference_type $hex\r\ntype_chain $hex\r\ninstance_flags $hex\r\nflags\r\nnfields 0 $hex\r\n$gdb_prompt $" { pass $msg } } -- 2.7.4