]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gfc-internals.texi (F2003 OOP), [...]): New chapter and section to document the inter...
authorDaniel Kraft <d@domob.eu>
Mon, 1 Sep 2008 10:55:50 +0000 (12:55 +0200)
committerDaniel Kraft <domob@gcc.gnu.org>
Mon, 1 Sep 2008 10:55:50 +0000 (12:55 +0200)
2008-09-01  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.

From-SVN: r139857

gcc/fortran/ChangeLog
gcc/fortran/dump-parse-tree.c
gcc/fortran/gfc-internals.texi
gcc/fortran/gfortran.h
gcc/fortran/primary.c

index 36da100bf1bf4837ccff58b4509b5de555345a6b..92a0d356fab7bd6d71a9e4a57af0e5b73159ddad 100644 (file)
@@ -1,3 +1,17 @@
+2008-09-01  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.
+
 2008-08-31  Richard Guenther  <rguenther@suse.de>
 
        * trans-expr.c (gfc_trans_string_copy): Use the correct types
index c829ebddc3c2c92d3846ded59a8be73ad54a4903..05d32c29a76b298a52db4317f97ff9a26c00d988 100644 (file)
@@ -316,6 +316,22 @@ show_char_const (const gfc_char_t *c, int length)
   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 e73d3b59f9a2e33d84877d77038b7913d24c4cdd..9cb5a54e4b47cc0ac5ce95804694619571aa1b21 100644 (file)
@@ -118,6 +118,7 @@ not accurately reflect the status of the most recent GNU Fortran compiler.
 * 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 intrinsic or external function,
 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
 
@@ -551,6 +559,96 @@ was a string constant, but the @code{ref} member is also set and points to a
 substring reference as described in the subsection above.
 
 
+@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 ---------------------------------------------------------------------
index 9020029c84877758f83d1a55939afd5bc0ddb339..400ef3950050ac16b0c8b424a7b753671cfe375f 100644 (file)
@@ -1593,7 +1593,6 @@ typedef struct gfc_expr
     {
       gfc_actual_arglist* actual;
       gfc_typebound_proc* tbp;
-      gfc_symbol* derived;
       const char* name;
     }
     compcall;
index 3a72dda8a992493caf330a5fb845dfe76d0e41db..c18774962fcede273d9b680eaf95f94a511915c9 100644 (file)
@@ -1779,7 +1779,6 @@ gfc_match_varspec (gfc_expr *primary, int equiv_flag, bool sub_flag)
 
          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)