Bug 34112

Summary: Add $!DEC ATTRIBUTE support for 32bit Windows' STDCALL
Product: gcc Reporter: Tobias Burnus <burnus>
Component: fortranAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: enhancement CC: dannysmith, gcc-bugs
Priority: P3    
Version: 4.3.0   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2009-06-16 14:22:11

Description Tobias Burnus 2007-11-15 18:22:56 UTC
32bit Windows uses a different calling convention (called procedure pops the stack, not caller) with a symbol name _<name>@n, where n is the number of bytes to pop off.

See also:
http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/19d77dfc75f8be58
http://gcc.gnu.org/ml/fortran/2007-11/msg00074.html

As the standard makes not provisions and !DEC$ (*DEC$, cDEC$) is widely used, gfortran should accept the following:

  function CallWndRetProc(nCode, wParam, lParam)
  !DEC$ ATTRIBUTES STDCALL,DECORATE, ALIAS: 'CallWndRetProc' :: CallWndRetProc 
  end function

Documentation:
http://www.intel.com/software/products/compilers/docs/fmac/doc_files/source/extfile/lref_for/source_files/rfattcst.htm
http://www.intel.com/software/products/compilers/docs/fmac/doc_files/source/extfile/lref_for/source_files/rfattrib.htm

They seem to map to (http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html):

STDCALL  ->  __attribute__(stdcall)
ALIAS    ->  __attribute__(alias("name"))
DECORATE -> ?

The problem with decorate is that its meaning depends on the platform. It may decorate the "name" of alias with a "_" prefix and "@n" postfix or only with a "_" prefix. Maybe one should start with STDCALL and ALIAS.

For alias one should do something as in c-pragma.c's apply_pragma_weak:

decl_attributes (&decl, build_tree_list (get_identifier ("alias"),
                                         build_tree_list (NULL, value)),
                 0);
Comment 1 Tobias Burnus 2007-11-15 19:25:10 UTC
For stdcall and @n decoration, see also PR 31073.
Comment 2 Danny Smith 2007-11-16 23:09:44 UTC
> The problem with decorate is that its meaning depends on the platform. It may
> decorate the "name" of alias with a "_" prefix and "@n" postfix or only with a
> "_" prefix. Maybe one should start with STDCALL and ALIAS.

Would the target hook TARGET_MANGLE_DECL_ASSEMBLER_NAME (see tm.texi, also config/i386/winnt.c for implementation) help here?
Danny
Comment 3 Thomas Koenig 2007-11-18 21:49:06 UTC
This would be useful.
Comment 4 Francois-Xavier Coudert 2008-02-05 10:17:26 UTC
(In reply to comment #0)
> As the standard makes not provisions and !DEC$ (*DEC$, cDEC$) is widely used,
> gfortran should accept the following:
> 
>   function CallWndRetProc(nCode, wParam, lParam)
>   !DEC$ ATTRIBUTES STDCALL,DECORATE, ALIAS: 'CallWndRetProc' :: CallWndRetProc 
>   end function

I thought a bit about that recently, and I don't like the idea of having to support parts of another vendor's extension. The first other idea I had was to add that STDCALL specification as an extension to the BIND syntax:   BIND(C,STDCALL). It is the logical place to put it, but it has to be protected by macros to compile on other compilers, which is not very Fortran-ish.

So, my next idea is to provide an compile-time option that would make all BIND(C) procedures in the compiled file STDCALL: true, this does not solve the problem of existing code, and true, it requires creating different source files if you want to use mixed calling conventions, but it seems like an good alternative to satisfy our Windows power users and yet not add too much extra kludge to the front-end.
Comment 5 Tobias Burnus 2008-02-05 15:12:00 UTC
> I thought a bit about that recently, and I don't like the idea of having to
> support parts of another vendor's extension. The first other idea I had was to
> add that STDCALL specification as an extension to the BIND syntax:

If we don't follow !$DEC than I'm in favor of this variant, which one could implement even if one implements !$DEC at some point.

> So, my next idea is to provide an compile-time option that would make all
> BIND(C) procedures in the compiled file STDCALL

I'm really against this; I think this is very confusing and makes it very hard to combine STDCALL with non-STDCALL procedures.

#if defined __GFORTRAN__
  #define STDCALL  STDCALL
#else
  #define STDCALL  C
#endif

  subroutine my() bind(STDCALL,name="foo")

Or alternatively, though more difficult to CPP:

  subroutine my() bind(C,attribute="stdcall",name="foo")

where one could think of allowing other items from http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
Comment 6 Tobias Burnus 2008-03-03 14:40:52 UTC
Initial patch by Franc,ois-Xavier:
http://gcc.gnu.org/ml/fortran/2008-03/msg00007.html
Comment 7 Tobias Burnus 2008-03-04 22:20:26 UTC
Intel documentation in PDF format:
http://softwarecommunity.intel.com/isn/downloads/softwareproducts/pdfs/347685.pdf
Directives (!DEC$) start at page 335
Comment 8 Tobias Burnus 2008-04-04 07:49:09 UTC
It would be useful if one could support also

   !$GNU attributes align:16 :: variable name

or alike for calls to libraries which need alignment such as FFTW.
Comment 9 Francois-Xavier Coudert 2008-04-04 08:35:10 UTC
(In reply to comment #8)
> It would be useful if one could support also
> 
>    !$GNU attributes align:16 :: variable name
> 
> or alike for calls to libraries which need alignment such as FFTW.

Yep, I think I mentioned that in my last c.l.f post about GNU attributes in gfortran. And I also had the very same thought when I read this morning's c.l.f thread :)

Comment 10 Tobias Burnus 2009-06-16 14:22:11 UTC
Add c.l.f link, mentioned in comment 9
http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/7bbe1ee44c505be8/

Regarding TARGET_MANGLE_DECL_ASSEMBLER_NAME (comment 2):
Currently, the decorating (@<nn>) seems to be only done for ADA, cf.
a) config/i386/cygming.h:
  #define TARGET_MANGLE_DECL_ASSEMBLER_NAME i386_pe_mangle_decl_assembler_name
b) config/i386/winnt.c and there: i386_pe_maybe_mangle_decl_assembler_name

Need to check, when it is added and when not. (It should only be added when "decorate" is specified.)
Comment 11 Tobias Burnus 2009-06-16 16:35:46 UTC
Note information I got from Kai. (He was not 100% sure for some of the items and I probably misunderstood also parts thus take with a grain of salt.)

With the stdcall attribute on Win32 the @<n> suffix is automatically added; with fastcall a @ prefix is added and with cdecl a leading _ is added.
And with Win64 nothing is added (well, cdecl adds a leading _ but this is about to change).

An alias does not automatically add the decoration thus the decoration attribute might be useful. (Though, we don't need to support (weak) aliases initially. For aliases, one needs in C a function prototype to get it working properly. Thus one needs to check how to handle it correctly.)

Procedure pointers: Here, the calling method is also crucial, i.e. one needs to be able (a) to specify it for proc pointers and (b) one needs to check it when one does a proc pointer assignment.

DLLEXPORT/DLLIMPORT: Here, one also needs to handle global variables (= common, module variables).
Comment 12 Tobias Burnus 2009-06-28 17:57:00 UTC
Subject: Bug 34112

Author: burnus
Date: Sun Jun 28 17:56:41 2009
New Revision: 149036

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=149036
Log:
2009-06-28  Tobias Burnus  <burnus@net-b.de>
	    Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>

	PR fortran/34112
	* symbol.c (gfc_add_ext_attribute): New function.
	(gfc_get_sym_tree): New argument allow_subroutine.
	(gfc_get_symbol,gfc_get_ha_sym_tree,gen_cptr_param,gen_fptr_param
	gen_shape_param,generate_isocbinding_symbol): Use it.
	* decl.c (find_special): New argument allow_subroutine.
	(add_init_expr_to_sym,add_hidden_procptr_result,attr_decl1,
	match_procedure_in_type,gfc_match_final_decl): Use it.
	(gfc_match_gcc_attributes): New function.
	* gfortran.texi (Mixed-Language Programming): New section
	"GNU Fortran Compiler Directives".
	* gfortran.h (ext_attr_t): New struct.
	(symbol_attributes): Use it.
	(gfc_add_ext_attribute): New prototype.
	(gfc_get_sym_tree): Update pototype.
	* expr.c (gfc_check_pointer_assign): Check whether call
	convention is the same.
	* module.c (import_iso_c_binding_module, create_int_parameter,
	use_iso_fortran_env_module): Update gfc_get_sym_tree call.
	* scanner.c (skip_gcc_attribute): New function.
	(skip_free_comments,skip_fixed_comments): Use it.
	(gfc_next_char_literal): Support !GCC$ lines.
	* resolve.c (check_host_association): Update
	gfc_get_sym_tree call.
	* match.c (gfc_match_sym_tree,gfc_match_call): Update
	gfc_get_sym_tree call.
	* trans-decl.c (add_attributes_to_decl): New function.
	(gfc_get_symbol_decl,get_proc_pointer_decl,
	gfc_get_extern_function_decl,build_function_decl: Use it.
	* match.h (gfc_match_gcc_attributes): Add prototype.
	* parse.c (decode_gcc_attribute): New function.
	(next_free,next_fixed): Support !GCC$ lines.
	* primary.c (match_actual_arg,check_for_implicit_index,
	gfc_match_rvalue,gfc_match_rvalue): Update
	gfc_get_sym_tree call.

2009-06-28  Tobias Burnus  <burnus@net-b.de>

	PR fortran/34112
	* gfortran.dg/compiler-directive_1.f90: New test.
	* gfortran.dg/compiler-directive_2.f: New test.


Added:
    trunk/gcc/testsuite/gfortran.dg/compiler-directive_1.f90
    trunk/gcc/testsuite/gfortran.dg/compiler-directive_2.f
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/decl.c
    trunk/gcc/fortran/expr.c
    trunk/gcc/fortran/gfortran.h
    trunk/gcc/fortran/gfortran.texi
    trunk/gcc/fortran/match.c
    trunk/gcc/fortran/match.h
    trunk/gcc/fortran/module.c
    trunk/gcc/fortran/parse.c
    trunk/gcc/fortran/primary.c
    trunk/gcc/fortran/resolve.c
    trunk/gcc/fortran/scanner.c
    trunk/gcc/fortran/symbol.c
    trunk/gcc/fortran/trans-decl.c
    trunk/gcc/testsuite/ChangeLog

Comment 13 Tobias Burnus 2009-06-28 19:51:46 UTC
FIXED on the trunk (4.5).