Mercurial > jwe > octave
changeset 22134:a51d5c5c71e6
handle gfortran and f2c calling conventions separately
* configure.ac: New option --enable-fortran-calling-convention.
Explicitly define config.h macros for gfortran, f2c, Cray, and Visual
Fortran options.
* f77-fcn.h: Handle gfortran separately from f2c.
(F77_CHAR_ARG_LEN_TYPE, F77_DBLE, F77_REAL, F77_DBLE_CMPLX, F77_CMPLX,
F77_INT, F77_INT4, F77_LOGICAL, F77_CMPLX_ARG, F77_CONST_CMPLX_ARG,
F77_DBLE_CMPLX_ARG, F77_CONST_DBLE_CMPLX_ARG): New macros.
* f77-fcn.c (xstopx): Use F77_CHAR_ARG_LEN_TYPE.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Mon, 18 Jul 2016 09:56:41 -0400 |
parents | 59cadee1c74b |
children | 407c66ae1e20 |
files | configure.ac liboctave/cruft/misc/f77-fcn.c liboctave/cruft/misc/f77-fcn.h |
diffstat | 3 files changed, 110 insertions(+), 26 deletions(-) [+] |
line wrap: on
line diff
--- a/configure.ac Sun Jul 17 12:42:37 2016 -0400 +++ b/configure.ac Mon Jul 18 09:56:41 2016 -0400 @@ -668,7 +668,6 @@ AC_MSG_ERROR([A Fortran compiler is required]) fi -## Determine calling conventions for Fortran compiler AC_F77_LIBRARY_LDFLAGS AC_F77_DUMMY_MAIN AC_F77_WRAPPERS @@ -706,6 +705,34 @@ ;; esac +if test $ac_cv_f77_compiler_gnu = yes; then + FORTRAN_CALLING_CONVENTION=gfortran +else + FORTRAN_CALLING_CONVENTION=unknown +fi +AC_ARG_ENABLE([fortran-calling-convention], + [AS_HELP_STRING([--enable-fortran-calling-convention=OPTION], + [Select C++ to Fortran calling convention. "gfortran" should be detected automatically. Other options are "cray", "visual-fortran", or "f2c".])], + [FORTRAN_CALLING_CONVENTION="$enableval"], []) + +case "$FORTRAN_CALLING_CONVENTION" in + gfortran) + AC_DEFINE(F77_USES_GFORTRAN_CALLING_CONVENTION, 1, [Define to 1 if calling Fortran from C++ should use the gfortran calling convention.]) + ;; + cray) + AC_DEFINE(F77_USES_CRAY_CALLING_CONVENTION, 1, [Define to 1 if calling Fortran from C++ should use the Cray Fortran calling convention.]) + ;; + visual-fortran) + AC_DEFINE(F77_USES_VISUAL_FORTRAN_CALLING_CONVENTION, 1, [Define to 1 if calling Fortran from C++ should use the Visual Fortran calling convention.]) + ;; + f2c) + AC_DEFINE(F77_USES_F2C_CALLING_CONVENTION, 1, [Define to 1 if calling Fortran from C++ should use the f2c calling convention.]) + ;; + *) + AC_MSG_ERROR([to build Octave, the C++ to Fortran calling convention must be known.]) + ;; +esac + if test -n "$FFLAGS"; then AC_MSG_NOTICE([defining FFLAGS to be $FFLAGS]) fi @@ -715,7 +742,7 @@ AC_SUBST(F77_APPEND_EXTRA_UNDERSCORE) if test -z "$F77"; then - AC_MSG_ERROR([in order to build Octave, you must have a compatible Fortran compiler or wrapper script for f2c that functions as a Fortran compiler installed and in your path. See the file INSTALL for more information.]) + AC_MSG_ERROR([to build Octave, you must have a compatible Fortran compiler or wrapper script for f2c that functions as a Fortran compiler installed and in your path. See the file INSTALL for more information.]) fi OCTAVE_CHECK_FUNC_FORTRAN_ISNAN @@ -756,7 +783,7 @@ OCTAVE_CHECK_SIZEOF_FORTRAN_INTEGER fi if test $octave_cv_sizeof_fortran_integer = no; then - AC_MSG_ERROR([in order to build Octave with 64-bit indexing support your Fortran compiler must have an option for setting the default integer size to 8 bytes. See the file INSTALL for more information.]) + AC_MSG_ERROR([to build Octave with 64-bit indexing support your Fortran compiler must have an option for setting the default integer size to 8 bytes. See the file INSTALL for more information.]) fi else AC_MSG_ERROR([your Fortran compiler must have an option to make integers the same size as octave_idx_type ($OCTAVE_IDX_TYPE). See the file INSTALL for more information.])
--- a/liboctave/cruft/misc/f77-fcn.c Sun Jul 17 12:42:37 2016 -0400 +++ b/liboctave/cruft/misc/f77-fcn.c Mon Jul 18 09:56:41 2016 -0400 @@ -36,15 +36,21 @@ XSTOPX jumps back to the entry point for the Fortran function that called us. Then the calling function should do whatever cleanup - is necessary. */ + is necessary. + + Note that the order of arguments for the Visual Fortran function + signature is the same as for gfortran and f2c only becuase there is + a single assumed size character string argument. Visual Fortran + inserts the length after each character string argument, f2c appends + all length arguments at the end of the parameter list, and gfortran + appends length arguments for assumed size character strings to the + end of the list (ignoring others). */ F77_RET_T #if defined (F77_USES_CRAY_CALLING_CONVENTION) F77_FUNC (xstopx, XSTOPX) (octave_cray_ftn_ch_dsc desc) -#elif defined (F77_USES_VISUAL_FORTRAN_CALLING_CONVENTION) -F77_FUNC (xstopx, XSTOPX) (const char *s, int slen) #else -F77_FUNC (xstopx, XSTOPX) (const char *s, long slen) +F77_FUNC (xstopx, XSTOPX) (const char *s, F77_CHAR_ARG_LEN_TYPE slen) #endif { #if defined (F77_USES_CRAY_CALLING_CONVENTION)
--- a/liboctave/cruft/misc/f77-fcn.h Sun Jul 17 12:42:37 2016 -0400 +++ b/liboctave/cruft/misc/f77-fcn.h Mon Jul 18 09:56:41 2016 -0400 @@ -86,13 +86,10 @@ The following macros are used for handling Fortran <-> C calling conventions. They are defined below for three different types of -systems, Cray (possibly now obsolete), Visual Fortran, and any system -that is compatible with the f2c calling conventions, including g77 and -gfortran. Note that gfortran is not completely compatible with the -f2c calling conventions, but that we only use the parts that are -compatible. For example, f2c and gfortran differ in the way they -handle Fortran functions that return complex values, but Octave does -not call any Fortran functions like that directly from C or C++. +systems, Cray (possibly now obsolete), Visual Fortran, and gfortran. +Note that we don't attempt to handle Fortran functions, we always use +subroutine wrappers for them and pass the return value as an extra +argument. Use these macros to pass character strings from C to Fortran: @@ -144,7 +141,10 @@ #include <fortran.h> -/* Use these macros to pass character strings from C to Fortran. */ +/* Use these macros to pass character strings from C to Fortran. Cray + Fortran uses a descriptor structure to pass a pointer to the string + and the length in a single argument. */ + #define F77_CHAR_ARG(x) octave_make_cray_ftn_ch_dsc (x, strlen (x)) #define F77_CONST_CHAR_ARG(x) \ octave_make_cray_const_ftn_ch_dsc (x, strlen (x)) @@ -153,9 +153,10 @@ #define F77_CXX_STRING_ARG(x) \ octave_make_cray_const_ftn_ch_dsc (x.c_str (), x.length ()) #define F77_CHAR_ARG_LEN(l) +#define F77_CHAR_ARG_LEN_TYPE +#define F77_CHAR_ARG_LEN_DECL #define F77_CHAR_ARG_DECL octave_cray_ftn_ch_dsc #define F77_CONST_CHAR_ARG_DECL octave_cray_ftn_ch_dsc -#define F77_CHAR_ARG_LEN_DECL /* Use these macros to write C-language functions that accept Fortran-style character strings. */ @@ -171,6 +172,7 @@ supposed to act like Fortran subroutines. F77_NORETURN is intended to be used as the last statement of such a function that has been tagged with a "noreturn" attribute. */ + #define F77_RETURN(retval) return retval; #if defined (HAVE_OCTAVE_NORETURN_ATTR) # define F77_NORETURN(retval) @@ -223,19 +225,23 @@ #elif defined (F77_USES_VISUAL_FORTRAN_CALLING_CONVENTION) -/* Use these macros to pass character strings from C to Fortran. */ +/* Use these macros to pass character strings from C to Fortran. + Visual Fortran inserts the length after each character string + argument. */ + #define F77_CHAR_ARG(x) x, strlen (x) #define F77_CONST_CHAR_ARG(x) F77_CHAR_ARG (x) #define F77_CHAR_ARG2(x, l) x, l #define F77_CONST_CHAR_ARG2(x, l) F77_CHAR_ARG2 (x, l) #define F77_CXX_STRING_ARG(x) F77_CONST_CHAR_ARG2 (x.c_str (), x.length ()) #define F77_CHAR_ARG_LEN(l) -#define F77_CHAR_ARG_DECL char *, int -#define F77_CONST_CHAR_ARG_DECL const char *, int +#define F77_CHAR_ARG_LEN_TYPE int #define F77_CHAR_ARG_LEN_DECL +#define F77_CHAR_ARG_DECL char *, F77_CHAR_ARG_LEN_TYPE +#define F77_CONST_CHAR_ARG_DECL const char *, F77_CHAR_ARG_LEN_TYPE -#define F77_CHAR_ARG_DEF(s, len) char *s, int len -#define F77_CONST_CHAR_ARG_DEF(s, len) const char *s, int len +#define F77_CHAR_ARG_DEF(s, len) char *s, F77_CHAR_ARG_LEN_TYPE len +#define F77_CONST_CHAR_ARG_DEF(s, len) const char *s, F77_CHAR_ARG_LEN_TYPE len #define F77_CHAR_ARG_LEN_DEF(len) #define F77_CHAR_ARG_USE(s) s #define F77_CHAR_ARG_LEN_USE(s, len) len @@ -245,9 +251,17 @@ #define F77_RETURN(retval) return; #define F77_NORETURN(retval) -#else +#elif defined (F77_USES_GFORTRAN_CALLING_CONVENTION) + +/* Use these macros to pass character strings from C to Fortran. + gfortran appends length arguments for assumed size character + strings to the and ignores others. -/* Assume f2c-compatible calling convention. */ + FIXME: I don't think we correctly handle the case of mixing some + fixed-length and some assumed-length character string arguments as + we don't handle each case separately, so it seems there could be + mismatch? However, I don't think we currently have to handle this + case in Octave. */ #define F77_CHAR_ARG(x) x #define F77_CONST_CHAR_ARG(x) F77_CHAR_ARG (x) @@ -255,13 +269,47 @@ #define F77_CONST_CHAR_ARG2(x, l) F77_CHAR_ARG2 (x, l) #define F77_CXX_STRING_ARG(x) F77_CONST_CHAR_ARG2 (x.c_str (), x.length ()) #define F77_CHAR_ARG_LEN(l) , l +#define F77_CHAR_ARG_LEN_TYPE int +#define F77_CHAR_ARG_LEN_DECL , F77_CHAR_ARG_LEN_TYPE #define F77_CHAR_ARG_DECL char * #define F77_CONST_CHAR_ARG_DECL const char * -#define F77_CHAR_ARG_LEN_DECL , long #define F77_CHAR_ARG_DEF(s, len) char *s #define F77_CONST_CHAR_ARG_DEF(s, len) const char *s -#define F77_CHAR_ARG_LEN_DEF(len) , long len +#define F77_CHAR_ARG_LEN_DEF(len) , F77_CHAR_ARG_LEN_TYPE len +#define F77_CHAR_ARG_USE(s) s +#define F77_CHAR_ARG_LEN_USE(s, len) len + +#define F77_RET_T void + +#define F77_RETURN(retval) return retval; +#if defined (HAVE_OCTAVE_NORETURN_ATTR) +# define F77_NORETURN(retval) +#else +# define F77_NORETURN(retval) return retval; +#endif + +#elif defined (F77_USES_F2C_CALLING_CONVENTION) + +/* Assume f2c-compatible calling convention. */ + +/* Use these macros to pass character strings from C to Fortran. f2c + appends all length arguments at the end of the parameter list. */ + +#define F77_CHAR_ARG(x) x +#define F77_CONST_CHAR_ARG(x) F77_CHAR_ARG (x) +#define F77_CHAR_ARG2(x, l) x +#define F77_CONST_CHAR_ARG2(x, l) F77_CHAR_ARG2 (x, l) +#define F77_CXX_STRING_ARG(x) F77_CONST_CHAR_ARG2 (x.c_str (), x.length ()) +#define F77_CHAR_ARG_LEN(l) , l +#define F77_CHAR_ARG_LEN_TYPE long +#define F77_CHAR_ARG_LEN_DECL , F77_CHAR_ARG_LEN_TYPE +#define F77_CHAR_ARG_DECL char * +#define F77_CONST_CHAR_ARG_DECL const char * + +#define F77_CHAR_ARG_DEF(s, len) char *s +#define F77_CONST_CHAR_ARG_DEF(s, len) const char *s +#define F77_CHAR_ARG_LEN_DEF(len) , F77_CHAR_ARG_LEN_TYPE len #define F77_CHAR_ARG_USE(s) s #define F77_CHAR_ARG_LEN_USE(s, len) len @@ -274,6 +322,10 @@ # define F77_NORETURN(retval) return retval; #endif +#else + +#error "unknown C++ to Fortran calling convention" + #endif #define F77_DBLE double @@ -294,7 +346,6 @@ memcpy (cs, F77_CHAR_ARG_USE (s), F77_CHAR_ARG_LEN_USE (s, len)); \ cs[F77_CHAR_ARG_LEN_USE(s, len)] = '\0' - OCTAVE_NORETURN OCTAVE_API extern F77_RET_T F77_FUNC (xstopx, XSTOPX) (F77_CONST_CHAR_ARG_DECL