Author: Armin Rigo <ar...@tunes.org> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit