Fix ctypedef extern class, assignment on declaration, redeclaration warnings
authorRobert Bradshaw <robertwb@math.washington.edu>
Sun, 21 Oct 2007 05:05:04 +0000 (22:05 -0700)
committerRobert Bradshaw <robertwb@math.washington.edu>
Sun, 21 Oct 2007 05:05:04 +0000 (22:05 -0700)
Cython/Compiler/Errors.py
Cython/Compiler/ModuleNode.py
Cython/Compiler/Nodes.py
Cython/Compiler/Parsing.py
Cython/Compiler/Symtab.py

index 6b936b5845d078441de25c538df65fedcd688c33..736d032615eaeb120b0e33042229ba71e7eff183 100644 (file)
@@ -90,7 +90,7 @@ def error(position, message):
 
 LEVEL=1 # warn about all errors level 1 or higher
 
-def warning(position, message, level):
+def warning(position, message, level=0):
     if level < LEVEL:
         return
     warn = CompileWarning(position, message)
index 2de7964688084f2242426ca99f0f2eec933069a8..6d533d408a96a1bcfcd06eaabdfeee53a00c4468 100644 (file)
@@ -1242,45 +1242,45 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         code.putln("%s {" % header)
         code.put_var_declarations(env.temp_entries)
 
-        #code.putln("/*--- Libary function declarations ---*/")
+        code.putln("/*--- Libary function declarations ---*/")
         env.generate_library_function_declarations(code)
         self.generate_filename_init_call(code)
 
-        #code.putln("/*--- Module creation code ---*/")
+        code.putln("/*--- Module creation code ---*/")
         self.generate_module_creation_code(env, code)
 
-        #code.putln("/*--- Intern code ---*/")
+        code.putln("/*--- Intern code ---*/")
         self.generate_intern_code(env, code)
 
-        #code.putln("/*--- String init code ---*/")
+        code.putln("/*--- String init code ---*/")
         self.generate_string_init_code(env, code)
 
-        #code.putln("/*--- Builtin init code ---*/")
-        # FIXME !!
+        code.putln("/*--- Builtin init code ---*/")
+        # TODO: FIXME !!
         #self.generate_builtin_init_code(env, code)
 
-        #code.putln("/*--- Global init code ---*/")
+        code.putln("/*--- Global init code ---*/")
         self.generate_global_init_code(env, code)
 
-        #code.putln("/*--- Module import code ---*/")
+        code.putln("/*--- Module import code ---*/")
         for module in imported_modules:
             self.generate_module_import_code(module, env, code)
         
-        #code.putln("/*--- Function export code ---*/")
+        code.putln("/*--- Function export code ---*/")
         self.generate_c_function_export_code(env, code)
 
-        #code.putln("/*--- Function import code ---*/")
+        code.putln("/*--- Function import code ---*/")
         for module in imported_modules:
             self.generate_c_function_import_code_for_module(module, env, code)
 
-        #code.putln("/*--- Type init code ---*/")
+        code.putln("/*--- Type init code ---*/")
         self.generate_type_init_code(env, code)
 
-        #code.putln("/*--- Type import code ---*/")
+        code.putln("/*--- Type import code ---*/")
         for module in imported_modules:
             self.generate_type_import_code_for_module(module, env, code)
 
-        #code.putln("/*--- Execution code ---*/")
+        code.putln("/*--- Execution code ---*/")
         self.body.generate_execution_code(code)
         code.putln("return;")
         code.put_label(code.error_label)
@@ -1391,6 +1391,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         for entry in module.c_class_entries:
             if entry.defined_in_pxd:
                 import_module = 1
+        print "generate_module_import_code", module, import_module
         if import_module:
             env.use_utility_code(import_module_utility_code)
             name = self.build_module_var_name(module.qualified_name)
index d4df57c764c21792ed5f93bd60fbfc607d605a9f..b6634144d0c6de1e6a769aa9c4522bab009a06e8 100644 (file)
@@ -1500,6 +1500,17 @@ class CClassDefNode(StatNode):
             error(self.pos, "Object struct name specification required for "
                 "C class defined in 'extern from' block")
         self.base_type = None
+        # Now that module imports are cached, we need to 
+        # import the modules for extern classes. 
+        if self.module_name:
+            self.module = None
+            for module in env.cimported_modules:
+                if module.name == self.module_name:
+                    self.module = module
+            if self.module is None:
+                self.module = ModuleScope(self.module_name, None, env.context)
+                env.cimported_modules.append(self.module)
+        print [e.name for e in env.cimported_modules]
         if self.base_class_name:
             if self.base_class_module:
                 base_class_scope = env.find_module(self.base_class_module, self.pos)
@@ -1530,6 +1541,10 @@ class CClassDefNode(StatNode):
             typedef_flag = self.typedef_flag,
             api = self.api)
         scope = self.entry.type.scope
+        
+        if self.module_name:
+            self.entry.defined_in_pxd = 1
+            self.module.c_class_entries.append(self.entry)
 
         if self.doc:
             if Options.embed_pos_in_docstring:
index 4550aa19eaf432d7e433ca886b8923ed58d96daa..b76e520fa642a626441f532ae27c500fe19e46e0 100644 (file)
@@ -1521,7 +1521,7 @@ def p_c_declarator(s, empty = 0, is_type = 0, cmethod_flag = 0, assignable = 0,
             base = Nodes.CNameDeclaratorNode(pos, name = "", cname = None)
             result = p_c_func_declarator(s, pos, base, cmethod_flag)
         else:
-            result = p_c_declarator(s, empty, is_type, cmethod_flag, nonempty,
+            result = p_c_declarator(s, empty, is_type, cmethod_flag, nonempty = nonempty,
                 calling_convention_allowed = 1)
             s.expect(')')
     else:
@@ -1587,14 +1587,14 @@ def p_c_simple_declarator(s, empty, is_type, cmethod_flag, assignable, nonempty)
                 error(s.position(), "Declarator should be empty")
             s.next()
             cname = p_opt_cname(s)
+            if s.sy == '=' and assignable:
+                s.next()
+                rhs = p_simple_expr(s)
         else:
             if nonempty:
                 error(s.position(), "Empty declarator")
             name = ""
             cname = None
-            if s.sy == '=' and assignable:
-                s.next()
-                rhs = p_simple_expr(s)
         result = Nodes.CNameDeclaratorNode(pos,
             name = name, cname = cname, rhs = rhs)
     result.calling_convention = calling_convention
index 913bddb6114c0044ec1d75a1794c362085b6055c..a35cce4fddfaf4da6c69055bf7f882984d8d61a0 100644 (file)
@@ -357,10 +357,10 @@ class Scope:
         entry = self.lookup_here(name)
         if entry:
             if visibility <> 'private' and visibility <> entry.visibility:
-                error(pos, "Function '%s' previously declared as '%s'" % (
-                    name, entry.visibility))
+                warning(pos, "Function '%s' previously declared as '%s'" % (name, entry.visibility), 1)
             if not entry.type.same_as(type):
-                error(pos, "Function signature does not match previous declaration")
+                warning(pos, "Function signature does not match previous declaration", 1)
+                entry.type = type
         else:
             if not cname:
                 if api or visibility <> 'private':
@@ -598,20 +598,21 @@ class BuiltinScope(Scope):
     def builtin_scope(self):
         return self
         
-    # TODO: built in functions conflict with built in types of same name...
-    # TODO: perhapse these should all be declared in some universal .pxi file? 
+    # TODO: merge this into builtin_function_table when error handling in Pyrex
+    #       is fixed. Also handle pyrex types as functions. 
     
     builtin_functions = {
+      "cmp":     ["PyObject_Compare", c_int_type, (py_object_type, py_object_type), None, True],
+      "unicode": ["PyObject_Unicode", py_object_type, (py_object_type, ), 0],
+      "type":    ["PyObject_Type", py_object_type, (py_object_type, ), 0],
+
       "hasattr": ["PyObject_HasAttr", c_bint_type, (py_object_type, py_object_type)],
       "setattr": ["PyObject_SetAttr", c_int_type, (py_object_type, py_object_type, py_object_type), -1],
-      "cmp":     ["PyObject_Compare", c_int_type, (py_object_type, py_object_type), None, True],
       "repr":    ["PyObject_Repr", py_object_type, (py_object_type, ), 0],
 #      "str":     ["PyObject_Str", py_object_type, (py_object_type, ), 0],
-      "unicode": ["PyObject_Unicode", py_object_type, (py_object_type, ), 0],
       "isinstance": ["PyObject_IsInstance", c_bint_type, (py_object_type, py_object_type), -1],
       "issubclass": ["PyObject_IsSubclass", c_bint_type, (py_object_type, py_object_type), -1],
       "hash":    ["PyObject_Hash", c_long_type, (py_object_type, ), -1, True],
-      "type":    ["PyObject_Type", py_object_type, (py_object_type, ), 0],
       "len":     ["PyObject_Size", c_py_ssize_t_type, (py_object_type, ), -1],
       "dir":     ["PyObject_Dir", py_object_type, (py_object_type, ), 0],
       "iter":    ["PyObject_GetIter", py_object_type, (py_object_type, ), 0],
@@ -1055,6 +1056,9 @@ class StructOrUnionScope(Scope):
                 "C struct/union member cannot be declared %s" % visibility)
         return entry
 
+    def declare_cfunction(self, name, type, pos, 
+            cname = None, visibility = 'private', defining = 0, api = 0, in_pxd = 0):
+        self.declare_var(name, type, pos, cname, visibility)
 
 class ClassScope(Scope):
     #  Abstract base class for namespace of