Previous: Function Basics, Up: Functions
9.6.2 Function Bodies
A function that has a definition in the current translation unit will
have a non-NULL
DECL_INITIAL
. However, back ends should not make
use of the particular value given by DECL_INITIAL
.
The DECL_SAVED_TREE
macro will give the complete body of the
function.
9.6.2.1 Statements
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_P
set. Temporaries created during such statements should be destroyed when the innermost enclosing statement withSTMT_IS_FULL_EXPR_P
set 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 will have 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 will sometimes use
several statements chained together.
ASM_EXPR
-
Used to represent an inline assembly statement. For an inline assembly
statement like:
asm ("mov x, y");
The
ASM_STRING
macro will return aSTRING_CST
node for"mov x, y"
. If the original statement made use of the extended-assembly syntax, thenASM_OUTPUTS
,ASM_INPUTS
, andASM_CLOBBERS
will be the outputs, inputs, and clobbers for the statement, represented asSTRING_CST
nodes. The extended-assembly syntax looks like:asm ("fsinx %1,%0" : "=f" (result) : "f" (angle));
The first string is the
ASM_STRING
, containing the instruction template. The next two strings are the output and inputs, respectively; this statement has no clobbers. As this example indicates, “plain” assembly statements are merely a special case of extended assembly statements; they have no cv-qualifiers, outputs, inputs, or clobbers. All of the strings will beNUL
-terminated, and will contain no embeddedNUL
-characters.If the assembly statement is declared
volatile
, or if the statement was not an extended assembly statement, and is therefore implicitly volatile, then the predicateASM_VOLATILE_P
will hold of theASM_EXPR
.ASM_USES
andASM_LABEL
are for CW assembly syntax only, providing REG_USE and label declaration information insideASM_EXPR
tree. BREAK_STMT
-
Used to represent a
break
statement. There are no additional fields. CASE_LABEL_EXPR
-
Use to represent a
case
label, range ofcase
labels, or adefault
label. IfCASE_LOW
isNULL_TREE
, then this is adefault
label. Otherwise, ifCASE_HIGH
isNULL_TREE
, then this is an ordinarycase
label. In this case,CASE_LOW
is an expression giving the value of the label. BothCASE_LOW
andCASE_HIGH
areINTEGER_CST
nodes. These values will have the same type as the condition expression in the switch statement.Otherwise, if both
CASE_LOW
andCASE_HIGH
are defined, the statement is a range of case labels. Such statements originate with the extension that allows users to write things of the form:case 2 ... 5:
The first value will be
CASE_LOW
, while the second will beCASE_HIGH
. 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_DECL
will be theVAR_DECL
destroyed. Otherwise,CLEANUP_DECL
will beNULL_TREE
. In any case, theCLEANUP_EXPR
is 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_STMT
s were encountered. CONTINUE_STMT
-
Used to represent a
continue
statement. There are no additional fields. CTOR_STMT
-
Used to mark the beginning (if
CTOR_BEGIN_P
holds) or end (ifCTOR_END_P
holds of the main body of a constructor. See alsoSUBOBJECT
for more information on how to use these nodes. DECL_STMT
-
Used to represent a local declaration. The
DECL_STMT_DECL
macro can be used to obtain the entity declared. This declaration may be aLABEL_DECL
, indicating that the label declared is a local label. (As an extension, GCC allows the declaration of labels with scope.) In C, this declaration may be aFUNCTION_DECL
, indicating the use of the GCC nested function extension. For more information, see Functions. DO_STMT
-
Used to represent a
do
loop. The body of the loop is given byDO_BODY
while 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_TYPE
represents the type of the object. EXPR_STMT
-
Used to represent an expression statement. Use
EXPR_STMT_EXPR
to obtain the expression. FOR_STMT
-
Used to represent a
for
statement. TheFOR_INIT_STMT
is the initialization statement for the loop. TheFOR_COND
is the termination condition. TheFOR_EXPR
is the expression executed right before theFOR_COND
on each loop iteration; often, this expression increments a counter. The body of the loop is given byFOR_BODY
. Note thatFOR_INIT_STMT
andFOR_BODY
return statements, whileFOR_COND
andFOR_EXPR
return expressions. GOTO_EXPR
-
Used to represent a
goto
statement. TheGOTO_DESTINATION
will usually be aLABEL_DECL
. However, if the “computed goto” extension has been used, theGOTO_DESTINATION
will be an arbitrary expression indicating the destination. This expression will always have pointer type. HANDLER
-
Used to represent a C++
catch
block. TheHANDLER_TYPE
is the type of exception that will be caught by this handler; it is equal (by pointer equality) toNULL
if this handler is for all types.HANDLER_PARMS
is theDECL_STMT
for the catch parameter, andHANDLER_BODY
is the code for the block itself. IF_STMT
-
Used to represent an
if
statement. TheIF_COND
is the expression.If the condition is a
TREE_LIST
, then theTREE_PURPOSE
is a statement (usually aDECL_STMT
). Each time the condition is evaluated, the statement should be executed. Then, theTREE_VALUE
should 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_CLAUSE
represents the statement given by thethen
condition, while theELSE_CLAUSE
represents the statement given by theelse
condition. LABEL_EXPR
-
Used to represent a label. The
LABEL_DECL
declared by this statement can be obtained with theLABEL_EXPR_LABEL
macro. TheIDENTIFIER_NODE
giving the name of the label can be obtained from theLABEL_DECL
withDECL_NAME
. RETURN_STMT
-
Used to represent a
return
statement. TheRETURN_EXPR
is the expression returned; it will beNULL_TREE
if the statement was justreturn;
SUBOBJECT
-
In a constructor, these nodes are used to mark the point at which a
subobject of
this
is fully constructed. If, after this point, an exception is thrown before aCTOR_STMT
withCTOR_END_P
set is encountered, theSUBOBJECT_CLEANUP
must be executed. The cleanups must be executed in the reverse order in which they appear. SWITCH_STMT
-
Used to represent a
switch
statement. TheSWITCH_STMT_COND
is the expression on which the switch is occurring. See the documentation for anIF_STMT
for more information on the representation used for the condition. TheSWITCH_STMT_BODY
is the body of the switch statement. TheSWITCH_STMT_TYPE
is the original type of switch expression as given in the source, before any compiler conversions. TRY_BLOCK
- Used to represent a
try
block. The body of the try block is given byTRY_STMTS
. Each of the catch blocks is aHANDLER
node. The first handler is given byTRY_HANDLERS
. Subsequent handlers are obtained by following theTREE_CHAIN
link from one handler to the next. The body of the handler is given byHANDLER_BODY
.If
CLEANUP_P
holds of theTRY_BLOCK
, then theTRY_HANDLERS
will not be aHANDLER
node. 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,terminate
must be called. USING_STMT
- Used to represent a
using
directive. 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
while
loop. TheWHILE_COND
is the termination condition for the loop. See the documentation for anIF_STMT
for more information on the representation used for the condition.The
WHILE_BODY
is the body of the loop.