This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch, Fortran] Documentation for type-bound procedures


Hi,

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 will regression-test (and make pdf html) tomorrow. Ok to commit if no errors?

I'm of course happy about comments on my text on spelling or "more English" sentences if you've got any :)

Yours,
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-28  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.
	* 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.
Index: gcc/fortran/dump-parse-tree.c
===================================================================
--- gcc/fortran/dump-parse-tree.c	(revision 139725)
+++ 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.tbp->n.sym->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,58 @@ 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 ();
+
+  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->access == ACCESS_PUBLIC)
+    fputs (", PUBLIC", dumpfile);
+  else
+    fputs (", PRIVATE", dumpfile);
+  if (st->typebound->non_overridable)
+    fputs (", NON_OVERRIDABLE", dumpfile);
+
+  fprintf (dumpfile, " :: %s => %s", st->n.sym->name,
+				     st->typebound->target->n.sym->name);
+}
+
+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 +773,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 +1189,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/gfc-internals.texi
===================================================================
--- gcc/fortran/gfc-internals.texi	(revision 139725)
+++ 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,67 @@ 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 (@code{PASS} and @code{NOPASS}, @code{NON_OVERRIDABLE} and
+the access-specifier) and the binding's target procedure.  In case of
+@code{PASS}, 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 in @code{gfc_typebound_proc}.
+
+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
+symtree of the type-bound procedure to be called as described above.  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}.
+
+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.
+
+
+@c ---------------------------------------------------------------------
 @c LibGFortran
 @c ---------------------------------------------------------------------
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]