From: Robert Bradshaw Date: Fri, 19 Jun 2009 04:26:40 +0000 (-0700) Subject: Resolve subclass assignment X-Git-Tag: 0.13.beta0~353^2~80 X-Git-Url: http://git.tremily.us/gitweb.cgi?a=commitdiff_plain;h=1b1626c1093dcc3d3710e16fb7336b160646a6b9;p=cython.git Resolve subclass assignment --- diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index 63d3bc72..c892a633 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -920,9 +920,18 @@ class CppClassNode(CStructOrUnionDefNode): scope = CppClassScope(self.name) else: self.attributes = None + base_class_types = [] + for base_class_name in self.base_classes: + base_class_entry = env.lookup(base_class_name) + if base_class_entry is None: + error(self.pos, "'%s' not found" % base_class_name) + elif not base_class_entry.is_type or not base_class_entry.type.is_cpp_class: + error(self.pos, "'%s' is not a cpp class type" % base_class_name) + else: + base_class_types.append(base_class_entry.type) self.entry = env.declare_cpp_class( self.name, "cppclass", scope, 0, self.pos, - self.cname, self.base_classes, self.namespace, visibility = self.visibility) + self.cname, base_class_types, self.namespace, visibility = self.visibility) if self.attributes is not None: if self.in_pxd and not env.in_cinclude: self.entry.defined_in_pxd = 1 diff --git a/Cython/Compiler/PyrexTypes.py b/Cython/Compiler/PyrexTypes.py index 9bd28744..6f6ba6e9 100644 --- a/Cython/Compiler/PyrexTypes.py +++ b/Cython/Compiler/PyrexTypes.py @@ -993,6 +993,9 @@ class CPtrType(CType): return self.base_type.pointer_assignable_from_resolved_type(other_type) else: return 0 + if (self.base_type.is_cpp_class and other_type.is_ptr + and other_type.base_type.is_cpp_class and other_type.base_type.is_subclass(self.base_type)): + return 1 if other_type.is_array or other_type.is_ptr: return self.base_type.is_void or self.base_type.same_as(other_type.base_type) return 0 @@ -1396,21 +1399,13 @@ class CppClassType(CType): return "%s %s" % (name, entity_code) def is_subclass(self, other_type): + if self.same_as_resolved_type(other_type): + return 1 for base_class in self.base_classes: if base_class.is_subclass(other_type): return 1 return 0 - def assignable_from_resolved_type(self, other_type): - print self.same_as_resolved_type(other_type) - print self.same_as(other_type) - print other_type.is_subclass(self) - if self.same_as_resolved_type(other_type): - return 1 - if other_type.is_subclass(self) or self.same_as(other_type): - return 1 - return 0 - def attributes_known(self): return self.scope is not None diff --git a/Cython/Compiler/Symtab.py b/Cython/Compiler/Symtab.py index d44c30ed..6a8d7f94 100644 --- a/Cython/Compiler/Symtab.py +++ b/Cython/Compiler/Symtab.py @@ -1097,14 +1097,6 @@ class ModuleScope(Scope): def declare_cpp_class(self, name, kind, scope, typedef_flag, pos, cname = None, base_classes = [], namespace = None, visibility = 'extern', packed = False): - def declare_inherited_attributes(entry, base_entry): - if base_entry: - for base_class in base_entry.type.base_classes: - new_entry = self.lookup(base_class) - if base_entry: - declare_inherited_attributes(entry, new_entry) - entry.type.scope.declare_inherited_cpp_attributes(new_entry.type.scope) - if visibility != 'extern': error(pos, "C++ classes may only be extern") if cname is None: @@ -1129,7 +1121,12 @@ class ModuleScope(Scope): if not scope and not entry.type.scope: self.check_for_illegal_incomplete_ctypedef(typedef_flag, pos) entry.type.scope = CppClassScope(name) - declare_inherited_attributes(entry, entry) + + def declare_inherited_attributes(entry, base_classes): + for base_class in base_classes: + declare_inherited_attributes(entry, base_class.base_classes) + entry.type.scope.declare_inherited_cpp_attributes(base_class.scope) + declare_inherited_attributes(entry, base_classes) return entry def check_for_illegal_incomplete_ctypedef(self, typedef_flag, pos): @@ -1621,11 +1618,9 @@ class CppClassScope(Scope): # Declare entries for all the C++ attributes of an # inherited type, with cnames modified appropriately # to work with this type. - def adapt(cname): - return "%s.%s" % (Naming.obj_base_cname, base_entry.cname) for base_entry in \ base_scope.inherited_var_entries + base_scope.var_entries: - entry = self.declare(base_entry.name, adapt(base_entry.cname), + entry = self.declare(base_entry.name, base_entry.cname, base_entry.type, None, 'extern') entry.is_variable = 1 self.inherited_var_entries.append(entry)