Commit 1b1626c1 authored by Robert Bradshaw's avatar Robert Bradshaw

Resolve subclass assignment

parent 533ae132
......@@ -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
......
......@@ -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,18 +1399,10 @@ class CppClassType(CType):
return "%s %s" % (name, entity_code)
def is_subclass(self, other_type):
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):
for base_class in self.base_classes:
if base_class.is_subclass(other_type):
return 1
return 0
......
......@@ -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)
......
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