Commit 189f4d85 authored by Xavier Thompson's avatar Xavier Thompson

Improve handling of 'self' argument in cypclass methods

parent df4856db
...@@ -672,28 +672,32 @@ class CFuncDeclaratorNode(CDeclaratorNode): ...@@ -672,28 +672,32 @@ class CFuncDeclaratorNode(CDeclaratorNode):
type = other_type type = other_type
if name_declarator.cname: if name_declarator.cname:
error(self.pos, "Function argument cannot have C name specification") error(self.pos, "Function argument cannot have C name specification")
if i == 0 and type.is_unspecified: if i == 0 and env.is_c_class_scope and type.is_unspecified:
if env.is_c_class_scope: # fix the type of self
# fix the type of self # XXX is it ever possible for the type not to have been deduced previsouly ?
type = env.parent_type type = env.parent_type
elif env.is_cyp_class_scope: elif i == 0 and env.is_cyp_class_scope and 'staticmethod' not in env.directives and self.declared_name() != "alloc":
if self.declared_name() != "__new__":
# Accept 'f(const self, ...)' syntax as equivalent to 'f(self, ...) const' # Accept 'f(const self, ...)' syntax as equivalent to 'f(self, ...) const'
is_const_self = type.is_const unqualified_type = type
# XXX is this different from 'env.parent_type' ? if type.is_const_cyp_class:
type = env.lookup_here("this").type self.is_const_method = True
if self.declared_name() != "__new__": unqualified_type = type.const_base_type
self.is_const_method |= is_const_self elif self.is_const_method:
if self.is_const_method: type = PyrexTypes.cyp_class_const_type(type)
type = PyrexTypes.cyp_class_const_type(type) # check that the type of self is correct:
# skip 'self' argument from the list of actual arguments if not unqualified_type.same_as(env.parent_type):
# to comply with C++ implicit 'this' argument passing. error(self.pos, "Wrong type for self argument - expected %s, got %s" % (env.parent_type, type))
self.skipped_self = (name, type, arg_node.pos, arg_node) # skip 'self' argument from the list of actual arguments
continue # to comply with C++ implicit 'this' argument passing.
else: self.skipped_self = (name, type, arg_node.pos, arg_node)
# Allow '__new__(alloc, ...)' syntax with untyped first argument. continue
# Its type will be deduced as an allocation function, aka type = {class_type} (*f)() nogil else:
# This is not a 'self' argument and '__new__' will be a static method, so don't skip it! # Allow '__new__(alloc, ...)' syntax with untyped first argument.
type = PyrexTypes.CPtrType(PyrexTypes.CFuncType(type, [], nogil=1)) # Its type will be deduced as an allocation function, aka type = {class_type} (*f)() nogil
# This is not a 'self' argument and '__new__' will be a static method, so don't skip it!
type = env.parent_type
type = PyrexTypes.CPtrType(PyrexTypes.CFuncType(type, [], nogil=1))
# Turn *[] argument into ** # Turn *[] argument into **
if type.is_array: if type.is_array:
type = PyrexTypes.c_ptr_type(type.base_type) type = PyrexTypes.c_ptr_type(type.base_type)
...@@ -1055,7 +1059,7 @@ class CSimpleBaseTypeNode(CBaseTypeNode): ...@@ -1055,7 +1059,7 @@ class CSimpleBaseTypeNode(CBaseTypeNode):
if self.is_self_arg and (env.is_c_class_scope or env.is_cyp_class_scope): if self.is_self_arg and (env.is_c_class_scope or env.is_cyp_class_scope):
#print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ### #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
# For cypclass methods, the type of 'self' is always determined in CFuncDeclaratorNode # For cypclass methods, the type of 'self' is always determined in CFuncDeclaratorNode
type = env.parent_type if env.is_c_class_scope else PyrexTypes.unspecified_type type = env.parent_type
## elif self.is_type_arg and env.is_c_class_scope: ## elif self.is_type_arg and env.is_c_class_scope:
## type = Builtin.type_type ## type = Builtin.type_type
else: else:
...@@ -1088,7 +1092,7 @@ class CSimpleBaseTypeNode(CBaseTypeNode): ...@@ -1088,7 +1092,7 @@ class CSimpleBaseTypeNode(CBaseTypeNode):
elif could_be_name: elif could_be_name:
if self.is_self_arg and (env.is_c_class_scope or env.is_cyp_class_scope): if self.is_self_arg and (env.is_c_class_scope or env.is_cyp_class_scope):
# For cypclass methods, the type of 'self' is always determined in CFuncDeclaratorNode # For cypclass methods, the type of 'self' is always determined in CFuncDeclaratorNode
type = env.parent_type if env.is_c_class_scope else PyrexTypes.unspecified_type type = env.parent_type
## elif self.is_type_arg and env.is_c_class_scope: ## elif self.is_type_arg and env.is_c_class_scope:
## type = Builtin.type_type ## type = Builtin.type_type
else: else:
......
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