[pypy-commit] creflect default: guess the float types, like we do the integer types

arigo noreply at buildbot.pypy.org
Thu Dec 4 13:28:21 CET 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r148:3471b7c2e683
Date: 2014-12-04 13:28 +0100
http://bitbucket.org/cffi/creflect/changeset/3471b7c2e683/

Log:	guess the float types, like we do the integer types

diff --git a/creflect/creflect.h b/creflect/creflect.h
--- a/creflect/creflect.h
+++ b/creflect/creflect.h
@@ -83,13 +83,20 @@
     _crx_sc_int       = 3,
     _crx_sc_long      = 4,
     _crx_sc_long_long = 5,
+
+    _crx_sc_float       = 1,
+    _crx_sc_double      = 2,
+    _crx_sc_long_double = 3,
 };
 
 #define _CRX_INT_TYPE(cb, expr, sizeclass)                              \
     _crx_int_type(cb, expr > 0, sizeof(expr), expr == 1, sizeclass)
 
-#define _CRX_INT_CONST(cb, expr, vp, pn)                 \
-    _crx_int_const(cb, vp, pn,                    \
+#define _CRX_FLOAT_TYPE(cb, expr, sizeclass)            \
+    _crx_float_type(cb, sizeof(expr), sizeclass)
+
+#define _CRX_INT_CONST(cb, expr, vp, pn)                \
+    _crx_int_const(cb, vp, pn,                          \
         "integer constant '" #expr "' is too large",    \
         !(((expr) * 0 + 4) << (sizeof(int)*8-2)),       \
         !(((expr) * 0L + 4L) << (sizeof(long)*8-2)),    \
@@ -98,9 +105,9 @@
         (expr) == (long long)(expr),                    \
         (unsigned long long)(expr))
 
-#define _CRX_CHAR_CONST(cb, expr, vp)                                    \
-    _crx_char_const(cb, vp,                                       \
-        "char constant '" #expr "' is too large",                       \
+#define _CRX_CHAR_CONST(cb, expr, vp)                                     \
+    _crx_char_const(cb, vp,                                               \
+        "char constant '" #expr "' is too large",                         \
         (expr) == (signed char)(expr) || (expr) == (unsigned char)(expr), \
         (char)(expr))
 
@@ -135,6 +142,25 @@
 }
 
 __attribute__((unused))
+static _crx_type_t *_crx_float_type(_crx_builder_t *cb, size_t size_of_expr,
+                                    int sizeclass)
+{
+    static size_t all_sizes[] = { 0, sizeof(float), sizeof(double),
+                                  sizeof(long double), (size_t)-1 };
+    while (all_sizes[sizeclass] != size_of_expr) {
+        if (all_sizes[sizeclass] > size_of_expr)
+            sizeclass--;
+        else
+            sizeclass++;
+    }
+    if (sizeclass < 1) sizeclass = 1;
+    if (sizeclass > 3) sizeclass = 3;
+
+    static const char *all_names[] = { NULL, "float", "double", "long double" };
+    return cb->get_float_type(cb, size_of_expr, all_names[sizeclass]);
+}
+
+__attribute__((unused))
 static _crx_type_t *_crx_int_const(_crx_builder_t *cb, _crx_num_const_t *vp,
                                    int preference_number,
                                    const char *toobig,
diff --git a/creflect/model.py b/creflect/model.py
--- a/creflect/model.py
+++ b/creflect/model.py
@@ -186,8 +186,8 @@
                 block.writeline('    cb->error(cb, "%s");' % (errmsg,))
                 block.writeline("    return;")
                 block.writeline("}")
-                expr = 'cb->get_float_type(cb, sizeof(%s), "%s")' % (
-                    star_p1, self.name)
+                hint = self.name.replace(' ', '_')
+                expr = '_CRX_FLOAT_TYPE(cb, %s, _crx_sc_%s)' % (star_p1, hint)
             else:
                 raise AssertionError
         else:
diff --git a/creflect/test/codegen/003g.c b/creflect/test/codegen/003g.c
--- a/creflect/test/codegen/003g.c
+++ b/creflect/test/codegen/003g.c
@@ -16,7 +16,7 @@
             cb->error(cb, "numeric type 'num_t' is an integer, not a float");
             return;
         }
-        t1 = cb->get_float_type(cb, sizeof(*p1), "double");
+        t1 = _CRX_FLOAT_TYPE(cb, *p1, _crx_sc_double);
         cb->define_type(cb, "num_t", t1, 0);
 #expect TYPEDEF num_t = double
     }
diff --git a/creflect/test/codegen/003k.c b/creflect/test/codegen/003k.c
new file mode 100644
--- /dev/null
+++ b/creflect/test/codegen/003k.c
@@ -0,0 +1,27 @@
+typedef double num_t;
+
+# ____________________________________________________________
+
+#define num_t  float
+
+# ____________________________________________________________
+
+void test003k(_crx_builder_t *cb)
+{
+    _crx_type_t *t1;
+    {
+        num_t *p1;
+        char b[sizeof(*p1)];
+        memset(b, 0, sizeof(b));
+        p1 = (void *)b;
+        (void)(*p1 / 2.0);  /* check that 'num_t' is a numeric type */
+        *p1 = -1;  /* check that 'num_t' is not declared 'const' */
+        if ((1 + *p1 * 0) / 2 == 0) {
+            cb->error(cb, "numeric type 'num_t' is an integer, not a float");
+            return;
+        }
+        t1 = _CRX_FLOAT_TYPE(cb, *p1, _crx_sc_double);
+        cb->define_type(cb, "num_t", t1, 0);
+#expect TYPEDEF num_t = float
+    }
+}


More information about the pypy-commit mailing list