Commit 5e149737 authored by Volker Mische's avatar Volker Mische

Add support for const pointers

parent 7538ecd2
...@@ -713,6 +713,19 @@ class CFuncDeclaratorNode(CDeclaratorNode): ...@@ -713,6 +713,19 @@ class CFuncDeclaratorNode(CDeclaratorNode):
func_type.op_arg_struct = PyrexTypes.c_ptr_type(op_args_struct.type) func_type.op_arg_struct = PyrexTypes.c_ptr_type(op_args_struct.type)
class CConstDeclaratorNode(CDeclaratorNode):
# base CDeclaratorNode
child_attrs = ["base"]
def analyse(self, base_type, env, nonempty = 0):
if base_type.is_pyobject:
error(self.pos,
"Const base type cannot be a Python object")
const = PyrexTypes.c_const_type(base_type)
return self.base.analyse(const, env, nonempty = nonempty)
class CArgDeclNode(Node): class CArgDeclNode(Node):
# Item in a function declaration argument list. # Item in a function declaration argument list.
# #
......
...@@ -2366,9 +2366,19 @@ def p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag, ...@@ -2366,9 +2366,19 @@ def p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag,
calling_convention = p_calling_convention(s) calling_convention = p_calling_convention(s)
if s.sy == '*': if s.sy == '*':
s.next() s.next()
base = p_c_declarator(s, ctx, empty = empty, is_type = is_type, if s.systring == 'const':
cmethod_flag = cmethod_flag, const_pos = s.position()
assignable = assignable, nonempty = nonempty) s.next()
const_base = p_c_declarator(s, ctx, empty = empty,
is_type = is_type,
cmethod_flag = cmethod_flag,
assignable = assignable,
nonempty = nonempty)
base = Nodes.CConstDeclaratorNode(const_pos, base = const_base)
else:
base = p_c_declarator(s, ctx, empty = empty, is_type = is_type,
cmethod_flag = cmethod_flag,
assignable = assignable, nonempty = nonempty)
result = Nodes.CPtrDeclaratorNode(pos, result = Nodes.CPtrDeclaratorNode(pos,
base = base) base = base)
elif s.sy == '**': # scanner returns this as a single token elif s.sy == '**': # scanner returns this as a single token
......
# mode: compile # mode: compile
cdef const_args(const int a, const int *b, const (int*) c): cdef const_args(const int a, const int *b, const (int*) c, int *const d):
print a print a
print b[0] print b[0]
b = NULL # OK, the pointer itself is not const b = NULL # OK, the pointer itself is not const
c[0] = 4 # OK, the value is not const c[0] = 4 # OK, the value is not const
d[0] = 7 # OK, the value is not const
def call_const_args(x): def call_const_args(x):
cdef int k = x cdef int k = x
const_args(x, &k, &k) const_args(x, &k, &k, &k)
...@@ -10,17 +10,22 @@ cdef const int x = 10 ...@@ -10,17 +10,22 @@ cdef const int x = 10
cdef struct S: cdef struct S:
int member int member
cdef func(const int a, const int* b, const (int*) c, const S s): cdef func(const int a, const int* b, const (int*) c, const S s, int *const d,
const S *const t):
a = 10 a = 10
c = NULL c = NULL
b[0] = 100 b[0] = 100
s.member = 1000 s.member = 1000
d = NULL
t = &s
_ERRORS = """ _ERRORS = """
3:5: Const base type cannot be a Python object 3:5: Const base type cannot be a Python object
8:5: Assignment to const 'x' 8:5: Assignment to const 'x'
14:6: Assignment to const 'a' 15:6: Assignment to const 'a'
15:6: Assignment to const 'c' 16:6: Assignment to const 'c'
16:5: Assignment to const dereference 17:5: Assignment to const dereference
17:5: Assignment to const attribute 'member' 18:5: Assignment to const attribute 'member'
19:6: Assignment to const 'd'
20:6: Assignment to const 't'
""" """
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