C and C++ Trees#
This section documents the internal representation used by GCC to represent C and C++ source programs. When presented with a C or C++ source program, GCC parses the program, performs semantic analysis (including the generation of error messages), and then produces the internal representation described here. This representation contains a complete representation for the entire translation unit provided as input to the front end. This representation is then typically processed by a code-generator in order to produce machine code, but could also be used in the creation of source browsers, intelligent editors, automatic documentation generators, interpreters, and any other programs needing the ability to process C or C++ code.
This section explains the internal representation. In particular, it documents the internal representation for C and C++ source constructs, and the macros, functions, and variables that can be used to access these constructs. The C++ representation is largely a superset of the representation used in the C front end. There is only one construct used in C that does not appear in the C++ front end and that is the GNU ‘nested function’ extension. Many of the macros documented here do not apply in C because the corresponding language constructs do not appear in C.
The C and C++ front ends generate a mix of GENERIC trees and ones specific to C and C++. These language-specific trees are higher-level constructs than the ones in GENERIC to make the parser’s job easier. This section describes those trees that aren’t part of GENERIC as well as aspects of GENERIC trees that are treated in a language-specific manner.
If you are developing a ‘back end’, be it is a code-generator or some other tool, that uses this representation, you may occasionally find that you need to ask questions not easily answered by the functions and macros available here. If that situation occurs, it is quite likely that GCC already supports the functionality you desire, but that the interface is simply not documented here. In that case, you should ask the GCC maintainers (via mail to gcc@gcc.gnu.org) about documenting the functionality you require. Similarly, if you find yourself writing functions that do not deal directly with your back end, but instead might be useful to other people using the GCC front end, you should submit your patches for inclusion in GCC.
Types for C++#
In C++, an array type is not qualified; rather the type of the array
elements is qualified. This situation is reflected in the intermediate
representation. The macros described here will always examine the
qualification of the underlying element type when applied to an array
type. (If the element type is itself an array, then the recursion
continues until a non-array type is found, and the qualification of this
type is examined.) So, for example, CP_TYPE_CONST_P will hold of
the type const int ()[7], denoting an array of seven int s.
The following functions and macros deal with cv-qualification of types:
cp_type_qualsThis function returns the set of type qualifiers applied to this type. This value is
TYPE_UNQUALIFIEDif no qualifiers have been applied. TheTYPE_QUAL_CONSTbit is set if the type isconst-qualified. TheTYPE_QUAL_VOLATILEbit is set if the type isvolatile-qualified. TheTYPE_QUAL_RESTRICTbit is set if the type isrestrict-qualified.
- CP_TYPE_CONST_P#
This macro holds if the type is
const-qualified.
- CP_TYPE_VOLATILE_P#
This macro holds if the type is
volatile-qualified.
- CP_TYPE_RESTRICT_P#
This macro holds if the type is
restrict-qualified.
- CP_TYPE_CONST_NON_VOLATILE_P#
This predicate holds for a type that is
const-qualified, but notvolatile-qualified; other cv-qualifiers are ignored as well: only theconst-ness is tested.
A few other macros and functions are usable with all types:
- TYPE_SIZE#
The number of bits required to represent the type, represented as an
INTEGER_CST. For an incomplete type,TYPE_SIZEwill beNULL_TREE.
- TYPE_ALIGN#
The alignment of the type, in bits, represented as an
int.
- TYPE_NAME#
This macro returns a declaration (in the form of a
TYPE_DECL) for the type. (Note this macro does not return anIDENTIFIER_NODE, as you might expect, given its name!) You can look at theDECL_NAMEof theTYPE_DECLto obtain the actual name of the type. TheTYPE_NAMEwill beNULL_TREEfor a type that is not a built-in type, the result of a typedef, or a named class type.
- CP_INTEGRAL_TYPE#
This predicate holds if the type is an integral type. Notice that in C++, enumerations are not integral types.
- ARITHMETIC_TYPE_P#
This predicate holds if the type is an integral type (in the C++ sense) or a floating point type.
- CLASS_TYPE_P#
This predicate holds for a class-type.
- TYPE_BUILT_IN#
This predicate holds for a built-in type.
- TYPE_PTRDATAMEM_P#
This predicate holds if the type is a pointer to data member.
- TYPE_PTR_P#
This predicate holds if the type is a pointer type, and the pointee is not a data member.
- TYPE_PTRFN_P#
This predicate holds for a pointer to function type.
- TYPE_PTROB_P#
This predicate holds for a pointer to object type. Note however that it does not hold for the generic pointer to object type
void *. You may useTYPE_PTROBV_Pto test for a pointer to object type as well asvoid *.
The table below describes types specific to C and C++ as well as language-dependent info about GENERIC types.
- POINTER_TYPE#
Used to represent pointer types, and pointer to data member types. If
TREE_TYPEis a pointer to data member type, thenTYPE_PTRDATAMEM_Pwill hold. For a pointer to data member type of the formT X::*,TYPE_PTRMEM_CLASS_TYPEwill be the typeX, whileTYPE_PTRMEM_POINTED_TO_TYPEwill be the typeT.
- RECORD_TYPE#
Used to represent
structandclasstypes in C and C++. IfTYPE_PTRMEMFUNC_Pholds, then this type is a pointer-to-member type. In that case, theTYPE_PTRMEMFUNC_FN_TYPEis aPOINTER_TYPEpointing to aMETHOD_TYPE. TheMETHOD_TYPEis the type of a function pointed to by the pointer-to-member function. IfTYPE_PTRMEMFUNC_Pdoes not hold, this type is a class type. For more information, see Classes.
- UNKNOWN_TYPE#
This node is used to represent a type the knowledge of which is insufficient for a sound processing.
- TYPENAME_TYPE#
Used to represent a construct of the form
typename T::A. TheTYPE_CONTEXTisT; theTYPE_NAMEis anIDENTIFIER_NODEforA. If the type is specified via a template-id, thenTYPENAME_TYPE_FULLNAMEyields aTEMPLATE_ID_EXPR. TheTREE_TYPEis non-NULLif the node is implicitly generated in support for the implicit typename extension; in which case theTREE_TYPEis a type node for the base-class.
- TYPEOF_TYPE#
Used to represent the
__typeof__extension. TheTYPE_FIELDSis the expression the type of which is being represented.
Namespaces#
The root of the entire intermediate representation is the variable
global_namespace. This is the namespace specified with ::
in C++ source code. All other namespaces, types, variables, functions,
and so forth can be found starting with this namespace.
However, except for the fact that it is distinguished as the root of the representation, the global namespace is no different from any other namespace. Thus, in what follows, we describe namespaces generally, rather than the global namespace in particular.
A namespace is represented by a NAMESPACE_DECL node.
The following macros and functions can be used on a NAMESPACE_DECL :
- DECL_NAME#
This macro is used to obtain the
IDENTIFIER_NODEcorresponding to the unqualified name of the name of the namespace (see Identifiers). The name of the global namespace is::, even though in C++ the global namespace is unnamed. However, you should use comparison withglobal_namespace, rather thanDECL_NAMEto determine whether or not a namespace is the global one. An unnamed namespace will have aDECL_NAMEequal toanonymous_namespace_name. Within a single translation unit, all unnamed namespaces will have the same name.
- DECL_CONTEXT#
This macro returns the enclosing namespace. The
DECL_CONTEXTfor theglobal_namespaceisNULL_TREE.
- DECL_NAMESPACE_ALIAS#
If this declaration is for a namespace alias, then
DECL_NAMESPACE_ALIASis the namespace for which this one is an alias.Do not attempt to use
cp_namespace_declsfor a namespace which is an alias. Instead, followDECL_NAMESPACE_ALIASlinks until you reach an ordinary, non-alias, namespace, and callcp_namespace_declsthere.
- DECL_NAMESPACE_STD_P#
This predicate holds if the namespace is the special
::stdnamespace.
cp_namespace_declsThis function will return the declarations contained in the namespace, including types, overloaded functions, other namespaces, and so forth. If there are no declarations, this function will return
NULL_TREE. The declarations are connected through theirTREE_CHAINfields.Although most entries on this list will be declarations,
TREE_LISTnodes may also appear. In this case, theTREE_VALUEwill be anOVERLOAD. The value of theTREE_PURPOSEis unspecified; back ends should ignore this value. As with the other kinds of declarations returned bycp_namespace_decls, theTREE_CHAINwill point to the next declaration in this list.For more information on the kinds of declarations that can occur on this list, See Declarations. Some declarations will not appear on this list. In particular, no
FIELD_DECL,LABEL_DECL, orPARM_DECLnodes will appear here.This function cannot be used with namespaces that have
DECL_NAMESPACE_ALIASset.
Classes#
Besides namespaces, the other high-level scoping construct in C++ is the
class. (Throughout this manual the term class is used to mean the
types referred to in the ANSI/ISO C++ Standard as classes; these include
types defined with the class, struct, and union
keywords.)
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_TYPE s. 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 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. If a function member is overloaded, each of the overloaded
functions appears; no OVERLOAD nodes appear on the TYPE_FIELDS
list. Implicitly declared functions (including default constructors,
copy constructors, assignment operators, and destructors) will appear on
this list as well.
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. However, back ends should handle the
TYPE_VFIELD just like all the entries on the TYPE_FIELDS
list.
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 binfos for a
particular binfo are held in a vector, whose length is obtained with
BINFO_N_BASE_BINFOS. The base binfos themselves are obtained
with BINFO_BASE_BINFO and BINFO_BASE_ITERATE. To add a
new binfo, use BINFO_BASE_APPEND. The vector of base binfos can
be obtained with BINFO_BASE_BINFOS, but normally you do not need
to use that. The class type associated with a binfo is given by
BINFO_TYPE. It is not always the case that BINFO_TYPE
(TYPE_BINFO (x)), because of typedefs and qualified types. Neither is
it the case that TYPE_BINFO (BINFO_TYPE (y)) is 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.
The access to a base type can be found with BINFO_BASE_ACCESS.
This will produce access_public_node, access_private_node
or access_protected_node. If bases are always public,
BINFO_BASE_ACCESSES may be NULL.
BINFO_VIRTUAL_P is used to specify whether the binfo is inherited
virtually or not. The other flags, BINFO_FLAG_0 to
BINFO_FLAG_6, can be used for language specific use.
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#
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.
Functions for C++#
A function is represented by a FUNCTION_DECL node. A set of
overloaded functions is sometimes represented by an OVERLOAD node.
An OVERLOAD node is not a declaration, so none of the
DECL_ macros should be used on an OVERLOAD. An
OVERLOAD node is similar to a TREE_LIST. Use
OVL_CURRENT to get the function associated with an
OVERLOAD node; use OVL_NEXT to get the next
OVERLOAD node in the list of overloaded functions. The macros
OVL_CURRENT and OVL_NEXT are actually polymorphic; you can
use them to work with FUNCTION_DECL nodes as well as with
overloads. In the case of a FUNCTION_DECL, OVL_CURRENT
will always return the function itself, and OVL_NEXT will always
be NULL_TREE.
To determine the scope of a function, you can use the
DECL_CONTEXT macro. This macro will return the class
(either a RECORD_TYPE or a UNION_TYPE) or namespace (a
NAMESPACE_DECL) of which the function is a member. For a virtual
function, this macro returns the class in which the function was
actually defined, not the base class in which the virtual declaration
occurred.
If a friend function is defined in a class scope, the
DECL_FRIEND_CONTEXT macro can be used to determine the class in
which it was defined. For example, in
class C { friend void f() {} };
the DECL_CONTEXT for f will be the
global_namespace, but the DECL_FRIEND_CONTEXT will be the
RECORD_TYPE for C.
The following macros and functions can be used on a FUNCTION_DECL :
- DECL_MAIN_P#
This predicate holds for a function that is the program entry point
::code.
- DECL_LOCAL_FUNCTION_P#
This predicate holds if the function was declared at block scope, even though it has a global scope.
- DECL_ANTICIPATED#
This predicate holds if the function is a built-in function but its prototype is not yet explicitly declared.
- DECL_EXTERN_C_FUNCTION_P#
This predicate holds if the function is declared as an ‘
extern "C"‘ function.
- DECL_LINKONCE_P#
This macro holds if multiple copies of this function may be emitted in various translation units. It is the responsibility of the linker to merge the various copies. Template instantiations are the most common example of functions for which
DECL_LINKONCE_Pholds; G++ instantiates needed templates in all translation units which require them, and then relies on the linker to remove duplicate instantiations.Todo
This macro is not yet implemented.
- DECL_FUNCTION_MEMBER_P#
This macro holds if the function is a member of a class, rather than a member of a namespace.
- DECL_STATIC_FUNCTION_P#
This predicate holds if the function a static member function.
- DECL_NONSTATIC_MEMBER_FUNCTION_P#
This macro holds for a non-static member function.
- DECL_CONST_MEMFUNC_P#
This predicate holds for a
const-member function.
- DECL_VOLATILE_MEMFUNC_P#
This predicate holds for a
volatile-member function.
- DECL_CONSTRUCTOR_P#
This macro holds if the function is a constructor.
- DECL_NONCONVERTING_P#
This predicate holds if the constructor is a non-converting constructor.
- DECL_COMPLETE_CONSTRUCTOR_P#
This predicate holds for a function which is a constructor for an object of a complete type.
- DECL_BASE_CONSTRUCTOR_P#
This predicate holds for a function which is a constructor for a base class sub-object.
- DECL_COPY_CONSTRUCTOR_P#
This predicate holds for a function which is a copy-constructor.
- DECL_DESTRUCTOR_P#
This macro holds if the function is a destructor.
- DECL_COMPLETE_DESTRUCTOR_P#
This predicate holds if the function is the destructor for an object a complete type.
- DECL_OVERLOADED_OPERATOR_P#
This macro holds if the function is an overloaded operator.
- DECL_CONV_FN_P#
This macro holds if the function is a type-conversion operator.
- DECL_GLOBAL_CTOR_P#
This predicate holds if the function is a file-scope initialization function.
- DECL_GLOBAL_DTOR_P#
This predicate holds if the function is a file-scope finalization function.
- DECL_THUNK_P#
This predicate holds if the function is a thunk.
These functions represent stub code that adjusts the
thispointer and then jumps to another function. When the jumped-to function returns, control is transferred directly to the caller, without returning to the thunk. The first parameter to the thunk is always thethispointer; the thunk should addTHUNK_DELTAto this value. (TheTHUNK_DELTAis anint, not anINTEGER_CST.)Then, if
THUNK_VCALL_OFFSET(anINTEGER_CST) is nonzero the adjustedthispointer must be adjusted again. The complete calculation is given by the following pseudo-code:this += THUNK_DELTA if (THUNK_VCALL_OFFSET) this += (*((ptrdiff_t **) this))[THUNK_VCALL_OFFSET]
Finally, the thunk should jump to the location given by
DECL_INITIAL; this will always be an expression for the address of a function.
- DECL_NON_THUNK_FUNCTION_P#
This predicate holds if the function is not a thunk function.
- GLOBAL_INIT_PRIORITY#
If either
DECL_GLOBAL_CTOR_PorDECL_GLOBAL_DTOR_Pholds, then this gives the initialization priority for the function. The linker will arrange that all functions for whichDECL_GLOBAL_CTOR_Pholds are run in increasing order of priority beforemainis called. When the program exits, all functions for whichDECL_GLOBAL_DTOR_Pholds are run in the reverse order.
- TYPE_RAISES_EXCEPTIONS#
This macro returns the list of exceptions that a (member-)function can raise. The returned list, if non
NULL, is comprised of nodes whoseTREE_VALUErepresents a type.
- TYPE_NOTHROW_P#
This predicate holds when the exception-specification of its arguments is of the form ‘
()‘.
- DECL_ARRAY_DELETE_OPERATOR_P#
This predicate holds if the function an overloaded
operator delete[].
Statements for C and C++#
A function that has a definition in the current translation unit has
a non- NULL DECL_INITIAL. However, back ends should not make
use of the particular value given by DECL_INITIAL.
The DECL_SAVED_TREE gives the complete body of the
function.
There are tree nodes corresponding to all of the source-level statement constructs, used within the C and C++ frontends. These are enumerated here, together with a list of the various macros that can be used to obtain information about them. There are a few macros that can be used with all statements:
- STMT_IS_FULL_EXPR_P#
In C++, statements normally constitute ‘full expressions’; temporaries created during a statement are destroyed when the statement is complete. However, G++ sometimes represents expressions by statements; these statements will not have
STMT_IS_FULL_EXPR_Pset. Temporaries created during such statements should be destroyed when the innermost enclosing statement withSTMT_IS_FULL_EXPR_Pset is exited.
Here is the list of the various statement nodes, and the macros used to access them. This documentation describes the use of these nodes in non-template functions (including instantiations of template functions). In template functions, the same nodes are used, but sometimes in slightly different ways.
Many of the statements have substatements. For example, a while
loop has a body, which is itself a statement. If the substatement
is NULL_TREE, it is considered equivalent to a statement
consisting of a single ;, i.e., an expression statement in which
the expression has been omitted. A substatement may in fact be a list
of statements, connected via their TREE_CHAIN s. So, you should
always process the statement tree by looping over substatements, like
this:
void process_stmt (stmt)
tree stmt;
{
while (stmt)
{
switch (TREE_CODE (stmt))
{
case IF_STMT:
process_stmt (THEN_CLAUSE (stmt));
/* More processing here. */
break;
...
}
stmt = TREE_CHAIN (stmt);
}
}
In other words, while the then clause of an if statement
in C++ can be only one statement (although that one statement may be a
compound statement), the intermediate representation sometimes uses
several statements chained together.
- BREAK_STMT#
Used to represent a
breakstatement. There are no additional fields.
- CLEANUP_STMT#
Used to represent an action that should take place upon exit from the enclosing scope. Typically, these actions are calls to destructors for local objects, but back ends cannot rely on this fact. If these nodes are in fact representing such destructors,
CLEANUP_DECLwill be theVAR_DECLdestroyed. Otherwise,CLEANUP_DECLwill beNULL_TREE. In any case, theCLEANUP_EXPRis the expression to execute. The cleanups executed on exit from a scope should be run in the reverse order of the order in which the associatedCLEANUP_STMTs were encountered.
- CONTINUE_STMT#
Used to represent a
continuestatement. There are no additional fields.
- CTOR_STMT#
Used to mark the beginning (if
CTOR_BEGIN_Pholds) or end (ifCTOR_END_Pholds of the main body of a constructor. See alsoSUBOBJECTfor more information on how to use these nodes.
- DO_STMT#
Used to represent a
doloop. The body of the loop is given byDO_BODYwhile the termination condition for the loop is given byDO_COND. The condition for ado-statement is always an expression.
- EMPTY_CLASS_EXPR#
Used to represent a temporary object of a class with no data whose address is never taken. (All such objects are interchangeable.) The
TREE_TYPErepresents the type of the object.
- EXPR_STMT#
Used to represent an expression statement. Use
EXPR_STMT_EXPRto obtain the expression.
- FOR_STMT#
Used to represent a
forstatement. TheFOR_INIT_STMTis the initialization statement for the loop. TheFOR_CONDis the termination condition. TheFOR_EXPRis the expression executed right before theFOR_CONDon each loop iteration; often, this expression increments a counter. The body of the loop is given byFOR_BODY.FOR_SCOPEholds the scope of theforstatement (used in the C++ front end only). Note thatFOR_INIT_STMTandFOR_BODYreturn statements, whileFOR_CONDandFOR_EXPRreturn expressions.
- HANDLER#
Used to represent a C++
catchblock. TheHANDLER_TYPEis the type of exception that will be caught by this handler; it is equal (by pointer equality) toNULLif this handler is for all types.HANDLER_PARMSis theDECL_STMTfor the catch parameter, andHANDLER_BODYis the code for the block itself.
- IF_STMT#
Used to represent an
ifstatement. TheIF_CONDis the expression.If the condition is a
TREE_LIST, then theTREE_PURPOSEis a statement (usually aDECL_STMT). Each time the condition is evaluated, the statement should be executed. Then, theTREE_VALUEshould be used as the conditional expression itself. This representation is used to handle C++ code like this:if (int i = 7) ...
where there is a new local variable (or variables) declared within the condition.
The
THEN_CLAUSErepresents the statement given by thethencondition, while theELSE_CLAUSErepresents the statement given by theelsecondition.C++ distinguishes between this and
COND_EXPRfor handling templates.
- SUBOBJECT#
In a constructor, these nodes are used to mark the point at which a subobject of
thisis fully constructed. If, after this point, an exception is thrown before aCTOR_STMTwithCTOR_END_Pset is encountered, theSUBOBJECT_CLEANUPmust be executed. The cleanups must be executed in the reverse order in which they appear.
- SWITCH_STMT#
Used to represent a
switchstatement. TheSWITCH_STMT_CONDis the expression on which the switch is occurring. See the documentation for anIF_STMTfor more information on the representation used for the condition. TheSWITCH_STMT_BODYis the body of the switch statement. TheSWITCH_STMT_TYPEis the original type of switch expression as given in the source, before any compiler conversions. TheSWITCH_STMT_SCOPEis the statement scope (used in the C++ front end only).There are also two boolean flags used with
SWITCH_STMT.SWITCH_STMT_ALL_CASES_Pis true if the switch includes a default label or the case label ranges cover all possible values of the condition expression.SWITCH_STMT_NO_BREAK_Pis true if there are nobreakstatements in the switch.
- TRY_BLOCK#
Used to represent a
tryblock. The body of the try block is given byTRY_STMTS. Each of the catch blocks is aHANDLERnode. The first handler is given byTRY_HANDLERS. Subsequent handlers are obtained by following theTREE_CHAINlink from one handler to the next. The body of the handler is given byHANDLER_BODY.If
CLEANUP_Pholds of theTRY_BLOCK, then theTRY_HANDLERSwill not be aHANDLERnode. Instead, it will be an expression that should be executed if an exception is thrown in the try block. It must rethrow the exception after executing that code. And, if an exception is thrown while the expression is executing,terminatemust be called.
- USING_STMT#
Used to represent a
usingdirective. The namespace is given byUSING_STMT_NAMESPACE, which will be a NAMESPACE_DECL. This node is needed inside template functions, to implement using directives during instantiation.
- WHILE_STMT#
Used to represent a
whileloop. TheWHILE_CONDis the termination condition for the loop. See the documentation for anIF_STMTfor more information on the representation used for the condition.The
WHILE_BODYis the body of the loop.
C++ Expressions#
This section describes expressions specific to the C and C++ front ends.
- TYPEID_EXPR#
Used to represent a
typeidexpression.
- NEW_EXPR#
Used to represent a call to
newandnew[]respectively.
- DELETE_EXPR#
Used to represent a call to
deleteanddelete[]respectively.
- MEMBER_REF#
Represents a reference to a member of a class.
- THROW_EXPR#
Represents an instance of
throwin the program. Operand 0, which is the expression to throw, may beNULL_TREE.
- AGGR_INIT_EXPR#
An
AGGR_INIT_EXPRrepresents the initialization as the return value of a function call, or as the result of a constructor. AnAGGR_INIT_EXPRwill only appear as a full-expression, or as the second operand of aTARGET_EXPR.AGGR_INIT_EXPRs have a representation similar to that ofCALL_EXPRs. You can use theAGGR_INIT_EXPR_FNandAGGR_INIT_EXPR_ARGmacros to access the function to call and the arguments to pass.If
AGGR_INIT_VIA_CTOR_Pholds of theAGGR_INIT_EXPR, then the initialization is via a constructor call. The address of theAGGR_INIT_EXPR_SLOToperand, which is always aVAR_DECL, is taken, and this value replaces the first argument in the argument list.In either case, the expression is void.