.. Copyright 1988-2022 Free Software Foundation, Inc. This is part of the GCC manual. For copying conditions, see the copyright.rst file. .. index:: declaration, variable, type declaration .. _declarations: Declarations ************ .. index:: LABEL_DECL, CONST_DECL, TYPE_DECL, VAR_DECL, PARM_DECL, DEBUG_EXPR_DECL, FIELD_DECL, NAMESPACE_DECL, RESULT_DECL, TEMPLATE_DECL, THUNK_DECL, THUNK_DELTA, DECL_INITIAL, DECL_SIZE, DECL_ALIGN, DECL_EXTERNAL This section covers the various kinds of declarations that appear in the internal representation, except for declarations of functions (represented by ``FUNCTION_DECL`` nodes), which are described in :ref:`functions`. .. toctree:: :maxdepth: 2 .. _working-with-declarations: Working with declarations ^^^^^^^^^^^^^^^^^^^^^^^^^ Some macros can be used with any kind of declaration. These include: .. envvar:: DECL_NAME This macro returns an ``IDENTIFIER_NODE`` giving the name of the entity. .. envvar:: TREE_TYPE This macro returns the type of the entity declared. .. envvar:: EXPR_FILENAME This macro returns the name of the file in which the entity was declared, as a ``char*``. For an entity declared implicitly by the compiler (like ``__builtin_memcpy``), this will be the string ``""``. .. envvar:: EXPR_LINENO This macro returns the line number at which the entity was declared, as an ``int``. .. envvar:: DECL_ARTIFICIAL This predicate holds if the declaration was implicitly generated by the compiler. For example, this predicate will hold of an implicitly declared member function, or of the ``TYPE_DECL`` implicitly generated for a class type. Recall that in C++ code like: .. code-block:: c++ struct S {}; is roughly equivalent to C code like: .. code-block:: c++ struct S {}; typedef struct S S; The implicitly generated ``typedef`` declaration is represented by a ``TYPE_DECL`` for which ``DECL_ARTIFICIAL`` holds. The various kinds of declarations include: .. envvar:: LABEL_DECL These nodes are used to represent labels in function bodies. For more information, see :ref:`functions`. These nodes only appear in block scopes. .. envvar:: CONST_DECL 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``. .. envvar:: RESULT_DECL These nodes represent the value returned by a function. When a value is assigned to a ``RESULT_DECL``, that indicates that the value should be returned, via bitwise copy, by the function. You can use ``DECL_SIZE`` and ``DECL_ALIGN`` on a ``RESULT_DECL``, just as with a ``VAR_DECL``. .. envvar:: TYPE_DECL 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. .. envvar:: VAR_DECL 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. .. envvar:: PARM_DECL Used to represent a parameter to a function. Treat these nodes similarly to ``VAR_DECL`` nodes. These nodes only appear in the ``DECL_ARGUMENTS`` for a ``FUNCTION_DECL``. The ``DECL_ARG_TYPE`` for a ``PARM_DECL`` is the type that will actually be used when a value is passed to this function. It may be a wider type than the ``TREE_TYPE`` of the parameter; for example, the ordinary type might be ``short`` while the ``DECL_ARG_TYPE`` is ``int``. .. envvar:: DEBUG_EXPR_DECL Used to represent an anonymous debug-information temporary created to hold an expression as it is optimized away, so that its value can be referenced in debug bind statements. .. envvar:: FIELD_DECL These nodes represent non-static data members. The ``DECL_SIZE`` and ``DECL_ALIGN`` behave as for ``VAR_DECL`` nodes. The position of the field within the parent record is specified by a combination of three attributes. ``DECL_FIELD_OFFSET`` is the position, counting in bytes, of the ``DECL_OFFSET_ALIGN`` -bit sized word containing the bit of the field closest to the beginning of the structure. ``DECL_FIELD_BIT_OFFSET`` is the bit offset of the first bit of the field within this word; this may be nonzero even for fields that are not bit-fields, since ``DECL_OFFSET_ALIGN`` may be greater than the natural alignment of the field's type. If ``DECL_C_BIT_FIELD`` holds, this field is a bit-field. In a bit-field, ``DECL_BIT_FIELD_TYPE`` also contains the type that was originally specified for it, while DECL_TYPE may be a modified type with lesser precision, according to the size of the bit field. .. envvar:: NAMESPACE_DECL Namespaces provide a name hierarchy for other declarations. They appear in the ``DECL_CONTEXT`` of other ``_DECL`` nodes. .. _internal-structure: Internal structure ^^^^^^^^^^^^^^^^^^ ``DECL`` nodes are represented internally as a hierarchy of structures. .. toctree:: :maxdepth: 2 .. _current-structure-hierarchy: Current structure hierarchy ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``struct tree_decl_minimal`` This is the minimal structure to inherit from in order for common ``DECL`` macros to work. The fields it contains are a unique ID, source location, context, and name. ``struct tree_decl_common`` This structure inherits from ``struct tree_decl_minimal``. It contains fields that most ``DECL`` nodes need, such as a field to store alignment, machine mode, size, and attributes. ``struct tree_field_decl`` This structure inherits from ``struct tree_decl_common``. It is used to represent ``FIELD_DECL``. ``struct tree_label_decl`` This structure inherits from ``struct tree_decl_common``. It is used to represent ``LABEL_DECL``. ``struct tree_translation_unit_decl`` This structure inherits from ``struct tree_decl_common``. It is used to represent ``TRANSLATION_UNIT_DECL``. ``struct tree_decl_with_rtl`` This structure inherits from ``struct tree_decl_common``. It contains a field to store the low-level RTL associated with a ``DECL`` node. ``struct tree_result_decl`` This structure inherits from ``struct tree_decl_with_rtl``. It is used to represent ``RESULT_DECL``. ``struct tree_const_decl`` This structure inherits from ``struct tree_decl_with_rtl``. It is used to represent ``CONST_DECL``. ``struct tree_parm_decl`` This structure inherits from ``struct tree_decl_with_rtl``. It is used to represent ``PARM_DECL``. ``struct tree_decl_with_vis`` This structure inherits from ``struct tree_decl_with_rtl``. It contains fields necessary to store visibility information, as well as a section name and assembler name. ``struct tree_var_decl`` This structure inherits from ``struct tree_decl_with_vis``. It is used to represent ``VAR_DECL``. ``struct tree_function_decl`` This structure inherits from ``struct tree_decl_with_vis``. It is used to represent ``FUNCTION_DECL``. .. _adding-new-decl-node-types: Adding new DECL node types ~~~~~~~~~~~~~~~~~~~~~~~~~~ Adding a new ``DECL`` tree consists of the following steps :samp:`Add a new tree code for the {DECL} node` For language specific ``DECL`` nodes, there is a :samp:`.def` file in each frontend directory where the tree code should be added. For ``DECL`` nodes that are part of the middle-end, the code should be added to :samp:`tree.def`. :samp:`Create a new structure type for the {DECL} node` These structures should inherit from one of the existing structures in the language hierarchy by using that structure as the first member. .. code-block:: c++ struct tree_foo_decl { struct tree_decl_with_vis common; } Would create a structure name ``tree_foo_decl`` that inherits from ``struct tree_decl_with_vis``. For language specific ``DECL`` nodes, this new structure type should go in the appropriate :samp:`.h` file. For ``DECL`` nodes that are part of the middle-end, the structure type should go in :samp:`tree.h`. Add a member to the tree structure enumerator for the node For garbage collection and dynamic checking purposes, each ``DECL`` node structure type is required to have a unique enumerator value specified with it. For language specific ``DECL`` nodes, this new enumerator value should go in the appropriate :samp:`.def` file. For ``DECL`` nodes that are part of the middle-end, the enumerator values are specified in :samp:`treestruct.def`. :samp:`Update {union tree_node}` In order to make your new structure type usable, it must be added to ``union tree_node``. For language specific ``DECL`` nodes, a new entry should be added to the appropriate :samp:`.h` file of the form .. code-block:: c++ struct tree_foo_decl GTY ((tag ("TS_VAR_DECL"))) foo_decl; For ``DECL`` nodes that are part of the middle-end, the additional member goes directly into ``union tree_node`` in :samp:`tree.h`. Update dynamic checking info In order to be able to check whether accessing a named portion of ``union tree_node`` is legal, and whether a certain ``DECL`` node contains one of the enumerated ``DECL`` node structures in the hierarchy, a simple lookup table is used. This lookup table needs to be kept up to date with the tree structure hierarchy, or else checking and containment macros will fail inappropriately. For language specific ``DECL`` nodes, there is an ``init_ts`` function in an appropriate :samp:`.c` file, which initializes the lookup table. Code setting up the table for new ``DECL`` nodes should be added there. For each ``DECL`` tree code and enumerator value representing a member of the inheritance hierarchy, the table should contain 1 if that tree code inherits (directly or indirectly) from that member. Thus, a ``FOO_DECL`` node derived from ``struct decl_with_rtl``, and enumerator value ``TS_FOO_DECL``, would be set up as follows .. code-block:: c++ tree_contains_struct[FOO_DECL][TS_FOO_DECL] = 1; tree_contains_struct[FOO_DECL][TS_DECL_WRTL] = 1; tree_contains_struct[FOO_DECL][TS_DECL_COMMON] = 1; tree_contains_struct[FOO_DECL][TS_DECL_MINIMAL] = 1; For ``DECL`` nodes that are part of the middle-end, the setup code goes into :samp:`tree.cc`. Add macros to access any new fields and flags Each added field or flag should have a macro that is used to access it, that performs appropriate checking to ensure only the right type of ``DECL`` nodes access the field. These macros generally take the following form .. code-block:: c++ #define FOO_DECL_FIELDNAME(NODE) FOO_DECL_CHECK(NODE)->foo_decl.fieldname However, if the structure is simply a base class for further structures, something like the following should be used .. code-block:: c++ #define BASE_STRUCT_CHECK(T) CONTAINS_STRUCT_CHECK(T, TS_BASE_STRUCT) #define BASE_STRUCT_FIELDNAME(NODE) \ (BASE_STRUCT_CHECK(NODE)->base_struct.fieldname Reading them from the generated :samp:`all-tree.def` file (which in turn includes all the :samp:`tree.def` files), :samp:`gencheck.cc` is used during GCC's build to generate the ``*_CHECK`` macros for all tree codes.