summaryrefslogtreecommitdiff
path: root/Cython/Compiler/ExprNodes.py
diff options
context:
space:
mode:
Diffstat (limited to 'Cython/Compiler/ExprNodes.py')
-rw-r--r--Cython/Compiler/ExprNodes.py36
1 files changed, 25 insertions, 11 deletions
diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py
index 56e490490..98a41f9b0 100644
--- a/Cython/Compiler/ExprNodes.py
+++ b/Cython/Compiler/ExprNodes.py
@@ -2288,6 +2288,8 @@ class NameNode(AtomicExprNode):
entry = self.entry
if not entry:
return "<error>" # There was an error earlier
+ if self.entry.is_cpp_optional and not self.is_target:
+ return "(*%s)" % entry.cname
return entry.cname
def generate_result_code(self, code):
@@ -2897,6 +2899,7 @@ class CppIteratorNode(ExprNode):
# Created at the analyse_types stage by IteratorNode
cpp_sequence_cname = None
cpp_attribute_op = "."
+ extra_dereference = ""
is_temp = True
subexprs = ['sequence']
@@ -2921,6 +2924,8 @@ class CppIteratorNode(ExprNode):
return self
iter_type = begin.type.return_type
if iter_type.is_cpp_class:
+ if env.directives['cpp_locals']:
+ self.extra_dereference = "*"
if env.lookup_operator_for_types(
self.pos,
"!=",
@@ -2965,7 +2970,7 @@ class CppIteratorNode(ExprNode):
# make the temp a pointer so we are not sensitive to users reassigning
# the pointer than it came from
temp_type = PyrexTypes.CPtrType(sequence_type.ref_base_type)
- if temp_type.is_ptr:
+ if temp_type.is_ptr or code.globalstate.directives['cpp_locals']:
self.cpp_attribute_op = "->"
# 3) (otherwise) sequence comes from a function call or similar, so we must
# create a temp to store it in
@@ -2979,14 +2984,16 @@ class CppIteratorNode(ExprNode):
def generate_iter_next_result_code(self, result_name, code):
# end call isn't cached to support containers that allow adding while iterating
# (much as this is usually a bad idea)
- code.putln("if (!(%s != %s%send())) break;" % (
+ code.putln("if (!(%s%s != %s%send())) break;" % (
+ self.extra_dereference,
self.result(),
self.cpp_sequence_cname or self.sequence.result(),
self.cpp_attribute_op))
- code.putln("%s = *%s;" % (
+ code.putln("%s = *%s%s;" % (
result_name,
+ self.extra_dereference,
self.result()))
- code.putln("++%s;" % self.result())
+ code.putln("++%s%s;" % (self.extra_dereference, self.result()))
def free_temps(self, code):
if self.cpp_sequence_cname:
@@ -7162,9 +7169,6 @@ class AttributeNode(ExprNode):
self.op = "->"
elif obj_type.is_reference and obj_type.is_fake_reference:
self.op = "->"
- elif (obj_type.is_cpp_class and (self.obj.is_name or self.obj.is_attribute) and
- self.obj.entry and self.obj.entry.is_cpp_optional):
- self.op = "->"
else:
self.op = "."
if obj_type.has_attributes:
@@ -7297,9 +7301,14 @@ class AttributeNode(ExprNode):
return NameNode.is_ephemeral(self)
def calculate_result_code(self):
- #print "AttributeNode.calculate_result_code:", self.member ###
- #print "...obj node =", self.obj, "code", self.obj.result() ###
- #print "...obj type", self.obj.type, "ctype", self.obj.ctype() ###
+ result = self.calculate_access_code()
+ if self.entry and self.entry.is_cpp_optional and not self.is_target:
+ result = "(*%s)" % result
+ return result
+
+ def calculate_access_code(self):
+ # Does the job of calculate_result_code but doesn't dereference cpp_optionals
+ # Therefore allowing access to the holder variable
obj = self.obj
obj_code = obj.result_as(obj.type)
#print "...obj_code =", obj_code ###
@@ -7374,7 +7383,12 @@ class AttributeNode(ExprNode):
'%s'
'}' % (self.result(), code.error_goto(self.pos)))
elif self.entry.is_cpp_optional and self.initialized_check:
- unbound_check_code = self.type.cpp_optional_check_for_null_code(self.result())
+ if self.is_target:
+ undereferenced_result = self.result()
+ else:
+ assert not self.is_temp # calculate_access_code() only makes sense for non-temps
+ undereferenced_result = self.calculate_access_code()
+ unbound_check_code = self.type.cpp_optional_check_for_null_code(undereferenced_result)
code.put_error_if_unbound(self.pos, self.entry, unbound_check_code=unbound_check_code)
else:
# result_code contains what is needed, but we may need to insert