From efaf3aeac094ae832a5d6f2f6187b0562138efaf Mon Sep 17 00:00:00 2001 From: Robert Bradshaw Date: Sat, 20 Oct 2007 22:05:04 -0700 Subject: [PATCH] Fix ctypedef extern class, assignment on declaration, redeclaration warnings --- Cython/Compiler/Errors.py | 2 +- Cython/Compiler/ModuleNode.py | 27 ++++++++++++++------------- Cython/Compiler/Nodes.py | 15 +++++++++++++++ Cython/Compiler/Parsing.py | 8 ++++---- Cython/Compiler/Symtab.py | 20 ++++++++++++-------- 5 files changed, 46 insertions(+), 26 deletions(-) diff --git a/Cython/Compiler/Errors.py b/Cython/Compiler/Errors.py index 6b936b58..736d0326 100644 --- a/Cython/Compiler/Errors.py +++ b/Cython/Compiler/Errors.py @@ -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) diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index 2de79646..6d533d40 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -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) diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index d4df57c7..b6634144 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -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: diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py index 4550aa19..b76e520f 100644 --- a/Cython/Compiler/Parsing.py +++ b/Cython/Compiler/Parsing.py @@ -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 diff --git a/Cython/Compiler/Symtab.py b/Cython/Compiler/Symtab.py index 913bddb6..a35cce4f 100644 --- a/Cython/Compiler/Symtab.py +++ b/Cython/Compiler/Symtab.py @@ -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 -- 2.26.2