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): ...@@ -90,7 +90,7 @@ def error(position, message):
LEVEL=1 # warn about all errors level 1 or higher LEVEL=1 # warn about all errors level 1 or higher
def warning(position, message, level): def warning(position, message, level=0):
if level < LEVEL: if level < LEVEL:
return return
warn = CompileWarning(position, message) warn = CompileWarning(position, message)
......
...@@ -1242,45 +1242,45 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1242,45 +1242,45 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("%s {" % header) code.putln("%s {" % header)
code.put_var_declarations(env.temp_entries) code.put_var_declarations(env.temp_entries)
#code.putln("/*--- Libary function declarations ---*/") code.putln("/*--- Libary function declarations ---*/")
env.generate_library_function_declarations(code) env.generate_library_function_declarations(code)
self.generate_filename_init_call(code) self.generate_filename_init_call(code)
#code.putln("/*--- Module creation code ---*/") code.putln("/*--- Module creation code ---*/")
self.generate_module_creation_code(env, code) self.generate_module_creation_code(env, code)
#code.putln("/*--- Intern code ---*/") code.putln("/*--- Intern code ---*/")
self.generate_intern_code(env, code) self.generate_intern_code(env, code)
#code.putln("/*--- String init code ---*/") code.putln("/*--- String init code ---*/")
self.generate_string_init_code(env, code) self.generate_string_init_code(env, code)
#code.putln("/*--- Builtin init code ---*/") code.putln("/*--- Builtin init code ---*/")
# FIXME !! # TODO: FIXME !!
#self.generate_builtin_init_code(env, code) #self.generate_builtin_init_code(env, code)
#code.putln("/*--- Global init code ---*/") code.putln("/*--- Global init code ---*/")
self.generate_global_init_code(env, code) self.generate_global_init_code(env, code)
#code.putln("/*--- Module import code ---*/") code.putln("/*--- Module import code ---*/")
for module in imported_modules: for module in imported_modules:
self.generate_module_import_code(module, env, code) 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) self.generate_c_function_export_code(env, code)
#code.putln("/*--- Function import code ---*/") code.putln("/*--- Function import code ---*/")
for module in imported_modules: for module in imported_modules:
self.generate_c_function_import_code_for_module(module, env, code) 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) self.generate_type_init_code(env, code)
#code.putln("/*--- Type import code ---*/") code.putln("/*--- Type import code ---*/")
for module in imported_modules: for module in imported_modules:
self.generate_type_import_code_for_module(module, env, code) self.generate_type_import_code_for_module(module, env, code)
#code.putln("/*--- Execution code ---*/") code.putln("/*--- Execution code ---*/")
self.body.generate_execution_code(code) self.body.generate_execution_code(code)
code.putln("return;") code.putln("return;")
code.put_label(code.error_label) code.put_label(code.error_label)
...@@ -1391,6 +1391,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1391,6 +1391,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
for entry in module.c_class_entries: for entry in module.c_class_entries:
if entry.defined_in_pxd: if entry.defined_in_pxd:
import_module = 1 import_module = 1
print "generate_module_import_code", module, import_module
if import_module: if import_module:
env.use_utility_code(import_module_utility_code) env.use_utility_code(import_module_utility_code)
name = self.build_module_var_name(module.qualified_name) name = self.build_module_var_name(module.qualified_name)
......
...@@ -1500,6 +1500,17 @@ class CClassDefNode(StatNode): ...@@ -1500,6 +1500,17 @@ class CClassDefNode(StatNode):
error(self.pos, "Object struct name specification required for " error(self.pos, "Object struct name specification required for "
"C class defined in 'extern from' block") "C class defined in 'extern from' block")
self.base_type = None 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_name:
if self.base_class_module: if self.base_class_module:
base_class_scope = env.find_module(self.base_class_module, self.pos) base_class_scope = env.find_module(self.base_class_module, self.pos)
...@@ -1530,6 +1541,10 @@ class CClassDefNode(StatNode): ...@@ -1530,6 +1541,10 @@ class CClassDefNode(StatNode):
typedef_flag = self.typedef_flag, typedef_flag = self.typedef_flag,
api = self.api) api = self.api)
scope = self.entry.type.scope 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 self.doc:
if Options.embed_pos_in_docstring: if Options.embed_pos_in_docstring:
......
...@@ -1521,7 +1521,7 @@ def p_c_declarator(s, empty = 0, is_type = 0, cmethod_flag = 0, assignable = 0, ...@@ -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) base = Nodes.CNameDeclaratorNode(pos, name = "", cname = None)
result = p_c_func_declarator(s, pos, base, cmethod_flag) result = p_c_func_declarator(s, pos, base, cmethod_flag)
else: 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) calling_convention_allowed = 1)
s.expect(')') s.expect(')')
else: else:
...@@ -1587,14 +1587,14 @@ def p_c_simple_declarator(s, empty, is_type, cmethod_flag, assignable, nonempty) ...@@ -1587,14 +1587,14 @@ def p_c_simple_declarator(s, empty, is_type, cmethod_flag, assignable, nonempty)
error(s.position(), "Declarator should be empty") error(s.position(), "Declarator should be empty")
s.next() s.next()
cname = p_opt_cname(s) cname = p_opt_cname(s)
if s.sy == '=' and assignable:
s.next()
rhs = p_simple_expr(s)
else: else:
if nonempty: if nonempty:
error(s.position(), "Empty declarator") error(s.position(), "Empty declarator")
name = "" name = ""
cname = None cname = None
if s.sy == '=' and assignable:
s.next()
rhs = p_simple_expr(s)
result = Nodes.CNameDeclaratorNode(pos, result = Nodes.CNameDeclaratorNode(pos,
name = name, cname = cname, rhs = rhs) name = name, cname = cname, rhs = rhs)
result.calling_convention = calling_convention result.calling_convention = calling_convention
......
...@@ -357,10 +357,10 @@ class Scope: ...@@ -357,10 +357,10 @@ class Scope:
entry = self.lookup_here(name) entry = self.lookup_here(name)
if entry: if entry:
if visibility <> 'private' and visibility <> entry.visibility: if visibility <> 'private' and visibility <> entry.visibility:
error(pos, "Function '%s' previously declared as '%s'" % ( warning(pos, "Function '%s' previously declared as '%s'" % (name, entry.visibility), 1)
name, entry.visibility))
if not entry.type.same_as(type): 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: else:
if not cname: if not cname:
if api or visibility <> 'private': if api or visibility <> 'private':
...@@ -598,20 +598,21 @@ class BuiltinScope(Scope): ...@@ -598,20 +598,21 @@ class BuiltinScope(Scope):
def builtin_scope(self): def builtin_scope(self):
return self return self
# TODO: built in functions conflict with built in types of same name... # TODO: merge this into builtin_function_table when error handling in Pyrex
# TODO: perhapse these should all be declared in some universal .pxi file? # is fixed. Also handle pyrex types as functions.
builtin_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)], "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], "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], "repr": ["PyObject_Repr", py_object_type, (py_object_type, ), 0],
# "str": ["PyObject_Str", 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], "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], "issubclass": ["PyObject_IsSubclass", c_bint_type, (py_object_type, py_object_type), -1],
"hash": ["PyObject_Hash", c_long_type, (py_object_type, ), -1, True], "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], "len": ["PyObject_Size", c_py_ssize_t_type, (py_object_type, ), -1],
"dir": ["PyObject_Dir", py_object_type, (py_object_type, ), 0], "dir": ["PyObject_Dir", py_object_type, (py_object_type, ), 0],
"iter": ["PyObject_GetIter", py_object_type, (py_object_type, ), 0], "iter": ["PyObject_GetIter", py_object_type, (py_object_type, ), 0],
...@@ -1055,6 +1056,9 @@ class StructOrUnionScope(Scope): ...@@ -1055,6 +1056,9 @@ class StructOrUnionScope(Scope):
"C struct/union member cannot be declared %s" % visibility) "C struct/union member cannot be declared %s" % visibility)
return entry 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): class ClassScope(Scope):
# Abstract base class for namespace of # 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