Resolve subclass assignment
authorRobert Bradshaw <robertwb@math.washington.edu>
Fri, 19 Jun 2009 04:26:40 +0000 (21:26 -0700)
committerRobert Bradshaw <robertwb@math.washington.edu>
Fri, 19 Jun 2009 04:26:40 +0000 (21:26 -0700)
Cython/Compiler/Nodes.py
Cython/Compiler/PyrexTypes.py
Cython/Compiler/Symtab.py

index 63d3bc72f4884a161b71db7e0cfedc23ab43771d..c892a633755ac02d2409f16d856fc97fa2949f16 100644 (file)
@@ -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
index 9bd28744a86c0c7afd076651018f8494c26ea48e..6f6ba6e9bd6489cefc979451391260f87294d099 100644 (file)
@@ -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
 
index d44c30ed6ce587ba71c78adfbb1e1a28be8e9b88..6a8d7f94e9f9f1e39e1bbf90d1bd14fad762aa3f 100644 (file)
@@ -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)