Type-bound procedures are stored in the
tb_sym_root of the namespace
f2k_derived associated with the derived-type symbol as
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
or the access-specifier), the binding’s target(s) and, if the current binding
overrides or extends an inherited binding of the same name,
points to this binding’s
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
The binding’s target procedure is pointed-to by
DEFERRED bindings are just like ordinary specific bindings, except
deferred flag is set of course and that
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.
Bindings declared as
GENERIC store the specific bindings they target as
a linked list using nodes of type
For each specific target, the parser records its symtree and during resolution
this symtree is bound to the corresponding
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.
Calls to type-bound procedures are stored in the parse-tree as
nodes of type
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
ref, as if the expression was of type
For code like this:
CALL myobj%procedure (arg1, arg2)
CALL is represented in the parse-tree as a
gfc_code node of
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
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
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
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.
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.