Block scopes and the variables they declare in GENERIC are
expressed using the BIND_EXPR
code, which in previous
versions of GCC was primarily used for the C statement-expression
extension.
Variables in a block are collected into BIND_EXPR_VARS
in
declaration order through their TREE_CHAIN
field. Any runtime
initialization is moved out of DECL_INITIAL
and into a
statement in the controlled block. When gimplifying from C or C++,
this initialization replaces the DECL_STMT
. These variables
will never require cleanups. The scope of these variables is just the
body
Variable-length arrays (VLAs) complicate this process, as their size
often refers to variables initialized earlier in the block and their
initialization involves an explicit stack allocation. To handle this,
we add an indirection and replace them with a pointer to stack space
allocated by means of alloca
. In most cases, we also arrange
for this space to be reclaimed when the enclosing BIND_EXPR
is
exited, the exception to this being when there is an explicit call to
alloca
in the source code, in which case the stack is left
depressed on exit of the BIND_EXPR
.
A C++ program will usually contain more BIND_EXPR
s than
there are syntactic blocks in the source code, since several C++
constructs have implicit scopes associated with them. On the
other hand, although the C++ front end uses pseudo-scopes to
handle cleanups for objects with destructors, these don't
translate into the GIMPLE form; multiple declarations at the same
level use the same BIND_EXPR
.