From: Volker Mische Date: Tue, 2 Apr 2013 17:08:26 +0000 (+0200) Subject: Add support for const pointers X-Git-Tag: 0.19b1~12^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5e1497371ee70fffb2deb6c7dab136cf6684f2df;p=platform%2Fupstream%2Fpython-cython.git Add support for const pointers --- diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index 0634f40..f4b3852 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -713,6 +713,19 @@ class CFuncDeclaratorNode(CDeclaratorNode): 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): # Item in a function declaration argument list. # diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py index ea1731b..dd665e2 100644 --- a/Cython/Compiler/Parsing.py +++ b/Cython/Compiler/Parsing.py @@ -2366,9 +2366,19 @@ def p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag, calling_convention = p_calling_convention(s) if s.sy == '*': s.next() - base = p_c_declarator(s, ctx, empty = empty, is_type = is_type, - cmethod_flag = cmethod_flag, - assignable = assignable, nonempty = nonempty) + if s.systring == 'const': + const_pos = s.position() + 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, base = base) elif s.sy == '**': # scanner returns this as a single token diff --git a/tests/compile/const_decl.pyx b/tests/compile/const_decl.pyx index fa293fb..5424c8f 100644 --- a/tests/compile/const_decl.pyx +++ b/tests/compile/const_decl.pyx @@ -1,11 +1,12 @@ # 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 b[0] b = NULL # OK, the pointer itself 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): cdef int k = x - const_args(x, &k, &k) + const_args(x, &k, &k, &k) diff --git a/tests/errors/const_decl_errors.pyx b/tests/errors/const_decl_errors.pyx index c04b1d2..48d7391 100644 --- a/tests/errors/const_decl_errors.pyx +++ b/tests/errors/const_decl_errors.pyx @@ -10,17 +10,22 @@ cdef const int x = 10 cdef struct S: 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 c = NULL b[0] = 100 s.member = 1000 + d = NULL + t = &s _ERRORS = """ 3:5: Const base type cannot be a Python object 8:5: Assignment to const 'x' -14:6: Assignment to const 'a' -15:6: Assignment to const 'c' -16:5: Assignment to const dereference -17:5: Assignment to const attribute 'member' +15:6: Assignment to const 'a' +16:6: Assignment to const 'c' +17:5: Assignment to const dereference +18:5: Assignment to const attribute 'member' +19:6: Assignment to const 'd' +20:6: Assignment to const 't' """