[pypy-commit] creflect default: enums
arigo
noreply at buildbot.pypy.org
Sat Dec 6 21:40:21 CET 2014
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r192:d43293d10be7
Date: 2014-12-06 21:40 +0100
http://bitbucket.org/cffi/creflect/changeset/d43293d10be7/
Log: enums
diff --git a/creflect/cparser.py b/creflect/cparser.py
--- a/creflect/cparser.py
+++ b/creflect/cparser.py
@@ -256,7 +256,7 @@
def get_struct_union_enum_type(self, kind, type, approx_name=None):
name = type.name or approx_name
- if not name or name.startswith('$$$'):
+ if kind != 'enum' and (not name or name.startswith('$$$')):
self.parse_error("not implemented: anonymous 'struct' elsewhere "
"than in 'typedef struct { ... } typename;' or "
"'typedef struct { ... } *typename;'", type)
@@ -270,7 +270,7 @@
if kind == 'struct' or kind == 'union':
typedecl = model.StructOrUnionDecl(result)
elif kind == 'enum':
- typedecl = XXX
+ typedecl = model.EnumDecl(result)
else:
raise AssertionError("kind = %r" % (kind,))
self.struct_union_enum_decl[key] = typedecl
@@ -280,8 +280,12 @@
#
# is there a 'type.decls'? If yes, then this is the place in the
# C sources that declare the fields.
- if type.decls is not None:
- self.add_fields_declaration(typedecl, type.decls)
+ if kind == 'struct' or kind == 'union':
+ if type.decls is not None:
+ self.add_fields_declaration(typedecl, type.decls)
+ if kind == 'enum':
+ if type.values is not None:
+ self.add_enum_values_declaration(typedecl, type.values)
if must_add:
self.declarations.append(typedecl)
return result
@@ -312,6 +316,13 @@
raise NotImplementedError("%s: using both bitfields and '...;'"
% (tp,))
+ def add_enum_values_declaration(self, typedecl, values):
+ for enumerator in values.enumerators:
+ self.declarations.append(
+ model.ConstDecl(enumerator.name,
+ model.QualType(model.int_type)))
+ typedecl.complete = True
+
def parse_constant(self, constant):
return int(constant.value) # xxx
diff --git a/creflect/creflect_debug_print.c b/creflect/creflect_debug_print.c
--- a/creflect/creflect_debug_print.c
+++ b/creflect/creflect_debug_print.c
@@ -202,7 +202,8 @@
static void tst_complete_enum(_crx_builder_t *cb, _crx_type_t *t,
_crx_type_t *inttype)
{
- abort();
+ assert(memcmp(t->text, "ENUM ", 5) == 0);
+ printf("%s = %s\n", t->text, inttype->text);
}
static void tst_define_type(_crx_builder_t *cb, const char *name,
diff --git a/creflect/model.py b/creflect/model.py
--- a/creflect/model.py
+++ b/creflect/model.py
@@ -249,6 +249,8 @@
block.writeline('cb->define_num_const(cb, "%s", %s, &v);' % (
varname, t1))
+int_type = PrimitiveType('int')
+
class FunctionType(BaseType):
_attrs_ = ('args', 'result', 'ellipsis')
@@ -730,6 +732,40 @@
funcblock.writeline(' %s, %d);' % (d1, len(self.fldnames)))
+class EnumDecl(object):
+
+ def __init__(self, type):
+ self.type = type
+ self.complete = False
+
+ def write_declaration(self, funcblock):
+ if not self.complete or self.type.name is None:
+ return # opaque
+ tp = "%s %s" % (self.type.kind, self.type.name)
+ block = CodeBlock(funcblock)
+ if not self.type.name.startswith('$'):
+ realtp = tp
+ else:
+ realtp = self.type.name[1:]
+ if not realtp.startswith('$'):
+ expr = '(%s)-1' % realtp
+ else:
+ # xxx obscure case: "typedef enum e *t;"
+ ptrtp = realtp[1:]
+ assert not ptrtp.startswith('$')
+ block.writedecl("%s p1;" % (ptrtp,))
+ block.writedecl("char b[sizeof(*p1)];")
+ block.writeline("memset(b, -1, sizeof(b));")
+ block.writeline("p1 = (%s)b;" % (ptrtp,))
+ expr = '*p1'
+ #
+ t1 = self.type.get_type_var(block)
+ t2 = block.write_crx_type_var('_CRX_INT_TYPE(cb, %s, _crx_sc_int)' %
+ (expr,))
+ block.writeline('cb->complete_enum(cb, %s, %s);' % (t1, t2))
+ funcblock.write_subblock(block)
+
+
class TypeDefDecl(object):
def __init__(self, name, qualtype):
self.name = name
diff --git a/creflect/test/codegen/enum-001.c b/creflect/test/codegen/enum-001.c
new file mode 100644
--- /dev/null
+++ b/creflect/test/codegen/enum-001.c
@@ -0,0 +1,13 @@
+typedef enum myname_e foo_t; // unusual, but valid C
+
+# ____________________________________________________________
+
+void testenum_001(_crx_builder_t *cb)
+{
+ _crx_type_t *t1;
+ {
+ t1 = cb->get_enum_type(cb, "myname_e");
+ cb->define_type(cb, "foo_t", t1, 0);
+#expect TYPEDEF foo_t = ENUM myname_e
+ }
+}
diff --git a/creflect/test/codegen/enum-002.c b/creflect/test/codegen/enum-002.c
new file mode 100644
--- /dev/null
+++ b/creflect/test/codegen/enum-002.c
@@ -0,0 +1,22 @@
+enum { AA, BB }; /* anonymous */
+
+# ____________________________________________________________
+
+void testenum_002(_crx_builder_t *cb)
+{
+ _crx_type_t *t1, *t2;
+ {
+ _crx_num_const_t v;
+ (void)((AA) << 1); /* check that 'AA' is an integer */
+ t1 = _CRX_INT_CONST(cb, AA, &v, 1);
+ cb->define_num_const(cb, "AA", t1, &v);
+#expect NUMCONST AA = int 0
+ }
+ {
+ _crx_num_const_t v;
+ (void)((BB) << 1); /* check that 'BB' is an integer */
+ t2 = _CRX_INT_CONST(cb, BB, &v, 1);
+ cb->define_num_const(cb, "BB", t2, &v);
+#expect NUMCONST BB = int 1
+ }
+}
diff --git a/creflect/test/codegen/enum-002b.c b/creflect/test/codegen/enum-002b.c
new file mode 100644
--- /dev/null
+++ b/creflect/test/codegen/enum-002b.c
@@ -0,0 +1,28 @@
+
+enum { AA=(10+10), BB=-4 };
+
+# ____________________________________________________________
+
+#define AA 100
+#define BB 200
+
+# ____________________________________________________________
+
+void testenum_002b(_crx_builder_t *cb)
+{
+ _crx_type_t *t1, *t2;
+ {
+ _crx_num_const_t v;
+ (void)((AA) << 1); /* check that 'AA' is an integer */
+ t1 = _CRX_INT_CONST(cb, AA, &v, 1);
+ cb->define_num_const(cb, "AA", t1, &v);
+#expect NUMCONST AA = int 100
+ }
+ {
+ _crx_num_const_t v;
+ (void)((BB) << 1); /* check that 'BB' is an integer */
+ t2 = _CRX_INT_CONST(cb, BB, &v, 1);
+ cb->define_num_const(cb, "BB", t2, &v);
+#expect NUMCONST BB = int 200
+ }
+}
diff --git a/creflect/test/codegen/enum-003.c b/creflect/test/codegen/enum-003.c
new file mode 100644
--- /dev/null
+++ b/creflect/test/codegen/enum-003.c
@@ -0,0 +1,23 @@
+enum myname_e { AA };
+/* note that with GCC, "enum myname_e" is equivalent to "unsigned int",
+ but AA itself is a constant of type "int", obscurely */
+
+# ____________________________________________________________
+
+void testenum_003(_crx_builder_t *cb)
+{
+ _crx_type_t *t1, *t2, *t3;
+ {
+ _crx_num_const_t v;
+ (void)((AA) << 1); /* check that 'AA' is an integer */
+ t1 = _CRX_INT_CONST(cb, AA, &v, 1);
+ cb->define_num_const(cb, "AA", t1, &v);
+#expect NUMCONST AA = int 0
+ }
+ {
+ t2 = cb->get_enum_type(cb, "myname_e");
+ t3 = _CRX_INT_TYPE(cb, (enum myname_e)-1, _crx_sc_int);
+ cb->complete_enum(cb, t2, t3);
+#expect ENUM myname_e = unsigned int
+ }
+}
diff --git a/creflect/test/codegen/enum-003b.c b/creflect/test/codegen/enum-003b.c
new file mode 100644
--- /dev/null
+++ b/creflect/test/codegen/enum-003b.c
@@ -0,0 +1,28 @@
+enum myname_e { AA=0x80000000U, BB=3U };
+
+# ____________________________________________________________
+
+void testenum_003b(_crx_builder_t *cb)
+{
+ _crx_type_t *t1, *t2, *t3, *t4;
+ {
+ _crx_num_const_t v;
+ (void)((AA) << 1); /* check that 'AA' is an integer */
+ t1 = _CRX_INT_CONST(cb, AA, &v, 1);
+ cb->define_num_const(cb, "AA", t1, &v);
+#expect NUMCONST AA = unsigned int 2147483648
+ }
+ {
+ _crx_num_const_t v;
+ (void)((BB) << 1); /* check that 'BB' is an integer */
+ t2 = _CRX_INT_CONST(cb, BB, &v, 1);
+ cb->define_num_const(cb, "BB", t2, &v);
+#expect NUMCONST BB = int 3
+ }
+ {
+ t3 = cb->get_enum_type(cb, "myname_e");
+ t4 = _CRX_INT_TYPE(cb, (enum myname_e)-1, _crx_sc_int);
+ cb->complete_enum(cb, t3, t4);
+#expect ENUM myname_e = unsigned int
+ }
+}
diff --git a/creflect/test/codegen/enum-003c.c b/creflect/test/codegen/enum-003c.c
new file mode 100644
--- /dev/null
+++ b/creflect/test/codegen/enum-003c.c
@@ -0,0 +1,21 @@
+enum myname_e { AA=-3L };
+
+# ____________________________________________________________
+
+void testenum_003c(_crx_builder_t *cb)
+{
+ _crx_type_t *t1, *t2, *t3;
+ {
+ _crx_num_const_t v;
+ (void)((AA) << 1); /* check that 'AA' is an integer */
+ t1 = _CRX_INT_CONST(cb, AA, &v, 1);
+ cb->define_num_const(cb, "AA", t1, &v);
+#expect NUMCONST AA = int -3
+ }
+ {
+ t2 = cb->get_enum_type(cb, "myname_e");
+ t3 = _CRX_INT_TYPE(cb, (enum myname_e)-1, _crx_sc_int);
+ cb->complete_enum(cb, t2, t3);
+#expect ENUM myname_e = int
+ }
+}
diff --git a/creflect/test/codegen/enum-004.c b/creflect/test/codegen/enum-004.c
new file mode 100644
--- /dev/null
+++ b/creflect/test/codegen/enum-004.c
@@ -0,0 +1,34 @@
+typedef enum { AA } *foo_t;
+
+# ____________________________________________________________
+
+void testenum_004(_crx_builder_t *cb)
+{
+ _crx_type_t *t1, *t2, *t3, *t4;
+ {
+ _crx_num_const_t v;
+ (void)((AA) << 1); /* check that 'AA' is an integer */
+ t1 = _CRX_INT_CONST(cb, AA, &v, 1);
+ cb->define_num_const(cb, "AA", t1, &v);
+#expect NUMCONST AA = int 0
+ }
+ {
+ foo_t p1;
+ char b[sizeof(*p1)];
+ memset(b, -1, sizeof(b));
+ p1 = (foo_t)b;
+ t2 = cb->get_enum_type(cb, "$$foo_t");
+ t3 = _CRX_INT_TYPE(cb, *p1, _crx_sc_int);
+ cb->complete_enum(cb, t2, t3);
+#expect ENUM $$foo_t = unsigned int
+ }
+ {
+ foo_t *p1;
+ char *p2;
+ p1 = (void *)&p2;
+ *p1 = (void *)0; /* check that 'foo_t' is a pointer type */
+ t4 = cb->get_pointer_type(cb, t2, 0);
+ cb->define_type(cb, "foo_t", t4, 0);
+#expect TYPEDEF foo_t = PTR ENUM $$foo_t
+ }
+}
More information about the pypy-commit
mailing list