From mboxrd@z Thu Jan 1 00:00:00 1970 From: Eli Zaretskii To: Dmitry Sivachenko Cc: gdb-patches@sourceware.cygnus.com Subject: Re: Patch to gdb.texinfo Date: Mon, 13 Mar 2000 01:33:00 -0000 Message-id: <200003130933.EAA25971@indy.delorie.com> References: <200003130906.MAA63437@netserv1.chg.ru> <200003121611.TAA45044@netserv1.chg.ru> <200003130859.DAA25938@indy.delorie.com> X-SW-Source: 2000-03/msg00223.html > > -For complicated cases, you can specify an arbitrary number of @r{-T}@var{section} @var{address} > > +For complicated cases, you can specify an arbitrary number of @samp{@r{-T}@var{section} @var{address}} > I don't see the rationale for this change. Could you please explain? > > Look at the printable copy. Single quotes around `-Tsection address' > looks better. You don't need a @samp to add the quotes. What I wanted to point out was that a @samp whose effect is effectively undone by @r and @var is not necessary. I'll let Stan decide on this one. >From dima@Chg.RU Mon Mar 13 01:44:00 2000 From: Dmitry Sivachenko To: eliz@is.elta.co.il Cc: gdb-patches@sourceware.cygnus.com Subject: Re: Patch to gdb.texinfo Date: Mon, 13 Mar 2000 01:44:00 -0000 Message-id: <200003130944.MAA64255@netserv1.chg.ru> References: <200003130906.MAA63437@netserv1.chg.ru> <200003121611.TAA45044@netserv1.chg.ru> <200003130859.DAA25938@indy.delorie.com> <200003130933.EAA25971@indy.delorie.com> X-SW-Source: 2000-03/msg00224.html Content-length: 771 > > -For complicated cases, you can specify an arbitrary number of @r{-T}@var{section} @var{address} > > +For complicated cases, you can specify an arbitrary number of @samp{@r{-T}@var{section} @var{address}} > I don't see the rationale for this change. Could you please explain? > > Look at the printable copy. Single quotes around `-Tsection address' > looks better. You don't need a @samp to add the quotes. What I wanted to point out was that a @samp whose effect is effectively undone by @r and @var is not necessary. I'll let Stan decide on this one. OK, may be it is better to replace @samp with explicit quotes (`.....'). --dima >From Peter.Schauer@regent.e-technik.tu-muenchen.de Mon Mar 13 01:48:00 2000 From: "Peter.Schauer" To: gdb-patches@sourceware.cygnus.com Subject: RFD: infrun.c: No bpstat_stop_status call after proceed over break ? Date: Mon, 13 Mar 2000 01:48:00 -0000 Message-id: <200003130948.KAA07547@reisser.regent.e-technik.tu-muenchen.de> X-SW-Source: 2000-03/msg00226.html Content-length: 4730 I am currently trying to fix a GDB bug with missing watchpoint triggers after proceeding over a breakpoint on x86 targets. Here is an example, using gdb.c++/annota2: (gdb) b main Breakpoint 1 at 0x8048b3a: file annota2.cc, line 21. (gdb) r Starting program: annota2 Breakpoint 1, main () at annota2.cc:21 21 a.x = 0; (gdb) watch a.x Watchpoint 2: a.x (gdb) c Continuing. Watchpoint 2: a.x Old value = -536882292 New value = 1 main () at annota2.cc:23 23 a.y = 2; (gdb) The breakpoint at main is at the instruction which should cause the watchpoint trigger (a.x = 0). When continuing over the breakpoint, breakpoints are removed and the target is single stepped with trap_expected set to one. After the step GDB does not reexamine the stop reason, missing the watchpoint trigger at a.x = 0 and stops too late at the second watchpoint trigger. Here is the relevant code from handle_inferior_event: /* Don't even think about breakpoints if just proceeded over a breakpoint. However, if we are trying to proceed over a breakpoint and end up in sigtramp, then through_sigtramp_breakpoint will be set and we should check whether we've hit the step breakpoint. */ if (stop_signal == TARGET_SIGNAL_TRAP && trap_expected && through_sigtramp_breakpoint == NULL) bpstat_clear (&stop_bpstat); else { /* See if there is a breakpoint at the current PC. */ stop_bpstat = bpstat_stop_status (&stop_pc, . . I currently have no idea why we need to special case the proceed over a breakpoint here, perhaps it is some historic remnant (although I do have this nagging feeling that I might miss something obvious). The patch below would get rid of the special case and fix the problem, it causes no testsuite regressions. Note that bpstat_clear is called and stop_print_frame is set to 1 unconditionally already a few lines above the bpstat_stop_status call, so there is no need to do it again. Any suggestions why we should need the old special case ? 2000-03-12 Peter Schauer * infrun.c (handle_inferior_event): Remove special case for stop after proceeding over a breakpoint, it caused missed watchpoints. *** gdb/infrun.c.orig Thu Feb 24 13:41:46 2000 --- gdb/infrun.c Mon Mar 13 10:11:50 2000 *************** *** 2076,2110 **** return; } ! /* Don't even think about breakpoints ! if just proceeded over a breakpoint. ! ! However, if we are trying to proceed over a breakpoint ! and end up in sigtramp, then through_sigtramp_breakpoint ! will be set and we should check whether we've hit the ! step breakpoint. */ ! if (stop_signal == TARGET_SIGNAL_TRAP && trap_expected ! && through_sigtramp_breakpoint == NULL) ! bpstat_clear (&stop_bpstat); ! else ! { ! /* See if there is a breakpoint at the current PC. */ ! stop_bpstat = bpstat_stop_status ! (&stop_pc, ! /* Pass TRUE if our reason for stopping is something other ! than hitting a breakpoint. We do this by checking that ! 1) stepping is going on and 2) we didn't hit a breakpoint ! in a signal handler without an intervening stop in ! sigtramp, which is detected by a new stack pointer value ! below any usual function calling stack adjustments. */ ! (currently_stepping (ecs) ! && !(step_range_end ! && INNER_THAN (read_sp (), (step_sp - 16)))) ! ); ! /* Following in case break condition called a ! function. */ ! stop_print_frame = 1; ! } if (stop_signal == TARGET_SIGNAL_TRAP) ecs->random_signal --- 2092,2114 ---- return; } ! /* See if there is a breakpoint at the current PC. ! Older versions of GDB did not call bpstat_stop_status after ! proceeding over a breakpoint, causing missed watchpoints when ! proceeding over a breakpoint on an instruction which triggers ! a watchpoint. */ ! stop_bpstat = bpstat_stop_status ! (&stop_pc, ! /* Pass TRUE if our reason for stopping is something other ! than hitting a breakpoint. We do this by checking that ! 1) stepping is going on and 2) we didn't hit a breakpoint ! in a signal handler without an intervening stop in ! sigtramp, which is detected by a new stack pointer value ! below any usual function calling stack adjustments. */ ! (currently_stepping (ecs) ! && !(step_range_end ! && INNER_THAN (read_sp (), (step_sp - 16)))) ! ); if (stop_signal == TARGET_SIGNAL_TRAP) ecs->random_signal -- Peter Schauer pes@regent.e-technik.tu-muenchen.de >From Peter.Schauer@regent.e-technik.tu-muenchen.de Mon Mar 13 01:48:00 2000 From: "Peter.Schauer" To: gdb-patches@sourceware.cygnus.com Subject: RFA: infrun.c, breakpoint.c: Kludge for Solaris x86 hardware watchpoint support Date: Mon, 13 Mar 2000 01:48:00 -0000 Message-id: <200003130947.KAA07528@reisser.regent.e-technik.tu-muenchen.de> X-SW-Source: 2000-03/msg00225.html Content-length: 2985 Unfortunately I'd need the following kludge to work around a Solaris x86 kernel problem with hardware watchpoint support. See the comment in the patches for a description of the problem. Any objections ? 2000-03-12 Peter Schauer breakpoint.c, breakpoint.h (remove_hw_watchpoints): New function. infrun.c (resume): Remove hardware watchpoints before stepping when CANNOT_STEP_HW_WATCHPOINTS is nonzero. *** gdb/breakpoint.c.orig Thu Feb 24 13:41:33 2000 --- gdb/breakpoint.c Sat Mar 4 11:42:48 2000 *************** *** 1080,1085 **** --- 1081,1107 ---- } int + remove_hw_watchpoints () + { + register struct breakpoint *b; + int val; + + ALL_BREAKPOINTS (b) + { + if (b->inserted + && (b->type == bp_hardware_watchpoint + || b->type == bp_read_watchpoint + || b->type == bp_access_watchpoint)) + { + val = remove_breakpoint (b, mark_uninserted); + if (val != 0) + return val; + } + } + return 0; + } + + int reattach_breakpoints (pid) int pid; { *** ./gdb/breakpoint.h.orig Thu Feb 3 05:14:27 2000 --- ./gdb/breakpoint.h Sat Mar 4 11:42:48 2000 *************** *** 562,567 **** --- 562,568 ---- extern int insert_breakpoints PARAMS ((void)); extern int remove_breakpoints PARAMS ((void)); + extern int remove_hw_watchpoints PARAMS ((void)); /* This function can be used to physically insert eventpoints from the specified traced inferior process, without modifying the breakpoint *** gdb/infrun.c.orig Thu Feb 24 13:41:46 2000 --- gdb/infrun.c Mon Mar 13 09:35:54 2000 *************** *** 296,301 **** --- 296,308 ---- #define HAVE_CONTINUABLE_WATCHPOINT 1 #endif + #ifndef CANNOT_STEP_HW_WATCHPOINTS + #define CANNOT_STEP_HW_WATCHPOINTS 0 + #else + #undef CANNOT_STEP_HW_WATCHPOINTS + #define CANNOT_STEP_HW_WATCHPOINTS 1 + #endif + /* Tables of how to react to signals; the user sets them. */ static unsigned char *signal_stop; *************** *** 796,801 **** --- 803,820 ---- if (step && breakpoints_inserted && breakpoint_here_p (read_pc ())) step = 0; #endif + + /* Some targets (e.g. Solaris x86) have a kernel bug when stepping + over an instruction that causes a page fault without triggering + a hardware watchpoint. The kernel properly notices that it shouldn't + stop, because the hardware watchpoint is not triggered, but it forgets + the step request and continues the program normally. + Work around the problem by removing hardware watchpoints if a step is + requested, GDB will check for a hardware watchpoint trigger after the + step anyway. */ + if (CANNOT_STEP_HW_WATCHPOINTS && step && breakpoints_inserted) + remove_hw_watchpoints (); + /* Normally, by the time we reach `resume', the breakpoints are either removed or inserted, as appropriate. The exception is if we're sitting -- Peter Schauer pes@regent.e-technik.tu-muenchen.de >From ac131313@cygnus.com Mon Mar 13 02:05:00 2000 From: Andrew Cagney To: GDB Patches Subject: [PATCH] Fix C++ overloading, add support for seeing through references. Date: Mon, 13 Mar 2000 02:05:00 -0000 Message-id: <38CCBD3A.35459C1C@cygnus.com> X-SW-Source: 2000-03/msg00227.html Content-length: 19325 FYI, I've committed the attatched from Daniel Berlin (except for minor edits). It has a very interesting effect on the arm-elf -> arm-sim testsuite results: ==> before # of expected passes 5715 # of unexpected failures 36 # of unexpected successes 2 # of expected failures 193 # of unresolved testcases 79 # of untested testcases 18 # of unsupported tests 2 ==> after # of expected passes 5716 # of unexpected failures 36 # of unexpected successes 16 # of expected failures 178 # of unresolved testcases 79 # of untested testcases 18 # of unsupported tests 2 where the actual changes are ( ``<'' for old, ``>'' for new): < XFAIL: gdb.c++/derivation.exp: print value of g_instance.afoo() < XFAIL: gdb.c++/derivation.exp: print value of g_instance.bfoo() < XFAIL: gdb.c++/derivation.exp: print value of g_instance.cfoo() > XPASS: gdb.c++/derivation.exp: print value of g_instance.afoo() > XPASS: gdb.c++/derivation.exp: print value of g_instance.bfoo() > XPASS: gdb.c++/derivation.exp: print value of g_instance.cfoo() < XFAIL: gdb.c++/overload.exp: print call overloaded func 1 arg < XFAIL: gdb.c++/overload.exp: print call overloaded func 2 args < XFAIL: gdb.c++/overload.exp: print call overloaded func 3 args > XPASS: gdb.c++/overload.exp: print call overloaded func 1 arg > XPASS: gdb.c++/overload.exp: print call overloaded func 2 args > XPASS: gdb.c++/overload.exp: print call overloaded func 3 args < XFAIL: gdb.c++/overload.exp: print call overloaded func void arg > XPASS: gdb.c++/overload.exp: print call overloaded func void arg < XFAIL: gdb.c++/overload.exp: print call overloaded func signed char arg < XFAIL: gdb.c++/overload.exp: print call overloaded func unsigned char arg > XPASS: gdb.c++/overload.exp: print call overloaded func signed char arg > XPASS: gdb.c++/overload.exp: print call overloaded func unsigned char arg < XFAIL: gdb.c++/overload.exp: print call overloaded func unsigned int arg > XPASS: gdb.c++/overload.exp: print call overloaded func unsigned int arg < XFAIL: gdb.c++/templates.exp: print t5i.value > PASS: gdb.c++/templates.exp: print t5i.value() < XFAIL: gdb.c++/virtfunc.exp: print pAe->f() < XFAIL: gdb.c++/virtfunc.exp: print pAa->f() > XPASS: gdb.c++/virtfunc.exp: print pAe->f() > XPASS: gdb.c++/virtfunc.exp: print pAa->f() < XFAIL: gdb.c++/virtfunc.exp: print pDd->vg() > XPASS: gdb.c++/virtfunc.exp: print pDd->vg() < XFAIL: gdb.c++/virtfunc.exp: print pVB->vvb() > XPASS: gdb.c++/virtfunc.exp: print pVB->vvb() so fixed some long outstanding bugs. Andrew Mon Mar 13 18:54:42 2000 Andrew Cagney From 2000-03-10 Daniel Berlin Fix C++ overloading, add support for seeing through references: * valops.c (find_overload_match): Handle STABS overloading for C++. (find_overload_match): Look in right place for function arguments in the debug info. (find_overload_match): Rather than giving up when we have >1 perfect match, just choose one, especially since the recommendation GDB gives ("disambiguate it by specifying function signature"), is basically impossible. (check_field_in): STREQ->strcmp_iw (search_struct_field): STREQ->strcmp_iw (find_method_list): STREQ->strcmp_iw * gdbtypes.c (rank_one_type): Add ability to see through references. (rank_one_type): strcmp->strcmp_iw, because the whitespace could be different. (rank_function): Rank function properly (was doing it wrong before, comparing the wrong parts of the arrays) (rank_one_type): Change #if 0 to #ifdef DEBUG_OLOAD. * gdbtypes.h: Add REFERENCE_CONVERSION_BADNESS for "badness" associated with converting a non-reference to a reference. * gdbtypes.c (rank_one_type): Add comment on how to eliminate the #ifdef DEBUG_OLOAD. Index: gdbtypes.c =================================================================== RCS file: /cvs/src/src/gdb/gdbtypes.c,v retrieving revision 1.3 diff -p -r1.3 gdbtypes.c *** gdbtypes.c 2000/03/13 07:30:00 1.3 --- gdbtypes.c 2000/03/13 08:47:00 *************** lookup_struct_elt_type (type, name, noer *** 994,1000 **** { char *t_field_name = TYPE_FIELD_NAME (type, i); ! if (t_field_name && STREQ (t_field_name, name)) { return TYPE_FIELD_TYPE (type, i); } --- 994,1000 ---- { char *t_field_name = TYPE_FIELD_NAME (type, i); ! if (t_field_name && (strcmp_iw (t_field_name, name) == 0)) { return TYPE_FIELD_TYPE (type, i); } *************** rank_function (parms, nparms, args, narg *** 2136,2143 **** LENGTH_MATCH (bv) = (nargs != nparms) ? LENGTH_MISMATCH_BADNESS : 0; /* Now rank all the parameters of the candidate function */ ! for (i = 1; i <= min_len; i++) ! bv->rank[i] = rank_one_type (parms[i - 1], args[i - 1]); /* If more arguments than parameters, add dummy entries */ for (i = min_len + 1; i <= nargs; i++) --- 2136,2143 ---- LENGTH_MATCH (bv) = (nargs != nparms) ? LENGTH_MISMATCH_BADNESS : 0; /* Now rank all the parameters of the candidate function */ ! for (i = 1; i < min_len; i++) ! bv->rank[i] = rank_one_type (parms[i], args[i]); /* If more arguments than parameters, add dummy entries */ for (i = min_len + 1; i <= nargs; i++) *************** rank_one_type (parm, arg) *** 2178,2185 **** if (parm == arg) return 0; ! #if 0 ! /* Debugging only */ printf ("------ Arg is %s [%d], parm is %s [%d]\n", TYPE_NAME (arg), TYPE_CODE (arg), TYPE_NAME (parm), TYPE_CODE (parm)); #endif --- 2178,2198 ---- if (parm == arg) return 0; ! /* See through references, since we can almost make non-references ! references. */ ! if (TYPE_CODE (arg) == TYPE_CODE_REF) ! return (rank_one_type (TYPE_TARGET_TYPE (arg), parm) ! + REFERENCE_CONVERSION_BADNESS); ! if (TYPE_CODE (parm) == TYPE_CODE_REF) ! return (rank_one_type (arg, TYPE_TARGET_TYPE (parm)) ! + REFERENCE_CONVERSION_BADNESS); ! ! #ifdef DEBUG_OLOAD ! /* Debugging only. */ ! /* FIXME/FYI: cagney/2000-03-13: No need to #ifdef this sort of ! thing. Instead add a command like ``set debug gdbtypes ''. ! (A predicate to this is the addition of the ``set debug''). Also, ! send the output to gdb_stderr and don't use printf. */ printf ("------ Arg is %s [%d], parm is %s [%d]\n", TYPE_NAME (arg), TYPE_CODE (arg), TYPE_NAME (parm), TYPE_CODE (parm)); #endif *************** rank_one_type (parm, arg) *** 2246,2261 **** { if (TYPE_UNSIGNED (arg)) { ! if (!strcmp (TYPE_NAME (parm), TYPE_NAME (arg))) return 0; /* unsigned int -> unsigned int, or unsigned long -> unsigned long */ ! else if (!strcmp (TYPE_NAME (arg), "int") && !strcmp (TYPE_NAME (parm), "long")) return INTEGER_PROMOTION_BADNESS; /* unsigned int -> unsigned long */ else return INTEGER_COERCION_BADNESS; /* unsigned long -> unsigned int */ } else { ! if (!strcmp (TYPE_NAME (arg), "long") && !strcmp (TYPE_NAME (parm), "int")) return INTEGER_COERCION_BADNESS; /* signed long -> unsigned int */ else return INTEGER_CONVERSION_BADNESS; /* signed int/long -> unsigned int/long */ --- 2259,2274 ---- { if (TYPE_UNSIGNED (arg)) { ! if (!strcmp_iw (TYPE_NAME (parm), TYPE_NAME (arg))) return 0; /* unsigned int -> unsigned int, or unsigned long -> unsigned long */ ! else if (!strcmp_iw (TYPE_NAME (arg), "int") && !strcmp_iw (TYPE_NAME (parm), "long")) return INTEGER_PROMOTION_BADNESS; /* unsigned int -> unsigned long */ else return INTEGER_COERCION_BADNESS; /* unsigned long -> unsigned int */ } else { ! if (!strcmp_iw (TYPE_NAME (arg), "long") && !strcmp_iw (TYPE_NAME (parm), "int")) return INTEGER_COERCION_BADNESS; /* signed long -> unsigned int */ else return INTEGER_CONVERSION_BADNESS; /* signed int/long -> unsigned int/long */ *************** rank_one_type (parm, arg) *** 2263,2271 **** } else if (!TYPE_NOSIGN (arg) && !TYPE_UNSIGNED (arg)) { ! if (!strcmp (TYPE_NAME (parm), TYPE_NAME (arg))) return 0; ! else if (!strcmp (TYPE_NAME (arg), "int") && !strcmp (TYPE_NAME (parm), "long")) return INTEGER_PROMOTION_BADNESS; else return INTEGER_COERCION_BADNESS; --- 2276,2284 ---- } else if (!TYPE_NOSIGN (arg) && !TYPE_UNSIGNED (arg)) { ! if (!strcmp_iw (TYPE_NAME (parm), TYPE_NAME (arg))) return 0; ! else if (!strcmp_iw (TYPE_NAME (arg), "int") && !strcmp_iw (TYPE_NAME (parm), "long")) return INTEGER_PROMOTION_BADNESS; else return INTEGER_COERCION_BADNESS; Index: gdbtypes.h =================================================================== RCS file: /cvs/src/src/gdb/gdbtypes.h,v retrieving revision 1.3 diff -p -r1.3 gdbtypes.h *** gdbtypes.h 2000/03/13 07:30:00 1.3 --- gdbtypes.h 2000/03/13 08:47:03 *************** count_virtual_fns PARAMS ((struct type * *** 1129,1136 **** #define POINTER_CONVERSION_BADNESS 2 /* Badness of conversion of pointer to void pointer */ #define VOID_PTR_CONVERSION_BADNESS 2 ! /* Badness of convering derived to base class */ #define BASE_CONVERSION_BADNESS 2 /* Non-standard conversions allowed by the debugger */ /* Converting a pointer to an int is usually OK */ --- 1129,1138 ---- #define POINTER_CONVERSION_BADNESS 2 /* Badness of conversion of pointer to void pointer */ #define VOID_PTR_CONVERSION_BADNESS 2 ! /* Badness of converting derived to base class */ #define BASE_CONVERSION_BADNESS 2 + /* Badness of converting from non-reference to reference */ + #define REFERENCE_CONVERSION_BADNESS 2 /* Non-standard conversions allowed by the debugger */ /* Converting a pointer to an int is usually OK */ Index: valops.c =================================================================== RCS file: /cvs/src/src/gdb/valops.c,v retrieving revision 1.5 diff -p -r1.5 valops.c *** valops.c 2000/03/13 07:30:00 1.5 --- valops.c 2000/03/13 08:47:19 *************** search_struct_field (name, arg1, offset, *** 2068,2074 **** { char *t_field_name = TYPE_FIELD_NAME (type, i); ! if (t_field_name && STREQ (t_field_name, name)) { value_ptr v; if (TYPE_FIELD_STATIC (type, i)) --- 2068,2074 ---- { char *t_field_name = TYPE_FIELD_NAME (type, i); ! if (t_field_name && (strcmp_iw (t_field_name, name) == 0)) { value_ptr v; if (TYPE_FIELD_STATIC (type, i)) *************** search_struct_field (name, arg1, offset, *** 2083,2089 **** if (t_field_name && (t_field_name[0] == '\0' || (TYPE_CODE (type) == TYPE_CODE_UNION ! && STREQ (t_field_name, "else")))) { struct type *field_type = TYPE_FIELD_TYPE (type, i); if (TYPE_CODE (field_type) == TYPE_CODE_UNION --- 2083,2089 ---- if (t_field_name && (t_field_name[0] == '\0' || (TYPE_CODE (type) == TYPE_CODE_UNION ! && (strcmp_iw (t_field_name, "else") == 0)))) { struct type *field_type = TYPE_FIELD_TYPE (type, i); if (TYPE_CODE (field_type) == TYPE_CODE_UNION *************** search_struct_field (name, arg1, offset, *** 2128,2134 **** is not yet filled in. */ int found_baseclass = (looking_for_baseclass && TYPE_BASECLASS_NAME (type, i) != NULL ! && STREQ (name, TYPE_BASECLASS_NAME (type, i))); if (BASETYPE_VIA_VIRTUAL (type, i)) { --- 2128,2134 ---- is not yet filled in. */ int found_baseclass = (looking_for_baseclass && TYPE_BASECLASS_NAME (type, i) != NULL ! && (strcmp_iw (name, TYPE_BASECLASS_NAME (type, i)) == 0)); if (BASETYPE_VIA_VIRTUAL (type, i)) { *************** search_struct_method (name, arg1p, args, *** 2314,2320 **** else if (cplus_demangle_opname (t_field_name, dem_opname, 0)) t_field_name = dem_opname; } ! if (t_field_name && STREQ (t_field_name, name)) { int j = TYPE_FN_FIELDLIST_LENGTH (type, i) - 1; struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i); --- 2314,2320 ---- else if (cplus_demangle_opname (t_field_name, dem_opname, 0)) t_field_name = dem_opname; } ! if (t_field_name && (strcmp_iw (t_field_name, name) == 0)) { int j = TYPE_FN_FIELDLIST_LENGTH (type, i) - 1; struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i); *************** find_method_list (argp, method, offset, *** 2570,2576 **** { /* pai: FIXME What about operators and type conversions? */ char *fn_field_name = TYPE_FN_FIELDLIST_NAME (type, i); ! if (fn_field_name && STREQ (fn_field_name, method)) { *num_fns = TYPE_FN_FIELDLIST_LENGTH (type, i); *basetype = type; --- 2570,2576 ---- { /* pai: FIXME What about operators and type conversions? */ char *fn_field_name = TYPE_FN_FIELDLIST_NAME (type, i); ! if (fn_field_name && (strcmp_iw (fn_field_name, method) == 0)) { *num_fns = TYPE_FN_FIELDLIST_LENGTH (type, i); *basetype = type; *************** find_overload_match (arg_types, nargs, n *** 2740,2745 **** --- 2740,2748 ---- /* Get the list of overloaded methods or functions */ if (method) { + int i; + int len; + struct type *domain; obj_type_name = TYPE_NAME (VALUE_TYPE (obj)); /* Hack: evaluate_subexp_standard often passes in a pointer value rather than the object itself, so try again */ *************** find_overload_match (arg_types, nargs, n *** 2756,2761 **** --- 2759,2784 ---- obj_type_name, (obj_type_name && *obj_type_name) ? "::" : "", name); + domain = TYPE_DOMAIN_TYPE (fns_ptr[0].type); + len = TYPE_NFN_FIELDS (domain); + /* NOTE: dan/2000-03-10: This stuff is for STABS, which won't + give us the info we need directly in the types. We have to + use the method stub conversion to get it. Be aware that this + is by no means perfect, and if you use STABS, please move to + DWARF-2, or something like it, because trying to improve + overloading using STABS is really a waste of time. */ + for (i = 0; i < len; i++) + { + int j; + struct fn_field *f = TYPE_FN_FIELDLIST1 (domain, i); + int len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i); + + for (j = 0; j < len2; j++) + { + if (TYPE_FN_FIELD_STUB (f, j)) + check_stub_method (domain, i, j); + } + } } else { *************** find_overload_match (arg_types, nargs, n *** 2782,2795 **** /* Consider each candidate in turn */ for (ix = 0; ix < num_fns; ix++) { ! /* Number of parameters for current candidate */ ! nparms = method ? TYPE_NFIELDS (fns_ptr[ix].type) ! : 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_FIELD_TYPE (fns_ptr[ix].type, jj) : TYPE_FIELD_TYPE (SYMBOL_TYPE (oload_syms[ix]), jj); /* Compare parameter types to supplied argument types */ --- 2805,2832 ---- /* Consider each candidate in turn */ for (ix = 0; ix < num_fns; ix++) { ! if (method) ! { ! /* For static member functions, we won't have a this pointer, but nothing ! else seems to handle them right now, so we just pretend ourselves */ ! nparms=0; + if (TYPE_FN_FIELD_ARGS(fns_ptr,ix)) + { + while (TYPE_CODE(TYPE_FN_FIELD_ARGS(fns_ptr,ix)[nparms]) != TYPE_CODE_VOID) + nparms++; + } + } + 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_FIELD_TYPE (SYMBOL_TYPE (oload_syms[ix]), jj); /* Compare parameter types to supplied argument types */ *************** find_overload_match (arg_types, nargs, n *** 2826,2841 **** } free (parm_types); #ifdef DEBUG_OLOAD if (method) printf ("Overloaded method instance %s, # of parms %d\n", fns_ptr[ix].physname, nparms); else printf ("Overloaded function instance %s # of parms %d\n", SYMBOL_DEMANGLED_NAME (oload_syms[ix]), nparms); ! for (jj = 0; jj <= nargs; jj++) printf ("...Badness @ %d : %d\n", jj, bv->rank[jj]); printf ("Overload resolution champion is %d, ambiguous? %d\n", oload_champ, oload_ambiguous); #endif } /* end loop over all candidates */ if (oload_ambiguous) { if (method) --- 2863,2885 ---- } free (parm_types); #ifdef DEBUG_OLOAD + /* FIXME: cagney/2000-03-12: Send the output to gdb_stderr. See + comments above about adding a ``set debug'' command. */ if (method) printf ("Overloaded method instance %s, # of parms %d\n", fns_ptr[ix].physname, nparms); else printf ("Overloaded function instance %s # of parms %d\n", SYMBOL_DEMANGLED_NAME (oload_syms[ix]), nparms); ! for (jj = 0; jj < nargs; jj++) printf ("...Badness @ %d : %d\n", jj, bv->rank[jj]); printf ("Overload resolution champion is %d, ambiguous? %d\n", oload_champ, oload_ambiguous); #endif } /* 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 + cases like overloads of .begin() */ + #if 0 if (oload_ambiguous) { if (method) *************** find_overload_match (arg_types, nargs, n *** 2847,2852 **** --- 2891,2897 ---- error ("Cannot resolve overloaded function %s to unique instance; disambiguate by specifying function signature", func_name); } + #endif /* Check how bad the best match is */ for (ix = 1; ix <= nargs; ix++) *************** check_field_in (type, name) *** 2943,2949 **** for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--) { char *t_field_name = TYPE_FIELD_NAME (type, i); ! if (t_field_name && STREQ (t_field_name, name)) return 1; } --- 2988,2994 ---- for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--) { char *t_field_name = TYPE_FIELD_NAME (type, i); ! if (t_field_name && (strcmp_iw (t_field_name, name) == 0)) return 1; } *************** check_field_in (type, name) *** 2960,2966 **** for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; --i) { ! if (STREQ (TYPE_FN_FIELDLIST_NAME (type, i), name)) return 1; } --- 3005,3011 ---- for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; --i) { ! if (strcmp_iw (TYPE_FN_FIELDLIST_NAME (type, i), name) == 0) return 1; } >From ac131313@cygnus.com Mon Mar 13 02:51:00 2000 From: Andrew Cagney To: GDB Patches Subject: [RFC] Notes on QUIT and STREQ et.al. Date: Mon, 13 Mar 2000 02:51:00 -0000 Message-id: <38CCC819.1071F28E@cygnus.com> X-SW-Source: 2000-03/msg00228.html Content-length: 1709 The attatched spells out the long term prospects of both STREQ et.al. and QUIT. Look OK to everyone? Andrew Mon Mar 13 21:21:41 2000 Andrew Cagney * defs.h (STREQ): Note that the STR* macros do not need to be used. (QUIT): Note that this can probably be replaced by a function. Index: defs.h =================================================================== RCS file: /cvs/src/src/gdb/defs.h,v retrieving revision 1.11 diff -p -r1.11 defs.h *** defs.h 2000/03/13 07:30:00 1.11 --- defs.h 2000/03/13 10:24:00 *************** extern int core_addr_greaterthan (CORE_A *** 120,125 **** --- 120,130 ---- /* Gdb does *lots* of string compares. Use macros to speed them up by avoiding function calls if the first characters are not the same. */ + /* NOTE: cagney/2000-03-13: There is no reason for using these macros + in new code (which is just short of marking them as deprecated). + While old code can continue to refer to them, new code is better + off using the more familar strcmp(). */ + #define STRCMP(a,b) (*(a) == *(b) ? strcmp ((a), (b)) : (int)*(a) - (int)*(b)) #define STREQ(a,b) (*(a) == *(b) ? !strcmp ((a), (b)) : 0) #define STREQN(a,b,c) (*(a) == *(b) ? !strncmp ((a), (b), (c)) : 0) *************** extern int immediate_quit; *** 152,157 **** --- 157,167 ---- extern int sevenbit_strings; extern void quit (void); + + /* FIXME: cagney/2000-03-13: It has been suggested that the peformance + benefits of having a ``QUIT'' macro rather than a function are + marginal. Before QUIT can be replaced by a function, a profile + confirming this, would be needed. */ #ifdef QUIT /* do twice to force compiler warning */ >From kettenis@wins.uva.nl Mon Mar 13 06:12:00 2000 From: Mark Kettenis To: ac131313@cygnus.com Cc: gdb-patches@sourceware.cygnus.com Subject: Re: [RFC] Notes on QUIT and STREQ et.al. Date: Mon, 13 Mar 2000 06:12:00 -0000 Message-id: <200003131412.PAA16094@landau.wins.uva.nl> References: <38CCC819.1071F28E@cygnus.com> X-SW-Source: 2000-03/msg00229.html Content-length: 573 Date: Mon, 13 Mar 2000 21:51:05 +1100 From: Andrew Cagney The attatched spells out the long term prospects of both STREQ et.al. and QUIT. Look OK to everyone? Well, STRCMP really doesn't make any sense. A decent compiler in combination with appropriate headers will take care of the optimization. I'm not sure if we want STREQ to go. I think that `STREQ (a, b)' is both easier to read and easier to type than `strcmp (a, b) == 0'. There are quite a few GNU projects that use exactly the same macro in exactly the same way. Mark