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.
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.