aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Carlton <carlton@bactrian.org>2003-01-25 01:04:31 +0000
committerDavid Carlton <carlton@bactrian.org>2003-01-25 01:04:31 +0000
commit9f63861e669c48b1766870a5bb67bc5f2ef593a3 (patch)
tree7ac6ebd9bfaada493db132b2ad89433b31db9a04
parent93085966bf003c80247cd6f5023c15812de356be (diff)
downloadgdb-9f63861e669c48b1766870a5bb67bc5f2ef593a3.zip
gdb-9f63861e669c48b1766870a5bb67bc5f2ef593a3.tar.gz
gdb-9f63861e669c48b1766870a5bb67bc5f2ef593a3.tar.bz2
2003-01-24 David Carlton <carlton@math.stanford.edu>
* valops.c (find_oload_champ): New function. (find_overload_match): Separate code into find_oload_champ and oload_method_static. (find_oload_champ): Call oload_method_static. (oload_method_static): New function. (find_overload_match): Call classify_oload_match. (classify_oload_match): New function. * value.h: Update declaration of find_overload_match. * eval.c (evaluate_subexp_standard): Pass current block to find_overload_match. * valops.c (find_overload_match): Add CURRENT_BLOCK arg. 2003-01-24 David Carlton <carlton@math.stanford.edu> * gdb.c++/overload.exp: Add tests involving overloadNamespace. Delete comment about GDB crashing. * gdb.c++/overload.cc: Add dummyClass, dummyInstance, overloadNamespace, and XXX.
-rw-r--r--gdb/ChangeLog14
-rw-r--r--gdb/eval.c25
-rw-r--r--gdb/testsuite/ChangeLog7
-rw-r--r--gdb/testsuite/gdb.c++/overload.cc26
-rw-r--r--gdb/testsuite/gdb.c++/overload.exp19
-rw-r--r--gdb/valops.c266
-rw-r--r--gdb/value.h1
7 files changed, 252 insertions, 106 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index cc4bc22..9735da0 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,17 @@
+2003-01-24 David Carlton <carlton@math.stanford.edu>
+
+ * valops.c (find_oload_champ): New function.
+ (find_overload_match): Separate code into find_oload_champ and
+ oload_method_static.
+ (find_oload_champ): Call oload_method_static.
+ (oload_method_static): New function.
+ (find_overload_match): Call classify_oload_match.
+ (classify_oload_match): New function.
+ * value.h: Update declaration of find_overload_match.
+ * eval.c (evaluate_subexp_standard): Pass current block to
+ find_overload_match.
+ * valops.c (find_overload_match): Add CURRENT_BLOCK arg.
+
2003-01-20 David Carlton <carlton@math.stanford.edu>
* p-exp.y: Add block to OP_FUNCALL.
diff --git a/gdb/eval.c b/gdb/eval.c
index d719671..ad7279f 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -392,6 +392,7 @@ evaluate_subexp_standard (struct type *expect_type,
long mem_offset;
struct type **arg_types;
int save_pos1;
+ const struct block *current_block;
pc = (*pos)++;
op = exp->elts[pc].opcode;
@@ -667,6 +668,8 @@ evaluate_subexp_standard (struct type *expect_type,
(*pos) += 3;
op = exp->elts[*pos].opcode;
nargs = longest_to_int (exp->elts[pc + 1].longconst);
+ current_block = exp->elts[pc + 2].block;
+
/* Allocate arg vector, including space for the function to be
called in argvec[0] and a terminating NULL */
argvec = (struct value **) alloca (sizeof (struct value *) * (nargs + 3));
@@ -834,10 +837,12 @@ evaluate_subexp_standard (struct type *expect_type,
for (ix = 1; ix <= nargs; ix++)
arg_types[ix - 1] = VALUE_TYPE (argvec[ix]);
- (void) find_overload_match (arg_types, nargs, tstr,
- 1 /* method */ , 0 /* strict match */ ,
- &arg2 /* the object */ , NULL,
- &valp, NULL, &static_memfuncp);
+ find_overload_match (arg_types, nargs, tstr,
+ 1 /* method */,
+ 0 /* strict match */ ,
+ &arg2 /* the object */, NULL,
+ current_block,
+ &valp, NULL, &static_memfuncp);
argvec[1] = arg2; /* the ``this'' pointer */
@@ -889,10 +894,14 @@ evaluate_subexp_standard (struct type *expect_type,
for (ix = 1; ix <= nargs; ix++)
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, exp->elts[save_pos1+2].symbol /* the function */ ,
- NULL, &symp, NULL);
+ find_overload_match (arg_types, nargs,
+ NULL /* no need for name */ ,
+ 0 /* not method */,
+ 0 /* strict match */ ,
+ NULL,
+ exp->elts[save_pos1+2].symbol /* the function */ ,
+ current_block,
+ NULL, &symp, NULL);
/* Now fix the expression being evaluated */
exp->elts[save_pos1+2].symbol = symp;
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index c25c499..5489bb6 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2003-01-24 David Carlton <carlton@math.stanford.edu>
+
+ * gdb.c++/overload.exp: Add tests involving overloadNamespace.
+ Delete comment about GDB crashing.
+ * gdb.c++/overload.cc: Add dummyClass, dummyInstance,
+ overloadNamespace, and XXX.
+
2003-01-10 David Carlton <carlton@math.stanford.edu>
* gdb.c++/templates.exp (do_tests): Update some of the regexps to
diff --git a/gdb/testsuite/gdb.c++/overload.cc b/gdb/testsuite/gdb.c++/overload.cc
index 97083c5..6d6fa10 100644
--- a/gdb/testsuite/gdb.c++/overload.cc
+++ b/gdb/testsuite/gdb.c++/overload.cc
@@ -48,6 +48,31 @@ int overloadargs (int a1, int a2, int a3, int a4, int a5, int a6, int a7,
void marker1()
{}
+// Now test how overloading and namespaces interact.
+
+class dummyClass {};
+
+dummyClass dummyInstance;
+
+int overloadNamespace(int i)
+{
+ return 1;
+}
+
+int overloadNamespace(dummyClass d)
+{
+ return 2;
+}
+
+namespace XXX {
+ int overloadNamespace (char c)
+ {
+ return 3;
+ }
+
+ void marker2() {}
+}
+
int main ()
{
char arg2 = 2;
@@ -74,6 +99,7 @@ int main ()
marker1();
+ XXX::marker2();
return 0;
}
diff --git a/gdb/testsuite/gdb.c++/overload.exp b/gdb/testsuite/gdb.c++/overload.exp
index e9aaae0..4a7c564 100644
--- a/gdb/testsuite/gdb.c++/overload.exp
+++ b/gdb/testsuite/gdb.c++/overload.exp
@@ -387,7 +387,24 @@ gdb_test "list foo::overloadfnarg(int, int (*)(int))" \
"int foo::overloadfnarg.*\\(int arg, int \\(\\*foo\\) \\(int\\)\\).*" \
"list overloaded function with function ptr args"
-# This one crashes GDB. Don't know why yet.
gdb_test "list \"foo::overloadfnarg(int, int (*)(int))\"" \
"int foo::overloadfnarg.*\\(int arg, int \\(\\*foo\\) \\(int\\)\\).*" \
"list overloaded function with function ptr args - quotes around argument"
+
+# Now some tests to see how overloading and namespaces interact.
+
+# FIXME: carlton/2003-01-24: It would be nice to throw using
+# declarations into the mix, once GDB handles them.
+
+gdb_test "print overloadNamespace(1)" ".\[0-9\]* = 1"
+gdb_test "print overloadNamespace('a')" ".\[0-9\]* = 1"
+gdb_test "print overloadNamespace(dummyInstance)" ".\[0-9\]* = 2"
+
+if ![runto 'XXX::marker2'] then {
+ perror "couldn't run to XXX::marker2"
+ continue
+}
+
+gdb_test "print overloadNamespace(1)" ".\[0-9\]* = 3" "print overloadNamespace(1) in XXX"
+gdb_test "print overloadNamespace('a')" ".\[0-9\]* = 3" "print overloadNamespace('a') in XXX"
+gdb_test "print overloadNamespace(dummyInstance)" ".\[0-9\]* = 2" "print overloadNamespace(dummyInstance) in XXX"
diff --git a/gdb/valops.c b/gdb/valops.c
index 1278b88..77d58fe 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -64,6 +64,23 @@ static struct value *search_struct_method (char *, struct value **,
struct value **,
int, int *, struct type *);
+enum oload_classification { STANDARD, NON_STANDARD, INCOMPATIBLE };
+
+static int find_oload_champ (struct type **arg_types, int nargs, int method,
+ int num_fns,
+ struct fn_field *fns_ptr,
+ struct symbol **oload_syms,
+ struct badness_vector **oload_champ_bv);
+
+static int oload_method_static (int method, struct fn_field *fns_ptr,
+ int index);
+
+static enum
+oload_classification classify_oload_match (struct badness_vector
+ * oload_champ_bv,
+ int nargs,
+ int static_offset);
+
static int check_field_in (struct type *, const char *);
static struct value *value_struct_elt_for_reference (struct type *domain,
@@ -2748,12 +2765,15 @@ value_find_oload_method_list (struct value **argp, char *method, int offset,
/* Given an array of argument types (ARGTYPES) (which includes an
entry for "this" in the case of C++ methods), the number of
- arguments NARGS, the NAME of a function whether it's a method or
+ arguments NARGS, the NAME of a function, whether it's a method or
not (METHOD), and the degree of laxness (LAX) in conforming to
overload resolution rules in ANSI C++, find the best function that
matches on the argument types according to the overload resolution
rules.
+ CURRENT_BLOCK is the context in which the evaluation is occurring;
+ this is used to get namespace info.
+
In the case of class methods, the parameter OBJ is an object value
in which to search for overloaded methods.
@@ -2777,21 +2797,17 @@ value_find_oload_method_list (struct value **argp, char *method, int offset,
int
find_overload_match (struct type **arg_types, int nargs, char *name, int method,
int lax, struct value **objp, struct symbol *fsym,
+ const struct block *current_block,
struct value **valp, struct symbol **symp, int *staticp)
{
- int nparms;
- struct type **parm_types;
- int champ_nparms = 0;
struct value *obj = (objp ? *objp : NULL);
- short oload_champ = -1; /* Index of best overloaded function */
+ int oload_champ; /* Index of best overloaded function */
+#if 0
short oload_ambiguous = 0; /* Current ambiguity state for overload resolution */
/* 0 => no ambiguity, 1 => two good funcs, 2 => incomparable funcs */
- short oload_ambig_champ = -1; /* 2nd contender for best match */
- short oload_non_standard = 0; /* did we have to use non-standard conversions? */
- short oload_incompatible = 0; /* are args supplied incompatible with any function? */
+#endif
- struct badness_vector *bv; /* A measure of how good an overloaded instance is */
struct badness_vector *oload_champ_bv = NULL; /* The measure for the current best match */
struct value *temp = obj;
@@ -2800,13 +2816,13 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method,
int num_fns = 0; /* Number of overloaded instances being considered */
struct type *basetype = NULL;
int boffset;
- register int jj;
register int ix;
int static_offset;
struct cleanup *cleanups = NULL;
const char *obj_type_name = NULL;
char *func_name = NULL;
+ enum oload_classification match_quality;
/* Get the list of overloaded methods or functions */
if (method)
@@ -2852,77 +2868,9 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method,
error ("Couldn't find function %s", func_name);
}
- oload_champ_bv = NULL;
-
- /* Consider each candidate in turn */
- for (ix = 0; ix < num_fns; ix++)
- {
- static_offset = 0;
- if (method)
- {
- if (TYPE_FN_FIELD_STATIC_P (fns_ptr, ix))
- static_offset = 1;
- nparms = TYPE_NFIELDS (TYPE_FN_FIELD_TYPE (fns_ptr, ix));
- }
- else
- {
- /* If it's not a method, this is the proper place */
- nparms=TYPE_NFIELDS(SYMBOL_TYPE(oload_syms[ix]));
- }
-
- /* Prepare array of parameter types */
- parm_types = (struct type **) xmalloc (nparms * (sizeof (struct type *)));
- for (jj = 0; jj < nparms; jj++)
- parm_types[jj] = (method
- ? (TYPE_FN_FIELD_ARGS (fns_ptr, ix)[jj].type)
- : TYPE_FIELD_TYPE (SYMBOL_TYPE (oload_syms[ix]), jj));
-
- /* Compare parameter types to supplied argument types. Skip THIS for
- static methods. */
- bv = rank_function (parm_types, nparms, arg_types + static_offset,
- nargs - static_offset);
+ oload_champ = find_oload_champ(arg_types, nargs, method, num_fns, fns_ptr,
+ oload_syms, &oload_champ_bv);
- if (!oload_champ_bv)
- {
- oload_champ_bv = bv;
- oload_champ = 0;
- champ_nparms = nparms;
- }
- else
- /* See whether current candidate is better or worse than previous best */
- switch (compare_badness (bv, oload_champ_bv))
- {
- case 0:
- oload_ambiguous = 1; /* top two contenders are equally good */
- oload_ambig_champ = ix;
- break;
- case 1:
- oload_ambiguous = 2; /* incomparable top contenders */
- oload_ambig_champ = ix;
- break;
- case 2:
- oload_champ_bv = bv; /* new champion, record details */
- oload_ambiguous = 0;
- oload_champ = ix;
- oload_ambig_champ = -1;
- champ_nparms = nparms;
- break;
- case 3:
- default:
- break;
- }
- xfree (parm_types);
- if (overload_debug)
- {
- if (method)
- fprintf_filtered (gdb_stderr,"Overloaded method instance %s, # of parms %d\n", fns_ptr[ix].physname, nparms);
- else
- fprintf_filtered (gdb_stderr,"Overloaded function instance %s # of parms %d\n", SYMBOL_DEMANGLED_NAME (oload_syms[ix]), nparms);
- for (jj = 0; jj < nargs - static_offset; jj++)
- fprintf_filtered (gdb_stderr,"...Badness @ %d : %d\n", jj, bv->rank[jj]);
- fprintf_filtered (gdb_stderr,"Overload resolution champion is %d, ambiguous? %d\n", oload_champ, oload_ambiguous);
- }
- } /* end loop over all candidates */
/* NOTE: dan/2000-03-10: Seems to be a better idea to just pick one
if they have the exact same goodness. This is because there is no
way to differentiate based on return type, which we need to in
@@ -2942,18 +2890,13 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method,
#endif
/* Check how bad the best match is. */
- static_offset = 0;
- if (method && TYPE_FN_FIELD_STATIC_P (fns_ptr, oload_champ))
- static_offset = 1;
- for (ix = 1; ix <= nargs - static_offset; ix++)
- {
- if (oload_champ_bv->rank[ix] >= 100)
- oload_incompatible = 1; /* truly mismatched types */
- else if (oload_champ_bv->rank[ix] >= 10)
- oload_non_standard = 1; /* non-standard type conversions needed */
- }
- if (oload_incompatible)
+ match_quality
+ = classify_oload_match (oload_champ_bv, nargs,
+ oload_method_static (method, fns_ptr,
+ oload_champ));
+
+ if (match_quality == INCOMPATIBLE)
{
if (method)
error ("Cannot resolve method %s%s%s to any overloaded instance",
@@ -2964,7 +2907,7 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method,
error ("Cannot resolve function %s to any overloaded instance",
func_name);
}
- else if (oload_non_standard)
+ else if (match_quality == NON_STANDARD)
{
if (method)
warning ("Using non-standard conversion to match method %s%s%s to supplied arguments",
@@ -2978,10 +2921,8 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method,
if (method)
{
- if (staticp && TYPE_FN_FIELD_STATIC_P (fns_ptr, oload_champ))
- *staticp = 1;
- else if (staticp)
- *staticp = 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, basetype, boffset);
else
@@ -3005,7 +2946,138 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method,
if (cleanups != NULL)
do_cleanups (cleanups);
- return oload_incompatible ? 100 : (oload_non_standard ? 10 : 0);
+ switch (match_quality)
+ {
+ case INCOMPATIBLE:
+ return 100;
+ case NON_STANDARD:
+ return 10;
+ default: /* STANDARD */
+ return 0;
+ }
+}
+
+/* Look for a function to take NARGS args of types ARG_TYPES. Find
+ the best match from among the overloaded methods or functions
+ (depending on METHOD) given by FNS_PTR or OLOAD_SYMS, respectively.
+ The number of methods/functions in the list is given by NUM_FNS.
+ Return the index of the best match; store an indication of the
+ quality of the match in OLOAD_CHAMP_BV. */
+
+static int
+find_oload_champ (struct type **arg_types, int nargs, int method,
+ int num_fns, struct fn_field *fns_ptr,
+ struct symbol **oload_syms,
+ struct badness_vector **oload_champ_bv)
+{
+ int ix;
+ struct badness_vector *bv; /* A measure of how good an overloaded instance is */
+ int oload_champ = -1; /* Index of best overloaded function */
+ int oload_ambiguous = 0; /* Current ambiguity state for overload resolution */
+ /* 0 => no ambiguity, 1 => two good funcs, 2 => incomparable funcs */
+
+ *oload_champ_bv = NULL;
+
+ /* Consider each candidate in turn */
+ for (ix = 0; ix < num_fns; ix++)
+ {
+ int jj;
+ int static_offset = oload_method_static (method, fns_ptr, ix);
+ int nparms;
+ struct type **parm_types;
+
+ if (method)
+ {
+ nparms = TYPE_NFIELDS (TYPE_FN_FIELD_TYPE (fns_ptr, ix));
+ }
+ else
+ {
+ /* If it's not a method, this is the proper place */
+ nparms=TYPE_NFIELDS(SYMBOL_TYPE(oload_syms[ix]));
+ }
+
+ /* Prepare array of parameter types */
+ parm_types = (struct type **) xmalloc (nparms * (sizeof (struct type *)));
+ for (jj = 0; jj < nparms; jj++)
+ parm_types[jj] = (method
+ ? (TYPE_FN_FIELD_ARGS (fns_ptr, ix)[jj].type)
+ : TYPE_FIELD_TYPE (SYMBOL_TYPE (oload_syms[ix]), jj));
+
+ /* Compare parameter types to supplied argument types. Skip THIS for
+ static methods. */
+ bv = rank_function (parm_types, nparms, arg_types + static_offset,
+ nargs - static_offset);
+
+ if (!*oload_champ_bv)
+ {
+ *oload_champ_bv = bv;
+ oload_champ = 0;
+ }
+ else
+ /* See whether current candidate is better or worse than previous best */
+ switch (compare_badness (bv, *oload_champ_bv))
+ {
+ case 0:
+ oload_ambiguous = 1; /* top two contenders are equally good */
+ break;
+ case 1:
+ oload_ambiguous = 2; /* incomparable top contenders */
+ break;
+ case 2:
+ *oload_champ_bv = bv; /* new champion, record details */
+ oload_ambiguous = 0;
+ oload_champ = ix;
+ break;
+ case 3:
+ default:
+ break;
+ }
+ xfree (parm_types);
+ if (overload_debug)
+ {
+ if (method)
+ fprintf_filtered (gdb_stderr,"Overloaded method instance %s, # of parms %d\n", fns_ptr[ix].physname, nparms);
+ else
+ fprintf_filtered (gdb_stderr,"Overloaded function instance %s # of parms %d\n", SYMBOL_DEMANGLED_NAME (oload_syms[ix]), nparms);
+ for (jj = 0; jj < nargs - static_offset; jj++)
+ fprintf_filtered (gdb_stderr,"...Badness @ %d : %d\n", jj, bv->rank[jj]);
+ fprintf_filtered (gdb_stderr,"Overload resolution champion is %d, ambiguous? %d\n", oload_champ, oload_ambiguous);
+ }
+ }
+
+ return oload_champ;
+}
+
+/* Return 1 if we're looking at a static method, 0 if we're looking at
+ a non-static method or a function that isn't a 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))
+ return 1;
+ else
+ return 0;
+}
+
+/* Check how good an overload match OLOAD_CHAMP_BV represents. */
+
+static enum oload_classification
+classify_oload_match (struct badness_vector *oload_champ_bv,
+ int nargs,
+ int static_offset)
+{
+ int ix;
+
+ for (ix = 1; ix <= nargs - static_offset; ix++)
+ {
+ if (oload_champ_bv->rank[ix] >= 100)
+ return INCOMPATIBLE; /* truly mismatched types */
+ else if (oload_champ_bv->rank[ix] >= 10)
+ return NON_STANDARD; /* non-standard type conversions needed */
+ }
+
+ return STANDARD; /* Only standard conversions needed. */
}
/* C++: return 1 is NAME is a legitimate name for the destructor
diff --git a/gdb/value.h b/gdb/value.h
index 178f653..a13002b 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -382,6 +382,7 @@ extern struct fn_field *value_find_oload_method_list (struct value **, char *,
extern int find_overload_match (struct type **arg_types, int nargs,
char *name, int method, int lax,
struct value **objp, struct symbol *fsym,
+ const struct block *current_block,
struct value **valp, struct symbol **symp,
int *staticp);