Commit f6afb399 authored by Xavier Thompson's avatar Xavier Thompson

Generate code correctly for 'const' cypclasses

parent 9ebbdf8a
......@@ -842,7 +842,7 @@ class FunctionState(object):
A C string referring to the variable is returned.
"""
if type.is_cv_qualified and not type.is_reference:
if type.is_cv_qualified and not type.is_reference and not type.is_cyp_class:
type = type.cv_base_type
elif type.is_reference and not type.is_fake_reference:
type = type.ref_base_type
......
......@@ -2099,7 +2099,7 @@ class NameNode(AtomicExprNode):
entry = self.entry = entry.as_variable
self.type = entry.type
if self.type.is_const:
if self.type.is_const and not self.type.is_cyp_class:
error(self.pos, "Assignment to const '%s'" % self.name)
if self.type.is_reference:
error(self.pos, "Assignment to reference '%s'" % self.name)
......
......@@ -1847,8 +1847,6 @@ class CConstOrVolatileType(BaseType):
def cv_string(self):
cvstring = ""
if self.is_cyp_class:
return cvstring
if self.is_const:
cvstring = "const " + cvstring
if self.is_volatile:
......@@ -1866,9 +1864,18 @@ class CConstOrVolatileType(BaseType):
cv = self.cv_string()
if for_display or pyrex:
return cv + self.cv_base_type.declaration_code(entity_code, for_display, dll_linkage, pyrex)
elif self.cv_base_type.is_cyp_class:
return cv + self.cv_base_type.declaration_code(entity_code, for_display, dll_linkage, pyrex)
else:
return self.cv_base_type.declaration_code(cv + entity_code, for_display, dll_linkage, pyrex)
def empty_declaration_code(self):
if self.cv_base_type.is_cyp_class:
cv = self.cv_string()
return cv + self.cv_base_type.empty_declaration_code()
else:
return super(CConstOrVolatileType, self).empty_declaration_code()
def specialize(self, values):
base_type = self.cv_base_type.specialize(values)
if base_type == self.cv_base_type:
......@@ -1896,6 +1903,15 @@ class CConstOrVolatileType(BaseType):
# Accept cv LHS <- non-cv RHS.
return self.cv_base_type.same_as_resolved_type(other_type)
def as_argument_type(self):
if self.is_cyp_class:
# A const cypclass is actually a pointer to a const cypclass.
return self
else:
# This strips 'const' and 'volatile' qualifiers, which is not the documented goal
# but temporaries and Python function argument conversions rely on that.
return self.cv_base_type.as_argument_type()
def __getattr__(self, name):
return getattr(self.cv_base_type, name)
......
......@@ -3236,13 +3236,20 @@ class CConstOrVolatileScope(Scope):
self.base_type_scope = base_type_scope
self.is_const = is_const
self.is_volatile = is_volatile
self.cached_const_entries = {}
def lookup_here(self, name):
entry = self.base_type_scope.lookup_here(name)
if entry is not None:
entry = copy.copy(entry)
entry.type = PyrexTypes.c_const_or_volatile_type(
entry.type, self.is_const, self.is_volatile)
try:
return self.cached_const_entries[name]
except KeyError:
entry = self.base_type_scope.lookup_here(name)
if entry is not None:
entry = copy.copy(entry)
entry.type = PyrexTypes.c_const_or_volatile_type(
entry.type, self.is_const, self.is_volatile)
# The entry must be cached because otherwise a new type is created at
# each lookup, which can cause type inference to reinfer forever.
self.cached_const_entries[name] = entry
return entry
......
......@@ -536,7 +536,7 @@ def simply_type(result_type, pos):
result_type = result_type.checked_base_type
if result_type.is_reference:
result_type = result_type.ref_base_type
if result_type.is_cv_qualified:
if result_type.is_cv_qualified and not result_type.is_cyp_class:
result_type = result_type.cv_base_type
if result_type.is_cpp_class:
result_type.check_nullary_constructor(pos)
......
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