[pypy-commit] creflect default: Const pointers
arigo
noreply at buildbot.pypy.org
Tue Sep 16 09:13:38 CEST 2014
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r41:a913f8ec3a30
Date: 2014-09-16 09:13 +0200
http://bitbucket.org/cffi/creflect/changeset/a913f8ec3a30/
Log: Const pointers
diff --git a/creflect/cparser.py b/creflect/cparser.py
--- a/creflect/cparser.py
+++ b/creflect/cparser.py
@@ -136,10 +136,10 @@
realtype = self._get_type(decl.type, name=decl.name)
self.declarations.append(model.TypeDef(decl.name, realtype))
- def _get_type_pointer(self, type):
+ def _get_type_pointer(self, type, const):
if isinstance(type, model.RawFunctionType):
return type.as_function_pointer()
- return model.PointerType(type)
+ return model.PointerType(type, const)
def _get_type(self, typenode, name=None, partial_length_ok=False):
# first, dereference typedefs, if we have it already parsed, we're good
@@ -162,7 +162,8 @@
#
if isinstance(typenode, pycparser.c_ast.PtrDecl):
# pointer type
- return self._get_type_pointer(self._get_type(typenode.type))
+ const = 'const' in typenode.quals
+ return self._get_type_pointer(self._get_type(typenode.type), const)
#
if isinstance(typenode, pycparser.c_ast.TypeDecl):
const = 'const' in typenode.quals
diff --git a/creflect/model.py b/creflect/model.py
--- a/creflect/model.py
+++ b/creflect/model.py
@@ -150,16 +150,18 @@
class PointerType(BaseType):
_attrs_ = ('totype',)
- _base_pattern = "*&"
- _base_pattern_array = "(*&)"
+ _base_pattern = {
+ (False, False): "*&",
+ (True, False): "(*&)",
+ (False, True): "*const &",
+ (True, True): "(*const &)",
+ }
- def __init__(self, totype):
+ def __init__(self, totype, const):
self.totype = totype
+ self.const = const
base = self.totype.c_name_with_marker
- if self.totype.is_array_type:
- extra = self._base_pattern_array
- else:
- extra = self._base_pattern
+ extra = self._base_pattern[self.totype.is_array_type, self.const]
self.c_name_with_marker = base.replace('&', extra)
def inspect_type(self, block, inspect):
@@ -167,12 +169,28 @@
new_var = 'p%d' % (len(inspect.levels) + 2,)
block.writedecl("char *%s;" % (new_var,))
inspect.assign_to_p1("&%s" % (new_var,))
+ #
+ if self.const:
+ errmsg = "type '%s' is not a pointer, but an array type" % (
+ inspect.get_comment_type(0, False),)
+ inspect.assign_target = new_var
+ def after():
+ ampersand_star_p1 = '&' + star_p1
+ if ampersand_star_p1.startswith('&*'):
+ ampersand_star_p1 = ampersand_star_p1[2:]
+ block.writeline("if ((void *)%s == (void *)%s) {" % (
+ ampersand_star_p1, star_p1))
+ block.writeline(" r = r0;")
+ block.sprintf(r"#error %s\n" % errmsg, indent=4)
+ block.tr.need_return_value()
+ block.writeline(" r1 = -1;")
+ block.writeline(" goto %s;" % block.get_skip_label())
+ block.writeline("}")
+ inspect.after_star_p1_assignment.append(after)
inspect.levels.append('*')
self.totype.inspect_type(block, inspect)
- if self.totype.is_array_type:
- extra = self._base_pattern_array
- else:
- extra = self._base_pattern
+ #
+ extra = self._base_pattern[self.totype.is_array_type, self.const]
block.sprintf_add_both_sides(extra)
@@ -292,6 +310,7 @@
self.started = True
self.after_star_p1_assignment = []
self.at_end = []
+ self.assign_target = None
def get_comment_type(self, levels_delta, ignore_array, minlevel=0):
end = len(self.levels)
@@ -333,20 +352,25 @@
return star_p1
def assign_to_p1(self, expr):
- length = len(self.levels)
- while length > 0 and self.levels[length - 1] == '[]':
- length -= 1
- comment = self.get_comment(-1, True, "a pointer type")
- spaces = comment and (' ' * (3 - len(expr)))
+ if self.assign_target is None:
+ length = len(self.levels)
+ while length > 0 and self.levels[length - 1] == '[]':
+ length -= 1
+ comment = self.get_comment(-1, True, "a pointer type")
+ spaces = comment and (' ' * (3 - len(expr)))
+ self.assign_target = '%sp1' % ('*' * length,)
+ else:
+ spaces = comment = ''
if self.structfield is None:
- line = '%sp1 = (void *)%s;%s%s' % ('*' * length, expr, spaces,
- comment)
+ line = '%s = (void *)%s;%s%s' % (self.assign_target, expr, spaces,
+ comment)
else:
if length > 0:
line = '%sp1->%s = (void *)%s;%s%s' % (
'*' * (length - 1), self.structfield, expr, spaces, comment)
else:
line = 'p1 = (void *)(((char *)%s) - (long)o);' % (expr,)
+ self.assign_target = None
self.block.writeline(line.rstrip())
for fn in self.after_star_p1_assignment:
fn()
diff --git a/test/codegen/006b.c b/test/codegen/006b.c
new file mode 100644
--- /dev/null
+++ b/test/codegen/006b.c
@@ -0,0 +1,60 @@
+typedef int *const num_t;
+
+# ____________________________________________________________
+
+int test006b(char *r)
+{
+ int r1 = 0;
+ if (!r)
+ return 57 + 8 + 18 + 16;
+ {
+ num_t *p1;
+ char *p2;
+ char b[sizeof(**p1)]; /* check that '*num_t' is a valid type */
+ char *r0 = r;
+ p1 = (void *)&p2;
+ p2 = (void *)b;
+ if ((void *)p1 == (void *)*p1) {
+ r = r0;
+ r += sprintf(r, "#error type 'num_t' is not a pointer, but an array type\n");
+ r1 = -1;
+ goto f2;
+ }
+ (void)(**p1 << 1); /* check that '*num_t' is an integer type */
+ r += sprintf(r, "typedef ");
+ **p1 = -1; /* check that '*num_t' is not declared 'const' */
+ if (**p1 > 0) {
+ if (sizeof(**p1) == 1 && **p1 == 1)
+ r += sprintf(r, "_Bool");
+ else if (sizeof(**p1) == sizeof(unsigned int))
+ r += sprintf(r, "unsigned int");
+ else if (sizeof(**p1) == sizeof(unsigned short))
+ r += sprintf(r, "unsigned short");
+ else if (sizeof(**p1) == sizeof(unsigned char))
+ r += sprintf(r, "unsigned char");
+ else if (sizeof(**p1) == sizeof(unsigned long))
+ r += sprintf(r, "unsigned long");
+ else if (sizeof(**p1) == sizeof(unsigned long long))
+ r += sprintf(r, "unsigned long long");
+ else
+ r += sprintf(r, "uint%u_t", (int)sizeof(**p1) * 8);
+ }
+ else {
+ if (sizeof(**p1) == sizeof(int))
+ r += sprintf(r, "int");
+ else if (sizeof(**p1) == sizeof(short))
+ r += sprintf(r, "short");
+ else if (sizeof(**p1) == sizeof(signed char))
+ r += sprintf(r, "signed char");
+ else if (sizeof(**p1) == sizeof(long))
+ r += sprintf(r, "long");
+ else if (sizeof(**p1) == sizeof(long long))
+ r += sprintf(r, "long long");
+ else
+ r += sprintf(r, "int%u_t", (int)sizeof(**p1) * 8);
+ }
+ r += sprintf(r, " *const num_t;\n");
+ f2:;
+ }
+ return r1;
+}
diff --git a/test/codegen/006c.c b/test/codegen/006c.c
new file mode 100644
--- /dev/null
+++ b/test/codegen/006c.c
@@ -0,0 +1,66 @@
+typedef int (*const foo_t)[27];
+
+# ____________________________________________________________
+
+int test006c(char *r)
+{
+ int r1 = 0;
+ if (!r)
+ return 57 + 58 + 8 + 18 + 44;
+ {
+ foo_t *p1;
+ char *p2;
+ char b[sizeof(***p1)]; /* check that '(*foo_t)[]' is a valid type */
+ char *r0 = r;
+ p1 = (void *)&p2;
+ p2 = (void *)b;
+ if ((void *)p1 == (void *)*p1) {
+ r = r0;
+ r += sprintf(r, "#error type 'foo_t' is not a pointer, but an array type\n");
+ r1 = -1;
+ goto f2;
+ }
+ if ((void *)*p1 != (void *)**p1) {
+ r = r0;
+ r += sprintf(r, "#error type '*foo_t' is not an array, but a pointer type\n");
+ r1 = -1;
+ goto f2;
+ }
+ (void)(***p1 << 1); /* check that '(*foo_t)[]' is an integer type */
+ r += sprintf(r, "typedef ");
+ ***p1 = -1; /* check that '(*foo_t)[]' is not declared 'const' */
+ if (***p1 > 0) {
+ if (sizeof(***p1) == 1 && ***p1 == 1)
+ r += sprintf(r, "_Bool");
+ else if (sizeof(***p1) == sizeof(unsigned int))
+ r += sprintf(r, "unsigned int");
+ else if (sizeof(***p1) == sizeof(unsigned short))
+ r += sprintf(r, "unsigned short");
+ else if (sizeof(***p1) == sizeof(unsigned char))
+ r += sprintf(r, "unsigned char");
+ else if (sizeof(***p1) == sizeof(unsigned long))
+ r += sprintf(r, "unsigned long");
+ else if (sizeof(***p1) == sizeof(unsigned long long))
+ r += sprintf(r, "unsigned long long");
+ else
+ r += sprintf(r, "uint%u_t", (int)sizeof(***p1) * 8);
+ }
+ else {
+ if (sizeof(***p1) == sizeof(int))
+ r += sprintf(r, "int");
+ else if (sizeof(***p1) == sizeof(short))
+ r += sprintf(r, "short");
+ else if (sizeof(***p1) == sizeof(signed char))
+ r += sprintf(r, "signed char");
+ else if (sizeof(***p1) == sizeof(long))
+ r += sprintf(r, "long");
+ else if (sizeof(***p1) == sizeof(long long))
+ r += sprintf(r, "long long");
+ else
+ r += sprintf(r, "int%u_t", (int)sizeof(***p1) * 8);
+ }
+ r += sprintf(r, " (*const foo_t)[%lld];\n", (long long)(sizeof(**p1) / sizeof(***p1)));
+ f2:;
+ }
+ return r1;
+}
More information about the pypy-commit
mailing list