diff mbox series

[1/3,PR,libfortran/101305] Bind(C): Fix type encodings in ISO_Fortran_binding.h

Message ID 20210713212859.1532449-2-sandra@codesourcery.com
State New
Headers show
Series Bind(C): Fix kind/size mappings | expand

Commit Message

Sandra Loosemore July 13, 2021, 9:28 p.m. UTC
ISO_Fortran_binding.h had many incorrect hardwired kind encodings in
the definitions of the CFI_type_* macros.  Additionally, not all
targets support all the defined type encodings, and the Fortran
standard requires those macros to have a negative value.

This patch changes ISO_Fortran_binding.h to use sizeof instead of
hard-coded sizes, and assembles it from fragments that reflect the
set of types supported by the target.

2021-07-13  Sandra Loosemore  <sandra@codesourcery.com>
	    Tobias Burnus  <tobias@codesourcery.com>

libgfortran/
	PR libfortran/101305
	* ISO_Fortran_binding.h: Fix hard-coded sizes and split into...
	* ISO_Fortran_binding-1-tmpl.h: New file.
	* ISO_Fortran_binding-2-tmpl.h: New file.
	* ISO_Fortran_binding-3-tmpl.h: New file.
	* Makefile.am: Add rule for generating ISO_Fortran_binding.h.
	Adjust pathnames to that file.
	* Makefile.in: Regenerated.
	* mk-kinds-h.sh: New file.
	* runtime/ISO_Fortran_binding.c: Fix include path.
---
 libgfortran/ISO_Fortran_binding-1-tmpl.h  | 196 ++++++++++++++++++++++++++++
 libgfortran/ISO_Fortran_binding-2-tmpl.h  |  42 ++++++
 libgfortran/ISO_Fortran_binding-3-tmpl.h  |   5 +
 libgfortran/ISO_Fortran_binding.h         | 206 ------------------------------
 libgfortran/Makefile.am                   |  15 ++-
 libgfortran/Makefile.in                   |  16 ++-
 libgfortran/mk-kinds-h.sh                 |  25 +++-
 libgfortran/runtime/ISO_Fortran_binding.c |   2 +-
 8 files changed, 292 insertions(+), 215 deletions(-)
 create mode 100644 libgfortran/ISO_Fortran_binding-1-tmpl.h
 create mode 100644 libgfortran/ISO_Fortran_binding-2-tmpl.h
 create mode 100644 libgfortran/ISO_Fortran_binding-3-tmpl.h
 delete mode 100644 libgfortran/ISO_Fortran_binding.h

Comments

Tobias Burnus July 21, 2021, 10:03 a.m. UTC | #1
On 13.07.21 23:28, Sandra Loosemore wrote:

> ISO_Fortran_binding.h had many incorrect hardwired kind encodings in
> the definitions of the CFI_type_* macros.  Additionally, not all
> targets support all the defined type encodings, and the Fortran
> standard requires those macros to have a negative value.
>
> This patch changes ISO_Fortran_binding.h to use sizeof instead of
> hard-coded sizes, and assembles it from fragments that reflect the
> set of types supported by the target.
>
> 2021-07-13  Sandra Loosemore<sandra@codesourcery.com>
>           Tobias Burnus<tobias@codesourcery.com>
>
> libgfortran/
>       PR libfortran/101305
>       * ISO_Fortran_binding.h: Fix hard-coded sizes and split into...
>       * ISO_Fortran_binding-1-tmpl.h: New file.
>       * ISO_Fortran_binding-2-tmpl.h: New file.
>       * ISO_Fortran_binding-3-tmpl.h: New file.
>       * Makefile.am: Add rule for generating ISO_Fortran_binding.h.
>       Adjust pathnames to that file.
>       * Makefile.in: Regenerated.
>       * mk-kinds-h.sh: New file.
>       * runtime/ISO_Fortran_binding.c: Fix include path.
LGTM – except for the following remark regarding a preexisting comment.

> --- /dev/null
> +++ b/libgfortran/ISO_Fortran_binding-1-tmpl.h
> +/* Error codes.
> +   CFI_INVALID_STRIDE should be defined in the standard because they are useful to the implementation of the functions.
> + */

The standard permits: "Error conditions other than those listed in this
subclause should be indicated by error codes different from the values
of the macros named in this subclause."

I personally do not like current (preexisting) the wording in the
comment – and CFI_FAILURE is also not listed, which is also not part
of Fortran standard. I think some wording along the following is
be more appropriate:
"Note that CFI_FAILURE and CFI_INVALID_STRIDE specific to GCC and not
part of the Fortran standard."


> +#define CFI_SUCCESS 0
> +#define CFI_FAILURE 1
> +#define CFI_ERROR_BASE_ADDR_NULL 2
> +#define CFI_ERROR_BASE_ADDR_NOT_NULL 3
> +#define CFI_INVALID_ELEM_LEN 4
> +#define CFI_INVALID_RANK 5
> +#define CFI_INVALID_TYPE 6
> +#define CFI_INVALID_ATTRIBUTE 7
> +#define CFI_INVALID_EXTENT 8
> +#define CFI_INVALID_STRIDE 9
> +#define CFI_INVALID_DESCRIPTOR 10
> +#define CFI_ERROR_MEM_ALLOCATION 11
> +#define CFI_ERROR_OUT_OF_BOUNDS 12

Tobias

-----------------
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955
diff mbox series

Patch

diff --git a/libgfortran/ISO_Fortran_binding-1-tmpl.h b/libgfortran/ISO_Fortran_binding-1-tmpl.h
new file mode 100644
index 0000000..dde7c3d
--- /dev/null
+++ b/libgfortran/ISO_Fortran_binding-1-tmpl.h
@@ -0,0 +1,196 @@ 
+/* Declarations for ISO Fortran binding.
+   Copyright (C) 2018-2021 Free Software Foundation, Inc.
+   Contributed by Daniel Celis Garza  <celisdanieljr@gmail.com>
+
+This file is part of the GNU Fortran runtime library (libgfortran).
+
+Libgfortran is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+Libgfortran is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef ISO_FORTRAN_BINDING_H
+#define ISO_FORTRAN_BINDING_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>  /* Standard ptrdiff_t tand size_t. */
+#include <stdint.h>  /* Integer types. */
+
+/* Constants, defined as macros. */
+#define CFI_VERSION 1
+#define CFI_MAX_RANK 15
+
+/* Attributes. */
+#define CFI_attribute_pointer 0
+#define CFI_attribute_allocatable 1
+#define CFI_attribute_other 2
+
+/* Error codes.
+   CFI_INVALID_STRIDE should be defined in the standard because they are useful to the implementation of the functions.
+ */
+#define CFI_SUCCESS 0
+#define CFI_FAILURE 1
+#define CFI_ERROR_BASE_ADDR_NULL 2
+#define CFI_ERROR_BASE_ADDR_NOT_NULL 3
+#define CFI_INVALID_ELEM_LEN 4
+#define CFI_INVALID_RANK 5
+#define CFI_INVALID_TYPE 6
+#define CFI_INVALID_ATTRIBUTE 7
+#define CFI_INVALID_EXTENT 8
+#define CFI_INVALID_STRIDE 9
+#define CFI_INVALID_DESCRIPTOR 10
+#define CFI_ERROR_MEM_ALLOCATION 11
+#define CFI_ERROR_OUT_OF_BOUNDS 12
+
+/* CFI type definitions. */
+typedef ptrdiff_t CFI_index_t;
+typedef int8_t CFI_rank_t;
+typedef int8_t CFI_attribute_t;
+typedef int16_t CFI_type_t;
+
+/* CFI_dim_t. */
+typedef struct CFI_dim_t
+  {
+    CFI_index_t lower_bound;
+    CFI_index_t extent;
+    CFI_index_t sm;
+  }
+CFI_dim_t;
+
+/* CFI_cdesc_t, C descriptors are cast to this structure as follows:
+   CFI_CDESC_T(CFI_MAX_RANK) foo;
+   CFI_cdesc_t * bar = (CFI_cdesc_t *) &foo;
+ */
+typedef struct CFI_cdesc_t
+ {
+    void *base_addr;
+    size_t elem_len;
+    int version;
+    CFI_rank_t rank;
+    CFI_attribute_t attribute;
+    CFI_type_t type;
+    CFI_dim_t dim[];
+ }
+CFI_cdesc_t;
+
+/* CFI_CDESC_T with an explicit type. */
+#define CFI_CDESC_TYPE_T(r, base_type) \
+	struct { \
+		base_type *base_addr; \
+		size_t elem_len; \
+		int version; \
+		CFI_rank_t rank; \
+		CFI_attribute_t attribute; \
+		CFI_type_t type; \
+		CFI_dim_t dim[r]; \
+	}
+#define CFI_CDESC_T(r) CFI_CDESC_TYPE_T (r, void)
+
+/* CFI function declarations. */
+extern void *CFI_address (const CFI_cdesc_t *, const CFI_index_t []);
+extern int CFI_allocate (CFI_cdesc_t *, const CFI_index_t [], const CFI_index_t [],
+			 size_t);
+extern int CFI_deallocate (CFI_cdesc_t *);
+extern int CFI_establish (CFI_cdesc_t *, void *, CFI_attribute_t, CFI_type_t, size_t,
+			  CFI_rank_t, const CFI_index_t []);
+extern int CFI_is_contiguous (const CFI_cdesc_t *);
+extern int CFI_section (CFI_cdesc_t *, const CFI_cdesc_t *, const CFI_index_t [],
+			const CFI_index_t [], const CFI_index_t []);
+extern int CFI_select_part (CFI_cdesc_t *, const CFI_cdesc_t *, size_t, size_t);
+extern int CFI_setpointer (CFI_cdesc_t *, CFI_cdesc_t *, const CFI_index_t []);
+
+/* Types and kind numbers. Allows bitwise and to reveal the intrinsic type of a kind type. It also allows us to find the kind parameter by inverting the bit-shift equation.
+   CFI_type_kind_shift = 8
+   CFI_intrinsic_type  = 0 0 0 0 0 0 0 0 0 0 1 0
+   CFI_type_kind       = 0 0 0 0 0 0 0 0 1 0 0 0
+   CFI_type_example    = CFI_intrinsic_type + (CFI_type_kind << CFI_type_kind_shift)
+   Defining the CFI_type_example.
+   CFI_type_kind       = 0 0 0 0 0 0 0 0 1 0 0 0  << CFI_type_kind_shift
+			-------------------------
+			 1 0 0 0 0 0 0 0 0 0 0 0  +
+   CFI_intrinsic_type  = 0 0 0 0 0 0 0 0 0 0 1 0
+			-------------------------
+   CFI_type_example    = 1 0 0 0 0 0 0 0 0 0 1 0
+   Finding the intrinsic type with the logical mask.
+   CFI_type_example    = 1 0 0 0 0 0 0 0 0 0 1 0  &
+   CFI_type_mask       = 0 0 0 0 1 1 1 1 1 1 1 1
+			-------------------------
+   CFI_intrinsic_type  = 0 0 0 0 0 0 0 0 0 0 1 0
+   Using the intrinsic type and kind shift to find the kind value of the type.
+   CFI_type_kind = (CFI_type_example - CFI_intrinsic_type) >> CFI_type_kind_shift
+   CFI_type_example   = 1 0 0 0 0 0 0 0 0 0 1 0  -
+   CFI_intrinsic_type = 0 0 0 0 0 0 0 0 0 0 1 0
+			-------------------------
+			1 0 0 0 0 0 0 0 0 0 0 0  >> CFI_type_kind_shift
+			-------------------------
+   CFI_type_kind      = 0 0 0 0 0 0 0 0 1 0 0 0
+ */
+#define CFI_type_mask 0xFF
+#define CFI_type_kind_shift 8
+
+/* Intrinsic types. Their kind number defines their storage size. */
+#define CFI_type_Integer 1
+#define CFI_type_Logical 2
+#define CFI_type_Real 3
+#define CFI_type_Complex 4
+#define CFI_type_Character 5
+
+/* Types with no kind. */
+#define CFI_type_struct 6
+#define CFI_type_cptr 7
+#define CFI_type_cfunptr 8
+#define CFI_type_other -1
+
+/* Types with kind parameter.
+   The kind parameter represents the type's byte size.  The exception is
+   real kind = 10, which has byte size of 128 bits but 80 bit precision.
+   Complex variables are double the byte size of their real counterparts.
+   The ucs4_char matches wchar_t if sizeof (wchar_t) == 4.
+ */
+#define CFI_type_char (CFI_type_Character + (1 << CFI_type_kind_shift))
+#define CFI_type_ucs4_char (CFI_type_Character + (4 << CFI_type_kind_shift))
+
+/* C-Fortran Interoperability types. */
+#define CFI_type_signed_char (CFI_type_Integer + (sizeof (char) << CFI_type_kind_shift))
+#define CFI_type_short (CFI_type_Integer + (sizeof (short) << CFI_type_kind_shift))
+#define CFI_type_int (CFI_type_Integer + (sizeof (int) << CFI_type_kind_shift))
+#define CFI_type_long (CFI_type_Integer + (sizeof (long) << CFI_type_kind_shift))
+#define CFI_type_long_long (CFI_type_Integer + (sizeof (long long) << CFI_type_kind_shift))
+#define CFI_type_size_t (CFI_type_Integer + (sizeof (size_t) << CFI_type_kind_shift))
+#define CFI_type_int8_t (CFI_type_Integer + (sizeof (int8_t) << CFI_type_kind_shift))
+#define CFI_type_int16_t (CFI_type_Integer + (sizeof (int16_t) << CFI_type_kind_shift))
+#define CFI_type_int32_t (CFI_type_Integer + (sizeof (int32_t) << CFI_type_kind_shift))
+#define CFI_type_int64_t (CFI_type_Integer + (sizeof (int64_t) << CFI_type_kind_shift))
+#define CFI_type_int_least8_t (CFI_type_Integer + (sizeof (int_least8_t) << CFI_type_kind_shift))
+#define CFI_type_int_least16_t (CFI_type_Integer + (sizeof (int_least16_t) << CFI_type_kind_shift))
+#define CFI_type_int_least32_t (CFI_type_Integer + (sizeof (int_least32_t) << CFI_type_kind_shift))
+#define CFI_type_int_least64_t (CFI_type_Integer + (sizeof (int_least64_t) << CFI_type_kind_shift))
+#define CFI_type_int_fast8_t (CFI_type_Integer + (sizeof (int_fast8_t) << CFI_type_kind_shift))
+#define CFI_type_int_fast16_t (CFI_type_Integer + (sizeof (int_fast16_t) << CFI_type_kind_shift))
+#define CFI_type_int_fast32_t (CFI_type_Integer + (sizeof (int_fast32_t) << CFI_type_kind_shift))
+#define CFI_type_int_fast64_t (CFI_type_Integer + (sizeof (int_fast64_t) << CFI_type_kind_shift))
+#define CFI_type_intmax_t (CFI_type_Integer + (sizeof (intmax_t) << CFI_type_kind_shift))
+#define CFI_type_intptr_t (CFI_type_Integer + (sizeof (intptr_t) << CFI_type_kind_shift))
+#define CFI_type_ptrdiff_t (CFI_type_Integer + (sizeof (ptrdiff_t) << CFI_type_kind_shift))
+#define CFI_type_Bool (CFI_type_Logical + (sizeof (_Bool) << CFI_type_kind_shift))
+#define CFI_type_float (CFI_type_Real + (sizeof (float) << CFI_type_kind_shift))
+#define CFI_type_double (CFI_type_Real + (sizeof (double) << CFI_type_kind_shift))
+#define CFI_type_float_Complex (CFI_type_Complex + (sizeof (float) << CFI_type_kind_shift))
+#define CFI_type_double_Complex (CFI_type_Complex + (sizeof (double) << CFI_type_kind_shift))
diff --git a/libgfortran/ISO_Fortran_binding-2-tmpl.h b/libgfortran/ISO_Fortran_binding-2-tmpl.h
new file mode 100644
index 0000000..ad88f8b
--- /dev/null
+++ b/libgfortran/ISO_Fortran_binding-2-tmpl.h
@@ -0,0 +1,42 @@ 
+#include "config.h"
+#include "kinds.inc"
+
+/* Note that -1 is used by CFI_type_other, hence, -2 is used for unavailable kinds.  */
+
+#if GFC_C_INT128_T_KIND == 16
+#define CFI_type_int128_t (CFI_type_Integer + (16 << CFI_type_kind_shift))
+#define CFI_type_int_least128_t (CFI_type_Integer + (16 << CFI_type_kind_shift))
+#define CFI_type_int_fast128_t (CFI_type_Integer + (16 << CFI_type_kind_shift))
+#elif GFC_C_INT128_T_KIND < 0
+#define CFI_type_int128_t -2
+#define CFI_type_int_least128_t -2
+#define CFI_type_int_fast128_t -2
+#else
+#error "Unexpected value for GFC_C_INT128_T_KIND"
+#endif 
+
+#if GFC_C_LONG_DOUBLE_KIND == 16
+#define CFI_type_long_double (CFI_type_Real + (16 << CFI_type_kind_shift))
+#define CFI_type_long_double_Complex (CFI_type_Complex + (16 << CFI_type_kind_shift))
+#elif GFC_C_LONG_DOUBLE_KIND == 10 
+#define CFI_type_long_double (CFI_type_Real + (10 << CFI_type_kind_shift))
+#define CFI_type_long_double_Complex (CFI_type_Complex + (10 << CFI_type_kind_shift))
+#elif GFC_C_LONG_DOUBLE_KIND == 8 
+#define CFI_type_long_double (CFI_type_Real + (8 << CFI_type_kind_shift))
+#define CFI_type_long_double_Complex (CFI_type_Complex + (8 << CFI_type_kind_shift))
+#elif GFC_C_LONG_DOUBLE_KIND < 0 
+#define CFI_type_long_double -2
+#define CFI_type_long_double_Complex -2
+#else
+#error "Unexpected value for GFC_C_LONG_DOUBLE_KIND"
+#endif 
+
+#if GFC_C_FLOAT128_KIND == 16
+#define CFI_type_float128 (CFI_type_Real + (16 << CFI_type_kind_shift))
+#define CFI_type_float128_Complex (CFI_type_Complex + (16 << CFI_type_kind_shift))
+#elif GFC_C_FLOAT128_KIND < 0
+#define CFI_type_float128 -2
+#define CFI_type_float128_Complex -2
+#else
+#error "Unexpected value for GFC_C_FLOAT128_KIND"
+#endif 
diff --git a/libgfortran/ISO_Fortran_binding-3-tmpl.h b/libgfortran/ISO_Fortran_binding-3-tmpl.h
new file mode 100644
index 0000000..aec4288
--- /dev/null
+++ b/libgfortran/ISO_Fortran_binding-3-tmpl.h
@@ -0,0 +1,5 @@ 
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ISO_FORTRAN_BINDING_H */
diff --git a/libgfortran/ISO_Fortran_binding.h b/libgfortran/ISO_Fortran_binding.h
deleted file mode 100644
index 6c4d461..0000000
--- a/libgfortran/ISO_Fortran_binding.h
+++ /dev/null
@@ -1,206 +0,0 @@ 
-/* Declarations for ISO Fortran binding.
-   Copyright (C) 2018-2021 Free Software Foundation, Inc.
-   Contributed by Daniel Celis Garza  <celisdanieljr@gmail.com>
-
-This file is part of the GNU Fortran runtime library (libgfortran).
-
-Libgfortran is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
-
-Libgfortran is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-Under Section 7 of GPL version 3, you are granted additional
-permissions described in the GCC Runtime Library Exception, version
-3.1, as published by the Free Software Foundation.
-
-You should have received a copy of the GNU General Public License and
-a copy of the GCC Runtime Library Exception along with this program;
-see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
-<http://www.gnu.org/licenses/>.  */
-
-#ifndef ISO_FORTRAN_BINDING_H
-#define ISO_FORTRAN_BINDING_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stddef.h>  /* Standard ptrdiff_t tand size_t. */
-#include <stdint.h>  /* Integer types. */
-
-/* Constants, defined as macros. */
-#define CFI_VERSION 1
-#define CFI_MAX_RANK 15
-
-/* Attributes. */
-#define CFI_attribute_pointer 0
-#define CFI_attribute_allocatable 1
-#define CFI_attribute_other 2
-
-/* Error codes.
-   CFI_INVALID_STRIDE should be defined in the standard because they are useful to the implementation of the functions.
- */
-#define CFI_SUCCESS 0
-#define CFI_FAILURE 1
-#define CFI_ERROR_BASE_ADDR_NULL 2
-#define CFI_ERROR_BASE_ADDR_NOT_NULL 3
-#define CFI_INVALID_ELEM_LEN 4
-#define CFI_INVALID_RANK 5
-#define CFI_INVALID_TYPE 6
-#define CFI_INVALID_ATTRIBUTE 7
-#define CFI_INVALID_EXTENT 8
-#define CFI_INVALID_STRIDE 9
-#define CFI_INVALID_DESCRIPTOR 10
-#define CFI_ERROR_MEM_ALLOCATION 11
-#define CFI_ERROR_OUT_OF_BOUNDS 12
-
-/* CFI type definitions. */
-typedef ptrdiff_t CFI_index_t;
-typedef int8_t CFI_rank_t;
-typedef int8_t CFI_attribute_t;
-typedef int16_t CFI_type_t;
-
-/* CFI_dim_t. */
-typedef struct CFI_dim_t
-  {
-    CFI_index_t lower_bound;
-    CFI_index_t extent;
-    CFI_index_t sm;
-  }
-CFI_dim_t;
-
-/* CFI_cdesc_t, C descriptors are cast to this structure as follows:
-   CFI_CDESC_T(CFI_MAX_RANK) foo;
-   CFI_cdesc_t * bar = (CFI_cdesc_t *) &foo;
- */
-typedef struct CFI_cdesc_t
- {
-    void *base_addr;
-    size_t elem_len;
-    int version;
-    CFI_rank_t rank;
-    CFI_attribute_t attribute;
-    CFI_type_t type;
-    CFI_dim_t dim[];
- }
-CFI_cdesc_t;
-
-/* CFI_CDESC_T with an explicit type. */
-#define CFI_CDESC_TYPE_T(r, base_type) \
-	struct { \
-		base_type *base_addr; \
-		size_t elem_len; \
-		int version; \
-		CFI_rank_t rank; \
-		CFI_attribute_t attribute; \
-		CFI_type_t type; \
-		CFI_dim_t dim[r]; \
-	}
-#define CFI_CDESC_T(r) CFI_CDESC_TYPE_T (r, void)
-
-/* CFI function declarations. */
-extern void *CFI_address (const CFI_cdesc_t *, const CFI_index_t []);
-extern int CFI_allocate (CFI_cdesc_t *, const CFI_index_t [], const CFI_index_t [],
-			 size_t);
-extern int CFI_deallocate (CFI_cdesc_t *);
-extern int CFI_establish (CFI_cdesc_t *, void *, CFI_attribute_t, CFI_type_t, size_t,
-			  CFI_rank_t, const CFI_index_t []);
-extern int CFI_is_contiguous (const CFI_cdesc_t *);
-extern int CFI_section (CFI_cdesc_t *, const CFI_cdesc_t *, const CFI_index_t [],
-			const CFI_index_t [], const CFI_index_t []);
-extern int CFI_select_part (CFI_cdesc_t *, const CFI_cdesc_t *, size_t, size_t);
-extern int CFI_setpointer (CFI_cdesc_t *, CFI_cdesc_t *, const CFI_index_t []);
-
-/* Types and kind numbers. Allows bitwise and to reveal the intrinsic type of a kind type. It also allows us to find the kind parameter by inverting the bit-shift equation.
-   CFI_type_kind_shift = 8
-   CFI_intrinsic_type  = 0 0 0 0 0 0 0 0 0 0 1 0
-   CFI_type_kind       = 0 0 0 0 0 0 0 0 1 0 0 0
-   CFI_type_example    = CFI_intrinsic_type + (CFI_type_kind << CFI_type_kind_shift)
-   Defining the CFI_type_example.
-   CFI_type_kind       = 0 0 0 0 0 0 0 0 1 0 0 0  << CFI_type_kind_shift
-			-------------------------
-			 1 0 0 0 0 0 0 0 0 0 0 0  +
-   CFI_intrinsic_type  = 0 0 0 0 0 0 0 0 0 0 1 0
-			-------------------------
-   CFI_type_example    = 1 0 0 0 0 0 0 0 0 0 1 0
-   Finding the intrinsic type with the logical mask.
-   CFI_type_example    = 1 0 0 0 0 0 0 0 0 0 1 0  &
-   CFI_type_mask       = 0 0 0 0 1 1 1 1 1 1 1 1
-			-------------------------
-   CFI_intrinsic_type  = 0 0 0 0 0 0 0 0 0 0 1 0
-   Using the intrinsic type and kind shift to find the kind value of the type.
-   CFI_type_kind = (CFI_type_example - CFI_intrinsic_type) >> CFI_type_kind_shift
-   CFI_type_example   = 1 0 0 0 0 0 0 0 0 0 1 0  -
-   CFI_intrinsic_type = 0 0 0 0 0 0 0 0 0 0 1 0
-			-------------------------
-			1 0 0 0 0 0 0 0 0 0 0 0  >> CFI_type_kind_shift
-			-------------------------
-   CFI_type_kind      = 0 0 0 0 0 0 0 0 1 0 0 0
- */
-#define CFI_type_mask 0xFF
-#define CFI_type_kind_shift 8
-
-/* Intrinsic types. Their kind number defines their storage size. */
-#define CFI_type_Integer 1
-#define CFI_type_Logical 2
-#define CFI_type_Real 3
-#define CFI_type_Complex 4
-#define CFI_type_Character 5
-
-/* Types with no kind. */
-#define CFI_type_struct 6
-#define CFI_type_cptr 7
-#define CFI_type_cfunptr 8
-#define CFI_type_other -1
-
-/* Types with kind parameter.
-   The kind parameter represents the type's byte size. The exception is kind = 10, which has byte size of 64 but 80 bit precision. Complex variables are double the byte size of their real counterparts. The ucs4_char matches wchar_t if sizeof (wchar_t) == 4.
- */
-#define CFI_type_char (CFI_type_Character + (1 << CFI_type_kind_shift))
-#define CFI_type_ucs4_char (CFI_type_Character + (4 << CFI_type_kind_shift))
-
-/* C-Fortran Interoperability types. */
-#define CFI_type_signed_char (CFI_type_Integer + (1 << CFI_type_kind_shift))
-#define CFI_type_short (CFI_type_Integer + (2 << CFI_type_kind_shift))
-#define CFI_type_int (CFI_type_Integer + (4 << CFI_type_kind_shift))
-#define CFI_type_long (CFI_type_Integer + (8 << CFI_type_kind_shift))
-#define CFI_type_long_long (CFI_type_Integer + (8 << CFI_type_kind_shift))
-#define CFI_type_size_t (CFI_type_Integer + (8 << CFI_type_kind_shift))
-#define CFI_type_int8_t (CFI_type_Integer + (1 << CFI_type_kind_shift))
-#define CFI_type_int16_t (CFI_type_Integer + (2 << CFI_type_kind_shift))
-#define CFI_type_int32_t (CFI_type_Integer + (4 << CFI_type_kind_shift))
-#define CFI_type_int64_t (CFI_type_Integer + (8 << CFI_type_kind_shift))
-#define CFI_type_int_least8_t (CFI_type_Integer + (1 << CFI_type_kind_shift))
-#define CFI_type_int_least16_t (CFI_type_Integer + (2 << CFI_type_kind_shift))
-#define CFI_type_int_least32_t (CFI_type_Integer + (4 << CFI_type_kind_shift))
-#define CFI_type_int_least64_t (CFI_type_Integer + (8 << CFI_type_kind_shift))
-#define CFI_type_int_fast8_t (CFI_type_Integer + (1 << CFI_type_kind_shift))
-#define CFI_type_int_fast16_t (CFI_type_Integer + (2 << CFI_type_kind_shift))
-#define CFI_type_int_fast32_t (CFI_type_Integer + (4 << CFI_type_kind_shift))
-#define CFI_type_int_fast64_t (CFI_type_Integer + (8 << CFI_type_kind_shift))
-#define CFI_type_intmax_t (CFI_type_Integer + (8 << CFI_type_kind_shift))
-#define CFI_type_intptr_t (CFI_type_Integer + (8 << CFI_type_kind_shift))
-#define CFI_type_ptrdiff_t (CFI_type_Integer + (8 << CFI_type_kind_shift))
-#define CFI_type_int128_t (CFI_type_Integer + (16 << CFI_type_kind_shift))
-#define CFI_type_int_least128_t (CFI_type_Integer + (16 << CFI_type_kind_shift))
-#define CFI_type_int_fast128_t (CFI_type_Integer + (16 << CFI_type_kind_shift))
-#define CFI_type_Bool (CFI_type_Logical + (1 << CFI_type_kind_shift))
-#define CFI_type_float (CFI_type_Real + (4 << CFI_type_kind_shift))
-#define CFI_type_double (CFI_type_Real + (8 << CFI_type_kind_shift))
-#define CFI_type_long_double (CFI_type_Real + (10 << CFI_type_kind_shift))
-#define CFI_type_float128 (CFI_type_Real + (16 << CFI_type_kind_shift))
-#define CFI_type_float_Complex (CFI_type_Complex + (4 << CFI_type_kind_shift))
-#define CFI_type_double_Complex (CFI_type_Complex + (8 << CFI_type_kind_shift))
-#define CFI_type_long_double_Complex (CFI_type_Complex + (10 << CFI_type_kind_shift))
-#define CFI_type_float128_Complex (CFI_type_Complex + (16 << CFI_type_kind_shift))
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ISO_FORTRAN_BINDING_H */
diff --git a/libgfortran/Makefile.am b/libgfortran/Makefile.am
index 61bf05d..3546a3f 100644
--- a/libgfortran/Makefile.am
+++ b/libgfortran/Makefile.am
@@ -30,8 +30,8 @@  version_arg =
 version_dep =
 endif
 
-gfor_c_HEADERS = $(srcdir)/ISO_Fortran_binding.h
-gfor_cdir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/include
+gfor_c_HEADERS = ISO_Fortran_binding.h
+gfor_cdir = $(libdir)/gcc/$(target_alias)/$(gcc_version)$(MULTISUBDIR)/include
 
 LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS)) \
 	    $(lt_host_flags)
@@ -817,6 +817,7 @@  gfor_built_src= $(i_all_c) $(i_any_c) $(i_count_c) $(i_maxloc0_c) \
     $(i_pow_c) $(i_pack_c) $(i_unpack_c) $(i_matmulavx128_c) \
     $(i_spread_c) selected_int_kind.inc selected_real_kind.inc kinds.h \
     $(i_cshift0_c) kinds.inc c99_protos.inc fpu-target.h fpu-target.inc \
+    ISO_Fortran_binding.h \
     $(i_cshift1a_c) $(i_maxloc0s_c) $(i_minloc0s_c) $(i_maxloc1s_c) \
     $(i_minloc1s_c) $(i_maxloc2s_c) $(i_minloc2s_c) $(i_maxvals_c) \
     $(i_maxval0s_c) $(i_minval0s_c) $(i_maxval1s_c) $(i_minval1s_c) \
@@ -1075,6 +1076,16 @@  fpu-target.inc: fpu-target.h $(srcdir)/libgfortran.h
 	grep '^#define GFC_FPE_' < $(top_srcdir)/../gcc/fortran/libgfortran.h > $@ || true
 	grep '^#define GFC_FPE_' < $(srcdir)/libgfortran.h >> $@ || true
 
+ISO_Fortran_binding.h: $(srcdir)/ISO_Fortran_binding-1-tmpl.h \
+		       $(srcdir)/ISO_Fortran_binding-2-tmpl.h \
+		       $(srcdir)/ISO_Fortran_binding-3-tmpl.h \
+		       kinds.inc
+	-rm -f $@
+	cp $(srcdir)/ISO_Fortran_binding-1-tmpl.h $@
+	$(COMPILE) -E -dD $(srcdir)/ISO_Fortran_binding-2-tmpl.h \
+	| grep '^#define CFI_type' >> $@
+	cat $(srcdir)/ISO_Fortran_binding-3-tmpl.h >> $@
+
 ## A 'normal' build shouldn't need to regenerate these
 ## so we only include them in maintainer mode
 
diff --git a/libgfortran/Makefile.in b/libgfortran/Makefile.in
index 3d043aa..a7d8e11 100644
--- a/libgfortran/Makefile.in
+++ b/libgfortran/Makefile.in
@@ -698,6 +698,7 @@  pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -723,8 +724,8 @@  gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER)
 @LIBGFOR_USE_SYMVER_FALSE@version_dep = 
 @LIBGFOR_USE_SYMVER_GNU_TRUE@@LIBGFOR_USE_SYMVER_TRUE@version_dep = $(srcdir)/gfortran.map
 @LIBGFOR_USE_SYMVER_SUN_TRUE@@LIBGFOR_USE_SYMVER_TRUE@version_dep = gfortran.map-sun
-gfor_c_HEADERS = $(srcdir)/ISO_Fortran_binding.h
-gfor_cdir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/include
+gfor_c_HEADERS = ISO_Fortran_binding.h
+gfor_cdir = $(libdir)/gcc/$(target_alias)/$(gcc_version)$(MULTISUBDIR)/include
 LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS)) \
 	    $(lt_host_flags)
 
@@ -1381,6 +1382,7 @@  gfor_built_src = $(i_all_c) $(i_any_c) $(i_count_c) $(i_maxloc0_c) \
     $(i_pow_c) $(i_pack_c) $(i_unpack_c) $(i_matmulavx128_c) \
     $(i_spread_c) selected_int_kind.inc selected_real_kind.inc kinds.h \
     $(i_cshift0_c) kinds.inc c99_protos.inc fpu-target.h fpu-target.inc \
+    ISO_Fortran_binding.h \
     $(i_cshift1a_c) $(i_maxloc0s_c) $(i_minloc0s_c) $(i_maxloc1s_c) \
     $(i_minloc1s_c) $(i_maxloc2s_c) $(i_minloc2s_c) $(i_maxvals_c) \
     $(i_maxval0s_c) $(i_minval0s_c) $(i_maxval1s_c) $(i_minval1s_c) \
@@ -7040,6 +7042,16 @@  fpu-target.inc: fpu-target.h $(srcdir)/libgfortran.h
 	grep '^#define GFC_FPE_' < $(top_srcdir)/../gcc/fortran/libgfortran.h > $@ || true
 	grep '^#define GFC_FPE_' < $(srcdir)/libgfortran.h >> $@ || true
 
+ISO_Fortran_binding.h: $(srcdir)/ISO_Fortran_binding-1-tmpl.h \
+		       $(srcdir)/ISO_Fortran_binding-2-tmpl.h \
+		       $(srcdir)/ISO_Fortran_binding-3-tmpl.h \
+		       kinds.inc
+	-rm -f $@
+	cp $(srcdir)/ISO_Fortran_binding-1-tmpl.h $@
+	$(COMPILE) -E -dD $(srcdir)/ISO_Fortran_binding-2-tmpl.h \
+	| grep '^#define CFI_type' >> $@
+	cat $(srcdir)/ISO_Fortran_binding-3-tmpl.h >> $@
+
 @MAINTAINER_MODE_TRUE@$(i_all_c): m4/all.m4 $(I_M4_DEPS2)
 @MAINTAINER_MODE_TRUE@	$(M4) -Dfile=$@ -I$(srcdir)/m4 all.m4 > $@
 
diff --git a/libgfortran/mk-kinds-h.sh b/libgfortran/mk-kinds-h.sh
index 2496190..f4244f0 100755
--- a/libgfortran/mk-kinds-h.sh
+++ b/libgfortran/mk-kinds-h.sh
@@ -35,8 +35,8 @@  for k in $possible_integer_kinds; do
     echo "typedef ${prefix}int${s}_t GFC_INTEGER_${k};"
     echo "typedef ${prefix}uint${s}_t GFC_UINTEGER_${k};"
     echo "typedef GFC_INTEGER_${k} GFC_LOGICAL_${k};"
-    echo "#define HAVE_GFC_LOGICAL_${k}"
-    echo "#define HAVE_GFC_INTEGER_${k}"
+    echo "#define HAVE_GFC_LOGICAL_${k} 1"
+    echo "#define HAVE_GFC_INTEGER_${k} 1"
     echo ""
   fi
   rm -f tmp$$.*
@@ -98,8 +98,8 @@  for k in $possible_real_kinds; do
     # Output the information we've gathered
     echo "typedef ${ctype} GFC_REAL_${k};"
     echo "typedef ${cplxtype} GFC_COMPLEX_${k};"
-    echo "#define HAVE_GFC_REAL_${k}"
-    echo "#define HAVE_GFC_COMPLEX_${k}"
+    echo "#define HAVE_GFC_REAL_${k} 1"
+    echo "#define HAVE_GFC_COMPLEX_${k} 1"
     echo "#define GFC_REAL_${k}_HUGE ${huge}${suffix}"
     echo "#define GFC_REAL_${k}_LITERAL_SUFFIX ${suffix}"
     if [ "x$suffix" = "x" ]; then
@@ -114,6 +114,23 @@  for k in $possible_real_kinds; do
   rm -f tmp$$.*
 done
 
+# For ISO_Fortran_binding.h
+for k in "C_LONG_DOUBLE" "C_FLOAT128" "C_INT128_T"; do
+  fname="tmp$$.val"
+  echo "use iso_c_binding, only: $k; end" > tmp$$.f90
+  if $compile -S -fdump-parse-tree tmp$$.f90 > "$fname"; then
+    kind=`grep "value:" "$fname" |grep value: | sed -e 's/.*value: *//'`
+    if [ "x$kind" = "x" ]; then
+      echo "ERROR: Failed to extract kind for $k" 1>&2
+      exit 1
+    fi
+    echo "#define GFC_${k}_KIND ${kind}"
+  else
+    echo "ERROR: Failed to extract kind for $k" 1>&2
+    exit 1
+  fi
+  rm -f tmp$$.*
+done
 
 # After this, we include a header that can override some of the
 # autodetected settings.
diff --git a/libgfortran/runtime/ISO_Fortran_binding.c b/libgfortran/runtime/ISO_Fortran_binding.c
index 73fb4c4..28fa9f5 100644
--- a/libgfortran/runtime/ISO_Fortran_binding.c
+++ b/libgfortran/runtime/ISO_Fortran_binding.c
@@ -27,7 +27,7 @@  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 <http://www.gnu.org/licenses/>.  */
 
 #include "libgfortran.h"
-#include <ISO_Fortran_binding.h>
+#include "ISO_Fortran_binding.h"
 #include <string.h>
 
 extern void cfi_desc_to_gfc_desc (gfc_array_void *, CFI_cdesc_t **);