gfc_code (GNU Fortran Compiler Internals)

### 3.1 `gfc_code` ¶

The executable statements in a program unit are represented by a nested chain of `gfc_code` structures. The type of statement is identified by the `op` member of the structure, the different possible values are enumerated in `gfc_exec_op`. A special member of this `enum` is `EXEC_NOP` which is used to represent the various `END` statements if they carry a label. Depending on the type of statement some of the other fields will be filled in. Fields that are generally applicable are the `next` and `here` fields. The former points to the next statement in the current block or is `NULL` if the current statement is the last in a block, `here` points to the statement label of the current statement.

If the current statement is one of `IF`, `DO`, `SELECT` it starts a block, i.e. a nested level in the program. In order to represent this, the `block` member is set to point to a `gfc_code` structure whose `next` member starts the chain of statements inside the block; this structure’s `op` member should be set to the same value as the parent structure’s `op` member. The `SELECT` and `IF` statements may contain various blocks (the chain of `ELSE IF` and `ELSE` blocks or the various `CASE`s, respectively). These chains are linked-lists formed by the `block` members.

Consider the following example code:

    IF (foo < 20) THEN
      PRINT *, "Too small"
      foo = 20
    ELSEIF (foo > 50) THEN
      PRINT *, "Too large"
      foo = 50
    ELSE
      PRINT *, "Good"
    END IF

This statement-block will be represented in the internal gfortran tree as follows, were the horizontal link-chains are those induced by the `next` members and vertical links down are those of `block`. ‘`==|`’ and ‘`--|`’ mean `NULL` pointers to mark the end of a chain:

    ... ==> IF ==> ...
            |
            +--> IF foo < 20 ==> PRINT *, "Too small" ==> foo = 20 ==|
                 |
                 +--> IF foo > 50 ==> PRINT *, "Too large" ==> foo = 50 ==|
                      |
                      +--> ELSE ==> PRINT *, "Good" ==|
                           |
                           +--|

#### 3.1.1 IF Blocks ¶

Conditionals are represented by `gfc_code` structures with their `op` member set to `EXEC_IF`. This structure’s `block` member must point to another `gfc_code` node that is the header of the if-block. This header’s `op` member must be set to `EXEC_IF`, too, its `expr` member holds the condition to check for, and its `next` should point to the code-chain of the statements to execute if the condition is true.

If in addition an `ELSEIF` or `ELSE` block is present, the `block` member of the if-block-header node points to yet another `gfc_code` structure that is the header of the elseif- or else-block. Its structure is identical to that of the if-block-header, except that in case of an `ELSE` block without a new condition the `expr` member should be `NULL`. This block can itself have its `block` member point to the next `ELSEIF` or `ELSE` block if there’s a chain of them.

#### 3.1.2 Loops ¶

`DO` loops are stored in the tree as `gfc_code` nodes with their `op` set to `EXEC_DO` for a `DO` loop with iterator variable and to `EXEC_DO_WHILE` for infinite `DO`s and `DO WHILE` blocks. Their `block` member should point to a `gfc_code` structure heading the code-chain of the loop body; its `op` member should be set to `EXEC_DO` or `EXEC_DO_WHILE`, too, respectively.

For `DO WHILE` loops, the loop condition is stored on the top `gfc_code` structure’s `expr` member; `DO` forever loops are simply `DO WHILE` loops with a constant `.TRUE.` loop condition in the internal representation.

Similarly, `DO` loops with an iterator have instead of the condition their `ext.iterator` member set to the correct values for the loop iterator variable and its range.

#### 3.1.3 `SELECT` Statements ¶

A `SELECT` block is introduced by a `gfc_code` structure with an `op` member of `EXEC_SELECT` and `expr` containing the expression to evaluate and test. Its `block` member starts a list of `gfc_code` structures linked together by their `block` members that stores the various `CASE` parts.

Each `CASE` node has its `op` member set to `EXEC_SELECT`, too, its `next` member points to the code-chain to be executed in the current case-block, and `extx.case_list` contains the case-values this block corresponds to. The `block` member links to the next case in the list.

#### 3.1.4 `BLOCK` and `ASSOCIATE` ¶

The code related to a `BLOCK` statement is stored inside an `gfc_code` structure (say c) with `c.op` set to `EXEC_BLOCK`. The `gfc_namespace` holding the locally defined variables of the `BLOCK` is stored in `c.ext.block.ns`. The code inside the construct is in `c.code`.

`ASSOCIATE` constructs are based on `BLOCK` and thus also have the internal storage structure described above (including `EXEC_BLOCK`). However, for them `c.ext.block.assoc` is set additionally and points to a linked list of `gfc_association_list` structures. Those structures basically store a link of associate-names to target expressions. The associate-names themselves are still also added to the `BLOCK`’s namespace as ordinary symbols, but they have their `gfc_symbol`’s member `assoc` set also pointing to the association-list structure. This way associate-names can be distinguished from ordinary variables and their target expressions identified.

For association to expressions (as opposed to variables), at the very beginning of the `BLOCK` construct assignments are automatically generated to set the corresponding variables to their target expressions’ values, and later on the compiler simply disallows using such associate-names in contexts that may change the value.