Commit efaf3aea authored by Robert Bradshaw's avatar Robert Bradshaw

Fix ctypedef extern class, assignment on declaration, redeclaration warnings

parent 06b9e15c
......@@ -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)
......
......@@ -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)
......
......@@ -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)
......@@ -1531,6 +1542,10 @@ class CClassDefNode(StatNode):
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:
scope.doc = 'File: %s (starting at line %s)'%relative_position(self.pos)
......
......@@ -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
......
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment