Ticket #355 - ctypedef class ordering
authorRobert Bradshaw <robertwb@math.washington.edu>
Fri, 11 Sep 2009 02:33:50 +0000 (19:33 -0700)
committerRobert Bradshaw <robertwb@math.washington.edu>
Fri, 11 Sep 2009 02:33:50 +0000 (19:33 -0700)
Cython/Compiler/ModuleNode.py
Cython/Compiler/PyrexTypes.py
Cython/Compiler/Symtab.py
tests/compile/ctypedef_public_class_T355.pxd
tests/compile/ctypedef_public_class_T355.pyx
tests/errors/e_ctypedefforward.pyx

index 172891ab49cc77045f601000738b3ec59e799309..b007d1cf163f5dc0e6db51ba7fab4db9646aec18 100644 (file)
@@ -811,6 +811,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
                 "%s;" %
                     attr.type.declaration_code(attr.cname))
         code.putln(footer)
+        if type.objtypedef_cname is not None:
+            # Only for exposing public typedef name.
+            code.putln("typedef struct %s %s;" % (type.objstruct_cname, type.objtypedef_cname))
 
     def generate_global_declarations(self, env, code, definition):
         code.putln("")
index d11b6d738534ea6c30a3426142110b710cc0a64e..3048d36dc5e62e16868a46176c87aad714cb78cb 100644 (file)
@@ -368,6 +368,7 @@ class PyExtensionType(PyObjectType):
     #  base_type        PyExtensionType or None
     #  module_name      string or None   Qualified name of defining module
     #  objstruct_cname  string           Name of PyObject struct
+    #  objtypedef_cname string           Name of PyObject struct typedef
     #  typeobj_cname    string or None   C code fragment referring to type object
     #  typeptr_cname    string or None   Name of pointer to external type object
     #  vtabslot_cname   string           Name of C method table member
@@ -378,6 +379,8 @@ class PyExtensionType(PyObjectType):
     is_extension_type = 1
     has_attributes = 1
     
+    objtypedef_cname = None
+    
     def __init__(self, name, typedef_flag, base_type):
         self.name = name
         self.scope = None
index 68a3aa66c55b7cb8b7a030f1c25bd3729e6efa59..97cb026ae3ab1ce069a15f5b9fef45d4c411c4ac 100644 (file)
@@ -1010,6 +1010,15 @@ class ModuleScope(Scope):
         module_name = None, base_type = None, objstruct_cname = None,
         typeobj_cname = None, visibility = 'private', typedef_flag = 0, api = 0,
         buffer_defaults = None):
+        # If this is a non-extern typedef class, expose the typedef, but use
+        # the non-typedef struct internally to avoid needing forward
+        # declarations for anonymous structs. 
+        if typedef_flag and visibility != 'extern':
+            objtypedef_cname = objstruct_cname
+            objstruct_cname = None
+            typedef_flag = 0
+        else:
+            objtypedef_cname = None
         #
         #  Look for previous declaration as a type
         #
@@ -1034,6 +1043,8 @@ class ModuleScope(Scope):
             type = PyrexTypes.PyExtensionType(name, typedef_flag, base_type)
             type.pos = pos
             type.buffer_defaults = buffer_defaults
+            if objtypedef_cname is not None:
+                type.objtypedef_cname = objtypedef_cname
             if visibility == 'extern':
                 type.module_name = module_name
             else:
@@ -1045,7 +1056,7 @@ class ModuleScope(Scope):
             if objstruct_cname:
                 type.objstruct_cname = objstruct_cname
             elif not entry.in_cinclude:
-                type.objstruct_cname = self.mangle(Naming.objstruct_prefix, name)                
+                type.objstruct_cname = self.mangle(Naming.objstruct_prefix, name)
             else:
                 error(entry.pos, 
                     "Object name required for 'public' or 'extern' C class")
index bb4dddfc8af0e76566e2fab9442ee8d120d8f093..178181c7a013631ac4610e3fef5c1d9c648effaa 100644 (file)
@@ -2,4 +2,4 @@ ctypedef public class Time [type MyTime_Type, object MyTimeObject]:
      cdef public double seconds
 
 ctypedef public class Event [type MyEvent_Type, object MyEventObject]:
-     cdef public Time time
\ No newline at end of file
+     cdef public Time time
index eff6e53c77f0bffe2ed3b1a01c0166f7e8113e4c..18178e40e3d635a2378437b8b8605894e3f20db8 100644 (file)
@@ -4,4 +4,4 @@ ctypedef public class Time [type MyTime_Type, object MyTimeObject]:
 
 ctypedef public class Event [type MyEvent_Type, object MyEventObject]:
      def __init__(self, Time time):
-         self.time = time
\ No newline at end of file
+         self.time = time
index b66f21dd4a7c8022bc557241ab60ecd788cb660e..f2358fd585f2e2443e4567c4798a3a6f6eb45fca 100644 (file)
@@ -1,5 +1,4 @@
 ctypedef struct Spam
-ctypedef class Eggs
 
 cdef extern from *:
        ctypedef struct Ham
@@ -7,12 +6,7 @@ cdef extern from *:
 ctypedef struct Spam:
        int i
 
-ctypedef class Eggs:
-       pass
-
 ctypedef struct Spam
-ctypedef class Eggs
 _ERRORS = u"""
 1:0: Forward-referenced type must use 'cdef', not 'ctypedef'
-2:0: Forward-referenced type must use 'cdef', not 'ctypedef'
 """