Commit 1e92f37a authored by Robert Bradshaw's avatar Robert Bradshaw

Allow no-arg constructor C++ classes as extension class members.

parent 456149b5
...@@ -1036,6 +1036,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1036,6 +1036,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
type.vtabslot_cname, type.vtabslot_cname,
struct_type_cast, type.vtabptr_cname)) struct_type_cast, type.vtabptr_cname))
for entry in scope.var_entries:
if entry.type.is_cpp_class:
code.putln("new(&(p->%s)) %s();" % (entry.cname, entry.type.cname));
for entry in py_attrs: for entry in py_attrs:
if scope.is_internal or entry.name == "__weakref__": if scope.is_internal or entry.name == "__weakref__":
# internal classes do not need None inits # internal classes do not need None inits
...@@ -1091,6 +1095,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1091,6 +1095,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if weakref_slot in scope.var_entries: if weakref_slot in scope.var_entries:
code.putln("if (p->__weakref__) PyObject_ClearWeakRefs(o);") code.putln("if (p->__weakref__) PyObject_ClearWeakRefs(o);")
for entry in scope.var_entries:
if entry.type.is_cpp_class:
code.putln("p->%s.~%s();" % (entry.cname, entry.type.cname));
for entry in py_attrs: for entry in py_attrs:
code.put_xdecref("p->%s" % entry.cname, entry.type, nanny=False) code.put_xdecref("p->%s" % entry.cname, entry.type, nanny=False)
......
...@@ -571,7 +571,7 @@ class Scope(object): ...@@ -571,7 +571,7 @@ class Scope(object):
if type.is_cpp_class and visibility != 'extern': if type.is_cpp_class and visibility != 'extern':
constructor = type.scope.lookup(u'<init>') constructor = type.scope.lookup(u'<init>')
if constructor is not None and PyrexTypes.best_match([], constructor.all_alternatives()) is None: if constructor is not None and PyrexTypes.best_match([], constructor.all_alternatives()) is None:
error(pos, "C++ class must have a default constructor to be stack allocated") error(pos, "C++ class must have a no-arg constructor to be stack allocated")
entry = self.declare(name, cname, type, pos, visibility) entry = self.declare(name, cname, type, pos, visibility)
entry.is_variable = 1 entry.is_variable = 1
if in_pxd and visibility != 'extern': if in_pxd and visibility != 'extern':
...@@ -1770,7 +1770,10 @@ class CClassScope(ClassScope): ...@@ -1770,7 +1770,10 @@ class CClassScope(ClassScope):
if visibility == 'private': if visibility == 'private':
cname = c_safe_identifier(cname) cname = c_safe_identifier(cname)
if type.is_cpp_class and visibility != 'extern': if type.is_cpp_class and visibility != 'extern':
error(pos, "C++ classes not allowed as members of an extension type, use a pointer or reference instead") constructor = type.scope.lookup(u'<init>')
if constructor is not None and \
PyrexTypes.best_match([], constructor.all_alternatives()) is None:
error(pos, "C++ class must have a no-arg constructor to be a member of an extension type; use a pointer instead")
entry = self.declare(name, cname, type, pos, visibility) entry = self.declare(name, cname, type, pos, visibility)
entry.is_variable = 1 entry.is_variable = 1
self.var_entries.append(entry) self.var_entries.append(entry)
......
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