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_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 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_CHAINs. 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_STRINGmacro will return aSTRING_CSTnode for"mov x, y". If the original statement made use of the extended-assembly syntax, thenASM_OUTPUTS,ASM_INPUTS, andASM_CLOBBERSwill be the outputs, inputs, and clobbers for the statement, represented asSTRING_CSTnodes. 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_Pwill hold of theASM_EXPR.ASM_USESandASM_LABELare for CW assembly syntax only, providing REG_USE and label declaration information insideASM_EXPRtree. BREAK_STMT-
Used to represent a
breakstatement. There are no additional fields. CASE_LABEL_EXPR-
Use to represent a
caselabel, range ofcaselabels, or adefaultlabel. IfCASE_LOWisNULL_TREE, then this is adefaultlabel. Otherwise, ifCASE_HIGHisNULL_TREE, then this is an ordinarycaselabel. In this case,CASE_LOWis an expression giving the value of the label. BothCASE_LOWandCASE_HIGHareINTEGER_CSTnodes. These values will have the same type as the condition expression in the switch statement.Otherwise, if both
CASE_LOWandCASE_HIGHare 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_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. DECL_STMT-
Used to represent a local declaration. The
DECL_STMT_DECLmacro 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
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. Note thatFOR_INIT_STMTandFOR_BODYreturn statements, whileFOR_CONDandFOR_EXPRreturn expressions. GOTO_EXPR-
Used to represent a
gotostatement. TheGOTO_DESTINATIONwill usually be aLABEL_DECL. However, if the “computed goto” extension has been used, theGOTO_DESTINATIONwill be an arbitrary expression indicating the destination. This expression will always have pointer type. 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. LABEL_EXPR-
Used to represent a label. The
LABEL_DECLdeclared by this statement can be obtained with theLABEL_EXPR_LABELmacro. TheIDENTIFIER_NODEgiving the name of the label can be obtained from theLABEL_DECLwithDECL_NAME. RETURN_STMT-
Used to represent a
returnstatement. TheRETURN_EXPRis the expression returned; it will beNULL_TREEif the statement was justreturn; 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. 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.