Repository: CastXML/CastXML (language: python)

Issue:
castxml: Add minimal support for GNU builtin _Float## types
`gcc >= 7` support these in C.  `g++ >= 13` support these in C++.
LLVM/Clang does not implement them, so simulate them.

Fixes: #251



Discussion / hints:

Fix patch:
diff --git a/src/RunClang.cxx b/src/RunClang.cxx
index 9a974f01..d765f3fa 100644
--- a/src/RunClang.cxx
+++ b/src/RunClang.cxx
@@ -392,26 +392,57 @@ class CastXMLPredefines : public T
         // Clang does not have these types for all sizes.
         // Provide our own approximation of the builtins.
         builtins += "\n"
-                    "typedef struct __castxml_Float32_s { "
-                    "  char x[4] __attribute__((aligned(4))); "
-                    "} __castxml_Float32;\n"
                     "#define _Float32 __castxml_Float32\n"
-                    "typedef struct __castxml_Float32x_s { "
-                    "  char x[8] __attribute__((aligned(8))); "
-                    "} __castxml_Float32x;\n"
                     "#define _Float32x __castxml_Float32x\n"
-                    "typedef struct __castxml_Float64_s { "
-                    "  char x[8] __attribute__((aligned(8))); "
-                    "} __castxml_Float64;\n"
                     "#define _Float64 __castxml_Float64\n"
-                    "typedef struct __castxml_Float64x_s { "
-                    "  char x[16] __attribute__((aligned(16))); "
-                    "} __castxml_Float64x;\n"
-                    "#define _Float64x __castxml_Float64x\n"
-                    "typedef struct __castxml_Float128_s { "
-                    "  char x[16] __attribute__((aligned(16))); "
-                    "} __castxml_Float128;\n"
-                    "#define _Float128 __castxml_Float128\n";
+                    "#define _Float64x __castxml_Float64x\n";
+        if (this->NeedFloat128(this->Opts.Predefines)) {
+          builtins += "#define _Float128 __castxml_Float128\n";
+        }
+
+        if (this->IsCPlusPlus(this->Opts.Predefines)) {
+          // In C++ we need distinct types for template specializations
+          // in glibc headers, but also need conversions.
+          builtins += "\n"
+                      "typedef struct __castxml_Float32_s { "
+                      "  float x; "
+                      "  operator float() const; "
+                      "  __castxml_Float32_s(float); "
+                      "} __castxml_Float32;\n"
+                      "typedef struct __castxml_Float32x_s { "
+                      "  double x; "
+                      "  operator double() const; "
+                      "  __castxml_Float32x_s(double); "
+                      "} __castxml_Float32x;\n"
+                      "typedef struct __castxml_Float64_s { "
+                      "  double x; "
+                      "  operator double() const; "
+                      "  __castxml_Float64_s(double); "
+                      "} __castxml_Float64;\n"
+                      "typedef struct __castxml_Float64x_s { "
+                      "  long double x; "
+                      "  operator long double() const; "
+                      "  __castxml_Float64x_s(long double); "
+                      "} __castxml_Float64x;\n";
+          if (this->NeedFloat128(this->Opts.Predefines)) {
+            builtins += "typedef struct __castxml_Float128_s { "
+                        "  __float128 x; "
+                        "  operator __float128() const; "
+                        "  __castxml_Float128_s(__float128); "
+                        "} __castxml_Float128;\n";
+          }
+
+        } else {
+          // In C we need real float types for conversions in glibc headers.
+          builtins += "\n"
+                      "typedef float __castxml_Float32;\n"
+                      "typedef double __castxml_Float32x;\n"
+                      "typedef double __castxml_Float64;\n"
+                      "typedef long double __castxml_Float64x;\n";
+          if (this->NeedFloat128(this->Opts.Predefines)) {
+            builtins += "typedef __float128 __castxml_Float128;\n";
+          }
+        }
       }
 
     } else {


Test patch:
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 488d210b..9cd6a8e6 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -696,6 +696,7 @@ castxml_test_output_c(GNU-_Float32)
 castxml_test_output_c(GNU-_Float32x)
 castxml_test_output_c(GNU-_Float64)
 castxml_test_output_c(GNU-_Float64x)
+set(castxml_test_output_extra_arguments --castxml-cc-gnu-c "(" $<TARGET_FILE:cc-gnu> --ver-major=7 --cc-define=__x86_64__ ")")
 castxml_test_output_c(GNU-_Float128)
 unset(castxml_test_output_extra_arguments)
 
@@ -704,6 +705,7 @@ castxml_test_output(GNU-_Float32)
 castxml_test_output(GNU-_Float32x)
 castxml_test_output(GNU-_Float64)
 castxml_test_output(GNU-_Float64x)
+set(castxml_test_output_extra_arguments --castxml-cc-gnu "(" $<TARGET_FILE:cc-gnu> --ver-major=13 --cc-define=__x86_64__ ")")
 castxml_test_output(GNU-_Float128)
 unset(castxml_test_output_extra_arguments)
 
diff --git a/test/input/GNU-_Float128.c b/test/input/GNU-_Float128.c
index f6c0ee1e..684e5ed8 100644
--- a/test/input/GNU-_Float128.c
+++ b/test/input/GNU-_Float128.c
@@ -1,1 +1,6 @@
 _Float128 start(_Float128);
+
+__float128 conversions(__float128 x)
+{
+  return start(x);
+}
diff --git a/test/input/GNU-_Float128.cxx b/test/input/GNU-_Float128.cxx
index f6c0ee1e..752c4204 100644
--- a/test/input/GNU-_Float128.cxx
+++ b/test/input/GNU-_Float128.cxx
@@ -1,1 +1,17 @@
 _Float128 start(_Float128);
+
+__float128 conversions(__float128 x)
+{
+  return start(x);
+}
+
+template <typename T>
+struct distinct;
+template <>
+struct distinct<__float128>
+{
+};
+template <>
+struct distinct<_Float128>
+{
+};
diff --git a/test/input/GNU-_Float32.c b/test/input/GNU-_Float32.c
index 07520fe4..9768803c 100644
--- a/test/input/GNU-_Float32.c
+++ b/test/input/GNU-_Float32.c
@@ -1,1 +1,6 @@
 _Float32 start(_Float32);
+
+float conversions(float x)
+{
+  return start(x);
+}
diff --git a/test/input/GNU-_Float32.cxx b/test/input/GNU-_Float32.cxx
index 07520fe4..58584f37 100644
--- a/test/input/GNU-_Float32.cxx
+++ b/test/input/GNU-_Float32.cxx
@@ -1,1 +1,17 @@
 _Float32 start(_Float32);
+
+float conversions(float x)
+{
+  return start(x);
+}
+
+template <typename T>
+struct distinct;
+template <>
+struct distinct<float>
+{
+};
+template <>
+struct distinct<_Float32>
+{
+};
diff --git a/test/input/GNU-_Float32x.c b/test/input/GNU-_Float32x.c
index 5f65016f..878e1467 100644
--- a/test/input/GNU-_Float32x.c
+++ b/test/input/GNU-_Float32x.c
@@ -1,1 +1,6 @@
 _Float32x start(_Float32x);
+
+double conversions(double x)
+{
+  return start(x);
+}
diff --git a/test/input/GNU-_Float32x.cxx b/test/input/GNU-_Float32x.cxx
index 5f65016f..f344fb15 100644
--- a/test/input/GNU-_Float32x.cxx
+++ b/test/input/GNU-_Float32x.cxx
@@ -1,1 +1,17 @@
 _Float32x start(_Float32x);
+
+double conversions(double x)
+{
+  return start(x);
+}
+
+template <typename T>
+struct distinct;
+template <>
+struct distinct<double>
+{
+};
+template <>
+struct distinct<_Float32x>
+{
+};
diff --git a/test/input/GNU-_Float64.c b/test/input/GNU-_Float64.c
index a75046ba..757047d3 100644
--- a/test/input/GNU-_Float64.c
+++ b/test/input/GNU-_Float64.c
@@ -1,1 +1,6 @@
 _Float64 start(_Float64);
+
+double conversions(double x)
+{
+  return start(x);
+}
diff --git a/test/input/GNU-_Float64.cxx b/test/input/GNU-_Float64.cxx
index a75046ba..41a67f95 100644
--- a/test/input/GNU-_Float64.cxx
+++ b/test/input/GNU-_Float64.cxx
@@ -1,1 +1,17 @@
 _Float64 start(_Float64);
+
+double conversions(double x)
+{
+  return start(x);
+}
+
+template <typename T>
+struct distinct;
+template <>
+struct distinct<double>
+{
+};
+template <>
+struct distinct<_Float64>
+{
+};
diff --git a/test/input/GNU-_Float64x.c b/test/input/GNU-_Float64x.c
index 2e255773..afaec582 100644
--- a/test/input/GNU-_Float64x.c
+++ b/test/input/GNU-_Float64x.c
@@ -1,1 +1,6 @@
 _Float64x start(_Float64x);
+
+long double conversions(long double x)
+{
+  return start(x);
+}
diff --git a/test/input/GNU-_Float64x.cxx b/test/input/GNU-_Float64x.cxx
index 2e255773..87812e11 100644
--- a/test/input/GNU-_Float64x.cxx
+++ b/test/input/GNU-_Float64x.cxx
@@ -1,1 +1,17 @@
 _Float64x start(_Float64x);
+
+long double conversions(long double x)
+{
+  return start(x);
+}
+
+template <typename T>
+struct distinct;
+template <>
+struct distinct<long double>
+{
+};
+template <>
+struct distinct<_Float64x>
+{
+};
diff --git a/test/run.cmake b/test/run.cmake
index 2f9160a1..35c0e638 100644
--- a/test/run.cmake
+++ b/test/run.cmake
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #=============================================================================
-cmake_minimum_required(VERSION 3.3)
+cmake_minimum_required(VERSION 3.5)
 
 if(xml)
   file(REMOVE "${xml}")