Studying note of GCC-3.4.6 source (139 - cont 1)

 

layout_class_type (continue)

 

4664     /* Create a pointer to our virtual function table.  */

4665     vptr = create_vtable_ptr (t, virtuals_p);

4666  

4667     /* The vptr is always the first thing in the class.  */

4668     if (vptr)

4669     {

4670       TREE_CHAIN (vptr) = TYPE_FIELDS (t);

4671       TYPE_FIELDS (t) = vptr;

4672       next_field = &TREE_CHAIN (vptr);

4673       place_field (rli, vptr);

4674     }

4675     else

4676       next_field = &TYPE_FIELDS (t);

 

Continue in layout_class_type , after the sanity check on the class and determining the primary base; the compiler prepares for vptr generation. Here in create_vtable_ptr , the argument virtuals_p comes from local variable virtuals in finish_struct_1 ; and argument t is the class itself. Note that TYPE_VFIELD (t) is not empty if its primary base contains vptr (it is set in set_primary_base ). So as along as the type can get TYPE_VFIELD from its primary base, no vptr will be created for it.

FOR loop at line 4238 is very important for building vtable, it copies out all virtual functions declared by the type into another list of virtual_p ; and note the assignment at line 4245, BV_DELTA of the function copied is set as 0 (BV_DELTA indicates the number of bytes by which to substract from the `this' pointer when calling this virtual function [so we get ‘this’ pointer of the base declares the virtual method]).

DECL_VINDEX is used for FUNCTION_DECL in two different ways. Before the struct containing the FUNCTION_DECL is laid out, DECL_VINDEX may point to a FUNCTION_DECL in a base class which is the FUNCTION_DECL which this FUNCTION_DECL will replace as a virtual function. When the class is laid out, this pointer is changed to an INTEGER_CST node which is suitable for use as an index into the virtual function table. Then for FUNCTION_DECLs of unlaid out class, they are recorded by tree_list referred by virtual_p .

 

4232   static tree

4233   create_vtable_ptr (tree t, tree* virtuals_p)                                                         in class.c

4234   {

4235     tree fn;

4236  

4237     /* Collect the virtual functions declared in T.  */

4238     for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn))

4239       if (DECL_VINDEX (fn) && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn)

4240          && TREE_CODE (DECL_VINDEX (fn)) != INTEGER_CST)

4241       {

4242         tree new_virtual = make_node (TREE_LIST);

4243       

4244         BV_FN (new_virtual) = fn;

4245         BV_DELTA (new_virtual) = integer_zero_node;

4246  

4247         TREE_CHAIN (new_virtual) = *virtuals_p;

4248         *virtuals_p = new_virtual;

4249       }

4250    

4251     /* If we couldn't find an appropriate base class, create a new field

4252       here. Even if there weren't any new virtual functions, we might need a

4253       new virtual function table if we're supposed to include vptrs in

4254       all classes that need them.  */

4255     if (!TYPE_VFIELD (t) && (*virtuals_p || TYPE_CONTAINS_VPTR_P (t)))

4256     {

4257       /* We build this decl with vtbl_ptr_type_node, which is a

4258         `vtable_entry_type*'. It might seem more precise to use

4259         `vtable_entry_type (*)[N]' where N is the number of firtual

4260         functions. However, that would require the vtable pointer in

4261         base classes to have a different type than the vtable pointer

4262         i n derived classes. We could make that happen, but that

4263         still wouldn't solve all the problems. In particular, the

4264         type-based alias analysis code would decide that assignments

4265         to the base class vtable pointer can't alias assignments to

4266         the derived class vtable pointer, since they have different

4267         types. Thus, in a derived class destructor, where the base

4268         class constructor was inlined, we could generate bad code for

4269         setting up the vtable pointer. 

4270  

4271         Therefore, we use one type for all vtable pointers. We still

4272         use a type-correct type; it's just doesn't indicate the array

4273         bounds. That's better than using `void*' or some such; it's

4274         cleaner, and it let's the alias analysis code know that these

4275         stores cannot alias stores to void*!  */

4276       tree field;

4277  

4278       field = build_decl (FIELD_DECL, get_vfield_name (t), vtbl_ptr_type_node );

4279       SET_DECL_ASSEMBLER_NAME (field, get_identifier (VFIELD_BASE));

4280       DECL_VIRTUAL_P (field) = 1;

4281       DECL_ARTIFICIAL (field) = 1;

4282       DECL_FIELD_CONTEXT (field) = t;

4283       DECL_FCONTEXT (field) = t;

4284        

4285       TYPE_VFIELD (t) = field;

4286        

4287       /* This class is non-empty.  */

4288       CLASSTYPE_EMPTY_P (t) = 0;

4289  

4290       if (CLASSTYPE_N_BASECLASSES (t))

4291         /* If there were any baseclasses, they can't possibly be at

4292           offset zero any more, because that's where the vtable

4293           pointer is. So, converting to a base class is going to

4294           take work.  */

4295         TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (t) = 1;

4296  

4297       return field;

4298     }

4299  

4300     return NULL_TREE;

4301   }

 

If the primary base contains no vtable (or the class has not primary base at all) but the derived contains virtual methods itself, then the compiler generates the vtable here. VFIELD_BASE at line 4279 is string “$vf”. And at line 4295, if the class has bases, the compiler will need to generate conversion operator for converting the class between its bases. At line 4278 vtbl_ptr_type_node is initialized in cxx_init_decl_processing as vtable_entry_type *, which in turn is of type int(*)().

See line 4673 in layout_class_type , if there is a new generated vtable, place_field is invoked to lay out this vtable within the class first.

 

layout_class_type (continue)

 

4678     /* Build FIELD_DECLs for all of the non-virtual base-types.  */

4679     empty_base_offsets = splay_tree_new (splay_tree_compare_integer_csts,

4680                                     NULL, NULL);

4681     build_base_fields (rli, empty_base_offsets, next_field);

 

Then for other parts, a splaying tree – empty_base_offsets is created as help to hold the offset of empty bases laid out in the procedure. With this splaying tree for argument offsets , build_base_fields begins layout bases of the class.

 

3729   static void

3730   build_base_fields (record_layout_info rli,                                                    in class.c

3731                   splay_tree offsets, tree *next_field)

3732   {

3733     /* Chain to hold all the new FIELD_DECLs which stand in for base class

3734       subobjects.  */

3735     tree t = rli->t;

3736     int n_baseclasses = CLASSTYPE_N_BASECLASSES (t);

3737     int i;

3738  

3739     /* The primary base class is always allocated first.  */

3740     if (CLASSTYPE_HAS_PRIMARY_BASE_P (t))

3741       next_field = build_base_field (rli, CLASSTYPE_PRIMARY_BINFO (t),

3742                                 offsets, next_field);

3743  

3744     /* Now allocate the rest of the bases.  */

3745     for (i = 0; i < n_baseclasses; ++i)

3746     {

3747       tree base_binfo;

3748  

3749       base_binfo = BINFO_BASETYPE (TYPE_BINFO (t), i);

3750  

3751       /* The primary base was already allocated above, so we don't

3752         need to allocate it again here.  */

3753       if (base_binfo == CLASSTYPE_PRIMARY_BINFO (t))

3754         continue ;

3755  

3756       /* Virtual bases are added at the end (a primary virtual base

3757         will have already been added).  */

3758       if (TREE_VIA_VIRTUAL (base_binfo))

3759         continue ;

3760  

3761       next_field = build_base_field (rli, base_binfo,

3762                                 offsets, next_field);

3763     }

3764   }

 

See, primary base is laid the first (no matter whether it is virtual base or not) – that is why it is called primary. Then other bases are handled in their inheritance order. Note condition at line 3758, see that non-primary virtual base are not laid out here, but later by layout_virtual_bases .

Next the compiler generates fields for the bases, so as to access the derived in unified way.

 

3628   static tree *

3629   build_base_field (record_layout_info rli, tree binfo,                                     in class.c

3630                  splay_tree offsets, tree *next_field)

3631   {

3632     tree t = rli->t;

3633     tree basetype = BINFO_TYPE (binfo);

3634  

3635     if (!COMPLETE_TYPE_P (basetype))

3636       /* This error is now reported in xref_tag, thus giving better

3637         location information.  */

3638       return next_field;

3639    

3640     /* Place the base class.  */

3641     if (!is_empty_class (basetype))

3642     {

3643       tree decl;

3644  

3645       /* The containing class is non-empty because it has a non-empty

3646         base class.  */

3647       CLASSTYPE_EMPTY_P (t) = 0;

3648        

3649       /* Create the FIELD_DECL.  */

3650       decl = build_decl (FIELD_DECL, NULL_TREE, CLASSTYPE_AS_BASE (basetype));

3651       DECL_ARTIFICIAL (decl) = 1;

3652       DECL_FIELD_CONTEXT (decl) = t;

3653       DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype);

3654       DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype);

3655       DECL_ALIGN (decl) = CLASSTYPE_ALIGN (basetype);

3656       DECL_USER_ALIGN (decl) = CLASSTYPE_USER_ALIGN (basetype);

3657       DECL_IGNORED_P (decl) = 1;

3658  

3659        /* Try to place the field. It may take more than one try if we

3660         have a hard time placing the field without putting two

3661         objects of the same type at the same address.  */

3662       layout_nonempty_base_or_field (rli, decl, binfo, offsets);

3663       /* Add the new FIELD_DECL to the list of fields for T.  */

3664       TREE_CHAIN (decl) = *next_field;

3665       *next_field = decl;

3666       next_field = &TREE_CHAIN (decl);

3667     }

 

CLASSTYPE_AS_BASE at line 3650 gives the type in which basetype is used as a base class (we will see what type it is in later in layout_class_type ). Those base representing fields, like other normal fields, should be laid out within derived.

 

3461   static void

3462   layout_nonempty_base_or_field (record_layout_info rli,                              in class.c

3463                               tree decl,

3464                              tree binfo,

3465                              splay_tree offsets)

3466   {

3467     tree offset = NULL_TREE;

3468     bool field_p;    

3469     tree type;

3470    

3471     if (binfo)

3472     {

3473       /* For the purposes of determining layout conflicts, we want to

3474         use the class type of BINFO; TREE_TYPE (DECL) will be the

3475         CLASSTYPE_AS_BASE version, which does not contain entries for

3476         zero-sized bases.  */

3477       type = TREE_TYPE (binfo);

3478       field_p = false;

3479     }

3480     else

3481     {

3482       type = TREE_TYPE (decl);

3483       field_p = true;

3484     }

3485  

3486     /* Try to place the field. It may take more than one try if we have

3487       a hard time placing the field without putting two objects of the

3488       same type at the same address.  */

3489     while (1)

3490     {

3491       struct record_layout_info_s old_rli = *rli;

3492  

3493       /* Place this field.  */

3494       place_field (rli, decl);

3495       offset = byte_position (decl);

3496  

3497       /* We have to check to see whether or not there is already

3498         something of the same type at the offset we're about to use.

3499         For example, consider:

3500       

3501          struct S {};

3502          struct T : public S { int i; };

3503          struct U : public S, public T {};

3504       

3505         Here, we put S at offset zero in U. Then, we can't put T at

3506         offset zero -- its S component would be at the same address

3507         as the S we already allocated. So, we have to skip ahead.

3508         Since all data members, including those whose type is an

3509         empty class, have nonzero size, any overlap can happen only

3510         with a direct or indirect base-class -- it can't happen with

3511         a data member.  */

3512       /* In a union, overlap is permitted; all members are placed at

3513         offset zero.  */

3514       if (TREE_CODE (rli->t) == UNION_TYPE)

3515         break ;

3516        /* G++ 3.2 did not check for overlaps when placing a non-empty

3517         virtual base.  */

3518       if (!abi_version_at_least (2) && binfo && TREE_VIA_VIRTUAL (binfo))

3519         break ;

3520       if (layout_conflict_p (field_p ? type : binfo, offset,

3521                         offsets, field_p))

3522       {

3523         /* Strip off the size allocated to this field. That puts us

3524           at the first place we could have put the field with

3525           proper alignment.  */

3526        *rli = old_rli;

3527  

3528         /* Bump up by the alignment required for the type.  */

3529         rli->bitpos

3530            = size_binop (PLUS_EXPR, rli->bitpos,

3531                        bitsize_int (binfo

3532                                   ? CLASSTYPE_ALIGN (type)

3533                                  : TYPE_ALIGN (type)));

3534         normalize_rli (rli);

3535       }

3536       else

3537         /* There was no conflict. We're done laying out this field.  */

3538         break ;

3539     }

3540  

3541     /* Now that we know where it will be placed, update its

3542       BINFO_OFFSET.  */

3543     if (binfo && CLASS_TYPE_P (BINFO_TYPE (binfo)))

3544       /* Indirect virtual bases may have a nonzero BINFO_OFFSET at

3545          this point because their BINFO_OFFSET is copied from another

3546         hierarchy. Therefore, we may not need to add the entire

3547         OFFSET.  */

3548       propagate_binfo_offsets (binfo,

3549                             size_diffop (convert (ssizetype, offset),

3550                            convert (ssizetype,

3551                                   BINFO_OFFSET (binfo))));

3552   }

 

The detail of placing field is covered by previous section FIELD_DECL of RECORD_TYPE , it will fill with field handled with DECL_FIELD_OFFSET (offset in count of bytes) and DECL_FIELD_BIT_OFFSET (offset in count of bits), and updates bitpos field of rli at line 3530 to indicate the offset from the head of the class in bits (note that it not always equate to DECL_FIELD_BIT_OFFSET of the field just placed as there may be padding bytes).

 

1175   tree

1176   byte_position (tree field)                                                                                  in tree.c

1177   {

1178     return byte_from_pos (DECL_FIELD_OFFSET (field),

1179                        DECL_FIELD_BIT_OFFSET (field));

1180   }

 

In C++, during layout, empty base class may not occupy space. For example:

class A {}; sizeof (A) gives 1, but in following statement:

class B: public A { public : int temp; };

class C { public : int temp; }; sizeof (B) and sizeof (C) both give result of 4.

Thus if there is class D: public A, C {}; the empty class A takes no space, but base C can’t avoid overlapping upon A by taking the same offset as A. That is why above, before place the field, the old layout information should be cached first. And after placing the field, it needs to verifiy that the offset it laid in is not occupied by empty class by layout_conflict_p .

And similar consideration is taken during laying out the fields of the class (it is shown in layout_class_type , we will see it soon).

Besides, for class D: public A, C {}; sizeof (D) also gives 4. Empty base A occupies no space, base C shares the offset with A. But for class D {A a; C c}; sizeof (D) gives 8 instead. Empty class A and class C have their own space. The root cause is because, layout of bases first considers non-empty bases, then empty bases, and virtual bases at last; but layout of fields must following the order of declaration. To check if the new placed field conflicts with already laid out field, invoking layout_conflict_p .

 

3434   static int

3435   layout_conflict_p (tree type,                                                                      in class.c

3436                  tree offset,

3437                  splay_tree offsets,

3438                  int vbases_p)

3439   {

3440     splay_tree_node max_node;

3441  

3442     /* Get the node in OFFSETS that indicates the maximum offset where

3443       an empty subobject is located.  */

3444     max_node = splay_tree_max (offsets);

3445     /* If there aren't any empty subobjects, then there's no point in

3446       performing this check.  */

3447     if (!max_node)

3448       return 0;

3449  

3450     return walk_subobject_offsets (type, check_subobject_offset , offset,

3451                              offsets, (tree) (max_node->key),

3452                              vbases_p);

3453   }

 

We have to skip the detail of splay tree, at line 3444, splay_tree_max returns the max offset of empty bases already allocated. Then check_subobject_offset returns the offset allocated for the type if it is the already laid-out empty type.

We have to skip the detail of splay tree. Roughly, in this splay tree, its nodes are sorted by offset (which is saved in key filed). Class fields or bases having the same offset are chained in value field in the same tree node. At line 3444, splay_tree_max returns the max offset already occupied, which defines the range walk_subobject_offsets will verify. And check_subobject_offset , given specified offset, checks if same type has been already laid. If so, means confliction, returns 1.

 

3193   static int

3194   check_subobject_offset (tree type, tree offset, splay_tree offsets)                in class.c

3195   {

3196     splay_tree_node n;

3197     tree t;

3198  

3199     if (!is_empty_class (type))

3200       return 0;

3201  

3202     /* Record the location of this empty object in OFFSETS.  */

3203     n = splay_tree_lookup (offsets, (splay_tree_key) offset);

3204     if (!n)

3205       return 0;

3206  

3207     for (t = (tree) n->value; t; t = TREE_CHAIN (t))

3208       if (same_type_p (TREE_VALUE (t), type))

3209         return 1;

3210  

3211     return 0;

3212   }

 

Then walk_subobject_offsets steps into subobjects of type which contains empty type, till the offset exceeds max_offsets if it is not zero. And for every subobjects encountered applies operation f , till in certain invocation f returns nonzero value or offset exceeds max_offsets if it is nonzero, or exhausts the type. And argument vbase_p followed if is one, means virtual non-primary base should be traversed too.

At invoking walk_subobject_offsets , argument type can be binfo (base), or RECORD_TYPE (class field of class type), or built-in type. It is no difference in nature for these 3 cases. Note that at that time, the type object has been placed by place_fields before within the class.

 

3225   static int

3226   walk_subobject_offsets (tree type,                                                            in class.c

3227                       subobject_offset_fn f,

3228                       tree offset,

3229                       splay_tree offsets,

3230                       tree max_offset,

3231                       int vbases_p)

3232   {

3233     int r = 0;

3234     tree type_binfo = NULL_TREE;

3235  

3236     /* If this OFFSET is bigger than the MAX_OFFSET, then we should

3237       stop.  */

3238     if (max_offset && INT_CST_LT (max_offset, offset))

3239       return 0;

3240  

3241     if (!TYPE_P (type))

3242     {

3243       if (abi_version_at_least (2))

3244         type_binfo = type;

3245       type = BINFO_TYPE (type);

3246     }

3247  

3248     if (CLASS_TYPE_P (type))

3249     {

3250       tree field;

3251       tree binfo;

3252       int i;

3253  

3254       /* Avoid recursing into objects that are not interesting.  */

3255       if (!CLASSTYPE_CONTAINS_EMPTY_CLASS_P (type))

3256         return 0;

3257  

3258        /* Record the location of TYPE.  */

3259       r = (*f) (type, offset, offsets);

3260       if (r)

3261         return r;

3262  

3263       /* Iterate through the direct base classes of TYPE.  */

3264       if (!type_binfo)

3265          type_binfo = TYPE_BINFO (type);

3266       for (i = 0; i < BINFO_N_BASETYPES (type_binfo); ++i)

3267       {

3268         tree binfo_offset;

3269  

3270         binfo = BINFO_BASETYPE (type_binfo, i);

3271  

3272         if (abi_version_at_least (2)

3273              && TREE_VIA_VIRTUAL (binfo))

3274           continue ;

3275  

3276         if (!vbases_p

3277            && TREE_VIA_VIRTUAL (binfo)

3278            && !BINFO_PRIMARY_P (binfo))

3279           continue ;

3280  

3281         if (!abi_version_at_least (2))

3282           binfo_offset = size_binop (PLUS_EXPR,

3283                                 offset,

3284                                 BINFO_OFFSET (binfo));

3285         else

3286         {

3287           tree orig_binfo;

3288           /* We cannot rely on BINFO_OFFSET being set for the base

3289             class yet, but the offsets for direct non-virtual

3290             bases can be calculated by going back to the TYPE.  */

3291           orig_binfo = BINFO_BASETYPE (TYPE_BINFO (type), i);

3292           binfo_offset = size_binop (PLUS_EXPR,        

3293                                 offset,

3294                                 BINFO_OFFSET (orig_binfo));

3295         }

3296  

3297         r = walk_subobject_offsets (binfo,

3298                                 f,

3299                                binfo_offset,

3300                                offsets,

3301                                max_offset,

3302                                 (abi_version_at_least (2)

3303                                ? /*vbases_p=*/ 0 : vbases_p));

3304         if (r)

3305           return r;

3306       }

3307  

3308       if (abi_version_at_least (2))

3309       {

3310         tree vbase;

3311  

3312          /* Iterate through the virtual base classes of TYPE. In G++

3313           3.2, we included virtual bases in the direct base class

3314           loop above, which results in incorrect results; the

3315           correct offsets for virtual bases are only known when

3316           working with the most derived type.  */

3317         if (vbases_p)

3318            for (vbase = CLASSTYPE_VBASECLASSES (type);

3319               vbase;

3320               vbase = TREE_CHAIN (vbase))

3321           {

3322             binfo = TREE_VALUE (vbase);

3323             r = walk_subobject_offsets (binfo,

3324                                    f,

3325                                    size_binop (PLUS_EXPR,

3326                                              offset,

3327                                              BINFO_OFFSET (binfo)),

3328                                     offsets,

3329                                    max_offset,

3330                                    /*vbases_p=*/ 0);

3331             if (r)

3332               return r;

3333           }

3334         else

3335         {

3336           /* We still have to walk the primary base, if it is

3337             virtual. (If it is non-virtual, then it was walked

3338             above.)  */

3339           vbase = get_primary_binfo (type_binfo);

3340           if (vbase && TREE_VIA_VIRTUAL (vbase)

3341              && BINFO_PRIMARY_BASE_OF (vbase) == type_binfo)

3342           {

3343             r = (walk_subobject_offsets

3344                      (vbase, f, offset,

3345                        offsets, max_offset, /*vbases_p=*/ 0));

3346             if (r)

3347               return r;

3348           }

3349         }

3350       }

3351  

3352       /* Iterate through the fields of TYPE.  */

3353       for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))

3354         if (TREE_CODE (field) == FIELD_DECL && !DECL_ARTIFICIAL (field))

3355         {

3356           tree field_offset;

3357  

3358           if (abi_version_at_least (2))

3359             field_offset = byte_position (field);

3360           else

3361             /* In G++ 3.2, DECL_FIELD_OFFSET was used.  */

3362             field_offset = DECL_FIELD_OFFSET (field);

3363  

3364           r = walk_subobject_offsets (TREE_TYPE (field),

3365                                  f,

3366                                  size_binop (PLUS_EXPR,

3367                                            offset,

3368                                            field_offset),

3369                                  offsets,

3370                                  max_offset,

3371                                  /*vbases_p=*/ 1);

3372           if (r)

3373             return r;

3374         }

3375     }

3376     else if (TREE_CODE (type) == ARRAY_TYPE)

3377     {

3378       tree element_type = strip_array_types (type);

3379       tree domain = TYPE_DOMAIN (type);

3380       tree index;

3381  

3382       /* Avoid recursing into objects that are not interesting.  */

3383       if (!CLASS_TYPE_P (element_type)

3384           || !CLASSTYPE_CONTAINS_EMPTY_CLASS_P (element_type))

3385         return 0;

3386  

3387       /* Step through each of the elements in the array.  */

3388       for (index = size_zero_node;

3389            /* G++ 3.2 had an off-by-one error here.  */

3390            (abi_version_at_least (2)

3391                ? !INT_CST_LT (TYPE_MAX_VALUE (domain), index)

3392               : INT_CST_LT (index, TYPE_MAX_VALUE (domain)));

3393            index = size_binop (PLUS_EXPR, index, size_one_node))

3394       {

3395         r = walk_subobject_offsets (TREE_TYPE (type),

3396                                f,

3397                                offset,

3398                                offsets,

3399                                max_offset,

3400                                /*vbases_p=*/ 1);

3401         if (r)

3402           return r;

3403         offset = size_binop (PLUS_EXPR, offset,

3404                          TYPE_SIZE_UNIT (TREE_TYPE (type)));

3405         /* If this new OFFSET is bigger than the MAX_OFFSET, then

3406           there's no point in iterating through the remaining

3407           elements of the array.  */

3408         if (max_offset && INT_CST_LT (max_offset, offset))

3409           break ;

3410       }

3411     }

3412  

3413     return 0;

3414   }

 

Above abi_version_at_least (2) returns nonzero if G++ is no earlier than 3.4.0. Comment at line 3312 tells the difference between G++ later than 3.4.0 and its former. The offset of indirect base to the class should be calculated by plus offset in the type with BINFO_OFFSET set for the base. And this handling is similar for non-virtual base and fields.

Non-empty type won’t be considered, as they must occupy their own space. If the same empty type is found has been placed at the specified offset, layout_conflict_p returns 1, it will float up offset to the next boundary of the alignment for the base (for class type, it is usual 4 bytes aligment).

While in build_base_field , empty class has special treatment. Below rli_size_unit_so_far calculates the total size of obejcts/fields has been laid in closest bytes towards zero. So eoc is the offset that closest to the total size now used at the boundary of alignment.

 

build_base_field (continue)

 

3668     else

3669     {

3670       tree eoc;

3671       bool atend;

3672  

3673       /* On some platforms (ARM), even empty classes will not be

3674         byte-aligned.  */

3675       eoc = round_up (rli_size_unit_so_far (rli),

3676                     CLASSTYPE_ALIGN_UNIT (basetype));

3677       atend = layout_empty_base (binfo, eoc, offsets);

3678       /* A nearly-empty class "has no proper base class that is empty,

3679         not morally virtual, and at an offset other than zero."  */

3680       if (!TREE_VIA_VIRTUAL (binfo) && CLASSTYPE_NEARLY_EMPTY_P (t))

3681       {

3682         if (atend)

3683           CLASSTYPE_NEARLY_EMPTY_P (t) = 0;

3684         /* The check above (used in G++ 3.2) is insufficient because

3685           an empty class placed at offset zero might itself have an

3686           empty base at a nonzero offset.  */

3687         else if (walk_subobject_offsets (basetype,

3688                                   empty_base_at_nonzero_offset_p,

3689                                   size_zero_node,

3690                                    /*offsets=*/ NULL,

3691                                   /*max_offset=*/ NULL_TREE,

3692                                   /*vbases_p=*/ true))

3693         {

3694           if (abi_version_at_least (2))

3695              CLASSTYPE_NEARLY_EMPTY_P (t) = 0;

3696           else if (warn_abi )

3697             warning ("class `%T' will be considered nearly empty in a "

3698                     "future version of GCC", t);

3699         }

3700       }

3701       

3702       /* We do not create a FIELD_DECL for empty base classes because

3703         it might overlap some other field. We want to be able to

3704         create CONSTRUCTORs for the class by iterating over the

3705         FIELD_DECLs, and the back end does not handle overlapping

3706         FIELD_DECLs.  */

3707  

3708       /* An empty virtual base causes a class to be non-empty

3709         -- but in that case we do not need to clear CLASSTYPE_EMPTY_P

3710         here because that was already done when the virtual table

3711         pointer was created.  */

3712     }

3713  

3714     /* Record the offsets of BINFO and its base subobjects.  */

3715     record_subobject_offsets (binfo,

3716                          BINFO_OFFSET (binfo),

3717                           offsets,

3718                          /*vbases_p=*/ 0);

3719  

3720     return next_field;

3721   }

 

Empty base is most preferred be placed at offset of 0 (as they share space with the primary base). In G++ later that v.3.4, empty base will be first forced be placed at offset 0.

 

3570   static bool

3571   layout_empty_base (tree binfo, tree eoc, splay_tree offsets)                         in class.c

3572   {

3573     tree alignment;

3574     tree basetype = BINFO_TYPE (binfo);

3575     bool atend = false;

3576  

3577     /* This routine should only be used for empty classes.  */

3578     my_friendly_assert (is_empty_class (basetype), 20000321);

3579     alignment = ssize_int (CLASSTYPE_ALIGN_UNIT (basetype));

3580  

3581     if (!integer_zerop (BINFO_OFFSET (binfo)))

3582     {

3583       if (abi_version_at_least (2))

3584         propagate_binfo_offsets

3585               (binfo, size_diffop (size_zero_node, BINFO_OFFSET (binfo)));

3586       else if (warn_abi )

3587         warning ("offset of empty base `%T' may not be ABI-compliant and may"

3588                 "change in a future version of GCC",

3589                 BINFO_TYPE (binfo));

3590     }

3591    

3592     /* This is an empty base class. We first try to put it at offset

3593       zero.  */

3594     if (layout_conflict_p (binfo,

3595                       BINFO_OFFSET (binfo),

3596                       offsets,

3597                       /*vbases_p=*/ 0))

3598     {

3599       /* That didn't work. Now, we move forward from the next

3600         available spot in the class.  */

3601       atend = true;

3602       propagate_binfo_offsets (binfo, convert (ssizetype, eoc));

3603       while (1)

3604       {

3605         if (!layout_conflict_p (binfo,

3606                           BINFO_OFFSET (binfo),

3607                           offsets,

3608                           /*vbases_p=*/ 0))

3609           /* We finally found a spot where there's no overlap.  */

3610           break ;

3611  

3612         /* There's overlap here, too. Bump along to the next spot.  */

3613         propagate_binfo_offsets (binfo, alignment);

3614       }

3615     }

3616     return atend;

3617   }

 

If offset 0 has been already occupied by the same type, this empty base has to be placed at offset of eoc calculated above. If eoc is occupied too, floats up the offset by alignment and try again, till this empty base can be placed. And notice that if the empty class can’t be placed at offset 0, the function returns nonzero value, at which, even the class only contains empty bases, it should be considered as non-empty. However, if the empty base has been placed at position 0; it is not guarantee the class is nearly empty. Considering following example:

class A {};

class B: public A {};

class C: public A, B {};

Base B can be placed at position 0 in C, but can’t its base A, as C’s base A has been there already. C, according to above rule, should be non-empty class. empty_base_at_nonzero_offset_p checks if there is any empty base has non-zero offset.

Comment at line 3702 explains why no FIELD_DECL is created for this empty base. At last, after resolving the conflictions, it updates the offset into the splay tree by below function.

 

3420   static void

3421   record_subobject_offsets (tree type,                                                                in class.c

3422                        tree offset,

3423                        splay_tree offsets,

3424                        int vbases_p)

3425   {

3426     walk_subobject_offsets (type, record_subobject_offset , offset,

3427                         offsets, /*max_offset=*/ NULL_TREE, vbases_p);

3428   }

 

See that we only remember the offset of empty bases.

 

3168   static int

3169   record_subobject_offset (tree type, tree offset, splay_tree offsets)                      in class.c

3170   {

3171     splay_tree_node n;

3172  

3173     if (!is_empty_class (type))

3174       return 0;

3175  

3176     /* Record the location of this empty object in OFFSETS.  */

3177     n = splay_tree_lookup (offsets, (splay_tree_key) offset);

3178     if (!n)

3179       n = splay_tree_insert (offsets,

3180                         (splay_tree_key) offset,

3181                         (splay_tree_value) NULL_TREE);

3182     n->value = ((splay_tree_value)

3183                         tree_cons (NULL_TREE,

3184                                  type,

3185                                  (tree) n->value));

3186  

3187     return 0;

3188   }

 

After placing all bases, it is in turn of data member. Remember that for non-emtpy bases, their FIELD_DECLs are created and linked in TYPE_FIELDS chain before non_static_data_members , so below FOR loop will not visit these FIELD_DECLs again.

 

你可能感兴趣的:(Studying,note,of,GCC-3.4.6,source,tree,class,layout,conflict,alignment,integer)