[pypy-commit] creflect default: Refactoring in progress...

arigo noreply at buildbot.pypy.org
Mon Nov 17 16:04:59 CET 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r51:6ddbcda0f7b3
Date: 2014-11-17 16:05 +0100
http://bitbucket.org/cffi/creflect/changeset/6ddbcda0f7b3/

Log:	Refactoring in progress...

diff --git a/creflect/creflect.h b/creflect/creflect.h
new file mode 100644
--- /dev/null
+++ b/creflect/creflect.h
@@ -0,0 +1,61 @@
+#include <stddef.h>
+
+
+typedef struct {
+    const char *name;
+    void *type;
+    size_t offset;
+    int numbits, bitshift;
+} crx_field_t;
+
+typedef struct crx_type_s crx_type_t;   /* opaque */
+typedef void (*crx_trampoline_t)(void *fn, void *args[], void *res);
+
+#define CRX_SELF struct _crx_builder_s *
+typedef struct _crx_builder_s {
+    crx_type_t *(*get_void_type)(CRX_SELF);
+    crx_type_t *(*get_char_type)(CRX_SELF);
+    crx_type_t *(*get_bool_type)(CRX_SELF);
+    crx_type_t *(*get_signed_type)(CRX_SELF, size_t,
+                                const char *);
+    crx_type_t *(*get_unsigned_type)(CRX_SELF, size_t,
+                                  const char *);
+    crx_type_t *(*get_float_type)(CRX_SELF, size_t,
+                               const char *);
+    crx_type_t *(*get_function_type)(CRX_SELF, crx_type_t *,
+                                     crx_type_t *[], int, crx_trampoline_t *);
+    crx_type_t *(*get_ellipsis_function_type)(CRX_SELF, crx_type_t *,
+                                              crx_type_t *[], int);
+    crx_type_t *(*get_pointer_type)(CRX_SELF, crx_type_t *);
+    crx_type_t *(*get_const_type)(CRX_SELF, crx_type_t *);
+    crx_type_t *(*get_array_type)(CRX_SELF, crx_type_t *, size_t);
+    crx_type_t *(*get_incomplete_array_type)(CRX_SELF, crx_type_t *);
+    crx_type_t *(*get_struct_type)(CRX_SELF, const char *);
+    crx_type_t *(*get_union_type)(CRX_SELF, const char *);
+    crx_type_t *(*get_enum_type)(CRX_SELF, const char *);
+    void (*complete)(CRX_SELF, crx_type_t *,
+                     size_t, size_t, crx_field_t[], int);
+    void (*complete_enum)(CRX_SELF, crx_type_t *, crx_type_t *);
+    void (*define_type)(CRX_SELF, const char *, crx_type_t *);
+    void (*define_var)(CRX_SELF, const char *, crx_type_t *,
+                       void *);
+    void (*error)(CRX_SELF, const char *, crx_type_t *);
+} crx_builder_t;
+#undef CRX_SELF
+
+
+#define CRX_INT_TYPE(cb, expr, guessname)                               \
+    _creflect__int_type(cb, expr > 0, sizeof(expr), expr == 1, guessname)
+
+__attribute__((unused))
+static crx_type_t *_creflect__int_type(crx_builder_t *cb, int expr_positive,
+                                       size_t size_of_expr, int expr_equal_one,
+                                       const char *guessname)
+{
+    if (!expr_positive)
+        return cb->get_signed_type(cb, size_of_expr, guessname);
+    else if (size_of_expr == 1 && expr_equal_one)
+        return cb->get_bool_type(cb);
+    else
+        return cb->get_unsigned_type(cb, size_of_expr, guessname);
+}
diff --git a/test/cgcompile.c b/test/cgcompile.c
new file mode 100644
--- /dev/null
+++ b/test/cgcompile.c
@@ -0,0 +1,190 @@
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+
+struct crx_type_s {
+    char text[1];
+};
+
+
+static crx_type_t *newtype(const char *a)
+{
+    size_t la = strlen(a);
+    crx_type_t *t = malloc(la + 1);
+    strcpy(t->text, a);
+    return t;
+}
+
+static crx_type_t *newtype2(const char *a, const char *b)
+{
+    size_t la = strlen(a);
+    size_t lb = strlen(b);
+    crx_type_t *t = malloc(la + lb + 1);
+    strcat(strcpy(t->text, a), b);
+    return t;
+}
+
+static crx_type_t *tst_get_void_type(crx_builder_t *cb)
+{
+    return newtype("void");
+}
+
+static crx_type_t *tst_get_char_type(crx_builder_t *cb)
+{
+    return newtype("char");
+}
+
+static crx_type_t *tst_get_bool_type(crx_builder_t *cb)
+{
+    return newtype("_Bool");
+}
+
+static crx_type_t *tst_get_signed_type(crx_builder_t *cb, size_t sz,
+                                       const char *g)
+{
+#define TT(name)  if (strcmp(g, #name) == 0) { found = sizeof(name); }
+    int found = 0;
+    TT(signed char);
+    TT(short);
+    TT(int);
+    TT(long);
+    TT(long long);
+    assert(found == sz);
+    return newtype(g);
+}
+
+static crx_type_t *tst_get_unsigned_type(crx_builder_t *cb, size_t sz,
+                                         const char *g)
+{
+    int found = 0;
+    TT(unsigned char);
+    TT(unsigned short);
+    TT(unsigned int);
+    TT(unsigned long);
+    TT(unsigned long long);
+    assert(found == sz);
+    return newtype(g);
+}
+
+static crx_type_t *tst_get_float_type(crx_builder_t *cb, size_t sz,
+                                      const char *g)
+{
+    int found = 0;
+    TT(float);
+    TT(double);
+    assert(found == sz);
+#undef TT
+    return newtype(g);
+}
+
+static crx_type_t *tst_get_function_type(crx_builder_t *cb, crx_type_t *ret,
+                                         crx_type_t *args[], int nargs,
+                                         crx_trampoline_t *trampl)
+{
+    abort();
+}
+
+static crx_type_t *tst_get_ellipsis_function_type(crx_builder_t *cb,
+                                                  crx_type_t *ret,
+                                                  crx_type_t *args[], int nargs)
+{
+    abort();
+}
+
+static crx_type_t *tst_get_pointer_type(crx_builder_t *cb, crx_type_t *t)
+{
+    return newtype2("PTR ", t->text);
+}
+
+static crx_type_t *tst_get_const_type(crx_builder_t *cb, crx_type_t *t)
+{
+    return newtype2("CONST ", t->text);
+}
+
+static crx_type_t *tst_get_array_type(crx_builder_t *cb, crx_type_t *t,
+                                      size_t len)
+{
+    char c[32];
+    sprintf(c, "ARRAY[%zd] ", len);
+    return newtype2(c, t->text);
+}
+
+static crx_type_t *tst_get_incomplete_array_type(crx_builder_t *cb,
+                                                 crx_type_t *t)
+{
+    return newtype2("ARRAY[] ", t->text);
+}
+
+static crx_type_t *tst_get_struct_type(crx_builder_t *cb, const char *name)
+{
+    return newtype2("STRUCT ", name);
+}
+
+static crx_type_t *tst_get_union_type(crx_builder_t *cb, const char *name)
+{
+    return newtype2("UNION ", name);
+}
+
+static crx_type_t *tst_get_enum_type(crx_builder_t *cb, const char *name)
+{
+    return newtype2("ENUM ", name);
+}
+
+static void tst_complete(crx_builder_t *cb, crx_type_t *t,
+                         size_t sz, size_t align,
+                         crx_field_t fields[], int nfields)
+{
+    abort();
+}
+
+static void tst_complete_enum(crx_builder_t *cb, crx_type_t *t,
+                              crx_type_t *inttype)
+{
+    abort();
+}
+
+static void tst_define_type(crx_builder_t *cb, const char *name, crx_type_t *t)
+{
+    printf("TYPEDEF %s = %s\n", name, t->text);
+}
+
+static void tst_define_var(crx_builder_t *cb, const char *name, crx_type_t *t,
+                           void *addr)
+{
+    printf("VAR %s: %s\n", name, t->text);
+}
+
+static void tst_error(crx_builder_t *cb, const char *msg, crx_type_t *t)
+{
+    printf("ERROR %s %s\n", msg, t ? t->text : "");
+}
+
+static crx_builder_t maincb = {
+    tst_get_void_type,
+    tst_get_char_type,
+    tst_get_bool_type,
+    tst_get_signed_type,
+    tst_get_unsigned_type,
+    tst_get_float_type,
+    tst_get_function_type,
+    tst_get_ellipsis_function_type,
+    tst_get_pointer_type,
+    tst_get_const_type,
+    tst_get_array_type,
+    tst_get_incomplete_array_type,
+    tst_get_struct_type,
+    tst_get_union_type,
+    tst_get_enum_type,
+    tst_complete,
+    tst_complete_enum,
+    tst_define_type,
+    tst_define_var,
+    tst_error,
+};
+
+int main(void)
+{
+    TESTFN(&maincb);
+    return 0;
+}
diff --git a/test/codegen/001.c b/test/codegen/001.c
--- a/test/codegen/001.c
+++ b/test/codegen/001.c
@@ -2,10 +2,6 @@
 
 # ____________________________________________________________
 
-int test001(char *r)
+void test001(crx_builder_t *cb)
 {
-    if (!r)
-        return 1;
-    *r = 0;
-    return 0;
 }
diff --git a/test/codegen/002.c b/test/codegen/002.c
--- a/test/codegen/002.c
+++ b/test/codegen/002.c
@@ -2,16 +2,17 @@
 
 # ____________________________________________________________
 
-int test002(char *r)
+void test002(crx_builder_t *cb)
 {
-    if (!r)
-        return 22;
+    crx_type_t *t1, *t2;
     {
         num_t *p1;
         char *p2;
         p1 = (void *)&p2;
         *p1 = (void *)0;    /* check that 'num_t' is a pointer type */
-        r += sprintf(r, "typedef void *num_t;\n");
+        t1 = cb->get_void_type(cb);
+        t2 = cb->get_pointer_type(cb, t1);
+        cb->define_type(cb, "num_t", t2);
+#expect TYPEDEF num_t = PTR void
     }
-    return 0;
 }
diff --git a/test/codegen/002b.c b/test/codegen/002b.c
--- a/test/codegen/002b.c
+++ b/test/codegen/002b.c
@@ -2,10 +2,9 @@
 
 # ____________________________________________________________
 
-int test002b(char *r)
+void test002b(crx_builder_t *cb)
 {
-    if (!r)
-        return 24;
+    crx_type_t *t1, *t2, *t3, *t4;
     {
         num_t *p1;
         char *p2;
@@ -15,7 +14,11 @@
         *p1 = (void *)&p3;  /* check that 'num_t' is a pointer type */
         **p1 = (void *)&p4;  /* check that '*num_t' is a pointer type */
         ***p1 = (void *)0;    /* check that '**num_t' is a pointer type */
-        r += sprintf(r, "typedef void ***num_t;\n");
+        t1 = cb->get_void_type(cb);
+        t2 = cb->get_pointer_type(cb, t1);
+        t3 = cb->get_pointer_type(cb, t2);
+        t4 = cb->get_pointer_type(cb, t3);
+        cb->define_type(cb, "num_t", t4);
+#expect TYPEDEF num_t = PTR PTR PTR void
     }
-    return 0;
 }
diff --git a/test/codegen/002c.c b/test/codegen/002c.c
--- a/test/codegen/002c.c
+++ b/test/codegen/002c.c
@@ -2,16 +2,18 @@
 
 # ____________________________________________________________
 
-int test002c(char *r)
+void test002c(crx_builder_t *cb)
 {
-    if (!r)
-        return 28;
+    crx_type_t *t1, *t2, *t3;
     {
         num_t *p1;
         char *p2;
         p1 = (void *)&p2;
         *p1 = (void *)0;    /* check that 'num_t' is a pointer type */
-        r += sprintf(r, "typedef const void *num_t;\n");
+        t1 = cb->get_void_type(cb);
+        t2 = cb->get_const_type(cb, t1);
+        t3 = cb->get_pointer_type(cb, t2);
+        cb->define_type(cb, "num_t", t3);
+#expect TYPEDEF num_t = PTR CONST void
     }
-    return 0;
 }
diff --git a/test/codegen/003.c b/test/codegen/003.c
--- a/test/codegen/003.c
+++ b/test/codegen/003.c
@@ -2,48 +2,16 @@
 
 # ____________________________________________________________
 
-int test003(char *r)
+void test003(crx_builder_t *cb)
 {
-    if (!r)
-        return 8 + 18 + 9;
+    crx_type_t *t1;
     {
         num_t *p1;
         char b[sizeof(*p1)];
         p1 = (void *)b;
         (void)(*p1 << 1);  /* check that 'num_t' is an integer type */
-        r += sprintf(r, "typedef ");
         *p1 = -1;  /* check that 'num_t' is not declared 'const' */
-        if (*p1 > 0) {
-            if (sizeof(*p1) == 1 && *p1 == 1)
-                r += sprintf(r, "_Bool");
-            else if (sizeof(*p1) == sizeof(unsigned int))
-                r += sprintf(r, "unsigned int");
-            else if (sizeof(*p1) == sizeof(unsigned short))
-                r += sprintf(r, "unsigned short");
-            else if (sizeof(*p1) == sizeof(unsigned char))
-                r += sprintf(r, "unsigned char");
-            else if (sizeof(*p1) == sizeof(unsigned long))
-                r += sprintf(r, "unsigned long");
-            else if (sizeof(*p1) == sizeof(unsigned long long))
-                r += sprintf(r, "unsigned long long");
-            else
-                r += sprintf(r, "uint%u_t", (int)sizeof(*p1) * 8);
-        }
-        else {
-            if (sizeof(*p1) == sizeof(int))
-                r += sprintf(r, "int");
-            else if (sizeof(*p1) == sizeof(short))
-                r += sprintf(r, "short");
-            else if (sizeof(*p1) == sizeof(signed char))
-                r += sprintf(r, "signed char");
-            else if (sizeof(*p1) == sizeof(long))
-                r += sprintf(r, "long");
-            else if (sizeof(*p1) == sizeof(long long))
-                r += sprintf(r, "long long");
-            else
-                r += sprintf(r, "int%u_t", (int)sizeof(*p1) * 8);
-        }
-        r += sprintf(r, " num_t;\n");
+        t1 = CRX_INT_TYPE(cb, *p1, "int");
+        cb->define_type(cb, "num_t", t1);
     }
-    return 0;
 }
diff --git a/test/codegen/003b.c b/test/codegen/003b.c
--- a/test/codegen/003b.c
+++ b/test/codegen/003b.c
@@ -2,48 +2,15 @@
 
 # ____________________________________________________________
 
-int test003b(char *r)
+void test003b(creflect_builder_t *cb)
 {
-    if (!r)
-        return 8 + 18 + 9;
     {
         num_t *p1;
         char b[sizeof(*p1)];
         p1 = (void *)b;
         (void)(*p1 << 1);  /* check that 'num_t' is an integer type */
-        r += sprintf(r, "typedef ");
         *p1 = -1;  /* check that 'num_t' is not declared 'const' */
-        if (*p1 > 0) {
-            if (sizeof(*p1) == 1 && *p1 == 1)
-                r += sprintf(r, "_Bool");
-            else if (sizeof(*p1) == sizeof(unsigned long))
-                r += sprintf(r, "unsigned long");
-            else if (sizeof(*p1) == sizeof(unsigned int))
-                r += sprintf(r, "unsigned int");
-            else if (sizeof(*p1) == sizeof(unsigned short))
-                r += sprintf(r, "unsigned short");
-            else if (sizeof(*p1) == sizeof(unsigned char))
-                r += sprintf(r, "unsigned char");
-            else if (sizeof(*p1) == sizeof(unsigned long long))
-                r += sprintf(r, "unsigned long long");
-            else
-                r += sprintf(r, "uint%u_t", (int)sizeof(*p1) * 8);
-        }
-        else {
-            if (sizeof(*p1) == sizeof(long))
-                r += sprintf(r, "long");
-            else if (sizeof(*p1) == sizeof(int))
-                r += sprintf(r, "int");
-            else if (sizeof(*p1) == sizeof(short))
-                r += sprintf(r, "short");
-            else if (sizeof(*p1) == sizeof(signed char))
-                r += sprintf(r, "signed char");
-            else if (sizeof(*p1) == sizeof(long long))
-                r += sprintf(r, "long long");
-            else
-                r += sprintf(r, "int%u_t", (int)sizeof(*p1) * 8);
-        }
-        r += sprintf(r, " num_t;\n");
+        void *t = CB__INT_TYPE(*p1, "long");
+        cb->define_type("num_t", t);
     }
-    return 0;
 }
diff --git a/test/codegen/003c.c b/test/codegen/003c.c
--- a/test/codegen/003c.c
+++ b/test/codegen/003c.c
@@ -2,48 +2,15 @@
 
 # ____________________________________________________________
 
-int test003c(char *r)
+void test003c(creflect_builder_t *cb)
 {
-    if (!r)
-        return 8 + 18 + 9;
     {
         num_t *p1;
         char b[sizeof(*p1)];
         p1 = (void *)b;
         (void)(*p1 << 1);  /* check that 'num_t' is an integer type */
-        r += sprintf(r, "typedef ");
         *p1 = -1;  /* check that 'num_t' is not declared 'const' */
-        if (*p1 > 0) {
-            if (sizeof(*p1) == 1 && *p1 == 1)
-                r += sprintf(r, "_Bool");
-            else if (sizeof(*p1) == sizeof(unsigned long long))
-                r += sprintf(r, "unsigned long long");
-            else if (sizeof(*p1) == sizeof(unsigned long))
-                r += sprintf(r, "unsigned long");
-            else if (sizeof(*p1) == sizeof(unsigned int))
-                r += sprintf(r, "unsigned int");
-            else if (sizeof(*p1) == sizeof(unsigned short))
-                r += sprintf(r, "unsigned short");
-            else if (sizeof(*p1) == sizeof(unsigned char))
-                r += sprintf(r, "unsigned char");
-            else
-                r += sprintf(r, "uint%u_t", (int)sizeof(*p1) * 8);
-        }
-        else {
-            if (sizeof(*p1) == sizeof(long long))
-                r += sprintf(r, "long long");
-            else if (sizeof(*p1) == sizeof(long))
-                r += sprintf(r, "long");
-            else if (sizeof(*p1) == sizeof(int))
-                r += sprintf(r, "int");
-            else if (sizeof(*p1) == sizeof(short))
-                r += sprintf(r, "short");
-            else if (sizeof(*p1) == sizeof(signed char))
-                r += sprintf(r, "signed char");
-            else
-                r += sprintf(r, "int%u_t", (int)sizeof(*p1) * 8);
-        }
-        r += sprintf(r, " num_t;\n");
+        void *t = CB__INT_TYPE(*p1, "long long");
+        cb->define_type("num_t", t);
     }
-    return 0;
 }
diff --git a/test/codegen/003d.c b/test/codegen/003d.c
--- a/test/codegen/003d.c
+++ b/test/codegen/003d.c
@@ -2,48 +2,15 @@
 
 # ____________________________________________________________
 
-int test003d(char *r)
+void test003d(creflect_builder_t *cb)
 {
-    if (!r)
-        return 8 + 18 + 9;
     {
         num_t *p1;
         char b[sizeof(*p1)];
         p1 = (void *)b;
         (void)(*p1 << 1);  /* check that 'num_t' is an integer type */
-        r += sprintf(r, "typedef ");
         *p1 = -1;  /* check that 'num_t' is not declared 'const' */
-        if (*p1 > 0) {
-            if (sizeof(*p1) == 1 && *p1 == 1)
-                r += sprintf(r, "_Bool");
-            else if (sizeof(*p1) == sizeof(unsigned char))
-                r += sprintf(r, "unsigned char");
-            else if (sizeof(*p1) == sizeof(unsigned short))
-                r += sprintf(r, "unsigned short");
-            else if (sizeof(*p1) == sizeof(unsigned int))
-                r += sprintf(r, "unsigned int");
-            else if (sizeof(*p1) == sizeof(unsigned long))
-                r += sprintf(r, "unsigned long");
-            else if (sizeof(*p1) == sizeof(unsigned long long))
-                r += sprintf(r, "unsigned long long");
-            else
-                r += sprintf(r, "uint%u_t", (int)sizeof(*p1) * 8);
-        }
-        else {
-            if (sizeof(*p1) == sizeof(signed char))
-                r += sprintf(r, "signed char");
-            else if (sizeof(*p1) == sizeof(short))
-                r += sprintf(r, "short");
-            else if (sizeof(*p1) == sizeof(int))
-                r += sprintf(r, "int");
-            else if (sizeof(*p1) == sizeof(long))
-                r += sprintf(r, "long");
-            else if (sizeof(*p1) == sizeof(long long))
-                r += sprintf(r, "long long");
-            else
-                r += sprintf(r, "int%u_t", (int)sizeof(*p1) * 8);
-        }
-        r += sprintf(r, " num_t;\n");
+        void *t = CB__INT_TYPE(*p1, "char");
+        cb->define_type(cb, "num_t", t);
     }
-    return 0;
 }
diff --git a/test/codegen/003e.c b/test/codegen/003e.c
--- a/test/codegen/003e.c
+++ b/test/codegen/003e.c
@@ -2,48 +2,18 @@
 
 # ____________________________________________________________
 
-int test003e(char *r)
+void test003e(crx_self_t *self, crx_builder_t *cb)
 {
-    if (!r)
-        return 8 + 18 + 9;
+    crx_type_t *t1;
     {
         num_t *p1;
         char b[sizeof(*p1)];
         p1 = (void *)b;
         (void)(*p1 << 1);  /* check that 'num_t' is an integer type */
-        r += sprintf(r, "typedef ");
         *p1 = -1;  /* check that 'num_t' is not declared 'const' */
-        if (*p1 > 0) {
-            if (sizeof(*p1) == 1 && *p1 == 1)
-                r += sprintf(r, "_Bool");
-            else if (sizeof(*p1) == sizeof(char))
-                r += sprintf(r, "char");
-            else if (sizeof(*p1) == sizeof(unsigned short))
-                r += sprintf(r, "unsigned short");
-            else if (sizeof(*p1) == sizeof(unsigned int))
-                r += sprintf(r, "unsigned int");
-            else if (sizeof(*p1) == sizeof(unsigned long))
-                r += sprintf(r, "unsigned long");
-            else if (sizeof(*p1) == sizeof(unsigned long long))
-                r += sprintf(r, "unsigned long long");
-            else
-                r += sprintf(r, "uint%u_t", (int)sizeof(*p1) * 8);
-        }
-        else {
-            if (sizeof(*p1) == sizeof(char))
-                r += sprintf(r, "char");
-            else if (sizeof(*p1) == sizeof(short))
-                r += sprintf(r, "short");
-            else if (sizeof(*p1) == sizeof(int))
-                r += sprintf(r, "int");
-            else if (sizeof(*p1) == sizeof(long))
-                r += sprintf(r, "long");
-            else if (sizeof(*p1) == sizeof(long long))
-                r += sprintf(r, "long long");
-            else
-                r += sprintf(r, "int%u_t", (int)sizeof(*p1) * 8);
-        }
-        r += sprintf(r, " num_t;\n");
+        char b2[sizeof(*p1) == 1 ? 1 : -1];  /* check that 'num_t' is a single-byte integer */
+        (void)b2;
+        t1 = cb->get_char_type(self);
+        cb->define_type(self, "num_t", t1);
     }
-    return 0;
 }
diff --git a/test/codegen/003f.c b/test/codegen/003f.c
--- a/test/codegen/003f.c
+++ b/test/codegen/003f.c
@@ -2,48 +2,15 @@
 
 # ____________________________________________________________
 
-int test003f(char *r)
+void test003f(creflect_builder_t *cb)
 {
-    if (!r)
-        return 8 + 18 + 9;
     {
         num_t *p1;
         char b[sizeof(*p1)];
         p1 = (void *)b;
         (void)(*p1 << 1);  /* check that 'num_t' is an integer type */
-        r += sprintf(r, "typedef ");
         *p1 = -1;  /* check that 'num_t' is not declared 'const' */
-        if (*p1 > 0) {
-            if (sizeof(*p1) == 1 && *p1 == 1)
-                r += sprintf(r, "_Bool");
-            else if (sizeof(*p1) == sizeof(unsigned long long))
-                r += sprintf(r, "unsigned long long");
-            else if (sizeof(*p1) == sizeof(unsigned long))
-                r += sprintf(r, "unsigned long");
-            else if (sizeof(*p1) == sizeof(unsigned int))
-                r += sprintf(r, "unsigned int");
-            else if (sizeof(*p1) == sizeof(unsigned short))
-                r += sprintf(r, "unsigned short");
-            else if (sizeof(*p1) == sizeof(unsigned char))
-                r += sprintf(r, "unsigned char");
-            else
-                r += sprintf(r, "uint%u_t", (int)sizeof(*p1) * 8);
-        }
-        else {
-            if (sizeof(*p1) == sizeof(long long))
-                r += sprintf(r, "long long");
-            else if (sizeof(*p1) == sizeof(long))
-                r += sprintf(r, "long");
-            else if (sizeof(*p1) == sizeof(int))
-                r += sprintf(r, "int");
-            else if (sizeof(*p1) == sizeof(short))
-                r += sprintf(r, "short");
-            else if (sizeof(*p1) == sizeof(signed char))
-                r += sprintf(r, "signed char");
-            else
-                r += sprintf(r, "int%u_t", (int)sizeof(*p1) * 8);
-        }
-        r += sprintf(r, " num_t;\n");
+        void *t = CB__INT_TYPE(cb, *p1, "unsigned long long");
+        cb->define_type(cb, "num_t", t);
     }
-    return 0;
 }
diff --git a/test/codegen/004.c b/test/codegen/004.c
--- a/test/codegen/004.c
+++ b/test/codegen/004.c
@@ -2,10 +2,8 @@
 
 # ____________________________________________________________
 
-int test004(char *r)
+void test004(creflect_builder_t *cb)
 {
-    if (!r)
-        return 8 + 18 + 10;
     {
         num_t *p1;
         char *p2;
@@ -13,8 +11,18 @@
         p1 = (void *)&p2;
         *p1 = (void *)b;    /* check that 'num_t' is a pointer type */
         (void)(**p1 << 1);  /* check that '*num_t' is an integer type */
-        r += sprintf(r, "typedef ");
         **p1 = -1;  /* check that '*num_t' is not declared 'const' */
+        void *t;
+        if (*p1 > 0) {
+            if (sizeof(*p1) == 1 && *p1 == 1)
+                t = cb->get_bool_type();
+            else
+                t = cb->get_signed_type(sizeof(*p1), "int");
+        }
+        else {
+            t = cb->get_unsigned_type(sizeof(*p1), "int");
+        }
+        
         if (**p1 > 0) {
             if (sizeof(**p1) == 1 && **p1 == 1)
                 r += sprintf(r, "_Bool");
diff --git a/test/codegen/006.c b/test/codegen/006.c
--- a/test/codegen/006.c
+++ b/test/codegen/006.c
@@ -10,10 +10,10 @@
     {
         num_t *p1;
         char b[sizeof(*p1)];
+        memset(b, -1, sizeof(b));
         p1 = (void *)b;
         (void)(*p1 << 1);  /* check that 'num_t' is an integer type */
         r += sprintf(r, "typedef const ");
-        memset(b, -1, sizeof(b));
         if (*p1 > 0) {
             if (sizeof(*p1) == 1 && *p1 == 1)
                 r += sprintf(r, "_Bool");
diff --git a/test/codegen/007.c b/test/codegen/007.c
new file mode 100644
--- /dev/null
+++ b/test/codegen/007.c
@@ -0,0 +1,22 @@
+typedef int (*myfunc_t)(long, unsigned long long);
+
+# ____________________________________________________________
+
+static void __creflect_t_myfunc_t(void *func, void *args[], void *result) {
+    myfunc_t f = func;
+    *(int *)result = f(*(long *)args[0], *(unsigned long long *)args[1]);
+}
+
+int test007(char *r)
+{
+    if (!r)
+        return 65;
+    {
+        myfunc_t *p1;
+        char *p2;
+        p1 = (void *)&p2;
+        *p1 = (void *)0;    /* check that 'myfunc_t' is a pointer type */
+        r += sprintf(r, "typedef int (*myfunc_t)(long, unsigned long long)/*%p*/;\n", &__creflect_t_myfunc_t);
+    }
+    return 0;
+}
diff --git a/test/codegen/func-001.c b/test/codegen/func-001.c
--- a/test/codegen/func-001.c
+++ b/test/codegen/func-001.c
@@ -6,7 +6,7 @@
 
 # ____________________________________________________________
 
-static void __creflect_t1(void *func, void *args[], void *result) {
+static void __creflect_t2(void *func, void *args[], void *result) {
     int(*f)(void) = func;
     *(int *)result = f();
 }
@@ -15,11 +15,12 @@
     return f();
 }
 
-int testfunc_001(char *r)
+void testfunc_001(crx_builder_t *cb)
 {
-    if (!r)
-        return 3 + 24 + 24 + 18 + 1;
-    r += sprintf(r, "/*%p*/", &__creflect_d_f);
-    r += sprintf(r, "int f(void)/*%p*/;\n", &__creflect_t1);
-    return 0;
+    crx_type *t1, *t2;
+    {
+        t1 = cb->get_signed_type(cb, sizeof(int), "int");
+        t2 = cb->get_function_type(cb, t1, 0, 0, &__creflect_t2);
+        cb->define_var(cb, "f", t2, &__creflect_d_f);
+    }
 }
diff --git a/test/codegen/func-001b.c b/test/codegen/func-001b.c
new file mode 100644
--- /dev/null
+++ b/test/codegen/func-001b.c
@@ -0,0 +1,46 @@
+unsigned int f(long long);
+long g(int, int);
+long h(int, int);
+
+# ____________________________________________________________
+
+unsigned int f(long long a) { return (unsigned int)(a / 1291); }
+long g(int a, int b) { return b - a; }
+long h(int a, int b) { return b * (long)a; }
+
+# ____________________________________________________________
+
+static void __creflect_t1(void *func, void *args[], void *result) {
+    unsigned int(*f)(long long) = func;
+    *(unsigned int *)result = f(*(long long *)args[0]);
+}
+
+static unsigned int __creflect_d_f(long long a0) {
+    return f(a0);
+}
+
+static void __creflect_t2(void *func, void *args[], void *result) {
+    long(*f)(int, int) = func;
+    *(long *)result = f(*(int *)args[0], *(int *)args[1]);
+}
+
+static long __creflect_d_g(int a0, int a1) {
+    return g(a0, a1);
+}
+
+static long __creflect_d_h(int a0, int a1) {
+    return h(a0, a1);
+}
+
+int testfunc_002(char *r)
+{
+    if (!r)
+        return 3 + 999 + 1;
+    r += sprintf(r, "unsigned int");
+    r += sprintf(r, " /*%p*/f(long long)/*%p*/;\n", &__creflect_d_f, &__creflect_t1);
+    r += sprintf(r, "long");
+    r += sprintf(r, " /*%p*/g(int, int)/*%p*/;\n", &__creflect_d_g, &__creflect_t2);
+    r += sprintf(r, "long");
+    r += sprintf(r, " /*%p*/h(int, int)/*%p*/;\n", &__creflect_d_h, &__creflect_t2);
+    return 0;
+}
diff --git a/test/codegen/func-002.c b/test/codegen/func-002.c
--- a/test/codegen/func-002.c
+++ b/test/codegen/func-002.c
@@ -1,46 +1,20 @@
-unsigned int f(long long);
-long g(int, int);
-long h(int, int);
+
+int f(int, ...);
 
 # ____________________________________________________________
 
-unsigned int f(long long a) { return (unsigned int)(a / 1291); }
-long g(int a, int b) { return b - a; }
-long h(int a, int b) { return b * (long)a; }
+int f(int a, ...) { return 42 * a; }
 
 # ____________________________________________________________
 
-static void __creflect_t1(void *func, void *args[], void *result) {
-    unsigned int(*f)(long long) = func;
-    *(unsigned int *)result = f(*(long long *)args[0]);
+void testfunc_002(crx_builder_t *cb)
+{
+    crx_type *t1, *a2[1], *t2;
+    {
+        int (*p1)(int, ...) = f;  /* check that 'f' is a function with exactly the given signature */
+        t1 = cb->get_signed_type(cb, sizeof(int), "int");
+        a2[0] = t1;
+        t2 = cb->get_ellipsis_function_type(cb, t1, a2, 1);
+        cb->define_var(cb, "f", t2, p1);
+    }
 }
-
-static unsigned int __creflect_d_f(long long a0) {
-    return f(a0);
-}
-
-static void __creflect_t2(void *func, void *args[], void *result) {
-    long(*f)(int, int) = func;
-    *(long *)result = f(*(int *)args[0], *(int *)args[1]);
-}
-
-static long __creflect_d_g(int a0, int a1) {
-    return g(a0, a1);
-}
-
-static long __creflect_d_h(int a0, int a1) {
-    return h(a0, a1);
-}
-
-int testfunc_002(char *r)
-{
-    if (!r)
-        return 3 + 999 + 1;
-    r += sprintf(r, "unsigned int");
-    r += sprintf(r, " /*%p*/f(long long)/*%p*/;\n", &__creflect_d_f, &__creflect_t1);
-    r += sprintf(r, "long");
-    r += sprintf(r, " /*%p*/g(int, int)/*%p*/;\n", &__creflect_d_g, &__creflect_t2);
-    r += sprintf(r, "long");
-    r += sprintf(r, " /*%p*/h(int, int)/*%p*/;\n", &__creflect_d_h, &__creflect_t2);
-    return 0;
-}
diff --git a/test/codegen/func-003.c b/test/codegen/func-003.c
--- a/test/codegen/func-003.c
+++ b/test/codegen/func-003.c
@@ -1,24 +1,25 @@
-typedef int(*func_t)(long);
+typedef int(*func_t)(long, long);
 
 # ____________________________________________________________
 
-static void __creflect_t1(void *func, void *args[], void *result) {
-    int(*f)(long) = func;
-    *(int *)result = f(*(long *)args[0]);
+static void __creflect_t3(void *func, void *args[], void *result) {
+    func_t f = func;
+    *(int *)result = f(*(long *)args[0], *(long *)args[1]);
 }
 
-int testfunc_003(char *r)
+void testfunc_003(crx_builder_t *cb)
 {
-    if (!r)
-        return 8 + 3 + 17 + 24 + 4 + 1;
-    r += sprintf(r, "typedef ");
+    crx_type *t1, *t2, *a3[2], *t3;
     {
         func_t *p1;
         char *p2;
         p1 = (void *)&p2;
         *p1 = (void *)0;    /* check that 'func_t' is a pointer type */
-        r += sprintf(r, "int");
+        t1 = cb->get_signed_type(cb, sizeof(int), "int");
+        t2 = cb->get_signed_type(cb, sizeof(long), "long");
+        a3[0] = t2;
+        a3[1] = t2;
+        t3 = cb->get_function_type(cb, t1, a3, 2, &__creflect_t3);
+        cb->define_type(cb, "func_t", t3);
     }
-    r += sprintf(r, "(*func_t)(long)/*%p*/;\n", __creflect_t1);
-    return 0;
 }
diff --git a/test/codegen/glob-001.c b/test/codegen/glob-001.c
--- a/test/codegen/glob-001.c
+++ b/test/codegen/glob-001.c
@@ -5,12 +5,12 @@
 int testglob_001(char *r)
 {
     if (!r)
-        return 3 + 24 + 4 + 24 + 1;
+        return 28 + 17;
     {
-        void *p1 = someglob;  /* check that 'someglob' is a pointer, of a type compatible with 'void *' */
+        void *p1 = someglob;  /* check that 'someglob' is a pointer */
+        r += sprintf(r, "/*%p*/", &someglob);
         if (0) { someglob = p1; }  /* check that 'someglob' is a pointer variable, and not an array or a constant */
-        r += sprintf(r, "void *someglob");
+        r += sprintf(r, "void *someglob;\n");
     }
-    r += sprintf(r, ";/*%p*/\n", &someglob);
     return 0;
 }
diff --git a/test/codegen/glob-002.c b/test/codegen/glob-002.c
--- a/test/codegen/glob-002.c
+++ b/test/codegen/glob-002.c
@@ -2,15 +2,14 @@
 
 # ____________________________________________________________
 
-int testglob_002(char *r)
+void testglob_002(crx_builder_t *cb)
 {
-    if (!r)
-        return 3 + 24 + 4 + 24 + 1;
+    crx_type *t1, *t2;
     {
         char (*p1)[] = &someglob;  /* check that 'someglob' is of type 'char[]' */
         (void)p1;
-        r += sprintf(r, "char someglob[%ld]", (long)(sizeof(someglob) / sizeof(*someglob)));
+        t1 = cb->get_char_type(cb);
+        t2 = cb->get_array_type(cb, t1, sizeof(someglob) / sizeof(*someglob));
+        cb->define_var(cb, "someglob", t2, &someglob);
     }
-    r += sprintf(r, ";/*%p*/\n", someglob);
-    return 0;
 }
diff --git a/test/codegen/glob-004.c b/test/codegen/glob-004.c
new file mode 100644
--- /dev/null
+++ b/test/codegen/glob-004.c
@@ -0,0 +1,21 @@
+int (*someglob)(long, long);
+
+# ____________________________________________________________
+
+static void __creflect_t1(void *func, void *args[], void *result) {
+    int(*f)(long, long) = func;
+    *(int *)result = f(*(long *)args[0], *(long *)args[1]);
+}
+
+int testglob_004(char *r)
+{
+    if (!r)
+        return 100;
+    {
+        int (**p1)(long, long) = &someglob;  /* check the exact type of 'someglob' */
+        (void)p1;
+        r += sprintf(r, "/*%p*/", &someglob);
+        r += sprintf(r, "int (*someglob)(long, long)/*%p*/;\n", &__creflect_t1);
+    }
+    return 0;
+}
diff --git a/test/codegen/struct-001.c b/test/codegen/struct-001.c
--- a/test/codegen/struct-001.c
+++ b/test/codegen/struct-001.c
@@ -1,54 +1,29 @@
 struct foo_s {
-  int aa;
-  unsigned int bb;
+    int aa;
+    unsigned int bb;
 };
 
 # ____________________________________________________________
 
-int teststruct_001(char *r)
+void teststruct_001(crx_builder_t *cb)
 {
-    if (!r)
-        return 69 + 30 + 18 + 6 + 30 + 18 + 6 + 4;
-    r += sprintf(r, "struct foo_s /*%lld,%lld*/{\n", (long long)sizeof(struct foo_s), (long long)(((char *)&((struct{char a; struct foo_s b;} *)0)->b) - (char *)0));
+    crx_type_t *t1, *t2, *t3;
+    crx_field_t d1[2];
+    t1 = cb->get_struct_type(cb, "foo_s");
     {
         struct foo_s *p1;
-        long long o = ((char *)&((struct foo_s *)0)->aa) - (char *)0;  /* check that 'struct foo_s::aa' is not an array */
+        size_t o = ((char *)&((struct foo_s *)0)->aa) - (char *)0;  /* check that 'struct foo_s::aa' is not an array */
         char b[sizeof(p1->aa)];
         r += sprintf(r, "  /*%lld*/", o);
         p1 = (void *)(((char *)b) - o);
         (void)(p1->aa << 1);  /* check that 'struct foo_s::aa' is an integer type */
         p1->aa = -1;  /* check that 'struct foo_s::aa' is not declared 'const' */
-        if (p1->aa > 0) {
-            if (sizeof(p1->aa) == 1 && p1->aa == 1)
-                r += sprintf(r, "_Bool");
-            else if (sizeof(p1->aa) == sizeof(unsigned int))
-                r += sprintf(r, "unsigned int");
-            else if (sizeof(p1->aa) == sizeof(unsigned short))
-                r += sprintf(r, "unsigned short");
-            else if (sizeof(p1->aa) == sizeof(unsigned char))
-                r += sprintf(r, "unsigned char");
-            else if (sizeof(p1->aa) == sizeof(unsigned long))
-                r += sprintf(r, "unsigned long");
-            else if (sizeof(p1->aa) == sizeof(unsigned long long))
-                r += sprintf(r, "unsigned long long");
-            else
-                r += sprintf(r, "uint%u_t", (int)sizeof(p1->aa) * 8);
-        }
-        else {
-            if (sizeof(p1->aa) == sizeof(int))
-                r += sprintf(r, "int");
-            else if (sizeof(p1->aa) == sizeof(short))
-                r += sprintf(r, "short");
-            else if (sizeof(p1->aa) == sizeof(signed char))
-                r += sprintf(r, "signed char");
-            else if (sizeof(p1->aa) == sizeof(long))
-                r += sprintf(r, "long");
-            else if (sizeof(p1->aa) == sizeof(long long))
-                r += sprintf(r, "long long");
-            else
-                r += sprintf(r, "int%u_t", (int)sizeof(p1->aa) * 8);
-        }
-        r += sprintf(r, " aa;\n");
+        t2 = CRX_INT_TYPE(cb, p1->aa, "int");
+        d1[0].name = "aa";
+        d1[0].type = t2;
+        d1[0].offset = o;
+        d1[0].numbits = -1;
+        d1[0].bitshift = -1;
     }
     {
         struct foo_s *p1;
@@ -58,38 +33,14 @@
         p1 = (void *)(((char *)b) - o);
         (void)(p1->bb << 1);  /* check that 'struct foo_s::bb' is an integer type */
         p1->bb = -1;  /* check that 'struct foo_s::bb' is not declared 'const' */
-        if (p1->bb > 0) {
-            if (sizeof(p1->bb) == 1 && p1->bb == 1)
-                r += sprintf(r, "_Bool");
-            else if (sizeof(p1->bb) == sizeof(unsigned int))
-                r += sprintf(r, "unsigned int");
-            else if (sizeof(p1->bb) == sizeof(unsigned short))
-                r += sprintf(r, "unsigned short");
-            else if (sizeof(p1->bb) == sizeof(unsigned char))
-                r += sprintf(r, "unsigned char");
-            else if (sizeof(p1->bb) == sizeof(unsigned long))
-                r += sprintf(r, "unsigned long");
-            else if (sizeof(p1->bb) == sizeof(unsigned long long))
-                r += sprintf(r, "unsigned long long");
-            else
-                r += sprintf(r, "uint%u_t", (int)sizeof(p1->bb) * 8);
-        }
-        else {
-            if (sizeof(p1->bb) == sizeof(int))
-                r += sprintf(r, "int");
-            else if (sizeof(p1->bb) == sizeof(short))
-                r += sprintf(r, "short");
-            else if (sizeof(p1->bb) == sizeof(signed char))
-                r += sprintf(r, "signed char");
-            else if (sizeof(p1->bb) == sizeof(long))
-                r += sprintf(r, "long");
-            else if (sizeof(p1->bb) == sizeof(long long))
-                r += sprintf(r, "long long");
-            else
-                r += sprintf(r, "int%u_t", (int)sizeof(p1->bb) * 8);
-        }
-        r += sprintf(r, " bb;\n");
+        t3 = CRX_INT_TYPE(cb, p1->bb, "int");
+        d1[0].name = "bb";
+        d1[0].type = t3;
+        d1[0].offset = o;
+        d1[0].numbits = -1;
+        d1[0].bitshift = -1;
     }
-    r += sprintf(r, "};\n");
-    return 0;
+    cb->complete(cb, t1, sizeof(struct foo_s),
+                 offsetof(struct{char a; struct foo_s b;}, b),
+                 d1, 2);
 }
diff --git a/test/codegen/struct-001b.c b/test/codegen/struct-001b.c
new file mode 100644
--- /dev/null
+++ b/test/codegen/struct-001b.c
@@ -0,0 +1,56 @@
+struct foo_s /*4,4*/{
+  /*0*/const int aa;
+};
+
+# ____________________________________________________________
+#include <string.h>
+
+int teststruct_001b(char *r)
+{
+    if (!r)
+        return 100;
+    r += sprintf(r, "struct foo_s /*%lld,%lld*/{\n", (long long)sizeof(struct foo_s), (long long)(((char *)&((struct{char a; struct foo_s b;} *)0)->b) - (char *)0));
+    {
+        struct foo_s *p1;
+        long long o = ((char *)&((struct foo_s *)0)->aa) - (char *)0;  /* check that 'struct foo_s::aa' is not an array */
+        char b[sizeof(p1->aa)];
+        memset(b, -1, sizeof(b));
+        r += sprintf(r, "  /*%lld*/", o);
+        p1 = (void *)(((char *)b) - o);
+        (void)(p1->aa << 1);  /* check that 'struct foo_s::aa' is an integer type */
+        r += sprintf(r, "const ");
+        if (p1->aa > 0) {
+            if (sizeof(p1->aa) == 1 && p1->aa == 1)
+                r += sprintf(r, "_Bool");
+            else if (sizeof(p1->aa) == sizeof(unsigned int))
+                r += sprintf(r, "unsigned int");
+            else if (sizeof(p1->aa) == sizeof(unsigned short))
+                r += sprintf(r, "unsigned short");
+            else if (sizeof(p1->aa) == sizeof(unsigned char))
+                r += sprintf(r, "unsigned char");
+            else if (sizeof(p1->aa) == sizeof(unsigned long))
+                r += sprintf(r, "unsigned long");
+            else if (sizeof(p1->aa) == sizeof(unsigned long long))
+                r += sprintf(r, "unsigned long long");
+            else
+                r += sprintf(r, "uint%u_t", (int)sizeof(p1->aa) * 8);
+        }
+        else {
+            if (sizeof(p1->aa) == sizeof(int))
+                r += sprintf(r, "int");
+            else if (sizeof(p1->aa) == sizeof(short))
+                r += sprintf(r, "short");
+            else if (sizeof(p1->aa) == sizeof(signed char))
+                r += sprintf(r, "signed char");
+            else if (sizeof(p1->aa) == sizeof(long))
+                r += sprintf(r, "long");
+            else if (sizeof(p1->aa) == sizeof(long long))
+                r += sprintf(r, "long long");
+            else
+                r += sprintf(r, "int%u_t", (int)sizeof(p1->aa) * 8);
+        }
+        r += sprintf(r, " aa;\n");
+    }
+    r += sprintf(r, "};\n");
+    return 0;
+}
diff --git a/test/codegen/struct-002.c b/test/codegen/struct-002.c
--- a/test/codegen/struct-002.c
+++ b/test/codegen/struct-002.c
@@ -1,26 +1,23 @@
 struct foo_s {
-    void *aa;
+  void *aa;
 };
 
 # ____________________________________________________________
 
-static void __creflect1(void r(char *, void**, int))
+int teststruct_002(char *r)
 {
-    void *a[2];
-    __CREFLECT_PREV(r);
-    a[0] = (void *)sizeof(struct foo_s);  /* size */
-    a[1] = &((struct{char a; struct foo_s b;}*)0)->b;  /* align */
-    r("struct foo_s", a, 2);
+    if (!r)
+        return 100;
+    r += sprintf(r, "struct foo_s /*%lld,%lld*/{\n", (long long)sizeof(struct foo_s), (long long)(((char *)&((struct{char a; struct foo_s b;} *)0)->b) - (char *)0));
     {
         struct foo_s *p1;
-        void *o = &((struct foo_s *)0)->aa;  /* offset */
-        char *p2;
-        a[1] = o;
-        p1 = (void *)(((char *)&p2) - (long)o);
+        long long o = ((char *)&((struct foo_s *)0)->aa) - (char *)0;  /* check that 'struct foo_s::aa' is not an array */
+        char b[sizeof(p1->aa)];
+        r += sprintf(r, "  /*%lld*/", o);
+        p1 = (void *)(((char *)b) - o);
         p1->aa = (void *)0;    /* check that 'struct foo_s::aa' is a pointer type */
+        r += sprintf(r, "void *aa;\n");
     }
-    r("{aa:void*", a, 2);
+    r += sprintf(r, "};\n");
+    return 0;
 }
-
-#expect  struct foo_s  8  8
-#expect  {aa:void*  99  0
diff --git a/test/codegen/struct-003.c b/test/codegen/struct-003.c
--- a/test/codegen/struct-003.c
+++ b/test/codegen/struct-003.c
@@ -1,30 +1,56 @@
 struct foo_s {
-    int *aa;
+  int *aa;
 };
 
 # ____________________________________________________________
 
-static void __creflect1(void r(char *, void**, int))
+int teststruct_003(char *r)
 {
-    void *a[3];
-    __CREFLECT_PREV(r);
-    a[0] = (void *)sizeof(struct foo_s);  /* size */
-    a[1] = &((struct{char a; struct foo_s b;}*)0)->b;  /* align */
-    r("struct foo_s", a, 2);
+    if (!r)
+        return 100;
+    r += sprintf(r, "struct foo_s /*%lld,%lld*/{\n", (long long)sizeof(struct foo_s), (long long)(((char *)&((struct{char a; struct foo_s b;} *)0)->b) - (char *)0));
     {
         struct foo_s *p1;
-        void *o = &((struct foo_s *)0)->aa;  /* offset */
         char *p2;
+        long long o = ((char *)&((struct foo_s *)0)->aa) - (char *)0;  /* check that 'struct foo_s::aa' is not an array */
         char b[sizeof(*p1->aa)];  /* check that '*struct foo_s::aa' is a valid type */
-        a[1] = o;
-        p1 = (void *)(((char *)&p2) - (long)o);
+        r += sprintf(r, "  /*%lld*/", o);
+        p1 = (void *)(((char *)&p2) - o);
         p1->aa = (void *)b;    /* check that 'struct foo_s::aa' is a pointer type */
         (void)(*p1->aa << 1);  /* check that '*struct foo_s::aa' is an integer type */
-        *p1->aa = -1;
-        a[2] = (void *)(*p1->aa > 0 ? sizeof(*p1->aa) : -sizeof(*p1->aa));
+        *p1->aa = -1;  /* check that '*struct foo_s::aa' is not declared 'const' */
+        if (*p1->aa > 0) {
+            if (sizeof(*p1->aa) == 1 && *p1->aa == 1)
+                r += sprintf(r, "_Bool");
+            else if (sizeof(*p1->aa) == sizeof(unsigned int))
+                r += sprintf(r, "unsigned int");
+            else if (sizeof(*p1->aa) == sizeof(unsigned short))
+                r += sprintf(r, "unsigned short");
+            else if (sizeof(*p1->aa) == sizeof(unsigned char))
+                r += sprintf(r, "unsigned char");
+            else if (sizeof(*p1->aa) == sizeof(unsigned long))
+                r += sprintf(r, "unsigned long");
+            else if (sizeof(*p1->aa) == sizeof(unsigned long long))
+                r += sprintf(r, "unsigned long long");
+            else
+                r += sprintf(r, "uint%u_t", (int)sizeof(*p1->aa) * 8);
+        }
+        else {
+            if (sizeof(*p1->aa) == sizeof(int))
+                r += sprintf(r, "int");
+            else if (sizeof(*p1->aa) == sizeof(short))
+                r += sprintf(r, "short");
+            else if (sizeof(*p1->aa) == sizeof(signed char))
+                r += sprintf(r, "signed char");
+            else if (sizeof(*p1->aa) == sizeof(long))
+                r += sprintf(r, "long");
+            else if (sizeof(*p1->aa) == sizeof(long long))
+                r += sprintf(r, "long long");
+            else
+                r += sprintf(r, "int%u_t", (int)sizeof(*p1->aa) * 8);
+        }
+        r += sprintf(r, " *aa;\n");
     }
-    r("{aa:int?*", a, 3);
+    r += sprintf(r, "};\n");
+    return 0;
 }
-
-#expect  struct foo_s  8  8
-#expect  {aa:int?*  99  0  -4
diff --git a/test/test_cgcompile.py b/test/test_cgcompile.py
--- a/test/test_cgcompile.py
+++ b/test/test_cgcompile.py
@@ -14,15 +14,6 @@
     for line in inputlines:
         if line.startswith('#expect'):
             expected.append(line[8:].rstrip())
-    if not expected:
-        for line in inputlines:
-            if line.startswith('# _______'):
-                break
-            line = line.split('//')[0].rstrip()
-            if line:
-                expected.append(line)
-        else:
-            raise ValueError("no '# _______' found in %r" % (filename,))
     #
     basename = os.path.splitext(filename)[0]
     infile = str(udir.join('cg-' + filename))
@@ -30,34 +21,14 @@
     assert infile != outfile
     f = open(infile, 'w')
     f.write('#include <stdio.h>\n')
-    f.write('#define TESTFN(r) test%s(r)\n' % (basename.replace('-','_'),))
+    f.write('#include "%s/../../creflect/creflect.h"\n' % path)
+    f.write('#define TESTFN(cb) test%s(cb)\n' % (basename.replace('-','_'),))
     f.write('\n')
     for line in inputlines:
         if not line.startswith('#') or line.startswith('#include'):
             f.write(line)
-    f.write(r'''
-#include <assert.h>
-int main(void)
-{
-    char buffer[8192];
-    int i, r, r2;
-    r = TESTFN((char *)0);
-    assert(r > 0);
-    assert(r <= 8188);
-    for (i = 0; i <= r+3; i++)
-        buffer[r] = 0xfd;
-    r2 = TESTFN(buffer);
-    for (i = 0; i < r; i++) {
-        assert(buffer[i] != (char)0xfd);
-        if (buffer[i] == 0)
-            break;
-    }
-    assert(i < r);
-    assert(i == 0 || buffer[i-1] == '\n');
-    printf("%s", buffer);
-    return (r2 != 0);
-}
-''')
+    f.write('\n')
+    f.write('#include "%s/../cgcompile.c"\n' % path)
     f.close()
     #
     err = os.system("gcc -Werror -Wall '%s' -o '%s'" % (infile, outfile))
@@ -67,7 +38,12 @@
     lines = g.readlines()
     err = g.close()
     assert not err
-    r_remove_addr = re.compile(r"/[*][-0-9a-fx,]+[*]/")
+    if any('/*' in line for line in expected):
+        # only remove the comments that are addresses
+        r_remove_addr = re.compile(r"/[*]0x[-0-9a-f]+[*]/")
+    else:
+        # remove the comments that are addresses or sizes
+        r_remove_addr = re.compile(r"/[*][-0-9a-fx,]+[*]/")
     got = [r_remove_addr.sub('', line.rstrip()) for line in lines]
     compare_lists(got, expected)
 


More information about the pypy-commit mailing list