From 5ce9ee471c957981aea10150f38e636d45104b82 Mon Sep 17 00:00:00 2001 From: Robert Bradshaw Date: Thu, 10 Sep 2009 19:33:50 -0700 Subject: [PATCH] Ticket #355 - ctypedef class ordering --- Cython/Compiler/ModuleNode.py | 3 +++ Cython/Compiler/PyrexTypes.py | 3 +++ Cython/Compiler/Symtab.py | 13 ++++++++++++- tests/compile/ctypedef_public_class_T355.pxd | 2 +- tests/compile/ctypedef_public_class_T355.pyx | 2 +- tests/errors/e_ctypedefforward.pyx | 6 ------ 6 files changed, 20 insertions(+), 9 deletions(-) diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index 172891ab..b007d1cf 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -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("") diff --git a/Cython/Compiler/PyrexTypes.py b/Cython/Compiler/PyrexTypes.py index d11b6d73..3048d36d 100644 --- a/Cython/Compiler/PyrexTypes.py +++ b/Cython/Compiler/PyrexTypes.py @@ -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 diff --git a/Cython/Compiler/Symtab.py b/Cython/Compiler/Symtab.py index 68a3aa66..97cb026a 100644 --- a/Cython/Compiler/Symtab.py +++ b/Cython/Compiler/Symtab.py @@ -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") diff --git a/tests/compile/ctypedef_public_class_T355.pxd b/tests/compile/ctypedef_public_class_T355.pxd index bb4dddfc..178181c7 100644 --- a/tests/compile/ctypedef_public_class_T355.pxd +++ b/tests/compile/ctypedef_public_class_T355.pxd @@ -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 diff --git a/tests/compile/ctypedef_public_class_T355.pyx b/tests/compile/ctypedef_public_class_T355.pyx index eff6e53c..18178e40 100644 --- a/tests/compile/ctypedef_public_class_T355.pyx +++ b/tests/compile/ctypedef_public_class_T355.pyx @@ -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 diff --git a/tests/errors/e_ctypedefforward.pyx b/tests/errors/e_ctypedefforward.pyx index b66f21dd..f2358fd5 100644 --- a/tests/errors/e_ctypedefforward.pyx +++ b/tests/errors/e_ctypedefforward.pyx @@ -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' """ -- 2.26.2