Studying note of GCC-3.4.6 source (13)

2.2.3.1.5.            Information of aggregate type
2.2.3.1.5.1.      Overview[2]

A class type is represented by either a RECORD_TYPE or a UNION_TYPE. A class declared with the union tag is represented by a UNION_TYPE, while classes declared with either the struct or the class tag are represented by RECORD_TYPEs. You can use the CLASSTYPE_DECLARED_CLASS macro to discern whether or not a particular type is a class as opposed to a struct. This macro will be true only for classes declared with the class tag.

Almost all non-function members are available on the TYPE_FIELDS list. Given one member, the next can be found by following the TREE_CHAIN. You should not depend in any way on the order in which fields appear on this list. All nodes on this list will be DECL nodes. A FIELD_DECL is used to represent a non-static data member, a VAR_DECL is used to represent a static data member, and a TYPE_DECL is used to represent a type. Note that the CONST_DECL for an enumeration constant will appear on this list, if the enumeration type was declared in the class. (Of course, the TYPE_DECL for the enumeration type will appear here as well.) There are no entries for base classes on this list. In particular, there is no FIELD_DECL for the "base-class portion" of an object (Note: in layout_class_type later, FIELD_DECL for the "base-class portion" of an object would be added by the compiler at the head of TYPE_FIELDS. But it happens in the last step as finishing the class).

The TYPE_VFIELD is a compiler-generated field used to point to virtual function tables. It may or may not appear on the TYPE_FIELDS list (Note: depends on whether the class needs it). However, back ends should handle the TYPE_VFIELD just like all the entries on the TYPE_FIELDS list.

The function members are available on the TYPE_METHODS list. Again, subsequent members are found by following the TREE_CHAIN field. If a function is overloaded, each of the overloaded functions appears; no OVERLOAD nodes (Note: represents the overloaded function) appear on the TYPE_METHODS list (Note: but on branches). Implicitly declared functions (including default constructors, copy constructors, assignment operators, and destructors) will appear on this list as well.

Every class has an associated "binfo", which can be obtained with TYPE_BINFO. Binfos are used to represent base-classes. The binfo given by TYPE_BINFO is the degenerate case, whereby every class is considered to be its own base-class. The base classes for a particular binfo can be obtained with BINFO_BASETYPES. These base-classes are themselves binfos. The class type associated with a binfo is given by BINFO_TYPE. It is always the case that BINFO_TYPE (TYPE_BINFO (x)) is the same type as x, up to qualifiers. However, it is not always the case that TYPE_BINFO (BINFO_TYPE (y)) is always the same binfo as y. The reason is that if y is a binfo representing a base-class B of a derived class D, then BINFO_TYPE (y) will be B, and TYPE_BINFO (BINFO_TYPE (y)) will be B as its own base-class, rather than as a base-class of D (Note: later, we can that see the binfo of B as base of D is a different object than that of B as base itself. Binfo can be thought as abbreviation of base information).

The BINFO_BASETYPES is a TREE_VEC. Base types appear in left-to-right order in this vector. You can tell whether or public, protected, or private inheritance was used by using the TREE_VIA_PUBLIC, TREE_VIA_PROTECTED, and TREE_VIA_PRIVATE macros. Each of these macros takes a BINFO and is true if and only if the indicated kind of inheritance was used. If TREE_VIA_VIRTUAL holds of a binfo, then its BINFO_TYPE (Note: the type corresponding to) was inherited from virtually.

The following macros can be used on a tree node representing a class-type.

LOCAL_CLASS_P: This predicate holds if the class is local class _i.e._ declared inside a function body.

TYPE_POLYMORPHIC_P: This predicate holds if the class has at least one virtual function (declared or inherited).

TYPE_HAS_DEFAULT_CONSTRUCTOR: This predicate holds whenever its argument represents a class-type with default constructor.

CLASSTYPE_HAS_MUTABLE, TYPE_HAS_MUTABLE_P: These predicates hold for a class-type having a mutable data member.

CLASSTYPE_NON_POD_P: This predicate holds only for class-types that are not PODs.

TYPE_HAS_NEW_OPERATOR: This predicate holds for a class-type that defines `operator new'.

TYPE_HAS_ARRAY_NEW_OPERATOR: This predicate holds for a class-type for which `operator new[]' is defined.

TYPE_OVERLOADS_CALL_EXPR: This predicate holds for class-type for which the function call `operator()' is overloaded.

TYPE_OVERLOADS_ARRAY_REF: This predicate holds for a class-type that overloads `operator[]'

TYPE_OVERLOADS_ARROW: This predicate holds for a class-type for which `operator->' is overloaded.

2.2.3.1.5.2.      layout of aggregate type

The aggregate types include following:

RECORD_TYPE [2]

²        Used to represent struct and class types, as well as pointers to member functions and similar constructs in other languages. TYPE_FIELDS contains the items contained in this type, each of which can be a FIELD_DECL, VAR_DECL, CONST_DECL, or TYPE_DECL. It may not make any assumptions about the ordering of the fields in the type or whether one or more of them overlap.

If TYPE_PTRMEMFUNC_P holds, then this type is a pointer-to-member type. In that case, TYPE_PTRMEMFUNC_FN_TYPE is a POINTER_TYPE pointing to a METHOD_TYPE. METHOD_TYPE is the type of a function pointed to by the pointer-to-member-function. If TYPE_PTRMEMFUNC_P does not hold, this type is a class type.

UNION_TYPE [2]

²        Used to represent union types. Similar to RECORD_TYPE except that all FIELD_DECL nodes in TYPE_FIELD start at bit position zero.

QUAL_UNION_TYPE [2]

²        Used to represent part of a variant record in Ada. Similar to UNION_TYPE except that each FIELD_DECL has a DECL_QUALIFIER field, which contains a boolean expression that indicates whether the field is present in the object. The type will only have one field, so each field's DECL_QUALIFIER is only evaluated if none of the expressions in the previous fields in TYPE_FIELDS are nonzero. Normally these expressions will reference a field in the outer object using a PLACEHOLDER_EXPR.

 

layout_type (continue)

 

1725     case RECORD_TYPE:

1726     case UNION_TYPE:

1727     case QUAL_UNION_TYPE:

1728     {

1729       tree field;

1730       record_layout_info rli;

1731

1732       /* Initialize the layout information.  */

1733       rli = start_record_layout (type);

1734

1735       /* If this is a QUAL_UNION_TYPE, we want to process the fields

1736         in the reverse order in building the COND_EXPR that denotes

1737         its size. We reverse them again later.  */

1738       if (TREE_CODE (type) == QUAL_UNION_TYPE)

1739         TYPE_FIELDS (type) = nreverse (TYPE_FIELDS (type));

1740

1741       /* Place all the fields.  */

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

1743         place_field (rli, field);

1744

1745       if (TREE_CODE (type) == QUAL_UNION_TYPE)

1746         TYPE_FIELDS (type) = nreverse (TYPE_FIELDS (type));

1747

1748       if (lang_adjust_rli)

1749         (*lang_adjust_rli) (rli);

1750

1751       /* Finish laying out the record.  */

1752       finish_record_layout (rli, /*free_p=*/true);

1753     }

1754     break;

 

Above is the code scrap the front-end will use to lay out aggregate types. It needs to point out that this code is just used by the front-end to lay out the artificial aggregate types created by it self. Those defined by used need much more complicate method to process (see layout_class_type at later).

2.2.3.1.5.2.1.              Struct to hold the information

For information of RECORD_TYPE/UNION_TYPE/QUAL_UNION_TYPE, we need a struct to save it. It is start_record_layout at below.

 

2332 typedef struct record_layout_info_s                                                             in tree.h

2333 {

2334   /* The RECORD_TYPE that we are laying out.  */

2335   tree t;

2336   /* The offset into the record so far, in bytes, not including bits in

2337     BITPOS.  */

2338   tree offset;

2339   /* The last known alignment of SIZE.  */

2340   unsigned int offset_align;

2341   /* The bit position within the last OFFSET_ALIGN bits, in bits.  */

2342   tree bitpos;

2343   /* The alignment of the record so far, in bits.  */

2344   unsigned int record_align;

2345   /* The alignment of the record so far, ignoring #pragma pack and

2346     __attribute__ ((packed)), in bits.  */

2347   unsigned int unpacked_align;

2348   /* The previous field layed out.  */

2349   tree prev_field;

2350   /* The static variables (i.e., class variables, as opposed to

2351     instance variables) encountered in T.  */

2352   tree pending_statics;

2353   /* Bits remaining in the current alignment group */

2354   int remaining_in_alignment;

2355   /* True if we've seen a packed field that didn't have normal

2356     alignment anyway.  */

2357   int packed_maybe_necessary;

2358 } *record_layout_info;

 

start_record_layout creates and initializes the record_layout_info. Below at line 564 STRUCTURE_SIZE_BOUNDARY is defined if the platform has alignment requirement for these kinds of type. For x86/Linux platform, the macro is undefined.

 

550  record_layout_info

551  start_record_layout (tree t)                                                                  in stor-layout.c

552  {

553    record_layout_info rli = xmalloc (sizeof (struct record_layout_info_s));

554 

555    rli->t = t;

556 

557    /* If the type has a minimum specified alignment (via an attribute

558      declaration, for example) use it -- otherwise, start with a

559      one-byte alignment.  */

560    rli->record_align = MAX (BITS_PER_UNIT, TYPE_ALIGN (t));

561    rli->unpacked_align = rli->record_align;

562    rli->offset_align = MAX (rli->record_align, BIGGEST_ALIGNMENT);

563 

564  #ifdef STRUCTURE_SIZE_BOUNDARY

565    /* Packed structures don't need to have minimum size.  */

566    if (!TYPE_PACKED (t))

567      rli->record_align = MAX (rli->record_align, (unsigned) STRUCTURE_SIZE_BOUNDARY);

568  #endif

569 

570    rli->offset = size_zero_node;

571    rli->bitpos = bitsize_zero_node;

572    rli->prev_field = 0;

573    rli->pending_statics = 0;

574    rli->packed_maybe_necessary = 0;

575 

576    return rli;

577  }

 

Also notice that at line 562, within layout having nonconstant size, offset_align records the alignment of the part laid out. At the beginning of layout, offset_align has the biggest alignment.

2.2.3.1.5.2.2.              Collecting information about fields

2.2.3.1.5.2.2.1.        Node of tree_decl

TYPE_FIELDS, at line 1742 in layout_type above, returns the chain of FIELD_DECLs for the fields of the struct. FIELD_DECL is object of tree_decl below.

 

1647 struct tree_decl GTY(())                                                                                    in tree.h

1648 {

1649   struct tree_common common;

1650   location_t locus;

1651   unsigned int uid;

1652   tree size;

1653   ENUM_BITFIELD(machine_mode) mode : 8;

1654

1655   unsigned external_flag : 1;

1656   unsigned nonlocal_flag : 1;

1657   unsigned regdecl_flag : 1;

1658   unsigned inline_flag : 1;

1659   unsigned bit_field_flag : 1;

1660   unsigned virtual_flag : 1;

1661   unsigned ignored_flag : 1;

1662   unsigned abstract_flag : 1;

1663

1664   unsigned in_system_header_flag : 1;

1665   unsigned common_flag : 1;

1666   unsigned defer_output : 1;

1667   unsigned transparent_union : 1;

1668   unsigned static_ctor_flag : 1;

1669   unsigned static_dtor_flag : 1;

1670   unsigned artificial_flag : 1;

1671   unsigned weak_flag : 1;

1672

1673   unsigned non_addr_const_p : 1;

1674   unsigned no_instrument_function_entry_exit : 1;

1675   unsigned comdat_flag : 1;

1676   unsigned malloc_flag : 1;

1677   unsigned no_limit_stack : 1;

1678   ENUM_BITFIELD (built_in_class) built_in_class : 2;

1679   unsigned pure_flag : 1;

1680

1681   unsigned non_addressable : 1;

1682   unsigned user_align : 1;

1683   unsigned uninlinable : 1;

1684   unsigned thread_local_flag : 1;

1685   unsigned declared_inline_flag : 1;

1686   ENUM_BITFIELD (symbol_visibility) visibility : 2;

1687   unsigned unused : 1;

1688   /* one unused bit.  */

1689

1690   unsigned lang_flag_0 : 1;

1691   unsigned lang_flag_1 : 1;

1692   unsigned lang_flag_2 : 1;

1693   unsigned lang_flag_3 : 1;

1694   unsigned lang_flag_4 : 1;

1695   unsigned lang_flag_5 : 1;

1696   unsigned lang_flag_6 : 1;

1697   unsigned lang_flag_7 : 1;

1698

1699   union tree_decl_u1 {

1700     /* In a FUNCTION_DECL for which DECL_BUILT_IN holds, this is

1701       DECL_FUNCTION_CODE.  */

1702     enum built_in_function f;

1703     /* In a FUNCTION_DECL for which DECL_BUILT_IN does not hold, this

1704       is used by language-dependent code.  */

1705     HOST_WIDE_INT i;

1706     /* DECL_ALIGN and DECL_OFFSET_ALIGN. (These are not used for

1707       FUNCTION_DECLs).  */

1708     struct tree_decl_u1_a {

1709       unsigned int align : 24;

1710       unsigned int off_align : 8;

1711     } a;

1712   } GTY ((skip (""))) u1;

1713

1714   tree size_unit;

1715   tree name;

1716   tree context;

1717   tree arguments; /* Also used for DECL_FIELD_OFFSET */

1718   tree result;        /* Also used for DECL_BIT_FIELD_TYPE */

1719   tree initial;       /* Also used for DECL_QUALIFIER */

1720   tree abstract_origin;

1721   tree assembler_name;

1722   tree section_name;

1723   tree attributes;

1724   rtx rtl;       /* RTL representation for object.  */

1725

1726   /* In FUNCTION_DECL, if it is inline, holds the saved insn chain.

1727     In FIELD_DECL, is DECL_FIELD_BIT_OFFSET.

1728     In PARM_DECL, holds an RTL for the stack slot

1729     of register where the data was actually passed.

1730     Used by Chill and Java in LABEL_DECL and by C++ and Java in VAR_DECL.  */

1731   union tree_decl_u2 {

1732     struct function * GTY ((tag ("FUNCTION_DECL"))) f;

1733     rtx GTY ((tag ("PARM_DECL"))) r;

1734     tree GTY ((tag ("FIELD_DECL"))) t;

1735     int GTY ((tag ("VAR_DECL"))) i;

1736   } GTY ((desc ("TREE_CODE((tree) &(%0))"))) u2;

1737

1738   /* In a FUNCTION_DECL, this is DECL_SAVED_TREE.  */

1739   tree saved_tree;

1740

1741   /* In a FUNCTION_DECL, these are function data which is to be kept

1742     as long as FUNCTION_DECL is kept.  */

1743   tree inlined_fns;

1744

1745   tree vindex;

1746   HOST_WIDE_INT pointer_alias_set;

1747   /* Points to a structure whose details depend on the language in use.  */

1748   struct lang_decl *lang_specific;

1749 };

 

In the same file, a serie macros beginning with DECL are defined to access fields of tree_decl (the red part is the definition). [2]

DECL_SECTION_NAME (DECL_CHECK (NODE)->decl.section_name): Records the section name in a section attribute (Note: GNU C++ allows using section attribute in declaration to specify the section the variable would be placed in object file). Used to pass the name from decl_attributes to make_function_rtl and make_decl_rtl.

DECL_CONTEXT (DECL_CHECK (NODE)->decl.context)

DECL_FIELD_CONTEXT (FIELD_DECL_CHECK (NODE)->decl.context) For FIELD_DECL, this is the RECORD_TYPE, UNION_TYPE, or QUAL_UNION_TYPE node that the field is a member of. For VAR_DECL, PARM_DECL, FUNCTION_DECL, LABEL_DECL, and CONST_DECL nodes, this points to either the FUNCTION_DECL for the containing function, the RECORD_TYPE or UNION_TYPE for the containing type, or NULL_TREE or a TRANSLATION_UNIT_DECL if the given decl has "file scope".

DECL_ATTRIBUTES (DECL_CHECK (NODE)->decl.attributes): In a DECL this is the field where attributes are stored.

DECL_FIELD_OFFSET (FIELD_DECL_CHECK (NODE)->decl.arguments): 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.

DECL_FIELD_BIT_OFFSET (FIELD_DECL_CHECK (NODE)->decl.u2.t) : In a FIELD_DECL, this is the offset, in bits, of the first bit of the field from DECL_FIELD_OFFSET.

DECL_BIT_FIELD_TYPE (FIELD_DECL_CHECK (NODE)->decl.result) : In a FIELD_DECL, this indicates whether the field was a bit-field and if so, the type that was originally specified for it. TREE_TYPE may have been modified (in finish_struct).

DECL_ARGUMENTS (DECL_CHECK (NODE)->decl.arguments) : In FUNCTION_DECL, a chain of . DECL nodes. VAR_DECL and PARM_DECL reserve the arguments slot for language-specific uses.

DECL_RESULT_FLD (DECL_CHECK (NODE)->decl.result) : In TEMPLATE_DECL, it is the associated TYPE_DECL. In a VAR_DECL for a variable declared in a for statement, this is the shadowed (local) variable.

DECL_RESULT (FUNCTION_DECL_CHECK (NODE)->decl.result) : In FUNCTION_DECL, holds the decl for the return value.

DECL_ORIGINAL_TYPE (TYPE_DECL_CHECK (NODE)->decl.result) : For a TYPE_DECL, holds the "original" type. (TREE_TYPE has the copy.)

DECL_ARG_TYPE_AS_WRITTEN (PARM_DECL_CHECK (NODE)->decl.result) : In PARM_DECL, holds the type as written (perhaps a function or array).

DECL_INITIAL (DECL_CHECK (NODE)->decl.initial) : For a FUNCTION_DECL, holds the tree of BINDINGs. For a TRANSLATION_UNIT_DECL, holds the namespace's BLOCK. For a VAR_DECL, holds the initial value. For a PARM_DECL, not used--default values for parameters are encoded in the type of the function, not in the PARM_DECL slot.

DECL_ARG_TYPE (PARM_DECL_CHECK (NODE)->decl.initial) : For a PARM_DECL, records the data type used to pass the argument, which may be different from the type seen in the program.

DECL_QUALIFIER (FIELD_DECL_CHECK (NODE)->decl.initial) : For a FIELD_DECL in a QUAL_UNION_TYPE, records the expression, which if nonzero, indicates that the field occupies the type.

DECL_SOURCE_LOCATION (DECL_CHECK (NODE)->decl.locus) : This field describes where in the source code the declaration was. If the declaration appears in several places (as for a C function that is declared first and then defined later), this information should refer to the definition.

DECL_SIZE (DECL_CHECK (NODE)->decl.size) : Holds the size of the datum, in bits, as a tree expression. Need not be constant.

DECL_SIZE_UNIT (DECL_CHECK (NODE)->decl.size_unit) : Likewise for the size in bytes.

DECL_ALIGN (DECL_CHECK (NODE)->decl.u1.a.align) : Holds the alignment required for the datum, in bits.

DECL_ALIGN_UNIT (DECL_ALIGN (NODE) / BITS_PER_UNIT) : The alignment of NODE, in bytes.

DECL_OFFSET_ALIGN

(((unsigned HOST_WIDE_INT)1) << FIELD_DECL_CHECK (NODE)->decl.u1.a.off_align) : For FIELD_DECLs, off_align holds the number of low-order bits of DECL_FIELD_OFFSET which are known to be always zero. DECL_OFFSET_ALIGN thus returns the alignment that DECL_FIELD_OFFSET has.

SET_DECL_OFFSET_ALIGN (FIELD_DECL_CHECK (NODE)->decl.u1.a.off_align = exact_log2 ((X) & -(X))) : Specify that DECL_ALIGN(NODE) is a multiple of X.

DECL_USER_ALIGN (DECL_CHECK (NODE)->decl.user_align) : 1 if the alignment for this type was requested by "aligned" attribute, 0 if it is the default for this type.

DECL_MODE (DECL_CHECK (NODE)->decl.mode) : Holds the machine mode corresponding to the declaration of a variable or field. Always equal to TYPE_MODE (TREE_TYPE (decl)) except for a FIELD_DECL.

DECL_RTL(DECL_CHECK (NODE)->decl.rtl                       /

   ? (NODE)->decl.rtl : (make_decl_rtl (NODE, NULL), (NODE)->decl.rtl)) : Holds the RTL expression for the value of a variable or function. This value can be evaluated lazily for functions, variables with static storage duration, and labels.

DECL_RTL_SET_P (DECL_CHECK (NODE)->decl.rtl != NULL) : Returns nonzero if the DECL_RTL for NODE has already been set.

COPY_DECL_RTL

(DECL_CHECK (NODE2)->decl.rtl = DECL_CHECK (NODE1)->decl.rtl) : Copy the RTL from NODE1 to NODE2. If the RTL was not set for NODE1, it will not be set for NODE2; this is a lazy copy.

DECL_INCOMING_RTL (PARM_DECL_CHECK (NODE)->decl.u2.r) : For PARM_DECL, holds an RTL for the stack slot or register where the data was actually passed.

DECL_SAVED_INSNS (FUNCTION_DECL_CHECK (NODE)->decl.u2.f) : For FUNCTION_DECL, if it is inline, holds the saved insn chain.

DECL_FUNCTION_CODE (FUNCTION_DECL_CHECK (NODE)->decl.u1.f) : For FUNCTION_DECL, if it is built-in, this identifies which built-in operation it is.

DECL_VINDEX (DECL_CHECK (NODE)->decl.vindex) : The DECL_VINDEX is used for FUNCTION_DECLS 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.

DECL_FCONTEXT (FIELD_DECL_CHECK (NODE)->decl.vindex) : For FIELD_DECLS, DECL_FCONTEXT is the *first* baseclass in which this FIELD_DECL is defined. This information is needed when writing debugging information about vfield and vbase decls for C++.

DECL_UID (DECL_CHECK (NODE)->decl.uid) : Every ..._DECL node gets a unique number.

DECL_ABSTRACT_ORIGIN (DECL_CHECK (NODE)->decl.abstract_origin) : For any sort of a ..._DECL node, this points to the original (abstract) decl node which this decl is an (inlined or template expanded) instance of, or else it is NULL indicating that this decl is not an instance of some other decl. For example, in a nested declaration of an inline function, this points back to the definition.

DECL_ORIGIN

(DECL_ABSTRACT_ORIGIN(NODE) ? DECL_ABSTRACT_ORIGIN(NODE) : (NODE)) : Like DECL_ABSTRACT_ORIGIN, but returns NODE if there's no abstract origin. This is useful when setting the DECL_ABSTRACT_ORIGIN.

DECL_FROM_INLINE (DECL_ABSTRACT_ORIGIN (NODE) != NULL_TREE /

&& DECL_ABSTRACT_ORIGIN (NODE) != (NODE)) : Nonzero for any sort of ..._DECL node means this decl node represents an inline instance of some original (abstract) decl from an inline function; suppress any warnings about shadowing some other variable. FUNCTION_DECL nodes can also have their abstract origin set to themselves.

DECL_IGNORED_P (DECL_CHECK (NODE)->decl.ignored_flag) : Nonzero if a _DECL means that the name of this decl should be ignored for symbolic debug purposes.

DECL_ABSTRACT (DECL_CHECK (NODE)->decl.abstract_flag) : Nonzero for a given ..._DECL node means that this node represents an "abstract instance" of the given declaration (e.g. in the original declaration of an inline function). When generating symbolic debugging information, we mustn't try to generate any address information for nodes marked as "abstract instances" because we don't actually generate any code or allocate any data space for such instances.

DECL_IN_SYSTEM_HEADER (DECL_CHECK (NODE)->decl.in_system_header_flag) : Nonzero if a _DECL means that no warnings should be generated just because this decl is unused.

DECL_COMMON (DECL_CHECK (NODE)->decl.common_flag) : Nonzero for a given DECL node means that this node should be put in .common, if possible. If a DECL_INITIAL is given, and it is not error_mark_node, then the decl cannot be put in .common.

DECL_LANG_SPECIFIC (DECL_CHECK (NODE)->decl.lang_specific) : Language-specific decl information.

DECL_EXTERNAL (DECL_CHECK (NODE)->decl.external_flag) : In a VAR_DECL or FUNCTION_DECL, nonzero means external reference: do not allocate storage, and refer to a definition elsewhere.

TYPE_DECL_SUPPRESS_DEBUG (TYPE_DECL_CHECK (NODE)->decl.external_flag) : In a TYPE_DECL nonzero means the detail info about this type is not dumped into stabs. Instead it will generate cross reference ('x') of names. This uses the same flag as DECL_EXTERNAL.

DECL_REGISTER (DECL_CHECK (NODE)->decl.regdecl_flag) : In VAR_DECL and PARM_DECL nodes, nonzero means declared `register'.

DECL_PACKED (FIELD_DECL_CHECK (NODE)->decl.regdecl_flag) : In a FIELD_DECL, indicates this field should be bit-packed.

DECL_NO_STATIC_CHAIN (FUNCTION_DECL_CHECK (NODE)->decl.regdecl_flag) : In a FUNCTION_DECL with a nonzero DECL_CONTEXT, indicates that a static chain is not needed.

DECL_INLINE (FUNCTION_DECL_CHECK (NODE)->decl.inline_flag) : Nonzero in a FUNCTION_DECL means this function can be substituted where it is called.

DECL_DECLARED_INLINE_P (FUNCTION_DECL_CHECK (NODE)->decl.declared_inline_flag) : Nonzero in a FUNCTION_DECL means that this function was declared inline, such as via the `inline' keyword in C/C++. This flag controls the linkage semantics of 'inline'; whether or not the function is inlined is controlled by DECL_INLINE.

DECL_VISIBILITY (DECL_CHECK (NODE)->decl.visibility) : Value of the decls's visibility attribute

DECL_UNINLINABLE (FUNCTION_DECL_CHECK (NODE)->decl.uninlinable) : In a FUNCTION_DECL, nonzero if the function cannot be inlined.

DECL_THREAD_LOCAL (VAR_DECL_CHECK (NODE)->decl.thread_local_flag) : In a VAR_DECL, nonzero if the data should be allocated from thread-local storage

DECL_SAVED_TREE (FUNCTION_DECL_CHECK (NODE)->decl.saved_tree) : In a FUNCTION_DECL, the saved representation of the body of the entire function. Usually a COMPOUND_STMT, but in C++ this may also be a RETURN_INIT, CTOR_INITIALIZER, or TRY_BLOCK.

DECL_INLINED_FNS (FUNCTION_DECL_CHECK (NODE)->decl.inlined_fns) : List of FUNCTION_DECLs inlined into this function's body.

DECL_IS_MALLOC (FUNCTION_DECL_CHECK (NODE)->decl.malloc_flag) : Nonzero in a FUNCTION_DECL means this function should be treated as if it were a malloc, meaning it returns a pointer that is not an alias (Note: refer to later chapter about alias or from wikipedia).

DECL_IS_PURE (FUNCTION_DECL_CHECK (NODE)->decl.pure_flag) : Nonzero in a FUNCTION_DECL means this function should be treated as "pure" function (like const function, but may read global memory).

DECL_BIT_FIELD (FIELD_DECL_CHECK (NODE)->decl.bit_field_flag) : Nonzero in a FIELD_DECL means it is a bit field, and must be accessed specially.

DECL_IN_TEXT_SECTION (VAR_DECL_CHECK (NODE)->decl.bit_field_flag) : In a VAR_DECL that's static, nonzero if the space is in the text section.

DECL_BUILT_IN (DECL_BUILT_IN_CLASS (NODE) != NOT_BUILT_IN) : In a FUNCTION_DECL, nonzero means a built in function.

DECL_BUILT_IN_CLASS (FUNCTION_DECL_CHECK (NODE)->decl.built_in_class) : For a builtin function, identify which part of the compiler defined it.

DECL_VIRTUAL_P (DECL_CHECK (NODE)->decl.virtual_flag) : Used in VAR_DECLs to indicate that the variable is a vtable. Used in FIELD_DECLs for vtable pointers. Used in FUNCTION_DECLs to indicate that the function is virtual.

DECL_DEFER_OUTPUT (DECL_CHECK (NODE)->decl.defer_output) : Used to indicate that the linkage status of this DECL is not yet known, so it should not be output now.

DECL_TRANSPARENT_UNION (PARM_DECL_CHECK (NODE)->decl.transparent_union) : Used in PARM_DECLs whose type are unions to indicate that the argument should be passed in the same way that the first union alternative would be passed.

DECL_STATIC_CONSTRUCTOR

(FUNCTION_DECL_CHECK (NODE)->decl.static_ctor_flag) :

DECL_STATIC_DESTRUCTOR

(FUNCTION_DECL_CHECK (NODE)->decl.static_dtor_flag) : Used in FUNCTION_DECLs to indicate that they should be run automatically at the beginning or end of execution.

DECL_ARTIFICIAL (DECL_CHECK (NODE)->decl.artificial_flag) : Used to indicate that this DECL represents a compiler-generated entity.

DECL_WEAK (DECL_CHECK (NODE)->decl.weak_flag) : Used to indicate that this DECL has weak linkage.

DECL_ONE_ONLY (DECL_CHECK (NODE)->decl.transparent_union) : Used in TREE_PUBLIC decls to indicate that copies of this DECL in multiple translation units should be merged.

DECL_COMDAT (DECL_CHECK (NODE)->decl.comdat_flag) : Used in a DECL to indicate that, even if it TREE_PUBLIC, it need not be put out unless it is needed in this translation unit. Entities like this are shared across translation units (like weak entities), but are guaranteed to be generated by any translation unit that needs them, and therefore need not be put out anywhere where they are not needed. DECL_COMDAT is just a hint to the back-end; it is up to front-ends which set this flag to ensure that there will never be any harm, other than bloat, in putting out something which is DECL_COMDAT.

DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT

(FUNCTION_DECL_CHECK (NODE)->decl.no_instrument_function_entry_exit) : Used in FUNCTION_DECLs to indicate that function entry and exit should be instrumented with calls to support routines.

DECL_NO_LIMIT_STACK (FUNCTION_DECL_CHECK (NODE)->decl.no_limit_stack) : Used in FUNCTION_DECLs to indicate that limit-stack-* should be disabled in this function.

DECL_NON_ADDR_CONST_P (DECL_CHECK (NODE)->decl.non_addr_const_p) : Used to indicate that the pointer to this DECL cannot be treated as an address constant.

DECL_NONADDRESSABLE_P

(FIELD_DECL_CHECK (NODE)->decl.non_addressable) :Used in a FIELD_DECL to indicate that we cannot form the address of this component.

DECL_POINTER_ALIAS_SET (DECL_CHECK (NODE)->decl.pointer_alias_set) : Used to indicate an alias set for the memory pointed to by this particular FIELD_DECL, PARM_DECL, or VAR_DECL, which must have pointer (or reference) type.

DECL_POINTER_ALIAS_SET_KNOWN_P (DECL_POINTER_ALIAS_SET (NODE) != - 1) : Nonzero if an alias set has been assigned to this declaration.

DECL_FILE_SCOPE_P (! DECL_CONTEXT (EXP)                                          /

   || TREE_CODE (DECL_CONTEXT (EXP)) == TRANSLATION_UNIT_DECL) : Nonzero for a decl which is at file scope.

 

List 3: Macros for TREE_DECL

2.2.3.1.5.2.2.2.        Fields layout

Also note that at line 1742 in layout_type, the declarations in one binding context are chained through the TREE_CHAIN field. So parameter field in place_field points to those declarations in ordering.

 

821  void

822  place_field (record_layout_info rli, tree field)                                       in stor-layout.c

823  {

824    /* The alignment required for FIELD.  */

825    unsigned int desired_align;

826    /* The alignment FIELD would have if we just dropped it into the

827       record as it presently stands.  */

828    unsigned int known_align;

829    unsigned int actual_align;

830    /* The type of this field.  */

831    tree type = TREE_TYPE (field);

832 

833    if (TREE_CODE (field) == ERROR_MARK || TREE_CODE (type) == ERROR_MARK)

834      return;

835 

836   /* If FIELD is static, then treat it like a separate variable, not

837      really like a structure field. If it is a FUNCTION_DECL, it's a

838      method. In both cases, all we do is lay out the decl, and we do

839      it *after* the record is laid out.  */

840    if (TREE_CODE (field) == VAR_DECL)

841    {

842      rli->pending_statics = tree_cons (NULL_TREE, field,

843                                     rli->pending_statics);

844      return;

845    }

2.2.3.1.5.2.2.3.        Type of VAR_DECL

As we have seen, VAR_DECL represents static data member of class, and the detail is given in following

VAR_DECL[2]

²        These nodes represent variables with namespace or block scope, as well as static data members. The DECL_SIZE and DECL_ALIGN are analogous to TYPE_SIZE and TYPE_ALIGN. For a declaration, you should always use the DECL_SIZE and DECL_ALIGN rather than the TYPE_SIZE and TYPE_ALIGN given by the TREE_TYPE, since special attributes may have been applied to the variable to give it a particular size and alignment. You may use the predicates DECL_THIS_STATIC or DECL_THIS_EXTERN to test whether the storage class specifiers static or extern were used to declare a variable.

If this variable is initialized (but does not require a constructor), the DECL_INITIAL will be an expression for the initializer. The initializer should be evaluated, and a bitwise copy into the variable performed. If the DECL_INITIAL is the error_mark_node, there is an initializer, but it is given by an explicit statement later in the code; no bitwise copy is required.

GCC provides an extension that allows either automatic variables, or global variables, to be placed in particular registers. This extension is being used for a particular VAR_DECL if DECL_REGISTER holds for the VAR_DECL, and if DECL_ASSEMBLER_NAME is not equal to DECL_NAME. In that case, DECL_ASSEMBLER_NAME is the name of the register into which the variable will be placed.

At line 842, tree_cons will create a tree_list, and chains this object into pending_statics field of rli. The objects linked into pending_statics will get handled at the last step of class layout. The reason is because such object may refer to the class (for example, singleton).

 

1039 tree

1040 tree_cons (tree purpose, tree value, tree chain)                                                    in tree.c

1041 {

1042   tree node;

1043

1044   node = ggc_alloc_tree (sizeof (struct tree_list));

1045

1046   memset (node, 0, sizeof (struct tree_common));

1047

1048 #ifdef GATHER_STATISTICS

1049   tree_node_counts[(int) x_kind]++;

1050   tree_node_sizes[(int) x_kind] += sizeof (struct tree_list);

1051 #endif

1052

1053   TREE_SET_CODE (node, TREE_LIST);

1054   TREE_CHAIN (node) = chain;

1055   TREE_PURPOSE (node) = purpose;

1056   TREE_VALUE (node) = value;

1057   return node;

1058 }

 

tree_list has the TREE_VALUE and TREE_PURPOSE fields. Nodes of tree_list are made into lists by chaining through the TREE_CHAIN field in tree_common. The elements of the list live in the TREE_VALUE fields, while TREE_PURPOSE fields are occasionally used as well to get the effect of Lisp association lists.

 

767  struct tree_list GTY(())                                                                                      in tree.h

768  {

769    struct tree_common common;

770    tree purpose;

771    tree value;

772  };

2.2.3.1.5.2.2.4.        Type of CONST_DECL, TYPE_DECL

In a class definition, only VAR_DECL, FIELD_DECL, CONST_DECL and TYPE_DECL will be present, so condition at line 842 below filters out CONST_DECL and TYPE_DECL. The detail about CONST_DECL and TYPE_DECL are given in following

CONST_DECL[2]

²        These nodes are used to represent enumeration constants. The value of the constant is given by DECL_INITIAL which will be an INTEGER_CST with the same type as the TREE_TYPE of the CONST_DECL, i.e., an ENUMERAL_TYPE.

TYPE_DECL[2]

²        These nodes represent typedef declarations. The TREE_TYPE is the type declared to have the name given by DECL_NAME. In some cases, there is no associated name.

 

place_field (continue)

 

847    /* Enumerators and enum types which are local to this class need not

848      be laid out. Likewise for initialized constant fields.  */

849    else if (TREE_CODE (field) != FIELD_DECL)

850      return;

851 

852    /* Unions are laid out very differently than records, so split

853      that code off to another function.  */

854    else if (TREE_CODE (rli->t) != RECORD_TYPE)

855    {

856      place_union_field (rli, field);

857      return;

858    }

 

As we have learnt, in C/C++, constant variable will be saved into bss section which will not occupy space of class instance.Tegother with typedef declaration, they needn’t be handled in place_field.

 

你可能感兴趣的:(Studying note of GCC-3.4.6 source (13))