X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Flinespec.c;h=91c5b901320ec5df64d34ab00bd5fe017a27cf76;hb=496c0e1ba7bd2b8596d90cc6b2bc87cf5c1cff67;hp=3e943a18e74c088a22b9e870cb3ffac544032d68;hpb=759ef83693911e20efd389b20cbf8f3a8eec30eb;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/linespec.c b/gdb/linespec.c index 3e943a18e7..91c5b90132 100644 --- a/gdb/linespec.c +++ b/gdb/linespec.c @@ -2,7 +2,7 @@ Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, - 2009 Free Software Foundation, Inc. + 2009, 2010 Free Software Foundation, Inc. This file is part of GDB. @@ -30,6 +30,7 @@ #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" @@ -39,6 +40,7 @@ #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. */ @@ -49,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); @@ -78,9 +78,8 @@ static struct symtabs_and_lines find_method (int funfirstline, struct symbol *sym_class, int *not_found_ptr); -static NORETURN void cplusplus_error (const char *name, - const char *fmt, ...) - ATTR_NORETURN ATTR_FORMAT (printf, 2, 3); +static void cplusplus_error (const char *name, const char *fmt, ...) + ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 3); static int total_number_of_methods (struct type *type); @@ -123,6 +122,9 @@ static struct symtabs_and_lines decode_dollar (char *copy, char ***canonical, struct symtab *file_symtab); +static int decode_label (char *copy, char ***canonical, + struct symtabs_and_lines *result); + static struct symtabs_and_lines decode_variable (char *copy, int funfirstline, char ***canonical, @@ -146,16 +148,18 @@ symtabs_and_lines minsym_found (int funfirstline, single quoted demangled C++ symbols as part of the completion error. */ -static NORETURN void +static 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); { va_list args; + va_start (args, fmt); vfprintf_unfiltered (tmp_stream, fmt, args); va_end (args); @@ -185,7 +189,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); @@ -627,6 +631,37 @@ See set/show multiple-symbol.")); 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. */ @@ -640,6 +675,7 @@ See set/show multiple-symbol.")); FILE:LINENUM -- that line in that file. PC returned is 0. FUNCTION -- line number of openbrace of that function. PC returned is the start of the function. + LABEL -- a label in the current scope VARIABLE -- line number of definition of that variable. PC returned is 0. FILE:FUNCTION -- likewise, but prefer functions in that file. @@ -687,16 +723,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; @@ -710,12 +747,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). */ @@ -726,20 +762,18 @@ 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. */ { struct symtabs_and_lines values; + values = decode_objc (argptr, funfirstline, NULL, canonical, saved_arg); if (values.sals != NULL) @@ -748,11 +782,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. @@ -761,52 +792,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, not_found_ptr); + { + 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 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 */ + file_symtab = symtab_from_filename (argptr, p, is_quote_enclosed, + not_found_ptr); - /* 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. */ - - copy = (char *) alloca (p - *argptr + 1); - memcpy (copy, *argptr, p - *argptr); - copy[p - *argptr] = '\000'; - sym = lookup_symbol (copy, 0, VAR_DOMAIN, 0); - 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); + 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 /* 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; @@ -828,7 +856,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.")); } @@ -837,10 +865,6 @@ 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); @@ -850,6 +874,14 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab, 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'; @@ -861,6 +893,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; @@ -873,6 +907,16 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab, return decode_dollar (copy, funfirstline, default_symtab, canonical, file_symtab); + /* Try the token as a label, but only if no file was specified, + because we can only really find labels in the current scope. */ + + if (!file_symtab) + { + struct symtabs_and_lines label_result; + if (decode_label (copy, canonical, &label_result)) + return label_result; + } + /* Look up that token as a variable. If file specified, use that file's per-file block to start with. */ @@ -895,10 +939,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 @@ -925,44 +968,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. */ @@ -1033,12 +1038,20 @@ 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] == '<') { char *temp_end = find_template_name_end (p); + if (!temp_end) error (_("malformed template specification in command")); p = temp_end; @@ -1062,8 +1075,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; @@ -1078,6 +1092,7 @@ locate_first_half (char **argptr, int *is_quote_enclosed) if (*is_quote_enclosed) { char *closing_quote = strchr (p - 1, '"'); + if (closing_quote && closing_quote[1] == '\0') *closing_quote = '\0'; } @@ -1171,11 +1186,19 @@ decode_objc (char **argptr, int funfirstline, struct symtab *file_symtab, } else { - /* The only match was a non-debuggable symbol. */ - values.sals[0].symtab = NULL; - 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; } @@ -1205,8 +1228,8 @@ decode_compound (char **argptr, int funfirstline, char ***canonical, struct symbol *sym; 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 @@ -1255,8 +1278,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); @@ -1330,10 +1357,59 @@ 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 @@ -1362,9 +1438,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, not_found_ptr); - + 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 */ @@ -1407,6 +1500,7 @@ lookup_prefix_sym (char **argptr, char *p) { char *p1; char *copy; + struct symbol *sym; /* Extract the class name. */ p1 = p; @@ -1425,7 +1519,28 @@ 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); + 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 @@ -1468,32 +1583,55 @@ 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 (not_found_ptr) *not_found_ptr = 1; - if (tmp[0] == '~') + 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); + SYMBOL_PRINT_NAME (sym_class), copy); } } @@ -1521,7 +1659,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; @@ -1573,6 +1712,8 @@ decode_all_digits (char **argptr, struct symtab *default_symtab, 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 @@ -1624,6 +1765,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)); @@ -1659,6 +1801,7 @@ decode_dollar (char *copy, int funfirstline, struct symtab *default_symtab, { /* We have a value history reference. */ struct value *val_history; + sscanf ((copy[1] == '$') ? copy + 2 : copy + 1, "%d", &index); val_history = access_value_history ((copy[1] == '$') ? -index : index); if (TYPE_CODE (value_type (val_history)) != TYPE_CODE_INT) @@ -1695,6 +1838,7 @@ decode_dollar (char *copy, int funfirstline, struct symtab *default_symtab, val.symtab = file_symtab ? file_symtab : default_symtab; val.line = valx; val.pc = 0; + val.pspace = current_program_space; values.sals = (struct symtab_and_line *) xmalloc (sizeof val); values.sals[0] = val; @@ -1708,6 +1852,27 @@ decode_dollar (char *copy, int funfirstline, struct symtab *default_symtab, +/* A helper for decode_line_1 that tries to find a label. The label + is searched for in the current block. + COPY is the name of the label to find. + CANONICAL is the same as the "canonical" argument to decode_line_1. + RESULT is a pointer to a symtabs_and_lines structure which will be + filled in on success. + This function returns 1 if a label was found, 0 otherwise. */ + +static int +decode_label (char *copy, char ***canonical, struct symtabs_and_lines *result) +{ + struct symbol *sym; + + sym = lookup_symbol (copy, get_selected_block (0), LABEL_DOMAIN, 0); + + if (sym != NULL) + *result = symbol_found (0, canonical, copy, sym, NULL); + + return sym != NULL; +} + /* Decode a linespec that's a variable. If FILE_SYMTAB is non-NULL, look in that symtab's static variables first. If NOT_FOUND_PTR is not NULL and the function cannot be found, store boolean true in the location pointed to @@ -1718,7 +1883,6 @@ decode_variable (char *copy, int funfirstline, char ***canonical, struct symtab *file_symtab, int *not_found_ptr) { struct symbol *sym; - struct minimal_symbol *msymbol; sym = lookup_symbol (copy, @@ -1780,14 +1944,15 @@ symbol_found (int funfirstline, char ***canonical, char *copy, { 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; } else { - if (funfirstline) + if (funfirstline && SYMBOL_CLASS (sym) != LOC_LABEL) error (_("\"%s\" is not a function"), copy); else if (SYMBOL_LINE (sym) != 0) { @@ -1798,6 +1963,7 @@ symbol_found (int funfirstline, char ***canonical, char *copy, memset (&values.sals[0], 0, sizeof (values.sals[0])); values.sals[0].symtab = SYMBOL_SYMTAB (sym); values.sals[0].line = SYMBOL_LINE (sym); + values.sals[0].pspace = SYMTAB_PSPACE (SYMBOL_SYMTAB (sym)); return values; } else @@ -1836,26 +2002,7 @@ minsym_found (int funfirstline, struct minimal_symbol *msymbol) values.sals[0] = find_pc_sect_line (pc, NULL, 0); if (funfirstline) - { - 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); - } + skip_prologue_sal (&values.sals[0]); values.nelts = 1; return values;