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