[pypy-commit] creflect default: Start support for 'const'
arigo
noreply at buildbot.pypy.org
Mon Sep 15 20:28:13 CEST 2014
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r40:604ad41bc138
Date: 2014-09-15 20:27 +0200
http://bitbucket.org/cffi/creflect/changeset/604ad41bc138/
Log: Start support for 'const'
diff --git a/creflect/codegen.py b/creflect/codegen.py
--- a/creflect/codegen.py
+++ b/creflect/codegen.py
@@ -145,7 +145,7 @@
#
if outerblock.includes:
extra = ['#include <%s>' % includename
- for includename in self.includes]
+ for includename in outerblock.includes]
extra.append('')
else:
extra = []
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):
+def resolve_common_type(names, const):
# reduce synonyms to a single chosen combination
names = list(names)
if names != ['signed', 'char']: # keep this unmodified
@@ -44,8 +44,11 @@
names = newnames + names
ident = ' '.join(names)
if ident == 'void':
- return model.void_type
+ if const:
+ return model.const_void_type
+ else:
+ return model.void_type
if ident == '__dotdotdot__': # XXX
raise api.FFIError(':%d: bad usage of "..."' %
typenode.coord.line)
- return model.PrimitiveType(ident)
+ return model.PrimitiveType(ident, const)
diff --git a/creflect/cparser.py b/creflect/cparser.py
--- a/creflect/cparser.py
+++ b/creflect/cparser.py
@@ -136,11 +136,9 @@
realtype = self._get_type(decl.type, name=decl.name)
self.declarations.append(model.TypeDef(decl.name, realtype))
- def _get_type_pointer(self, type, const=False):
+ def _get_type_pointer(self, type):
if isinstance(type, model.RawFunctionType):
return type.as_function_pointer()
- if const:
- return model.ConstPointerType(type)
return model.PointerType(type)
def _get_type(self, typenode, name=None, partial_length_ok=False):
@@ -164,15 +162,14 @@
#
if isinstance(typenode, pycparser.c_ast.PtrDecl):
# pointer type
- const = (isinstance(typenode.type, pycparser.c_ast.TypeDecl)
- and 'const' in typenode.type.quals)
- return self._get_type_pointer(self._get_type(typenode.type), const)
+ return self._get_type_pointer(self._get_type(typenode.type))
#
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)
+ return resolve_common_type(type.names, const)
#
if isinstance(type, pycparser.c_ast.Struct):
# 'struct foobar'
diff --git a/creflect/model.py b/creflect/model.py
--- a/creflect/model.py
+++ b/creflect/model.py
@@ -11,7 +11,8 @@
return '<%s>' % (self._get_c_name(),)
def _get_items(self):
- return [(name, getattr(self, name)) for name in self._attrs_]
+ return [(name, getattr(self, name))
+ for name in (self._attrs_ + 'const')]
def inspect_type(self, block, inspect):
block.sprintf_add_both_sides(self.c_name_with_marker)
@@ -32,14 +33,20 @@
class VoidType(BaseType):
_attrs_ = ()
- c_name_with_marker = 'void &'
+
+ def __init__(self, const):
+ self.const = const
+ self.c_name_with_marker = 'void &'
+ if const:
+ self.c_name_with_marker = 'const ' + self.c_name_with_marker
def inspect_type(self, block, inspect):
if inspect.started:
inspect.assign_to_p1('0')
BaseType.inspect_type(self, block, inspect)
-void_type = VoidType()
+void_type = VoidType(const=False)
+const_void_type = VoidType(const=True)
class PrimitiveType(BaseType):
@@ -63,10 +70,13 @@
'_Bool': 'i',
}
- def __init__(self, name):
+ def __init__(self, name, const):
assert name in self.ALL_PRIMITIVE_TYPES
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'
@@ -79,11 +89,18 @@
star_p1 = inspect.fetch_star_p1()
comment1 = inspect.get_comment(0, False, "a valid type", minlevel=1)
comment2 = inspect.get_comment(0, False, "an integer type")
+ comment3 = inspect.get_comment(0, False, "not declared 'const'")
block.writedecl("char b[sizeof(%s)];%s" % (star_p1, comment1))
inspect.assign_to_p1("b")
block.writeline("(void)(%s << 1);%s" % (star_p1, comment2))
+ if self.const:
+ block.sprintf_add_left("const ")
disjunction = block.flushleft()
- block.writeline("%s = -1;" % (star_p1,))
+ if self.const:
+ block.add_include("string.h")
+ block.writeline("memset(b, -1, sizeof(b));")
+ else:
+ block.writeline("%s = -1;%s" % (star_p1, comment3))
block.writeline("if (%s > 0) {" % (star_p1,))
block.writeline(" if (sizeof(%s) == 1 && %s == 1)" %
(star_p1, star_p1))
diff --git a/test/codegen/002c.c b/test/codegen/002c.c
new file mode 100644
--- /dev/null
+++ b/test/codegen/002c.c
@@ -0,0 +1,17 @@
+typedef const void *num_t;
+
+# ____________________________________________________________
+
+int test002c(char *r)
+{
+ if (!r)
+ return 28;
+ {
+ num_t *p1;
+ char *p2;
+ p1 = (void *)&p2;
+ *p1 = (void *)0; /* check that 'num_t' is a pointer type */
+ r += sprintf(r, "typedef const void *num_t;\n");
+ }
+ return 0;
+}
diff --git a/test/codegen/003.c b/test/codegen/003.c
--- a/test/codegen/003.c
+++ b/test/codegen/003.c
@@ -12,7 +12,7 @@
p1 = (void *)b;
(void)(*p1 << 1); /* check that 'num_t' is an integer type */
r += sprintf(r, "typedef ");
- *p1 = -1;
+ *p1 = -1; /* check that 'num_t' is not declared 'const' */
if (*p1 > 0) {
if (sizeof(*p1) == 1 && *p1 == 1)
r += sprintf(r, "_Bool");
diff --git a/test/codegen/003b.c b/test/codegen/003b.c
--- a/test/codegen/003b.c
+++ b/test/codegen/003b.c
@@ -12,7 +12,7 @@
p1 = (void *)b;
(void)(*p1 << 1); /* check that 'num_t' is an integer type */
r += sprintf(r, "typedef ");
- *p1 = -1;
+ *p1 = -1; /* check that 'num_t' is not declared 'const' */
if (*p1 > 0) {
if (sizeof(*p1) == 1 && *p1 == 1)
r += sprintf(r, "_Bool");
diff --git a/test/codegen/003c.c b/test/codegen/003c.c
--- a/test/codegen/003c.c
+++ b/test/codegen/003c.c
@@ -12,7 +12,7 @@
p1 = (void *)b;
(void)(*p1 << 1); /* check that 'num_t' is an integer type */
r += sprintf(r, "typedef ");
- *p1 = -1;
+ *p1 = -1; /* check that 'num_t' is not declared 'const' */
if (*p1 > 0) {
if (sizeof(*p1) == 1 && *p1 == 1)
r += sprintf(r, "_Bool");
diff --git a/test/codegen/003d.c b/test/codegen/003d.c
--- a/test/codegen/003d.c
+++ b/test/codegen/003d.c
@@ -12,7 +12,7 @@
p1 = (void *)b;
(void)(*p1 << 1); /* check that 'num_t' is an integer type */
r += sprintf(r, "typedef ");
- *p1 = -1;
+ *p1 = -1; /* check that 'num_t' is not declared 'const' */
if (*p1 > 0) {
if (sizeof(*p1) == 1 && *p1 == 1)
r += sprintf(r, "_Bool");
diff --git a/test/codegen/003e.c b/test/codegen/003e.c
--- a/test/codegen/003e.c
+++ b/test/codegen/003e.c
@@ -12,7 +12,7 @@
p1 = (void *)b;
(void)(*p1 << 1); /* check that 'num_t' is an integer type */
r += sprintf(r, "typedef ");
- *p1 = -1;
+ *p1 = -1; /* check that 'num_t' is not declared 'const' */
if (*p1 > 0) {
if (sizeof(*p1) == 1 && *p1 == 1)
r += sprintf(r, "_Bool");
diff --git a/test/codegen/003f.c b/test/codegen/003f.c
--- a/test/codegen/003f.c
+++ b/test/codegen/003f.c
@@ -12,7 +12,7 @@
p1 = (void *)b;
(void)(*p1 << 1); /* check that 'num_t' is an integer type */
r += sprintf(r, "typedef ");
- *p1 = -1;
+ *p1 = -1; /* check that 'num_t' is not declared 'const' */
if (*p1 > 0) {
if (sizeof(*p1) == 1 && *p1 == 1)
r += sprintf(r, "_Bool");
diff --git a/test/codegen/004.c b/test/codegen/004.c
--- a/test/codegen/004.c
+++ b/test/codegen/004.c
@@ -14,7 +14,7 @@
*p1 = (void *)b; /* check that 'num_t' is a pointer type */
(void)(**p1 << 1); /* check that '*num_t' is an integer type */
r += sprintf(r, "typedef ");
- **p1 = -1;
+ **p1 = -1; /* check that '*num_t' is not declared 'const' */
if (**p1 > 0) {
if (sizeof(**p1) == 1 && **p1 == 1)
r += sprintf(r, "_Bool");
diff --git a/test/codegen/004b.c b/test/codegen/004b.c
--- a/test/codegen/004b.c
+++ b/test/codegen/004b.c
@@ -16,7 +16,7 @@
**p1 = (void *)b; /* check that '*num_t' is a pointer type */
(void)(***p1 << 1); /* check that '**num_t' is an integer type */
r += sprintf(r, "typedef ");
- ***p1 = -1;
+ ***p1 = -1; /* check that '**num_t' is not declared 'const' */
if (***p1 > 0) {
if (sizeof(***p1) == 1 && ***p1 == 1)
r += sprintf(r, "_Bool");
diff --git a/test/codegen/005.c b/test/codegen/005.c
--- a/test/codegen/005.c
+++ b/test/codegen/005.c
@@ -20,7 +20,7 @@
}
(void)(**p1 << 1); /* check that 'foo_t[]' is an integer type */
r += sprintf(r, "typedef ");
- **p1 = -1;
+ **p1 = -1; /* check that 'foo_t[]' is not declared 'const' */
if (**p1 > 0) {
if (sizeof(**p1) == 1 && **p1 == 1)
r += sprintf(r, "_Bool");
diff --git a/test/codegen/005b.c b/test/codegen/005b.c
--- a/test/codegen/005b.c
+++ b/test/codegen/005b.c
@@ -22,7 +22,7 @@
**p1 = (void *)b; /* check that 'foo_t[]' is a pointer type */
(void)(***p1 << 1); /* check that '*foo_t[]' is an integer type */
r += sprintf(r, "typedef ");
- ***p1 = -1;
+ ***p1 = -1; /* check that '*foo_t[]' is not declared 'const' */
if (***p1 > 0) {
if (sizeof(***p1) == 1 && ***p1 == 1)
r += sprintf(r, "_Bool");
diff --git a/test/codegen/005c.c b/test/codegen/005c.c
--- a/test/codegen/005c.c
+++ b/test/codegen/005c.c
@@ -22,7 +22,7 @@
}
(void)(***p1 << 1); /* check that '(*foo_t)[]' is an integer type */
r += sprintf(r, "typedef ");
- ***p1 = -1;
+ ***p1 = -1; /* check that '(*foo_t)[]' is not declared 'const' */
if (***p1 > 0) {
if (sizeof(***p1) == 1 && ***p1 == 1)
r += sprintf(r, "_Bool");
diff --git a/test/codegen/005d.c b/test/codegen/005d.c
--- a/test/codegen/005d.c
+++ b/test/codegen/005d.c
@@ -48,7 +48,7 @@
*********p1 = (void *)b; /* check that '*(***foo_t[][])[][]' is a pointer type */
(void)(**********p1 << 1); /* check that '**(***foo_t[][])[][]' is an integer type */
r += sprintf(r, "typedef ");
- **********p1 = -1;
+ **********p1 = -1; /* check that '**(***foo_t[][])[][]' is not declared 'const' */
if (**********p1 > 0) {
if (sizeof(**********p1) == 1 && **********p1 == 1)
r += sprintf(r, "_Bool");
diff --git a/test/codegen/005e.c b/test/codegen/005e.c
--- a/test/codegen/005e.c
+++ b/test/codegen/005e.c
@@ -21,7 +21,7 @@
}
(void)(**p1 << 1); /* check that 'foo_t[]' is an integer type */
r += sprintf(r, "typedef ");
- **p1 = -1;
+ **p1 = -1; /* check that 'foo_t[]' is not declared 'const' */
if (**p1 > 0) {
if (sizeof(**p1) == 1 && **p1 == 1)
r += sprintf(r, "_Bool");
@@ -68,7 +68,7 @@
}
(void)(**p1 << 1); /* check that 'bar_t[]' is an integer type */
r += sprintf(r, "typedef ");
- **p1 = -1;
+ **p1 = -1; /* check that 'bar_t[]' is not declared 'const' */
if (**p1 > 0) {
if (sizeof(**p1) == 1 && **p1 == 1)
r += sprintf(r, "_Bool");
diff --git a/test/codegen/006.c b/test/codegen/006.c
new file mode 100644
--- /dev/null
+++ b/test/codegen/006.c
@@ -0,0 +1,50 @@
+typedef const unsigned int num_t;
+
+# ____________________________________________________________
+#include <string.h>
+
+int test006(char *r)
+{
+ if (!r)
+ return 14 + 18 + 9;
+ {
+ num_t *p1;
+ char b[sizeof(*p1)];
+ p1 = (void *)b;
+ (void)(*p1 << 1); /* check that 'num_t' is an integer type */
+ r += sprintf(r, "typedef const ");
+ memset(b, -1, sizeof(b));
+ 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, " num_t;\n");
+ }
+ return 0;
+}
More information about the pypy-commit
mailing list