This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [Fortran, Patch] Proposed type-bound procedures patch, part 1
- From: Tobias Burnus <tobias dot burnus at physik dot fu-berlin dot de>
- To: Daniel Kraft <d at domob dot eu>, Fortran List <fortran at gcc dot gnu dot org>, gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 22 Aug 2008 22:58:37 +0200
- Subject: Re: [Fortran, Patch] Proposed type-bound procedures patch, part 1
Hello Daniel,
Daniel Kraft wrote:
> attached is a proposed draft-patch for type-bound procedures; it is
> meant to parse and resolve (that is, check the binding, PASS/NOPASS
> and such is correct) specific bindings, that is ones of the form
+ /* XXX: Below is quite a lot of ugly code duplication... I couldrewrite this
+ using macros, but that might be even uglier... What do you think? Any
+ completely other suggestions maybe? */
I don't have any good idea. For procedure pointer components, one has
the same problem. (Actually, match_binding_attributes can be used for
both, (NO)PASS and PUBLIC/PRIVATE are the same; proc. pointers need POINTER
while type-bounds procedures have DEFERRED and NON_OVERRIDABLE.)
One could refactor the PUBLIC/PRIVATE matching, which occurs also for
GENERIC.
You could add DEFERRED to match_binding_attributes (or add a TODO).
[I would go for the latter.]
+ /* XXX: Here's nothing about the need to be inside the specification part of
+ a module! */
True. There is only something about module procedures or external
procedures.
+ /* TODO: Implement PROCEDURE(interface). */
Aha, that explains why PROCEDURE(foo) gives strange error messages.
Maybe one should add an if(match(" (")) gfc_error
with: Procedure with interface only allowed in abstract types"
That gives a nice error message, which is valid as long as abstract
types are not supported.
+ /* See if we already have a binding with this name in the symtree which would
+ be an error. */
+ /* XXX: It should be one, right? */
Looks ok - at least until we have GENERIC.
+ /* XXX: Should we use static array of GFC_MAX_SYMBOL_LENGTH+1 characters?
+ This makes life easier to avoid leaking but may cost a lot of memory if
+ there are lots of these structs around. */
I think either is OK - I don't have strong preferences for either.
+/* XXX: Which file to put this best in? */
+gfc_symtree* gfc_find_typebound_proc (gfc_symbol*, const char*);
Spontaneously I would say: symbol.c, but resolve.c is also OK.
+ if (!proc->attr.subroutine && !proc->attr.function)
+ {
+ gfc_error ("Binding-target '%s' must be a procedure at %L",
+ proc->name, &where);
+ goto error;
+ }
The error message is misleading for:
procedure() :: foo
[...]
type t
contains
procedure,nopass :: foo
Here, foo is a procedure - but without an explicit interface and
without knowing whether it is a subroutine or a function. How about:
Additionally, I find "binding-target" not that easy to understand. How
about:
"Error: Procedure must be a module procedure or an external
procedure with an explicit interface"
or
"Error: Procedure name must be the name of a module procedure or
an external procedure with an explicit interface"
or
"Error: '%s' must be a module procedure or an external
procedure with an explicit interface"
+ gfc_error ("Binding-target '%s' with PASS(%s) at %L has no"
+ gfc_error ("Binding-target '%s' with PASS at %L must have at"
+ gfc_error ("Argument '%s' of the binding target '%s' with PASS(%s)"
Ditto: I still do not like "Binding-target" - how about "Procedure" ?
+! XXX: Do overriding bindings have to have the same or some "matching" signature
+! as their overridden binding?
Yes, see long list in "4.5.6.2 Type-bound procedure overriding".
+ ! XXX: How to do a PRIVATE subroutine for access checking?
You don't mean something like the following, do you? Without parsing the
CALL statement, it is a bit difficult to test.
module m
type t
contains
private
procedure pp
end type t
contains
subroutine test
type(t) :: myt
call myt%pp() ! OK
end subroutine test
subroutine pp(...
[...]
use m
type(t) :: myt
call myt%pp() ! INVALID
+ /* Find the super-type of the current derived type. */
+ /* XXX: Should we do this one time and make super_type a global, too?
*/
+ super_type = get_derived_super_type (resolve_bindings_derived);
I don't have a strong opinion on this. It is a question of speed vs.
complexity/readability. I'm not convinced that it will help much with
the calculation speed. (And I have to admit I'm not too concerned about
the compilation speed - unless something becomes really a hot spot.)
Can you add additional checks for
(a) procedures which are abstract interfaces [like "three"]
(b) neither module nor external procedures [like "bar"]
see my previous email with the example at
http://gcc.gnu.org/ml/fortran/2008-08/msg00150.html
Otherwise OK if you add a not-yet-implemented error.
Thanks for the patch.
Tobias