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
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
cython
Commits
df4856db
Commit
df4856db
authored
Sep 21, 2020
by
Xavier Thompson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Annotate looked-up method types with the qualifiers of their object
parent
379b2aca
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
113 additions
and
7 deletions
+113
-7
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+103
-1
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+10
-6
No files found.
Cython/Compiler/PyrexTypes.py
View file @
df4856db
...
...
@@ -180,6 +180,9 @@ class PyrexType(BaseType):
# 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_from_qualified boolean Is a method looked-up from a qualified type
# is_from_const boolean Is a method looked-up from a const type
# is_from_volatile boolean Is a method looked-up from a volatile type
# is_struct_or_union boolean Is a C struct or union type
# is_struct boolean Is a C struct type
# is_enum boolean Is a C enum type
...
...
@@ -246,6 +249,9 @@ class PyrexType(BaseType):
is_volatile
=
0
is_cv_qualified
=
0
is_cfunction
=
0
is_from_qualified
=
0
is_from_const
=
0
is_from_volatile
=
0
is_struct_or_union
=
0
is_cpp_class
=
0
is_cyp_class
=
0
...
...
@@ -1913,6 +1919,95 @@ def CConstType(base_type):
return
CConstOrVolatileType
(
base_type
,
is_const
=
1
)
class
QualifiedMethodType
(
BaseType
):
"A method looked-up from a qualified object"
subtypes
=
[
'method_base_type'
]
is_from_qualified
=
1
is_from_const
=
0
is_from_volatile
=
0
def
__init__
(
self
,
base_type
,
const
=
0
,
volatile
=
0
):
assert
isinstance
(
base_type
,
CFuncType
)
self
.
method_base_type
=
base_type
self
.
is_from_const
=
const
self
.
is_from_volatile
=
volatile
def
specialize
(
self
,
values
):
base_type
=
self
.
method_base_type
.
specialize
(
values
)
if
base_type
==
self
.
method_base_type
:
return
self
return
QualifiedMethodType
(
base_type
,
self
.
is_from_const
,
self
.
is_from_volatile
)
def
resolve
(
self
):
base_type
=
self
.
method_base_type
.
resolve
()
if
base_type
==
self
.
method_base_type
:
return
self
return
QualifiedMethodType
(
base_type
,
self
.
is_from_const
,
self
.
is_from_volatile
)
def
with_with_gil
(
self
,
with_gil
):
base_type
=
self
.
method_base_type
.
with_with_gil
()
if
base_type
==
self
.
method_base_type
:
return
self
return
QualifiedMethodType
(
base_type
,
self
.
is_from_const
,
self
.
is_from_volatile
)
def
as_argument_type
(
self
):
return
c_ptr_type
(
self
)
# All that follows is just to behave exactly like the underlying function type
def
__getattr__
(
self
,
name
):
return
getattr
(
self
.
method_base_type
,
name
)
# These are defined because the definitions in BaseType might bypass __getattr__
def
can_coerce_to_pyobject
(
self
,
env
):
return
self
.
method_base_type
.
can_coerce_to_pyobject
(
env
)
def
can_coerce_from_pyobject
(
self
,
env
):
return
self
.
method_base_type
.
can_coerce_from_pyobject
(
env
)
def
can_coerce_to_pystring
(
self
,
env
,
format_spec
=
None
):
return
self
.
method_base_type
.
can_coerce_to_pystring
(
env
,
format_spec
)
def
convert_to_pystring
(
self
,
cvalue
,
code
,
format_spec
=
None
):
return
self
.
method_base_type
.
convert_to_pystring
(
cvalue
,
code
,
format_spec
)
def
cast_code
(
self
,
expr_code
):
return
self
.
method_base_type
.
cast_code
(
expr_code
)
def
empty_declaration_code
(
self
):
return
self
.
method_base_type
.
empty_declaration_code
()
def
specialization_name
(
self
):
return
self
.
method_base_type
.
specialization_name
()
def
get_fused_types
(
self
,
result
=
None
,
seen
=
None
,
subtypes
=
None
):
return
self
.
method_base_type
.
get_fused_types
(
result
,
seen
,
subtypes
)
def
specialize_fused
(
self
,
env
):
return
self
.
method_base_type
.
specialize_fused
(
env
)
def
deduce_template_params
(
self
,
actual
):
return
self
.
method_base_type
.
deduce_template_params
def
__lt__
(
self
,
other
):
return
self
.
method_base_type
.
__lt__
(
other
)
def
py_type_name
(
self
):
return
self
.
method_base_type
.
py_type_name
()
def
typeof_name
(
self
):
return
self
.
method_base_type
.
typeof_name
()
def
check_for_null_code
(
self
,
cname
):
return
self
.
method_base_type
.
check_for_null_code
(
cname
)
def
invalid_value
(
self
):
return
self
.
method_base_type
.
invalid_value
()
class
FusedType
(
CType
):
"""
Represents a Fused Type. All it needs to do is keep track of the types
...
...
@@ -5171,7 +5266,7 @@ def best_match(arg_types, functions, pos=None, env=None, args=None, throw=False)
errors
.
append
((
func
,
error_mesg
))
continue
# Skip non_const methods called on const object
if
func_type
.
is_const
and
not
func_type
.
is_const_method
and
not
func_type
.
is_static_method
:
if
func_type
.
is_
from_
const
and
not
func_type
.
is_const_method
and
not
func_type
.
is_static_method
:
# Impose const-correctness only on cypclass methods for now
if
func_type
.
is_cyp_class_method
:
error_mesg
=
"Cannot call non-const method on const object"
...
...
@@ -5567,6 +5662,13 @@ def cyp_class_const_type(base_type):
else
:
return
ConstCypclassType
(
base_type
)
def
qualified_method_type
(
base_type
,
const
,
volatile
):
# Construct a proxy type for methods looked-up from qualified objects.
if
base_type
is
error_type
:
return
error_type
else
:
return
QualifiedMethodType
(
base_type
,
const
,
volatile
)
def
same_type
(
type1
,
type2
):
return
type1
.
same_as
(
type2
)
...
...
Cython/Compiler/Symtab.py
View file @
df4856db
...
...
@@ -3253,21 +3253,25 @@ class CConstOrVolatileScope(Scope):
return
self
.
cached_const_or_volatile_entries
[
name
]
except
KeyError
:
entry
=
self
.
base_type_scope
.
lookup_here
(
name
)
if
entry
is
not
None
and
not
entry
.
is_type
and
(
not
entry
.
is_mutable
or
self
.
is_volatile
):
if
entry
is
not
None
and
not
entry
.
is_type
:
if
entry
.
is_cfunction
:
entry
=
copy
.
copy
(
entry
)
entry
.
type
=
PyrexTypes
.
c_const_or_volatile
_type
(
entry
.
type
=
PyrexTypes
.
qualified_method
_type
(
entry
.
type
,
self
.
is_const
,
self
.
is_volatile
)
# Copy and adapt all the overloaded alternatives
if
entry
.
is_cfunction
:
# the overloaded entry at index 0 is always the one in the scope dict
overloaded_alternatives
=
[
entry
]
for
alt
in
entry
.
overloaded_alternatives
[
1
:]:
qual_alt
=
copy
.
copy
(
alt
)
qual_alt
.
type
=
PyrexTypes
.
c_const_or_volatile
_type
(
qual_alt
.
type
=
PyrexTypes
.
qualified_method
_type
(
alt
.
type
,
self
.
is_const
,
self
.
is_volatile
)
qual_alt
.
overloaded_alternatives
=
overloaded_alternatives
overloaded_alternatives
.
append
(
qual_alt
)
entry
.
overloaded_alternatives
=
overloaded_alternatives
elif
not
entry
.
is_mutable
or
self
.
is_volatile
:
entry
=
copy
.
copy
(
entry
)
entry
.
type
=
PyrexTypes
.
c_const_or_volatile_type
(
entry
.
type
,
self
.
is_const
,
self
.
is_volatile
)
self
.
cached_const_or_volatile_entries
[
name
]
=
entry
return
entry
...
...
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