summaryrefslogtreecommitdiff
path: root/gdb/linespec.c
diff options
context:
space:
mode:
authornobody <>2004-02-14 00:00:34 +0000
committernobody <>2004-02-14 00:00:34 +0000
commit2f344a4dcd2a8c4297702027a943e3587e6b60c8 (patch)
tree8614f4d9fc669ec37a90e4b4f70b31f00c489661 /gdb/linespec.c
parenta5dd37ab655106440e987830db5111b43f271ecc (diff)
downloadbinutils-gdb-cagney_bfdfile-20040213-branch.tar.gz
This commit was manufactured by cvs2svn to create branchcagney_bfdfile-20040213-branchpointcagney_bfdfile-20040213-branch
'cagney_bfdfile-20040213-branch'. Sprout from cagney_bigcore-20040122-branch 2004-01-22 00:00:03 UTC nobody 'This commit was manufactured by cvs2svn to create branch' Cherrypick from master 2004-02-14 00:00:33 UTC gdbadmin <gdbadmin@sourceware.org> '*** empty log message ***': COPYING.NEWLIB ChangeLog Makefile.def Makefile.in bfd/ChangeLog bfd/bfd-in.h bfd/bfd-in2.h bfd/bfdio.c bfd/cache.c bfd/coff-h8300.c bfd/config.in bfd/configure bfd/configure.in bfd/elf-bfd.h bfd/elf.c bfd/elf32-arm.h bfd/elf32-frv.c bfd/elf32-h8300.c bfd/elf64-alpha.c bfd/elfxx-ia64.c bfd/elfxx-mips.c bfd/elfxx-mips.h bfd/elfxx-target.h bfd/libbfd-in.h bfd/libbfd.h bfd/version.h binutils/ChangeLog binutils/readelf.c configure configure.in gas/ChangeLog gas/config/tc-arm.c gas/config/tc-ia64.c gas/config/tc-ia64.h gas/config/tc-m68k.c gas/config/tc-m68k.h gas/config/tc-mips.c gas/config/tc-mips.h gas/doc/internals.texi gas/dwarf2dbg.c gas/frags.c gas/frags.h gas/read.c gas/read.h gas/testsuite/ChangeLog gas/testsuite/gas/arm/arm.exp gas/testsuite/gas/arm/undefined.l gas/testsuite/gas/arm/undefined.s gas/testsuite/gas/macros/test2.s gas/testsuite/gas/mips/div.d gas/testsuite/gas/mips/elf-rel-got-n32.d gas/testsuite/gas/mips/elf-rel-got-n64.d gas/testsuite/gas/mips/elf-rel-xgot-n32.d gas/testsuite/gas/mips/elf-rel-xgot-n64.d gas/testsuite/gas/mips/elf-rel19.d gas/testsuite/gas/mips/elf-rel19.s gas/testsuite/gas/mips/la-svr4pic.d gas/testsuite/gas/mips/la-xgot.d gas/testsuite/gas/mips/lca-svr4pic.d gas/testsuite/gas/mips/lca-xgot.d gas/testsuite/gas/mips/macro-warn-1-n32.d gas/testsuite/gas/mips/macro-warn-1-n32.l gas/testsuite/gas/mips/macro-warn-1.d gas/testsuite/gas/mips/macro-warn-1.l gas/testsuite/gas/mips/macro-warn-1.s gas/testsuite/gas/mips/macro-warn-2-n32.d gas/testsuite/gas/mips/macro-warn-2.d gas/testsuite/gas/mips/macro-warn-2.l gas/testsuite/gas/mips/macro-warn-2.s gas/testsuite/gas/mips/macro-warn-3.d gas/testsuite/gas/mips/macro-warn-3.l gas/testsuite/gas/mips/macro-warn-3.s gas/testsuite/gas/mips/macro-warn-4.d gas/testsuite/gas/mips/macro-warn-4.l gas/testsuite/gas/mips/macro-warn-4.s gas/testsuite/gas/mips/mips.exp gas/testsuite/gas/mips/relax-swap1-mips2.d gas/testsuite/gas/mips/relax-swap1.s gas/testsuite/gas/mips/relax-swap2.s gas/testsuite/gas/sh/basic.exp gas/testsuite/gas/sh/err-sh4a-fp.s gas/testsuite/gas/sh/sh4a-fp.d gas/testsuite/gas/sh/sh4a-fp.s gdb/ChangeLog gdb/Makefile.in gdb/NEWS gdb/PROBLEMS gdb/ada-lang.c gdb/alpha-tdep.c gdb/arch-utils.c gdb/arch-utils.h gdb/arm-tdep.c gdb/auxv.c gdb/auxv.h gdb/avr-tdep.c gdb/ax-gdb.c gdb/bcache.c gdb/blockframe.c gdb/breakpoint.c gdb/breakpoint.h gdb/buildsym.c gdb/c-lang.c gdb/cli/cli-cmds.c gdb/cli/cli-decode.c gdb/coffread.c gdb/config/mips/tm-linux.h gdb/config/nm-linux.h gdb/config/sparc/nm-nbsd.h gdb/config/sparc/obsd.mt gdb/config/sparc/obsd64.mt gdb/configure gdb/configure.host gdb/configure.in gdb/configure.tgt gdb/corelow.c gdb/cp-namespace.c gdb/cp-support.c gdb/cp-support.h gdb/cris-tdep.c gdb/d10v-tdep.c gdb/dbxread.c gdb/defs.h gdb/doc/ChangeLog gdb/doc/gdb.texinfo gdb/doc/gdbint.texinfo gdb/doc/stabs.texinfo gdb/dwarf2-frame.c gdb/dwarf2-frame.h gdb/dwarf2loc.c gdb/dwarf2loc.h gdb/dwarf2read.c gdb/dwarfread.c gdb/elfread.c gdb/f-lang.c gdb/findvar.c gdb/frame.c gdb/frame.h gdb/frv-tdep.c gdb/gdb-events.h gdb/gdb-events.sh gdb/gdb_curses.h gdb/gdb_obstack.h gdb/gdbarch.c gdb/gdbarch.h gdb/gdbarch.sh gdb/gdbserver/ChangeLog gdb/gdbserver/linux-low.c gdb/gdbserver/linux-low.h gdb/gdbserver/regcache.c gdb/gdbtypes.c gdb/gdbtypes.h gdb/h8300-tdep.c gdb/hppa-tdep.c gdb/hpread.c gdb/i386-linux-tdep.c gdb/i386-nto-tdep.c gdb/ia64-tdep.c gdb/infcmd.c gdb/infrun.c gdb/inftarg.c gdb/jv-lang.c gdb/language.c gdb/language.h gdb/linespec.c gdb/linux-proc.c gdb/m2-lang.c gdb/m32r-rom.c gdb/m32r-tdep.c gdb/m68hc11-tdep.c gdb/m68k-tdep.c gdb/m68klinux-tdep.c gdb/main.c gdb/mcore-tdep.c gdb/mdebugread.c gdb/mi/mi-cmd-stack.c gdb/mi/mi-cmd-var.c gdb/mi/mi-cmds.h gdb/minsyms.c gdb/mips-linux-nat.c gdb/mips-linux-tdep.c gdb/mips-tdep.c gdb/mn10300-tdep.c gdb/ns32k-tdep.c gdb/objc-lang.c gdb/objfiles.c gdb/objfiles.h gdb/osabi.c gdb/p-lang.c gdb/pa64solib.c gdb/printcmd.c gdb/proc-api.c gdb/procfs.c gdb/regcache.c gdb/remote-fileio.c gdb/remote-rdi.c gdb/remote-sim.c gdb/remote.c gdb/rs6000-tdep.c gdb/s390-tdep.c gdb/scm-lang.c gdb/ser-pipe.c gdb/sh-tdep.c gdb/sh64-tdep.c gdb/sol-thread.c gdb/solib-sunos.c gdb/somread.c gdb/somsolib.c gdb/source.c gdb/sparc-nat.c gdb/sparc-tdep.c gdb/sparc-tdep.h gdb/sparc64-tdep.h gdb/sparc64nbsd-tdep.c gdb/sparc64obsd-tdep.c gdb/sparcnbsd-tdep.c gdb/sparcobsd-tdep.c gdb/stabsread.c gdb/stack.c gdb/symfile.c gdb/symfile.h gdb/symmisc.c gdb/symtab.c gdb/symtab.h gdb/target.h gdb/testsuite/ChangeLog gdb/testsuite/config/sim.exp gdb/testsuite/gdb.arch/gdb1291.c gdb/testsuite/gdb.arch/gdb1431.c gdb/testsuite/gdb.asm/asm-source.exp gdb/testsuite/gdb.asm/ia64.inc gdb/testsuite/gdb.asm/openbsd.inc gdb/testsuite/gdb.base/Makefile.in gdb/testsuite/gdb.base/bang.exp gdb/testsuite/gdb.base/call-ar-st.exp gdb/testsuite/gdb.base/charset.c gdb/testsuite/gdb.base/chng-syms.c gdb/testsuite/gdb.base/chng-syms.exp gdb/testsuite/gdb.base/completion.exp gdb/testsuite/gdb.base/dump.c gdb/testsuite/gdb.base/dump.exp gdb/testsuite/gdb.base/fileio.c gdb/testsuite/gdb.base/finish.exp gdb/testsuite/gdb.base/gcore.exp gdb/testsuite/gdb.base/huge.c gdb/testsuite/gdb.base/huge.exp gdb/testsuite/gdb.base/info-proc.exp gdb/testsuite/gdb.base/langs.exp gdb/testsuite/gdb.base/maint.exp gdb/testsuite/gdb.base/pending.c gdb/testsuite/gdb.base/pending.exp gdb/testsuite/gdb.base/pendshr.c gdb/testsuite/gdb.base/return2.exp gdb/testsuite/gdb.base/shlib-call.exp gdb/testsuite/gdb.cp/ambiguous.exp gdb/testsuite/gdb.cp/annota2.exp gdb/testsuite/gdb.cp/annota3.exp gdb/testsuite/gdb.cp/anon-union.exp gdb/testsuite/gdb.cp/breakpoint.cc gdb/testsuite/gdb.cp/breakpoint.exp gdb/testsuite/gdb.cp/bs15503.cc gdb/testsuite/gdb.cp/casts.exp gdb/testsuite/gdb.cp/class2.cc gdb/testsuite/gdb.cp/classes.exp gdb/testsuite/gdb.cp/cplusfuncs.exp gdb/testsuite/gdb.cp/ctti.exp gdb/testsuite/gdb.cp/cttiadd.cc gdb/testsuite/gdb.cp/cttiadd1.cc gdb/testsuite/gdb.cp/cttiadd2.cc gdb/testsuite/gdb.cp/cttiadd3.cc gdb/testsuite/gdb.cp/demangle.exp gdb/testsuite/gdb.cp/derivation.exp gdb/testsuite/gdb.cp/exception.cc gdb/testsuite/gdb.cp/exception.exp gdb/testsuite/gdb.cp/hang.exp gdb/testsuite/gdb.cp/inherit.exp gdb/testsuite/gdb.cp/local.exp gdb/testsuite/gdb.cp/maint.exp gdb/testsuite/gdb.cp/member-ptr.cc gdb/testsuite/gdb.cp/member-ptr.exp gdb/testsuite/gdb.cp/method.exp gdb/testsuite/gdb.cp/misc.exp gdb/testsuite/gdb.cp/namespace.cc gdb/testsuite/gdb.cp/namespace.exp gdb/testsuite/gdb.cp/namespace1.cc gdb/testsuite/gdb.cp/overload.cc gdb/testsuite/gdb.cp/overload.exp gdb/testsuite/gdb.cp/ovldbreak.exp gdb/testsuite/gdb.cp/psmang.exp gdb/testsuite/gdb.cp/ref-types.exp gdb/testsuite/gdb.cp/rtti.exp gdb/testsuite/gdb.cp/rtti1.cc gdb/testsuite/gdb.cp/templates.exp gdb/testsuite/gdb.cp/userdef.exp gdb/testsuite/gdb.cp/virtfunc.exp gdb/testsuite/gdb.mi/mi-stack.exp gdb/testsuite/gdb.mi/mi-var-child.exp gdb/testsuite/gdb.objc/basicclass.exp gdb/testsuite/gdb.threads/gcore-thread.exp gdb/testsuite/gdb.threads/thread-specific.c gdb/testsuite/gdb.threads/thread-specific.exp gdb/testsuite/lib/compiler.c gdb/testsuite/lib/compiler.cc gdb/testsuite/lib/gdb.exp gdb/tui/tui-command.c gdb/tui/tui-data.c gdb/tui/tui-data.h gdb/tui/tui-disasm.c gdb/tui/tui-file.c gdb/tui/tui-hooks.c gdb/tui/tui-hooks.h gdb/tui/tui-interp.c gdb/tui/tui-io.c gdb/tui/tui-layout.c gdb/tui/tui-layout.h gdb/tui/tui-regs.c gdb/tui/tui-regs.h gdb/tui/tui-source.c gdb/tui/tui-source.h gdb/tui/tui-stack.c gdb/tui/tui-stack.h gdb/tui/tui-win.c gdb/tui/tui-win.h gdb/tui/tui-windata.c gdb/tui/tui-windata.h gdb/tui/tui-wingeneral.c gdb/tui/tui-wingeneral.h gdb/tui/tui-winsource.c gdb/tui/tui-winsource.h gdb/tui/tui.c gdb/tui/tui.h gdb/utils.c gdb/v850-tdep.c gdb/valops.c gdb/values.c gdb/vax-tdep.c gdb/version.in gdb/xcoffread.c gdb/xstormy16-tdep.c include/elf/ChangeLog include/elf/common.h include/opcode/ChangeLog include/opcode/h8300.h ld/ChangeLog ld/emulparams/armelf.sh ld/emulparams/armelf_linux.sh ld/emulparams/elf32bmip.sh ld/emulparams/elf32bmipn32.sh ld/emulparams/elf32btsmipn32.sh ld/emulparams/elf64_ia64.sh ld/emulparams/shlelf_linux.sh ld/emultempl/pe.em ld/genscripts.sh ld/testsuite/ChangeLog ld/testsuite/ld-arm/arm-app-abs32.d ld/testsuite/ld-arm/arm-app-abs32.r ld/testsuite/ld-arm/arm-app-abs32.s ld/testsuite/ld-arm/arm-elf.exp ld/testsuite/ld-h8300/h8300.exp ld/testsuite/ld-h8300/relax-5-coff.d ld/testsuite/ld-h8300/relax-5.d ld/testsuite/ld-h8300/relax-5.s libiberty/ChangeLog libiberty/Makefile.in libiberty/configure libiberty/configure.ac libiberty/getpwd.c libiberty/maint-tool opcodes/ChangeLog opcodes/m32r-dis.c opcodes/sh-opc.h readline/ChangeLog.gdb readline/bind.c readline/mbutil.c readline/readline.c readline/vi_mode.c sim/ChangeLog sim/configure sim/configure.in sim/m32r/ChangeLog sim/m32r/mloop2.in sim/m32r/mloopx.in sim/ppc/ChangeLog sim/ppc/ppc-instructions sim/sh/ChangeLog sim/sh/gencode.c sim/sh/interp.c sim/testsuite/ChangeLog sim/testsuite/lib/sim-defs.exp sim/testsuite/sim/mips/ChangeLog sim/testsuite/sim/mips/basic.exp sim/testsuite/sim/mips/sanity.s sim/testsuite/sim/mips/testutils.inc sim/testsuite/sim/sh/ChangeLog sim/testsuite/sim/sh/allinsn.exp sim/testsuite/sim/sh/and.s sim/testsuite/sim/sh/movi.s sim/testsuite/sim/sh/sett.s sim/testsuite/sim/sh/testutils.inc Delete: gdb/testsuite/gdb.mi/mi1-basics.exp gdb/testsuite/gdb.mi/mi1-break.exp gdb/testsuite/gdb.mi/mi1-console.exp gdb/testsuite/gdb.mi/mi1-disassemble.exp gdb/testsuite/gdb.mi/mi1-eval.exp gdb/testsuite/gdb.mi/mi1-hack-cli.exp gdb/testsuite/gdb.mi/mi1-pthreads.exp gdb/testsuite/gdb.mi/mi1-read-memory.exp gdb/testsuite/gdb.mi/mi1-regs.exp gdb/testsuite/gdb.mi/mi1-return.exp gdb/testsuite/gdb.mi/mi1-simplerun.exp gdb/testsuite/gdb.mi/mi1-stack.exp gdb/testsuite/gdb.mi/mi1-stepi.exp gdb/testsuite/gdb.mi/mi1-symbol.exp gdb/testsuite/gdb.mi/mi1-until.exp gdb/testsuite/gdb.mi/mi1-var-block.exp gdb/testsuite/gdb.mi/mi1-var-child.exp gdb/testsuite/gdb.mi/mi1-var-cmd.exp gdb/testsuite/gdb.mi/mi1-var-display.exp gdb/testsuite/gdb.mi/mi1-watch.exp
Diffstat (limited to 'gdb/linespec.c')
-rw-r--r--gdb/linespec.c259
1 files changed, 159 insertions, 100 deletions
diff --git a/gdb/linespec.c b/gdb/linespec.c
index e16e96ea16e..eedc671fd00 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -694,7 +694,11 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
/* Check to see if it's a multipart linespec (with colons or
periods). */
- /* Locate the end of the first half of the linespec. */
+ /* Locate the end of the first half of the linespec.
+ After the call, for instance, if the argptr string is "foo.c:123"
+ p will point at "123". If there is only one part, like "foo", p
+ will point to "". If this is a C++ name, like "A::B::foo", p will
+ point to "::B::foo". Argptr is not changed by this call. */
p = locate_first_half (argptr, &is_quote_enclosed);
@@ -723,8 +727,13 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
if (is_quoted)
*argptr = *argptr + 1;
- /* Is it a C++ or Java compound data structure? */
-
+ /* Is it a C++ or Java compound data structure?
+ The check on p[1] == ':' is capturing the case of "::",
+ since p[0]==':' was checked above.
+ Note that the call to decode_compound does everything
+ for us, including the lookup on the symbol table, so we
+ can return now. */
+
if (p[0] == '.' || p[1] == ':')
return decode_compound (argptr, funfirstline, canonical,
saved_arg, p);
@@ -954,7 +963,9 @@ decode_indirect (char **argptr)
/* Locate the first half of the linespec, ending in a colon, period,
or whitespace. (More or less.) Also, check to see if *ARGPTR is
enclosed in double quotes; if so, set is_quote_enclosed, advance
- ARGPTR past that and zero out the trailing double quote. */
+ ARGPTR past that and zero out the trailing double quote.
+ If ARGPTR is just a simple name like "main", p will point to ""
+ at the end. */
static char *
locate_first_half (char **argptr, int *is_quote_enclosed)
@@ -1141,7 +1152,9 @@ decode_objc (char **argptr, int funfirstline, struct symtab *file_symtab,
}
/* This handles C++ and Java compound data structures. P should point
- at the first component separator, i.e. double-colon or period. */
+ at the first component separator, i.e. double-colon or period. As
+ an example, on entrance to this function we could have ARGPTR
+ pointing to "AAA::inA::fun" and P pointing to "::inA::fun". */
static struct symtabs_and_lines
decode_compound (char **argptr, int funfirstline, char ***canonical,
@@ -1149,9 +1162,6 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
{
struct symtabs_and_lines values;
char *p2;
-#if 0
- char *q, *q1;
-#endif
char *saved_arg2 = *argptr;
char *temp_end;
struct symbol *sym;
@@ -1162,100 +1172,52 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
struct symbol **sym_arr;
struct type *t;
- /* First check for "global" namespace specification,
- of the form "::foo". If found, skip over the colons
- and jump to normal symbol processing. */
+ /* First check for "global" namespace specification, of the form
+ "::foo". If found, skip over the colons and jump to normal
+ symbol processing. I.e. the whole line specification starts with
+ "::" (note the condition that *argptr == p). */
if (p[0] == ':'
&& ((*argptr == p) || (p[-1] == ' ') || (p[-1] == '\t')))
saved_arg2 += 2;
- /* We have what looks like a class or namespace
- scope specification (A::B), possibly with many
- levels of namespaces or classes (A::B::C::D).
-
- Some versions of the HP ANSI C++ compiler (as also possibly
- other compilers) generate class/function/member names with
- embedded double-colons if they are inside namespaces. To
- handle this, we loop a few times, considering larger and
- larger prefixes of the string as though they were single
- symbols. So, if the initially supplied string is
- A::B::C::D::foo, we have to look up "A", then "A::B",
- then "A::B::C", then "A::B::C::D", and finally
- "A::B::C::D::foo" as single, monolithic symbols, because
- A, B, C or D may be namespaces.
-
- Note that namespaces can nest only inside other
- namespaces, and not inside classes. So we need only
- consider *prefixes* of the string; there is no need to look up
- "B::C" separately as a symbol in the previous example. */
+ /* Given our example "AAA::inA::fun", we have two cases to consider:
- p2 = p; /* Save for restart. */
- while (1)
- {
- sym_class = lookup_prefix_sym (argptr, p);
+ 1) AAA::inA is the name of a class. In that case, presumably it
+ has a method called "fun"; we then look up that method using
+ find_method.
- if (sym_class &&
- (t = check_typedef (SYMBOL_TYPE (sym_class)),
- (TYPE_CODE (t) == TYPE_CODE_STRUCT
- || TYPE_CODE (t) == TYPE_CODE_UNION)))
- {
- /* Arg token is not digits => try it as a function name.
- Find the next token (everything up to end or next
- blank). */
- if (**argptr
- && strchr (get_gdb_completer_quote_characters (),
- **argptr) != NULL)
- {
- p = skip_quoted (*argptr);
- *argptr = *argptr + 1;
- }
- else
- {
- p = *argptr;
- while (*p && *p != ' ' && *p != '\t' && *p != ',' && *p != ':')
- p++;
- }
-/*
- q = operator_chars (*argptr, &q1);
- if (q1 - q)
- {
- char *opname;
- char *tmp = alloca (q1 - q + 1);
- memcpy (tmp, q, q1 - q);
- tmp[q1 - q] = '\0';
- opname = cplus_mangle_opname (tmp, DMGL_ANSI);
- if (opname == NULL)
- {
- cplusplus_error (saved_arg, "no mangling for \"%s\"\n", tmp);
- }
- copy = (char*) alloca (3 + strlen(opname));
- sprintf (copy, "__%s", opname);
- p = q1;
- }
- else
- */
- {
- copy = (char *) alloca (p - *argptr + 1);
- memcpy (copy, *argptr, p - *argptr);
- copy[p - *argptr] = '\0';
- if (p != *argptr
- && copy[p - *argptr - 1]
- && strchr (get_gdb_completer_quote_characters (),
- copy[p - *argptr - 1]) != NULL)
- copy[p - *argptr - 1] = '\0';
- }
+ 2) AAA::inA isn't the name of a class. In that case, either the
+ user made a typo or AAA::inA is the name of a namespace.
+ Either way, we just look up AAA::inA::fun with lookup_symbol.
- /* No line number may be specified. */
- while (*p == ' ' || *p == '\t')
- p++;
- *argptr = p;
+ Thus, our first task is to find everything before the last set of
+ double-colons and figure out if it's the name of a class. So we
+ first loop through all of the double-colons. */
- return find_method (funfirstline, canonical, saved_arg,
- copy, t, sym_class);
- }
+ p2 = p; /* Save for restart. */
+
+ /* This is very messy. Following the example above we have now the
+ following pointers:
+ p -> "::inA::fun"
+ argptr -> "AAA::inA::fun
+ saved_arg -> "AAA::inA::fun
+ saved_arg2 -> "AAA::inA::fun
+ p2 -> "::inA::fun". */
+
+ /* In the loop below, with these strings, we'll make 2 passes, each
+ is marked in comments.*/
+ while (1)
+ {
/* Move pointer up to next possible class/namespace token. */
+
p = p2 + 1; /* Restart with old value +1. */
+
+ /* PASS1: at this point p2->"::inA::fun", so p->":inA::fun",
+ i.e. if there is a double-colon, p will now point to the
+ second colon. */
+ /* PASS2: p2->"::fun", p->":fun" */
+
/* Move pointer ahead to next double-colon. */
while (*p && (p[0] != ' ') && (p[0] != '\t') && (p[0] != '\''))
{
@@ -1266,22 +1228,113 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
error ("malformed template specification in command");
p = temp_end;
}
+ /* Note that, since, at the start of this loop, p would be
+ pointing to the second colon in a double-colon, we only
+ satisfy the condition below if there is another
+ double-colon to the right (after). I.e. there is another
+ component that can be a class or a namespace. I.e, if at
+ the beginning of this loop (PASS1), we had
+ p->":inA::fun", we'll trigger this when p has been
+ advanced to point to "::fun". */
+ /* PASS2: we will not trigger this. */
else if ((p[0] == ':') && (p[1] == ':'))
break; /* Found double-colon. */
else
+ /* PASS2: We'll keep getting here, until p->"", at which point
+ we exit this loop. */
p++;
}
if (*p != ':')
- break; /* Out of the while (1). */
-
- p2 = p; /* Save restart for next time around. */
- *argptr = saved_arg2; /* Restore argptr. */
+ break; /* Out of the while (1). This would happen
+ for instance if we have looked up
+ unsuccessfully all the components of the
+ string, and p->""(PASS2) */
+
+ /* We get here if p points to ' ', '\t', '\'', "::" or ""(i.e
+ string ended). */
+ /* Save restart for next time around. */
+ p2 = p;
+ /* Restore argptr as it was on entry to this function. */
+ *argptr = saved_arg2;
+ /* PASS1: at this point p->"::fun" argptr->"AAA::inA::fun",
+ p2->"::fun". */
+
+ /* All ready for next pass through the loop. */
} /* while (1) */
- /* Last chance attempt -- check entire name as a symbol. Use "copy"
- in preparation for jumping out of this block, to be consistent
- with usage following the jump target. */
+
+ /* Start of lookup in the symbol tables. */
+
+ /* Lookup in the symbol table the substring between argptr and
+ p. Note, this call changes the value of argptr. */
+ /* Before the call, argptr->"AAA::inA::fun",
+ p->"", p2->"::fun". After the call: argptr->"fun", p, p2
+ unchanged. */
+ sym_class = lookup_prefix_sym (argptr, p2);
+
+ /* If sym_class has been found, and if "AAA::inA" is a class, then
+ we're in case 1 above. So we look up "fun" as a method of that
+ class. */
+ if (sym_class &&
+ (t = check_typedef (SYMBOL_TYPE (sym_class)),
+ (TYPE_CODE (t) == TYPE_CODE_STRUCT
+ || TYPE_CODE (t) == TYPE_CODE_UNION)))
+ {
+ /* Arg token is not digits => try it as a function name.
+ Find the next token (everything up to end or next
+ blank). */
+ if (**argptr
+ && strchr (get_gdb_completer_quote_characters (),
+ **argptr) != NULL)
+ {
+ p = skip_quoted (*argptr);
+ *argptr = *argptr + 1;
+ }
+ else
+ {
+ /* At this point argptr->"fun". */
+ p = *argptr;
+ while (*p && *p != ' ' && *p != '\t' && *p != ',' && *p != ':')
+ p++;
+ /* At this point p->"". String ended. */
+ }
+
+ /* Allocate our own copy of the substring between argptr and
+ p. */
+ copy = (char *) alloca (p - *argptr + 1);
+ memcpy (copy, *argptr, p - *argptr);
+ copy[p - *argptr] = '\0';
+ if (p != *argptr
+ && copy[p - *argptr - 1]
+ && strchr (get_gdb_completer_quote_characters (),
+ copy[p - *argptr - 1]) != NULL)
+ copy[p - *argptr - 1] = '\0';
+
+ /* At this point copy->"fun", p->"" */
+
+ /* No line number may be specified. */
+ while (*p == ' ' || *p == '\t')
+ p++;
+ *argptr = p;
+ /* At this point arptr->"". */
+
+ /* Look for copy as a method of sym_class. */
+ /* At this point copy->"fun", sym_class is "AAA:inA",
+ saved_arg->"AAA::inA::fun". This concludes the scanning of
+ the string for possible components matches. If we find it
+ here, we return. If not, and we are at the and of the string,
+ we'll lookup the whole string in the symbol tables. */
+
+ return find_method (funfirstline, canonical, saved_arg,
+ copy, t, sym_class);
+
+ } /* End if symbol found */
+
+
+ /* We couldn't find a class, so we're in case 2 above. We check the
+ entire name as a symbol instead. */
+
copy = (char *) alloca (p - saved_arg2 + 1);
memcpy (copy, saved_arg2, p - saved_arg2);
/* Note: if is_quoted should be true, we snuff out quote here
@@ -1289,6 +1342,7 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
copy[p - saved_arg2] = '\000';
/* Set argptr to skip over the name. */
*argptr = (*p == '\'') ? p + 1 : p;
+
/* Look up entire name */
sym = lookup_symbol (copy, 0, VAR_DOMAIN, 0, &sym_symtab);
if (sym)
@@ -1307,7 +1361,9 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
/* Return the symbol corresponding to the substring of *ARGPTR ending
at P, allowing whitespace. Also, advance *ARGPTR past the symbol
name in question, the compound object separator ("::" or "."), and
- whitespace. */
+ whitespace. Note that *ARGPTR is changed whether or not the
+ lookup_symbol call finds anything (i.e we return NULL). As an
+ example, say ARGPTR is "AAA::inA::fun" and P is "::inA::fun". */
static struct symbol *
lookup_prefix_sym (char **argptr, char *p)
@@ -1323,12 +1379,15 @@ lookup_prefix_sym (char **argptr, char *p)
memcpy (copy, *argptr, p - *argptr);
copy[p - *argptr] = 0;
- /* Discard the class name from the arg. */
+ /* Discard the class name from the argptr. */
p = p1 + (p1[0] == ':' ? 2 : 1);
while (*p == ' ' || *p == '\t')
p++;
*argptr = p;
+ /* At this point p1->"::inA::fun", p->"inA::fun" copy->"AAA",
+ argptr->"inA::fun" */
+
return lookup_symbol (copy, 0, STRUCT_DOMAIN, 0,
(struct symtab **) NULL);
}