mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-12-11 14:14:23 +00:00
Test and support all cpp operator types.
2010-06-07 Sami Wagiaalla <swagiaal@redhat.com> * value.h: Created oload_search_type enum. (find_overload_match): Use oload_search_type enum. * valops.c (find_overload_match): Support combined member and non-member search. * eval.c (evaluate_subexp_standard): Calls to find_overload_match now use oload_search_type enum. (oload_method_static): Verify index is a proper value. * valarith.c (value_user_defined_cpp_op): Search for and handle both member and non-member operators. (value_user_defined_cpp_op): New function. (value_user_defined_op): New function. (value_x_unop): Use value_user_defined_op. (value_x_binop): Ditto. * cp-support.c (make_symbol_overload_list_using): Added block iteration. Add check for namespace aliases and imported declarations. 2010-06-07 Sami Wagiaalla <swagiaal@redhat.com> * gdb.cp/koenig.exp: Test for ADL operators. * gdb.cp/koenig.cc: Added ADL operators. * gdb.cp/operator.exp: New test. * gdb.cp/operator.cc: New test.
This commit is contained in:
parent
0f32ea4ce3
commit
4c3376c849
@ -1,3 +1,22 @@
|
||||
2010-06-07 Sami Wagiaalla <swagiaal@redhat.com>
|
||||
|
||||
* value.h: Created oload_search_type enum.
|
||||
(find_overload_match): Use oload_search_type enum.
|
||||
* valops.c (find_overload_match): Support combined member and
|
||||
non-member search.
|
||||
* eval.c (evaluate_subexp_standard): Calls to
|
||||
find_overload_match now use oload_search_type enum.
|
||||
(oload_method_static): Verify index is a proper value.
|
||||
* valarith.c (value_user_defined_cpp_op): Search for and handle
|
||||
both member and non-member operators.
|
||||
(value_user_defined_cpp_op): New function.
|
||||
(value_user_defined_op): New function.
|
||||
(value_x_unop): Use value_user_defined_op.
|
||||
(value_x_binop): Ditto.
|
||||
* cp-support.c (make_symbol_overload_list_using): Added block
|
||||
iteration.
|
||||
Add check for namespace aliases and imported declarations.
|
||||
|
||||
2010-06-07 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
* breakpoint.h (owner): Extend the comment.
|
||||
|
@ -803,21 +803,26 @@ make_symbol_overload_list_using (const char *func_name,
|
||||
const char *namespace)
|
||||
{
|
||||
const struct using_direct *current;
|
||||
const struct block *block;
|
||||
|
||||
/* First, go through the using directives. If any of them apply,
|
||||
look in the appropriate namespaces for new functions to match
|
||||
on. */
|
||||
|
||||
for (current = block_using (get_selected_block (0));
|
||||
current != NULL;
|
||||
current = current->next)
|
||||
{
|
||||
if (strcmp (namespace, current->import_dest) == 0)
|
||||
{
|
||||
make_symbol_overload_list_using (func_name,
|
||||
current->import_src);
|
||||
}
|
||||
}
|
||||
for (block = get_selected_block (0);
|
||||
block != NULL;
|
||||
block = BLOCK_SUPERBLOCK (block))
|
||||
for (current = block_using (block);
|
||||
current != NULL;
|
||||
current = current->next)
|
||||
{
|
||||
/* If this is a namespace alias or imported declaration ignore it. */
|
||||
if (current->alias != NULL || current->declaration != NULL)
|
||||
continue;
|
||||
|
||||
if (strcmp (namespace, current->import_dest) == 0)
|
||||
make_symbol_overload_list_using (func_name, current->import_src);
|
||||
}
|
||||
|
||||
/* Now, add names for this namespace. */
|
||||
make_symbol_overload_list_namespace (func_name, namespace);
|
||||
|
@ -1535,7 +1535,7 @@ evaluate_subexp_standard (struct type *expect_type,
|
||||
arg_types[ix - 1] = value_type (argvec[ix]);
|
||||
|
||||
find_overload_match (arg_types, nargs, func_name,
|
||||
0 /* not method */ , 0 /* strict match */ ,
|
||||
NON_METHOD /* not method */ , 0 /* strict match */ ,
|
||||
NULL, NULL /* pass NULL symbol since symbol is unknown */ ,
|
||||
NULL, &symp, NULL, 0);
|
||||
|
||||
@ -1572,7 +1572,7 @@ evaluate_subexp_standard (struct type *expect_type,
|
||||
arg_types[ix - 1] = value_type (argvec[ix]);
|
||||
|
||||
(void) find_overload_match (arg_types, nargs, tstr,
|
||||
1 /* method */ , 0 /* strict match */ ,
|
||||
METHOD /* method */ , 0 /* strict match */ ,
|
||||
&arg2 /* the object */ , NULL,
|
||||
&valp, NULL, &static_memfuncp, 0);
|
||||
|
||||
@ -1642,8 +1642,8 @@ evaluate_subexp_standard (struct type *expect_type,
|
||||
arg_types[ix - 1] = value_type (argvec[ix]);
|
||||
|
||||
(void) find_overload_match (arg_types, nargs, NULL /* no need for name */ ,
|
||||
0 /* not method */ , 0 /* strict match */ ,
|
||||
NULL, function /* the function */ ,
|
||||
NON_METHOD /* not method */ , 0 /* strict match */ ,
|
||||
NULL, function /* the function */ ,
|
||||
NULL, &symp, NULL, no_adl);
|
||||
|
||||
if (op == OP_VAR_VALUE)
|
||||
|
@ -1,3 +1,10 @@
|
||||
2010-06-07 Sami Wagiaalla <swagiaal@redhat.com>
|
||||
|
||||
* gdb.cp/koenig.exp: Test for ADL operators.
|
||||
* gdb.cp/koenig.cc: Added ADL operators.
|
||||
* gdb.cp/operator.exp: New test.
|
||||
* gdb.cp/operator.cc: New test.
|
||||
|
||||
2010-06-04 Michael Snyder <msnyder@vmware.com>
|
||||
|
||||
* gdb.base/attach.exp: Replace gdb_test_multiple with gdb_test.
|
||||
|
@ -175,6 +175,7 @@ typedef O::A TOA;
|
||||
typedef TOA TTOA;
|
||||
|
||||
//------------
|
||||
|
||||
static union {
|
||||
int a;
|
||||
char b;
|
||||
@ -182,6 +183,49 @@ static union {
|
||||
|
||||
//------------
|
||||
|
||||
namespace P {
|
||||
class Q{
|
||||
public:
|
||||
int operator== (int)
|
||||
{
|
||||
return 24;
|
||||
}
|
||||
|
||||
int operator== (float)
|
||||
{
|
||||
return 25;
|
||||
}
|
||||
|
||||
int operator+ (float)
|
||||
{
|
||||
return 26;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
int operator!= (Q, int)
|
||||
{
|
||||
return 27;
|
||||
}
|
||||
|
||||
int operator!= (Q, double)
|
||||
{
|
||||
return 28;
|
||||
}
|
||||
|
||||
int operator+ (Q, int)
|
||||
{
|
||||
return 29;
|
||||
}
|
||||
|
||||
int operator++ (Q)
|
||||
{
|
||||
return 30;
|
||||
}
|
||||
}
|
||||
|
||||
//------------
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
@ -245,6 +289,16 @@ main ()
|
||||
TTOA ttoa;
|
||||
foo (ttoa, 'a');
|
||||
|
||||
P::Q q;
|
||||
q == 5;
|
||||
q == 5.0f;
|
||||
q != 5;
|
||||
q != 5.0f;
|
||||
q + 5;
|
||||
q + 5.0f;
|
||||
|
||||
++q;
|
||||
|
||||
return first (0, c) + foo (eo) +
|
||||
foo (eo, eo) + foo (eo, eo, 1) +
|
||||
foo (fo, eo) + foo (1 ,fo, eo) +
|
||||
|
@ -13,25 +13,12 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
if $tracelevel then {
|
||||
strace $tracelevel
|
||||
}
|
||||
|
||||
set testfile koenig
|
||||
set srcfile ${testfile}.cc
|
||||
set binfile ${objdir}/${subdir}/${testfile}
|
||||
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
|
||||
untested "Couldn't compile test program"
|
||||
return -1
|
||||
if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} {debug c++}] } {
|
||||
return -1
|
||||
}
|
||||
|
||||
# Get things started.
|
||||
|
||||
gdb_exit
|
||||
gdb_start
|
||||
gdb_reinitialize_dir $srcdir/$subdir
|
||||
gdb_load ${binfile}
|
||||
|
||||
############################################
|
||||
|
||||
if ![runto_main] then {
|
||||
@ -109,3 +96,22 @@ gdb_test "p foo(ttoa, 'a')" "= 23"
|
||||
#test that lookup is not thwarted by anonymous types
|
||||
gdb_test "p foo (p_union)" \
|
||||
"Cannot resolve function foo to any overloaded instance"
|
||||
|
||||
# test lookup of namespace user-defined operators
|
||||
# and overload resolution:
|
||||
|
||||
# within class
|
||||
gdb_test "p q == 5" "= 24"
|
||||
gdb_test "p q == 5.0f" "= 25"
|
||||
|
||||
# within namespace
|
||||
gdb_test "p q != 5" "= 27"
|
||||
gdb_test "p q != 5.0f" "= 28"
|
||||
|
||||
# across namespace and class
|
||||
gdb_test "p q + 5.0f" "= 26"
|
||||
gdb_test "p q + 5" "= 29"
|
||||
|
||||
# some unary operators for good measure
|
||||
# Cannot resolve function operator++ to any overloaded instance
|
||||
gdb_test "p ++q" "= 30"
|
||||
|
195
gdb/testsuite/gdb.cp/operator.cc
Normal file
195
gdb/testsuite/gdb.cp/operator.cc
Normal file
@ -0,0 +1,195 @@
|
||||
class A
|
||||
{
|
||||
};
|
||||
|
||||
int operator== (A, int)
|
||||
{
|
||||
return 11;
|
||||
}
|
||||
|
||||
int operator== (A, char)
|
||||
{
|
||||
return 12;
|
||||
}
|
||||
|
||||
//------------------
|
||||
|
||||
namespace B
|
||||
{
|
||||
class C
|
||||
{
|
||||
};
|
||||
|
||||
int operator== (C, int)
|
||||
{
|
||||
return 22;
|
||||
}
|
||||
|
||||
int operator== (C, char)
|
||||
{
|
||||
return 23;
|
||||
}
|
||||
|
||||
namespace BD
|
||||
{
|
||||
int operator== (C, int)
|
||||
{
|
||||
return 24;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------
|
||||
|
||||
class D
|
||||
{
|
||||
};
|
||||
namespace
|
||||
{
|
||||
int operator== (D, int)
|
||||
{
|
||||
return 33;
|
||||
}
|
||||
|
||||
int operator== (D, char)
|
||||
{
|
||||
return 34;
|
||||
}
|
||||
}
|
||||
|
||||
int operator== (D, float)
|
||||
{
|
||||
return 35;
|
||||
}
|
||||
|
||||
//------------------
|
||||
|
||||
class E
|
||||
{
|
||||
};
|
||||
namespace F
|
||||
{
|
||||
int operator== (E, int)
|
||||
{
|
||||
return 44;
|
||||
}
|
||||
|
||||
int operator== (E, char)
|
||||
{
|
||||
return 45;
|
||||
}
|
||||
}
|
||||
|
||||
int operator== (E, float)
|
||||
{
|
||||
return 46;
|
||||
}
|
||||
|
||||
using namespace F;
|
||||
|
||||
//-----------------
|
||||
|
||||
class G
|
||||
{
|
||||
public:
|
||||
int operator== (int)
|
||||
{
|
||||
return 55;
|
||||
}
|
||||
};
|
||||
|
||||
int operator== (G, char)
|
||||
{
|
||||
return 56;
|
||||
}
|
||||
|
||||
//------------------
|
||||
|
||||
class H
|
||||
{
|
||||
};
|
||||
namespace I
|
||||
{
|
||||
int operator== (H, int)
|
||||
{
|
||||
return 66;
|
||||
}
|
||||
}
|
||||
|
||||
namespace ALIAS = I;
|
||||
|
||||
//------------------
|
||||
|
||||
class J
|
||||
{
|
||||
};
|
||||
|
||||
namespace K
|
||||
{
|
||||
int i;
|
||||
int operator== (J, int)
|
||||
{
|
||||
return 77;
|
||||
}
|
||||
}
|
||||
|
||||
using K::i;
|
||||
|
||||
//------------------
|
||||
|
||||
class L
|
||||
{
|
||||
};
|
||||
namespace M
|
||||
{
|
||||
int operator== (L, int)
|
||||
{
|
||||
return 88;
|
||||
}
|
||||
}
|
||||
|
||||
namespace N
|
||||
{
|
||||
using namespace M;
|
||||
}
|
||||
|
||||
using namespace N;
|
||||
|
||||
//------------------
|
||||
|
||||
int main ()
|
||||
{
|
||||
A a;
|
||||
a == 1;
|
||||
a == 'a';
|
||||
|
||||
B::C bc;
|
||||
bc == 1;
|
||||
bc == 'a';
|
||||
B::BD::operator== (bc,'a');
|
||||
|
||||
D d;
|
||||
d == 1;
|
||||
d == 'a';
|
||||
d == 1.0f;
|
||||
|
||||
E e;
|
||||
e == 1;
|
||||
e == 'a';
|
||||
e == 1.0f;
|
||||
|
||||
G g;
|
||||
g == 1;
|
||||
g == 'a';
|
||||
|
||||
H h;
|
||||
I::operator== (h, 1);
|
||||
|
||||
J j;
|
||||
K::operator== (j, 1);
|
||||
|
||||
L l;
|
||||
l == 1;
|
||||
|
||||
return 0;
|
||||
}
|
58
gdb/testsuite/gdb.cp/operator.exp
Normal file
58
gdb/testsuite/gdb.cp/operator.exp
Normal file
@ -0,0 +1,58 @@
|
||||
# Copyright 2008 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
set testfile operator
|
||||
set srcfile ${testfile}.cc
|
||||
if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} {debug c++}] } {
|
||||
return -1
|
||||
}
|
||||
|
||||
############################################
|
||||
|
||||
if ![runto_main] then {
|
||||
perror "couldn't run to breakpoint main"
|
||||
continue
|
||||
}
|
||||
|
||||
# Test global operator
|
||||
gdb_test "p a == 1" "= 11" "global operator"
|
||||
gdb_test "p a == 'a'" "= 12" "global operator overload"
|
||||
|
||||
# Test ADL operator
|
||||
gdb_test "p bc == 1" "= 22" "ADL operator"
|
||||
gdb_test "p bc == 'a'" "= 23" "ADL operator overload"
|
||||
gdb_test "p B::BD::operator== (bc,'a')" "= 24" "Fully qualified explicit operator call"
|
||||
|
||||
# Test operator imported from anonymous namespace
|
||||
gdb_test "p d == 1" "= 33" "anonymous namespace operator"
|
||||
gdb_test "p d == 'a'" "= 34" "anonymous namespace operator overload"
|
||||
gdb_test "p d == 1.0f" "= 35" "anonymous namespace operator overload float"
|
||||
|
||||
# Test operator imported by using directive
|
||||
gdb_test "p e == 1" "= 44" "imported operator"
|
||||
gdb_test "p e == 'a'" "= 45" "imported operator overload"
|
||||
gdb_test "p e == 1.0f" "= 46" "imported operator overload float"
|
||||
|
||||
# Test member operator
|
||||
gdb_test "p g == 1" "= 55" "member operator"
|
||||
gdb_test "p g == 'a'" "= 56" "member operator overload"
|
||||
|
||||
# Test that operators are not wrongly imported
|
||||
# by import declarations and namespace aliases
|
||||
gdb_test "p h == 1" "Cannot resolve function operator== to any overloaded instance" "namespace alias"
|
||||
gdb_test "p j == 1" "Cannot resolve function operator== to any overloaded instance" "imported declaration"
|
||||
|
||||
# Test that indirectly imported operators work
|
||||
gdb_test "p l == 1" "= 88"
|
@ -31,6 +31,7 @@
|
||||
#include "dfp.h"
|
||||
#include <math.h>
|
||||
#include "infcall.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
/* Define whether or not the C operator '/' truncates towards zero for
|
||||
differently signed operands (truncation direction is undefined in C). */
|
||||
@ -319,6 +320,67 @@ unop_user_defined_p (enum exp_opcode op, struct value *arg1)
|
||||
}
|
||||
}
|
||||
|
||||
/* Try to find an operator named OPERATOR which takes NARGS arguments
|
||||
specified in ARGS. If the operator found is a static member operator
|
||||
*STATIC_MEMFUNP will be set to 1, and otherwise 0.
|
||||
The search if performed through find_overload_match which will handle
|
||||
member operators, non member operators, operators imported implicitly or
|
||||
explicitly, and perform correct overload resolution in all of the above
|
||||
situations or combinations thereof. */
|
||||
|
||||
static struct value *
|
||||
value_user_defined_cpp_op (struct value **args, int nargs, char *operator,
|
||||
int *static_memfuncp)
|
||||
{
|
||||
|
||||
struct symbol *symp = NULL;
|
||||
struct value *valp = NULL;
|
||||
struct type **arg_types;
|
||||
int i;
|
||||
|
||||
arg_types = (struct type **) alloca (nargs * (sizeof (struct type *)));
|
||||
/* Prepare list of argument types for overload resolution */
|
||||
for (i = 0; i < nargs; i++)
|
||||
arg_types[i] = value_type (args[i]);
|
||||
|
||||
find_overload_match (arg_types, nargs, operator, BOTH /* could be method */,
|
||||
0 /* strict match */, &args[0], /* objp */
|
||||
NULL /* pass NULL symbol since symbol is unknown */,
|
||||
&valp, &symp, static_memfuncp, 0);
|
||||
|
||||
if (valp)
|
||||
return valp;
|
||||
|
||||
if (symp)
|
||||
{
|
||||
/* This is a non member function and does not
|
||||
expect a reference as its first argument
|
||||
rather the explicit structure. */
|
||||
args[0] = value_ind (args[0]);
|
||||
return value_of_variable (symp, 0);
|
||||
}
|
||||
|
||||
error (_("Could not find %s."), operator);
|
||||
}
|
||||
|
||||
/* Lookup user defined operator NAME. Return a value representing the
|
||||
function, otherwise return NULL. */
|
||||
|
||||
static struct value *
|
||||
value_user_defined_op (struct value **argp, struct value **args, char *name,
|
||||
int *static_memfuncp, int nargs)
|
||||
{
|
||||
struct value *result = NULL;
|
||||
|
||||
if (current_language->la_language == language_cplus)
|
||||
result = value_user_defined_cpp_op (args, nargs, name, static_memfuncp);
|
||||
else
|
||||
result = value_struct_elt (argp, args, name, static_memfuncp,
|
||||
"structure");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* We know either arg1 or arg2 is a structure, so try to find the right
|
||||
user defined function. Create an argument vector that calls
|
||||
arg1.operator @ (arg1,arg2) and return that value (where '@' is any
|
||||
@ -459,7 +521,8 @@ value_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op,
|
||||
error (_("Invalid binary operation specified."));
|
||||
}
|
||||
|
||||
argvec[0] = value_struct_elt (&arg1, argvec + 1, tstr, &static_memfuncp, "structure");
|
||||
argvec[0] = value_user_defined_op (&arg1, argvec + 1, tstr,
|
||||
&static_memfuncp, 2);
|
||||
|
||||
if (argvec[0])
|
||||
{
|
||||
@ -557,7 +620,8 @@ value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside)
|
||||
error (_("Invalid unary operation specified."));
|
||||
}
|
||||
|
||||
argvec[0] = value_struct_elt (&arg1, argvec + 1, tstr, &static_memfuncp, "structure");
|
||||
argvec[0] = value_user_defined_op (&arg1, argvec + 1, tstr,
|
||||
&static_memfuncp, nargs);
|
||||
|
||||
if (argvec[0])
|
||||
{
|
||||
|
148
gdb/valops.c
148
gdb/valops.c
@ -2315,6 +2315,16 @@ value_find_oload_method_list (struct value **argp, const char *method,
|
||||
matches on the argument types according to the overload resolution
|
||||
rules.
|
||||
|
||||
METHOD can be one of three values:
|
||||
NON_METHOD for non-member functions.
|
||||
METHOD: for member functions.
|
||||
BOTH: used for overload resolution of operators where the
|
||||
candidates are expected to be either member or non member
|
||||
functions. In this case the first argument ARGTYPES
|
||||
(representing 'this') is expected to be a reference to the
|
||||
target object, and will be dereferenced when attempting the
|
||||
non-member search.
|
||||
|
||||
In the case of class methods, the parameter OBJ is an object value
|
||||
in which to search for overloaded methods.
|
||||
|
||||
@ -2342,16 +2352,20 @@ value_find_oload_method_list (struct value **argp, const char *method,
|
||||
|
||||
int
|
||||
find_overload_match (struct type **arg_types, int nargs,
|
||||
const char *name, int method, int lax,
|
||||
struct value **objp, struct symbol *fsym,
|
||||
const char *name, enum oload_search_type method,
|
||||
int lax, struct value **objp, struct symbol *fsym,
|
||||
struct value **valp, struct symbol **symp,
|
||||
int *staticp, const int no_adl)
|
||||
{
|
||||
struct value *obj = (objp ? *objp : NULL);
|
||||
/* Index of best overloaded function. */
|
||||
int oload_champ;
|
||||
int func_oload_champ = -1;
|
||||
int method_oload_champ = -1;
|
||||
|
||||
/* The measure for the current best match. */
|
||||
struct badness_vector *oload_champ_bv = NULL;
|
||||
struct badness_vector *method_badness = NULL;
|
||||
struct badness_vector *func_badness = NULL;
|
||||
|
||||
struct value *temp = obj;
|
||||
/* For methods, the list of overloaded methods. */
|
||||
struct fn_field *fns_ptr = NULL;
|
||||
@ -2367,9 +2381,11 @@ find_overload_match (struct type **arg_types, int nargs,
|
||||
const char *obj_type_name = NULL;
|
||||
const char *func_name = NULL;
|
||||
enum oload_classification match_quality;
|
||||
enum oload_classification method_match_quality = INCOMPATIBLE;
|
||||
enum oload_classification func_match_quality = INCOMPATIBLE;
|
||||
|
||||
/* Get the list of overloaded methods or functions. */
|
||||
if (method)
|
||||
if (method == METHOD || method == BOTH)
|
||||
{
|
||||
gdb_assert (obj);
|
||||
|
||||
@ -2392,10 +2408,13 @@ find_overload_match (struct type **arg_types, int nargs,
|
||||
}
|
||||
}
|
||||
|
||||
/* Retrieve the list of methods with the name NAME. */
|
||||
fns_ptr = value_find_oload_method_list (&temp, name,
|
||||
0, &num_fns,
|
||||
&basetype, &boffset);
|
||||
if (!fns_ptr || !num_fns)
|
||||
/* If this is a method only search, and no methods were found
|
||||
the search has faild. */
|
||||
if (method == METHOD && (!fns_ptr || !num_fns))
|
||||
error (_("Couldn't find method %s%s%s"),
|
||||
obj_type_name,
|
||||
(obj_type_name && *obj_type_name) ? "::" : "",
|
||||
@ -2403,15 +2422,33 @@ find_overload_match (struct type **arg_types, int nargs,
|
||||
/* If we are dealing with stub method types, they should have
|
||||
been resolved by find_method_list via
|
||||
value_find_oload_method_list above. */
|
||||
gdb_assert (TYPE_DOMAIN_TYPE (fns_ptr[0].type) != NULL);
|
||||
oload_champ = find_oload_champ (arg_types, nargs, method,
|
||||
num_fns, fns_ptr,
|
||||
oload_syms, &oload_champ_bv);
|
||||
if (fns_ptr)
|
||||
{
|
||||
gdb_assert (TYPE_DOMAIN_TYPE (fns_ptr[0].type) != NULL);
|
||||
method_oload_champ = find_oload_champ (arg_types, nargs, method,
|
||||
num_fns, fns_ptr,
|
||||
oload_syms, &method_badness);
|
||||
|
||||
method_match_quality =
|
||||
classify_oload_match (method_badness, nargs,
|
||||
oload_method_static (method, fns_ptr,
|
||||
method_oload_champ));
|
||||
|
||||
make_cleanup (xfree, method_badness);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
|
||||
if (method == NON_METHOD || method == BOTH)
|
||||
{
|
||||
const char *qualified_name = NULL;
|
||||
|
||||
/* If the the overload match is being search for both
|
||||
as a method and non member function, the first argument
|
||||
must now be dereferenced. */
|
||||
if (method == BOTH)
|
||||
arg_types[0] = TYPE_TARGET_TYPE (arg_types[0]);
|
||||
|
||||
if (fsym)
|
||||
{
|
||||
qualified_name = SYMBOL_NATURAL_NAME (fsym);
|
||||
@ -2454,30 +2491,67 @@ find_overload_match (struct type **arg_types, int nargs,
|
||||
return 0;
|
||||
}
|
||||
|
||||
make_cleanup (xfree, oload_syms);
|
||||
make_cleanup (xfree, oload_champ_bv);
|
||||
func_oload_champ = find_oload_champ_namespace (arg_types, nargs,
|
||||
func_name,
|
||||
qualified_name,
|
||||
&oload_syms,
|
||||
&func_badness,
|
||||
no_adl);
|
||||
|
||||
oload_champ = find_oload_champ_namespace (arg_types, nargs,
|
||||
func_name,
|
||||
qualified_name,
|
||||
&oload_syms,
|
||||
&oload_champ_bv,
|
||||
no_adl);
|
||||
if (func_oload_champ >= 0)
|
||||
func_match_quality = classify_oload_match (func_badness, nargs, 0);
|
||||
|
||||
make_cleanup (xfree, oload_syms);
|
||||
make_cleanup (xfree, func_badness);
|
||||
}
|
||||
|
||||
/* Did we find a match ? */
|
||||
if (oload_champ == -1)
|
||||
if (method_oload_champ == -1 && func_oload_champ == -1)
|
||||
error (_("No symbol \"%s\" in current context."), name);
|
||||
|
||||
/* Check how bad the best match is. */
|
||||
match_quality =
|
||||
classify_oload_match (oload_champ_bv, nargs,
|
||||
oload_method_static (method, fns_ptr,
|
||||
oload_champ));
|
||||
/* If we have found both a method match and a function
|
||||
match, find out which one is better, and calculate match
|
||||
quality. */
|
||||
if (method_oload_champ >= 0 && func_oload_champ >= 0)
|
||||
{
|
||||
switch (compare_badness (func_badness, method_badness))
|
||||
{
|
||||
case 0: /* Top two contenders are equally good. */
|
||||
/* FIXME: GDB does not support the general ambiguous
|
||||
case. All candidates should be collected and presented
|
||||
the the user. */
|
||||
error (_("Ambiguous overload resolution"));
|
||||
break;
|
||||
case 1: /* Incomparable top contenders. */
|
||||
/* This is an error incompatible candidates
|
||||
should not have been proposed. */
|
||||
error (_("Internal error: incompatible overload candidates proposed"));
|
||||
break;
|
||||
case 2: /* Function champion. */
|
||||
method_oload_champ = -1;
|
||||
match_quality = func_match_quality;
|
||||
break;
|
||||
case 3: /* Method champion. */
|
||||
func_oload_champ = -1;
|
||||
match_quality = method_match_quality;
|
||||
break;
|
||||
default:
|
||||
error (_("Internal error: unexpected overload comparison result"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We have either a method match or a function match. */
|
||||
if (method_oload_champ >= 0)
|
||||
match_quality = method_match_quality;
|
||||
else
|
||||
match_quality = func_match_quality;
|
||||
}
|
||||
|
||||
if (match_quality == INCOMPATIBLE)
|
||||
{
|
||||
if (method)
|
||||
if (method == METHOD)
|
||||
error (_("Cannot resolve method %s%s%s to any overloaded instance"),
|
||||
obj_type_name,
|
||||
(obj_type_name && *obj_type_name) ? "::" : "",
|
||||
@ -2488,7 +2562,7 @@ find_overload_match (struct type **arg_types, int nargs,
|
||||
}
|
||||
else if (match_quality == NON_STANDARD)
|
||||
{
|
||||
if (method)
|
||||
if (method == METHOD)
|
||||
warning (_("Using non-standard conversion to match method %s%s%s to supplied arguments"),
|
||||
obj_type_name,
|
||||
(obj_type_name && *obj_type_name) ? "::" : "",
|
||||
@ -2498,21 +2572,20 @@ find_overload_match (struct type **arg_types, int nargs,
|
||||
func_name);
|
||||
}
|
||||
|
||||
if (method)
|
||||
if (staticp != NULL)
|
||||
*staticp = oload_method_static (method, fns_ptr, method_oload_champ);
|
||||
|
||||
if (method_oload_champ >= 0)
|
||||
{
|
||||
if (staticp != NULL)
|
||||
*staticp = oload_method_static (method, fns_ptr, oload_champ);
|
||||
if (TYPE_FN_FIELD_VIRTUAL_P (fns_ptr, oload_champ))
|
||||
*valp = value_virtual_fn_field (&temp, fns_ptr, oload_champ,
|
||||
if (TYPE_FN_FIELD_VIRTUAL_P (fns_ptr, method_oload_champ))
|
||||
*valp = value_virtual_fn_field (&temp, fns_ptr, method_oload_champ,
|
||||
basetype, boffset);
|
||||
else
|
||||
*valp = value_fn_field (&temp, fns_ptr, oload_champ,
|
||||
*valp = value_fn_field (&temp, fns_ptr, method_oload_champ,
|
||||
basetype, boffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
*symp = oload_syms[oload_champ];
|
||||
}
|
||||
*symp = oload_syms[func_oload_champ];
|
||||
|
||||
if (objp)
|
||||
{
|
||||
@ -2801,7 +2874,8 @@ find_oload_champ (struct type **arg_types, int nargs, int method,
|
||||
static int
|
||||
oload_method_static (int method, struct fn_field *fns_ptr, int index)
|
||||
{
|
||||
if (method && TYPE_FN_FIELD_STATIC_P (fns_ptr, index))
|
||||
if (method && fns_ptr && index >= 0
|
||||
&& TYPE_FN_FIELD_STATIC_P (fns_ptr, index))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
|
@ -447,8 +447,11 @@ extern struct fn_field *value_find_oload_method_list (struct value **,
|
||||
int, int *,
|
||||
struct type **, int *);
|
||||
|
||||
enum oload_search_type { NON_METHOD, METHOD, BOTH };
|
||||
|
||||
extern int find_overload_match (struct type **arg_types, int nargs,
|
||||
const char *name, int method, int lax,
|
||||
const char *name,
|
||||
enum oload_search_type method, int lax,
|
||||
struct value **objp, struct symbol *fsym,
|
||||
struct value **valp, struct symbol **symp,
|
||||
int *staticp, const int no_adl);
|
||||
|
Loading…
Reference in New Issue
Block a user