Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r98:76b1612c5824
Date: 2014-11-27 17:46 +0100
http://bitbucket.org/cffi/creflect/changeset/76b1612c5824/

Log:    Use of a typedef'ed name: first in globals

diff --git a/creflect/commontypes.py b/creflect/commontypes.py
--- a/creflect/commontypes.py
+++ b/creflect/commontypes.py
@@ -48,7 +48,4 @@
             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, const)
diff --git a/creflect/cparser.py b/creflect/cparser.py
--- a/creflect/cparser.py
+++ b/creflect/cparser.py
@@ -28,7 +28,7 @@
 r_comment1 = re.compile(r"//.*")
 r_comment2 = re.compile(r"/[*]")
 r_comment3 = re.compile(r"[*]/")
-r_empty_braces = re.compile(r"{.*}")     # after comments have been removed
+r_empty_braces = re.compile(r"{\s*}")     # after comments have been removed
 
 def remove_comments(csource):
     csource = r_comment1.sub('', csource)     # remove the '//' comments
@@ -83,6 +83,7 @@
 
     def get_declarations(self):
         self.declarations = []
+        self.typedefs = {}
         ast = self.to_ast()
         for decl in ast.ext:
             if isinstance(decl, pycparser.c_ast.Decl):
@@ -138,6 +139,9 @@
             realtype = model.unknown_ptr_type(decl.name)
         else:
             realtype = self._get_type(decl.type, approx_name = '$' + decl.name)
+        if decl.name in self.typedefs:
+            self._parse_error("duplicate typedef declaring %r" % (decl.name,))
+        self.typedefs[decl.name] = model.UserType(decl.name, realtype)
         self.declarations.append(model.TypeDefDecl(decl.name, realtype))
 
     def _get_type(self, typenode, approx_name=None, partial_length_ok=False):
@@ -145,10 +149,8 @@
         if (isinstance(typenode, pycparser.c_ast.TypeDecl) and
             isinstance(typenode.type, pycparser.c_ast.IdentifierType) and
             len(typenode.type.names) == 1 and
-            0): #('typedef ' + typenode.type.names[0]) in self._declarations):
-            #XXX
-            type = self._declarations['typedef ' + typenode.type.names[0]]
-            return type
+            typenode.type.names[0] in self.typedefs):
+            return self.typedefs[typenode.type.names[0]]
         #
         if isinstance(typenode, pycparser.c_ast.ArrayDecl):
             # array type
diff --git a/creflect/model.py b/creflect/model.py
--- a/creflect/model.py
+++ b/creflect/model.py
@@ -76,7 +76,7 @@
         }
 
     def __init__(self, name, const):
-        assert name in self.ALL_PRIMITIVE_TYPES
+        assert name in self.ALL_PRIMITIVE_TYPES, repr(name)
         self.name = name
         self.const = const
         self.c_name_with_marker = name + ' &'
@@ -453,6 +453,29 @@
         return self.get_type_var(block)
 
 
+class UserType(BaseType):
+    _attrs_ = ('name', 'realtype')
+
+    def __init__(self, name, realtype, const=False):
+        self.name = name
+        self.realtype = realtype
+        self.const = const or realtype.const
+        self.c_name_with_marker = name + ' &'
+        if const:
+            self.c_name_with_marker = 'const ' + self.c_name_with_marker
+
+    def inspect_nonconst_type(self, block, inspect):
+        inspect.flush()
+        if isinstance(inspect, VarInspector):
+            decl = self.get_c_name("*p1")
+            block.writeline("%s = &%s;  /* check that '%s' is of type '%s'"
+                            " */" % (decl, inspect.varname,
+                                     inspect.varname, self.get_c_name()))
+            block.writeline("(void)p1;")
+        return block.write_crx_type_var('cb->get_user_type(cb, "%s")' % (
+            self.name,))
+
+
 # ____________________________________________________________
 
 
diff --git a/creflect/src/creflect.h b/creflect/src/creflect.h
--- a/creflect/src/creflect.h
+++ b/creflect/src/creflect.h
@@ -51,6 +51,7 @@
     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 *);
+    crx_type_t *(*get_user_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 *);
diff --git a/creflect/src/creflect_print.h b/creflect/src/creflect_print.h
--- a/creflect/src/creflect_print.h
+++ b/creflect/src/creflect_print.h
@@ -162,6 +162,11 @@
     return newtype2("ENUM ", name);
 }
 
+static crx_type_t *tst_get_user_type(crx_builder_t *cb, const char *name)
+{
+    return newtype(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)
@@ -252,6 +257,7 @@
     tst_get_struct_type,
     tst_get_union_type,
     tst_get_enum_type,
+    tst_get_user_type,
     tst_complete,
     tst_complete_enum,
     tst_define_type,
diff --git a/test/codegen/glob-005.c b/test/codegen/glob-005.c
new file mode 100644
--- /dev/null
+++ b/test/codegen/glob-005.c
@@ -0,0 +1,27 @@
+typedef void *mytype_t;
+
+mytype_t foobar;
+
+# ____________________________________________________________
+
+void testglob_005(crx_builder_t *cb)
+{
+    crx_type_t *t1, *t2, *t3;
+    {
+        mytype_t *p1;
+        char *p2;
+        p1 = (void *)&p2;
+        *p1 = (void *)0;    /* check that 'mytype_t' is a pointer type */
+        t1 = cb->get_void_type(cb);
+        t2 = cb->get_pointer_type(cb, t1);
+        cb->define_type(cb, "mytype_t", t2);
+#expect TYPEDEF mytype_t = PTR void
+    }
+    {
+        mytype_t *p1 = &foobar;  /* check that 'foobar' is of type 'mytype_t' 
*/
+        (void)p1;
+        t3 = cb->get_user_type(cb, "mytype_t");
+        cb->define_var(cb, "foobar", t3, &foobar);
+#expect VAR foobar: mytype_t
+    }
+}
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to