Commit 9c5ad7a0 authored by Xavier Thompson's avatar Xavier Thompson

Parse 'const' cypclasses as 'pointer to const'

parent e3aec038
......@@ -573,7 +573,7 @@ class CypclassLockTransform(Visitor.EnvTransform):
if setitem and len(setitem.type.args) == 2:
arg_type = setitem.type.args[1].type
if arg_type.is_cyp_class:
return self.lockcheck_written_or_read(rhs, reading=arg_type.is_const)
return self.lockcheck_written_or_read(rhs, reading=arg_type.is_const_cyp_class)
# else: should have caused a previous error
return rhs
......@@ -582,7 +582,7 @@ class CypclassLockTransform(Visitor.EnvTransform):
arg_locks = []
for arg in cyp_class_args:
# Mark each cypclass arguments as locked within the function body
arg_locks.append(self.stacklock(arg, "rlocked" if arg.type.is_const else "wlocked"))
arg_locks.append(self.stacklock(arg, "rlocked" if arg.type.is_const_cyp_class else "wlocked"))
with_body = lambda: self.visit(node.body)
self.with_nested_stacklocks(iter(arg_locks), with_body)
return node
......@@ -711,7 +711,7 @@ class CypclassLockTransform(Visitor.EnvTransform):
actual_nargs = len(node.args)
for i, formal_arg, actual_arg in zip(range(actual_nargs), func_type.args, node.args):
if formal_arg.type.is_cyp_class and actual_arg.type.is_cyp_class:
node.args[i] = self.lockcheck_written_or_read(actual_arg, reading=formal_arg.type.is_const)
node.args[i] = self.lockcheck_written_or_read(actual_arg, reading=formal_arg.type.is_const_cyp_class)
with self.accesscontext(reading=True):
self.visitchildren(node)
return node
......@@ -737,7 +737,7 @@ class CypclassLockTransform(Visitor.EnvTransform):
node.base = self.lockcheck_written_or_read(node.base, reading=func_type.is_const_method)
if len(func_type.args):
if func_type.args[0].type.is_cyp_class:
node.index = self.lockcheck_written_or_read(node.index, reading=func_type.args[0].type.is_const)
node.index = self.lockcheck_written_or_read(node.index, reading=func_type.args[0].type.is_const_cyp_class)
with self.accesscontext(reading=True):
self.visitchildren(node)
return node
......@@ -748,14 +748,14 @@ class CypclassLockTransform(Visitor.EnvTransform):
node.operand1 = self.lockcheck_written_or_read(node.operand1, reading=func_type.is_const_method)
arg_type = func_type.args[0].type
if arg_type.is_cyp_class:
node.operand2 = self.lockcheck_written_or_read(node.operand2, reading=arg_type.is_const)
node.operand2 = self.lockcheck_written_or_read(node.operand2, reading=arg_type.is_const_cyp_class)
elif len(func_type.args) == 2:
arg1_type = func_type.args[0].type
if arg1_type.is_cyp_class:
node.operand1 = self.lockcheck_written_or_read(node.operand1, reading=arg1_type.is_const)
node.operand1 = self.lockcheck_written_or_read(node.operand1, reading=arg1_type.is_const_cyp_class)
arg2_type = func_type.args[1].type
if arg2_type.is_cyp_class:
node.operand2 = self.lockcheck_written_or_read(node.operand2, reading=arg2_type.is_const)
node.operand2 = self.lockcheck_written_or_read(node.operand2, reading=arg2_type.is_const_cyp_class)
def visit_BinopNode(self, node):
func_type = node.op_func_type
......
......@@ -1307,6 +1307,11 @@ class CConstOrVolatileTypeNode(CBaseTypeNode):
if base.is_pyobject:
error(self.pos,
"Const/volatile base type cannot be a Python object")
if base.is_cyp_class:
if not self.is_const or self.is_volatile:
error(self.pos, "Cypclass doesn't support 'volatile' yet")
return base
return PyrexTypes.cyp_class_const_type(base)
return PyrexTypes.c_const_or_volatile_type(base, self.is_const, self.is_volatile)
......@@ -2726,7 +2731,7 @@ class CFuncDefNode(FuncDefNode):
_name, _type, _pos, _ = declarator.skipped_self
_cname = "this"
if self.is_const_method:
_type = PyrexTypes.CConstType(_type)
_type = PyrexTypes.cyp_class_const_type(_type)
entry = self.local_scope.declare(_name, _cname, _type, _pos, 'private')
entry.is_variable = 1
entry.is_self_arg = 1
......
......@@ -249,6 +249,7 @@ class PyrexType(BaseType):
is_struct_or_union = 0
is_cpp_class = 0
is_cyp_class = 0
is_const_cyp_class = 0
is_cpp_string = 0
is_struct = 0
is_enum = 0
......@@ -4551,6 +4552,66 @@ class CypClassType(CppClassType):
raise NotImplementedError("Cy_XDECREF_SET is not defined for decrementing a group of cyobjects")
class ConstCypclassType(BaseType):
"A const cypclass"
subtypes = ['const_base_type']
is_const_cyp_class = 1
def __init__(self, base_type):
assert base_type.is_cyp_class
self.const_base_type = base_type
if base_type.has_attributes and base_type.scope is not None:
from .Symtab import CConstOrVolatileScope
self.scope = CConstOrVolatileScope(base_type.scope, is_const = 1, is_volatile = 0)
def __repr__(self):
return "<ConstCypclassType %s%r>" % self.const_base_type
def __str__(self):
return self.declaration_code("", for_display=1)
def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0):
return "const %s" % self.const_base_type.declaration_code(entity_code, for_display, dll_linkage, pyrex)
def empty_declaration_code(self):
if self._empty_declaration is None:
self._empty_declaration = "const %s" % self.const_base_type.empty_declaration_code()
return self._empty_declaration
def specialize(self, values):
base_type = self.const_base_type.specialize(values)
if base_type == self.const_base_type:
return self
return ConstCypclassType(base_type)
def as_argument_type(self):
return self
def deduce_template_params(self, actual):
return self.const_base_type.deduce_template_params(actual)
def can_coerce_to_pyobject(self, env):
return self.const_base_type.can_coerce_to_pyobject(env)
def can_coerce_from_pyobject(self, env):
return self.const_base_type.can_coerce_from_pyobject(env)
def create_to_py_utility_code(self, env):
if self.const_base_type.create_to_py_utility_code(env):
self.to_py_function = self.const_base_type.to_py_function
return True
def same_as_resolved_type(self, other_type):
if other_type.is_const_cyp_class:
return self.const_base_type.same_as_resolved_type(other_type.const_base_type)
return 0
def __getattr__(self, name):
return getattr(self.const_base_type, name)
class TemplatePlaceholderType(CType):
is_template_typename = 1
......@@ -5437,6 +5498,13 @@ def c_const_or_volatile_type(base_type, is_const, is_volatile):
else:
return CConstOrVolatileType(base_type, is_const, is_volatile)
def cyp_class_const_type(base_type):
# Construct a Cypclass const type.
if base_type is error_type:
return error_type
else:
return ConstCypclassType(base_type)
def same_type(type1, type2):
return type1.same_as(type2)
......
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