Commit 012374eb authored by gsamain's avatar gsamain

Make declaration of cypclass methods work when declaring without defining a...

Make declaration of cypclass methods work when declaring without defining a pointer type as return type
parent 6837ec46
...@@ -1394,28 +1394,35 @@ class CVarDefNode(StatNode): ...@@ -1394,28 +1394,35 @@ class CVarDefNode(StatNode):
return return
if type.is_reference and self.visibility != 'extern': if type.is_reference and self.visibility != 'extern':
error(declarator.pos, "C++ references cannot be declared; use a pointer instead") error(declarator.pos, "C++ references cannot be declared; use a pointer instead")
cfunc_declarator = declarator
if type.is_cfunction: if type.is_cfunction:
while not isinstance(cfunc_declarator, (CFuncDeclaratorNode, CNameDeclaratorNode)):
cfunc_declarator = cfunc_declarator.base
if isinstance(cfunc_declarator, CNameDeclaratorNode):
# It's probably a typedef'ed attribute, in which case the self
# handling has already been done, so skip all self hacks.
cfunc_declarator = None
if 'staticmethod' in env.directives: if 'staticmethod' in env.directives:
type.is_static_method = True type.is_static_method = True
elif name in ("__new__", "__alloc__") and\ elif cfunc_declarator and name in ("__new__", "__alloc__") and\
env.is_cpp_class_scope and env.parent_type.is_cyp_class: env.is_cpp_class_scope and env.parent_type.is_cyp_class:
type.is_static_method = True type.is_static_method = True
if declarator.skipped_self: if cfunc_declarator.skipped_self:
_name, _type, _pos, _arg = declarator.skipped_self _name, _type, _pos, _arg = cfunc_declarator.skipped_self
if name == "__new__": if name == "__new__":
_type = PyrexTypes.CPtrType(PyrexTypes.CFuncType(_type, [], nogil=1)) _type = PyrexTypes.CPtrType(PyrexTypes.CFuncType(_type, [], nogil=1))
# aka _type = {class_type} (*f)() nogil # aka _type = {class_type} (*f)() nogil
reinjected_arg = PyrexTypes.CFuncTypeArg(_name, _type, _pos) reinjected_arg = PyrexTypes.CFuncTypeArg(_name, _type, _pos)
type.args = [reinjected_arg] + type.args type.args = [reinjected_arg] + type.args
declarator.args = [_arg] + declarator.args cfunc_declarator.args = [_arg] + cfunc_declarator.args
elif name == "__alloc__": elif name == "__alloc__":
# Force __alloc__ to have the signature: # Force __alloc__ to have the signature:
# {class_type} f() nogil # {class_type} f() nogil
type.return_type = _type type.return_type = _type
type.args = [] type.args = []
declarator.args = [] cfunc_declarator.args = []
declarator.skipped_self = None cfunc_declarator.skipped_self = None
self.entry = dest_scope.declare_cfunction( self.entry = dest_scope.declare_cfunction(
name, type, declarator.pos, name, type, declarator.pos,
...@@ -1426,8 +1433,8 @@ class CVarDefNode(StatNode): ...@@ -1426,8 +1433,8 @@ class CVarDefNode(StatNode):
if create_extern_wrapper: if create_extern_wrapper:
self.entry.type.create_to_py_utility_code(env) self.entry.type.create_to_py_utility_code(env)
self.entry.create_wrapper = True self.entry.create_wrapper = True
if env.is_cpp_class_scope and env.parent_type.is_cyp_class\ if cfunc_declarator and type.is_cfunction and env.is_cpp_class_scope and env.parent_type.is_cyp_class\
and not declarator.skipped_self and not type.is_static_method: and not cfunc_declarator.skipped_self and not type.is_static_method:
# It means we have a cypclass method without the self argument # It means we have a cypclass method without the self argument
# => shout # => shout
error(self.pos, "Cypclass methods must have a self argument") error(self.pos, "Cypclass methods must have a self argument")
......
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