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):
"%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("")
......
......@@ -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
......
......@@ -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")
......
......@@ -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
......@@ -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
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'
"""
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