[pypy-commit] creflect default: Allow multiple declarations of a function with the same name.
arigo
noreply at buildbot.pypy.org
Fri Dec 12 12:47:30 CET 2014
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r198:1676e7d1646f
Date: 2014-12-12 11:47 +0000
http://bitbucket.org/cffi/creflect/changeset/1676e7d1646f/
Log: Allow multiple declarations of a function with the same name.
diff --git a/creflect/codegen.py b/creflect/codegen.py
--- a/creflect/codegen.py
+++ b/creflect/codegen.py
@@ -65,6 +65,7 @@
outerblock = CodeBlock(parent=None)
outerblock.writeline('#include "creflect.h"')
outerblock.crx_func_name = crx_func_name
+ outerblock.func_names_seen = set()
funcblock = CodeBlock(outerblock)
diff --git a/creflect/model.py b/creflect/model.py
--- a/creflect/model.py
+++ b/creflect/model.py
@@ -348,7 +348,7 @@
def shadow_global_var(self, top_level_block, fnname):
if self.ellipsis:
return fnname
- shadowname = '%s__d_%s' % (top_level_block.crx_func_name, fnname)
+ shadowname = _unique_name(top_level_block, '%s__d%s_%s', fnname)
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')
@@ -365,7 +365,7 @@
# a special-case for global function declarations
assert not self.ellipsis
toplevel = block.crx_top_level
- crx_func_name = '%s__c_%s' % (toplevel.crx_func_name, fnname)
+ crx_func_name = _unique_name(toplevel, '%s__c%s_%s', fnname)
wrline = toplevel.writeline
wrline('static void %s(void *args[], void *result) {' % (
crx_func_name,))
@@ -378,6 +378,16 @@
fnname, t1, a2, len(self.args), crx_func_name, shadow))
+def _unique_name(toplevel, pattern, fnname):
+ result = pattern % (toplevel.crx_func_name, '', fnname)
+ n = 0
+ while result in toplevel.func_names_seen:
+ n += 1
+ result = pattern % (toplevel.crx_func_name, n, fnname)
+ toplevel.func_names_seen.add(result)
+ return result
+
+
class PointerType(BaseType):
_attrs_ = ('toqualtype',)
diff --git a/creflect/test/codegen/func-006.c b/creflect/test/codegen/func-006.c
new file mode 100644
--- /dev/null
+++ b/creflect/test/codegen/func-006.c
@@ -0,0 +1,51 @@
+/* Multiple declarations of a function with the same name:
+ a way to work around "..." in signatures */
+
+int f(int);
+int f(int, long);
+
+# ____________________________________________________________
+# drop
+
+int f(int a, ...) { return 42 * a; }
+
+# ____________________________________________________________
+
+static void testfunc_006__c_f(void *args[], void *result) {
+ *(int *)result = f(*(int *)args[0]);
+}
+
+static int testfunc_006__d_f(int a0) {
+ return f(a0);
+}
+
+static void testfunc_006__c1_f(void *args[], void *result) {
+ *(int *)result = f(*(int *)args[0], *(long *)args[1]);
+}
+
+static int testfunc_006__d1_f(int a0, long a1) {
+ return f(a0, a1);
+}
+
+void testfunc_006(_crx_builder_t *cb)
+{
+ _crx_type_t *t1, *t2;
+ _crx_qual_type a1[1];
+ _crx_qual_type a2[2];
+ {
+ t1 = cb->get_signed_type(cb, sizeof(int), "int");
+ a1[0].type = t1;
+ a1[0].qualifiers = 0;
+ cb->define_func(cb, "f", t1, a1, 1, &testfunc_006__c_f, &testfunc_006__d_f);
+#expect FUNC f: int -> int
+ }
+ {
+ t2 = cb->get_signed_type(cb, sizeof(long), "long");
+ a2[0].type = t1;
+ a2[0].qualifiers = 0;
+ a2[1].type = t2;
+ a2[1].qualifiers = 0;
+ cb->define_func(cb, "f", t1, a2, 2, &testfunc_006__c1_f, &testfunc_006__d1_f);
+#expect FUNC f: int -> long -> int
+ }
+}
diff --git a/creflect/test/test_cgcompile.py b/creflect/test/test_cgcompile.py
--- a/creflect/test/test_cgcompile.py
+++ b/creflect/test/test_cgcompile.py
@@ -25,11 +25,15 @@
#include "creflect.h"
#include "creflect_debug_print.h"
''')
+ start_pos = f.tell()
for line in inputlines:
if not (line.startswith('# ') or line.startswith('#expect')):
if line.startswith('typedef ...'):
line = 'typedef struct _missing ' + line[11:]
f.write(line)
+ elif line.startswith('# drop'):
+ f.seek(start_pos)
+ f.truncate()
f.write('''
int main(void)
{
@@ -48,13 +52,7 @@
lines = g.readlines()
err = g.close()
assert not err
- if any('/*' in line for line in expected):
- # only remove the comments that are addresses
- r_remove_addr = re.compile(r"/[*]0x[-0-9a-f]+[*]/")
- else:
- # remove the comments that are addresses or sizes
- r_remove_addr = re.compile(r"/[*][-0-9a-fx,]+[*]/")
- got = [r_remove_addr.sub('', line.rstrip()) for line in lines]
+ got = [line.rstrip() for line in lines]
compare_lists(got, expected)
More information about the pypy-commit
mailing list