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]

Re: [Patch, Fortran] Documentation for type-bound procedures


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


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