Author: Armin Rigo <[email protected]>
Branch:
Changeset: r195:9d9333df0699
Date: 2014-12-11 12:09 +0000
http://bitbucket.org/cffi/creflect/changeset/9d9333df0699/
Log: Record which constants were declared as part of an enum
diff --git a/creflect/cparser.py b/creflect/cparser.py
--- a/creflect/cparser.py
+++ b/creflect/cparser.py
@@ -317,11 +317,13 @@
% (tp,))
def add_enum_values_declaration(self, typedecl, values):
+ enumerators = []
for enumerator in values.enumerators:
+ enumerators.append(enumerator.name)
self.declarations.append(
model.ConstDecl(enumerator.name,
model.QualType(model.int_type)))
- typedecl.complete = True
+ typedecl.enumerators = enumerators
def parse_constant(self, constant):
return int(constant.value) # xxx
diff --git a/creflect/creflect.h b/creflect/creflect.h
--- a/creflect/creflect.h
+++ b/creflect/creflect.h
@@ -64,7 +64,8 @@
_crx_type_t *(*get_unknown_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 (*complete_enum)(_CRX_SELF, _crx_type_t *, _crx_type_t *,
+ const char *[], int);
void (*define_type)(_CRX_SELF, const char *, _crx_type_t *, int);
void (*define_var)(_CRX_SELF, const char *, _crx_type_t *, int,
const void *);
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
@@ -200,10 +200,15 @@
}
static void tst_complete_enum(_crx_builder_t *cb, _crx_type_t *t,
- _crx_type_t *inttype)
+ _crx_type_t *inttype,
+ const char *enumvalues[], int nvalues)
{
+ int i;
assert(memcmp(t->text, "ENUM ", 5) == 0);
printf("%s = %s\n", t->text, inttype->text);
+ for (i = 0; i < nvalues; i++) {
+ printf("| %s\n", enumvalues[i]);
+ }
}
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
@@ -741,10 +741,10 @@
def __init__(self, type):
self.type = type
- self.complete = False
+ self.enumerators = None
def write_declaration(self, funcblock):
- if not self.complete or self.type.name is None:
+ if self.enumerators is None or self.type.name is None:
return # opaque
tp = "%s %s" % (self.type.kind, self.type.name)
block = CodeBlock(funcblock)
@@ -767,7 +767,14 @@
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))
+ if len(self.enumerators) == 0:
+ e_var = "0"
+ else:
+ block.writedecl("const char *e[] = { %s };" % (
+ ", ".join(['"%s"' % e for e in self.enumerators]),))
+ e_var = "e"
+ block.writeline('cb->complete_enum(cb, %s, %s, %s, %d);' % (
+ t1, t2, e_var, len(self.enumerators)))
funcblock.write_subblock(block)
diff --git a/creflect/test/codegen/enum-003.c b/creflect/test/codegen/enum-003.c
--- a/creflect/test/codegen/enum-003.c
+++ b/creflect/test/codegen/enum-003.c
@@ -15,9 +15,11 @@
#expect NUMCONST AA = int 0
}
{
+ const char *e[] = { "AA" };
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);
+ cb->complete_enum(cb, t2, t3, e, 1);
#expect ENUM myname_e = unsigned int
+#expect | AA
}
}
diff --git a/creflect/test/codegen/enum-003b.c
b/creflect/test/codegen/enum-003b.c
--- a/creflect/test/codegen/enum-003b.c
+++ b/creflect/test/codegen/enum-003b.c
@@ -20,9 +20,12 @@
#expect NUMCONST BB = int 3
}
{
+ const char *e[] = { "AA", "BB" };
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);
+ cb->complete_enum(cb, t3, t4, e, 2);
#expect ENUM myname_e = unsigned int
+#expect | AA
+#expect | BB
}
}
diff --git a/creflect/test/codegen/enum-003c.c
b/creflect/test/codegen/enum-003c.c
--- a/creflect/test/codegen/enum-003c.c
+++ b/creflect/test/codegen/enum-003c.c
@@ -13,9 +13,11 @@
#expect NUMCONST AA = int -3
}
{
+ const char *e[] = { "AA" };
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);
+ cb->complete_enum(cb, t2, t3, e, 1);
#expect ENUM myname_e = int
+#expect | AA
}
}
diff --git a/creflect/test/codegen/enum-004.c b/creflect/test/codegen/enum-004.c
--- a/creflect/test/codegen/enum-004.c
+++ b/creflect/test/codegen/enum-004.c
@@ -15,12 +15,14 @@
{
foo_t p1;
char b[sizeof(*p1)];
+ const char *e[] = { "AA" };
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);
+ cb->complete_enum(cb, t2, t3, e, 1);
#expect ENUM $$foo_t = unsigned int
+#expect | AA
}
{
foo_t *p1;
diff --git a/zeffir/builder.c b/zeffir/builder.c
--- a/zeffir/builder.c
+++ b/zeffir/builder.c
@@ -410,8 +410,8 @@
return _zef_array_type(cb, ctitem, (size_t)-1, NULL);
}
-static _crx_type_t *_zef_struct_or_union(_crx_builder_t *cb, const char *name,
- int flag, const char *prefix_name)
+static _crx_type_t *_zef_struct_union_enum(_crx_builder_t *cb, const char
*name,
+ int flag, const char *prefix_name)
{
if (PyErr_Occurred())
return NULL;
@@ -448,17 +448,17 @@
static _crx_type_t *zef_get_struct_type(_crx_builder_t *cb, const char *name)
{
- return _zef_struct_or_union(cb, name, CT_STRUCT, "struct ");
+ return _zef_struct_union_enum(cb, name, CT_STRUCT, "struct ");
}
static _crx_type_t *zef_get_union_type(_crx_builder_t *cb, const char *name)
{
- return _zef_struct_or_union(cb, name, CT_UNION, "union ");
+ return _zef_struct_union_enum(cb, name, CT_UNION, "union ");
}
static _crx_type_t *zef_get_enum_type(_crx_builder_t *cb, const char *name)
{
- abort();
+ return _zef_struct_union_enum(cb, name, CT_UNKNOWN | CT_IS_ENUM, "enum ");
}
static _crx_qual_type zef_get_user_type(_crx_builder_t *cb, const char *name)
@@ -738,10 +738,22 @@
Py_DECREF(interned_fields);
}
-static void zef_complete_enum(_crx_builder_t *cb, _crx_type_t *t,
- _crx_type_t *inttype)
+static void zef_complete_enum(_crx_builder_t *cb, _crx_type_t *ct,
+ _crx_type_t *inttype,
+ const char *enumvalues[], int nvalues)
{
- abort();
+ assert(inttype->ct_flags & (CT_PRIMITIVE_SIGNED | CT_PRIMITIVE_UNSIGNED));
+ assert(ct->ct_flags & CT_IS_ENUM);
+ if (ct->ct_size >= 0) {
+ PyErr_Format(ZefError, "duplicate declaration of the enum '%s'",
+ ct->ct_name);
+ return;
+ }
+
+ //...
+
+ ct->ct_flags = inttype->ct_flags | CT_IS_ENUM;
+ ct->ct_size = inttype->ct_size;
}
static void zef_define_type(_crx_builder_t *cb, const char *name,
diff --git a/zeffir/test/enum.crx b/zeffir/test/enum.crx
new file mode 100644
--- /dev/null
+++ b/zeffir/test/enum.crx
@@ -0,0 +1,8 @@
+enum foo_e { AA, BB, CC };
+
+
+// CREFLECT: start
+
+enum foo_e { AA, CC };
+
+// CREFLECT: end
diff --git a/zeffir/test/test_enum.py b/zeffir/test/test_enum.py
new file mode 100644
--- /dev/null
+++ b/zeffir/test/test_enum.py
@@ -0,0 +1,10 @@
+import py
+import support
+
+
+def test_simple_enum():
+ ffi, lib = support.compile_and_open('enum')
+ assert lib.AA == 0
+ assert lib.CC == 2
+ n = int(ffi.cast('enum foo_e', -5))
+ assert n == 2 ** 32 - 5 # unsigned
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit