Next: , Up: Object Orientation   [Contents][Index]


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.


Next: , Up: Object Orientation   [Contents][Index]