re PR fortran/90351 (-fc-prototypes does not dump prototypes for external procedures)
2019-05-08 Thomas Koenig <tkoenig@gcc.gnu.org> PR fortran/90351 PR fortran/90329 * gfortran.dg/dump-parse-tree.c: Include version.h. (gfc_dump_external_c_prototypes): New function. (get_c_type_name): Select "char" as a name for a simple char. Adjust to handling external functions. Also handle complex. (write_decl): Add argument bind_c. Adjust for dumping of external procedures. (write_proc): Likewise. (write_interop_decl): Add bind_c argument to call of write_proc. * gfortran.h: Add prototype for gfc_dump_external_c_prototypes. * lang.opt: Add -fc-prototypes-external flag. * parse.c (gfc_parse_file): Move dumping of BIND(C) prototypes. Call gfc_dump_external_c_prototypes if option is set. * invoke.texi: Document -fc-prototypes-external. From-SVN: r271018
This commit is contained in:
parent
8ba2bda8e4
commit
6328ce1f83
6 changed files with 150 additions and 26 deletions
|
@ -1,3 +1,21 @@
|
||||||
|
2019-05-08 Thomas Koenig <tkoenig@gcc.gnu.org>
|
||||||
|
|
||||||
|
PR fortran/90351
|
||||||
|
PR fortran/90329
|
||||||
|
* gfortran.dg/dump-parse-tree.c: Include version.h.
|
||||||
|
(gfc_dump_external_c_prototypes): New function.
|
||||||
|
(get_c_type_name): Select "char" as a name for a simple char.
|
||||||
|
Adjust to handling external functions. Also handle complex.
|
||||||
|
(write_decl): Add argument bind_c. Adjust for dumping of external
|
||||||
|
procedures.
|
||||||
|
(write_proc): Likewise.
|
||||||
|
(write_interop_decl): Add bind_c argument to call of write_proc.
|
||||||
|
* gfortran.h: Add prototype for gfc_dump_external_c_prototypes.
|
||||||
|
* lang.opt: Add -fc-prototypes-external flag.
|
||||||
|
* parse.c (gfc_parse_file): Move dumping of BIND(C) prototypes.
|
||||||
|
Call gfc_dump_external_c_prototypes if option is set.
|
||||||
|
* invoke.texi: Document -fc-prototypes-external.
|
||||||
|
|
||||||
2019-05-06 Steven G. Kargl <kargl@gcc.gnu.org>
|
2019-05-06 Steven G. Kargl <kargl@gcc.gnu.org>
|
||||||
|
|
||||||
PR fortran/90290
|
PR fortran/90290
|
||||||
|
|
|
@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see
|
||||||
#include "coretypes.h"
|
#include "coretypes.h"
|
||||||
#include "gfortran.h"
|
#include "gfortran.h"
|
||||||
#include "constructor.h"
|
#include "constructor.h"
|
||||||
|
#include "version.h"
|
||||||
|
|
||||||
/* Keep track of indentation for symbol tree dumps. */
|
/* Keep track of indentation for symbol tree dumps. */
|
||||||
static int show_level = 0;
|
static int show_level = 0;
|
||||||
|
@ -3074,6 +3075,7 @@ gfc_dump_parse_tree (gfc_namespace *ns, FILE *file)
|
||||||
/* This part writes BIND(C) definition for use in external C programs. */
|
/* This part writes BIND(C) definition for use in external C programs. */
|
||||||
|
|
||||||
static void write_interop_decl (gfc_symbol *);
|
static void write_interop_decl (gfc_symbol *);
|
||||||
|
static void write_proc (gfc_symbol *, bool);
|
||||||
|
|
||||||
void
|
void
|
||||||
gfc_dump_c_prototypes (gfc_namespace *ns, FILE *file)
|
gfc_dump_c_prototypes (gfc_namespace *ns, FILE *file)
|
||||||
|
@ -3086,6 +3088,33 @@ gfc_dump_c_prototypes (gfc_namespace *ns, FILE *file)
|
||||||
gfc_traverse_ns (ns, write_interop_decl);
|
gfc_traverse_ns (ns, write_interop_decl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Loop over all global symbols, writing out their declrations. */
|
||||||
|
|
||||||
|
void
|
||||||
|
gfc_dump_external_c_prototypes (FILE * file)
|
||||||
|
{
|
||||||
|
dumpfile = file;
|
||||||
|
fprintf (dumpfile,
|
||||||
|
_("/* Prototypes for external procedures generated from %s\n"
|
||||||
|
" by GNU Fortran %s%s.\n\n"
|
||||||
|
" Use of this interface is discouraged, consider using the\n"
|
||||||
|
" BIND(C) feature of standard Fortran instead. */\n\n"),
|
||||||
|
gfc_source_file, pkgversion_string, version_string);
|
||||||
|
|
||||||
|
for (gfc_current_ns = gfc_global_ns_list; gfc_current_ns;
|
||||||
|
gfc_current_ns = gfc_current_ns->sibling)
|
||||||
|
{
|
||||||
|
gfc_symbol *sym = gfc_current_ns->proc_name;
|
||||||
|
|
||||||
|
if (sym == NULL || sym->attr.flavor != FL_PROCEDURE
|
||||||
|
|| sym->attr.is_bind_c)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
write_proc (sym, false);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
enum type_return { T_OK=0, T_WARN, T_ERROR };
|
enum type_return { T_OK=0, T_WARN, T_ERROR };
|
||||||
|
|
||||||
/* Return the name of the type for later output. Both function pointers and
|
/* Return the name of the type for later output. Both function pointers and
|
||||||
|
@ -3104,7 +3133,7 @@ get_c_type_name (gfc_typespec *ts, gfc_array_spec *as, const char **pre,
|
||||||
*asterisk = false;
|
*asterisk = false;
|
||||||
*post = "";
|
*post = "";
|
||||||
*type_name = "<error>";
|
*type_name = "<error>";
|
||||||
if (ts->type == BT_REAL || ts->type == BT_INTEGER)
|
if (ts->type == BT_REAL || ts->type == BT_INTEGER || ts->type == BT_COMPLEX)
|
||||||
{
|
{
|
||||||
if (ts->is_c_interop && ts->interop_kind)
|
if (ts->is_c_interop && ts->interop_kind)
|
||||||
{
|
{
|
||||||
|
@ -3113,6 +3142,12 @@ get_c_type_name (gfc_typespec *ts, gfc_array_spec *as, const char **pre,
|
||||||
*type_name = "signed char";
|
*type_name = "signed char";
|
||||||
else if (strcmp (*type_name, "size_t") == 0)
|
else if (strcmp (*type_name, "size_t") == 0)
|
||||||
*type_name = "ssize_t";
|
*type_name = "ssize_t";
|
||||||
|
else if (strcmp (*type_name, "float_complex") == 0)
|
||||||
|
*type_name = "float complex";
|
||||||
|
else if (strcmp (*type_name, "double_complex") == 0)
|
||||||
|
*type_name = "double complex";
|
||||||
|
else if (strcmp (*type_name, "long_double_complex") == 0)
|
||||||
|
*type_name = "long double complex";
|
||||||
|
|
||||||
ret = T_OK;
|
ret = T_OK;
|
||||||
}
|
}
|
||||||
|
@ -3130,6 +3165,12 @@ get_c_type_name (gfc_typespec *ts, gfc_array_spec *as, const char **pre,
|
||||||
*type_name = "signed char";
|
*type_name = "signed char";
|
||||||
else if (strcmp (*type_name, "size_t") == 0)
|
else if (strcmp (*type_name, "size_t") == 0)
|
||||||
*type_name = "ssize_t";
|
*type_name = "ssize_t";
|
||||||
|
else if (strcmp (*type_name, "float_complex") == 0)
|
||||||
|
*type_name = "float complex";
|
||||||
|
else if (strcmp (*type_name, "double_complex") == 0)
|
||||||
|
*type_name = "double complex";
|
||||||
|
else if (strcmp (*type_name, "long_double_complex") == 0)
|
||||||
|
*type_name = "long double complex";
|
||||||
|
|
||||||
ret = T_WARN;
|
ret = T_WARN;
|
||||||
break;
|
break;
|
||||||
|
@ -3167,16 +3208,21 @@ get_c_type_name (gfc_typespec *ts, gfc_array_spec *as, const char **pre,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Let's select an appropriate int, with a warning. */
|
if (ts->kind == gfc_default_character_kind)
|
||||||
for (int i = 0; i < ISOCBINDING_NUMBER; i++)
|
*type_name = "char";
|
||||||
{
|
else
|
||||||
if (c_interop_kinds_table[i].f90_type == BT_INTEGER
|
/* Let's select an appropriate int. */
|
||||||
&& c_interop_kinds_table[i].value == ts->kind)
|
for (int i = 0; i < ISOCBINDING_NUMBER; i++)
|
||||||
{
|
{
|
||||||
*type_name = c_interop_kinds_table[i].name + 2;
|
if (c_interop_kinds_table[i].f90_type == BT_INTEGER
|
||||||
ret = T_WARN;
|
&& c_interop_kinds_table[i].value == ts->kind)
|
||||||
}
|
{
|
||||||
|
*type_name = c_interop_kinds_table[i].name + 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
ret = T_WARN;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ts->type == BT_DERIVED)
|
else if (ts->type == BT_DERIVED)
|
||||||
|
@ -3200,12 +3246,14 @@ get_c_type_name (gfc_typespec *ts, gfc_array_spec *as, const char **pre,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*asterisk = true;
|
*asterisk = true;
|
||||||
|
ret = T_OK;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*type_name = ts->u.derived->name;
|
*type_name = ts->u.derived->name;
|
||||||
|
|
||||||
ret = T_OK;
|
ret = T_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret != T_ERROR && as)
|
if (ret != T_ERROR && as)
|
||||||
{
|
{
|
||||||
mpz_t sz;
|
mpz_t sz;
|
||||||
|
@ -3222,7 +3270,7 @@ get_c_type_name (gfc_typespec *ts, gfc_array_spec *as, const char **pre,
|
||||||
/* Write out a declaration. */
|
/* Write out a declaration. */
|
||||||
static void
|
static void
|
||||||
write_decl (gfc_typespec *ts, gfc_array_spec *as, const char *sym_name,
|
write_decl (gfc_typespec *ts, gfc_array_spec *as, const char *sym_name,
|
||||||
bool func_ret, locus *where)
|
bool func_ret, locus *where, bool bind_c)
|
||||||
{
|
{
|
||||||
const char *pre, *type_name, *post;
|
const char *pre, *type_name, *post;
|
||||||
bool asterisk;
|
bool asterisk;
|
||||||
|
@ -3245,7 +3293,7 @@ write_decl (gfc_typespec *ts, gfc_array_spec *as, const char *sym_name,
|
||||||
fputs (sym_name, dumpfile);
|
fputs (sym_name, dumpfile);
|
||||||
fputs (post, dumpfile);
|
fputs (post, dumpfile);
|
||||||
|
|
||||||
if (rok == T_WARN)
|
if (rok == T_WARN && bind_c)
|
||||||
fprintf (dumpfile," /* WARNING: Converting '%s' to interoperable type */",
|
fprintf (dumpfile," /* WARNING: Converting '%s' to interoperable type */",
|
||||||
gfc_typename (ts));
|
gfc_typename (ts));
|
||||||
}
|
}
|
||||||
|
@ -3262,7 +3310,7 @@ write_type (gfc_symbol *sym)
|
||||||
for (c = sym->components; c; c = c->next)
|
for (c = sym->components; c; c = c->next)
|
||||||
{
|
{
|
||||||
fputs (" ", dumpfile);
|
fputs (" ", dumpfile);
|
||||||
write_decl (&(c->ts), c->as, c->name, false, &sym->declared_at);
|
write_decl (&(c->ts), c->as, c->name, false, &sym->declared_at, true);
|
||||||
fputs (";\n", dumpfile);
|
fputs (";\n", dumpfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3284,14 +3332,14 @@ write_variable (gfc_symbol *sym)
|
||||||
sym_name = sym->name;
|
sym_name = sym->name;
|
||||||
|
|
||||||
fputs ("extern ", dumpfile);
|
fputs ("extern ", dumpfile);
|
||||||
write_decl (&(sym->ts), sym->as, sym_name, false, &sym->declared_at);
|
write_decl (&(sym->ts), sym->as, sym_name, false, &sym->declared_at, true);
|
||||||
fputs (";\n", dumpfile);
|
fputs (";\n", dumpfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Write out a procedure, including its arguments. */
|
/* Write out a procedure, including its arguments. */
|
||||||
static void
|
static void
|
||||||
write_proc (gfc_symbol *sym)
|
write_proc (gfc_symbol *sym, bool bind_c)
|
||||||
{
|
{
|
||||||
const char *pre, *type_name, *post;
|
const char *pre, *type_name, *post;
|
||||||
bool asterisk;
|
bool asterisk;
|
||||||
|
@ -3299,22 +3347,35 @@ write_proc (gfc_symbol *sym)
|
||||||
gfc_formal_arglist *f;
|
gfc_formal_arglist *f;
|
||||||
const char *sym_name;
|
const char *sym_name;
|
||||||
const char *intent_in;
|
const char *intent_in;
|
||||||
|
bool external_character;
|
||||||
|
|
||||||
|
external_character = sym->ts.type == BT_CHARACTER && !bind_c;
|
||||||
|
|
||||||
if (sym->binding_label)
|
if (sym->binding_label)
|
||||||
sym_name = sym->binding_label;
|
sym_name = sym->binding_label;
|
||||||
else
|
else
|
||||||
sym_name = sym->name;
|
sym_name = sym->name;
|
||||||
|
|
||||||
if (sym->ts.type == BT_UNKNOWN)
|
if (sym->ts.type == BT_UNKNOWN || external_character)
|
||||||
{
|
{
|
||||||
fprintf (dumpfile, "void ");
|
fprintf (dumpfile, "void ");
|
||||||
fputs (sym_name, dumpfile);
|
fputs (sym_name, dumpfile);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
write_decl (&(sym->ts), sym->as, sym_name, true, &sym->declared_at);
|
write_decl (&(sym->ts), sym->as, sym_name, true, &sym->declared_at, bind_c);
|
||||||
|
|
||||||
|
if (!bind_c)
|
||||||
|
fputs ("_", dumpfile);
|
||||||
|
|
||||||
fputs (" (", dumpfile);
|
fputs (" (", dumpfile);
|
||||||
|
if (external_character)
|
||||||
|
{
|
||||||
|
fprintf (dumpfile, "char *result_%s, size_t result_%s_len",
|
||||||
|
sym_name, sym_name);
|
||||||
|
if (sym->formal)
|
||||||
|
fputs (", ", dumpfile);
|
||||||
|
}
|
||||||
|
|
||||||
for (f = sym->formal; f; f = f->next)
|
for (f = sym->formal; f; f = f->next)
|
||||||
{
|
{
|
||||||
gfc_symbol *s;
|
gfc_symbol *s;
|
||||||
|
@ -3325,7 +3386,7 @@ write_proc (gfc_symbol *sym)
|
||||||
{
|
{
|
||||||
gfc_error_now ("Cannot convert %qs to interoperable type at %L",
|
gfc_error_now ("Cannot convert %qs to interoperable type at %L",
|
||||||
gfc_typename (&s->ts), &s->declared_at);
|
gfc_typename (&s->ts), &s->declared_at);
|
||||||
fprintf (stderr, "/* Cannot convert '%s' to interoperable type */",
|
fprintf (dumpfile, "/* Cannot convert '%s' to interoperable type */",
|
||||||
gfc_typename (&s->ts));
|
gfc_typename (&s->ts));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3346,12 +3407,17 @@ write_proc (gfc_symbol *sym)
|
||||||
|
|
||||||
fputs (s->name, dumpfile);
|
fputs (s->name, dumpfile);
|
||||||
fputs (post, dumpfile);
|
fputs (post, dumpfile);
|
||||||
if (rok == T_WARN)
|
if (bind_c && rok == T_WARN)
|
||||||
fputs(" /* WARNING: non-interoperable KIND */ ", dumpfile);
|
fputs(" /* WARNING: non-interoperable KIND */ ", dumpfile);
|
||||||
|
|
||||||
if (f->next)
|
if (f->next)
|
||||||
fputs(", ", dumpfile);
|
fputs(", ", dumpfile);
|
||||||
}
|
}
|
||||||
|
if (!bind_c)
|
||||||
|
for (f = sym->formal; f; f = f->next)
|
||||||
|
if (f->sym->ts.type == BT_CHARACTER)
|
||||||
|
fprintf (dumpfile, ", size_t %s_len", f->sym->name);
|
||||||
|
|
||||||
fputs (");\n", dumpfile);
|
fputs (");\n", dumpfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3375,5 +3441,5 @@ write_interop_decl (gfc_symbol *sym)
|
||||||
else if (sym->attr.flavor == FL_DERIVED)
|
else if (sym->attr.flavor == FL_DERIVED)
|
||||||
write_type (sym);
|
write_type (sym);
|
||||||
else if (sym->attr.flavor == FL_PROCEDURE)
|
else if (sym->attr.flavor == FL_PROCEDURE)
|
||||||
write_proc (sym);
|
write_proc (sym, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3462,6 +3462,7 @@ void gfc_delete_bbt (void *, void *, compare_fn);
|
||||||
/* dump-parse-tree.c */
|
/* dump-parse-tree.c */
|
||||||
void gfc_dump_parse_tree (gfc_namespace *, FILE *);
|
void gfc_dump_parse_tree (gfc_namespace *, FILE *);
|
||||||
void gfc_dump_c_prototypes (gfc_namespace *, FILE *);
|
void gfc_dump_c_prototypes (gfc_namespace *, FILE *);
|
||||||
|
void gfc_dump_external_c_prototypes (FILE *);
|
||||||
|
|
||||||
/* parse.c */
|
/* parse.c */
|
||||||
bool gfc_parse_file (void);
|
bool gfc_parse_file (void);
|
||||||
|
|
|
@ -176,7 +176,7 @@ and warnings}.
|
||||||
|
|
||||||
@item Interoperability Options
|
@item Interoperability Options
|
||||||
@xref{Interoperability Options,,Options for interoperability}.
|
@xref{Interoperability Options,,Options for interoperability}.
|
||||||
@gccoptlist{-fc-prototypes}
|
@gccoptlist{-fc-prototypes -fc-prototypes-external}
|
||||||
|
|
||||||
@item Code Generation Options
|
@item Code Generation Options
|
||||||
@xref{Code Gen Options,,Options for code generation conventions}.
|
@xref{Code Gen Options,,Options for code generation conventions}.
|
||||||
|
@ -1870,7 +1870,7 @@ shared by @command{gfortran}, @command{gcc}, and other GNU compilers.
|
||||||
|
|
||||||
@item -fc-prototypes
|
@item -fc-prototypes
|
||||||
@opindex @code{c-prototypes}
|
@opindex @code{c-prototypes}
|
||||||
@cindex Generating C prototypes from Fortran source code
|
@cindex Generating C prototypes from Fortran BIND(C) enteties
|
||||||
This option will generate C prototypes from @code{BIND(C)} variable
|
This option will generate C prototypes from @code{BIND(C)} variable
|
||||||
declarations, types and procedure interfaces and writes them to
|
declarations, types and procedure interfaces and writes them to
|
||||||
standard output. @code{ENUM} is not yet supported.
|
standard output. @code{ENUM} is not yet supported.
|
||||||
|
@ -1889,6 +1889,32 @@ $ gfortran -fc-prototypes -fsyntax-only foo.f90 > foo.h
|
||||||
@end smallexample
|
@end smallexample
|
||||||
where the C code intended for interoperating with the Fortran code
|
where the C code intended for interoperating with the Fortran code
|
||||||
then uses @code{#include "foo.h"}.
|
then uses @code{#include "foo.h"}.
|
||||||
|
|
||||||
|
@item -fc-prototypes-external
|
||||||
|
@opindex @code{c-prototypes-external}
|
||||||
|
@cindex Generating C prototypes from external procedures
|
||||||
|
This option will generate C prototypes from external functions and
|
||||||
|
subroutines and write them to standard output. This may be useful for
|
||||||
|
making sure that C bindings to Fortran code are correct. This option
|
||||||
|
does not generate prototypes for @code{BIND(C)} procedures, use
|
||||||
|
@option{-fc-prototypes} for that.
|
||||||
|
|
||||||
|
The generated prototypes may need inclusion of an appropriate
|
||||||
|
header, such as as @code{<stdint.h>} or @code{<stdlib.h>}.
|
||||||
|
|
||||||
|
This is primarily meant for legacy code to ensure that existing C
|
||||||
|
bindings match what @command{gfortran} emits. The generated C
|
||||||
|
prototypes should be correct for the current version of the compiler,
|
||||||
|
but may not match what other compilers or earlier versions of
|
||||||
|
@command{gfortran} need. For new developments, use of the
|
||||||
|
@code{BIND(C)} features is recommended.
|
||||||
|
|
||||||
|
Example of use:
|
||||||
|
@smallexample
|
||||||
|
$ gfortran -fc-prototypes-external -fsyntax-only foo.f > foo.h
|
||||||
|
@end smallexample
|
||||||
|
where the C code intended for interoperating with the Fortran code
|
||||||
|
then uses @code{#include "foo.h"}.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@node Environment Variables
|
@node Environment Variables
|
||||||
|
|
|
@ -428,6 +428,10 @@ fc-prototypes
|
||||||
Fortran Var(flag_c_prototypes)
|
Fortran Var(flag_c_prototypes)
|
||||||
Generate C prototypes from BIND(C) declarations.
|
Generate C prototypes from BIND(C) declarations.
|
||||||
|
|
||||||
|
fc-prototypes-external
|
||||||
|
Fortran Var(flag_c_prototypes_external)
|
||||||
|
Generate C prototypes from non-BIND(C) external procedure definitions.
|
||||||
|
|
||||||
fd-lines-as-code
|
fd-lines-as-code
|
||||||
Fortran RejectNegative
|
Fortran RejectNegative
|
||||||
Ignore 'D' in column one in fixed form.
|
Ignore 'D' in column one in fixed form.
|
||||||
|
|
|
@ -6278,9 +6278,6 @@ loop:
|
||||||
if (flag_dump_fortran_original)
|
if (flag_dump_fortran_original)
|
||||||
gfc_dump_parse_tree (gfc_current_ns, stdout);
|
gfc_dump_parse_tree (gfc_current_ns, stdout);
|
||||||
|
|
||||||
if (flag_c_prototypes)
|
|
||||||
gfc_dump_c_prototypes (gfc_current_ns, stdout);
|
|
||||||
|
|
||||||
gfc_get_errors (NULL, &errors);
|
gfc_get_errors (NULL, &errors);
|
||||||
if (s.state == COMP_MODULE || s.state == COMP_SUBMODULE)
|
if (s.state == COMP_MODULE || s.state == COMP_SUBMODULE)
|
||||||
{
|
{
|
||||||
|
@ -6333,6 +6330,18 @@ done:
|
||||||
fputs ("------------------------------------------\n\n", stdout);
|
fputs ("------------------------------------------\n\n", stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Dump C prototypes. */
|
||||||
|
if (flag_c_prototypes)
|
||||||
|
{
|
||||||
|
for (gfc_current_ns = gfc_global_ns_list; gfc_current_ns;
|
||||||
|
gfc_current_ns = gfc_current_ns->sibling)
|
||||||
|
gfc_dump_c_prototypes (gfc_current_ns, stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dump external prototypes. */
|
||||||
|
if (flag_c_prototypes_external)
|
||||||
|
gfc_dump_external_c_prototypes (stdout);
|
||||||
|
|
||||||
/* Do the translation. */
|
/* Do the translation. */
|
||||||
translate_all_program_units (gfc_global_ns_list);
|
translate_all_program_units (gfc_global_ns_list);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue