This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [Patch, Fortran] Documentation for type-bound procedures
- From: "Paul Richard Thomas" <paul dot richard dot thomas at gmail dot com>
- To: "Daniel Kraft" <d at domob dot eu>
- Cc: "Fortran List" <fortran at gcc dot gnu dot org>, gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 1 Sep 2008 12:33:03 +0200
- Subject: Re: [Patch, Fortran] Documentation for type-bound procedures
- References: <48B7196B.3080300@domob.eu> <48BAA7F8.5010501@domob.eu>
Daniel,
OK to commit
Many thanks for the rapid response.
Paul
On Sun, Aug 31, 2008 at 4:17 PM, Daniel Kraft <d@domob.eu> wrote:
> Daniel Kraft wrote:
>>
>> here's my follow-up patch to document type-bound procedures in a new
>> chapter about F2003 OOP internals in gfc-internals.texi and to extend
>> dump-parse-tree.c to output procedure bindings (type-bound procedures and
>> finalizers). I also included code to output EXPR_COMPCALL and EXEC_COMPCALL
>> nodes; but as those are currently always transformed into ordinary calls
>> this code is never executed at the moment. I still think it is best to put
>> it in and adapt it if needed later when those expressions will stay until
>> trans for dynamic dispatch (or whatever might come).
>
>>
>>
>> I'm of course happy about comments on my text on spelling or "more
>> English" sentences if you've got any :)
>
> Updated the patch to include the necessary changes for GENERIC bindings,
> too. On the way I removed an unused member
> (gfc_expr->value.compcall->derived) that has survived my clean-up of the
> GENERIC patch.
>
> make info html pdf tested, doing a regression test now. Any
> comments/suggestions for improvement? Ok to commit?
>
> Cheers,
> Daniel
>
> --
> Done: Arc-Bar-Cav-Sam-Val-Wiz, Dwa-Elf-Gno-Hum-Orc, Law-Neu-Cha, Fem-Mal
> To go: Hea-Kni-Mon-Pri-Ran-Rog-Tou
>
> 2008-08-31 Daniel Kraft <d@domob.eu>
>
> * gfc-internals.texi (F2003 OOP), (Type-bound Procedures): New
> chapter
> and section to document the internals of type-bound procedures.
> (gfc_expr): Document EXPR_COMPCALL.
> * gfortran.h (struct gfc_expr): Remove unused `derived' from
> compcall.
> * dump-parse-tree.c (show_compcall): New method.
> (show_expr): Call it for EXPR_COMPCALL.
> (show_typebound), (show_f2k_derived): New methods.
> (show_symbol): Call show_f2k_derived.
> (show_code_node): Handle EXEC_COMPCALL.
> * primary.c (gfc_match_varspec): Don't initialize removed `derived'
> in
> primary->value.compcall.
>
> Index: gcc/fortran/dump-parse-tree.c
> ===================================================================
> --- gcc/fortran/dump-parse-tree.c (revision 139826)
> +++ gcc/fortran/dump-parse-tree.c (working copy)
> @@ -316,6 +316,22 @@ show_char_const (const gfc_char_t *c, in
> fputc ('\'', dumpfile);
> }
>
> +
> +/* Show a component-call expression. */
> +
> +static void
> +show_compcall (gfc_expr* p)
> +{
> + gcc_assert (p->expr_type == EXPR_COMPCALL);
> +
> + fprintf (dumpfile, "%s", p->symtree->n.sym->name);
> + show_ref (p->ref);
> + fprintf (dumpfile, "%s", p->value.compcall.name);
> +
> + show_actual_arglist (p->value.compcall.actual);
> +}
> +
> +
> /* Show an expression. */
>
> static void
> @@ -539,6 +555,10 @@ show_expr (gfc_expr *p)
>
> break;
>
> + case EXPR_COMPCALL:
> + show_compcall (p);
> + break;
> +
> default:
> gfc_internal_error ("show_expr(): Don't know how to show expr");
> }
> @@ -646,6 +666,76 @@ show_components (gfc_symbol *sym)
> }
>
>
> +/* Show the f2k_derived namespace with procedure bindings. */
> +
> +static void
> +show_typebound (gfc_symtree* st)
> +{
> + if (!st->typebound)
> + return;
> +
> + show_indent ();
> +
> + if (st->typebound->is_generic)
> + fputs ("GENERIC", dumpfile);
> + else
> + {
> + fputs ("PROCEDURE, ", dumpfile);
> + if (st->typebound->nopass)
> + fputs ("NOPASS", dumpfile);
> + else
> + {
> + if (st->typebound->pass_arg)
> + fprintf (dumpfile, "PASS(%s)", st->typebound->pass_arg);
> + else
> + fputs ("PASS", dumpfile);
> + }
> + if (st->typebound->non_overridable)
> + fputs (", NON_OVERRIDABLE", dumpfile);
> + }
> +
> + if (st->typebound->access == ACCESS_PUBLIC)
> + fputs (", PUBLIC", dumpfile);
> + else
> + fputs (", PRIVATE", dumpfile);
> +
> + fprintf (dumpfile, " :: %s => ", st->n.sym->name);
> +
> + if (st->typebound->is_generic)
> + {
> + gfc_tbp_generic* g;
> + for (g = st->typebound->u.generic; g; g = g->next)
> + {
> + fputs (g->specific_st->name, dumpfile);
> + if (g->next)
> + fputs (", ", dumpfile);
> + }
> + }
> + else
> + fputs (st->typebound->u.specific->n.sym->name, dumpfile);
> +}
> +
> +static void
> +show_f2k_derived (gfc_namespace* f2k)
> +{
> + gfc_finalizer* f;
> +
> + ++show_level;
> +
> + /* Finalizer bindings. */
> + for (f = f2k->finalizers; f; f = f->next)
> + {
> + show_indent ();
> + fprintf (dumpfile, "FINAL %s", f->proc_sym->name);
> + }
> +
> + /* Type-bound procedures. */
> + gfc_traverse_symtree (f2k->sym_root, &show_typebound);
> +
> + --show_level;
> +}
> +
> +
> /* Show a symbol. If a symbol is an ENTRY, SUBROUTINE or FUNCTION, we
> show the interface. Information needed to reconstruct the list of
> specific interfaces associated with a generic symbol is done within
> @@ -701,6 +791,13 @@ show_symbol (gfc_symbol *sym)
> show_components (sym);
> }
>
> + if (sym->f2k_derived)
> + {
> + show_indent ();
> + fputs ("Procedure bindings:\n", dumpfile);
> + show_f2k_derived (sym->f2k_derived);
> + }
> +
> if (sym->formal)
> {
> show_indent ();
> @@ -1110,6 +1207,11 @@ show_code_node (int level, gfc_code *c)
> show_actual_arglist (c->ext.actual);
> break;
>
> + case EXEC_COMPCALL:
> + fputs ("CALL ", dumpfile);
> + show_compcall (c->expr);
> + break;
> +
> case EXEC_RETURN:
> fputs ("RETURN ", dumpfile);
> if (c->expr)
> Index: gcc/fortran/gfortran.h
> ===================================================================
> --- gcc/fortran/gfortran.h (revision 139826)
> +++ gcc/fortran/gfortran.h (working copy)
> @@ -1593,7 +1593,6 @@ typedef struct gfc_expr
> {
> gfc_actual_arglist* actual;
> gfc_typebound_proc* tbp;
> - gfc_symbol* derived;
> const char* name;
> }
> compcall;
> Index: gcc/fortran/primary.c
> ===================================================================
> --- gcc/fortran/primary.c (revision 139826)
> +++ gcc/fortran/primary.c (working copy)
> @@ -1779,7 +1779,6 @@ gfc_match_varspec (gfc_expr *primary, in
>
> primary->expr_type = EXPR_COMPCALL;
> primary->value.compcall.tbp = tbp->typebound;
> - primary->value.compcall.derived = sym;
> primary->value.compcall.name = tbp->name;
> gcc_assert (primary->symtree->n.sym->attr.referenced);
> if (tbp_sym)
> Index: gcc/fortran/gfc-internals.texi
> ===================================================================
> --- gcc/fortran/gfc-internals.texi (revision 139826)
> +++ gcc/fortran/gfc-internals.texi (working copy)
> @@ -118,6 +118,7 @@ not accurately reflect the status of the
> * User Interface:: Code that Interacts with the User.
> * Frontend Data Structures::
> Data structures used by the frontend
> +* Object Orientation:: Internals of Fortran 2003 OOP features.
> * LibGFortran:: The LibGFortran Runtime Library.
> * GNU Free Documentation License::
> How you can copy and share this manual.
> @@ -466,6 +467,13 @@ function symbol if the call is to an int
> respectively. These values are determined during resolution-phase from the
> structure's @code{symtree} member.
>
> +A special case of function calls are ``component calls'' to type-bound
> +procedures; those have the @code{expr_type} @code{EXPR_COMPCALL} with
> +@code{value.compcall} containing the argument list and the procedure
> called,
> +while @code{symtree} and @code{ref} describe the object on which the
> procedure
> +was called in the same way as a @code{EXPR_VARIABLE} expression would.
> +@xref{Type-bound Procedures}.
> +
>
> @subsection Array- and Structure-Constructors
>
> @@ -552,6 +560,96 @@ substring reference as described in the
>
>
> @c ---------------------------------------------------------------------
> +@c F2003 OOP
> +@c ---------------------------------------------------------------------
> +
> +@node Object Orientation
> +@chapter Internals of Fortran 2003 OOP Features
> +
> +@menu
> +* Type-bound Procedures:: Type-bound procedures.
> +@end menu
> +
> +
> +@c Type-bound procedures
> +@c ---------------------
> +
> +@node Type-bound Procedures
> +@section Type-bound Procedures
> +
> +Type-bound procedures are stored in the @code{sym_root} of the namespace
> +@code{f2k_derived} associated with the derived-type symbol as
> @code{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, those and only those symtrees representing a type-bound
> procedure
> +have their @code{typebound} member set; @code{typebound} points to a struct
> of
> +type @code{gfc_typebound_proc} containing the additional data needed: The
> +binding attributes (like @code{PASS} and @code{NOPASS},
> @code{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,
> @code{overridden}
> +points to this binding's @code{gfc_typebound_proc} structure.
> +
> +
> +@subsection Specific Bindings
> +@c --------------------------
> +
> +For specific bindings (declared with @code{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 @code{pass_arg_num} in
> @code{gfc_typebound_proc}.
> +The binding's target procedure is pointed-to by @code{u.specific}.
> +
> +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.
> +
> +
> +@subsection Generic Bindings
> +@c -------------------------
> +
> +Bindings declared as @code{GENERIC} store the specific bindings they target
> as
> +a linked list using nodes of type @code{gfc_tbp_generic} in
> @code{u.generic}.
> +For each specific target, the parser records its symtree and during
> resolution
> +this symtree is bound to the corresponding @code{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 (@code{value.compcall.tbp}) is re-pointed
> to
> +the found specific binding and this call is subsequently handled by the
> logic
> +for specific binding calls.
> +
> +
> +@subsection Calls to Type-bound Procedures
> +@c ---------------------------------------
> +
> +Calls to type-bound procedures are stored in the parse-tree as
> @code{gfc_expr}
> +nodes of type @code{EXPR_COMPCALL}. Their @code{value.compcall.actual}
> saves
> +the actual argument list of the call and @code{value.compcall.tbp} points
> to the
> +@code{gfc_typebound_proc} structure of the binding to be called. The
> object
> +in whose context the procedure was called is saved by combination of
> +@code{symtree} and @code{ref}, as if the expression was of type
> +@code{EXPR_VARIABLE}.
> +
> +For code like this:
> +@smallexample
> +CALL myobj%procedure (arg1, arg2)
> +@end smallexample
> +@noindent
> +the @code{CALL} is represented in the parse-tree as a @code{gfc_code} node
> of
> +type @code{EXEC_COMPCALL}. The @code{expr} member of this node holds an
> +expression of type @code{EXPR_COMPCALL} of the same structure as mentioned
> above
> +except that its target procedure is of course a @code{SUBROUTINE} and not a
> +@code{FUNCTION}.
> +
> +
> +@c ---------------------------------------------------------------------
> @c LibGFortran
> @c ---------------------------------------------------------------------
>
>
>
--
The knack of flying is learning how to throw yourself at the ground and miss.
--Hitchhikers Guide to the Galaxy