/* Parser for linespec for the GNU debugger, GDB.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
- 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+
+ Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
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,
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., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include "symtab.h"
#include "block.h"
#include "objc-lang.h"
#include "linespec.h"
+#include "exceptions.h"
+#include "language.h"
/* We share this one with symtab.c, but it is not exported widely. */
struct symbol *sym_class);
static int collect_methods (char *copy, struct type *t,
+ struct symbol *sym_class,
struct symbol **sym_arr);
static NORETURN void cplusplus_error (const char *name,
static int total_number_of_methods (struct type *type);
-static int find_methods (struct type *, char *, struct symbol **);
+static int find_methods (struct type *, char *,
+ enum language, struct symbol **);
static int add_matching_methods (int method_counter, struct type *t,
+ enum language language,
struct symbol **sym_arr);
static int add_constructors (int method_counter, struct type *t,
+ enum language language,
struct symbol **sym_arr);
static void build_canonical_line_spec (struct symtab_and_line *,
Note that this function is g++ specific. */
static int
-find_methods (struct type *t, char *name, struct symbol **sym_arr)
+find_methods (struct type *t, char *name, enum language language,
+ struct symbol **sym_arr)
{
int i1 = 0;
int ibase;
unless we figure out how to get the physname without the name of
the class, then the loop can't do any good. */
if (class_name
- && (lookup_symbol (class_name, (struct block *) NULL,
- STRUCT_DOMAIN, (int *) NULL,
+ && (lookup_symbol_in_language (class_name, (struct block *) NULL,
+ STRUCT_DOMAIN, language, (int *) NULL,
(struct symtab **) NULL)))
{
int method_counter;
if (strcmp_iw (name, method_name) == 0)
/* Find all the overloaded methods with that name. */
- i1 += add_matching_methods (method_counter, t,
+ i1 += add_matching_methods (method_counter, t, language,
sym_arr + i1);
else if (strncmp (class_name, name, name_len) == 0
&& (class_name[name_len] == '\0'
|| class_name[name_len] == '<'))
- i1 += add_constructors (method_counter, t,
+ i1 += add_constructors (method_counter, t, language,
sym_arr + i1);
}
}
if (i1 == 0)
for (ibase = 0; ibase < TYPE_N_BASECLASSES (t); ibase++)
- i1 += find_methods (TYPE_BASECLASS (t, ibase), name, sym_arr + i1);
+ i1 += find_methods (TYPE_BASECLASS (t, ibase), name,
+ language, sym_arr + i1);
return i1;
}
static int
add_matching_methods (int method_counter, struct type *t,
- struct symbol **sym_arr)
+ enum language language, struct symbol **sym_arr)
{
int field_counter;
int i1 = 0;
}
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 (phys_name,
+ sym_arr[i1] = lookup_symbol_in_language (phys_name,
NULL, VAR_DOMAIN,
+ language,
(int *) NULL,
(struct symtab **) NULL);
if (sym_arr[i1])
static int
add_constructors (int method_counter, struct type *t,
- struct symbol **sym_arr)
+ enum language language, struct symbol **sym_arr)
{
int field_counter;
int i1 = 0;
{
struct fn_field *f;
char *phys_name;
-
+
f = TYPE_FN_FIELDLIST1 (t, method_counter);
/* GCC 3.x will never produce stabs stub methods, so
/* If this method is actually defined, include it in the
list. */
- sym_arr[i1] = lookup_symbol (phys_name,
+ sym_arr[i1] = lookup_symbol_in_language (phys_name,
NULL, VAR_DOMAIN,
+ language,
(int *) NULL,
(struct symtab **) NULL);
if (sym_arr[i1])
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 *)
}
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)
+ 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");
+ error_no_arg (_("one or more choice numbers"));
i = 0;
while (*args)
while (*arg1 >= '0' && *arg1 <= '9')
arg1++;
if (*arg1 && *arg1 != ' ' && *arg1 != '\t')
- error ("Arguments must be choice numbers.");
+ error (_("Arguments must be choice numbers."));
num = atoi (args);
if (num == 0)
- error ("canceled");
+ error (_("canceled"));
else if (num == 1)
{
if (canonical_arr)
if (num >= nelts + 2)
{
- printf_unfiltered ("No choice number %d.\n", num);
+ printf_unfiltered (_("No choice number %d.\n"), num);
}
else
{
}
else
{
- printf_unfiltered ("duplicate request for %d ignored.\n", num);
+ printf_unfiltered (_("duplicate request for %d ignored.\n"), num);
}
}
{
p = skip_quoted (*argptr);
if (p[-1] != '\'')
- error ("Unmatched single quote.");
+ error (_("Unmatched single quote."));
}
else if (is_objc_method)
{
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;
}
{
char *temp_end = find_template_name_end (p);
if (!temp_end)
- error ("malformed template specification in command");
+ error (_("malformed template specification in command"));
p = temp_end;
}
/* Check for a colon and a plus or minus and a [ (which
struct symbol *sym = NULL;
char *copy = NULL;
struct block *block = NULL;
- int i1 = 0;
- int i2 = 0;
+ unsigned i1 = 0;
+ unsigned i2 = 0;
values.sals = NULL;
values.nelts = 0;
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;
sym = find_pc_function (SYMBOL_VALUE_ADDRESS (sym_arr[0]));
if ((sym != NULL) && strcmp (SYMBOL_LINKAGE_NAME (sym_arr[0]), SYMBOL_LINKAGE_NAME (sym)) != 0)
{
- warning ("debugging symbol \"%s\" does not match selector; ignoring", SYMBOL_LINKAGE_NAME (sym));
+ warning (_("debugging symbol \"%s\" does not match selector; ignoring"), SYMBOL_LINKAGE_NAME (sym));
sym = NULL;
}
}
else
{
/* The only match was a non-debuggable symbol. */
- values.sals[0].symtab = 0;
+ 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]);
&& ((*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:
+
+ 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.
+
+ 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.
+
+ 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. */
p2 = p; /* Save for restart. */
while (1)
{
-
- /* 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. */
- /* PASS1: Before the call, argptr->"AAA::inA::fun",
- p->"::inA::fun". After the call: argptr->"inA::fun", p
- unchanged. */
- /* PASS2: Before the call, argptr->"AAA::inA::fun", p->"::fun".
- After the call: argptr->"fun", p->"::fun". */
- sym_class = lookup_prefix_sym (argptr, p);
-
- /* PASS1: assume sym_class == NULL. Skip the whole if-stmt. */
- /* PASS2: assume sym_class has been found, i.e. "AAA::inA" is a
- class. Enter the if-stmt. */
- 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
- {
- /* PASS2: at this point argptr->"fun". */
- p = *argptr;
- while (*p && *p != ' ' && *p != '\t' && *p != ',' && *p != ':')
- p++;
- /* PASS2: 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';
-
- /* PASS2: At this point copy->"fun", p->"" */
-
- /* No line number may be specified. */
- while (*p == ' ' || *p == '\t')
- p++;
- *argptr = p;
-
- /* Look for copy as a method of sym_class. */
- /* PASS2: at this point copy->"fun", sym_class is "AAA:inA".
- 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 get out
- of the loop and lookup the whole string in the symbol
- tables. */
-
- return find_method (funfirstline, canonical, saved_arg,
- copy, t, sym_class);
- } /* End if symbol found */
-
- /* End of lookup in the symbol tables. */
-
- /* Prepare for next run through the loop. */
/* 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] != '\''))
{
temp_end = find_template_name_end (p);
if (!temp_end)
- error ("malformed template specification in command");
+ error (_("malformed template specification in command"));
p = temp_end;
}
/* Note that, since, at the start of this loop, p would be
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++;
}
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->"". */
+ string, and p->""(PASS2) */
/* We get here if p points to ' ', '\t', '\'', "::" or ""(i.e
string ended). */
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". */
+ /* 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
char *copy, struct type *t, struct symbol *sym_class)
{
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 *));
/* Find all methods with a matching name, and put them in
sym_arr. */
- i1 = collect_methods (copy, t, sym_arr);
+ i1 = collect_methods (copy, t, sym_class, sym_arr);
if (i1 == 1)
{
}
else
{
+ values.sals = NULL;
values.nelts = 0;
}
return values;
static int
collect_methods (char *copy, struct type *t,
- struct symbol **sym_arr)
+ struct symbol *sym_class, struct symbol **sym_arr)
{
int i1 = 0; /* Counter for the symbol array. */
}
}
else
- i1 = find_methods (t, copy, sym_arr);
+ i1 = find_methods (t, copy, SYMBOL_LANGUAGE (sym_class), sym_arr);
return i1;
}
if (file_symtab == 0)
{
if (!have_full_symbols () && !have_partial_symbols ())
- error ("No symbol table is loaded. Use the \"file\" command.");
+ error (_("No symbol table is loaded. Use the \"file\" command."));
if (not_found_ptr)
- {
- *not_found_ptr = 1;
- /* The caller has indicated that it wishes quiet notification of any
- error where the function or file is not found. A call to
- error_silent causes an error to occur, but it does not issue
- the supplied message. The message can be manually output by
- the caller, if desired. This is used, for example, when
- attempting to set breakpoints for functions in shared libraries
- that have not yet been loaded. */
- error_silent ("No source file named %s.", copy);
- }
- error ("No source file named %s.", copy);
+ *not_found_ptr = 1;
+ throw_error (NOT_FOUND_ERROR, _("No source file named %s."), copy);
}
/* Discard the file name from the arg. */
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);
values.nelts = 1;
if (need_canonical)
build_canonical_line_spec (values.sals, NULL, canonical);
+ values.sals[0].explicit_line = 1;
return values;
}
/* We have a value history reference. */
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)
- error ("History values used in line specs must have integer values.");
+ if (TYPE_CODE (value_type (valx)) != TYPE_CODE_INT)
+ error (_("History values used in line specs must have integer values."));
}
else
{
/* Look up entire name as a symbol first. */
sym = lookup_symbol (copy, 0, VAR_DOMAIN, 0, &sym_symtab);
- file_symtab = (struct symtab *) 0;
+ file_symtab = (struct symtab *) NULL;
need_canonical = 1;
/* Symbol was found --> jump to normal symbol processing. */
if (sym)
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)
- error ("Convenience variables used in line specs must have integer values.");
+ if (TYPE_CODE (value_type (valx)) != TYPE_CODE_INT)
+ error (_("Convenience variables used in line specs must have integer values."));
}
init_sal (&val);
if (!have_full_symbols () &&
!have_partial_symbols () && !have_minimal_symbols ())
- error ("No symbol table is loaded. Use the \"file\" command.");
+ error (_("No symbol table is loaded. Use the \"file\" command."));
if (not_found_ptr)
- {
- *not_found_ptr = 1;
- /* The caller has indicated that it wishes quiet notification of any
- error where the function or file is not found. A call to
- error_silent causes an error to occur, but it does not issue
- the supplied message. The message can be manually output by
- the caller, if desired. This is used, for example, when
- attempting to set breakpoints for functions in shared libraries
- that have not yet been loaded. */
- error_silent ("Function \"%s\" not defined.", copy);
- }
-
- error ("Function \"%s\" not defined.", copy);
+ *not_found_ptr = 1;
+ throw_error (NOT_FOUND_ERROR, _("Function \"%s\" not defined."), copy);
}
else
{
if (funfirstline)
- error ("\"%s\" is not a function", copy);
+ error (_("\"%s\" is not a function"), copy);
else if (SYMBOL_LINE (sym) != 0)
{
/* We know its line number. */
/* FIXME: Shouldn't we just set .line and .symtab to zero
and return? For example, "info line foo" could print
the address. */
- error ("Line number not known for symbol \"%s\"", copy);
+ error (_("Line number not known for symbol \"%s\""), copy);
}
}
values.sals[0].section = SYMBOL_BFD_SECTION (msymbol);
if (funfirstline)
{
- values.sals[0].pc += FUNCTION_START_OFFSET;
- values.sals[0].pc = SKIP_PROLOGUE (values.sals[0].pc);
+ struct symtab_and_line sal;
+
+ values.sals[0].pc
+ += gdbarch_deprecated_function_start_offset (current_gdbarch);
+ values.sals[0].pc = gdbarch_skip_prologue
+ (current_gdbarch, values.sals[0].pc);
+
+ 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;
}