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.
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
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)),
For stdcall and @n decoration, see also PR 31073.
> 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?
This would be useful.
(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.
> 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
#define STDCALL C
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
Initial patch by Franc,ois-Xavier:
Intel documentation in PDF format:
Directives (!DEC$) start at page 335
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.
(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 :)
Add c.l.f link, mentioned in comment 9
Regarding TARGET_MANGLE_DECL_ASSEMBLER_NAME (comment 2):
Currently, the decorating (@<nn>) seems to be only done for ADA, cf.
#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.)
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).
Subject: Bug 34112
Date: Sun Jun 28 17:56:41 2009
New Revision: 149036
2009-06-28 Tobias Burnus <firstname.lastname@example.org>
Francois-Xavier Coudert <email@example.com>
* symbol.c (gfc_add_ext_attribute): New function.
(gfc_get_sym_tree): New argument allow_subroutine.
gen_shape_param,generate_isocbinding_symbol): Use it.
* decl.c (find_special): New argument allow_subroutine.
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
* match.c (gfc_match_sym_tree,gfc_match_call): Update
* trans-decl.c (add_attributes_to_decl): New function.
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,
2009-06-28 Tobias Burnus <firstname.lastname@example.org>
* gfortran.dg/compiler-directive_1.f90: New test.
* gfortran.dg/compiler-directive_2.f: New test.
FIXED on the trunk (4.5).