Commit a64a8f2f by Daniel Kraft Committed by Daniel Kraft

gfc-internals.texi (F2003 OOP), [...]): New chapter and section to document the…

gfc-internals.texi (F2003 OOP), [...]): New chapter and section to document the internals of type-bound procedures.

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
parent f69bbb46
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
......
......@@ -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)
......
......@@ -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
......@@ -552,6 +560,96 @@ 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 ---------------------------------------------------------------------
......
......@@ -1593,7 +1593,6 @@ typedef struct gfc_expr
{
gfc_actual_arglist* actual;
gfc_typebound_proc* tbp;
gfc_symbol* derived;
const char* name;
}
compcall;
......
......@@ -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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment