[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