When generating C prototypes for Fortran procedures with the
-fc-prototypes and -fc-prototypes-external options, print a snippet
defining macros for complex types, and add C++ support by suppressing
mangling.

fortran/ChangeLog:

2019-05-12  Janne Blomqvist  <j...@gcc.gnu.org>

        * dump-parse-tree.c (get_c_type_name): Use macros for complex type
        names.
        * parse.c (gfc_parse_file): Define complex macros, add CPP support
        when printing C prototypes.

Ok for trunk?
---
 gcc/fortran/dump-parse-tree.c | 12 ++++++------
 gcc/fortran/parse.c           | 22 ++++++++++++++++++++++
 2 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/gcc/fortran/dump-parse-tree.c b/gcc/fortran/dump-parse-tree.c
index 54af5dfd50d..21305243522 100644
--- a/gcc/fortran/dump-parse-tree.c
+++ b/gcc/fortran/dump-parse-tree.c
@@ -3143,11 +3143,11 @@ get_c_type_name (gfc_typespec *ts, gfc_array_spec *as, 
const char **pre,
          else if (strcmp (*type_name, "size_t") == 0)
            *type_name = "ssize_t";
          else if (strcmp (*type_name, "float_complex") == 0)
-           *type_name = "float complex";
+           *type_name = "FLOAT_COMPLEX";
          else if (strcmp (*type_name, "double_complex") == 0)
-           *type_name = "double complex";
+           *type_name = "DOUBLE_COMPLEX";
          else if (strcmp (*type_name, "long_double_complex") == 0)
-           *type_name = "long double complex";
+           *type_name = "LONG_DOUBLE_COMPLEX";
 
          ret = T_OK;
        }
@@ -3166,11 +3166,11 @@ get_c_type_name (gfc_typespec *ts, gfc_array_spec *as, 
const char **pre,
                  else if (strcmp (*type_name, "size_t") == 0)
                    *type_name = "ssize_t";
                  else if (strcmp (*type_name, "float_complex") == 0)
-                   *type_name = "float complex";
+                   *type_name = "FLOAT_COMPLEX";
                  else if (strcmp (*type_name, "double_complex") == 0)
-                   *type_name = "double complex";
+                   *type_name = "DOUBLE_COMPLEX";
                  else if (strcmp (*type_name, "long_double_complex") == 0)
-                   *type_name = "long double complex";
+                   *type_name = "LONG_DOUBLE_COMPLEX";
 
                  ret = T_WARN;
                  break;
diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index 9d693595e20..8077da870b0 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -6331,6 +6331,24 @@ done:
       }
 
   /* Dump C prototypes.  */
+  if (flag_c_prototypes || flag_c_prototypes_external)
+    {
+      fprintf (stdout,
+              _("#include <stddef.h>\n"
+                "#ifdef __cplusplus\n"
+                "#include <complex>\n"
+                "#define FLOAT_COMPLEX std::complex<float>\n"
+                "#define DOUBLE_COMPLEX std::complex<double>\n"
+                "#define LONG_DOUBLE_COMPLEX std::complex<long double>\n"
+                "extern \"C\" {\n"
+                "#else\n"
+                "#define FLOAT_COMPLEX float _Complex\n"
+                "#define DOUBLE_COMPLEX double _Complex\n"
+                "#define LONG_DOUBLE_COMPLEX long double _Complex\n"
+                "#endif\n\n"));
+    }
+
+  /* First dump BIND(C) prototypes.  */
   if (flag_c_prototypes)
     {
       for (gfc_current_ns = gfc_global_ns_list; gfc_current_ns;
@@ -6342,6 +6360,10 @@ done:
   if (flag_c_prototypes_external)
     gfc_dump_external_c_prototypes (stdout);
 
+  if (flag_c_prototypes || flag_c_prototypes_external)
+    fprintf (stdout,
+            _("\n#ifdef __cplusplus\n}\n#endif\n"));
+
   /* Do the translation.  */
   translate_all_program_units (gfc_global_ns_list);
 
-- 
2.17.1

Reply via email to