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
Boxiang Sun
cython
Commits
34741cc4
Commit
34741cc4
authored
Feb 09, 2010
by
Craig Citro
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix trac #506 -- error with overloading, pops up in cpp_classes
parent
4b26e417
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
60 additions
and
31 deletions
+60
-31
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+60
-31
No files found.
Cython/Compiler/PyrexTypes.py
View file @
34741cc4
...
...
@@ -2227,49 +2227,78 @@ def is_promotion(src_type, dst_type):
def
best_match
(
args
,
functions
,
pos
=
None
):
"""
Finds the best function to be called
Error if no function fits the call or an ambiguity is find (two or more possible functions)
Given a list args of arguments and a list of functions, choose one
to call which seems to be the "best" fit for this list of arguments.
This function is used, e.g., when deciding which overloaded method
to dispatch for C++ classes.
We first eliminate functions based on arity, and if only one
function has the correct arity, we return it. Otherwise, we weight
functions based on how much work must be done to convert the
arguments, with the following priorities:
* identical types or pointers to identical types
* promotions
* non-Python types
That is, we prefer functions where no arguments need converted,
and failing that, functions where only promotions are required, and
so on.
If no function is deemed a good fit, or if two or more functions have
the same weight, we return None (as there is no best match). If pos
is not None, we also generate an error.
"""
# TODO: args should be a list of types, not a list of Nodes.
actual_nargs
=
len
(
args
)
possibilities
=
[]
bad_types
=
0
from_type
=
None
target_type
=
None
candidates
=
[]
errors
=
[]
for
func
in
functions
:
error_mesg
=
""
func_type
=
func
.
type
if
func_type
.
is_ptr
:
func_type
=
func_type
.
base_type
# Check function type
if
not
func_type
.
is_cfunction
:
if
not
func_type
.
is_error
and
pos
is
not
None
:
error
(
pos
,
"Calling non-function type '%s'"
%
func_type
)
return
None
error_mesg
=
"Calling non-function type '%s'"
%
func_type
errors
.
append
((
func
,
error_mesg
))
continue
# Check no. of args
max_nargs
=
len
(
func_type
.
args
)
min_nargs
=
max_nargs
-
func_type
.
optional_arg_count
if
actual_nargs
<
min_nargs
\
or
(
not
func_type
.
has_varargs
and
actual_nargs
>
max_nargs
):
if
max_nargs
==
min_nargs
and
not
func_type
.
has_varargs
:
expectation
=
max_nargs
elif
actual_nargs
<
min_nargs
:
expectation
=
"at least %s"
%
min_nargs
else
:
expectation
=
"at most %s"
%
max_nargs
error_str
=
"Call with wrong number of arguments (expected %s, got %s)"
\
%
(
expectation
,
actual_nargs
)
continue
if
len
(
functions
)
==
1
:
# Optimize the most common case of no overloading...
return
func
if
actual_nargs
<
min_nargs
or
\
(
not
func_type
.
has_varargs
and
actual_nargs
>
max_nargs
):
if
max_nargs
==
min_nargs
and
not
func_type
.
has_varargs
:
expectation
=
max_nargs
elif
actual_nargs
<
min_nargs
:
expectation
=
"at least %s"
%
min_nargs
else
:
expectation
=
"at most %s"
%
max_nargs
error_mesg
=
"Call with wrong number of arguments (expected %s, got %s)"
\
%
(
expectation
,
actual_nargs
)
errors
.
append
((
func
,
error_mesg
))
continue
candidates
.
append
((
func
,
func_type
))
# Optimize the most common case of no overloading...
if
len
(
candidates
)
==
1
:
return
candidates
[
0
]
elif
len
(
candidates
)
==
0
:
if
len
(
errors
)
==
1
and
pos
is
not
None
:
error
(
pos
,
errors
[
0
][
1
])
return
None
possibilities
=
[]
bad_types
=
[]
for
func
,
func_type
in
candidates
:
score
=
[
0
,
0
,
0
]
for
i
in
range
(
min
(
len
(
args
),
len
(
func_type
.
args
))):
src_type
=
args
[
i
].
type
dst_type
=
func_type
.
args
[
i
].
type
if
dst_type
.
assignable_from
(
src_type
):
if
src_type
==
dst_type
or
(
dst_type
.
is_reference
and
\
src_type
==
dst_type
.
base_type
)
or
\
dst_type
.
same_as
(
src_type
):
src_type
==
dst_type
.
base_type
)
\
or
dst_type
.
same_as
(
src_type
):
pass
# score 0
elif
is_promotion
(
src_type
,
dst_type
):
score
[
2
]
+=
1
...
...
@@ -2278,13 +2307,13 @@ def best_match(args, functions, pos=None):
else
:
score
[
0
]
+=
1
else
:
bad_types
=
func
from_type
=
src_type
target_type
=
dst_type
error_mesg
=
"Invalid conversion from '%s' to '%s'"
%
(
src_type
,
dst_type
)
bad_types
.
append
((
func
,
error_mesg
))
break
else
:
possibilities
.
append
((
score
,
func
))
# so we can sort it
if
len
(
possibilities
)
:
if
possibilities
:
possibilities
.
sort
()
if
len
(
possibilities
)
>
1
and
possibilities
[
0
][
0
]
==
possibilities
[
1
][
0
]:
if
pos
is
not
None
:
...
...
@@ -2292,10 +2321,10 @@ def best_match(args, functions, pos=None):
return
None
return
possibilities
[
0
][
1
]
if
pos
is
not
None
:
if
bad_types
:
error
(
pos
,
"Invalid conversion from '%s' to '%s'"
%
(
from_type
,
target_type
)
)
if
len
(
bad_types
)
==
1
:
error
(
pos
,
bad_types
[
0
][
1
]
)
else
:
error
(
pos
,
error_str
)
error
(
pos
,
"no suitable method found"
)
return
None
...
...
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