X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Flinespec.c;h=ec4d569a75c22ed5eb0737898c9bb5ba83e5c26e;hb=94af9270db6b89f9a3a1f72e8f5091fee8b0294b;hp=4950d373cb08077f4f094497f32048d11d2e1430;hpb=53c5240fe15861d08db96684b1a06c4b4ecb1958;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/linespec.c b/gdb/linespec.c index 4950d373cb..ec4d569a75 100644 --- a/gdb/linespec.c +++ b/gdb/linespec.c @@ -1,14 +1,14 @@ /* Parser for linespec for the GNU debugger, GDB. Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, - 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007 - Free Software Foundation, Inc. + 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, + 2009, 2010 Free Software Foundation, Inc. This file is part of GDB. 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 2 of the License, or + 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, @@ -17,9 +17,7 @@ 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, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + along with this program. If not, see . */ #include "defs.h" #include "symtab.h" @@ -32,12 +30,17 @@ #include "value.h" #include "completer.h" #include "cp-abi.h" +#include "cp-support.h" #include "parser-defs.h" #include "block.h" #include "objc-lang.h" #include "linespec.h" #include "exceptions.h" #include "language.h" +#include "interps.h" +#include "mi/mi-cmds.h" +#include "target.h" +#include "arch-utils.h" /* We share this one with symtab.c, but it is not exported widely. */ @@ -48,8 +51,6 @@ extern char *operator_chars (char *, char **); static void initialize_defaults (struct symtab **default_symtab, int *default_line); -static void set_flags (char *arg, int *is_quoted, char **paren_pointer); - static struct symtabs_and_lines decode_indirect (char **argptr); static char *locate_first_half (char **argptr, int *is_quote_enclosed); @@ -64,7 +65,8 @@ static struct symtabs_and_lines decode_compound (char **argptr, int funfirstline, char ***canonical, char *saved_arg, - char *p); + char *p, + int *not_found_ptr); static struct symbol *lookup_prefix_sym (char **argptr, char *p); @@ -73,11 +75,8 @@ static struct symtabs_and_lines find_method (int funfirstline, char *saved_arg, char *copy, struct type *t, - struct symbol *sym_class); - -static int collect_methods (char *copy, struct type *t, - struct symbol *sym_class, - struct symbol **sym_arr); + struct symbol *sym_class, + int *not_found_ptr); static NORETURN void cplusplus_error (const char *name, const char *fmt, ...) @@ -135,8 +134,7 @@ symtabs_and_lines symbol_found (int funfirstline, char ***canonical, char *copy, struct symbol *sym, - struct symtab *file_symtab, - struct symtab *sym_symtab); + struct symtab *file_symtab); static struct symtabs_and_lines minsym_found (int funfirstline, @@ -152,6 +150,7 @@ static NORETURN void cplusplus_error (const char *name, const char *fmt, ...) { struct ui_file *tmp_stream; + char *message; tmp_stream = mem_fileopen (); make_cleanup_ui_file_delete (tmp_stream); @@ -168,7 +167,10 @@ cplusplus_error (const char *name, const char *fmt, ...) ("Hint: try '%s or '%s\n" "(Note leading single quote.)"), name, name); - error_stream (tmp_stream); + + message = ui_file_xstrdup (tmp_stream, NULL); + make_cleanup (xfree, message); + throw_error (NOT_FOUND_ERROR, "%s", message); } /* Return the number of methods described for TYPE, including the @@ -183,7 +185,7 @@ total_number_of_methods (struct type *type) int count; CHECK_TYPEDEF (type); - if (TYPE_CPLUS_SPECIFIC (type) == NULL) + if (! HAVE_CPLUS_STRUCT (type)) return 0; count = TYPE_NFN_FIELDS_TOTAL (type); @@ -213,8 +215,7 @@ find_methods (struct type *t, char *name, enum language language, the class, then the loop can't do any good. */ if (class_name && (lookup_symbol_in_language (class_name, (struct block *) NULL, - STRUCT_DOMAIN, language, (int *) NULL, - (struct symtab **) NULL))) + STRUCT_DOMAIN, language, (int *) NULL))) { int method_counter; int name_len = strlen (name); @@ -307,16 +308,10 @@ add_matching_methods (int method_counter, struct type *t, else phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter); - /* Destructor is handled by caller, don't add it to - the list. */ - if (is_destructor_name (phys_name) != 0) - continue; - sym_arr[i1] = lookup_symbol_in_language (phys_name, NULL, VAR_DOMAIN, language, - (int *) NULL, - (struct symtab **) NULL); + (int *) NULL); if (sym_arr[i1]) i1++; else @@ -373,8 +368,7 @@ add_constructors (int method_counter, struct type *t, sym_arr[i1] = lookup_symbol_in_language (phys_name, NULL, VAR_DOMAIN, language, - (int *) NULL, - (struct symtab **) NULL); + (int *) NULL); if (sym_arr[i1]) i1++; } @@ -493,7 +487,13 @@ decode_line_2 (struct symbol *sym_arr[], int nelts, int funfirstline, char *symname; struct cleanup *old_chain; char **canonical_arr = (char **) NULL; + const char *select_mode = multiple_symbols_select_mode (); + if (select_mode == multiple_symbols_cancel) + error (_("\ +canceled because the command is ambiguous\n\ +See set/show multiple-symbol.")); + values.sals = (struct symtab_and_line *) alloca (nelts * sizeof (struct symtab_and_line)); return_values.sals = (struct symtab_and_line *) @@ -509,38 +509,53 @@ decode_line_2 (struct symbol *sym_arr[], int nelts, int funfirstline, } i = 0; - printf_unfiltered (_("[0] cancel\n[1] all\n")); while (i < nelts) { init_sal (&return_values.sals[i]); /* Initialize to zeroes. */ init_sal (&values.sals[i]); if (sym_arr[i] && SYMBOL_CLASS (sym_arr[i]) == LOC_BLOCK) - { - values.sals[i] = find_function_start_sal (sym_arr[i], funfirstline); - if (values.sals[i].symtab) - printf_unfiltered ("[%d] %s at %s:%d\n", - (i + 2), - SYMBOL_PRINT_NAME (sym_arr[i]), - values.sals[i].symtab->filename, - values.sals[i].line); - else - printf_unfiltered (_("[%d] %s at ?FILE:%d [No symtab? Probably broken debug info...]\n"), - (i + 2), - SYMBOL_PRINT_NAME (sym_arr[i]), - values.sals[i].line); - - } - else - printf_unfiltered (_("?HERE\n")); + values.sals[i] = find_function_start_sal (sym_arr[i], funfirstline); i++; } - prompt = getenv ("PS2"); - if (prompt == NULL) + /* If select_mode is "all", then do not print the multiple-choice + menu and act as if the user had chosen choice "1" (all). */ + if (select_mode == multiple_symbols_all + || ui_out_is_mi_like_p (interp_ui_out (top_level_interpreter ()))) + args = "1"; + else { - prompt = "> "; + i = 0; + printf_unfiltered (_("[0] cancel\n[1] all\n")); + while (i < nelts) + { + if (sym_arr[i] && SYMBOL_CLASS (sym_arr[i]) == LOC_BLOCK) + { + if (values.sals[i].symtab) + printf_unfiltered ("[%d] %s at %s:%d\n", + (i + 2), + SYMBOL_PRINT_NAME (sym_arr[i]), + values.sals[i].symtab->filename, + values.sals[i].line); + else + printf_unfiltered (_("[%d] %s at ?FILE:%d [No symtab? Probably broken debug info...]\n"), + (i + 2), + SYMBOL_PRINT_NAME (sym_arr[i]), + values.sals[i].line); + + } + else + printf_unfiltered (_("?HERE\n")); + i++; + } + + prompt = getenv ("PS2"); + if (prompt == NULL) + { + prompt = "> "; + } + args = command_line_input (prompt, 0, "overload-choice"); } - args = command_line_input (prompt, 0, "overload-choice"); if (args == 0 || *args == 0) error_no_arg (_("one or more choice numbers")); @@ -568,8 +583,8 @@ decode_line_2 (struct symbol *sym_arr[], int nelts, int funfirstline, { if (canonical_arr[i] == NULL) { - symname = DEPRECATED_SYMBOL_NAME (sym_arr[i]); - canonical_arr[i] = savestring (symname, strlen (symname)); + symname = SYMBOL_LINKAGE_NAME (sym_arr[i]); + canonical_arr[i] = xstrdup (symname); } } } @@ -591,9 +606,9 @@ decode_line_2 (struct symbol *sym_arr[], int nelts, int funfirstline, { if (canonical_arr) { - symname = DEPRECATED_SYMBOL_NAME (sym_arr[num]); + symname = SYMBOL_LINKAGE_NAME (sym_arr[num]); make_cleanup (xfree, symname); - canonical_arr[i] = savestring (symname, strlen (symname)); + canonical_arr[i] = xstrdup (symname); } return_values.sals[i++] = values.sals[num]; values.sals[num].pc = 0; @@ -612,6 +627,37 @@ decode_line_2 (struct symbol *sym_arr[], int nelts, int funfirstline, discard_cleanups (old_chain); return return_values; } + +/* A helper function for decode_line_1 and friends which skips P + past any method overload information at the beginning of P, e.g., + "(const struct foo *)". + + This function assumes that P has already been validated to contain + overload information, and it will assert if *P != '('. */ +static char * +find_method_overload_end (char *p) +{ + int depth = 0; + + gdb_assert (*p == '('); + + while (*p) + { + if (*p == '(') + ++depth; + else if (*p == ')') + { + if (--depth == 0) + { + ++p; + break; + } + } + ++p; + } + + return p; +} /* The parser of linespec itself. */ @@ -672,16 +718,17 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab, struct symtab *file_symtab = NULL; char *copy; - /* This is NULL if there are no parens in *ARGPTR, or a pointer to - the closing parenthesis if there are parens. */ - char *paren_pointer; /* This says whether or not something in *ARGPTR is quoted with completer_quotes (i.e. with single quotes). */ int is_quoted; - /* Is part of *ARGPTR is enclosed in double quotes? */ + /* Is *ARGPTR is enclosed in double quotes? */ int is_quote_enclosed; int is_objc_method = 0; char *saved_arg = *argptr; + /* If IS_QUOTED, the end of the quoted bit. */ + char *end_quote = NULL; + /* The "first half" of the linespec. */ + char *first_half; if (not_found_ptr) *not_found_ptr = 0; @@ -695,12 +742,11 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab, if (**argptr == '*') return decode_indirect (argptr); - /* Set various flags. 'paren_pointer' is important for overload - checking, where we allow things like: - (gdb) break c::f(int) - */ - - set_flags (*argptr, &is_quoted, &paren_pointer); + is_quoted = (*argptr + && strchr (get_gdb_completer_quote_characters (), + **argptr) != NULL); + if (is_quoted) + end_quote = skip_quoted (*argptr); /* Check to see if it's a multipart linespec (with colons or periods). */ @@ -711,15 +757,12 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab, 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); + first_half = p = locate_first_half (argptr, &is_quote_enclosed); /* Check if this is an Objective-C method (anything that starts with a '+' or '-' and a '['). */ if (is_objc_method_format (p)) - { - is_objc_method = 1; - paren_pointer = NULL; /* Just a category name. Ignore it. */ - } + is_objc_method = 1; /* Check if the symbol could be an Objective-C selector. */ @@ -733,11 +776,8 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab, /* Does it look like there actually were two parts? */ - if ((p[0] == ':' || p[0] == '.') && paren_pointer == NULL) + if (p[0] == ':' || p[0] == '.') { - if (is_quoted) - *argptr = *argptr + 1; - /* 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. @@ -746,53 +786,49 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab, can return now. */ if (p[0] == '.' || p[1] == ':') - return decode_compound (argptr, funfirstline, canonical, - saved_arg, p); + { + struct symtabs_and_lines values; + + if (is_quote_enclosed) + ++saved_arg; + values = decode_compound (argptr, funfirstline, canonical, + saved_arg, p, not_found_ptr); + if (is_quoted && **argptr == '\'') + *argptr = *argptr + 1; + return values; + } - /* No, the first part is a filename; set s to be that file's + /* No, the first part is a filename; set file_symtab to be that file's symtab. Also, move argptr past the filename. */ - file_symtab = symtab_from_filename (argptr, p, is_quote_enclosed, - not_found_ptr); - } -#if 0 - /* No one really seems to know why this was added. It certainly - breaks the command line, though, whenever the passed - name is of the form ClassName::Method. This bit of code - singles out the class name, and if funfirstline is set (for - example, you are setting a breakpoint at this function), - you get an error. This did not occur with earlier - verions, so I am ifdef'ing this out. 3/29/99 */ - else - { - /* Check if what we have till now is a symbol name */ - - /* We may be looking at a template instantiation such - as "foo". Check here whether we know about it, - instead of falling through to the code below which - handles ordinary function names, because that code - doesn't like seeing '<' and '>' in a name -- the - skip_quoted call doesn't go past them. So see if we - can figure it out right now. */ + file_symtab = symtab_from_filename (argptr, p, is_quote_enclosed, + not_found_ptr); - copy = (char *) alloca (p - *argptr + 1); - memcpy (copy, *argptr, p - *argptr); - copy[p - *argptr] = '\000'; - sym = lookup_symbol (copy, 0, VAR_DOMAIN, 0, &sym_symtab); - if (sym) + /* Check for single quotes on the non-filename part. */ + if (!is_quoted) { - *argptr = (*p == '\'') ? p + 1 : p; - return symbol_found (funfirstline, canonical, copy, sym, - NULL, sym_symtab); + is_quoted = (**argptr + && strchr (get_gdb_completer_quote_characters (), + **argptr) != NULL); + if (is_quoted) + end_quote = skip_quoted (*argptr); } - /* Otherwise fall out from here and go to file/line spec - processing, etc. */ } -#endif - /* S is specified file's symtab, or 0 if no file specified. + /* file_symtab is specified file's symtab, or 0 if no file specified. arg no longer contains the file name. */ + /* If the filename was quoted, we must re-check the quotation. */ + + if (end_quote == first_half && *end_quote!= '\0') + { + is_quoted = (**argptr + && strchr (get_gdb_completer_quote_characters (), + **argptr) != NULL); + if (is_quoted) + end_quote = skip_quoted (*argptr); + } + /* Check whether arg is all digits (and sign). */ q = *argptr; @@ -814,7 +850,7 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab, p = skip_quoted (*argptr + (((*argptr)[1] == '$') ? 2 : 1)); else if (is_quoted) { - p = skip_quoted (*argptr); + p = end_quote; if (p[-1] != '\'') error (_("Unmatched single quote.")); } @@ -823,15 +859,23 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab, /* allow word separators in method names for Obj-C */ p = skip_quoted_chars (*argptr, NULL, ""); } - else if (paren_pointer != NULL) - { - p = paren_pointer + 1; - } else { p = skip_quoted (*argptr); } + /* Keep any template parameters */ + if (*p == '<') + p = find_template_name_end (p); + + /* Keep method overload information. */ + if (*p == '(') + p = find_method_overload_end (p); + + /* Make sure we keep important kewords like "const" */ + if (strncmp (p, " const", 6) == 0) + p += 6; + copy = (char *) alloca (p - *argptr + 1); memcpy (copy, *argptr, p - *argptr); copy[p - *argptr] = '\0'; @@ -843,6 +887,8 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab, copy[p - *argptr - 1] = '\0'; copy++; } + else if (is_quoted) + copy[p - *argptr - 1] = '\0'; while (*p == ' ' || *p == '\t') p++; *argptr = p; @@ -877,10 +923,9 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab, function is passed ARGPTR as an argument, it modifies what ARGPTR points to; typically, it advances *ARGPTR past whatever substring it has just looked at. (If it doesn't modify *ARGPTR, then the - function gets passed *ARGPTR instead, which is then called ARG: see - set_flags, for example.) Also, functions that return a struct - symtabs_and_lines may modify CANONICAL, as in the description of - decode_line_1. + function gets passed *ARGPTR instead, which is then called ARG.) + Also, functions that return a struct symtabs_and_lines may modify + CANONICAL, as in the description of decode_line_1. If a function returns a struct symtabs_and_lines, then that struct will immediately make its way up the call chain to be returned by @@ -907,44 +952,6 @@ initialize_defaults (struct symtab **default_symtab, int *default_line) } } -static void -set_flags (char *arg, int *is_quoted, char **paren_pointer) -{ - char *ii; - int has_if = 0; - - /* 'has_if' is for the syntax: - (gdb) break foo if (a==b) - */ - if ((ii = strstr (arg, " if ")) != NULL || - (ii = strstr (arg, "\tif ")) != NULL || - (ii = strstr (arg, " if\t")) != NULL || - (ii = strstr (arg, "\tif\t")) != NULL || - (ii = strstr (arg, " if(")) != NULL || - (ii = strstr (arg, "\tif( ")) != NULL) - has_if = 1; - /* Temporarily zap out "if (condition)" to not confuse the - parenthesis-checking code below. This is undone below. Do not - change ii!! */ - if (has_if) - { - *ii = '\0'; - } - - *is_quoted = (*arg - && strchr (get_gdb_completer_quote_characters (), - *arg) != NULL); - - *paren_pointer = strchr (arg, '('); - if (*paren_pointer != NULL) - *paren_pointer = strrchr (*paren_pointer, ')'); - - /* Now that we're safely past the paren_pointer check, put back " if - (condition)" so outer layers can see it. */ - if (has_if) - *ii = ' '; -} - /* Decode arg of the form *PC. */ @@ -965,6 +972,7 @@ decode_indirect (char **argptr) values.sals[0] = find_pc_line (pc, 0); values.sals[0].pc = pc; values.sals[0].section = find_pc_overlay (pc); + values.sals[0].explicit_pc = 1; return values; } @@ -1014,7 +1022,14 @@ locate_first_half (char **argptr, int *is_quote_enclosed) p++; } else - *is_quote_enclosed = 0; + { + *is_quote_enclosed = 0; + if (strchr (get_gdb_completer_quote_characters (), *p)) + { + ++(*argptr); + ++p; + } + } for (; *p; p++) { if (p[0] == '<') @@ -1043,8 +1058,9 @@ locate_first_half (char **argptr, int *is_quote_enclosed) if (p[0] == '.' && strchr (p, ':') == NULL) { /* Java qualified method. Find the *last* '.', since the - others are package qualifiers. */ - for (p1 = p; *p1; p1++) + others are package qualifiers. Stop at any open parenthesis + which might provide overload information. */ + for (p1 = p; *p1 && *p1 != '('; p1++) { if (*p1 == '.') p = p1; @@ -1098,14 +1114,22 @@ decode_objc (char **argptr, int funfirstline, struct symtab *file_symtab, if (file_symtab != NULL) block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (file_symtab), STATIC_BLOCK); else - block = get_selected_block (0); - + { + enum language save_language; + + /* get_selected_block can change the current language when there is + no selected frame yet. */ + save_language = current_language->la_language; + block = get_selected_block (0); + set_language (save_language); + } + copy = find_imps (file_symtab, block, *argptr, NULL, &i1, &i2); if (i1 > 0) { sym_arr = (struct symbol **) alloca ((i1 + 1) * sizeof (struct symbol *)); - sym_arr[i1] = 0; + sym_arr[i1] = NULL; copy = find_imps (file_symtab, block, *argptr, sym_arr, &i1, &i2); *argptr = copy; @@ -1144,11 +1168,19 @@ decode_objc (char **argptr, int funfirstline, struct symtab *file_symtab, } else { - /* The only match was a non-debuggable symbol. */ - values.sals[0].symtab = 0; - values.sals[0].line = 0; - values.sals[0].end = 0; - values.sals[0].pc = SYMBOL_VALUE_ADDRESS (sym_arr[0]); + /* The only match was a non-debuggable symbol, which might point + to a function descriptor; resolve it to the actual code address + instead. */ + struct minimal_symbol *msymbol = (struct minimal_symbol *)sym_arr[0]; + struct objfile *objfile = msymbol_objfile (msymbol); + struct gdbarch *gdbarch = get_objfile_arch (objfile); + CORE_ADDR pc = SYMBOL_VALUE_ADDRESS (msymbol); + + pc = gdbarch_convert_from_func_ptr_addr (gdbarch, pc, + ¤t_target); + + init_sal (&values.sals[0]); + values.sals[0].pc = pc; } return values; } @@ -1169,19 +1201,18 @@ decode_objc (char **argptr, int funfirstline, struct symtab *file_symtab, static struct symtabs_and_lines decode_compound (char **argptr, int funfirstline, char ***canonical, - char *saved_arg, char *p) + char *saved_arg, char *p, int *not_found_ptr) { struct symtabs_and_lines values; char *p2; char *saved_arg2 = *argptr; char *temp_end; struct symbol *sym; - /* The symtab that SYM was found in. */ - struct symtab *sym_symtab; char *copy; struct symbol *sym_class; struct symbol **sym_arr; struct type *t; + char *saved_java_argptr = NULL; /* First check for "global" namespace specification, of the form "::foo". If found, skip over the colons and jump to normal @@ -1230,8 +1261,12 @@ decode_compound (char **argptr, int funfirstline, char ***canonical, /* PASS2: p2->"::fun", p->":fun" */ /* Move pointer ahead to next double-colon. */ - while (*p && (p[0] != ' ') && (p[0] != '\t') && (p[0] != '\'')) + while (*p && (p[0] != ' ') && (p[0] != '\t') && (p[0] != '\'') + && (*p != '(')) { + if (current_language->la_language == language_cplus) + p += cp_validate_operator (p); + if (p[0] == '<') { temp_end = find_template_name_end (p); @@ -1305,10 +1340,57 @@ decode_compound (char **argptr, int funfirstline, char ***canonical, else { /* At this point argptr->"fun". */ + char *a; p = *argptr; - while (*p && *p != ' ' && *p != '\t' && *p != ',' && *p != ':') + while (*p && *p != ' ' && *p != '\t' && *p != ',' && *p != ':' + && *p != '(') p++; /* At this point p->"". String ended. */ + /* Nope, C++ operators could have spaces in them + ("foo::operator <" or "foo::operator delete []"). + I apologize, this is a bit hacky... */ + if (current_language->la_language == language_cplus + && *p == ' ' && p - 8 - *argptr + 1 > 0) + { + /* The above loop has already swallowed "operator". */ + p += cp_validate_operator (p - 8) - 8; + } + + /* Keep any template parameters */ + if (*p == '<') + p = find_template_name_end (p); + + /* Keep method overload information. */ + a = strchr (p, '('); + if (a != NULL) + p = find_method_overload_end (a); + + /* Make sure we keep important kewords like "const" */ + if (strncmp (p, " const", 6) == 0) + p += 6; + + /* Java may append typenames, so assume that if there is + anything else left in *argptr, it must be a typename. */ + if (*p && current_language->la_language == language_java) + { + struct type *type; + p2 = p; + while (*p2) + ++p2; + copy = (char *) alloca (p2 - p + 1); + memcpy (copy, p, p2 - p); + copy[p2 - p] = '\0'; + type = lookup_typename (current_language, get_current_arch (), + copy, NULL, 1); + if (type != NULL) + { + /* Save the location of this just in case this + method/type combination isn't actually defined. + It will be checked later. */ + saved_java_argptr = p; + p = p2; + } + } } /* Allocate our own copy of the substring between argptr and @@ -1337,9 +1419,26 @@ decode_compound (char **argptr, int funfirstline, char ***canonical, 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); - + values = find_method (funfirstline, canonical, saved_arg, + copy, t, sym_class, not_found_ptr); + if (saved_java_argptr != NULL && values.nelts == 1) + { + /* The user specified a specific return type for a java method. + Double-check that it really is the one the user specified. + [This is a necessary evil because strcmp_iw_ordered stops + comparisons too prematurely.] */ + sym = find_pc_sect_function (values.sals[0].pc, + values.sals[0].section); + /* We just found a SAL, we had better be able to go backwards! */ + gdb_assert (sym != NULL); + if (strcmp_iw (SYMBOL_LINKAGE_NAME (sym), saved_arg) != 0) + { + xfree (values.sals); + error (_("the class `%s' does not have any method instance named %s\n"), + SYMBOL_PRINT_NAME (sym_class), copy); + } + } + return values; } /* End if symbol found */ @@ -1355,13 +1454,14 @@ decode_compound (char **argptr, int funfirstline, char ***canonical, *argptr = (*p == '\'') ? p + 1 : p; /* Look up entire name */ - sym = lookup_symbol (copy, 0, VAR_DOMAIN, 0, &sym_symtab); + sym = lookup_symbol (copy, 0, VAR_DOMAIN, 0); if (sym) - return symbol_found (funfirstline, canonical, copy, sym, - NULL, sym_symtab); + return symbol_found (funfirstline, canonical, copy, sym, NULL); /* Couldn't find any interpretation as classes/namespaces, so give up. The quotes are important if copy is empty. */ + if (not_found_ptr) + *not_found_ptr = 1; cplusplus_error (saved_arg, "Can't find member of namespace, class, struct, or union named \"%s\"\n", copy); @@ -1381,6 +1481,7 @@ lookup_prefix_sym (char **argptr, char *p) { char *p1; char *copy; + struct symbol *sym; /* Extract the class name. */ p1 = p; @@ -1399,8 +1500,26 @@ lookup_prefix_sym (char **argptr, char *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); + sym = lookup_symbol (copy, 0, STRUCT_DOMAIN, 0); + if (sym == NULL) + { + /* Typedefs are in VAR_DOMAIN so the above symbol lookup will + fail when the user attempts to lookup a method of a class + via a typedef'd name (NOT via the class's name, which is already + handled in symbol_matches_domain). So try the lookup again + using VAR_DOMAIN (where typedefs live) and double-check that we + found a struct/class type. */ + struct symbol *s = lookup_symbol (copy, 0, VAR_DOMAIN, 0); + if (s != NULL) + { + struct type *t = SYMBOL_TYPE (s); + CHECK_TYPEDEF (t); + if (TYPE_CODE (t) == TYPE_CODE_STRUCT) + return s; + } + } + + return sym; } /* This finds the method COPY in the class whose type is T and whose @@ -1408,10 +1527,10 @@ lookup_prefix_sym (char **argptr, char *p) static struct symtabs_and_lines find_method (int funfirstline, char ***canonical, char *saved_arg, - char *copy, struct type *t, struct symbol *sym_class) + char *copy, struct type *t, struct symbol *sym_class, int *not_found_ptr) { struct symtabs_and_lines values; - struct symbol *sym = 0; + struct symbol *sym = NULL; int i1; /* Counter for the symbol array. */ struct symbol **sym_arr = alloca (total_number_of_methods (t) * sizeof (struct symbol *)); @@ -1419,7 +1538,7 @@ find_method (int funfirstline, char ***canonical, char *saved_arg, /* Find all methods with a matching name, and put them in sym_arr. */ - i1 = collect_methods (copy, t, sym_class, sym_arr); + i1 = find_methods (t, copy, SYMBOL_LANGUAGE (sym_class), sym_arr); if (i1 == 1) { @@ -1443,63 +1562,54 @@ find_method (int funfirstline, char ***canonical, char *saved_arg, } if (i1 > 0) { - /* There is more than one field with that name - (overloaded). Ask the user which one to use. */ + /* If we were given a specific overload instance, use that + (or error if no matches were found). Otherwise ask the user + which one to use. */ + if (strchr (saved_arg, '(') != NULL) + { + int i; + for (i = 0; i < i1; ++i) + { + char *name = saved_arg; + char *canon = cp_canonicalize_string (name); + if (canon != NULL) + name = canon; + + if (strcmp_iw (name, SYMBOL_LINKAGE_NAME (sym_arr[i])) == 0) + { + values.sals = (struct symtab_and_line *) + xmalloc (sizeof (struct symtab_and_line)); + values.nelts = 1; + values.sals[0] = find_function_start_sal (sym_arr[i], + funfirstline); + if (canon) + xfree (canon); + return values; + } + + if (canon) + xfree (canon); + } + + error (_("the class `%s' does not have any method instance named %s\n"), + SYMBOL_PRINT_NAME (sym_class), copy); + } + return decode_line_2 (sym_arr, i1, funfirstline, canonical); } else { - char *tmp; - - if (is_operator_name (copy)) - { - tmp = (char *) alloca (strlen (copy + 3) + 9); - strcpy (tmp, "operator "); - strcat (tmp, copy + 3); - } - else - tmp = copy; - if (tmp[0] == '~') + if (not_found_ptr) + *not_found_ptr = 1; + if (copy[0] == '~') cplusplus_error (saved_arg, "the class `%s' does not have destructor defined\n", SYMBOL_PRINT_NAME (sym_class)); else cplusplus_error (saved_arg, "the class %s does not have any method named %s\n", - SYMBOL_PRINT_NAME (sym_class), tmp); - } -} - -/* Find all methods named COPY in the class whose type is T, and put - them in SYM_ARR. Return the number of methods found. */ - -static int -collect_methods (char *copy, struct type *t, - struct symbol *sym_class, struct symbol **sym_arr) -{ - int i1 = 0; /* Counter for the symbol array. */ - - if (destructor_name_p (copy, t)) - { - /* Destructors are a special case. */ - int m_index, f_index; - - if (get_destructor_fn_field (t, &m_index, &f_index)) - { - struct fn_field *f = TYPE_FN_FIELDLIST1 (t, m_index); - - sym_arr[i1] = - lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, f_index), - NULL, VAR_DOMAIN, (int *) NULL, - (struct symtab **) NULL); - if (sym_arr[i1]) - i1++; - } + SYMBOL_PRINT_NAME (sym_class), copy); } - else - i1 = find_methods (t, copy, SYMBOL_LANGUAGE (sym_class), sym_arr); - - return i1; } @@ -1526,7 +1636,8 @@ symtab_from_filename (char **argptr, char *p, int is_quote_enclosed, copy = (char *) alloca (p - *argptr + 1); memcpy (copy, *argptr, p - *argptr); /* It may have the ending quote right after the file name. */ - if (is_quote_enclosed && copy[p - *argptr - 1] == '"') + if ((is_quote_enclosed && copy[p - *argptr - 1] == '"') + || copy[p - *argptr - 1] == '\'') copy[p - *argptr - 1] = 0; else copy[p - *argptr] = 0; @@ -1535,10 +1646,11 @@ symtab_from_filename (char **argptr, char *p, int is_quote_enclosed, file_symtab = lookup_symtab (copy); if (file_symtab == 0) { - if (!have_full_symbols () && !have_partial_symbols ()) - error (_("No symbol table is loaded. Use the \"file\" command.")); if (not_found_ptr) *not_found_ptr = 1; + if (!have_full_symbols () && !have_partial_symbols ()) + throw_error (NOT_FOUND_ERROR, + _("No symbol table is loaded. Use the \"file\" command.")); throw_error (NOT_FOUND_ERROR, _("No source file named %s."), copy); } @@ -1573,10 +1685,12 @@ decode_all_digits (char **argptr, struct symtab *default_symtab, sign = none; /* We might need a canonical line spec if no file was specified. */ - int need_canonical = (file_symtab == 0) ? 1 : 0; + int need_canonical = (file_symtab == NULL) ? 1 : 0; init_sal (&val); + val.pspace = current_program_space; + /* This is where we need to make sure that we have good defaults. We must guarantee that this section of code is never executed when we are called with just a function name, since @@ -1628,6 +1742,7 @@ decode_all_digits (char **argptr, struct symtab *default_symtab, if (val.symtab == 0) val.symtab = file_symtab; + val.pspace = SYMTAB_PSPACE (val.symtab); val.pc = 0; values.sals = (struct symtab_and_line *) xmalloc (sizeof (struct symtab_and_line)); @@ -1635,6 +1750,7 @@ decode_all_digits (char **argptr, struct symtab *default_symtab, values.nelts = 1; if (need_canonical) build_canonical_line_spec (values.sals, NULL, canonical); + values.sals[0].explicit_line = 1; return values; } @@ -1646,15 +1762,13 @@ static struct symtabs_and_lines decode_dollar (char *copy, int funfirstline, struct symtab *default_symtab, char ***canonical, struct symtab *file_symtab) { - struct value *valx; + LONGEST valx; int index = 0; int need_canonical = 0; struct symtabs_and_lines values; struct symtab_and_line val; char *p; struct symbol *sym; - /* The symtab that SYM was found in. */ - struct symtab *sym_symtab; struct minimal_symbol *msymbol; p = (copy[1] == '$') ? copy + 2 : copy + 1; @@ -1663,10 +1777,12 @@ decode_dollar (char *copy, int funfirstline, struct symtab *default_symtab, if (!*p) /* Reached end of token without hitting non-digit. */ { /* We have a value history reference. */ + struct value *val_history; sscanf ((copy[1] == '$') ? copy + 2 : copy + 1, "%d", &index); - valx = access_value_history ((copy[1] == '$') ? -index : index); - if (TYPE_CODE (value_type (valx)) != TYPE_CODE_INT) + val_history = access_value_history ((copy[1] == '$') ? -index : index); + if (TYPE_CODE (value_type (val_history)) != TYPE_CODE_INT) error (_("History values used in line specs must have integer values.")); + valx = value_as_long (val_history); } else { @@ -1674,13 +1790,12 @@ decode_dollar (char *copy, int funfirstline, struct symtab *default_symtab, convenience variable. */ /* Look up entire name as a symbol first. */ - sym = lookup_symbol (copy, 0, VAR_DOMAIN, 0, &sym_symtab); - file_symtab = (struct symtab *) 0; + sym = lookup_symbol (copy, 0, VAR_DOMAIN, 0); + file_symtab = (struct symtab *) NULL; need_canonical = 1; /* Symbol was found --> jump to normal symbol processing. */ if (sym) - return symbol_found (funfirstline, canonical, copy, sym, - NULL, sym_symtab); + return symbol_found (funfirstline, canonical, copy, sym, NULL); /* If symbol was not found, look in minimal symbol tables. */ msymbol = lookup_minimal_symbol (copy, NULL, NULL); @@ -1689,9 +1804,7 @@ decode_dollar (char *copy, int funfirstline, struct symtab *default_symtab, return minsym_found (funfirstline, msymbol); /* Not a user variable or function -- must be convenience variable. */ - need_canonical = (file_symtab == 0) ? 1 : 0; - valx = value_of_internalvar (lookup_internalvar (copy + 1)); - if (TYPE_CODE (value_type (valx)) != TYPE_CODE_INT) + if (!get_internalvar_integer (lookup_internalvar (copy + 1), &valx)) error (_("Convenience variables used in line specs must have integer values.")); } @@ -1699,8 +1812,9 @@ decode_dollar (char *copy, int funfirstline, struct symtab *default_symtab, /* Either history value or convenience value from above, in valx. */ val.symtab = file_symtab ? file_symtab : default_symtab; - val.line = value_as_long (valx); + val.line = valx; val.pc = 0; + val.pspace = current_program_space; values.sals = (struct symtab_and_line *) xmalloc (sizeof val); values.sals[0] = val; @@ -1724,8 +1838,6 @@ decode_variable (char *copy, int funfirstline, char ***canonical, struct symtab *file_symtab, int *not_found_ptr) { struct symbol *sym; - /* The symtab that SYM was found in. */ - struct symtab *sym_symtab; struct minimal_symbol *msymbol; @@ -1734,23 +1846,24 @@ decode_variable (char *copy, int funfirstline, char ***canonical, ? BLOCKVECTOR_BLOCK (BLOCKVECTOR (file_symtab), STATIC_BLOCK) : get_selected_block (0)), - VAR_DOMAIN, 0, &sym_symtab); + VAR_DOMAIN, 0); if (sym != NULL) - return symbol_found (funfirstline, canonical, copy, sym, - file_symtab, sym_symtab); + return symbol_found (funfirstline, canonical, copy, sym, file_symtab); msymbol = lookup_minimal_symbol (copy, NULL, NULL); if (msymbol != NULL) return minsym_found (funfirstline, msymbol); - if (!have_full_symbols () && - !have_partial_symbols () && !have_minimal_symbols ()) - error (_("No symbol table is loaded. Use the \"file\" command.")); - if (not_found_ptr) *not_found_ptr = 1; + + if (!have_full_symbols () + && !have_partial_symbols () + && !have_minimal_symbols ()) + throw_error (NOT_FOUND_ERROR, + _("No symbol table is loaded. Use the \"file\" command.")); throw_error (NOT_FOUND_ERROR, _("Function \"%s\" not defined."), copy); } @@ -1765,8 +1878,7 @@ decode_variable (char *copy, int funfirstline, char ***canonical, static struct symtabs_and_lines symbol_found (int funfirstline, char ***canonical, char *copy, - struct symbol *sym, struct symtab *file_symtab, - struct symtab *sym_symtab) + struct symbol *sym, struct symtab *file_symtab) { struct symtabs_and_lines values; @@ -1786,9 +1898,9 @@ symbol_found (int funfirstline, char ***canonical, char *copy, function. */ if (file_symtab == 0) { - struct blockvector *bv = BLOCKVECTOR (sym_symtab); + struct blockvector *bv = BLOCKVECTOR (SYMBOL_SYMTAB (sym)); struct block *b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); - if (lookup_block_symbol (b, copy, NULL, VAR_DOMAIN) != NULL) + if (lookup_block_symbol (b, copy, VAR_DOMAIN) != NULL) build_canonical_line_spec (values.sals, copy, canonical); } return values; @@ -1804,7 +1916,7 @@ symbol_found (int funfirstline, char ***canonical, char *copy, xmalloc (sizeof (struct symtab_and_line)); values.nelts = 1; memset (&values.sals[0], 0, sizeof (values.sals[0])); - values.sals[0].symtab = sym_symtab; + values.sals[0].symtab = SYMBOL_SYMTAB (sym); values.sals[0].line = SYMBOL_LINE (sym); return values; } @@ -1824,18 +1936,47 @@ symbol_found (int funfirstline, char ***canonical, char *copy, static struct symtabs_and_lines minsym_found (int funfirstline, struct minimal_symbol *msymbol) { + struct objfile *objfile = msymbol_objfile (msymbol); + struct gdbarch *gdbarch = get_objfile_arch (objfile); struct symtabs_and_lines values; + CORE_ADDR pc; values.sals = (struct symtab_and_line *) xmalloc (sizeof (struct symtab_and_line)); values.sals[0] = find_pc_sect_line (SYMBOL_VALUE_ADDRESS (msymbol), - (struct bfd_section *) 0, 0); - values.sals[0].section = SYMBOL_BFD_SECTION (msymbol); + (struct obj_section *) 0, 0); + values.sals[0].section = SYMBOL_OBJ_SECTION (msymbol); + + /* The minimal symbol might point to a function descriptor; + resolve it to the actual code address instead. */ + pc = gdbarch_convert_from_func_ptr_addr (gdbarch, + values.sals[0].pc, + ¤t_target); + if (pc != values.sals[0].pc) + values.sals[0] = find_pc_sect_line (pc, NULL, 0); + if (funfirstline) { - values.sals[0].pc += DEPRECATED_FUNCTION_START_OFFSET; - values.sals[0].pc = SKIP_PROLOGUE (values.sals[0].pc); + struct symtab_and_line sal; + + values.sals[0].pc = find_function_start_pc (gdbarch, + values.sals[0].pc, + values.sals[0].section); + + sal = find_pc_sect_line (values.sals[0].pc, values.sals[0].section, 0); + + /* Check if SKIP_PROLOGUE left us in mid-line, and the next + line is still part of the same function. If there is no + line information here, sal.pc will be the passed in PC. */ + if (sal.pc != values.sals[0].pc + && (lookup_minimal_symbol_by_pc_section (values.sals[0].pc, + values.sals[0].section) + == lookup_minimal_symbol_by_pc_section (sal.end, + values.sals[0].section))) + /* Recalculate the line number (might not be N+1). */ + values.sals[0] = find_pc_sect_line (sal.end, values.sals[0].section, 0); } + values.nelts = 1; return values; }