[pypy-commit] creflect default: in-progress: refactoring: like C, we distinguish now "type qualifiers"
arigo
noreply at buildbot.pypy.org
Sun Nov 30 22:29:41 CET 2014
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r129:7673f248edbc
Date: 2014-11-30 22:29 +0100
http://bitbucket.org/cffi/creflect/changeset/7673f248edbc/
Log: in-progress: refactoring: like C, we distinguish now "type
qualifiers" as something different from types
diff --git a/creflect/codegen.py b/creflect/codegen.py
--- a/creflect/codegen.py
+++ b/creflect/codegen.py
@@ -7,11 +7,13 @@
if parent is None:
self.crx_type_vars = []
self.crx_type_cache = {}
+ self.crx_qualtype_vars = []
self.crx_field_vars = []
self.crx_top_level = self
else:
self.crx_type_vars = parent.crx_type_vars
self.crx_type_cache = parent.crx_type_cache
+ self.crx_qualtype_vars = parent.crx_qualtype_vars
self.crx_field_vars = parent.crx_field_vars
self.crx_top_level = parent.crx_top_level
@@ -40,13 +42,12 @@
self.writeline('%s = %s;' % (t1, expr))
return t1
- def add_array_crx_types(self, array_size):
- if array_size > 0:
- a1 = self._get_next_name('a')
- self.crx_type_vars.append('*%s[%d]' % (a1, array_size))
- return a1
- else:
+ def write_crx_qualtype_var(self, array_size):
+ if array_size == 0:
return '0'
+ a1 = 'a%d' % (len(self.crx_qualtype_vars) + 1)
+ self.crx_qualtype_vars.append('%s[%d]' % (a1, array_size))
+ return a1
def write_crx_field_var(self, nfields):
d1 = 'd%d' % (len(self.crx_field_vars) + 1)
@@ -67,6 +68,8 @@
if funcblock.crx_type_vars:
funcblock.writedecl("_crx_type_t %s;" % (
', '.join(funcblock.crx_type_vars),))
+ for a1 in funcblock.crx_qualtype_vars:
+ funcblock.writedecl("_crx_qual_type %s;" % a1)
for d1 in funcblock.crx_field_vars:
funcblock.writedecl("_crx_field_t %s;" % d1)
diff --git a/creflect/commontypes.py b/creflect/commontypes.py
--- a/creflect/commontypes.py
+++ b/creflect/commontypes.py
@@ -19,7 +19,7 @@
'_Bool': 'i',
}
-def resolve_common_type(names, const):
+def resolve_common_type(names):
# reduce synonyms to a single chosen combination
names = list(names)
if names != ['signed', 'char']: # keep this unmodified
@@ -44,8 +44,5 @@
names = newnames + names
ident = ' '.join(names)
if ident == 'void':
- if const:
- return model.const_void_type
- else:
- return model.void_type
- return model.PrimitiveType(ident, const)
+ return model.void_type
+ return model.PrimitiveType(ident)
diff --git a/creflect/cparser.py b/creflect/cparser.py
--- a/creflect/cparser.py
+++ b/creflect/cparser.py
@@ -68,7 +68,7 @@
def __init__(self, cdefblock, first_lineno=1):
self.cdefblock = cdefblock
self.first_lineno = first_lineno
- self._struct_union_enum_decl = {}
+ self.struct_union_enum_decl = {}
def prepare_source(self):
csource = remove_comments(self.cdefblock)
@@ -104,130 +104,125 @@
assert ast.ext[0].name == '__crx_unknown_t'
for decl in ast.ext[1:]:
if isinstance(decl, pycparser.c_ast.Decl):
- self._parse_decl(decl)
+ self.parse_decl(decl)
elif isinstance(decl, pycparser.c_ast.Typedef):
- self._parse_typedef(decl)
+ self.parse_typedef(decl)
else:
- self._parse_error("unrecognized construct", decl)
+ self.parse_error("unrecognized construct", decl)
return self.declarations
- def _parse_error(self, msg, decl):
+ def parse_error(self, msg, decl):
raise CDefError(msg, self, decl.coord.line - 1)
- def _parse_decl(self, decl):
+ def parse_decl(self, decl):
node = decl.type
if isinstance(node, pycparser.c_ast.FuncDecl):
- tp = self._get_type(node)
- assert isinstance(tp, model.FunctionType)
- self.declarations.append(model.FuncDecl(decl.name, tp))
+ qualtp = self.get_qualtype(node)
+ assert isinstance(qualtp.type, model.FunctionType)
+ self.declarations.append(model.FuncDecl(decl.name, qualtp))
else:
const = 'const' in decl.quals
if isinstance(node, pycparser.c_ast.Struct):
if node.decls is not None:
- self._get_struct_union_enum_type('struct', node, const)
+ self.get_struct_union_enum_type('struct', node, const)
elif isinstance(node, pycparser.c_ast.Union):
if node.decls is not None:
- self._get_struct_union_enum_type('union', node, const)
+ self.get_struct_union_enum_type('union', node, const)
elif isinstance(node, pycparser.c_ast.Enum):
if node.values is not None:
- self._get_struct_union_enum_type('enum', node, const)
+ self.get_struct_union_enum_type('enum', node, const)
elif not decl.name:
raise api.CDefError("construct does not declare any variable",
decl)
#
if decl.name:
- tp = self._get_type(node, partial_length_ok=True)
- if self._is_constant_globalvar(node):
- self.declarations.append(model.ConstDecl(decl.name, tp))
+ qualtp = self.get_qualtype(node)
+ if self.is_constant_globalvar(node):
+ self.declarations.append(model.ConstDecl(decl.name, qualtp))
else:
- self.declarations.append(model.VarDecl(decl.name, tp))
+ self.declarations.append(model.VarDecl(decl.name, qualtp))
- def _parse_typedef(self, decl):
+ def parse_typedef(self, decl):
if not decl.name:
- self._parse_error("typedef does not declare any name", decl)
- if (isinstance(decl.type.type, pycparser.c_ast.IdentifierType)
- and decl.type.type.names == ['__dotdotdot__']):
- realtype = model.unknown_type(decl.name)
- elif (isinstance(decl.type, pycparser.c_ast.PtrDecl) and
- isinstance(decl.type.type, pycparser.c_ast.TypeDecl) and
- isinstance(decl.type.type.type,
- pycparser.c_ast.IdentifierType) and
- decl.type.type.type.names == ['__dotdotdot__']):
- realtype = model.unknown_ptr_type(decl.name)
- else:
- realtype = self._get_type(decl.type, approx_name = '$' + decl.name)
+ self.parse_error("typedef does not declare any name", decl)
+ qualtype = self.get_qualtype(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))
+ self.parse_error("duplicate typedef declaring %r" % (decl.name,))
+ self.typedefs[decl.name] = model.UserType(decl.name)
+ self.declarations.append(model.TypeDefDecl(decl.name, qualtype))
- def _get_type(self, typenode, approx_name=None, partial_length_ok=False):
+ def get_qualtype(self, typenode, approx_name=None):
# first, dereference typedefs, if we have it already parsed, we're good
if (isinstance(typenode, pycparser.c_ast.TypeDecl) and
isinstance(typenode.type, pycparser.c_ast.IdentifierType) and
len(typenode.type.names) == 1):
typename = typenode.type.names[0]
if typename in self.typedefs:
- return self.typedefs[typenode.type.names[0]]
+ return model.QualType(self.typedefs[typenode.type.names[0]],
+ quals_num(typenode.quals))
if typename == '__crx_unknown_t':
assert approx_name, "XXX"
- return model.UnknownType(approx_name)
+ return model.QualType(model.UnknownType(approx_name),
+ quals_num(typenode.quals))
#
if isinstance(typenode, pycparser.c_ast.ArrayDecl):
# array type
if typenode.dim is None:
length = None
else:
- length = self._parse_constant(
- typenode.dim, partial_length_ok=partial_length_ok)
- return model.ArrayType(self._get_type(typenode.type), length)
+ length = self.parse_constant(typenode.dim)
+ qualtype = self.get_qualtype(typenode.type)
+ return model.QualType(model.ArrayType(qualtype.type, length),
+ qualtype.quals)
#
if isinstance(typenode, pycparser.c_ast.PtrDecl):
# pointer type
- const = 'const' in typenode.quals
if approx_name:
approx_name = '$' + approx_name
- realtype = self._get_type(typenode.type, approx_name)
- return model.PointerType(realtype, const)
+ qualtype = self.get_qualtype(typenode.type, approx_name)
+ return model.QualType(model.PointerType(qualtype),
+ quals_num(typenode.quals))
#
if isinstance(typenode, pycparser.c_ast.TypeDecl):
const = 'const' in typenode.quals
type = typenode.type
if isinstance(type, pycparser.c_ast.IdentifierType):
# assume a primitive type.
- return resolve_common_type(type.names, const)
+ realtype = resolve_common_type(type.names)
+ return model.QualType(realtype, quals_num(typenode.quals))
#
if isinstance(type, pycparser.c_ast.Struct):
# 'struct foobar'
- return self._get_struct_union_enum_type('struct', type, const,
- approx_name)
+ return self.get_struct_union_enum_type('struct', type, const,
+ approx_name)
#
if isinstance(type, pycparser.c_ast.Union):
# 'union foobar'
- return self._get_struct_union_enum_type('union', type, const,
- approx_name)
+ return self.get_struct_union_enum_type('union', type, const,
+ approx_name)
#
if isinstance(type, pycparser.c_ast.Enum):
# 'enum foobar'
- return self._get_struct_union_enum_type('enum', type, const,
- approx_name)
+ return self.get_struct_union_enum_type('enum', type, const,
+ approx_name)
#
if isinstance(typenode, pycparser.c_ast.FuncDecl):
- # a function type
- return self._parse_function_type(typenode, approx_name)
+ # a function type (it is never qualified)
+ return model.QualType(
+ self.parse_function_type(typenode, approx_name), 0)
#
# nested anonymous structs or unions end up here
if isinstance(typenode, pycparser.c_ast.Struct):
- return self._get_struct_union_enum_type('struct', typenode, const,
- name, nested=True)
+ return self.get_struct_union_enum_type('struct', typenode, const,
+ name, nested=True)
if isinstance(typenode, pycparser.c_ast.Union):
- return self._get_struct_union_enum_type('union', typenode, const,
- name, nested=True)
+ return self.get_struct_union_enum_type('union', typenode, const,
+ name, nested=True)
#
raise api.FFIError(":%d: bad or unsupported type declaration" %
typenode.coord.line)
- def _parse_function_type(self, typenode, funcname=None):
+ def parse_function_type(self, typenode, funcname=None):
params = list(getattr(typenode.args, 'params', []))
ellipsis = (
len(params) > 0 and
@@ -243,37 +238,32 @@
isinstance(params[0].type.type, pycparser.c_ast.IdentifierType)
and list(params[0].type.type.names) == ['void']):
del params[0]
- args = [self._as_func_arg(self._get_type(argdeclnode.type))
- for argdeclnode in params]
- result = self._get_type(typenode.type)
- return model.FunctionType(tuple(args), result, ellipsis)
+ #
+ args_quals = [self.get_qualtype(argdeclnode.type)
+ for argdeclnode in params]
+ # ignore the quals of the result type (GCC produces a warning with
+ # -Wignored-qualifiers, but it is not even included in -Wall)
+ qual_result = self.get_qualtype(typenode.type)
+ return model.FunctionType(tuple(args_quals), qual_result.type, ellipsis)
- def _as_func_arg(self, type):
- if isinstance(type, model.ArrayType):
- return model.PointerType(type.item, const=False)
- elif isinstance(type, model.FunctionType):
- return model.PointerType(type, const=False)
- else:
- return type
-
- def _is_constant_globalvar(self, typenode):
+ def is_constant_globalvar(self, typenode):
if isinstance(typenode, pycparser.c_ast.PtrDecl):
return 'const' in typenode.quals
if isinstance(typenode, pycparser.c_ast.TypeDecl):
return 'const' in typenode.quals
return False
- def _get_struct_union_enum_type(self, kind, type, const, approx_name=None):
+ def get_struct_union_enum_type(self, kind, type, const, approx_name=None):
name = type.name or approx_name
if not name or name.startswith('$$$'):
- self._parse_error("not implemented: anonymous 'struct' elsewhere "
- "than in 'typedef struct { ... } typename;' or "
- "'typedef struct { ... } *typename;'", type)
+ self.parse_error("not implemented: anonymous 'struct' elsewhere "
+ "than in 'typedef struct { ... } typename;' or "
+ "'typedef struct { ... } *typename;'", type)
result = model.StructOrUnionOrEnum(kind, name, const)
#
# get the type declaration or create it if needed
key = '%s %s' % (kind, name)
- typedecl = self._struct_union_enum_decl.get(key, None)
+ typedecl = self.struct_union_enum_decl.get(key, None)
#
if typedecl is None:
if kind == 'struct' or kind == 'union':
@@ -282,7 +272,7 @@
typedecl = XXX
else:
raise AssertionError("kind = %r" % (kind,))
- self._struct_union_enum_decl[key] = typedecl
+ self.struct_union_enum_decl[key] = typedecl
must_add = True
else:
must_add = False
@@ -290,12 +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)
+ self.add_fields_declaration(typedecl, type.decls)
if must_add:
self.declarations.append(typedecl)
return result
- def _add_fields_declaration(self, typedecl, fields):
+ def add_fields_declaration(self, typedecl, fields):
if typedecl.fldnames is not None:
raise api.CDefError("duplicate declaration of struct %s" % name)
fldnames = []
@@ -307,13 +297,13 @@
if decl.bitsize is None:
bitsize = -1
else:
- bitsize = self._parse_constant(decl.bitsize)
- self._partial_length = False
- type = self._get_type(decl.type, partial_length_ok=True)
- if self._partial_length:
- self._make_partial(tp, nested)
+ bitsize = self.parse_constant(decl.bitsize)
+ self.partial_length = False
+ type = self.get_type(decl.type)
+ if self.partial_length:
+ self.make_partial(tp, nested)
#if isinstance(type, model.StructType) and type.partial:
- # self._make_partial(tp, nested)
+ # self.make_partial(tp, nested)
fldnames.append(decl.name or '')
fldtypes.append(type)
fldbitsize.append(bitsize)
@@ -326,5 +316,18 @@
raise NotImplementedError("%s: using both bitfields and '...;'"
% (tp,))
- def _parse_constant(self, *args, **kwds):
- return None # XXX
+ def parse_constant(self, constant):
+ return int(constant.value) # xxx
+
+
+def quals_num(quals):
+ assert isinstance(quals, (list, str))
+ if isinstance(quals, str):
+ quals = [quals]
+ result = 0
+ for qual in quals:
+ if qual == 'const':
+ result |= model.CRX_CONST
+ if qual == 'volatile':
+ result |= model.CRX_VOLATILE
+ return result
diff --git a/creflect/creflect.h b/creflect/creflect.h
--- a/creflect/creflect.h
+++ b/creflect/creflect.h
@@ -10,8 +10,14 @@
typedef void (*_crx_trampoline1_fn)(void *fn, void *args[], void *res);
typedef struct {
+ _crx_type_t *type;
+ int qualifiers;
+} _crx_qual_type;
+
+typedef struct {
const char *name;
_crx_type_t *type;
+ int qualifiers;
size_t offset;
int numbits, bitshift;
} _crx_field_t;
@@ -29,6 +35,9 @@
long double as_long_double;
} _crx_num_const_t;
+#define _CRX_CONST 1
+#define _CRX_VOLATILE 2
+
#define _CRX_SELF struct _crx_builder_s *
typedef struct _crx_builder_s {
_crx_type_t *(*get_void_type)(_CRX_SELF);
@@ -41,27 +50,25 @@
_crx_type_t *(*get_float_type)(_CRX_SELF, size_t,
const char *);
_crx_type_t *(*get_function_type)(_CRX_SELF, _crx_type_t *,
- _crx_type_t *[], int,
+ _crx_qual_type[], int,
_crx_trampoline1_fn);
_crx_type_t *(*get_ellipsis_function_type)(_CRX_SELF, _crx_type_t *,
- _crx_type_t *[], int);
- _crx_type_t *(*get_pointer_type)(_CRX_SELF, _crx_type_t *);
- _crx_type_t *(*get_const_type)(_CRX_SELF, _crx_type_t *);
+ _crx_qual_type[], int);
+ _crx_type_t *(*get_pointer_type)(_CRX_SELF, _crx_type_t *, int);
_crx_type_t *(*get_array_type)(_CRX_SELF, _crx_type_t *, size_t);
_crx_type_t *(*get_incomplete_array_type)(_CRX_SELF, _crx_type_t *);
_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 *);
+ _crx_qual_type(*get_user_type)(_CRX_SELF, const char *);
_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 (*define_type)(_CRX_SELF, const char *, _crx_type_t *);
- void (*define_var)(_CRX_SELF, const char *, _crx_type_t *,
- void *);
+ void (*define_type)(_CRX_SELF, const char *, _crx_type_t *, int);
+ void (*define_var)(_CRX_SELF, const char *, _crx_type_t *, int, void *);
void (*define_func)(_CRX_SELF, const char *, _crx_type_t *,
- _crx_type_t *[], int, _crx_trampoline0_fn, void *);
+ _crx_qual_type[], int, _crx_trampoline0_fn, void *);
void (*define_num_const)(_CRX_SELF, const char *, _crx_type_t *,
_crx_num_const_t *);
void (*error)(_CRX_SELF, const char *);
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
@@ -32,6 +32,31 @@
return t;
}
+static const char *show_qualtype2(_crx_type_t *type, int qualifiers)
+{
+ size_t la = strlen(type->text);
+ size_t extra = 1;
+ if (qualifiers & _CRX_VOLATILE) extra += strlen("VOLATILE ");
+ if (qualifiers & _CRX_CONST) extra += strlen("CONST " );
+ char *p = malloc(la + extra);
+ char *q = p;
+ if (qualifiers & _CRX_VOLATILE) {
+ strcpy(q, "VOLATILE ");
+ q += strlen("VOLATILE ");
+ }
+ if (qualifiers & _CRX_CONST) {
+ strcpy(q, "CONST ");
+ q += strlen("CONST ");
+ }
+ strcat(q, type->text);
+ return p;
+}
+
+static const char *show_qualtype1(_crx_qual_type qualtype)
+{
+ return show_qualtype2(qualtype.type, qualtype.qualifiers);
+}
+
static _crx_type_t *tst_get_void_type(_crx_builder_t *cb)
{
return newtype("void");
@@ -108,13 +133,13 @@
}
static _crx_type_t *tst_get_function_type(_crx_builder_t *cb, _crx_type_t *ret,
- _crx_type_t *args[], int nargs,
+ _crx_qual_type args[], int nargs,
_crx_trampoline1_fn trampl)
{
int i;
const char *prev = "FUNC( ";
for (i = 0; i < nargs; i++) {
- prev = newtype2(prev, args[i]->text)->text;
+ prev = newtype2(prev, show_qualtype1(args[i]))->text;
prev = newtype2(prev, " -> ")->text;
}
prev = newtype2(prev, ret->text)->text;
@@ -123,21 +148,17 @@
static _crx_type_t *tst_get_ellipsis_function_type(_crx_builder_t *cb,
_crx_type_t *ret,
- _crx_type_t *args[],
+ _crx_qual_type args[],
int nargs)
{
_crx_type_t *dotdotdot = newtype2("... -> ", ret->text);
return tst_get_function_type(cb, dotdotdot, args, nargs, 0);
}
-static _crx_type_t *tst_get_pointer_type(_crx_builder_t *cb, _crx_type_t *t)
+static _crx_type_t *tst_get_pointer_type(_crx_builder_t *cb,
+ _crx_type_t *type, int qualifiers)
{
- return newtype2("PTR ", t->text);
-}
-
-static _crx_type_t *tst_get_const_type(_crx_builder_t *cb, _crx_type_t *t)
-{
- return newtype2("CONST ", t->text);
+ return newtype2("PTR ", show_qualtype2(type, qualifiers));
}
static _crx_type_t *tst_get_array_type(_crx_builder_t *cb, _crx_type_t *t,
@@ -169,9 +190,12 @@
return newtype2("ENUM ", name);
}
-static _crx_type_t *tst_get_user_type(_crx_builder_t *cb, const char *name)
+static _crx_qual_type tst_get_user_type(_crx_builder_t *cb, const char *name)
{
- return newtype(name);
+ _crx_qual_type result;
+ result.type = newtype(name);
+ result.qualifiers = 0; // approximation: we don't really know here
+ return result;
}
static _crx_type_t *tst_get_unknown_type(_crx_builder_t *cb, const char *name)
@@ -186,7 +210,8 @@
int i;
printf("%s:\n", t->text);
for (i = 0; i < nfields; i++) {
- printf("| %s: %s\n", fields[i].name, fields[i].type->text);
+ printf("| %s: %s\n", fields[i].name,
+ show_qualtype2(fields[i].type, fields[i].qualifiers));
}
}
@@ -196,25 +221,26 @@
abort();
}
-static void tst_define_type(_crx_builder_t *cb, const char *name, _crx_type_t *t)
+static void tst_define_type(_crx_builder_t *cb, const char *name,
+ _crx_type_t *type, int qualifiers)
{
- printf("TYPEDEF %s = %s\n", name, t->text);
+ printf("TYPEDEF %s = %s\n", name, show_qualtype2(type, qualifiers));
}
-static void tst_define_var(_crx_builder_t *cb, const char *name, _crx_type_t *t,
- void *addr)
+static void tst_define_var(_crx_builder_t *cb, const char *name,
+ _crx_type_t *type, int qualifiers, void *addr)
{
- printf("VAR %s: %s\n", name, t->text);
+ printf("VAR %s: %s\n", name, show_qualtype2(type, qualifiers));
}
static void tst_define_func(_crx_builder_t *cb, const char *name,
- _crx_type_t *ret, _crx_type_t *args[], int nargs,
+ _crx_type_t *ret, _crx_qual_type args[], int nargs,
_crx_trampoline0_fn trampl, void *directcall)
{
int i;
printf("FUNC %s: ", name);
for (i = 0; i < nargs; i++)
- printf("%s -> ", args[i]->text);
+ printf("%s -> ", show_qualtype1(args[i]));
printf("%s\n", ret->text);
}
@@ -263,7 +289,6 @@
tst_get_function_type,
tst_get_ellipsis_function_type,
tst_get_pointer_type,
- tst_get_const_type,
tst_get_array_type,
tst_get_incomplete_array_type,
tst_get_struct_type,
diff --git a/creflect/model.py b/creflect/model.py
--- a/creflect/model.py
+++ b/creflect/model.py
@@ -1,26 +1,61 @@
from .codegen import CodeBlock
+CRX_CONST = 1
+CRX_VOLATILE = 2
+
+
+class QualType(object):
+ def __init__(self, type, quals=0):
+ self.type = type
+ self.quals = quals
+
+ def get_c_name(self, replace_with=''):
+ if self.quals & CRX_CONST:
+ replace_with = ('const ' + replace_with).rstrip()
+ if self.quals & CRX_VOLATILE:
+ replace_with = ('volatile ' + replace_with).rstrip()
+ #
+ if replace_with == '' and ' &' in self.type.c_name_with_marker:
+ replace_from = ' &'
+ else:
+ replace_from = '&'
+ return self.type.c_name_with_marker.replace(replace_from, replace_with)
+
+ def inspect_qualtype(self, block, inspect):
+ return self.type.inspect_type(block, inspect, self.quals)
+
+ def as_func_arg(self):
+ if isinstance(self.type, ArrayType):
+ return QualType(PointerType(QualType(self.type.item, self.quals)),
+ 0)
+ if isinstance(self.type, FunctionType):
+ return QualType(PointerType(self), 0)
+ return self
+
+ def __repr__(self):
+ return '<QualType %s>' % (self.get_c_name(),)
+
+ def __eq__(self, other):
+ return (self.__class__ == other.__class__ and
+ self.type == other.type and self.quals == other.quals)
+
+ def __ne__(self, other):
+ return not self == other
+
+ def __hash__(self):
+ return hash((self.type, self.quals))
+
class BaseType(object):
- def get_c_name(self, replace_with=''):
- return self.c_name_with_marker.replace('&', replace_with).rstrip()
-
def __repr__(self):
- return '<%s>' % (self.get_c_name(),)
+ return '<%s %s>' % (self.__class__.__name__,
+ QualType(self).get_c_name(),)
def _get_items(self):
- return [(name, getattr(self, name))
- for name in (self._attrs_ + 'const')]
+ return [(name, getattr(self, name)) for name in self._attrs_]
- def inspect_type(self, block, inspect):
- t1 = self.inspect_nonconst_type(block, inspect)
- if self.const:
- return block.write_crx_type_var('cb->get_const_type(cb, %s)' % t1)
- else:
- return t1
-
- def inspect_nonconst_type(self, block, inspect):
+ def inspect_type(self, block, inspect, qualifiers):
raise NotImplementedError
def shadow_global_var(self, top_level_block, name):
@@ -40,18 +75,14 @@
class VoidType(BaseType):
_attrs_ = ()
- def __init__(self, const):
- self.const = const
+ def __init__(self):
self.c_name_with_marker = 'void &'
- if const:
- self.c_name_with_marker = 'const ' + self.c_name_with_marker
- def inspect_nonconst_type(self, block, inspect):
+ def inspect_type(self, block, inspect, qualifiers):
inspect.flush()
return block.write_crx_type_var('cb->get_void_type(cb)')
-void_type = VoidType(const=False)
-const_void_type = VoidType(const=True)
+void_type = VoidType()
class PrimitiveType(BaseType):
@@ -75,13 +106,10 @@
'_Bool': 'u',
}
- def __init__(self, name, const):
+ def __init__(self, name):
assert name in self.ALL_PRIMITIVE_TYPES, repr(name)
self.name = name
- self.const = const
self.c_name_with_marker = name + ' &'
- if const:
- self.c_name_with_marker = 'const ' + self.c_name_with_marker
def is_char_type(self):
return self.ALL_PRIMITIVE_TYPES[self.name] == 'c'
@@ -94,7 +122,7 @@
def is_float_type(self):
return self.ALL_PRIMITIVE_TYPES[self.name] == 'f'
- def inspect_nonconst_type(self, block, inspect):
+ def inspect_type(self, block, inspect, qualifiers):
if isinstance(inspect, TypeInspector):
star_p1 = inspect.fetch_star_p1()
comment1 = inspect.get_comment(0, False, "a valid type", minlevel=1)
@@ -106,7 +134,7 @@
block.writedecl("char b[sizeof(%s)];%s" % (star_p1, comment1))
if self.is_float_type():
block.writeline("memset(b, 0, sizeof(b));")
- elif self.const:
+ elif qualifiers & CRX_CONST:
block.writeline("memset(b, -1, sizeof(b));")
inspect.assign_to_p1("b")
if self.is_float_type():
@@ -114,7 +142,7 @@
else:
op = '<< 1'
block.writeline("(void)(%s %s);%s" % (star_p1, op, comment2))
- if not self.const:
+ if not (qualifiers & CRX_CONST):
block.writeline("%s = -1;%s" % (star_p1, comment3))
if self.is_integer_type():
hint = self.name.split()
@@ -196,14 +224,13 @@
class FunctionType(BaseType):
_attrs_ = ('args', 'result', 'ellipsis')
- const = True
def __init__(self, args, result, ellipsis):
- self.args = args
- self.result = result
+ self.args = args # list of QualTypes
+ self.result = result # a plain BaseType
self.ellipsis = ellipsis
#
- reprargs = [arg.get_c_name() for arg in self.args]
+ reprargs = [qualarg.get_c_name() for qualarg in self.args]
if self.ellipsis:
reprargs.append('...')
reprargs = reprargs or ['void']
@@ -213,30 +240,30 @@
def _get_arg_ret_types(self, block):
inspect = MissingInspector()
- t1 = self.result.inspect_type(block, inspect)
- t_args = [arg.inspect_type(block, inspect) for arg in self.args]
- a2 = block.add_array_crx_types(len(t_args))
- for i, t in enumerate(t_args):
- block.writeline('%s[%d] = %s;' % (a2, i, t))
+ t1 = self.result.inspect_type(block, inspect, 0)
+ a2 = block.write_crx_qualtype_var(len(self.args))
+ for i, arg in enumerate(self.args):
+ t3 = arg.inspect_qualtype(block, inspect)
+ block.writeline('%s[%d].type = %s;' % (a2, i, t3))
+ block.writeline('%s[%d].qualifiers = %d;' % (a2, i, arg.quals))
return t1, a2
def _get_c_call_sequence(self, varname):
call = [' ']
if not isinstance(self.result, VoidType):
- call.append('*(%s)result = ' % (self.result.get_c_name('*'),))
+ call.append('*(%s)result = ' % (
+ QualType(self.result).get_c_name('*'),))
call.append(varname)
call.append('(')
for i in range(len(self.args)):
if i > 0:
call.append(', ')
- call.append('*(%s)args[%d]' % (self.args[i].get_c_name('*'), i))
+ call.append('*(%s)args[%d]' % (
+ self.args[i].as_func_arg().get_c_name('*'), i))
call.append(');')
return ''.join(call)
- def inspect_type(self, block, inspect):
- # this class overrides inspect_type() instead of
- # inspect_nonconst_type(), to avoid the extra call to get_const_type()
-
+ def inspect_type(self, block, inspect, qualifiers):
# this variable is set if we support slightly misdeclared function
# args or return value; this is the case only for typedefs that
# declare a pointer to a function without ellipsis.
@@ -245,7 +272,7 @@
if common_case:
inspect.flush()
else:
- inspect.flush('(%s)' % self.get_c_name('(*)'),
+ inspect.flush('(%s)' % QualType(self).get_c_name('(*)'),
"a function pointer type with exactly the given signature")
if self.ellipsis:
@@ -254,7 +281,7 @@
if common_case:
decl = '%s f' % inspect.typename
else:
- decl = self.get_c_name('(*f)')
+ decl = QualType(self).get_c_name('(*f)')
toplevel = block.crx_top_level
extraname = block._get_next_name('f')
@@ -273,7 +300,7 @@
def inspect_type_ellipsis(self, block, inspect):
if isinstance(inspect, VarInspector):
- decl = self.get_c_name("(*p1)")
+ decl = QualType(self).get_c_name("(*p1)")
block.writeline("%s = &%s; /* check that '%s' is a function with"
" exactly the given signature */" % (
decl, inspect.varname, inspect.varname))
@@ -290,7 +317,7 @@
wrline = top_level_block.writeline
args = [arg.get_c_name('a%d' % i) for i, arg in enumerate(self.args)]
decl = '%s(%s)' % (shadowname, ', '.join(args) or 'void')
- wrline('static %s {' % self.result.get_c_name(decl))
+ wrline('static %s {' % QualType(self.result).get_c_name(decl))
args = ['a%d' % i for i, arg in enumerate(self.args)]
wrline(' %s%s(%s);' % ('' if isinstance(self.result, VoidType)
else 'return ',
@@ -317,30 +344,25 @@
class PointerType(BaseType):
- _attrs_ = ('totype',)
- _base_pattern = {
- (False, False): "*&",
- (True, False): "(*&)",
- (False, True): "*const &",
- (True, True): "(*const &)",
- }
+ _attrs_ = ('toqualtype',)
- def __init__(self, totype, const):
- self.totype = totype
- self.const = const
- base = self.totype.c_name_with_marker
- parens = isinstance(self.totype, (ArrayType, FunctionType))
- extra = self._base_pattern[parens, self.const]
- self.c_name_with_marker = base.replace('&', extra)
+ def __init__(self, toqualtype):
+ assert isinstance(toqualtype, QualType)
+ self.toqualtype = toqualtype
+ if isinstance(toqualtype.type, (ArrayType, FunctionType)):
+ name = self.toqualtype.get_c_name('(*&)')
+ else:
+ name = self.toqualtype.get_c_name('*&')
+ self.c_name_with_marker = name
- def inspect_nonconst_type(self, block, inspect):
+ def inspect_type(self, block, inspect, qualifiers):
if isinstance(inspect, TypeInspector):
star_p1 = inspect.fetch_star_p1()
new_var = 'p%d' % (len(inspect.levels) + 2,)
block.writedecl("char *%s;" % (new_var,))
inspect.assign_to_p1("&%s" % (new_var,))
#
- if self.const:
+ if qualifiers & CRX_CONST:
errmsg = "type '%s' is not a pointer, but an array type" % (
inspect.get_comment_type(0, False),)
inspect.assign_target = new_var
@@ -371,13 +393,13 @@
inspect.varname, self.get_c_name()))
block.writeline("(void)p1;")
inspect = MissingInspector()
- t1 = self.totype.inspect_type(block, inspect)
- return block.write_crx_type_var('cb->get_pointer_type(cb, %s)' % t1)
+ t1 = self.toqualtype.inspect_qualtype(block, inspect)
+ return block.write_crx_type_var('cb->get_pointer_type(cb, %s, %d)'
+ % (t1, self.toqualtype.quals))
class ArrayType(BaseType):
_attrs_ = ('item', 'length')
- const = True # not really applicable, but must have one
def __init__(self, item, length):
self.item = item
@@ -385,20 +407,12 @@
#
if length is None:
brackets = '&[]'
- elif length == '...':
- brackets = '&[/*...*/]'
else:
brackets = '&[%d]' % length
- if ' &' in self.item.c_name_with_marker:
- replace_from = ' &'
- else:
- replace_from = '&'
self.c_name_with_marker = (
- self.item.c_name_with_marker.replace(replace_from, brackets))
+ self.item.c_name_with_marker.replace('&', brackets))
- def inspect_type(self, block, inspect):
- # this class overrides inspect_type() instead of
- # inspect_nonconst_type(), to avoid the extra call to get_const_type()
+ def inspect_type(self, block, inspect, qualifiers):
if isinstance(inspect, TypeInspector):
star_p1 = inspect.fetch_star_p1()
errmsg = "type '%s' is not an array, but a pointer type" % (
@@ -424,7 +438,7 @@
inspect = MissingInspector()
else:
star_p1 = None
- t1 = self.item.inspect_type(block, inspect)
+ t1 = self.item.inspect_type(block, inspect, qualifiers)
if star_p1 is not None:
expr = 'cb->get_array_type(cb, %s, sizeof(%s) / sizeof(*%s))' % (
t1, star_p1, star_p1)
@@ -436,10 +450,9 @@
class StructOrUnionOrEnum(BaseType):
_attrs_ = ('kind', 'name')
- def __init__(self, kind, name, const):
+ def __init__(self, kind, name):
self.kind = kind
self.name = name
- self.const = const
self.c_name_with_marker = '%s %s &' % (self.kind, self.name)
if const:
self.c_name_with_marker = 'const ' + self.c_name_with_marker
@@ -448,23 +461,19 @@
return block.write_crx_type_var('cb->get_%s_type(cb, "%s")' % (
self.kind, self.name))
- def inspect_nonconst_type(self, block, inspect):
+ def inspect_type(self, block, inspect, qualifiers):
inspect.flush()
return self.get_type_var(block)
class UserType(BaseType):
- _attrs_ = ('name', 'realtype')
+ _attrs_ = ('name',)
- def __init__(self, name, realtype, const=False):
+ def __init__(self, name):
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):
+ def inspect_type(self, block, inspect, qualifiers):
inspect.flush()
if isinstance(inspect, VarInspector):
decl = self.get_c_name("*p1")
@@ -478,13 +487,12 @@
class UnknownType(BaseType):
_attrs_ = ('approx_name',)
- const = False
def __init__(self, approx_name):
self.approx_name = approx_name
self.c_name_with_marker = '... &'
- def inspect_nonconst_type(self, block, inspect):
+ def inspect_type(self, block, inspect, qualifiers):
inspect.flush()
return block.write_crx_type_var('cb->get_unknown_type(cb, "%s")' % (
self.approx_name,))
@@ -688,41 +696,43 @@
class TypeDefDecl(object):
- def __init__(self, name, type):
+ def __init__(self, name, qualtype):
self.name = name
- self.type = type
+ self.qualtype = qualtype
def write_declaration(self, funcblock):
block = CodeBlock(funcblock)
inspect = TypeInspector(block, self.name)
- t1 = self.type.inspect_type(block, inspect)
+ t1 = self.qualtype.inspect_qualtype(block, inspect)
inspect.stop()
- block.writeline('cb->define_type(cb, "%s", %s);' % (self.name, t1))
+ block.writeline('cb->define_type(cb, "%s", %s, %d);' % (
+ self.name, t1, self.qualtype.quals))
funcblock.write_subblock(block)
class VarDecl(object):
- def __init__(self, name, type):
+ def __init__(self, name, qualtype):
self.name = name
- self.type = type
+ self.qualtype = qualtype
def write_declaration(self, funcblock):
block = CodeBlock(funcblock)
inspect = VarInspector(block, self.name)
- t1 = self.type.inspect_type(block, inspect)
- shadow = self.type.shadow_global_var(block.crx_top_level, self.name)
- block.writeline('cb->define_var(cb, "%s", %s, &%s);' % (
- self.name, t1, shadow))
+ t1 = self.qualtype.inspect_qualtype(block, inspect)
+ shadow = self.qualtype.type.shadow_global_var(block.crx_top_level,
+ self.name)
+ block.writeline('cb->define_var(cb, "%s", %s, %d, &%s);' % (
+ self.name, t1, self.qualtype.quals, shadow))
funcblock.write_subblock(block)
class FuncDecl(VarDecl):
def write_declaration(self, funcblock):
- if self.type.ellipsis:
+ if self.qualtype.type.ellipsis:
VarDecl.write_declaration(self, funcblock)
else:
block = CodeBlock(funcblock)
- self.type.write_func_decl(block, self.name)
+ self.qualtype.type.write_func_decl(block, self.name)
funcblock.write_subblock(block)
diff --git a/creflect/test/codegen/002.c b/creflect/test/codegen/002.c
--- a/creflect/test/codegen/002.c
+++ b/creflect/test/codegen/002.c
@@ -11,8 +11,8 @@
p1 = (void *)&p2;
*p1 = (void *)0; /* check that 'num_t' is a pointer type */
t1 = cb->get_void_type(cb);
- t2 = cb->get_pointer_type(cb, t1);
- cb->define_type(cb, "num_t", t2);
+ t2 = cb->get_pointer_type(cb, t1, 0);
+ cb->define_type(cb, "num_t", t2, 0);
#expect TYPEDEF num_t = PTR void
}
}
diff --git a/creflect/test/codegen/002b.c b/creflect/test/codegen/002b.c
--- a/creflect/test/codegen/002b.c
+++ b/creflect/test/codegen/002b.c
@@ -15,10 +15,10 @@
**p1 = (void *)&p4; /* check that '*num_t' is a pointer type */
***p1 = (void *)0; /* check that '**num_t' is a pointer type */
t1 = cb->get_void_type(cb);
- t2 = cb->get_pointer_type(cb, t1);
- t3 = cb->get_pointer_type(cb, t2);
- t4 = cb->get_pointer_type(cb, t3);
- cb->define_type(cb, "num_t", t4);
+ t2 = cb->get_pointer_type(cb, t1, 0);
+ t3 = cb->get_pointer_type(cb, t2, 0);
+ t4 = cb->get_pointer_type(cb, t3, 0);
+ cb->define_type(cb, "num_t", t4, 0);
#expect TYPEDEF num_t = PTR PTR PTR void
}
}
diff --git a/creflect/test/codegen/002c.c b/creflect/test/codegen/002c.c
--- a/creflect/test/codegen/002c.c
+++ b/creflect/test/codegen/002c.c
@@ -4,16 +4,15 @@
void test002c(_crx_builder_t *cb)
{
- _crx_type_t *t1, *t2, *t3;
+ _crx_type_t *t1, *t2;
{
num_t *p1;
char *p2;
p1 = (void *)&p2;
*p1 = (void *)0; /* check that 'num_t' is a pointer type */
t1 = cb->get_void_type(cb);
- t2 = cb->get_const_type(cb, t1);
- t3 = cb->get_pointer_type(cb, t2);
- cb->define_type(cb, "num_t", t3);
+ t2 = cb->get_pointer_type(cb, t1, 1);
+ cb->define_type(cb, "num_t", t2, 0);
#expect TYPEDEF num_t = PTR CONST void
}
}
diff --git a/creflect/test/codegen/002d.c b/creflect/test/codegen/002d.c
new file mode 100644
--- /dev/null
+++ b/creflect/test/codegen/002d.c
@@ -0,0 +1,22 @@
+typedef void *const num_t;
+
+# ____________________________________________________________
+
+void test002d(_crx_builder_t *cb)
+{
+ _crx_type_t *t1, *t2;
+ {
+ num_t *p1;
+ char *p2;
+ p1 = (void *)&p2;
+ p2 = (void *)0;
+ if ((void *)p1 == (void *)*p1) {
+ cb->error(cb, "type 'num_t' is not a pointer, but an array type");
+ return;
+ }
+ t1 = cb->get_void_type(cb);
+ t2 = cb->get_pointer_type(cb, t1, 0);
+ cb->define_type(cb, "num_t", t2, 1);
+#expect TYPEDEF num_t = CONST PTR void
+ }
+}
diff --git a/creflect/test/codegen/003.c b/creflect/test/codegen/003.c
--- a/creflect/test/codegen/003.c
+++ b/creflect/test/codegen/003.c
@@ -12,7 +12,7 @@
(void)(*p1 << 1); /* check that 'num_t' is an integer type */
*p1 = -1; /* check that 'num_t' is not declared 'const' */
t1 = _CRX_INT_TYPE(cb, *p1, "int");
- cb->define_type(cb, "num_t", t1);
+ cb->define_type(cb, "num_t", t1, 0);
#expect TYPEDEF num_t = int
}
}
diff --git a/creflect/test/codegen/003b.c b/creflect/test/codegen/003b.c
--- a/creflect/test/codegen/003b.c
+++ b/creflect/test/codegen/003b.c
@@ -12,7 +12,7 @@
(void)(*p1 << 1); /* check that 'num_t' is an integer type */
*p1 = -1; /* check that 'num_t' is not declared 'const' */
t1 = _CRX_INT_TYPE(cb, *p1, "long");
- cb->define_type(cb, "num_t", t1);
+ cb->define_type(cb, "num_t", t1, 0);
#expect TYPEDEF num_t = long
}
}
diff --git a/creflect/test/codegen/003c.c b/creflect/test/codegen/003c.c
--- a/creflect/test/codegen/003c.c
+++ b/creflect/test/codegen/003c.c
@@ -12,7 +12,7 @@
(void)(*p1 << 1); /* check that 'num_t' is an integer type */
*p1 = -1; /* check that 'num_t' is not declared 'const' */
t1 = _CRX_INT_TYPE(cb, *p1, "long long");
- cb->define_type(cb, "num_t", t1);
+ cb->define_type(cb, "num_t", t1, 0);
#expect TYPEDEF num_t = long long
}
}
diff --git a/creflect/test/codegen/003d.c b/creflect/test/codegen/003d.c
--- a/creflect/test/codegen/003d.c
+++ b/creflect/test/codegen/003d.c
@@ -12,7 +12,7 @@
(void)(*p1 << 1); /* check that 'num_t' is an integer type */
*p1 = -1; /* check that 'num_t' is not declared 'const' */
t1 = _CRX_INT_TYPE(cb, *p1, "char");
- cb->define_type(cb, "num_t", t1);
+ cb->define_type(cb, "num_t", t1, 0);
#expect TYPEDEF num_t = signed char
}
}
diff --git a/creflect/test/codegen/003e.c b/creflect/test/codegen/003e.c
--- a/creflect/test/codegen/003e.c
+++ b/creflect/test/codegen/003e.c
@@ -16,7 +16,7 @@
return;
}
t1 = cb->get_char_type(cb);
- cb->define_type(cb, "num_t", t1);
+ cb->define_type(cb, "num_t", t1, 0);
#expect TYPEDEF num_t = char
}
}
diff --git a/creflect/test/codegen/003f.c b/creflect/test/codegen/003f.c
--- a/creflect/test/codegen/003f.c
+++ b/creflect/test/codegen/003f.c
@@ -12,7 +12,7 @@
(void)(*p1 << 1); /* check that 'num_t' is an integer type */
*p1 = -1; /* check that 'num_t' is not declared 'const' */
t1 = _CRX_INT_TYPE(cb, *p1, "long long");
- cb->define_type(cb, "num_t", t1);
+ cb->define_type(cb, "num_t", t1, 0);
#expect TYPEDEF num_t = unsigned long long
}
}
diff --git a/creflect/test/codegen/003g.c b/creflect/test/codegen/003g.c
--- a/creflect/test/codegen/003g.c
+++ b/creflect/test/codegen/003g.c
@@ -17,7 +17,7 @@
return;
}
t1 = cb->get_float_type(cb, sizeof(*p1), "double");
- cb->define_type(cb, "num_t", t1);
+ cb->define_type(cb, "num_t", t1, 0);
#expect TYPEDEF num_t = double
}
}
diff --git a/creflect/test/codegen/003h.c b/creflect/test/codegen/003h.c
--- a/creflect/test/codegen/003h.c
+++ b/creflect/test/codegen/003h.c
@@ -16,7 +16,7 @@
(void)(*p1 << 1); /* check that 'num_t' is an integer type */
*p1 = -1; /* check that 'num_t' is not declared 'const' */
t1 = _CRX_INT_TYPE(cb, *p1, "long long");
- cb->define_type(cb, "num_t", t1);
+ cb->define_type(cb, "num_t", t1, 0);
#expect TYPEDEF num_t = int
}
}
diff --git a/creflect/test/codegen/003i.c b/creflect/test/codegen/003i.c
--- a/creflect/test/codegen/003i.c
+++ b/creflect/test/codegen/003i.c
@@ -12,7 +12,7 @@
(void)(*p1 << 1); /* check that 'num_t' is an integer type */
*p1 = -1; /* check that 'num_t' is not declared 'const' */
t1 = _CRX_INT_TYPE(cb, *p1, "char");
- cb->define_type(cb, "num_t", t1);
+ cb->define_type(cb, "num_t", t1, 0);
#expect TYPEDEF num_t = signed char
}
}
diff --git a/creflect/test/codegen/004.c b/creflect/test/codegen/004.c
--- a/creflect/test/codegen/004.c
+++ b/creflect/test/codegen/004.c
@@ -14,8 +14,8 @@
(void)(**p1 << 1); /* check that '*num_t' is an integer type */
**p1 = -1; /* check that '*num_t' is not declared 'const' */
t1 = _CRX_INT_TYPE(cb, **p1, "int");
- t2 = cb->get_pointer_type(cb, t1);
- cb->define_type(cb, "num_t", t2);
+ t2 = cb->get_pointer_type(cb, t1, 0);
+ cb->define_type(cb, "num_t", t2, 0);
#expect TYPEDEF num_t = PTR int
}
}
diff --git a/creflect/test/codegen/004b.c b/creflect/test/codegen/004b.c
--- a/creflect/test/codegen/004b.c
+++ b/creflect/test/codegen/004b.c
@@ -16,9 +16,9 @@
(void)(***p1 << 1); /* check that '**num_t' is an integer type */
***p1 = -1; /* check that '**num_t' is not declared 'const' */
t1 = _CRX_INT_TYPE(cb, ***p1, "int");
- t2 = cb->get_pointer_type(cb, t1);
- t3 = cb->get_pointer_type(cb, t2);
- cb->define_type(cb, "num_t", t3);
+ t2 = cb->get_pointer_type(cb, t1, 0);
+ t3 = cb->get_pointer_type(cb, t2, 0);
+ cb->define_type(cb, "num_t", t3, 0);
#expect TYPEDEF num_t = PTR PTR int
}
}
diff --git a/creflect/test/codegen/005.c b/creflect/test/codegen/005.c
--- a/creflect/test/codegen/005.c
+++ b/creflect/test/codegen/005.c
@@ -17,7 +17,7 @@
**p1 = -1; /* check that 'foo_t[]' is not declared 'const' */
t1 = _CRX_INT_TYPE(cb, **p1, "int");
t2 = cb->get_array_type(cb, t1, sizeof(*p1) / sizeof(**p1));
- cb->define_type(cb, "foo_t", t2);
+ cb->define_type(cb, "foo_t", t2, 0);
#expect TYPEDEF foo_t = ARRAY[27] int
}
}
diff --git a/creflect/test/codegen/005b.c b/creflect/test/codegen/005b.c
--- a/creflect/test/codegen/005b.c
+++ b/creflect/test/codegen/005b.c
@@ -18,9 +18,9 @@
(void)(***p1 << 1); /* check that '*foo_t[]' is an integer type */
***p1 = -1; /* check that '*foo_t[]' is not declared 'const' */
t1 = _CRX_INT_TYPE(cb, ***p1, "int");
- t2 = cb->get_pointer_type(cb, t1);
+ t2 = cb->get_pointer_type(cb, t1, 0);
t3 = cb->get_array_type(cb, t2, sizeof(*p1) / sizeof(**p1));
- cb->define_type(cb, "foo_t", t3);
+ cb->define_type(cb, "foo_t", t3, 0);
#expect TYPEDEF foo_t = ARRAY[27] PTR int
}
}
diff --git a/creflect/test/codegen/005c.c b/creflect/test/codegen/005c.c
--- a/creflect/test/codegen/005c.c
+++ b/creflect/test/codegen/005c.c
@@ -19,8 +19,8 @@
***p1 = -1; /* check that '(*foo_t)[]' is not declared 'const' */
t1 = _CRX_INT_TYPE(cb, ***p1, "int");
t2 = cb->get_array_type(cb, t1, sizeof(**p1) / sizeof(***p1));
- t3 = cb->get_pointer_type(cb, t2);
- cb->define_type(cb, "foo_t", t3);
+ t3 = cb->get_pointer_type(cb, t2, 0);
+ cb->define_type(cb, "foo_t", t3, 0);
#expect TYPEDEF foo_t = PTR ARRAY[27] int
}
}
diff --git a/creflect/test/codegen/005d.c b/creflect/test/codegen/005d.c
--- a/creflect/test/codegen/005d.c
+++ b/creflect/test/codegen/005d.c
@@ -38,16 +38,16 @@
(void)(**********p1 << 1); /* check that '**(***foo_t[][])[][]' is an integer type */
**********p1 = -1; /* check that '**(***foo_t[][])[][]' is not declared 'const' */
t1 = _CRX_INT_TYPE(cb, **********p1, "int");
- t2 = cb->get_pointer_type(cb, t1);
- t3 = cb->get_pointer_type(cb, t2);
+ t2 = cb->get_pointer_type(cb, t1, 0);
+ t3 = cb->get_pointer_type(cb, t2, 0);
t4 = cb->get_array_type(cb, t3, sizeof(*******p1) / sizeof(********p1));
t5 = cb->get_array_type(cb, t4, sizeof(******p1) / sizeof(*******p1));
- t6 = cb->get_pointer_type(cb, t5);
- t7 = cb->get_pointer_type(cb, t6);
- t8 = cb->get_pointer_type(cb, t7);
+ t6 = cb->get_pointer_type(cb, t5, 0);
+ t7 = cb->get_pointer_type(cb, t6, 0);
+ t8 = cb->get_pointer_type(cb, t7, 0);
t9 = cb->get_array_type(cb, t8, sizeof(**p1) / sizeof(***p1));
t10 = cb->get_array_type(cb, t9, sizeof(*p1) / sizeof(**p1));
- cb->define_type(cb, "foo_t", t10);
+ cb->define_type(cb, "foo_t", t10, 0);
#expect TYPEDEF foo_t = ARRAY[4] ARRAY[3] PTR PTR PTR ARRAY[27] ARRAY[91] PTR PTR int
}
}
diff --git a/creflect/test/codegen/006.c b/creflect/test/codegen/006.c
--- a/creflect/test/codegen/006.c
+++ b/creflect/test/codegen/006.c
@@ -4,7 +4,7 @@
void test006(_crx_builder_t *cb)
{
- _crx_type_t *t1, *t2;
+ _crx_type_t *t1;
{
num_t *p1;
char b[sizeof(*p1)];
@@ -12,8 +12,7 @@
p1 = (void *)b;
(void)(*p1 << 1); /* check that 'num_t' is an integer type */
t1 = _CRX_INT_TYPE(cb, *p1, "int");
- t2 = cb->get_const_type(cb, t1);
- cb->define_type(cb, "num_t", t2);
+ cb->define_type(cb, "num_t", t1, 1);
#expect TYPEDEF num_t = CONST unsigned int
}
}
diff --git a/creflect/test/codegen/006b.c b/creflect/test/codegen/006b.c
--- a/creflect/test/codegen/006b.c
+++ b/creflect/test/codegen/006b.c
@@ -4,7 +4,7 @@
void test006b(_crx_builder_t *cb)
{
- _crx_type_t *t1, *t2, *t3;
+ _crx_type_t *t1, *t2;
{
num_t *p1;
char *p2;
@@ -18,9 +18,8 @@
(void)(**p1 << 1); /* check that '*num_t' is an integer type */
**p1 = -1; /* check that '*num_t' is not declared 'const' */
t1 = _CRX_INT_TYPE(cb, **p1, "int");
- t2 = cb->get_pointer_type(cb, t1);
- t3 = cb->get_const_type(cb, t2);
- cb->define_type(cb, "num_t", t3);
+ t2 = cb->get_pointer_type(cb, t1, 0);
+ cb->define_type(cb, "num_t", t2, 1);
#expect TYPEDEF num_t = CONST PTR int
}
}
diff --git a/creflect/test/codegen/006c.c b/creflect/test/codegen/006c.c
--- a/creflect/test/codegen/006c.c
+++ b/creflect/test/codegen/006c.c
@@ -4,7 +4,7 @@
void test006c(_crx_builder_t *cb)
{
- _crx_type_t *t1, *t2, *t3, *t4;
+ _crx_type_t *t1, *t2, *t3;
{
foo_t *p1;
char *p2;
@@ -23,9 +23,8 @@
***p1 = -1; /* check that '(*foo_t)[]' is not declared 'const' */
t1 = _CRX_INT_TYPE(cb, ***p1, "int");
t2 = cb->get_array_type(cb, t1, sizeof(**p1) / sizeof(***p1));
- t3 = cb->get_pointer_type(cb, t2);
- t4 = cb->get_const_type(cb, t3);
- cb->define_type(cb, "foo_t", t4);
+ t3 = cb->get_pointer_type(cb, t2, 0);
+ cb->define_type(cb, "foo_t", t3, 1);
#expect TYPEDEF foo_t = CONST PTR ARRAY[27] int
}
}
diff --git a/creflect/test/codegen/007.c b/creflect/test/codegen/007.c
--- a/creflect/test/codegen/007.c
+++ b/creflect/test/codegen/007.c
@@ -7,7 +7,7 @@
_crx_type_t *t1;
{
t1 = cb->get_unknown_type(cb, "$num_t");
- cb->define_type(cb, "num_t", t1);
+ cb->define_type(cb, "num_t", t1, 0);
#expect TYPEDEF num_t = UNKNOWN $num_t
}
}
diff --git a/creflect/test/codegen/func-001b.c b/creflect/test/codegen/func-001b.c
--- a/creflect/test/codegen/func-001b.c
+++ b/creflect/test/codegen/func-001b.c
@@ -36,25 +36,33 @@
void testfunc_001b(_crx_builder_t *cb)
{
- _crx_type_t *t1, *t2, *a3[1], *t4, *a5[2], *a6[2];
+ _crx_type_t *t1, *t2, *t3;
+ _crx_qual_type a1[1];
+ _crx_qual_type a2[2];
+ _crx_qual_type a3[2];
{
t1 = cb->get_unsigned_type(cb, sizeof(unsigned int), "unsigned int");
t2 = cb->get_signed_type(cb, sizeof(long), "long");
- a3[0] = t2;
- cb->define_func(cb, "f", t1, a3, 1, &testfunc_001b__c_f, &testfunc_001b__d_f);
+ a1[0].type = t2;
+ a1[0].qualifiers = 0;
+ cb->define_func(cb, "f", t1, a1, 1, &testfunc_001b__c_f, &testfunc_001b__d_f);
#expect FUNC f: long -> unsigned int
}
{
- t4 = cb->get_signed_type(cb, sizeof(int), "int");
- a5[0] = t4;
- a5[1] = t4;
- cb->define_func(cb, "g", t2, a5, 2, &testfunc_001b__c_g, &testfunc_001b__d_g);
+ t3 = cb->get_signed_type(cb, sizeof(int), "int");
+ a2[0].type = t3;
+ a2[0].qualifiers = 0;
+ a2[1].type = t3;
+ a2[1].qualifiers = 0;
+ cb->define_func(cb, "g", t2, a2, 2, &testfunc_001b__c_g, &testfunc_001b__d_g);
#expect FUNC g: int -> int -> long
}
{
- a6[0] = t4;
- a6[1] = t4;
- cb->define_func(cb, "h", t2, a6, 2, &testfunc_001b__c_h, &testfunc_001b__d_h);
+ a3[0].type = t3;
+ a3[0].qualifiers = 0;
+ a3[1].type = t3;
+ a3[1].qualifiers = 0;
+ cb->define_func(cb, "h", t2, a3, 2, &testfunc_001b__c_h, &testfunc_001b__d_h);
#expect FUNC h: int -> int -> long
}
}
diff --git a/creflect/test/codegen/func-001c.c b/creflect/test/codegen/func-001c.c
--- a/creflect/test/codegen/func-001c.c
+++ b/creflect/test/codegen/func-001c.c
@@ -16,12 +16,14 @@
void testfunc_001c(_crx_builder_t *cb)
{
- _crx_type_t *t1, *t2, *a3[1];
+ _crx_type_t *t1, *t2;
+ _crx_qual_type a1[1];
{
t1 = cb->get_float_type(cb, sizeof(double), "double");
t2 = cb->get_float_type(cb, sizeof(float), "float");
- a3[0] = t2;
- cb->define_func(cb, "f", t1, a3, 1, &testfunc_001c__c_f, &testfunc_001c__d_f);
+ a1[0].type = t2;
+ a1[0].qualifiers = 0;
+ cb->define_func(cb, "f", t1, a1, 1, &testfunc_001c__c_f, &testfunc_001c__d_f);
#expect FUNC f: float -> double
}
}
diff --git a/creflect/test/codegen/func-002.c b/creflect/test/codegen/func-002.c
--- a/creflect/test/codegen/func-002.c
+++ b/creflect/test/codegen/func-002.c
@@ -9,14 +9,16 @@
void testfunc_002(_crx_builder_t *cb)
{
- _crx_type_t *t1, *a2[1], *t3;
+ _crx_type_t *t1, *t2;
+ _crx_qual_type a1[1];
{
int (*p1)(int, ...) = &f; /* check that 'f' is a function with exactly the given signature */
(void)p1;
t1 = cb->get_signed_type(cb, sizeof(int), "int");
- a2[0] = t1;
- t3 = cb->get_ellipsis_function_type(cb, t1, a2, 1);
- cb->define_var(cb, "f", t3, &f);
+ a1[0].type = t1;
+ a1[0].qualifiers = 0;
+ t2 = cb->get_ellipsis_function_type(cb, t1, a1, 1);
+ cb->define_var(cb, "f", t2, 0, &f);
#expect VAR f: FUNC( int -> ... -> int )
}
}
diff --git a/creflect/test/codegen/func-003.c b/creflect/test/codegen/func-003.c
--- a/creflect/test/codegen/func-003.c
+++ b/creflect/test/codegen/func-003.c
@@ -9,7 +9,8 @@
void testfunc_003(_crx_builder_t *cb)
{
- _crx_type_t *t1, *t2, *a3[3], *t4, *t5;
+ _crx_type_t *t1, *t2, *t3, *t4;
+ _crx_qual_type a1[3];
{
func_t *p1;
char *p2;
@@ -17,12 +18,15 @@
*p1 = (void *)0; /* check that 'func_t' is a pointer type */
t1 = cb->get_signed_type(cb, sizeof(int), "int");
t2 = cb->get_signed_type(cb, sizeof(long), "long");
- a3[0] = t2;
- a3[1] = t2;
- a3[2] = t1;
- t4 = cb->get_function_type(cb, t1, a3, 3, &testfunc_003__f1);
- t5 = cb->get_pointer_type(cb, t4);
- cb->define_type(cb, "func_t", t5);
+ a1[0].type = t2;
+ a1[0].qualifiers = 0;
+ a1[1].type = t2;
+ a1[1].qualifiers = 0;
+ a1[2].type = t1;
+ a1[2].qualifiers = 0;
+ t3 = cb->get_function_type(cb, t1, a1, 3, &testfunc_003__f1);
+ t4 = cb->get_pointer_type(cb, t3, 0);
+ cb->define_type(cb, "func_t", t4, 0);
#expect TYPEDEF func_t = PTR FUNC( long -> long -> int -> int )
}
}
diff --git a/creflect/test/codegen/func-003b.c b/creflect/test/codegen/func-003b.c
--- a/creflect/test/codegen/func-003b.c
+++ b/creflect/test/codegen/func-003b.c
@@ -4,7 +4,8 @@
void testfunc_003b(_crx_builder_t *cb)
{
- _crx_type_t *t1, *t2, *a3[1], *t4, *t5;
+ _crx_type_t *t1, *t2, *t3, *t4;
+ _crx_qual_type a1[1];
{
func_t *p1;
char *p2;
@@ -12,10 +13,11 @@
*p1 = (int (*)(long, ...))0; /* check that 'func_t' is a function pointer type with exactly the given signature */
t1 = cb->get_signed_type(cb, sizeof(int), "int");
t2 = cb->get_signed_type(cb, sizeof(long), "long");
- a3[0] = t2;
- t4 = cb->get_ellipsis_function_type(cb, t1, a3, 1);
- t5 = cb->get_pointer_type(cb, t4);
- cb->define_type(cb, "func_t", t5);
+ a1[0].type = t2;
+ a1[0].qualifiers = 0;
+ t3 = cb->get_ellipsis_function_type(cb, t1, a1, 1);
+ t4 = cb->get_pointer_type(cb, t3, 0);
+ cb->define_type(cb, "func_t", t4, 0);
#expect TYPEDEF func_t = PTR FUNC( long -> ... -> int )
}
}
diff --git a/creflect/test/codegen/func-004.c b/creflect/test/codegen/func-004.c
--- a/creflect/test/codegen/func-004.c
+++ b/creflect/test/codegen/func-004.c
@@ -9,7 +9,8 @@
void testfunc_004(_crx_builder_t *cb)
{
- _crx_type_t *t1, *t2, *a3[2], *t4, *t5, *t6;
+ _crx_type_t *t1, *t2, *t3, *t4, *t5;
+ _crx_qual_type a1[2];
{
func_t *p1;
char *p2;
@@ -19,12 +20,14 @@
**p1 = (int (*)(long, int))0; /* check that '*func_t' is a function pointer type with exactly the given signature */
t1 = cb->get_signed_type(cb, sizeof(int), "int");
t2 = cb->get_signed_type(cb, sizeof(long), "long");
- a3[0] = t2;
- a3[1] = t1;
- t4 = cb->get_function_type(cb, t1, a3, 2, &testfunc_004__f1);
- t5 = cb->get_pointer_type(cb, t4);
- t6 = cb->get_pointer_type(cb, t5);
- cb->define_type(cb, "func_t", t6);
+ a1[0].type = t2;
+ a1[0].qualifiers = 0;
+ a1[1].type = t1;
+ a1[1].qualifiers = 0;
+ t3 = cb->get_function_type(cb, t1, a1, 2, &testfunc_004__f1);
+ t4 = cb->get_pointer_type(cb, t3, 0);
+ t5 = cb->get_pointer_type(cb, t4, 0);
+ cb->define_type(cb, "func_t", t5, 0);
#expect TYPEDEF func_t = PTR PTR FUNC( long -> int -> int )
}
}
diff --git a/creflect/test/codegen/func-005.c b/creflect/test/codegen/func-005.c
--- a/creflect/test/codegen/func-005.c
+++ b/creflect/test/codegen/func-005.c
@@ -1,16 +1,16 @@
-void f(int[], long(char, short));
+void f(const int[], long(char, short));
# ____________________________________________________________
-void f(int a[], long g(char, short)) { }
+void f(const int a[], long g(char, short)) { }
# ____________________________________________________________
static void testfunc_005__c_f(void *args[], void *result) {
- f(*(int **)args[0], *(long (**)(char, short))args[1]);
+ f(*(int const **)args[0], *(long (**)(char, short))args[1]);
}
-static void testfunc_005__d_f(int *a0, long (*a1)(char, short)) {
+static void testfunc_005__d_f(int const a0[], long a1(char, short)) {
f(a0, a1);
}
@@ -21,21 +21,26 @@
void testfunc_005(_crx_builder_t *cb)
{
- _crx_type_t *t1, *t2, *t3, *t4, *t5, *t6, *a7[2], *t8, *t9, *a10[2];
+ _crx_type_t *t1, *t2, *t3, *t4, *t5, *t6, *t7;
+ _crx_qual_type a1[2];
+ _crx_qual_type a2[2];
{
t1 = cb->get_void_type(cb);
t2 = cb->get_signed_type(cb, sizeof(int), "int");
- t3 = cb->get_pointer_type(cb, t2);
+ t3 = cb->get_incomplete_array_type(cb, t2);
+ a1[0].type = t3;
+ a1[0].qualifiers = 1;
t4 = cb->get_signed_type(cb, sizeof(long), "long");
t5 = cb->get_char_type(cb);
+ a2[0].type = t5;
+ a2[0].qualifiers = 0;
t6 = cb->get_signed_type(cb, sizeof(short), "short");
- a7[0] = t5;
- a7[1] = t6;
- t8 = cb->get_function_type(cb, t4, a7, 2, &testfunc_005__f4);
- t9 = cb->get_pointer_type(cb, t8);
- a10[0] = t3;
- a10[1] = t9;
- cb->define_func(cb, "f", t1, a10, 2, &testfunc_005__c_f, &testfunc_005__d_f);
-#expect FUNC f: PTR int -> PTR FUNC( char -> short -> long ) -> void
+ a2[1].type = t6;
+ a2[1].qualifiers = 0;
+ t7 = cb->get_function_type(cb, t4, a2, 2, &testfunc_005__f4);
+ a1[1].type = t7;
+ a1[1].qualifiers = 0;
+ cb->define_func(cb, "f", t1, a1, 2, &testfunc_005__c_f, &testfunc_005__d_f);
+#expect FUNC f: CONST ARRAY[] int -> FUNC( char -> short -> long ) -> void
}
}
diff --git a/creflect/test/codegen/glob-001.c b/creflect/test/codegen/glob-001.c
--- a/creflect/test/codegen/glob-001.c
+++ b/creflect/test/codegen/glob-001.c
@@ -9,8 +9,8 @@
void *p1 = someglob; /* check that 'someglob' is a pointer */
if (0) { someglob = p1; } /* check that 'someglob' is a pointer variable, and not an array or a constant */
t1 = cb->get_void_type(cb);
- t2 = cb->get_pointer_type(cb, t1);
- cb->define_var(cb, "someglob", t2, &someglob);
+ t2 = cb->get_pointer_type(cb, t1, 0);
+ cb->define_var(cb, "someglob", t2, 0, &someglob);
#expect VAR someglob: PTR void
}
}
diff --git a/creflect/test/codegen/glob-002.c b/creflect/test/codegen/glob-002.c
--- a/creflect/test/codegen/glob-002.c
+++ b/creflect/test/codegen/glob-002.c
@@ -10,7 +10,7 @@
(void)p1;
t1 = cb->get_char_type(cb);
t2 = cb->get_array_type(cb, t1, sizeof(someglob) / sizeof(*someglob));
- cb->define_var(cb, "someglob", t2, &someglob);
+ cb->define_var(cb, "someglob", t2, 0, &someglob);
#expect VAR someglob: ARRAY[100] char
}
}
diff --git a/creflect/test/codegen/glob-002b.c b/creflect/test/codegen/glob-002b.c
--- a/creflect/test/codegen/glob-002b.c
+++ b/creflect/test/codegen/glob-002b.c
@@ -12,7 +12,7 @@
(void)p1;
t1 = cb->get_signed_type(cb, sizeof(int), "int");
t2 = cb->get_array_type(cb, t1, sizeof(someglob) / sizeof(*someglob));
- cb->define_var(cb, "someglob", t2, &someglob);
+ cb->define_var(cb, "someglob", t2, 0, &someglob);
#expect VAR someglob: ARRAY[100] int
}
}
diff --git a/creflect/test/codegen/glob-002c.c b/creflect/test/codegen/glob-002c.c
--- a/creflect/test/codegen/glob-002c.c
+++ b/creflect/test/codegen/glob-002c.c
@@ -11,7 +11,7 @@
int *p1 = &someglob; /* check that 'someglob' is of type 'int' */
(void)p1;
t1 = cb->get_signed_type(cb, sizeof(int), "int");
- cb->define_var(cb, "someglob", t1, &someglob);
+ cb->define_var(cb, "someglob", t1, 0, &someglob);
#expect VAR someglob: int
}
}
diff --git a/creflect/test/codegen/glob-002d.c b/creflect/test/codegen/glob-002d.c
--- a/creflect/test/codegen/glob-002d.c
+++ b/creflect/test/codegen/glob-002d.c
@@ -9,8 +9,8 @@
int **p1 = &someglob; /* check that 'someglob' is of type 'int *' */
(void)p1;
t1 = cb->get_signed_type(cb, sizeof(int), "int");
- t2 = cb->get_pointer_type(cb, t1);
- cb->define_var(cb, "someglob", t2, &someglob);
+ t2 = cb->get_pointer_type(cb, t1, 0);
+ cb->define_var(cb, "someglob", t2, 0, &someglob);
#expect VAR someglob: PTR int
}
}
diff --git a/creflect/test/codegen/glob-004.c b/creflect/test/codegen/glob-004.c
--- a/creflect/test/codegen/glob-004.c
+++ b/creflect/test/codegen/glob-004.c
@@ -18,8 +18,8 @@
a3[0] = t2;
a3[1] = t2;
t4 = cb->get_function_type(cb, t1, a3, 2, &testglob_004__f1);
- t5 = cb->get_pointer_type(cb, t4);
- cb->define_var(cb, "someglob", t5, &someglob);
+ t5 = cb->get_pointer_type(cb, t4, 0);
+ cb->define_var(cb, "someglob", t5, 0, &someglob);
#expect VAR someglob: PTR FUNC( long -> long -> int )
}
}
diff --git a/creflect/test/codegen/glob-005.c b/creflect/test/codegen/glob-005.c
--- a/creflect/test/codegen/glob-005.c
+++ b/creflect/test/codegen/glob-005.c
@@ -13,15 +13,16 @@
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);
+ t2 = cb->get_pointer_type(cb, t1, 0);
+ cb->define_type(cb, "mytype_t", t2, 0);
#expect TYPEDEF mytype_t = PTR void
}
{
mytype_t *p1 = &foobar; /* check that 'foobar' is of type 'mytype_t' */
+ int q1 = 0;
(void)p1;
- t3 = cb->get_user_type(cb, "mytype_t");
- cb->define_var(cb, "foobar", t3, &foobar);
+ t3 = cb->get_user_type(cb, "mytype_t", &q1);
+ cb->define_var(cb, "foobar", t3, q1, &foobar);
#expect VAR foobar: mytype_t
}
}
diff --git a/creflect/test/codegen/struct-001.c b/creflect/test/codegen/struct-001.c
--- a/creflect/test/codegen/struct-001.c
+++ b/creflect/test/codegen/struct-001.c
@@ -20,6 +20,7 @@
t2 = _CRX_INT_TYPE(cb, p1->aa, "int");
d1[0].name = "aa";
d1[0].type = t2;
+ d1[0].qualifiers = 0;
d1[0].offset = o;
d1[0].numbits = -1;
d1[0].bitshift = -1;
@@ -34,6 +35,7 @@
t3 = _CRX_INT_TYPE(cb, p1->bb, "int");
d1[1].name = "bb";
d1[1].type = t3;
+ d1[1].qualifiers = 0;
d1[1].offset = o;
d1[1].numbits = -1;
d1[1].bitshift = -1;
diff --git a/creflect/test/codegen/struct-001b.c b/creflect/test/codegen/struct-001b.c
--- a/creflect/test/codegen/struct-001b.c
+++ b/creflect/test/codegen/struct-001b.c
@@ -6,7 +6,7 @@
void teststruct_001b(_crx_builder_t *cb)
{
- _crx_type_t *t1, *t2, *t3;
+ _crx_type_t *t1, *t2;
_crx_field_t d1[1];
t1 = cb->get_struct_type(cb, "foo_s");
{
@@ -17,9 +17,9 @@
p1 = (void *)(((char *)b) - o);
(void)(p1->aa << 1); /* check that 'struct foo_s::aa' is an integer type */
t2 = _CRX_INT_TYPE(cb, p1->aa, "int");
- t3 = cb->get_const_type(cb, t2);
d1[0].name = "aa";
- d1[0].type = t3;
+ d1[0].type = t2;
+ d1[0].qualifiers = _CRX_CONST;
d1[0].offset = o;
d1[0].numbits = -1;
d1[0].bitshift = -1;
diff --git a/creflect/test/codegen/struct-002.c b/creflect/test/codegen/struct-002.c
--- a/creflect/test/codegen/struct-002.c
+++ b/creflect/test/codegen/struct-002.c
@@ -16,9 +16,10 @@
p1 = (void *)(((char *)&p2) - o);
p1->aa = (void *)0; /* check that 'struct foo_s::aa' is a pointer type */
t2 = cb->get_void_type(cb);
- t3 = cb->get_pointer_type(cb, t2);
+ t3 = cb->get_pointer_type(cb, t2, 0);
d1[0].name = "aa";
d1[0].type = t3;
+ d1[0].qualifiers = 0;
d1[0].offset = o;
d1[0].numbits = -1;
d1[0].bitshift = -1;
diff --git a/creflect/test/codegen/struct-003.c b/creflect/test/codegen/struct-003.c
--- a/creflect/test/codegen/struct-003.c
+++ b/creflect/test/codegen/struct-003.c
@@ -19,9 +19,10 @@
(void)(*p1->aa << 1); /* check that '*struct foo_s::aa' is an integer type */
*p1->aa = -1; /* check that '*struct foo_s::aa' is not declared 'const' */
t2 = _CRX_INT_TYPE(cb, *p1->aa, "int");
- t3 = cb->get_pointer_type(cb, t2);
+ t3 = cb->get_pointer_type(cb, t2, 0);
d1[0].name = "aa";
d1[0].type = t3;
+ d1[0].qualifiers = 0;
d1[0].offset = o;
d1[0].numbits = -1;
d1[0].bitshift = -1;
diff --git a/creflect/test/codegen/struct-004.c b/creflect/test/codegen/struct-004.c
--- a/creflect/test/codegen/struct-004.c
+++ b/creflect/test/codegen/struct-004.c
@@ -24,6 +24,7 @@
t3 = cb->get_array_type(cb, t2, sizeof(p1->aa) / sizeof(*p1->aa));
d1[0].name = "aa";
d1[0].type = t3;
+ d1[0].qualifiers = 0;
d1[0].offset = o;
d1[0].numbits = -1;
d1[0].bitshift = -1;
diff --git a/creflect/test/codegen/struct-005.c b/creflect/test/codegen/struct-005.c
--- a/creflect/test/codegen/struct-005.c
+++ b/creflect/test/codegen/struct-005.c
@@ -17,6 +17,7 @@
t2 = _CRX_INT_TYPE(cb, p1->aa, "int");
d1[0].name = "aa";
d1[0].type = t2;
+ d1[0].qualifiers = 0;
d1[0].offset = o;
d1[0].numbits = -1;
d1[0].bitshift = -1;
@@ -27,7 +28,7 @@
#expect STRUCT $foo_t:
#expect | aa: int
{
- cb->define_type(cb, "foo_t", t1);
+ cb->define_type(cb, "foo_t", t1, 0);
#expect TYPEDEF foo_t = STRUCT $foo_t
}
}
diff --git a/creflect/test/codegen/struct-005b.c b/creflect/test/codegen/struct-005b.c
--- a/creflect/test/codegen/struct-005b.c
+++ b/creflect/test/codegen/struct-005b.c
@@ -17,6 +17,7 @@
t2 = _CRX_INT_TYPE(cb, p1->aa, "int");
d1[0].name = "aa";
d1[0].type = t2;
+ d1[0].qualifiers = 0;
d1[0].offset = o;
d1[0].numbits = -1;
d1[0].bitshift = -1;
@@ -31,8 +32,8 @@
char *p2;
p1 = (void *)&p2;
*p1 = (void *)0; /* check that 'foo_p' is a pointer type */
- t3 = cb->get_pointer_type(cb, t1);
- cb->define_type(cb, "foo_p", t3);
+ t3 = cb->get_pointer_type(cb, t1, 0);
+ cb->define_type(cb, "foo_p", t3, 0);
#expect TYPEDEF foo_p = PTR STRUCT $$foo_p
}
}
diff --git a/creflect/test/codegen/struct-006.c b/creflect/test/codegen/struct-006.c
--- a/creflect/test/codegen/struct-006.c
+++ b/creflect/test/codegen/struct-006.c
@@ -11,7 +11,7 @@
NULL, 0);
#expect STRUCT $foo_t:
{
- cb->define_type(cb, "foo_t", t1);
+ cb->define_type(cb, "foo_t", t1, 0);
#expect TYPEDEF foo_t = STRUCT $foo_t
}
}
diff --git a/creflect/test/test_cparser.py b/creflect/test/test_cparser.py
--- a/creflect/test/test_cparser.py
+++ b/creflect/test/test_cparser.py
@@ -1,6 +1,7 @@
import py
from cStringIO import StringIO
from creflect.cparser import CSource, remove_comments, CDefError
+from creflect.model import TypeDefDecl, VarDecl
def test_remove_comments():
@@ -41,3 +42,46 @@
TypeDecl: f, []
IdentifierType: ['unsigned', 'long']
"""
+
+def get_c_name(csrc):
+ csource = CSource("typedef %s;" % (csrc,))
+ typedefdecl = csource.get_declarations()[-1]
+ assert isinstance(typedefdecl, TypeDefDecl)
+ return typedefdecl.qualtype.get_c_name('x')
+
+def get_decl_name(csrc):
+ csource = CSource("%s;" % (csrc,))
+ vardecl = csource.get_declarations()[-1]
+ assert isinstance(vardecl, VarDecl) # or subclass FuncDecl or ConstDecl
+ return vardecl.qualtype.get_c_name('x')
+
+def test_c_name():
+ assert get_c_name('long int x') == 'long x'
+ assert get_c_name('int***x') == 'int ***x'
+ assert get_c_name('const int x') == 'int const x'
+ assert get_c_name('int(x[5])') == 'int x[5]'
+ assert get_c_name('int(*x[5])') == 'int *x[5]'
+ assert get_c_name('int(*x)[5]') == 'int (*x)[5]'
+ assert get_c_name('const int *x[5]') == 'int const *x[5]'
+ assert get_c_name('int *const x[5]') == 'int *const x[5]'
+ assert get_c_name('int (*const x)[5]') == 'int (*const x)[5]'
+ assert get_c_name('const int(*x)[5]') == 'int const (*x)[5]'
+ #
+ assert get_c_name('const int x[5]') == 'int const x[5]'
+ assert get_c_name('void* x') == 'void *x'
+ assert get_c_name('int x(long,...)') == 'int x(long, ...)'
+ assert get_c_name('const int x(long,...)') == 'int x(long, ...)' # ignored
+ assert get_c_name('int *(x(long,...))') == 'int *x(long, ...)'
+ assert get_c_name('int (*x)(long,...)') == 'int (*x)(long, ...)'
+ assert get_c_name('const int *x') == 'int const *x'
+ assert get_c_name('int * const x') == 'int *const x'
+ #
+ # hacks to declare two types
+ assert get_c_name('int tt; typedef tt x') == 'tt x'
+ assert get_c_name('int tt; typedef const tt x') == 'tt const x'
+ assert get_c_name('const __crx_unknown_t *x') == '... const *x'
+
+def test_decl_name():
+ assert get_decl_name('int x') == 'int x'
+ assert get_decl_name('const int x') == 'int const x'
+ assert get_decl_name('int x(long)') == 'int x(long)'
diff --git a/setup.py b/setup.py
new file mode 100644
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,10 @@
+from distutils.core import setup
+from distutils.extension import Extension
+
+setup(
+ ext_modules=[
+ Extension(name = 'zeffir',
+ sources=['zeffir/zeffir.c',
+ 'creflect/creflect_cdecl.c'],
+ )
+ ])
diff --git a/zeffir/zef_builder.c b/zeffir/zef_builder.c
--- a/zeffir/zef_builder.c
+++ b/zeffir/zef_builder.c
@@ -165,10 +165,12 @@
}
static void zef_define_num_const(_crx_builder_t *cb, const char *name,
- _crx_type_t *t, _crx_num_const_t *value)
+ _crx_type_t *ct, _crx_num_const_t *value)
{
PyObject *dict = ((zeffir_builder_t *)cb)->dict;
+ assert(ct->ct_flags & CT_PRIMITIVE_ANY);
+
PyObject *x = PyInt_FromLong(value->as_int);
if (x == NULL)
return;
More information about the pypy-commit
mailing list