Commit 5ce9ee47 authored by Robert Bradshaw's avatar Robert Bradshaw

Ticket #355 - ctypedef class ordering

parent 23e1262c
...@@ -811,6 +811,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -811,6 +811,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
"%s;" % "%s;" %
attr.type.declaration_code(attr.cname)) attr.type.declaration_code(attr.cname))
code.putln(footer) 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): def generate_global_declarations(self, env, code, definition):
code.putln("") code.putln("")
......
...@@ -368,6 +368,7 @@ class PyExtensionType(PyObjectType): ...@@ -368,6 +368,7 @@ class PyExtensionType(PyObjectType):
# base_type PyExtensionType or None # base_type PyExtensionType or None
# module_name string or None Qualified name of defining module # module_name string or None Qualified name of defining module
# objstruct_cname string Name of PyObject struct # 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 # typeobj_cname string or None C code fragment referring to type object
# typeptr_cname string or None Name of pointer to external type object # typeptr_cname string or None Name of pointer to external type object
# vtabslot_cname string Name of C method table member # vtabslot_cname string Name of C method table member
...@@ -378,6 +379,8 @@ class PyExtensionType(PyObjectType): ...@@ -378,6 +379,8 @@ class PyExtensionType(PyObjectType):
is_extension_type = 1 is_extension_type = 1
has_attributes = 1 has_attributes = 1
objtypedef_cname = None
def __init__(self, name, typedef_flag, base_type): def __init__(self, name, typedef_flag, base_type):
self.name = name self.name = name
self.scope = None self.scope = None
......
...@@ -1010,6 +1010,15 @@ class ModuleScope(Scope): ...@@ -1010,6 +1010,15 @@ class ModuleScope(Scope):
module_name = None, base_type = None, objstruct_cname = None, module_name = None, base_type = None, objstruct_cname = None,
typeobj_cname = None, visibility = 'private', typedef_flag = 0, api = 0, typeobj_cname = None, visibility = 'private', typedef_flag = 0, api = 0,
buffer_defaults = None): 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 # Look for previous declaration as a type
# #
...@@ -1034,6 +1043,8 @@ class ModuleScope(Scope): ...@@ -1034,6 +1043,8 @@ class ModuleScope(Scope):
type = PyrexTypes.PyExtensionType(name, typedef_flag, base_type) type = PyrexTypes.PyExtensionType(name, typedef_flag, base_type)
type.pos = pos type.pos = pos
type.buffer_defaults = buffer_defaults type.buffer_defaults = buffer_defaults
if objtypedef_cname is not None:
type.objtypedef_cname = objtypedef_cname
if visibility == 'extern': if visibility == 'extern':
type.module_name = module_name type.module_name = module_name
else: else:
...@@ -1045,7 +1056,7 @@ class ModuleScope(Scope): ...@@ -1045,7 +1056,7 @@ class ModuleScope(Scope):
if objstruct_cname: if objstruct_cname:
type.objstruct_cname = objstruct_cname type.objstruct_cname = objstruct_cname
elif not entry.in_cinclude: elif not entry.in_cinclude:
type.objstruct_cname = self.mangle(Naming.objstruct_prefix, name) type.objstruct_cname = self.mangle(Naming.objstruct_prefix, name)
else: else:
error(entry.pos, error(entry.pos,
"Object name required for 'public' or 'extern' C class") "Object name required for 'public' or 'extern' C class")
......
...@@ -2,4 +2,4 @@ ctypedef public class Time [type MyTime_Type, object MyTimeObject]: ...@@ -2,4 +2,4 @@ ctypedef public class Time [type MyTime_Type, object MyTimeObject]:
cdef public double seconds cdef public double seconds
ctypedef public class Event [type MyEvent_Type, object MyEventObject]: ctypedef public class Event [type MyEvent_Type, object MyEventObject]:
cdef public Time time cdef public Time time
\ No newline at end of file
...@@ -4,4 +4,4 @@ ctypedef public class Time [type MyTime_Type, object MyTimeObject]: ...@@ -4,4 +4,4 @@ ctypedef public class Time [type MyTime_Type, object MyTimeObject]:
ctypedef public class Event [type MyEvent_Type, object MyEventObject]: ctypedef public class Event [type MyEvent_Type, object MyEventObject]:
def __init__(self, Time time): def __init__(self, Time time):
self.time = time self.time = time
\ No newline at end of file
ctypedef struct Spam ctypedef struct Spam
ctypedef class Eggs
cdef extern from *: cdef extern from *:
ctypedef struct Ham ctypedef struct Ham
...@@ -7,12 +6,7 @@ cdef extern from *: ...@@ -7,12 +6,7 @@ cdef extern from *:
ctypedef struct Spam: ctypedef struct Spam:
int i int i
ctypedef class Eggs:
pass
ctypedef struct Spam ctypedef struct Spam
ctypedef class Eggs
_ERRORS = u""" _ERRORS = u"""
1:0: Forward-referenced type must use 'cdef', not 'ctypedef' 1:0: Forward-referenced type must use 'cdef', not 'ctypedef'
2:0: Forward-referenced type must use 'cdef', not 'ctypedef'
""" """
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