#286, make sure cdef classes fully defined in pxd
authorRobert Bradshaw <robertwb@math.washington.edu>
Thu, 10 Sep 2009 08:30:06 +0000 (01:30 -0700)
committerRobert Bradshaw <robertwb@math.washington.edu>
Thu, 10 Sep 2009 08:30:06 +0000 (01:30 -0700)
Cython/Compiler/Main.py
Cython/Compiler/ModuleNode.py
Cython/Compiler/Symtab.py

index 7b8b7efd4a96ff8baf08588aca22504b836005a7..61576421bbaecfcbab6bf61f672da3c5d948b2fe 100644 (file)
@@ -85,7 +85,7 @@ class Context(object):
         from Optimize import FlattenInListTransform, SwitchTransform, IterationTransform
         from Optimize import FlattenBuiltinTypeCreation, ConstantFolding, FinalOptimizePhase
         from Buffer import IntroduceBufferAuxiliaryVars
-        from ModuleNode import check_c_declarations
+        from ModuleNode import check_c_declarations, check_c_declarations_pxd
 
         # Temporary hack that can be used to ensure that all result_code's
         # are generated at code generation time.
@@ -97,7 +97,7 @@ class Context(object):
                 return node
 
         if pxd:
-            _check_c_declarations = None
+            _check_c_declarations = check_c_declarations_pxd
             _specific_post_parse = PxdPostParse(self)
         else:
             _check_c_declarations = check_c_declarations
index f418baaff9c6322d547d88e51155b672e2804c68..172891ab49cc77045f601000738b3ec59e799309 100644 (file)
@@ -27,6 +27,10 @@ from Cython.Utils import open_new_file, replace_suffix, UtilityCode
 from StringEncoding import escape_byte_string, EncodedString
 
 
+def check_c_declarations_pxd(module_node):
+    module_node.scope.check_c_classes_pxd()
+    return module_node
+
 def check_c_declarations(module_node):
     module_node.scope.check_c_classes()
     module_node.scope.check_c_functions()
index 8c96a208f205a2f127c0ddd00aba24d36077b1d7..68a3aa66c55b7cb8b7a030f1c25bd3729e6efa59 100644 (file)
@@ -1114,6 +1114,22 @@ class ModuleScope(Scope):
             type.vtabstruct_cname = self.mangle(Naming.vtabstruct_prefix, entry.name)
             type.vtabptr_cname = self.mangle(Naming.vtabptr_prefix, entry.name)
 
+    def check_c_classes_pxd(self):
+        # Performs post-analysis checking and finishing up of extension types
+        # being implemented in this module. This is called only for the .pxd.
+        #
+        # Checks all extension types declared in this scope to
+        # make sure that:
+        #
+        #    * The extension type is fully declared
+        #
+        # Also allocates a name for the vtable if needed.
+        #
+        for entry in self.c_class_entries:
+            # Check defined
+            if not entry.type.scope:
+                error(entry.pos, "C class '%s' is declared but not defined" % entry.name)
+                
     def check_c_classes(self):
         # Performs post-analysis checking and finishing up of extension types
         # being implemented in this module. This is called only for the main
@@ -1389,7 +1405,8 @@ class CClassScope(ClassScope):
         # If the type or any of its base types have Python-valued
         # C attributes, then it needs to participate in GC.
         return self.has_pyobject_attrs or \
-            (self.parent_type.base_type and \
+            (self.parent_type.base_type and
+                self.parent_type.base_type.scope is not None and
                 self.parent_type.base_type.scope.needs_gc())
 
     def declare_var(self, name, type, pos, 
@@ -1399,7 +1416,7 @@ class CClassScope(ClassScope):
             if self.defined:
                 error(pos,
                     "C attributes cannot be added in implementation part of"
-                    " extension type")
+                    " extension type defined in a pxd")
             if get_special_method_signature(name):
                 error(pos, 
                     "The name '%s' is reserved for a special method."