Declarations#
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
Functions.
Working with declarations#
Some macros can be used with any kind of declaration. These include:
- DECL_NAME#
This macro returns an
IDENTIFIER_NODE
giving the name of the entity.
- TREE_TYPE#
This macro returns the type of the entity declared.
- 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"<internal>"
.
- EXPR_LINENO#
This macro returns the line number at which the entity was declared, as an
int
.
- 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:struct S {};
is roughly equivalent to C code like:
struct S {}; typedef struct S S;
The implicitly generated
typedef
declaration is represented by aTYPE_DECL
for whichDECL_ARTIFICIAL
holds.
The various kinds of declarations include:
- LABEL_DECL#
These nodes are used to represent labels in function bodies. For more information, see Functions. These nodes only appear in block scopes.
- CONST_DECL#
These nodes are used to represent enumeration constants. The value of the constant is given by
DECL_INITIAL
which will be anINTEGER_CST
with the same type as theTREE_TYPE
of theCONST_DECL
, i.e., anENUMERAL_TYPE
.
- 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 useDECL_SIZE
andDECL_ALIGN
on aRESULT_DECL
, just as with aVAR_DECL
.
- TYPE_DECL#
These nodes represent
typedef
declarations. TheTREE_TYPE
is the type declared to have the name given byDECL_NAME
. In some cases, there is no associated name.
- VAR_DECL#
These nodes represent variables with namespace or block scope, as well as static data members. The
DECL_SIZE
andDECL_ALIGN
are analogous toTYPE_SIZE
andTYPE_ALIGN
. For a declaration, you should always use theDECL_SIZE
andDECL_ALIGN
rather than theTYPE_SIZE
andTYPE_ALIGN
given by theTREE_TYPE
, since special attributes may have been applied to the variable to give it a particular size and alignment. You may use the predicatesDECL_THIS_STATIC
orDECL_THIS_EXTERN
to test whether the storage class specifiersstatic
orextern
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 theDECL_INITIAL
is theerror_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
ifDECL_REGISTER
holds for theVAR_DECL
, and ifDECL_ASSEMBLER_NAME
is not equal toDECL_NAME
. In that case,DECL_ASSEMBLER_NAME
is the name of the register into which the variable will be placed.
- PARM_DECL#
Used to represent a parameter to a function. Treat these nodes similarly to
VAR_DECL
nodes. These nodes only appear in theDECL_ARGUMENTS
for aFUNCTION_DECL
.The
DECL_ARG_TYPE
for aPARM_DECL
is the type that will actually be used when a value is passed to this function. It may be a wider type than theTREE_TYPE
of the parameter; for example, the ordinary type might beshort
while theDECL_ARG_TYPE
isint
.
- 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.
- FIELD_DECL#
These nodes represent non-static data members. The
DECL_SIZE
andDECL_ALIGN
behave as forVAR_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 theDECL_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, sinceDECL_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.
- NAMESPACE_DECL#
Namespaces provide a name hierarchy for other declarations. They appear in the
DECL_CONTEXT
of other_DECL
nodes.
Internal structure#
DECL
nodes are represented internally as a hierarchy of
structures.
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 mostDECL
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 representFIELD_DECL
.struct tree_label_decl
This structure inherits from
struct tree_decl_common
. It is used to representLABEL_DECL
.struct tree_translation_unit_decl
This structure inherits from
struct tree_decl_common
. It is used to representTRANSLATION_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 aDECL
node.struct tree_result_decl
This structure inherits from
struct tree_decl_with_rtl
. It is used to representRESULT_DECL
.struct tree_const_decl
This structure inherits from
struct tree_decl_with_rtl
. It is used to representCONST_DECL
.struct tree_parm_decl
This structure inherits from
struct tree_decl_with_rtl
. It is used to representPARM_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 representVAR_DECL
.struct tree_function_decl
This structure inherits from
struct tree_decl_with_vis
. It is used to representFUNCTION_DECL
.
Adding new DECL node types#
Adding a new DECL
tree consists of the following steps
Add a new tree code for the DECL node
For language specific
DECL
nodes, there is a.def
file in each frontend directory where the tree code should be added. ForDECL
nodes that are part of the middle-end, the code should be added totree.def
.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.
struct tree_foo_decl { struct tree_decl_with_vis common; }
Would create a structure name
tree_foo_decl
that inherits fromstruct tree_decl_with_vis
.For language specific
DECL
nodes, this new structure type should go in the appropriate.h
file. ForDECL
nodes that are part of the middle-end, the structure type should go intree.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 specificDECL
nodes, this new enumerator value should go in the appropriate.def
file. ForDECL
nodes that are part of the middle-end, the enumerator values are specified intreestruct.def
.Update union tree_node
In order to make your new structure type usable, it must be added to
union tree_node
. For language specificDECL
nodes, a new entry should be added to the appropriate.h
file of the formstruct 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 intounion tree_node
intree.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 certainDECL
node contains one of the enumeratedDECL
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 aninit_ts
function in an appropriate.c
file, which initializes the lookup table. Code setting up the table for newDECL
nodes should be added there. For eachDECL
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, aFOO_DECL
node derived fromstruct decl_with_rtl
, and enumerator valueTS_FOO_DECL
, would be set up as followstree_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 intotree.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
#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
#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
all-tree.def
file (which in turn includes all thetree.def
files),gencheck.cc
is used during GCC’s build to generate the*_CHECK
macros for all tree codes.