------- Additional Comments From dberlin at gcc dot gnu dot org 2005-09-27 20:42 ------- We have a var of type C named D.2117
<var_decl 0x4022cec8 D.2117 type <record_type 0x40212ac8 C addressable tree_2 needs-constructing type_1 type_4 type_5 BLK size <integer_cst 0x40210ed0 constant invariant 224> unit size <integer_cst 0x40210f00 constant invariant 28> align 32 symtab 0 alias set 21 fields <field_decl 0x40212ebc D.1814 type <record_type 0x40212170 B> ignored decl_6 BLK file /home/dberlin/22488.cc line 18 size <integer_cst 0x401693f0 constant invariant 32> unit size <integer_cst 0x40169180 constant invariant 4> align 32 offset_align 128 offset <integer_cst 0x40169198 constant invariant 0> bit offset <integer_cst 0x40169960 constant invariant 0> context <record_type 0x40212ac8 C> chain <field_decl 0x40212b24 x>> needs-constructor needs-destructor X() X(constX&) this=(X&) n_parents=1 use_template=0 interface-unknown pointer_to_this <pointer_type 0x40212c38> chain <type_decl 0x401eedd0 C>> addressable ignored BLK file /home/dberlin/22488.cc line 26 size <integer_cst 0x40210ed0 224> unit size <integer_cst 0x40210f00 28> align 32 context <function_decl 0x40214680 foo>> The first field of this is a field D.2184 of type B <field_decl 0x40212ebc D.1814 type <record_type 0x40212170 B addressable tree_2 needs-constructing type_1 type_4 type_5 BLK size <integer_cst 0x40169660 constant invariant 128> unit size <integer_cst 0x40169678 constant invariant 16> align 32 symtab 0 alias set 2 fields <field_decl 0x40212450 _vptr.B type <pointer_type 0x401f005c> unsigned virtual SI file /home/dberlin/22488.cc line 15 size <integer_cst 0x401693f0 constant invariant 32> unit size <integer_cst 0x40169180 constant invariant 4> align 32 offset_align 128 offset <integer_cst 0x40169198 constant invariant 0> bit offset <integer_cst 0x40169960 constant invariant 0> context <record_type 0x40212170 B> chain <type_decl 0x401eec98 B>> needs-constructor needs-destructor X() X(constX&) this=(X&) n_parents=1 use_template=0 interface-unknown pointer_to_this <pointer_type 0x40212228> chain <type_decl 0x401eec30 B>> ignored decl_6 BLK file /home/dberlin/22488.cc line 18 size <integer_cst 0x401693f0 32> unit size <integer_cst 0x40169180 4> align 32 offset_align 128 offset <integer_cst 0x40169198 0> bit offset <integer_cst 0x40169960 0> context <record_type 0x40212ac8 C> chain <field_decl 0x40212b24 x>> This field of type B is at offset (offset = 0 + bit_offset = 0) from our var of type C The first field of B is _vptr.B: <field_decl 0x40212450 _vptr.B type <pointer_type 0x401f005c type <pointer_type 0x401e5f74 __vtbl_ptr_type type <function_type 0x401e5f18> unsigned SI size <integer_cst 0x401693f0 constant invariant 32> unit size <integer_cst 0x40169180 constant invariant 4> align 32 symtab 0 alias set 7 pointer_to_this <pointer_type 0x401f005c>> unsigned SI size <integer_cst 0x401693f0 32> unit size <integer_cst 0x40169180 4> align 32 symtab 0 alias set 4> unsigned virtual SI file /home/dberlin/22488.cc line 15 size <integer_cst 0x401693f0 32> unit size <integer_cst 0x40169180 4> align 32 offset_align 128 offset <integer_cst 0x40169198 type <integer_type 0x4017b000 unsigned int> constant invariant 0> bit offset <integer_cst 0x40169960 type <integer_type 0x4017b05c bit_size_type> constant invariant 0> context <record_type 0x40212170 B> chain <type_decl 0x401eec98 B>> It is at offset 0 from our field of type B, which is at offset 0 from our var of type C. The next field after B is a type_decl. The next field after the type_decl is field_decl 0x40212564 D.1781 <field_decl 0x40212564 D.1781 type <record_type 0x4020e9b4 A addressable tree_2 needs-constructing type_1 type_4 type_5 BLK size <integer_cst 0x40169a80 constant invariant 96> unit size <integer_cst 0x40169a98 constant invariant 12> align 32 symtab 0 alias set 3 fields <field_decl 0x4020ee04 _vptr.A type <pointer_type 0x401f005c> unsigned virtual SI file /home/dberlin/22488.cc line 8 size <integer_cst 0x401693f0 constant invariant 32> unit size <integer_cst 0x40169180 constant invariant 4> align 32 offset_align 128 offset <integer_cst 0x40169198 constant invariant 0> bit offset <integer_cst 0x40169960 constant invariant 0> context <record_type 0x4020e9b4 A> chain <field_decl 0x4020ea10 i>> needs-constructor needs-destructor X() X(constX&) this=(X&) n_parents=0 use_template=0 interface-only pointer_to_this <pointer_type 0x4020ebdc> chain <type_decl 0x401eea90 A>> ignored decl_6 BLK file /home/dberlin/22488.cc line 15 size <integer_cst 0x40210630 type <integer_type 0x4017b05c bit_size_type> constant invariant 80> unit size <integer_cst 0x40210678 type <integer_type 0x4017b000 unsigned int> constant invariant 10> align 32 offset_align 128 offset <integer_cst 0x40169198 0> bit offset <integer_cst 0x401693f0 32> context <record_type 0x40212170 B>> It is at offset 32 from our field of type B, which is at offset 0 from our var of type C. So total offset = 32 for this field. It is of type A. The first field of type A is _vptr.A. <field_decl 0x4020ee04 _vptr.A type <pointer_type 0x401f005c type <pointer_type 0x401e5f74 __vtbl_ptr_type type <function_type 0x401e5f18> unsigned SI size <integer_cst 0x401693f0 constant invariant 32> unit size <integer_cst 0x40169180 constant invariant 4> align 32 symtab 0 alias set 7 pointer_to_this <pointer_type 0x401f005c>> unsigned SI size <integer_cst 0x401693f0 32> unit size <integer_cst 0x40169180 4> align 32 symtab 0 alias set 4> unsigned virtual SI file /home/dberlin/22488.cc line 8 size <integer_cst 0x401693f0 32> unit size <integer_cst 0x40169180 4> align 32 offset_align 128 offset <integer_cst 0x40169198 type <integer_type 0x4017b000 unsigned int> constant invariant 0> bit offset <integer_cst 0x40169960 type <integer_type 0x4017b05c bit_size_type> constant invariant 0> context <record_type 0x4020e9b4 A> chain <field_decl 0x4020ea10 i>> This field is at offset 0 from our field of type A, which is at offset 32 from our field of type B, which is at offset 0 from our var of type C. So total offset = 32 from var C for this field. Let's skip the rest of the fields of our field of type A since they don't mtater for showing the overlap. Pop back up to the field of type B, then pop back up to our original var of type C. The next *field* of type C is <field_decl 0x40212b24 x type <record_type 0x4020e844 X type_1 type_5 BLK size <integer_cst 0x40169a80 constant invariant 96> unit size <integer_cst 0x40169a98 constant invariant 12> align 32 symtab 0 alias set 22 fields <field_decl 0x4020e8a0 i0 type <integer_type 0x4017b284 int> nonlocal decl_3 SI file /home/dberlin/22488.cc line 3 size <integer_cst 0x401693f0 constant invariant 32> unit size <integer_cst 0x40169180 constant invariant 4> align 32 offset_align 128 offset <integer_cst 0x40169198 constant invariant 0> bit offset <integer_cst 0x40169960 constant invariant 0> context <record_type 0x4020e844 X> chain <field_decl 0x4020e8fc i1>> X() X(constX&) this=(X&) n_parents=0 use_template=0 interface-unknown pointer_to_this <pointer_type 0x402164ac> reference_to_this <reference_type 0x4021633c> chain <type_decl 0x401ee958 X>> used nonlocal decl_3 BLK file /home/dberlin/22488.cc line 19 size <integer_cst 0x40169a80 96> unit size <integer_cst 0x40169a98 12> align 32 offset_align 128 offset <integer_cst 0x40169198 0> bit offset <integer_cst 0x401693f0 32> context <record_type 0x40212ac8 C> chain <type_decl 0x401eee38 C>> This says that we have a field decl named x of type X at offset 32 from our var of type C. It's first field is i0: <field_decl 0x4020e8a0 i0 type <integer_type 0x4017b284 int public SI size <integer_cst 0x401693f0 constant invariant 32> unit size <integer_cst 0x40169180 constant invariant 4> align 32 symtab 0 alias set 5 precision 32 min <integer_cst 0x401693a8 -2147483648> max <integer_cst 0x401693c0 2147483647> pointer_to_this <pointer_type 0x4017bc38>> nonlocal decl_3 SI file /home/dberlin/22488.cc line 3 size <integer_cst 0x401693f0 32> unit size <integer_cst 0x40169180 4> align 32 offset_align 128 offset <integer_cst 0x40169198 type <integer_type 0x4017b000 unsigned int> constant invariant 0> bit offset <integer_cst 0x40169960 type <integer_type 0x4017b05c bit_size_type> constant invariant 0> context <record_type 0x4020e844 X> chain <field_decl 0x4020e8fc i1>> This field is at offset 0 from our var of field of type X which is at offset 32 from our var of type C. Thus, it overlaps with _vptr.A. Does your frontend output look like this? Are we expected to be adding the deepest offset from the first depth first search to the following ones when we pop back up or something? If so, the docs should be clarified so they state "structure type" instead of "structure", since i consider the *structure* here to be the variable (as would, i argue, anyone who programs instead of works on type systems :P), in which case, the offsets are wrong. /* In a FIELD_DECL, this is the field position, counting in bytes, of the byte containing the bit closest to the beginning of the structure. */ #define DECL_FIELD_OFFSET(NODE) (FIELD_DECL_CHECK (NODE)->field_decl.offset) /* In a FIELD_DECL, this is the offset, in bits, of the first bit of the field from DECL_FIELD_OFFSET. */ #define DECL_FIELD_BIT_OFFSET(NODE) (FIELD_DECL_CHECK (NODE)->field_decl.bit_offset) -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=22488