Commit 0078df28 authored by Robert Bradshaw's avatar Robert Bradshaw

Various C++ operator overloading fixes.

parent 5ce30f5b
...@@ -4130,8 +4130,7 @@ class UnopNode(ExprNode): ...@@ -4130,8 +4130,7 @@ class UnopNode(ExprNode):
def is_cpp_operation(self): def is_cpp_operation(self):
type = self.operand.type type = self.operand.type
return (type.is_cpp_class or return type.is_cpp_class or type.is_reference and type.base_type.is_cpp_class
(type.is_ptr or type.is_reference) and type.base_type.is_cpp_class)
def coerce_operand_to_pyobject(self, env): def coerce_operand_to_pyobject(self, env):
self.operand = self.operand.coerce_to_pyobject(env) self.operand = self.operand.coerce_to_pyobject(env)
...@@ -4157,7 +4156,7 @@ class UnopNode(ExprNode): ...@@ -4157,7 +4156,7 @@ class UnopNode(ExprNode):
self.type = PyrexTypes.error_type self.type = PyrexTypes.error_type
def analyse_cpp_operation(self, env): def analyse_cpp_operation(self, env):
type = operand.type type = self.operand.type
if type.is_ptr or type.is_reference: if type.is_ptr or type.is_reference:
type = type.base_type type = type.base_type
entry = env.lookup(type.name) entry = env.lookup(type.name)
...@@ -4167,7 +4166,10 @@ class UnopNode(ExprNode): ...@@ -4167,7 +4166,10 @@ class UnopNode(ExprNode):
% (self.operator, type)) % (self.operator, type))
self.type_error() self.type_error()
return return
self.type = function.type.return_type func_type = function.type
if func_type.is_ptr:
func_type = func_type.base_type
self.type = func_type.return_type
class NotNode(ExprNode): class NotNode(ExprNode):
...@@ -4215,6 +4217,9 @@ class UnaryPlusNode(UnopNode): ...@@ -4215,6 +4217,9 @@ class UnaryPlusNode(UnopNode):
return "PyNumber_Positive" return "PyNumber_Positive"
def calculate_result_code(self): def calculate_result_code(self):
if self.is_cpp_operation():
return "(+%s)" % self.operand.result()
else:
return self.operand.result() return self.operand.result()
...@@ -4269,6 +4274,8 @@ class CUnopNode(UnopNode): ...@@ -4269,6 +4274,8 @@ class CUnopNode(UnopNode):
class DereferenceNode(CUnopNode): class DereferenceNode(CUnopNode):
# unary * operator # unary * operator
operator = '*'
def analyse_c_operation(self, env): def analyse_c_operation(self, env):
if self.operand.type.is_ptr: if self.operand.type.is_ptr:
self.type = self.operand.type.base_type self.type = self.operand.type.base_type
...@@ -4651,9 +4658,9 @@ class BinopNode(ExprNode): ...@@ -4651,9 +4658,9 @@ class BinopNode(ExprNode):
def is_cpp_operation(self): def is_cpp_operation(self):
type1 = self.operand1.type type1 = self.operand1.type
type2 = self.operand2.type type2 = self.operand2.type
if type1.is_ptr: if type1.is_reference:
type1 = type1.base_type type1 = type1.base_type
if type2.is_ptr: if type2.is_reference:
type2 = type2.base_type type2 = type2.base_type
return (type1.is_cpp_class return (type1.is_cpp_class
or type2.is_cpp_class) or type2.is_cpp_class)
...@@ -4897,6 +4904,8 @@ class DivNode(NumBinopNode): ...@@ -4897,6 +4904,8 @@ class DivNode(NumBinopNode):
else: else:
self.ctruedivision = self.truedivision self.ctruedivision = self.truedivision
NumBinopNode.analyse_types(self, env) NumBinopNode.analyse_types(self, env)
if self.is_cpp_operation():
self.cdivision = True
if not self.type.is_pyobject: if not self.type.is_pyobject:
self.zerodivision_check = ( self.zerodivision_check = (
self.cdivision is None and not env.directives['cdivision'] self.cdivision is None and not env.directives['cdivision']
......
...@@ -2105,6 +2105,10 @@ def p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag, ...@@ -2105,6 +2105,10 @@ def p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag,
# TODO: This needs to be more strict... # TODO: This needs to be more strict...
name += s.sy name += s.sy
s.next() s.next()
if name[-1] == s.sy:
# ++ and -- are parsed as two tokens
name += s.sy
s.next()
result = Nodes.CNameDeclaratorNode(pos, result = Nodes.CNameDeclaratorNode(pos,
name = name, cname = cname, default = rhs) name = name, cname = cname, default = rhs)
result.calling_convention = calling_convention result.calling_convention = calling_convention
......
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