Commit 40f879db authored by root's avatar root

Added reference tracking to template arguments. Not fully tested, complete solution to ticket #838.

parent 5284bb23
# Can be enabled at the command line with --debug-xxx.
debug_disposal_code = 0
debug_temp_alloc = 0
debug_temp_alloc = 1
debug_coercion = 0
# Write comments into the C code that show where temporary variables
......
......@@ -1110,7 +1110,7 @@ class TemplatedTypeNode(CBaseTypeNode):
error(template_node.pos, "unknown type in template argument")
return error_type
template_types.append(type)
self.type = base_type.specialize_here(self.pos, template_types)
self.type = base_type.specialize_here(self.pos, template_types, is_reference=self.is_reference)
elif base_type.is_pyobject:
# Buffer
......@@ -2821,7 +2821,6 @@ class DefNode(FuncDefNode):
error(arg.pos, "Only Python type arguments can have 'not None'")
if arg.or_none:
error(arg.pos, "Only Python type arguments can have 'or None'")
env.fused_to_specific = f2s
def analyse_signature(self, env):
......
......@@ -2168,7 +2168,8 @@ def p_buffer_or_template(s, base_type_node, templates):
result = Nodes.TemplatedTypeNode(pos,
positional_args = positional_args,
keyword_args = keyword_dict,
base_type_node = base_type_node)
base_type_node = base_type_node,
is_reference = (s.sy == '&'))
return result
def p_bracketed_base_type(s, base_type_node, nonempty, empty):
......@@ -2392,7 +2393,7 @@ def p_c_array_declarator(s, base):
s.expect(']')
return Nodes.CArrayDeclaratorNode(pos, base = base, dimension = dim)
def p_c_func_declarator(s, pos, ctx, base, cmethod_flag):
def p_c_func_declarator(s, pos, ctx, base, cmethod_flag):
# Opening paren has already been skipped
args = p_c_arg_list(s, ctx, cmethod_flag = cmethod_flag,
nonempty_declarators = 0)
......
......@@ -12,7 +12,7 @@ from .Code import UtilityCode, LazyUtilityCode, TempitaUtilityCode
from . import StringEncoding
from . import Naming
from .Errors import error
from .Errors import error, warning
class BaseType(object):
......@@ -3217,7 +3217,7 @@ class CppClassType(CType):
subtypes = ['templates']
def __init__(self, name, scope, cname, base_classes, templates = None, template_type = None):
def __init__(self, name, scope, cname, base_classes, templates = None, template_type = None, is_reference = False):
self.name = name
self.cname = cname
self.scope = scope
......@@ -3227,6 +3227,7 @@ class CppClassType(CType):
self.template_type = template_type
self.specializations = {}
self.is_cpp_string = cname in cpp_string_conversions
self.is_reference = is_reference
def use_conversion_utility(self, from_or_to):
pass
......@@ -3286,6 +3287,10 @@ class CppClassType(CType):
tags = type_identifier(self),
else:
cls = self.cname[5:]
if self.is_reference:
warning("dwqkokw", -1)
print "warned"
cname = '__pyx_convert_%s_from_py_%s' % (cls, '__and_'.join(tags))
context = {
'template_type_declarations': '\n'.join(declarations),
......@@ -3350,7 +3355,7 @@ class CppClassType(CType):
T.get_fused_types(result, seen)
return result
def specialize_here(self, pos, template_values = None):
def specialize_here(self, pos, template_values = None, is_reference = False):
if not self.is_template_type():
error(pos, "'%s' type is not a template" % self)
return error_type
......@@ -3366,19 +3371,19 @@ class CppClassType(CType):
"Python object type '%s' cannot be used as a template argument" % value)
if has_object_template_param:
return error_type
return self.specialize(dict(zip(self.templates, template_values)))
return self.specialize(dict(zip(self.templates, template_values)), is_reference)
def specialize(self, values):
def specialize(self, values, is_reference = False):
if not self.templates and not self.namespace:
return self
if self.templates is None:
self.templates = []
key = tuple(values.items())
key = tuple(values.items() + [is_reference]) # Python 3?
if key in self.specializations:
return self.specializations[key]
template_values = [t.specialize(values) for t in self.templates]
specialized = self.specializations[key] = \
CppClassType(self.name, None, self.cname, [], template_values, template_type=self)
CppClassType(self.name, None, self.cname, [], template_values, template_type=self, is_reference=is_reference)
# Need to do these *after* self.specializations[key] is set
# to avoid infinite recursion on circular references.
specialized.base_classes = [b.specialize(values) for b in self.base_classes]
......
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