[gfortran] Implement ENTRY statements.

Paul Brook paul@codesourcery.com
Tue Aug 17 15:57:00 GMT 2004


The attached patch implements ENTRY statements in subroutines.
Functions are still not handled.

These are implemented the same way as in g77. We create a "master" function 
who's arguments are the union of the entry point arguments, plus an 
additional integer argument to identify the argument. This additional 
argument is then used in a switch statement to jump to the position of that 
entry point within the master function.

For each entry point we generate a thunk function which tailcalls the master 
functions, passing NULL for any arguments which don't exist for that 
function.

When writing out module files we write out the entry points as normal 
functions, and omit the master function. The main complication is that we can 
now have multiple functions with the same formal namespace, so I added 
refcounting for namespaces.

Tobi started the patch, then got busy with other things.  Originally we were 
creating the thunk function bodies in resolve.c. This created all sorts of 
problems, so I scrapped that idea and made the backend interface generate 
them from the magical "entry" attribute.

Paul

2004-08-17  Paul Brook  <paul@codesourcery.com>
	Tobias Schlueter  <tobias.schlueter@physik.uni-muenchen.de>

	PR fortran/13082
	* decl.c (get_proc_name): Update mystery comment.
	(gfc_match_entry): Check for errors earlier.  Add entry point to list.
	* dump-parse-tree.c (gfc_show_code_node): Print EXEC_ENTRY nodes.
	* gfortran.h (symbol_attribute): Add entry_master.  Document entry.
	(struct gfc_entry_list): Define.
	(gfc_get_entry_list): Define.
	(struct gfc_namespace): Add refs and entries.
	(enum gfc_exec_op): Add EXEC_ENTRY.
	(struct gfc_code): Add ext.entry.
	* module.c (ab_attribute, attr_bits): Remove AB_ENTRY.
	(mio_symbol_attribute): Don't save/reture addr->entry.
	(mio_namespace_ref): Refcount namespaces.
	* parse.c (accept_statement): Handle ST_ENTRY.
	(gfc_fixup_sibling_symbols): Mark symbol as referenced.
	(parse_contained): Fixup sibling references to entry points
	after parsing the procedure body.
	* resolve.c (resolve_contained_fntype): New function.
	(merge_argument_lists, resolve_entries): New functions.
	(resolve_contained_functions): Use them.
	(resolve_code): Handle EXEC_ENTRY.
	(gfc_resolve): Call resolve_entries.
	* st.c (gfc_free_statement): Handle EXEC_ENTRY.
	* symbol.c (gfc_get_namespace): Refcount namespaces.
	(gfc_free_namespace): Ditto.
	* trans-array.c (gfc_trans_dummy_array_bias): Treat all args as
	optional when multiple entry points are present.
	* trans-decl.c (gfc_get_symbol_decl): Remove incorrect check.
	(gfc_get_extern_function_decl): Add assertion.  Fix coment.
	(create_function_arglist, trans_function_start, build_entry_thunks):
	New functions.
	(gfc_build_function_decl): Rename ...
	(build_function_decl): ... to this.
	(gfc_create_function_decl): New function.
	(gfc_generate_contained_functions): Use it.
	(gfc_trans_entry_master_switch): New function.
	(gfc_generate_function_code): Use new functions.
	* trans-stmt.c (gfc_trans_entry): New function.
	* trans-stmt.h (gfc_trans_entry): Add prototype.
	* trans-types.c (gfc_get_function_type): Add entry point argument.
	* trans.c (gfc_trans_code): Handle EXEC_ENTRY.
	(gfc_generate_module_code): Call gfc_create_function_decl.
	* trans.h (gfc_build_function_decl): Remove.
	(gfc_create_function_decl): Add prototype.
testsuite/
	* gfortran.dg/entry_1.f90: New test.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: patch.entry
Type: text/x-diff
Size: 40587 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20040817/f58e662d/attachment.bin>
-------------- next part --------------
! Test alternate entry points in a module procedure
module m
contains
subroutine indirecta (p)
  call p (3, 4)
end subroutine
subroutine indirectb (p)
  call p (5)
end subroutine

subroutine test1
  implicit none
  call indidecta (foo)
  call indirectb (bar)
end subroutine

subroutine foo(a, b)
  integer a, b
  logical, save :: was_foo = .false.
  if ((a .ne. 3) .or. (b .ne. 4)) call abort
  was_foo = .true.
entry bar(a)
  if (was_foo) then
    if ((a .ne. 3) .or. (b .ne. 4)) call abort
  else
    if (a .ne. 5) call abort
  end if
  was_foo = .false.
end subroutine

subroutine test2
  call foo (3, 4)
  call bar (5)
end subroutine
end module

program p
  use m
  call foo (3, 4)
  call bar (5)
  call test1 ()
  call test2 ()
end program


More information about the Gcc-patches mailing list