Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Gwenaël Samain
cython
Commits
ec5a056e
Commit
ec5a056e
authored
Apr 10, 2017
by
Jeroen Demeyer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support for "volatile" keyword
parent
4b64bbe1
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
158 additions
and
74 deletions
+158
-74
Cython/Compiler/Code.py
Cython/Compiler/Code.py
+2
-2
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+4
-4
Cython/Compiler/MemoryView.py
Cython/Compiler/MemoryView.py
+1
-1
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+5
-3
Cython/Compiler/Parsing.py
Cython/Compiler/Parsing.py
+22
-7
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+76
-46
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+12
-8
Cython/Compiler/TypeInference.py
Cython/Compiler/TypeInference.py
+2
-2
tests/compile/volatile.pyx
tests/compile/volatile.pyx
+17
-0
tests/errors/const_decl_errors.pyx
tests/errors/const_decl_errors.pyx
+4
-1
tests/errors/duplicate_const.pyx
tests/errors/duplicate_const.pyx
+13
-0
No files found.
Cython/Compiler/Code.py
View file @
ec5a056e
...
@@ -822,8 +822,8 @@ class FunctionState(object):
...
@@ -822,8 +822,8 @@ class FunctionState(object):
A C string referring to the variable is returned.
A C string referring to the variable is returned.
"""
"""
if type.is_c
onst
and not type.is_reference:
if type.is_c
v_qualified
and not type.is_reference:
type = type.c
onst
_base_type
type = type.c
v
_base_type
elif type.is_reference and not type.is_fake_reference:
elif type.is_reference and not type.is_fake_reference:
type = type.ref_base_type
type = type.ref_base_type
if not type.is_pyobject and not type.is_memoryviewslice:
if not type.is_pyobject and not type.is_memoryviewslice:
...
...
Cython/Compiler/ExprNodes.py
View file @
ec5a056e
...
@@ -881,8 +881,8 @@ class ExprNode(Node):
...
@@ -881,8 +881,8 @@ class ExprNode(Node):
if
used_as_reference
and
not
src_type
.
is_reference
:
if
used_as_reference
and
not
src_type
.
is_reference
:
dst_type
=
dst_type
.
ref_base_type
dst_type
=
dst_type
.
ref_base_type
if
src_type
.
is_c
onst
:
if
src_type
.
is_c
v_qualified
:
src_type
=
src_type
.
c
onst
_base_type
src_type
=
src_type
.
c
v
_base_type
if
src_type
.
is_fused
or
dst_type
.
is_fused
:
if
src_type
.
is_fused
or
dst_type
.
is_fused
:
# See if we are coercing a fused function to a pointer to a
# See if we are coercing a fused function to a pointer to a
...
@@ -2868,8 +2868,8 @@ class NextNode(AtomicExprNode):
...
@@ -2868,8 +2868,8 @@ class NextNode(AtomicExprNode):
item_type
=
env
.
lookup_operator_for_types
(
self
.
pos
,
"*"
,
[
iterator_type
]).
type
.
return_type
item_type
=
env
.
lookup_operator_for_types
(
self
.
pos
,
"*"
,
[
iterator_type
]).
type
.
return_type
if
item_type
.
is_reference
:
if
item_type
.
is_reference
:
item_type
=
item_type
.
ref_base_type
item_type
=
item_type
.
ref_base_type
if
item_type
.
is_c
onst
:
if
item_type
.
is_c
v_qualified
:
item_type
=
item_type
.
c
onst
_base_type
item_type
=
item_type
.
c
v
_base_type
return
item_type
return
item_type
else
:
else
:
# Avoid duplication of complicated logic.
# Avoid duplication of complicated logic.
...
...
Cython/Compiler/MemoryView.py
View file @
ec5a056e
...
@@ -487,7 +487,7 @@ def copy_c_or_fortran_cname(memview):
...
@@ -487,7 +487,7 @@ def copy_c_or_fortran_cname(memview):
def
get_copy_new_utility
(
pos
,
from_memview
,
to_memview
):
def
get_copy_new_utility
(
pos
,
from_memview
,
to_memview
):
if
(
from_memview
.
dtype
!=
to_memview
.
dtype
and
if
(
from_memview
.
dtype
!=
to_memview
.
dtype
and
not
(
from_memview
.
dtype
.
is_c
onst
and
from_memview
.
dtype
.
const
_base_type
==
to_memview
.
dtype
)):
not
(
from_memview
.
dtype
.
is_c
v_qualified
and
from_memview
.
dtype
.
cv
_base_type
==
to_memview
.
dtype
)):
error
(
pos
,
"dtypes must be the same!"
)
error
(
pos
,
"dtypes must be the same!"
)
return
return
if
len
(
from_memview
.
axes
)
!=
len
(
to_memview
.
axes
):
if
len
(
from_memview
.
axes
)
!=
len
(
to_memview
.
axes
):
...
...
Cython/Compiler/Nodes.py
View file @
ec5a056e
...
@@ -1273,8 +1273,10 @@ class FusedTypeNode(CBaseTypeNode):
...
@@ -1273,8 +1273,10 @@ class FusedTypeNode(CBaseTypeNode):
return
PyrexTypes
.
FusedType
(
types
,
name
=
self
.
name
)
return
PyrexTypes
.
FusedType
(
types
,
name
=
self
.
name
)
class
CConstTypeNode
(
CBaseTypeNode
):
class
CConst
OrVolatile
TypeNode
(
CBaseTypeNode
):
# base_type CBaseTypeNode
# base_type CBaseTypeNode
# is_const boolean
# is_volatile boolean
child_attrs
=
[
"base_type"
]
child_attrs
=
[
"base_type"
]
...
@@ -1282,8 +1284,8 @@ class CConstTypeNode(CBaseTypeNode):
...
@@ -1282,8 +1284,8 @@ class CConstTypeNode(CBaseTypeNode):
base
=
self
.
base_type
.
analyse
(
env
,
could_be_name
)
base
=
self
.
base_type
.
analyse
(
env
,
could_be_name
)
if
base
.
is_pyobject
:
if
base
.
is_pyobject
:
error
(
self
.
pos
,
error
(
self
.
pos
,
"Const base type cannot be a Python object"
)
"Const
/volatile
base type cannot be a Python object"
)
return
PyrexTypes
.
c_const_
type
(
bas
e
)
return
PyrexTypes
.
c_const_
or_volatile_type
(
base
,
self
.
is_const
,
self
.
is_volatil
e
)
class
CVarDefNode
(
StatNode
):
class
CVarDefNode
(
StatNode
):
...
...
Cython/Compiler/Parsing.py
View file @
ec5a056e
...
@@ -317,8 +317,8 @@ def p_typecast(s):
...
@@ -317,8 +317,8 @@ def p_typecast(s):
base_type
=
p_c_base_type
(
s
)
base_type
=
p_c_base_type
(
s
)
is_memslice
=
isinstance
(
base_type
,
Nodes
.
MemoryViewSliceTypeNode
)
is_memslice
=
isinstance
(
base_type
,
Nodes
.
MemoryViewSliceTypeNode
)
is_template
=
isinstance
(
base_type
,
Nodes
.
TemplatedTypeNode
)
is_template
=
isinstance
(
base_type
,
Nodes
.
TemplatedTypeNode
)
is_const
=
isinstance
(
base_type
,
Nodes
.
CConst
TypeNode
)
is_const
_volatile
=
isinstance
(
base_type
,
Nodes
.
CConstOrVolatile
TypeNode
)
if
(
not
is_memslice
and
not
is_template
and
not
is_const
if
(
not
is_memslice
and
not
is_template
and
not
is_const
_volatile
and
base_type
.
name
is
None
):
and
base_type
.
name
is
None
):
s
.
error
(
"Unknown type"
)
s
.
error
(
"Unknown type"
)
declarator
=
p_c_declarator
(
s
,
empty
=
1
)
declarator
=
p_c_declarator
(
s
,
empty
=
1
)
...
@@ -2479,16 +2479,31 @@ def p_c_simple_base_type(s, self_flag, nonempty, templates = None):
...
@@ -2479,16 +2479,31 @@ def p_c_simple_base_type(s, self_flag, nonempty, templates = None):
complex
=
0
complex
=
0
module_path
=
[]
module_path
=
[]
pos
=
s
.
position
()
pos
=
s
.
position
()
if
not
s
.
sy
==
'IDENT'
:
error
(
pos
,
"Expected an identifier, found '%s'"
%
s
.
sy
)
# Handle const/volatile
if
s
.
systring
==
'const'
:
is_const
=
is_volatile
=
0
while
True
:
if
s
.
systring
==
'const'
:
if
is_const
:
error
(
pos
,
"Duplicate 'const'"
)
is_const
=
1
elif
s
.
systring
==
'volatile'
:
if
is_volatile
:
error
(
pos
,
"Duplicate 'volatile'"
)
is_volatile
=
1
else
:
break
s
.
next
()
s
.
next
()
if
is_const
or
is_volatile
:
base_type
=
p_c_base_type
(
s
,
self_flag
=
self_flag
,
nonempty
=
nonempty
,
templates
=
templates
)
base_type
=
p_c_base_type
(
s
,
self_flag
=
self_flag
,
nonempty
=
nonempty
,
templates
=
templates
)
if
isinstance
(
base_type
,
Nodes
.
MemoryViewSliceTypeNode
):
if
isinstance
(
base_type
,
Nodes
.
MemoryViewSliceTypeNode
):
# reverse order to avoid having to write "(const int)[:]"
# reverse order to avoid having to write "(const int)[:]"
base_type
.
base_type_node
=
Nodes
.
CConstTypeNode
(
pos
,
base_type
=
base_type
.
base_type_node
)
base_type
.
base_type_node
=
Nodes
.
CConstOrVolatileTypeNode
(
pos
,
base_type
=
base_type
.
base_type_node
,
is_const
=
is_const
,
is_volatile
=
is_volatile
)
return
base_type
return
base_type
return
Nodes
.
CConstTypeNode
(
pos
,
base_type
=
base_type
)
return
Nodes
.
CConstOrVolatileTypeNode
(
pos
,
base_type
=
base_type
,
is_const
=
is_const
,
is_volatile
=
is_volatile
)
if
s
.
sy
!=
'IDENT'
:
error
(
pos
,
"Expected an identifier, found '%s'"
%
s
.
sy
)
if
looking_at_base_type
(
s
):
if
looking_at_base_type
(
s
):
#print "p_c_simple_base_type: looking_at_base_type at", s.position()
#print "p_c_simple_base_type: looking_at_base_type at", s.position()
is_basic
=
1
is_basic
=
1
...
...
Cython/Compiler/PyrexTypes.py
View file @
ec5a056e
...
@@ -176,7 +176,9 @@ class PyrexType(BaseType):
...
@@ -176,7 +176,9 @@ class PyrexType(BaseType):
# is_ptr boolean Is a C pointer type
# is_ptr boolean Is a C pointer type
# is_null_ptr boolean Is the type of NULL
# is_null_ptr boolean Is the type of NULL
# is_reference boolean Is a C reference type
# is_reference boolean Is a C reference type
# is_const boolean Is a C const type.
# is_const boolean Is a C const type
# is_volatile boolean Is a C volatile type
# is_cv_qualified boolean Is a C const or volatile type
# is_cfunction boolean Is a C function type
# is_cfunction boolean Is a C function type
# is_struct_or_union boolean Is a C struct or union type
# is_struct_or_union boolean Is a C struct or union type
# is_struct boolean Is a C struct type
# is_struct boolean Is a C struct type
...
@@ -236,6 +238,8 @@ class PyrexType(BaseType):
...
@@ -236,6 +238,8 @@ class PyrexType(BaseType):
is_null_ptr
=
0
is_null_ptr
=
0
is_reference
=
0
is_reference
=
0
is_const
=
0
is_const
=
0
is_volatile
=
0
is_cv_qualified
=
0
is_cfunction
=
0
is_cfunction
=
0
is_struct_or_union
=
0
is_struct_or_union
=
0
is_cpp_class
=
0
is_cpp_class
=
0
...
@@ -713,8 +717,8 @@ class MemoryViewSliceType(PyrexType):
...
@@ -713,8 +717,8 @@ class MemoryViewSliceType(PyrexType):
to_axes_f
=
contig_dim
+
follow_dim
*
(
ndim
-
1
)
to_axes_f
=
contig_dim
+
follow_dim
*
(
ndim
-
1
)
dtype
=
self
.
dtype
dtype
=
self
.
dtype
if
dtype
.
is_c
onst
:
if
dtype
.
is_c
v_qualified
:
dtype
=
dtype
.
c
onst
_base_type
dtype
=
dtype
.
c
v
_base_type
to_memview_c
=
MemoryViewSliceType
(
dtype
,
to_axes_c
)
to_memview_c
=
MemoryViewSliceType
(
dtype
,
to_axes_c
)
to_memview_f
=
MemoryViewSliceType
(
dtype
,
to_axes_f
)
to_memview_f
=
MemoryViewSliceType
(
dtype
,
to_axes_f
)
...
@@ -791,15 +795,18 @@ class MemoryViewSliceType(PyrexType):
...
@@ -791,15 +795,18 @@ class MemoryViewSliceType(PyrexType):
# return False
# return False
src_dtype
,
dst_dtype
=
src
.
dtype
,
dst
.
dtype
src_dtype
,
dst_dtype
=
src
.
dtype
,
dst
.
dtype
if
dst_dtype
.
is_const
:
# We can add but not remove const/volatile modifiers
# Requesting read-only views is always ok => consider only the non-const base type.
# (except if we are copying by value, then anything is fine)
dst_dtype
=
dst_dtype
.
const_base_type
if
not
copying
:
if
src_dtype
.
is_const
:
if
src_dtype
.
is_const
and
not
dst_dtype
.
is_const
:
# When assigning between read-only views, compare only the non-const base types.
return
False
src_dtype
=
src_dtype
.
const_base_type
if
src_dtype
.
is_volatile
and
not
dst_dtype
.
is_volatile
:
elif
copying
and
src_dtype
.
is_const
:
return
False
# Copying by value => ignore const on source.
# const/volatile checks are done, remove those qualifiers
src_dtype
=
src_dtype
.
const_base_type
if
src_dtype
.
is_cv_qualified
:
src_dtype
=
src_dtype
.
cv_base_type
if
dst_dtype
.
is_cv_qualified
:
dst_dtype
=
dst_dtype
.
cv_base_type
if
src_dtype
!=
dst_dtype
:
if
src_dtype
!=
dst_dtype
:
return
False
return
False
...
@@ -1558,58 +1565,74 @@ class PythranExpr(CType):
...
@@ -1558,58 +1565,74 @@ class PythranExpr(CType):
return
hash
(
self
.
pythran_type
)
return
hash
(
self
.
pythran_type
)
class
CConstType
(
BaseType
):
class
CConstOrVolatileType
(
BaseType
):
"A C const or volatile type"
is_c
onst
=
1
is_c
v_qualified
=
1
def
__init__
(
self
,
const_base_type
):
def
__init__
(
self
,
base_type
,
is_const
=
0
,
is_volatile
=
0
):
self
.
const_base_type
=
const_base_type
self
.
cv_base_type
=
base_type
if
const_base_type
.
has_attributes
and
const_base_type
.
scope
is
not
None
:
self
.
is_const
=
is_const
from
.
import
Symtab
self
.
is_volatile
=
is_volatile
self
.
scope
=
Symtab
.
CConstScope
(
const_base_type
.
scope
)
if
base_type
.
has_attributes
and
base_type
.
scope
is
not
None
:
from
.Symtab
import
CConstOrVolatileScope
self
.
scope
=
CConstOrVolatileScope
(
base_type
.
scope
,
is_const
,
is_volatile
)
def
cv_string
(
self
):
cvstring
=
""
if
self
.
is_const
:
cvstring
=
"const "
+
cvstring
if
self
.
is_volatile
:
cvstring
=
"volatile "
+
cvstring
return
cvstring
def
__repr__
(
self
):
def
__repr__
(
self
):
return
"<CConst
Type %s>"
%
repr
(
self
.
const
_base_type
)
return
"<CConst
OrVolatileType %s%r>"
%
(
self
.
cv_string
(),
self
.
cv
_base_type
)
def
__str__
(
self
):
def
__str__
(
self
):
return
self
.
declaration_code
(
""
,
for_display
=
1
)
return
self
.
declaration_code
(
""
,
for_display
=
1
)
def
declaration_code
(
self
,
entity_code
,
def
declaration_code
(
self
,
entity_code
,
for_display
=
0
,
dll_linkage
=
None
,
pyrex
=
0
):
for_display
=
0
,
dll_linkage
=
None
,
pyrex
=
0
):
cv
=
self
.
cv_string
()
if
for_display
or
pyrex
:
if
for_display
or
pyrex
:
return
"const "
+
self
.
const
_base_type
.
declaration_code
(
entity_code
,
for_display
,
dll_linkage
,
pyrex
)
return
cv
+
self
.
cv
_base_type
.
declaration_code
(
entity_code
,
for_display
,
dll_linkage
,
pyrex
)
else
:
else
:
return
self
.
c
onst_base_type
.
declaration_code
(
"const %s"
%
entity_code
,
for_display
,
dll_linkage
,
pyrex
)
return
self
.
c
v_base_type
.
declaration_code
(
cv
+
entity_code
,
for_display
,
dll_linkage
,
pyrex
)
def
specialize
(
self
,
values
):
def
specialize
(
self
,
values
):
base_type
=
self
.
c
onst
_base_type
.
specialize
(
values
)
base_type
=
self
.
c
v
_base_type
.
specialize
(
values
)
if
base_type
==
self
.
c
onst
_base_type
:
if
base_type
==
self
.
c
v
_base_type
:
return
self
return
self
else
:
return
CConstOrVolatileType
(
base_type
,
return
CConstType
(
base_typ
e
)
self
.
is_const
,
self
.
is_volatil
e
)
def
deduce_template_params
(
self
,
actual
):
def
deduce_template_params
(
self
,
actual
):
return
self
.
c
onst
_base_type
.
deduce_template_params
(
actual
)
return
self
.
c
v
_base_type
.
deduce_template_params
(
actual
)
def
can_coerce_to_pyobject
(
self
,
env
):
def
can_coerce_to_pyobject
(
self
,
env
):
return
self
.
c
onst
_base_type
.
can_coerce_to_pyobject
(
env
)
return
self
.
c
v
_base_type
.
can_coerce_to_pyobject
(
env
)
def
can_coerce_from_pyobject
(
self
,
env
):
def
can_coerce_from_pyobject
(
self
,
env
):
return
self
.
c
onst
_base_type
.
can_coerce_from_pyobject
(
env
)
return
self
.
c
v
_base_type
.
can_coerce_from_pyobject
(
env
)
def
create_to_py_utility_code
(
self
,
env
):
def
create_to_py_utility_code
(
self
,
env
):
if
self
.
c
onst
_base_type
.
create_to_py_utility_code
(
env
):
if
self
.
c
v
_base_type
.
create_to_py_utility_code
(
env
):
self
.
to_py_function
=
self
.
c
onst
_base_type
.
to_py_function
self
.
to_py_function
=
self
.
c
v
_base_type
.
to_py_function
return
True
return
True
def
same_as_resolved_type
(
self
,
other_type
):
def
same_as_resolved_type
(
self
,
other_type
):
if
other_type
.
is_c
onst
:
if
other_type
.
is_c
v_qualified
:
return
self
.
c
onst_base_type
.
same_as_resolved_type
(
other_type
.
const
_base_type
)
return
self
.
c
v_base_type
.
same_as_resolved_type
(
other_type
.
cv
_base_type
)
# Accept c
onst LHS <- non-const
RHS.
# Accept c
v LHS <- non-cv
RHS.
return
self
.
c
onst
_base_type
.
same_as_resolved_type
(
other_type
)
return
self
.
c
v
_base_type
.
same_as_resolved_type
(
other_type
)
def
__getattr__
(
self
,
name
):
def
__getattr__
(
self
,
name
):
return
getattr
(
self
.
const_base_type
,
name
)
return
getattr
(
self
.
cv_base_type
,
name
)
def
CConstType
(
base_type
):
return
CConstOrVolatileType
(
base_type
,
is_const
=
1
)
class
FusedType
(
CType
):
class
FusedType
(
CType
):
...
@@ -2302,8 +2325,8 @@ class CPointerBaseType(CType):
...
@@ -2302,8 +2325,8 @@ class CPointerBaseType(CType):
def
__init__
(
self
,
base_type
):
def
__init__
(
self
,
base_type
):
self
.
base_type
=
base_type
self
.
base_type
=
base_type
if
base_type
.
is_c
onst
:
if
base_type
.
is_c
v_qualified
:
base_type
=
base_type
.
c
onst
_base_type
base_type
=
base_type
.
c
v
_base_type
for
char_type
in
(
c_char_type
,
c_uchar_type
,
c_schar_type
):
for
char_type
in
(
c_char_type
,
c_uchar_type
,
c_schar_type
):
if
base_type
.
same_as
(
char_type
):
if
base_type
.
same_as
(
char_type
):
self
.
is_string
=
1
self
.
is_string
=
1
...
@@ -2527,8 +2550,8 @@ class CPtrType(CPointerBaseType):
...
@@ -2527,8 +2550,8 @@ class CPtrType(CPointerBaseType):
return
1
return
1
if
other_type
.
is_null_ptr
:
if
other_type
.
is_null_ptr
:
return
1
return
1
if
self
.
base_type
.
is_c
onst
:
if
self
.
base_type
.
is_c
v_qualified
:
self
=
CPtrType
(
self
.
base_type
.
c
onst
_base_type
)
self
=
CPtrType
(
self
.
base_type
.
c
v
_base_type
)
if
self
.
base_type
.
is_cfunction
:
if
self
.
base_type
.
is_cfunction
:
if
other_type
.
is_ptr
:
if
other_type
.
is_ptr
:
other_type
=
other_type
.
base_type
.
resolve
()
other_type
=
other_type
.
base_type
.
resolve
()
...
@@ -3709,8 +3732,8 @@ class CppClassType(CType):
...
@@ -3709,8 +3732,8 @@ class CppClassType(CType):
return
specialized
return
specialized
def
deduce_template_params
(
self
,
actual
):
def
deduce_template_params
(
self
,
actual
):
if
actual
.
is_c
onst
:
if
actual
.
is_c
v_qualified
:
actual
=
actual
.
c
onst
_base_type
actual
=
actual
.
c
v
_base_type
if
actual
.
is_reference
:
if
actual
.
is_reference
:
actual
=
actual
.
ref_base_type
actual
=
actual
.
ref_base_type
if
self
==
actual
:
if
self
==
actual
:
...
@@ -4452,10 +4475,10 @@ def widest_numeric_type(type1, type2):
...
@@ -4452,10 +4475,10 @@ def widest_numeric_type(type1, type2):
type1
=
type1
.
ref_base_type
type1
=
type1
.
ref_base_type
if
type2
.
is_reference
:
if
type2
.
is_reference
:
type2
=
type2
.
ref_base_type
type2
=
type2
.
ref_base_type
if
type1
.
is_c
onst
:
if
type1
.
is_c
v_qualified
:
type1
=
type1
.
c
onst
_base_type
type1
=
type1
.
c
v
_base_type
if
type2
.
is_c
onst
:
if
type2
.
is_c
v_qualified
:
type2
=
type2
.
c
onst
_base_type
type2
=
type2
.
c
v
_base_type
if
type1
==
type2
:
if
type1
==
type2
:
widest_type
=
type1
widest_type
=
type1
elif
type1
.
is_complex
or
type2
.
is_complex
:
elif
type1
.
is_complex
or
type2
.
is_complex
:
...
@@ -4675,6 +4698,13 @@ def c_const_type(base_type):
...
@@ -4675,6 +4698,13 @@ def c_const_type(base_type):
else
:
else
:
return
CConstType
(
base_type
)
return
CConstType
(
base_type
)
def
c_const_or_volatile_type
(
base_type
,
is_const
,
is_volatile
):
# Construct a C const/volatile type.
if
base_type
is
error_type
:
return
error_type
else
:
return
CConstOrVolatileType
(
base_type
,
is_const
,
is_volatile
)
def
same_type
(
type1
,
type2
):
def
same_type
(
type1
,
type2
):
return
type1
.
same_as
(
type2
)
return
type1
.
same_as
(
type2
)
...
...
Cython/Compiler/Symtab.py
View file @
ec5a056e
...
@@ -2523,23 +2523,27 @@ class PropertyScope(Scope):
...
@@ -2523,23 +2523,27 @@ class PropertyScope(Scope):
return
None
return
None
class
CConstScope
(
Scope
):
class
CConst
OrVolatile
Scope
(
Scope
):
def
__init__
(
self
,
const_base_type_scope
):
def
__init__
(
self
,
base_type_scope
,
is_const
=
0
,
is_volatile
=
0
):
Scope
.
__init__
(
Scope
.
__init__
(
self
,
self
,
'const_'
+
const_base_type_scope
.
name
,
'cv_'
+
base_type_scope
.
name
,
const_base_type_scope
.
outer_scope
,
base_type_scope
.
outer_scope
,
const_base_type_scope
.
parent_scope
)
base_type_scope
.
parent_scope
)
self
.
const_base_type_scope
=
const_base_type_scope
self
.
base_type_scope
=
base_type_scope
self
.
is_const
=
is_const
self
.
is_volatile
=
is_volatile
def
lookup_here
(
self
,
name
):
def
lookup_here
(
self
,
name
):
entry
=
self
.
const_
base_type_scope
.
lookup_here
(
name
)
entry
=
self
.
base_type_scope
.
lookup_here
(
name
)
if
entry
is
not
None
:
if
entry
is
not
None
:
entry
=
copy
.
copy
(
entry
)
entry
=
copy
.
copy
(
entry
)
entry
.
type
=
PyrexTypes
.
c_const_type
(
entry
.
type
)
entry
.
type
=
PyrexTypes
.
c_const_or_volatile_type
(
entry
.
type
,
self
.
is_const
,
self
.
is_volatile
)
return
entry
return
entry
class
TemplateScope
(
Scope
):
class
TemplateScope
(
Scope
):
def
__init__
(
self
,
name
,
outer_scope
):
def
__init__
(
self
,
name
,
outer_scope
):
Scope
.
__init__
(
self
,
name
,
outer_scope
,
None
)
Scope
.
__init__
(
self
,
name
,
outer_scope
,
None
)
...
...
Cython/Compiler/TypeInference.py
View file @
ec5a056e
...
@@ -533,8 +533,8 @@ def find_spanning_type(type1, type2):
...
@@ -533,8 +533,8 @@ def find_spanning_type(type1, type2):
def
simply_type
(
result_type
,
pos
):
def
simply_type
(
result_type
,
pos
):
if
result_type
.
is_reference
:
if
result_type
.
is_reference
:
result_type
=
result_type
.
ref_base_type
result_type
=
result_type
.
ref_base_type
if
result_type
.
is_c
onst
:
if
result_type
.
is_c
v_qualified
:
result_type
=
result_type
.
c
onst
_base_type
result_type
=
result_type
.
c
v
_base_type
if
result_type
.
is_cpp_class
:
if
result_type
.
is_cpp_class
:
result_type
.
check_nullary_constructor
(
pos
)
result_type
.
check_nullary_constructor
(
pos
)
if
result_type
.
is_array
:
if
result_type
.
is_array
:
...
...
tests/compile/volatile.pyx
0 → 100644
View file @
ec5a056e
# mode: compile
cdef
volatile
int
x
=
1
cdef
const
volatile
char
*
greeting1
=
"hello world"
cdef
volatile
const
char
*
greeting2
=
"goodbye"
cdef
extern
from
"stdlib.h"
:
volatile
void
*
malloc
(
size_t
)
cdef
volatile
long
*
test
(
volatile
size_t
s
):
cdef
volatile
long
*
arr
=
<
long
*><
volatile
long
*>
malloc
(
s
)
return
arr
test
(
64
)
tests/errors/const_decl_errors.pyx
View file @
ec5a056e
...
@@ -19,9 +19,11 @@ cdef func(const int a, const int* b, const (int*) c, const S s, int *const d,
...
@@ -19,9 +19,11 @@ cdef func(const int a, const int* b, const (int*) c, const S s, int *const d,
d
=
NULL
d
=
NULL
t
=
&
s
t
=
&
s
cdef
volatile
object
v
_ERRORS
=
"""
_ERRORS
=
"""
3:5: Const base type cannot be a Python object
3:5: Const
/volatile
base type cannot be a Python object
8:5: Assignment to const 'x'
8:5: Assignment to const 'x'
15:4: Assignment to const 'a'
15:4: Assignment to const 'a'
16:4: Assignment to const 'c'
16:4: Assignment to const 'c'
...
@@ -29,4 +31,5 @@ _ERRORS = """
...
@@ -29,4 +31,5 @@ _ERRORS = """
18:5: Assignment to const attribute 'member'
18:5: Assignment to const attribute 'member'
19:4: Assignment to const 'd'
19:4: Assignment to const 'd'
20:4: Assignment to const 't'
20:4: Assignment to const 't'
22:5: Const/volatile base type cannot be a Python object
"""
"""
tests/errors/duplicate_const.pyx
0 → 100644
View file @
ec5a056e
# mode: error
cdef
extern
from
*
:
cdef
const
const
int
a
cdef
const
volatile
int
b
cdef
volatile
const
int
c
cdef
volatile
volatile
int
d
_ERRORS
=
"""
4:9: Duplicate 'const'
7:9: Duplicate 'volatile'
"""
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment