Type-bound Procedures (GNU Fortran Compiler Internals)

### 4.1 Type-bound Procedures ¶

Type-bound procedures are stored in the `tb_sym_root` of the namespace `f2k_derived` associated with the derived-type symbol as `gfc_symtree` nodes. The name and symbol of these symtrees corresponds to the binding-name of the procedure, i.e. the name that is used to call it from the context of an object of the derived-type.

In addition, this type of symtrees stores in `n.tb` a struct of type `gfc_typebound_proc` containing the additional data needed: The binding attributes (like `PASS` and `NOPASS`, `NON_OVERRIDABLE` or the access-specifier), the binding’s target(s) and, if the current binding overrides or extends an inherited binding of the same name, `overridden` points to this binding’s `gfc_typebound_proc` structure.

#### 4.1.1 Specific Bindings ¶

For specific bindings (declared with `PROCEDURE`), if they have a passed-object argument, the passed-object dummy argument is first saved by its name, and later during resolution phase the corresponding argument is looked for and its position remembered as `pass_arg_num` in `gfc_typebound_proc`. The binding’s target procedure is pointed-to by `u.specific`.

`DEFERRED` bindings are just like ordinary specific bindings, except that their `deferred` flag is set of course and that `u.specific` points to their “interface” defining symbol (might be an abstract interface) instead of the target procedure.

At the moment, all type-bound procedure calls are statically dispatched and transformed into ordinary procedure calls at resolution time; their actual argument list is updated to include at the right position the passed-object argument, if applicable, and then a simple procedure call to the binding’s target procedure is built. To handle dynamic dispatch in the future, this will be extended to allow special code generation during the trans-phase to dispatch based on the object’s dynamic type.

#### 4.1.2 Generic Bindings ¶

Bindings declared as `GENERIC` store the specific bindings they target as a linked list using nodes of type `gfc_tbp_generic` in `u.generic`. For each specific target, the parser records its symtree and during resolution this symtree is bound to the corresponding `gfc_typebound_proc` structure of the specific target.

Calls to generic bindings are handled entirely in the resolution-phase, where for the actual argument list present the matching specific binding is found and the call’s target procedure (`value.compcall.tbp`) is re-pointed to the found specific binding and this call is subsequently handled by the logic for specific binding calls.

#### 4.1.3 Calls to Type-bound Procedures ¶

Calls to type-bound procedures are stored in the parse-tree as `gfc_expr` nodes of type `EXPR_COMPCALL`. Their `value.compcall.actual` saves the actual argument list of the call and `value.compcall.tbp` points to the `gfc_typebound_proc` structure of the binding to be called. The object in whose context the procedure was called is saved by combination of `symtree` and `ref`, as if the expression was of type `EXPR_VARIABLE`.

For code like this:

    CALL myobj%procedure (arg1, arg2)

the `CALL` is represented in the parse-tree as a `gfc_code` node of type `EXEC_COMPCALL`. The `expr` member of this node holds an expression of type `EXPR_COMPCALL` of the same structure as mentioned above except that its target procedure is of course a `SUBROUTINE` and not a `FUNCTION`.

Expressions that are generated internally (as expansion of a type-bound operator call) may also use additional flags and members. `value.compcall.ignore_pass` signals that even though a `PASS` attribute may be present the actual argument list should not be updated because it already contains the passed-object. `value.compcall.base_object` overrides, if it is set, the base-object (that is normally stored in `symtree` and `ref` as mentioned above); this is needed because type-bound operators can be called on a base-object that need not be of type `EXPR_VARIABLE` and thus representable in this way. Finally, if `value.compcall.assign` is set, the call was produced in expansion of a type-bound assignment; this means that proper dependency-checking needs to be done when relevant.