[pypy-commit] creflect default: Start support for 'const'

arigo noreply at buildbot.pypy.org
Mon Sep 15 20:28:13 CEST 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r40:604ad41bc138
Date: 2014-09-15 20:27 +0200
http://bitbucket.org/cffi/creflect/changeset/604ad41bc138/

Log:	Start support for 'const'

diff --git a/creflect/codegen.py b/creflect/codegen.py
--- a/creflect/codegen.py
+++ b/creflect/codegen.py
@@ -145,7 +145,7 @@
         #
         if outerblock.includes:
             extra = ['#include <%s>' % includename
-                     for includename in self.includes]
+                     for includename in outerblock.includes]
             extra.append('')
         else:
             extra = []
diff --git a/creflect/commontypes.py b/creflect/commontypes.py
--- a/creflect/commontypes.py
+++ b/creflect/commontypes.py
@@ -19,7 +19,7 @@
     '_Bool':              'i',
     }
 
-def resolve_common_type(names):
+def resolve_common_type(names, const):
     # reduce synonyms to a single chosen combination
     names = list(names)
     if names != ['signed', 'char']:    # keep this unmodified
@@ -44,8 +44,11 @@
         names = newnames + names
     ident = ' '.join(names)
     if ident == 'void':
-        return model.void_type
+        if const:
+            return model.const_void_type
+        else:
+            return model.void_type
     if ident == '__dotdotdot__':   # XXX
         raise api.FFIError(':%d: bad usage of "..."' %
                 typenode.coord.line)
-    return model.PrimitiveType(ident)
+    return model.PrimitiveType(ident, const)
diff --git a/creflect/cparser.py b/creflect/cparser.py
--- a/creflect/cparser.py
+++ b/creflect/cparser.py
@@ -136,11 +136,9 @@
             realtype = self._get_type(decl.type, name=decl.name)
         self.declarations.append(model.TypeDef(decl.name, realtype))
 
-    def _get_type_pointer(self, type, const=False):
+    def _get_type_pointer(self, type):
         if isinstance(type, model.RawFunctionType):
             return type.as_function_pointer()
-        if const:
-            return model.ConstPointerType(type)
         return model.PointerType(type)
 
     def _get_type(self, typenode, name=None, partial_length_ok=False):
@@ -164,15 +162,14 @@
         #
         if isinstance(typenode, pycparser.c_ast.PtrDecl):
             # pointer type
-            const = (isinstance(typenode.type, pycparser.c_ast.TypeDecl)
-                     and 'const' in typenode.type.quals)
-            return self._get_type_pointer(self._get_type(typenode.type), const)
+            return self._get_type_pointer(self._get_type(typenode.type))
         #
         if isinstance(typenode, pycparser.c_ast.TypeDecl):
+            const = 'const' in typenode.quals
             type = typenode.type
             if isinstance(type, pycparser.c_ast.IdentifierType):
                 # assume a primitive type.
-                return resolve_common_type(type.names)
+                return resolve_common_type(type.names, const)
             #
             if isinstance(type, pycparser.c_ast.Struct):
                 # 'struct foobar'
diff --git a/creflect/model.py b/creflect/model.py
--- a/creflect/model.py
+++ b/creflect/model.py
@@ -11,7 +11,8 @@
         return '<%s>' % (self._get_c_name(),)
 
     def _get_items(self):
-        return [(name, getattr(self, name)) for name in self._attrs_]
+        return [(name, getattr(self, name))
+                for name in (self._attrs_ + 'const')]
 
     def inspect_type(self, block, inspect):
         block.sprintf_add_both_sides(self.c_name_with_marker)
@@ -32,14 +33,20 @@
 
 class VoidType(BaseType):
     _attrs_ = ()
-    c_name_with_marker = 'void &'
+
+    def __init__(self, const):
+        self.const = const
+        self.c_name_with_marker = 'void &'
+        if const:
+            self.c_name_with_marker = 'const ' + self.c_name_with_marker
 
     def inspect_type(self, block, inspect):
         if inspect.started:
             inspect.assign_to_p1('0')
         BaseType.inspect_type(self, block, inspect)
 
-void_type = VoidType()
+void_type = VoidType(const=False)
+const_void_type = VoidType(const=True)
 
 
 class PrimitiveType(BaseType):
@@ -63,10 +70,13 @@
         '_Bool':              'i',
         }
 
-    def __init__(self, name):
+    def __init__(self, name, const):
         assert name in self.ALL_PRIMITIVE_TYPES
         self.name = name
+        self.const = const
         self.c_name_with_marker = name + ' &'
+        if const:
+            self.c_name_with_marker = 'const ' + self.c_name_with_marker
 
     def is_char_type(self):
         return self.ALL_PRIMITIVE_TYPES[self.name] == 'c'
@@ -79,11 +89,18 @@
         star_p1 = inspect.fetch_star_p1()
         comment1 = inspect.get_comment(0, False, "a valid type", minlevel=1)
         comment2 = inspect.get_comment(0, False, "an integer type")
+        comment3 = inspect.get_comment(0, False, "not declared 'const'")
         block.writedecl("char b[sizeof(%s)];%s" % (star_p1, comment1))
         inspect.assign_to_p1("b")
         block.writeline("(void)(%s << 1);%s" % (star_p1, comment2))
+        if self.const:
+            block.sprintf_add_left("const ")
         disjunction = block.flushleft()
-        block.writeline("%s = -1;" % (star_p1,))
+        if self.const:
+            block.add_include("string.h")
+            block.writeline("memset(b, -1, sizeof(b));")
+        else:
+            block.writeline("%s = -1;%s" % (star_p1, comment3))
         block.writeline("if (%s > 0) {" % (star_p1,))
         block.writeline("    if (sizeof(%s) == 1 && %s == 1)" %
                         (star_p1, star_p1))
diff --git a/test/codegen/002c.c b/test/codegen/002c.c
new file mode 100644
--- /dev/null
+++ b/test/codegen/002c.c
@@ -0,0 +1,17 @@
+typedef const void *num_t;
+
+# ____________________________________________________________
+
+int test002c(char *r)
+{
+    if (!r)
+        return 28;
+    {
+        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");
+    }
+    return 0;
+}
diff --git a/test/codegen/003.c b/test/codegen/003.c
--- a/test/codegen/003.c
+++ b/test/codegen/003.c
@@ -12,7 +12,7 @@
         p1 = (void *)b;
         (void)(*p1 << 1);  /* check that 'num_t' is an integer type */
         r += sprintf(r, "typedef ");
-        *p1 = -1;
+        *p1 = -1;  /* check that 'num_t' is not declared 'const' */
         if (*p1 > 0) {
             if (sizeof(*p1) == 1 && *p1 == 1)
                 r += sprintf(r, "_Bool");
diff --git a/test/codegen/003b.c b/test/codegen/003b.c
--- a/test/codegen/003b.c
+++ b/test/codegen/003b.c
@@ -12,7 +12,7 @@
         p1 = (void *)b;
         (void)(*p1 << 1);  /* check that 'num_t' is an integer type */
         r += sprintf(r, "typedef ");
-        *p1 = -1;
+        *p1 = -1;  /* check that 'num_t' is not declared 'const' */
         if (*p1 > 0) {
             if (sizeof(*p1) == 1 && *p1 == 1)
                 r += sprintf(r, "_Bool");
diff --git a/test/codegen/003c.c b/test/codegen/003c.c
--- a/test/codegen/003c.c
+++ b/test/codegen/003c.c
@@ -12,7 +12,7 @@
         p1 = (void *)b;
         (void)(*p1 << 1);  /* check that 'num_t' is an integer type */
         r += sprintf(r, "typedef ");
-        *p1 = -1;
+        *p1 = -1;  /* check that 'num_t' is not declared 'const' */
         if (*p1 > 0) {
             if (sizeof(*p1) == 1 && *p1 == 1)
                 r += sprintf(r, "_Bool");
diff --git a/test/codegen/003d.c b/test/codegen/003d.c
--- a/test/codegen/003d.c
+++ b/test/codegen/003d.c
@@ -12,7 +12,7 @@
         p1 = (void *)b;
         (void)(*p1 << 1);  /* check that 'num_t' is an integer type */
         r += sprintf(r, "typedef ");
-        *p1 = -1;
+        *p1 = -1;  /* check that 'num_t' is not declared 'const' */
         if (*p1 > 0) {
             if (sizeof(*p1) == 1 && *p1 == 1)
                 r += sprintf(r, "_Bool");
diff --git a/test/codegen/003e.c b/test/codegen/003e.c
--- a/test/codegen/003e.c
+++ b/test/codegen/003e.c
@@ -12,7 +12,7 @@
         p1 = (void *)b;
         (void)(*p1 << 1);  /* check that 'num_t' is an integer type */
         r += sprintf(r, "typedef ");
-        *p1 = -1;
+        *p1 = -1;  /* check that 'num_t' is not declared 'const' */
         if (*p1 > 0) {
             if (sizeof(*p1) == 1 && *p1 == 1)
                 r += sprintf(r, "_Bool");
diff --git a/test/codegen/003f.c b/test/codegen/003f.c
--- a/test/codegen/003f.c
+++ b/test/codegen/003f.c
@@ -12,7 +12,7 @@
         p1 = (void *)b;
         (void)(*p1 << 1);  /* check that 'num_t' is an integer type */
         r += sprintf(r, "typedef ");
-        *p1 = -1;
+        *p1 = -1;  /* check that 'num_t' is not declared 'const' */
         if (*p1 > 0) {
             if (sizeof(*p1) == 1 && *p1 == 1)
                 r += sprintf(r, "_Bool");
diff --git a/test/codegen/004.c b/test/codegen/004.c
--- a/test/codegen/004.c
+++ b/test/codegen/004.c
@@ -14,7 +14,7 @@
         *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;
+        **p1 = -1;  /* check that '*num_t' is not declared 'const' */
         if (**p1 > 0) {
             if (sizeof(**p1) == 1 && **p1 == 1)
                 r += sprintf(r, "_Bool");
diff --git a/test/codegen/004b.c b/test/codegen/004b.c
--- a/test/codegen/004b.c
+++ b/test/codegen/004b.c
@@ -16,7 +16,7 @@
         **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;
+        ***p1 = -1;  /* check that '**num_t' is not declared 'const' */
         if (***p1 > 0) {
             if (sizeof(***p1) == 1 && ***p1 == 1)
                 r += sprintf(r, "_Bool");
diff --git a/test/codegen/005.c b/test/codegen/005.c
--- a/test/codegen/005.c
+++ b/test/codegen/005.c
@@ -20,7 +20,7 @@
         }
         (void)(**p1 << 1);  /* check that 'foo_t[]' is an integer type */
         r += sprintf(r, "typedef ");
-        **p1 = -1;
+        **p1 = -1;  /* check that 'foo_t[]' is not declared 'const' */
         if (**p1 > 0) {
             if (sizeof(**p1) == 1 && **p1 == 1)
                 r += sprintf(r, "_Bool");
diff --git a/test/codegen/005b.c b/test/codegen/005b.c
--- a/test/codegen/005b.c
+++ b/test/codegen/005b.c
@@ -22,7 +22,7 @@
         **p1 = (void *)b;    /* check that 'foo_t[]' is a pointer type */
         (void)(***p1 << 1);  /* check that '*foo_t[]' is an integer type */
         r += sprintf(r, "typedef ");
-        ***p1 = -1;
+        ***p1 = -1;  /* check that '*foo_t[]' is not declared 'const' */
         if (***p1 > 0) {
             if (sizeof(***p1) == 1 && ***p1 == 1)
                 r += sprintf(r, "_Bool");
diff --git a/test/codegen/005c.c b/test/codegen/005c.c
--- a/test/codegen/005c.c
+++ b/test/codegen/005c.c
@@ -22,7 +22,7 @@
         }
         (void)(***p1 << 1);  /* check that '(*foo_t)[]' is an integer type */
         r += sprintf(r, "typedef ");
-        ***p1 = -1;
+        ***p1 = -1;  /* check that '(*foo_t)[]' is not declared 'const' */
         if (***p1 > 0) {
             if (sizeof(***p1) == 1 && ***p1 == 1)
                 r += sprintf(r, "_Bool");
diff --git a/test/codegen/005d.c b/test/codegen/005d.c
--- a/test/codegen/005d.c
+++ b/test/codegen/005d.c
@@ -48,7 +48,7 @@
         *********p1 = (void *)b;    /* check that '*(***foo_t[][])[][]' is a pointer type */
         (void)(**********p1 << 1);  /* check that '**(***foo_t[][])[][]' is an integer type */
         r += sprintf(r, "typedef ");
-        **********p1 = -1;
+        **********p1 = -1;  /* check that '**(***foo_t[][])[][]' is not declared 'const' */
         if (**********p1 > 0) {
             if (sizeof(**********p1) == 1 && **********p1 == 1)
                 r += sprintf(r, "_Bool");
diff --git a/test/codegen/005e.c b/test/codegen/005e.c
--- a/test/codegen/005e.c
+++ b/test/codegen/005e.c
@@ -21,7 +21,7 @@
         }
         (void)(**p1 << 1);  /* check that 'foo_t[]' is an integer type */
         r += sprintf(r, "typedef ");
-        **p1 = -1;
+        **p1 = -1;  /* check that 'foo_t[]' is not declared 'const' */
         if (**p1 > 0) {
             if (sizeof(**p1) == 1 && **p1 == 1)
                 r += sprintf(r, "_Bool");
@@ -68,7 +68,7 @@
         }
         (void)(**p1 << 1);  /* check that 'bar_t[]' is an integer type */
         r += sprintf(r, "typedef ");
-        **p1 = -1;
+        **p1 = -1;  /* check that 'bar_t[]' is not declared 'const' */
         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
new file mode 100644
--- /dev/null
+++ b/test/codegen/006.c
@@ -0,0 +1,50 @@
+typedef const unsigned int num_t;
+
+# ____________________________________________________________
+#include <string.h>
+
+int test006(char *r)
+{
+    if (!r)
+        return 14 + 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 const ");
+        memset(b, -1, sizeof(b));
+        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");
+    }
+    return 0;
+}


More information about the pypy-commit mailing list