From 714f19d5576e314d5b9c3b674b11bf4212a3faeb Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Mon, 8 Feb 2010 20:55:43 +0000 Subject: [PATCH] gdb PR c++/8017: * value.h: Update. * valops.c (search_struct_field): Make 'name' const. (search_struct_method): Likewise. (find_method_list): Make 'method' const. (value_struct_elt): Make 'name' and 'err' const. (value_find_oload_method_list): Make 'method' const. (find_overload_match): Make 'name' const. * eval.c (evaluate_subexp_standard): New locals function, function_name. : Handle OP_SCOPE specially. gdb/testsuite PR c++/8017: * gdb.cp/overload.exp: Add tests. * gdb.cp/overload.cc (struct K): New. (namespace N): New. (main): Call new functions. (K::staticoverload): Define. --- gdb/ChangeLog | 14 +++++ gdb/eval.c | 85 +++++++++++++++++++++++++++---- gdb/testsuite/ChangeLog | 9 ++++ gdb/testsuite/gdb.cp/overload.cc | 22 ++++++++ gdb/testsuite/gdb.cp/overload.exp | 10 ++++ gdb/valops.c | 22 ++++---- gdb/value.h | 9 ++-- 7 files changed, 146 insertions(+), 25 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index f06ec83a654..0df0ae00a79 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,17 @@ +2010-02-08 Tom Tromey + + PR c++/8017: + * value.h: Update. + * valops.c (search_struct_field): Make 'name' const. + (search_struct_method): Likewise. + (find_method_list): Make 'method' const. + (value_struct_elt): Make 'name' and 'err' const. + (value_find_oload_method_list): Make 'method' const. + (find_overload_match): Make 'name' const. + * eval.c (evaluate_subexp_standard): New locals function, + function_name. + : Handle OP_SCOPE specially. + 2010-02-08 Ulrich Weigand * infrun.c (handle_inferior_event): Do not look up regcache diff --git a/gdb/eval.c b/gdb/eval.c index a0556cf90cb..e2ceea74875 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -696,6 +696,8 @@ evaluate_subexp_standard (struct type *expect_type, long mem_offset; struct type **arg_types; int save_pos1; + struct symbol *function = NULL; + char *function_name = NULL; pc = (*pos)++; op = exp->elts[pc].opcode; @@ -1410,6 +1412,47 @@ evaluate_subexp_standard (struct type *expect_type, /* Now, say which argument to start evaluating from */ tem = 2; } + else if (op == OP_SCOPE + && overload_resolution + && (exp->language_defn->la_language == language_cplus)) + { + /* Unpack it locally so we can properly handle overload + resolution. */ + struct type *qual_type; + char *name; + int local_tem; + + pc2 = (*pos)++; + local_tem = longest_to_int (exp->elts[pc2 + 2].longconst); + (*pos) += 4 + BYTES_TO_EXP_ELEM (local_tem + 1); + type = exp->elts[pc2 + 1].type; + name = &exp->elts[pc2 + 3].string; + + function = NULL; + function_name = NULL; + if (TYPE_CODE (type) == TYPE_CODE_NAMESPACE) + { + function = cp_lookup_symbol_namespace (TYPE_TAG_NAME (type), + name, NULL, + get_selected_block (0), + VAR_DOMAIN, 1); + if (function == NULL) + error (_("No symbol \"%s\" in namespace \"%s\"."), + name, TYPE_TAG_NAME (type)); + + tem = 1; + } + else + { + gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT + || TYPE_CODE (type) == TYPE_CODE_UNION); + function_name = name; + + arg2 = value_zero (type, lval_memory); + ++nargs; + tem = 2; + } + } else { /* Non-method function call */ @@ -1441,15 +1484,22 @@ evaluate_subexp_standard (struct type *expect_type, /* signal end of arglist */ argvec[tem] = 0; - if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR) + if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR + || (op == OP_SCOPE && function_name != NULL)) { int static_memfuncp; - char tstr[256]; + char *tstr; /* Method invocation : stuff "this" as first parameter */ argvec[1] = arg2; - /* Name of method from expression */ - strcpy (tstr, &exp->elts[pc2 + 2].string); + + if (op != OP_SCOPE) + { + /* Name of method from expression */ + tstr = &exp->elts[pc2 + 2].string; + } + else + tstr = function_name; if (overload_resolution && (exp->language_defn->la_language == language_cplus)) { @@ -1466,7 +1516,13 @@ evaluate_subexp_standard (struct type *expect_type, &arg2 /* the object */ , NULL, &valp, NULL, &static_memfuncp); - + if (op == OP_SCOPE && !static_memfuncp) + { + /* For the time being, we don't handle this. */ + error (_("Call to overloaded function %s requires " + "`this' pointer"), + function_name); + } argvec[1] = arg2; /* the ``this'' pointer */ argvec[0] = valp; /* use the method found after overload resolution */ } @@ -1499,7 +1555,7 @@ evaluate_subexp_standard (struct type *expect_type, argvec[1] = arg2; argvec[0] = arg1; } - else if (op == OP_VAR_VALUE) + else if (op == OP_VAR_VALUE || (op == OP_SCOPE && function != NULL)) { /* Non-member function being called */ /* fn: This can only be done for C++ functions. A C-style function @@ -1511,6 +1567,9 @@ evaluate_subexp_standard (struct type *expect_type, /* Language is C++, do some overload resolution before evaluation */ struct symbol *symp; + if (op == OP_VAR_VALUE) + function = exp->elts[save_pos1+2].symbol; + /* Prepare list of argument types for overload resolution */ arg_types = (struct type **) alloca (nargs * (sizeof (struct type *))); for (ix = 1; ix <= nargs; ix++) @@ -1518,12 +1577,18 @@ evaluate_subexp_standard (struct type *expect_type, (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, function /* the function */ , NULL, &symp, NULL); - /* Now fix the expression being evaluated */ - exp->elts[save_pos1+2].symbol = symp; - argvec[0] = evaluate_subexp_with_coercion (exp, &save_pos1, noside); + if (op == OP_VAR_VALUE) + { + /* Now fix the expression being evaluated */ + exp->elts[save_pos1+2].symbol = symp; + argvec[0] = evaluate_subexp_with_coercion (exp, &save_pos1, + noside); + } + else + argvec[0] = value_of_variable (symp, get_selected_block (0)); } else { diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index ccdc8ef8bae..4bbbd9377e3 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2010-02-08 Tom Tromey + + PR c++/8017: + * gdb.cp/overload.exp: Add tests. + * gdb.cp/overload.cc (struct K): New. + (namespace N): New. + (main): Call new functions. + (K::staticoverload): Define. + Mon Feb 8 13:18:22 2010 Chris Moller PR gdb/10728 diff --git a/gdb/testsuite/gdb.cp/overload.cc b/gdb/testsuite/gdb.cp/overload.cc index 64c2090c522..e643d4cdfde 100644 --- a/gdb/testsuite/gdb.cp/overload.cc +++ b/gdb/testsuite/gdb.cp/overload.cc @@ -42,7 +42,18 @@ int overloadargs (int a1, int a2, int a3, int a4, int a5, int a6, int a7, int overloadargs (int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, int a11); +}; + +struct K { + static int staticoverload (); + static int staticoverload (int); + static int staticoverload (int, int); +}; +namespace N { + int nsoverload () { return 1; } + int nsoverload (int x) { return x; } + int nsoverload (int x, int y) { return x + y; } }; int intToChar (char c) @@ -97,6 +108,14 @@ int main () foo foo_instance2(222, str); foo foo_instance3(foo_instance2); + // Some calls to ensure all the functions are emitted. + K::staticoverload(); + K::staticoverload(2); + K::staticoverload(2, 3); + N::nsoverload(); + N::nsoverload(2); + N::nsoverload(2, 3); + #ifdef usestubs set_debug_traps(); breakpoint(); @@ -196,3 +215,6 @@ int foo::overloadargs (int a1, int a2, int a3, int a4, int a5, int a6, int a7, +int K::staticoverload () { return 1; } +int K::staticoverload (int x) { return x; } +int K::staticoverload (int x, int y) { return x + y; } diff --git a/gdb/testsuite/gdb.cp/overload.exp b/gdb/testsuite/gdb.cp/overload.exp index 1bfa0f323b4..317cbc5eb69 100644 --- a/gdb/testsuite/gdb.cp/overload.exp +++ b/gdb/testsuite/gdb.cp/overload.exp @@ -299,6 +299,16 @@ gdb_test "print overloadNamespace(1)" ".\[0-9\]* = 1" gdb_test "print overloadNamespace('a')" ".\[0-9\]* = 1" gdb_test "print overloadNamespace(dummyInstance)" ".\[0-9\]* = 2" +# Static methods. +gdb_test "print K::staticoverload ()" " = 1" +gdb_test "print K::staticoverload (2)" " = 2" +gdb_test "print K::staticoverload (2, 3)" " = 5" + +# Namespace-qualified functions. +gdb_test "print N::nsoverload ()" " = 1" +gdb_test "print N::nsoverload (2)" " = 2" +gdb_test "print N::nsoverload (2, 3)" " = 5" + if ![runto 'XXX::marker2'] then { perror "couldn't run to XXX::marker2" continue diff --git a/gdb/valops.c b/gdb/valops.c index cc7eadf5991..b94c411f062 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -53,12 +53,12 @@ extern int overload_debug; static int typecmp (int staticp, int varargs, int nargs, struct field t1[], struct value *t2[]); -static struct value *search_struct_field (char *, struct value *, +static struct value *search_struct_field (const char *, struct value *, int, struct type *, int); -static struct value *search_struct_method (char *, struct value **, - struct value **, - int, int *, struct type *); +static struct value *search_struct_method (const char *, struct value **, + struct value **, + int, int *, struct type *); static int find_oload_champ_namespace (struct type **, int, const char *, const char *, @@ -100,7 +100,7 @@ static CORE_ADDR allocate_space_in_inferior (int); static struct value *cast_into_complex (struct type *, struct value *); -static struct fn_field *find_method_list (struct value **, char *, +static struct fn_field *find_method_list (struct value **, const char *, int, struct type *, int *, struct type **, int *); @@ -1806,7 +1806,7 @@ typecmp (int staticp, int varargs, int nargs, fields, look for a baseclass named NAME. */ static struct value * -search_struct_field (char *name, struct value *arg1, int offset, +search_struct_field (const char *name, struct value *arg1, int offset, struct type *type, int looking_for_baseclass) { int i; @@ -1963,7 +1963,7 @@ search_struct_field (char *name, struct value *arg1, int offset, (value) -1, else return NULL. */ static struct value * -search_struct_method (char *name, struct value **arg1p, +search_struct_method (const char *name, struct value **arg1p, struct value **args, int offset, int *static_memfuncp, struct type *type) { @@ -2093,7 +2093,7 @@ search_struct_method (char *name, struct value **arg1p, struct value * value_struct_elt (struct value **argp, struct value **args, - char *name, int *static_memfuncp, char *err) + const char *name, int *static_memfuncp, const char *err) { struct type *t; struct value *v; @@ -2188,7 +2188,7 @@ value_struct_elt (struct value **argp, struct value **args, */ static struct fn_field * -find_method_list (struct value **argp, char *method, +find_method_list (struct value **argp, const char *method, int offset, struct type *type, int *num_fns, struct type **basetype, int *boffset) { @@ -2258,7 +2258,7 @@ find_method_list (struct value **argp, char *method, */ struct fn_field * -value_find_oload_method_list (struct value **argp, char *method, +value_find_oload_method_list (struct value **argp, const char *method, int offset, int *num_fns, struct type **basetype, int *boffset) { @@ -2315,7 +2315,7 @@ value_find_oload_method_list (struct value **argp, char *method, int find_overload_match (struct type **arg_types, int nargs, - char *name, int method, int lax, + const char *name, int method, int lax, struct value **objp, struct symbol *fsym, struct value **valp, struct symbol **symp, int *staticp) diff --git a/gdb/value.h b/gdb/value.h index 42b4497d4c1..43b8c3bc0e5 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -431,8 +431,8 @@ extern struct value *value_complement (struct value *arg1); extern struct value *value_struct_elt (struct value **argp, struct value **args, - char *name, int *static_memfuncp, - char *err); + const char *name, int *static_memfuncp, + const char *err); extern struct value *value_aggregate_elt (struct type *curtype, char *name, @@ -442,12 +442,13 @@ extern struct value *value_aggregate_elt (struct type *curtype, extern struct value *value_static_field (struct type *type, int fieldno); -extern struct fn_field *value_find_oload_method_list (struct value **, char *, +extern struct fn_field *value_find_oload_method_list (struct value **, + const char *, int, int *, struct type **, int *); extern int find_overload_match (struct type **arg_types, int nargs, - char *name, int method, int lax, + const char *name, int method, int lax, struct value **objp, struct symbol *fsym, struct value **valp, struct symbol **symp, int *staticp); -- 2.30.2