X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Flinespec.c;h=2360cc14faf998ee449ae3f25677d841d9ebf79d;hb=11cf4ffb5e256d268a8f4cea0fc88a0a46bf824c;hp=81f526d6f6b1428ad405c9796d2d8bdb57e9cf2a;hpb=f168693bc9d109c387e442119354bd57ecec8267;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/linespec.c b/gdb/linespec.c index 81f526d6f6..2360cc14fa 100644 --- a/gdb/linespec.c +++ b/gdb/linespec.c @@ -1,6 +1,6 @@ /* Parser for linespec for the GNU debugger, GDB. - Copyright (C) 1986-2015 Free Software Foundation, Inc. + Copyright (C) 1986-2016 Free Software Foundation, Inc. This file is part of GDB. @@ -43,6 +43,7 @@ #include "filenames.h" #include "ada-lang.h" #include "stack.h" +#include "location.h" typedef struct symbol *symbolp; DEF_VEC_P (symbolp); @@ -64,73 +65,26 @@ typedef struct bound_minimal_symbol bound_minimal_symbol_d; DEF_VEC_O (bound_minimal_symbol_d); -/* An enumeration of possible signs for a line offset. */ -enum offset_relative_sign -{ - /* No sign */ - LINE_OFFSET_NONE, - - /* A plus sign ("+") */ - LINE_OFFSET_PLUS, - - /* A minus sign ("-") */ - LINE_OFFSET_MINUS, - - /* A special "sign" for unspecified offset. */ - LINE_OFFSET_UNKNOWN -}; - -/* A line offset in a linespec. */ - -struct line_offset -{ - /* Line offset and any specified sign. */ - int offset; - enum offset_relative_sign sign; -}; - /* A linespec. Elements of this structure are filled in by a parser (either parse_linespec or some other function). The structure is then converted into SALs by convert_linespec_to_sals. */ struct linespec { - /* An expression and the resulting PC. Specifying an expression - currently precludes the use of other members. */ - - /* The expression entered by the user. */ - const char *expression; - - /* The resulting PC expression derived from evaluating EXPRESSION. */ - CORE_ADDR expr_pc; - - /* Any specified file symtabs. */ - - /* The user-supplied source filename or NULL if none was specified. */ - const char *source_filename; + /* An explicit location describing the SaLs. */ + struct explicit_location explicit_loc; /* The list of symtabs to search to which to limit the search. May not - be NULL. If SOURCE_FILENAME is NULL (no user-specified filename), - FILE_SYMTABS should contain one single NULL member. This will - cause the code to use the default symtab. */ + be NULL. If explicit.SOURCE_FILENAME is NULL (no user-specified + filename), FILE_SYMTABS should contain one single NULL member. This + will cause the code to use the default symtab. */ VEC (symtab_ptr) *file_symtabs; - /* The name of a function or method and any matching symbols. */ - - /* The user-specified function name. If no function name was - supplied, this may be NULL. */ - const char *function_name; - /* A list of matching function symbols and minimal symbols. Both lists may be NULL if no matching symbols were found. */ VEC (symbolp) *function_symbols; VEC (bound_minimal_symbol_d) *minimal_symbols; - /* The name of a label and matching symbols. */ - - /* The user-specified label name. */ - const char *label_name; - /* A structure of matching label symbols and the corresponding function symbol in which the label was found. Both may be NULL or both must be non-NULL. */ @@ -139,10 +93,6 @@ struct linespec VEC (symbolp) *label_symbols; VEC (symbolp) *function_symbols; } labels; - - /* Line offset. It may be LINE_OFFSET_UNKNOWN, meaning that no - offset was specified. */ - struct line_offset line_offset; }; typedef struct linespec *linespec_p; @@ -173,6 +123,10 @@ struct linespec_state /* The program space as seen when the module was entered. */ struct program_space *program_space; + /* If not NULL, the search is restricted to just this program + space. */ + struct program_space *search_pspace; + /* The default symtab to use, if no other symtab is specified. */ struct symtab *default_symtab; @@ -195,6 +149,9 @@ struct linespec_state /* This is a set of address_entry objects which is used to prevent duplicate symbols from being entered into the result. */ htab_t addr_set; + + /* Are we building a linespec? */ + int is_linespec; }; /* This is a helper object that is used when collecting symbols into a @@ -281,8 +238,8 @@ struct ls_parser const char *saved_arg; /* Head of the input stream. */ - const char **stream; -#define PARSER_STREAM(P) (*(P)->lexer.stream) + const char *stream; +#define PARSER_STREAM(P) ((P)->lexer.stream) /* The current token. */ linespec_token current; @@ -301,6 +258,10 @@ struct ls_parser }; typedef struct ls_parser linespec_parser; +/* A convenience macro for accessing the explicit location result of + the parser. */ +#define PARSER_EXPLICIT(PPTR) (&PARSER_RESULT ((PPTR))->explicit_loc) + /* Prototypes for local functions. */ static void iterate_over_file_blocks (struct symtab *symtab, @@ -311,13 +272,14 @@ static void iterate_over_file_blocks (struct symtab *symtab, static void initialize_defaults (struct symtab **default_symtab, int *default_line); -static CORE_ADDR linespec_expression_to_pc (const char **exp_ptr); +CORE_ADDR linespec_expression_to_pc (const char **exp_ptr); static struct symtabs_and_lines decode_objc (struct linespec_state *self, linespec_p ls, - const char **argptr); + const char *arg); -static VEC (symtab_ptr) *symtabs_from_filename (const char *); +static VEC (symtab_ptr) *symtabs_from_filename (const char *, + struct program_space *pspace); static VEC (symbolp) *find_label_symbols (struct linespec_state *self, VEC (symbolp) *function_symbols, @@ -345,7 +307,9 @@ static void add_all_symbol_names_from_pspace (struct collect_info *info, struct program_space *pspace, VEC (const_char_ptr) *names); -static VEC (symtab_ptr) *collect_symtabs_from_filename (const char *file); +static VEC (symtab_ptr) * + collect_symtabs_from_filename (const char *file, + struct program_space *pspace); static void decode_digits_ordinary (struct linespec_state *self, linespec_p ls, @@ -366,8 +330,6 @@ static int compare_symbols (const void *a, const void *b); static int compare_msymbols (const void *a, const void *b); -static const char *find_toplevel_char (const char *s, char c); - /* Permitted quote characters for the parser. This is different from the completer's quote characters to allow backward compatibility with the previous parser. */ @@ -462,10 +424,9 @@ linespec_lexer_lex_keyword (const char *p) return NULL; } -/* Does STRING represent an Ada operator? If so, return the length - of the decoded operator name. If not, return 0. */ +/* See description in linespec.h. */ -static int +int is_ada_operator (const char *string) { const struct ada_opname_map *mapping; @@ -715,7 +676,7 @@ linespec_lexer_lex_string (linespec_parser *parser) && (PARSER_STREAM (parser) - start) > 8 /* strlen ("operator") */) { - char *p = strstr (start, "operator"); + const char *p = strstr (start, "operator"); if (p != NULL && is_operator_name (p)) { @@ -856,7 +817,7 @@ add_sal_to_sals_basic (struct symtabs_and_lines *sals, struct symtab_and_line *sal) { ++sals->nelts; - sals->sals = xrealloc (sals->sals, sals->nelts * sizeof (sals->sals[0])); + sals->sals = XRESIZEVEC (struct symtab_and_line, sals->sals, sals->nelts); sals->sals[sals->nelts - 1] = *sal; } @@ -879,9 +840,8 @@ add_sal_to_sals (struct linespec_state *self, { struct linespec_canonical_name *canonical; - self->canonical_names = xrealloc (self->canonical_names, - (sals->nelts - * sizeof (*self->canonical_names))); + self->canonical_names = XRESIZEVEC (struct linespec_canonical_name, + self->canonical_names, sals->nelts); canonical = &self->canonical_names[sals->nelts - 1]; if (!literal_canonical && sal->symtab) { @@ -915,7 +875,7 @@ add_sal_to_sals (struct linespec_state *self, static hashval_t hash_address_entry (const void *p) { - const struct address_entry *aep = p; + const struct address_entry *aep = (const struct address_entry *) p; hashval_t hash; hash = iterative_hash_object (aep->pspace, 0); @@ -927,8 +887,8 @@ hash_address_entry (const void *p) static int eq_address_entry (const void *a, const void *b) { - const struct address_entry *aea = a; - const struct address_entry *aeb = b; + const struct address_entry *aea = (const struct address_entry *) a; + const struct address_entry *aeb = (const struct address_entry *) b; return aea->pspace == aeb->pspace && aea->addr == aeb->addr; } @@ -976,7 +936,8 @@ iterate_inline_only (struct symbol *sym, void *d) { if (SYMBOL_INLINED (sym)) { - struct symbol_and_data_callback *cad = d; + struct symbol_and_data_callback *cad + = (struct symbol_and_data_callback *) d; return cad->callback (sym, cad->data); } @@ -1000,7 +961,8 @@ struct symbol_matcher_data static int iterate_name_matcher (const char *name, void *d) { - const struct symbol_matcher_data *data = d; + const struct symbol_matcher_data *data + = (const struct symbol_matcher_data *) d; if (data->symbol_name_cmp (name, data->lookup_name) == 0) return 1; /* Expand this symbol's symbol table. */ @@ -1183,7 +1145,7 @@ find_methods (struct type *t, const char *name, strings. Also, ignore the char within a template name, like a ',' within foo. */ -static const char * +const char * find_toplevel_char (const char *s, char c) { int quoted = 0; /* zero if we're not in quotes; @@ -1341,8 +1303,8 @@ struct decode_line_2_item static int decode_line_2_compare_items (const void *ap, const void *bp) { - const struct decode_line_2_item *a = ap; - const struct decode_line_2_item *b = bp; + const struct decode_line_2_item *a = (const struct decode_line_2_item *) ap; + const struct decode_line_2_item *b = (const struct decode_line_2_item *) bp; int retval; retval = strcmp (a->displayform, b->displayform); @@ -1378,7 +1340,7 @@ decode_line_2 (struct linespec_state *self, /* Prepare ITEMS array. */ items_count = result->nelts; - items = xmalloc (sizeof (*items) * items_count); + items = XNEWVEC (struct decode_line_2_item, items_count); make_cleanup (xfree, items); for (i = 0; i < items_count; ++i) { @@ -1571,11 +1533,35 @@ unexpected_linespec_error (linespec_parser *parser) token_type_strings[token.type]); } -/* Parse and return a line offset in STRING. */ +/* Throw an undefined label error. */ -static struct line_offset +static void ATTRIBUTE_NORETURN +undefined_label_error (const char *function, const char *label) +{ + if (function != NULL) + throw_error (NOT_FOUND_ERROR, + _("No label \"%s\" defined in function \"%s\"."), + label, function); + else + throw_error (NOT_FOUND_ERROR, + _("No label \"%s\" defined in current function."), + label); +} + +/* Throw a source file not found error. */ + +static void ATTRIBUTE_NORETURN +source_file_not_found_error (const char *name) +{ + throw_error (NOT_FOUND_ERROR, _("No source file named %s."), name); +} + +/* See description in linespec.h. */ + +struct line_offset linespec_parse_line_offset (const char *string) { + const char *start = string; struct line_offset line_offset = {0, LINE_OFFSET_NONE}; if (*string == '+') @@ -1589,6 +1575,9 @@ linespec_parse_line_offset (const char *string) ++string; } + if (*string != '\0' && !isdigit (*string)) + error (_("malformed line offset: \"%s\""), start); + /* Right now, we only allow base 10 for offsets. */ line_offset.offset = atoi (string); return line_offset; @@ -1617,7 +1606,7 @@ linespec_parse_basic (linespec_parser *parser) /* Record the line offset and get the next token. */ name = copy_token_string (token); cleanup = make_cleanup (xfree, name); - PARSER_RESULT (parser)->line_offset = linespec_parse_line_offset (name); + PARSER_EXPLICIT (parser)->line_offset = linespec_parse_line_offset (name); do_cleanups (cleanup); /* Get the next token. */ @@ -1654,7 +1643,7 @@ linespec_parse_basic (linespec_parser *parser) { PARSER_RESULT (parser)->function_symbols = symbols; PARSER_RESULT (parser)->minimal_symbols = minimal_symbols; - PARSER_RESULT (parser)->function_name = name; + PARSER_EXPLICIT (parser)->function_name = name; symbols = NULL; discard_cleanups (cleanup); } @@ -1668,7 +1657,7 @@ linespec_parse_basic (linespec_parser *parser) { PARSER_RESULT (parser)->labels.label_symbols = labels; PARSER_RESULT (parser)->labels.function_symbols = symbols; - PARSER_RESULT (parser)->label_name = name; + PARSER_EXPLICIT (parser)->label_name = name; symbols = NULL; discard_cleanups (cleanup); } @@ -1676,14 +1665,14 @@ linespec_parse_basic (linespec_parser *parser) && *LS_TOKEN_STOKEN (token).ptr == '$') { /* User specified a convenience variable or history value. */ - PARSER_RESULT (parser)->line_offset + PARSER_EXPLICIT (parser)->line_offset = linespec_parse_variable (PARSER_STATE (parser), name); - if (PARSER_RESULT (parser)->line_offset.sign == LINE_OFFSET_UNKNOWN) + if (PARSER_EXPLICIT (parser)->line_offset.sign == LINE_OFFSET_UNKNOWN) { /* The user-specified variable was not valid. Do not throw an error here. parse_linespec will do it for us. */ - PARSER_RESULT (parser)->function_name = name; + PARSER_EXPLICIT (parser)->function_name = name; discard_cleanups (cleanup); return; } @@ -1698,7 +1687,7 @@ linespec_parse_basic (linespec_parser *parser) an error here. parse_linespec will do it for us. */ /* Save a copy of the name we were trying to lookup. */ - PARSER_RESULT (parser)->function_name = name; + PARSER_EXPLICIT (parser)->function_name = name; discard_cleanups (cleanup); return; } @@ -1718,7 +1707,7 @@ linespec_parse_basic (linespec_parser *parser) get the next token. */ name = copy_token_string (token); cleanup = make_cleanup (xfree, name); - PARSER_RESULT (parser)->line_offset + PARSER_EXPLICIT (parser)->line_offset = linespec_parse_line_offset (name); do_cleanups (cleanup); @@ -1738,16 +1727,15 @@ linespec_parse_basic (linespec_parser *parser) { PARSER_RESULT (parser)->labels.label_symbols = labels; PARSER_RESULT (parser)->labels.function_symbols = symbols; - PARSER_RESULT (parser)->label_name = name; + PARSER_EXPLICIT (parser)->label_name = name; symbols = NULL; discard_cleanups (cleanup); } else { /* We don't know what it was, but it isn't a label. */ - throw_error (NOT_FOUND_ERROR, - _("No label \"%s\" defined in function \"%s\"."), - name, PARSER_RESULT (parser)->function_name); + undefined_label_error (PARSER_EXPLICIT (parser)->function_name, + name); } /* Check for a line offset. */ @@ -1765,7 +1753,7 @@ linespec_parse_basic (linespec_parser *parser) name = copy_token_string (token); cleanup = make_cleanup (xfree, name); - PARSER_RESULT (parser)->line_offset + PARSER_EXPLICIT (parser)->line_offset = linespec_parse_line_offset (name); do_cleanups (cleanup); @@ -1782,74 +1770,49 @@ linespec_parse_basic (linespec_parser *parser) } /* Canonicalize the linespec contained in LS. The result is saved into - STATE->canonical. */ + STATE->canonical. This function handles both linespec and explicit + locations. */ static void -canonicalize_linespec (struct linespec_state *state, linespec_p ls) +canonicalize_linespec (struct linespec_state *state, const linespec_p ls) { + struct event_location *canon; + struct explicit_location *explicit_loc; + /* If canonicalization was not requested, no need to do anything. */ if (!state->canonical) return; - /* Shortcut expressions, which can only appear by themselves. */ - if (ls->expression != NULL) - state->canonical->addr_string = xstrdup (ls->expression); - else - { - struct ui_file *buf; - int need_colon = 0; - - buf = mem_fileopen (); - if (ls->source_filename) - { - fputs_unfiltered (ls->source_filename, buf); - need_colon = 1; - } + /* Save everything as an explicit location. */ + canon = state->canonical->location + = new_explicit_location (&ls->explicit_loc); + explicit_loc = get_explicit_location (canon); - if (ls->function_name) - { - if (need_colon) - fputc_unfiltered (':', buf); - fputs_unfiltered (ls->function_name, buf); - need_colon = 1; - } + if (explicit_loc->label_name != NULL) + { + state->canonical->special_display = 1; - if (ls->label_name) + if (explicit_loc->function_name == NULL) { - if (need_colon) - fputc_unfiltered (':', buf); - - if (ls->function_name == NULL) - { - struct symbol *s; - - /* No function was specified, so add the symbol name. */ - gdb_assert (ls->labels.function_symbols != NULL - && (VEC_length (symbolp, ls->labels.function_symbols) - == 1)); - s = VEC_index (symbolp, ls->labels.function_symbols, 0); - fputs_unfiltered (SYMBOL_NATURAL_NAME (s), buf); - fputc_unfiltered (':', buf); - } - - fputs_unfiltered (ls->label_name, buf); - need_colon = 1; - state->canonical->special_display = 1; + struct symbol *s; + + /* No function was specified, so add the symbol name. */ + gdb_assert (ls->labels.function_symbols != NULL + && (VEC_length (symbolp, ls->labels.function_symbols) + == 1)); + s = VEC_index (symbolp, ls->labels.function_symbols, 0); + explicit_loc->function_name = xstrdup (SYMBOL_NATURAL_NAME (s)); } + } - if (ls->line_offset.sign != LINE_OFFSET_UNKNOWN) - { - if (need_colon) - fputc_unfiltered (':', buf); - fprintf_filtered (buf, "%s%d", - (ls->line_offset.sign == LINE_OFFSET_NONE ? "" - : (ls->line_offset.sign - == LINE_OFFSET_PLUS ? "+" : "-")), - ls->line_offset.offset); - } + /* If this location originally came from a linespec, save a string + representation of it for display and saving to file. */ + if (state->is_linespec) + { + char *linespec = explicit_location_to_linespec (explicit_loc); - state->canonical->addr_string = ui_file_xstrdup (buf, NULL); - ui_file_delete (buf); + set_event_location_string (canon, linespec); + xfree (linespec); } } @@ -1886,22 +1849,23 @@ create_sals_line_offset (struct linespec_state *self, fullname = symtab_to_fullname (self->default_symtab); VEC_pop (symtab_ptr, ls->file_symtabs); VEC_free (symtab_ptr, ls->file_symtabs); - ls->file_symtabs = collect_symtabs_from_filename (fullname); + ls->file_symtabs = collect_symtabs_from_filename (fullname, + self->search_pspace); use_default = 1; } - val.line = ls->line_offset.offset; - switch (ls->line_offset.sign) + val.line = ls->explicit_loc.line_offset.offset; + switch (ls->explicit_loc.line_offset.sign) { case LINE_OFFSET_PLUS: - if (ls->line_offset.offset == 0) + if (ls->explicit_loc.line_offset.offset == 0) val.line = 5; if (use_default) val.line = self->default_line + val.line; break; case LINE_OFFSET_MINUS: - if (ls->line_offset.offset == 0) + if (ls->explicit_loc.line_offset.offset == 0) val.line = 15; if (use_default) val.line = self->default_line - val.line; @@ -1993,9 +1957,9 @@ create_sals_line_offset (struct linespec_state *self, if (values.nelts == 0) { - if (ls->source_filename) + if (ls->explicit_loc.source_filename) throw_error (NOT_FOUND_ERROR, _("No line %d in file \"%s\"."), - val.line, ls->source_filename); + val.line, ls->explicit_loc.source_filename); else throw_error (NOT_FOUND_ERROR, _("No line %d in the current file."), val.line); @@ -2004,6 +1968,24 @@ create_sals_line_offset (struct linespec_state *self, return values; } +/* Convert the given ADDRESS into SaLs. */ + +static struct symtabs_and_lines +convert_address_location_to_sals (struct linespec_state *self, + CORE_ADDR address) +{ + struct symtab_and_line sal; + struct symtabs_and_lines sals = {NULL, 0}; + + sal = find_pc_line (address, 0); + sal.pc = address; + sal.section = find_pc_overlay (address); + sal.explicit_pc = 1; + add_sal_to_sals (self, &sals, &sal, core_addr_to_string (address), 1); + + return sals; +} + /* Create and return SALs from the linespec LS. */ static struct symtabs_and_lines @@ -2011,18 +1993,7 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls) { struct symtabs_and_lines sals = {NULL, 0}; - if (ls->expression != NULL) - { - struct symtab_and_line sal; - - /* We have an expression. No other attribute is allowed. */ - sal = find_pc_line (ls->expr_pc, 0); - sal.pc = ls->expr_pc; - sal.section = find_pc_overlay (ls->expr_pc); - sal.explicit_pc = 1; - add_sal_to_sals (state, &sals, &sal, ls->expression, 1); - } - else if (ls->labels.label_symbols != NULL) + if (ls->labels.label_symbols != NULL) { /* We have just a bunch of functions/methods or labels. */ int i; @@ -2085,13 +2056,13 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls) } } } - else if (ls->line_offset.sign != LINE_OFFSET_UNKNOWN) + else if (ls->explicit_loc.line_offset.sign != LINE_OFFSET_UNKNOWN) { /* Only an offset was specified. */ sals = create_sals_line_offset (state, ls); /* Make sure we have a filename for canonicalization. */ - if (ls->source_filename == NULL) + if (ls->explicit_loc.source_filename == NULL) { const char *fullname = symtab_to_fullname (state->default_symtab); @@ -2099,7 +2070,7 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls) form so that displaying SOURCE_FILENAME can follow the current FILENAME_DISPLAY_STRING setting. But as it is used only rarely it has been kept for code simplicity only in absolute form. */ - ls->source_filename = xstrdup (fullname); + ls->explicit_loc.source_filename = xstrdup (fullname); } } else @@ -2116,14 +2087,80 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls) return sals; } +/* Convert the explicit location EXPLICIT_LOC into SaLs. */ + +static struct symtabs_and_lines +convert_explicit_location_to_sals (struct linespec_state *self, + linespec_p result, + const struct explicit_location *explicit_loc) +{ + VEC (symbolp) *symbols, *labels; + VEC (bound_minimal_symbol_d) *minimal_symbols; + + if (explicit_loc->source_filename != NULL) + { + TRY + { + result->file_symtabs + = symtabs_from_filename (explicit_loc->source_filename, + self->search_pspace); + } + CATCH (except, RETURN_MASK_ERROR) + { + source_file_not_found_error (explicit_loc->source_filename); + } + END_CATCH + result->explicit_loc.source_filename + = xstrdup (explicit_loc->source_filename); + } + else + { + /* A NULL entry means to use the default symtab. */ + VEC_safe_push (symtab_ptr, result->file_symtabs, NULL); + } + + if (explicit_loc->function_name != NULL) + { + find_linespec_symbols (self, result->file_symtabs, + explicit_loc->function_name, &symbols, + &minimal_symbols); + + if (symbols == NULL && minimal_symbols == NULL) + symbol_not_found_error (explicit_loc->function_name, + result->explicit_loc.source_filename); + + result->explicit_loc.function_name + = xstrdup (explicit_loc->function_name); + result->function_symbols = symbols; + result->minimal_symbols = minimal_symbols; + } + + if (explicit_loc->label_name != NULL) + { + symbols = NULL; + labels = find_label_symbols (self, result->function_symbols, + &symbols, explicit_loc->label_name); + + if (labels == NULL) + undefined_label_error (result->explicit_loc.function_name, + explicit_loc->label_name); + + result->explicit_loc.label_name = xstrdup (explicit_loc->label_name); + result->labels.label_symbols = labels; + result->labels.function_symbols = symbols; + } + + if (explicit_loc->line_offset.sign != LINE_OFFSET_UNKNOWN) + result->explicit_loc.line_offset = explicit_loc->line_offset; + + return convert_linespec_to_sals (self, result); +} + /* Parse a string that specifies a linespec. - Pass the address of a char * variable; that variable will be - advanced over the characters actually parsed. The basic grammar of linespecs: - linespec -> expr_spec | var_spec | basic_spec - expr_spec -> '*' STRING + linespec -> var_spec | basic_spec var_spec -> '$' (STRING | NUMBER) basic_spec -> file_offset_spec | function_spec | label_spec @@ -2167,10 +2204,10 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls) if no file is validly specified. Callers must check that. Also, the line number returned may be invalid. */ -/* Parse the linespec in ARGPTR. */ +/* Parse the linespec in ARG. */ static struct symtabs_and_lines -parse_linespec (linespec_parser *parser, const char **argptr) +parse_linespec (linespec_parser *parser, const char *arg) { linespec_token token; struct symtabs_and_lines values; @@ -2181,30 +2218,30 @@ parse_linespec (linespec_parser *parser, const char **argptr) IDEs to work around bugs in the previous parser by quoting the entire linespec, so we attempt to deal with this nicely. */ parser->is_quote_enclosed = 0; - if (!is_ada_operator (*argptr) - && strchr (linespec_quote_characters, **argptr) != NULL) + if (!is_ada_operator (arg) + && strchr (linespec_quote_characters, *arg) != NULL) { const char *end; - end = skip_quote_char (*argptr + 1, **argptr); + end = skip_quote_char (arg + 1, *arg); if (end != NULL && is_closing_quote_enclosed (end)) { - /* Here's the special case. Skip ARGPTR past the initial + /* Here's the special case. Skip ARG past the initial quote. */ - ++(*argptr); + ++arg; parser->is_quote_enclosed = 1; } } - parser->lexer.saved_arg = *argptr; - parser->lexer.stream = argptr; + parser->lexer.saved_arg = arg; + parser->lexer.stream = arg; /* Initialize the default symtab and line offset. */ initialize_defaults (&PARSER_STATE (parser)->default_symtab, &PARSER_STATE (parser)->default_line); /* Objective-C shortcut. */ - values = decode_objc (PARSER_STATE (parser), PARSER_RESULT (parser), argptr); + values = decode_objc (PARSER_STATE (parser), PARSER_RESULT (parser), arg); if (values.sals != NULL) return values; @@ -2214,33 +2251,7 @@ parse_linespec (linespec_parser *parser, const char **argptr) token = linespec_lexer_lex_one (parser); /* It must be either LSTOKEN_STRING or LSTOKEN_NUMBER. */ - if (token.type == LSTOKEN_STRING && *LS_TOKEN_STOKEN (token).ptr == '*') - { - char *expr; - const char *copy; - - /* User specified an expression, *EXPR. */ - copy = expr = copy_token_string (token); - cleanup = make_cleanup (xfree, expr); - PARSER_RESULT (parser)->expr_pc = linespec_expression_to_pc (©); - discard_cleanups (cleanup); - PARSER_RESULT (parser)->expression = expr; - - /* This is a little hacky/tricky. If linespec_expression_to_pc - did not evaluate the entire token, then we must find the - string COPY inside the original token buffer. */ - if (*copy != '\0') - { - PARSER_STREAM (parser) = strstr (parser->lexer.saved_arg, copy); - gdb_assert (PARSER_STREAM (parser) != NULL); - } - - /* Consume the token. */ - linespec_lexer_consume_token (parser); - - goto convert_to_sals; - } - else if (token.type == LSTOKEN_STRING && *LS_TOKEN_STOKEN (token).ptr == '$') + if (token.type == LSTOKEN_STRING && *LS_TOKEN_STOKEN (token).ptr == '$') { char *var; @@ -2250,13 +2261,13 @@ parse_linespec (linespec_parser *parser, const char **argptr) /* User specified a convenience variable or history value. */ var = copy_token_string (token); cleanup = make_cleanup (xfree, var); - PARSER_RESULT (parser)->line_offset + PARSER_EXPLICIT (parser)->line_offset = linespec_parse_variable (PARSER_STATE (parser), var); do_cleanups (cleanup); /* If a line_offset wasn't found (VAR is the name of a user variable/function), then skip to normal symbol processing. */ - if (PARSER_RESULT (parser)->line_offset.sign != LINE_OFFSET_UNKNOWN) + if (PARSER_EXPLICIT (parser)->line_offset.sign != LINE_OFFSET_UNKNOWN) { /* Consume this token. */ linespec_lexer_consume_token (parser); @@ -2283,7 +2294,8 @@ parse_linespec (linespec_parser *parser, const char **argptr) TRY { PARSER_RESULT (parser)->file_symtabs - = symtabs_from_filename (user_filename); + = symtabs_from_filename (user_filename, + PARSER_STATE (parser)->search_pspace); } CATCH (ex, RETURN_MASK_ERROR) { @@ -2294,7 +2306,7 @@ parse_linespec (linespec_parser *parser, const char **argptr) if (file_exception.reason >= 0) { /* Symtabs were found for the file. Record the filename. */ - PARSER_RESULT (parser)->source_filename = user_filename; + PARSER_EXPLICIT (parser)->source_filename = user_filename; /* Get the next token. */ token = linespec_lexer_consume_token (parser); @@ -2331,7 +2343,7 @@ parse_linespec (linespec_parser *parser, const char **argptr) if (PARSER_RESULT (parser)->function_symbols == NULL && PARSER_RESULT (parser)->labels.label_symbols == NULL - && PARSER_RESULT (parser)->line_offset.sign == LINE_OFFSET_UNKNOWN + && PARSER_EXPLICIT (parser)->line_offset.sign == LINE_OFFSET_UNKNOWN && PARSER_RESULT (parser)->minimal_symbols == NULL) { /* The linespec didn't parse. Re-throw the file exception if @@ -2340,8 +2352,8 @@ parse_linespec (linespec_parser *parser, const char **argptr) throw_exception (file_exception); /* Otherwise, the symbol is not found. */ - symbol_not_found_error (PARSER_RESULT (parser)->function_name, - PARSER_RESULT (parser)->source_filename); + symbol_not_found_error (PARSER_EXPLICIT (parser)->function_name, + PARSER_EXPLICIT (parser)->source_filename); } convert_to_sals: @@ -2365,6 +2377,7 @@ parse_linespec (linespec_parser *parser, const char **argptr) static void linespec_state_constructor (struct linespec_state *self, int flags, const struct language_defn *language, + struct program_space *search_pspace, struct symtab *default_symtab, int default_line, struct linespec_result *canonical) @@ -2373,12 +2386,14 @@ linespec_state_constructor (struct linespec_state *self, self->language = language; self->funfirstline = (flags & DECODE_LINE_FUNFIRSTLINE) ? 1 : 0; self->list_mode = (flags & DECODE_LINE_LIST_MODE) ? 1 : 0; + self->search_pspace = search_pspace; self->default_symtab = default_symtab; self->default_line = default_line; self->canonical = canonical; self->program_space = current_program_space; self->addr_set = htab_create_alloc (10, hash_address_entry, eq_address_entry, xfree, xcalloc, xfree); + self->is_linespec = 0; } /* Initialize a new linespec parser. */ @@ -2386,14 +2401,17 @@ linespec_state_constructor (struct linespec_state *self, static void linespec_parser_new (linespec_parser *parser, int flags, const struct language_defn *language, + struct program_space *search_pspace, struct symtab *default_symtab, int default_line, struct linespec_result *canonical) { + memset (parser, 0, sizeof (linespec_parser)); parser->lexer.current.type = LSTOKEN_CONSUMED; memset (PARSER_RESULT (parser), 0, sizeof (struct linespec)); - PARSER_RESULT (parser)->line_offset.sign = LINE_OFFSET_UNKNOWN; + PARSER_EXPLICIT (parser)->line_offset.sign = LINE_OFFSET_UNKNOWN; linespec_state_constructor (PARSER_STATE (parser), flags, language, + search_pspace, default_symtab, default_line, canonical); } @@ -2412,10 +2430,9 @@ linespec_parser_delete (void *arg) { linespec_parser *parser = (linespec_parser *) arg; - xfree ((char *) PARSER_RESULT (parser)->expression); - xfree ((char *) PARSER_RESULT (parser)->source_filename); - xfree ((char *) PARSER_RESULT (parser)->label_name); - xfree ((char *) PARSER_RESULT (parser)->function_name); + xfree (PARSER_EXPLICIT (parser)->source_filename); + xfree (PARSER_EXPLICIT (parser)->label_name); + xfree (PARSER_EXPLICIT (parser)->function_name); if (PARSER_RESULT (parser)->file_symtabs != NULL) VEC_free (symtab_ptr, PARSER_RESULT (parser)->file_symtabs); @@ -2435,10 +2452,117 @@ linespec_parser_delete (void *arg) linespec_state_destructor (PARSER_STATE (parser)); } +/* See description in linespec.h. */ + +void +linespec_lex_to_end (char **stringp) +{ + linespec_parser parser; + struct cleanup *cleanup; + linespec_token token; + const char *orig; + + if (stringp == NULL || *stringp == NULL) + return; + + linespec_parser_new (&parser, 0, current_language, NULL, NULL, 0, NULL); + cleanup = make_cleanup (linespec_parser_delete, &parser); + parser.lexer.saved_arg = *stringp; + PARSER_STREAM (&parser) = orig = *stringp; + + do + { + /* Stop before any comma tokens; we need it to keep it + as the next token in the string. */ + token = linespec_lexer_peek_token (&parser); + if (token.type == LSTOKEN_COMMA) + break; + token = linespec_lexer_consume_token (&parser); + } + while (token.type != LSTOKEN_EOI && token.type != LSTOKEN_KEYWORD); + + *stringp += PARSER_STREAM (&parser) - orig; + do_cleanups (cleanup); +} + +/* A helper function for decode_line_full and decode_line_1 to + turn LOCATION into symtabs_and_lines. */ + +static struct symtabs_and_lines +event_location_to_sals (linespec_parser *parser, + const struct event_location *location) +{ + struct symtabs_and_lines result = {NULL, 0}; + + switch (event_location_type (location)) + { + case LINESPEC_LOCATION: + { + PARSER_STATE (parser)->is_linespec = 1; + TRY + { + result = parse_linespec (parser, get_linespec_location (location)); + } + CATCH (except, RETURN_MASK_ERROR) + { + throw_exception (except); + } + END_CATCH + } + break; + + case ADDRESS_LOCATION: + { + const char *addr_string = get_address_string_location (location); + CORE_ADDR addr = get_address_location (location); + + if (addr_string != NULL) + { + char *expr = xstrdup (addr_string); + const char *const_expr = expr; + struct cleanup *cleanup = make_cleanup (xfree, expr); + + addr = linespec_expression_to_pc (&const_expr); + if (PARSER_STATE (parser)->canonical != NULL) + PARSER_STATE (parser)->canonical->location + = copy_event_location (location); + + do_cleanups (cleanup); + } + + result = convert_address_location_to_sals (PARSER_STATE (parser), + addr); + } + break; + + case EXPLICIT_LOCATION: + { + const struct explicit_location *explicit_loc; + + explicit_loc = get_explicit_location_const (location); + result = convert_explicit_location_to_sals (PARSER_STATE (parser), + PARSER_RESULT (parser), + explicit_loc); + } + break; + + case PROBE_LOCATION: + /* Probes are handled by their own decoders. */ + gdb_assert_not_reached ("attempt to decode probe location"); + break; + + default: + gdb_assert_not_reached ("unhandled event location type"); + } + + return result; +} + /* See linespec.h. */ void -decode_line_full (char **argptr, int flags, +decode_line_full (const struct event_location *location, int flags, + struct program_space *search_pspace, struct symtab *default_symtab, int default_line, struct linespec_result *canonical, const char *select_mode, @@ -2449,7 +2573,6 @@ decode_line_full (char **argptr, int flags, VEC (const_char_ptr) *filters = NULL; linespec_parser parser; struct linespec_state *state; - const char *copy, *orig; gdb_assert (canonical != NULL); /* The filter only makes sense for 'all'. */ @@ -2460,18 +2583,16 @@ decode_line_full (char **argptr, int flags, || select_mode == multiple_symbols_cancel); gdb_assert ((flags & DECODE_LINE_LIST_MODE) == 0); - linespec_parser_new (&parser, flags, current_language, default_symtab, + linespec_parser_new (&parser, flags, current_language, + search_pspace, default_symtab, default_line, canonical); cleanups = make_cleanup (linespec_parser_delete, &parser); save_current_program_space (); - orig = copy = *argptr; - result = parse_linespec (&parser, ©); - *argptr += copy - orig; + result = event_location_to_sals (&parser, location); state = PARSER_STATE (&parser); gdb_assert (result.nelts == 1 || canonical->pre_expanded); - gdb_assert (canonical->addr_string != NULL); canonical->pre_expanded = 1; /* Arrange for allocated canonical names to be freed. */ @@ -2515,23 +2636,22 @@ decode_line_full (char **argptr, int flags, /* See linespec.h. */ struct symtabs_and_lines -decode_line_1 (char **argptr, int flags, +decode_line_1 (const struct event_location *location, int flags, + struct program_space *search_pspace, struct symtab *default_symtab, int default_line) { struct symtabs_and_lines result; linespec_parser parser; struct cleanup *cleanups; - const char *copy, *orig; - linespec_parser_new (&parser, flags, current_language, default_symtab, + linespec_parser_new (&parser, flags, current_language, + search_pspace, default_symtab, default_line, NULL); cleanups = make_cleanup (linespec_parser_delete, &parser); save_current_program_space (); - orig = copy = *argptr; - result = parse_linespec (&parser, ©); - *argptr += copy - orig; + result = event_location_to_sals (&parser, location); do_cleanups (cleanups); return result; @@ -2544,6 +2664,8 @@ decode_line_with_current_source (char *string, int flags) { struct symtabs_and_lines sals; struct symtab_and_line cursal; + struct event_location *location; + struct cleanup *cleanup; if (string == 0) error (_("Empty line specification.")); @@ -2552,11 +2674,15 @@ decode_line_with_current_source (char *string, int flags) and get a default source symtab+line or it will recursively call us! */ cursal = get_current_source_symtab_and_line (); - sals = decode_line_1 (&string, flags, + location = string_to_event_location (&string, current_language); + cleanup = make_cleanup_delete_event_location (location); + sals = decode_line_1 (location, flags, NULL, cursal.symtab, cursal.line); if (*string) error (_("Junk at end of line specification: %s"), string); + + do_cleanups (cleanup); return sals; } @@ -2566,19 +2692,25 @@ struct symtabs_and_lines decode_line_with_last_displayed (char *string, int flags) { struct symtabs_and_lines sals; + struct event_location *location; + struct cleanup *cleanup; if (string == 0) error (_("Empty line specification.")); + location = string_to_event_location (&string, current_language); + cleanup = make_cleanup_delete_event_location (location); if (last_displayed_sal_is_valid ()) - sals = decode_line_1 (&string, flags, + sals = decode_line_1 (location, flags, NULL, get_last_displayed_symtab (), get_last_displayed_line ()); else - sals = decode_line_1 (&string, flags, (struct symtab *) NULL, 0); + sals = decode_line_1 (location, flags, NULL, (struct symtab *) NULL, 0); if (*string) error (_("Junk at end of line specification: %s"), string); + + do_cleanups (cleanup); return sals; } @@ -2608,7 +2740,7 @@ initialize_defaults (struct symtab **default_symtab, int *default_line) /* Evaluate the expression pointed to by EXP_PTR into a CORE_ADDR, advancing EXP_PTR past any parsed text. */ -static CORE_ADDR +CORE_ADDR linespec_expression_to_pc (const char **exp_ptr) { if (current_program_space->executing_startup) @@ -2631,7 +2763,7 @@ linespec_expression_to_pc (const char **exp_ptr) the existing C++ code to let the user choose one. */ static struct symtabs_and_lines -decode_objc (struct linespec_state *self, linespec_p ls, const char **argptr) +decode_objc (struct linespec_state *self, linespec_p ls, const char *arg) { struct collect_info info; VEC (const_char_ptr) *symbol_names = NULL; @@ -2649,7 +2781,7 @@ decode_objc (struct linespec_state *self, linespec_p ls, const char **argptr) values.nelts = 0; values.sals = NULL; - new_argptr = find_imps (*argptr, &symbol_names); + new_argptr = find_imps (arg, &symbol_names); if (VEC_empty (const_char_ptr, symbol_names)) { do_cleanups (cleanup); @@ -2663,28 +2795,34 @@ decode_objc (struct linespec_state *self, linespec_p ls, const char **argptr) { char *saved_arg; - saved_arg = alloca (new_argptr - *argptr + 1); - memcpy (saved_arg, *argptr, new_argptr - *argptr); - saved_arg[new_argptr - *argptr] = '\0'; + saved_arg = (char *) alloca (new_argptr - arg + 1); + memcpy (saved_arg, arg, new_argptr - arg); + saved_arg[new_argptr - arg] = '\0'; - ls->function_name = xstrdup (saved_arg); + ls->explicit_loc.function_name = xstrdup (saved_arg); ls->function_symbols = info.result.symbols; ls->minimal_symbols = info.result.minimal_symbols; values = convert_linespec_to_sals (self, ls); if (self->canonical) { + char *str; + self->canonical->pre_expanded = 1; - if (ls->source_filename) - self->canonical->addr_string - = xstrprintf ("%s:%s", ls->source_filename, saved_arg); + + if (ls->explicit_loc.source_filename) + { + str = xstrprintf ("%s:%s", + ls->explicit_loc.source_filename, saved_arg); + } else - self->canonical->addr_string = xstrdup (saved_arg); + str = xstrdup (saved_arg); + + make_cleanup (xfree, str); + self->canonical->location = new_linespec_location (&str); } } - *argptr = new_argptr; - do_cleanups (cleanup); return values; @@ -2709,7 +2847,8 @@ struct decode_compound_collector static int collect_one_symbol (struct symbol *sym, void *d) { - struct decode_compound_collector *collector = d; + struct decode_compound_collector *collector + = (struct decode_compound_collector *) d; void **slot; struct type *t; @@ -2789,8 +2928,8 @@ lookup_prefix_sym (struct linespec_state *state, VEC (symtab_ptr) *file_symtabs, static int compare_symbols (const void *a, const void *b) { - struct symbol * const *sa = a; - struct symbol * const *sb = b; + struct symbol * const *sa = (struct symbol * const*) a; + struct symbol * const *sb = (struct symbol * const*) b; uintptr_t uia, uib; uia = (uintptr_t) SYMTAB_PSPACE (symbol_symtab (*sa)); @@ -2817,8 +2956,10 @@ compare_symbols (const void *a, const void *b) static int compare_msymbols (const void *a, const void *b) { - const struct bound_minimal_symbol *sa = a; - const struct bound_minimal_symbol *sb = b; + const struct bound_minimal_symbol *sa + = (const struct bound_minimal_symbol *) a; + const struct bound_minimal_symbol *sb + = (const struct bound_minimal_symbol *) b; uintptr_t uia, uib; uia = (uintptr_t) sa->objfile->pspace; @@ -2999,7 +3140,7 @@ struct symtab_collector static int add_symtabs_to_list (struct symtab *symtab, void *d) { - struct symtab_collector *data = d; + struct symtab_collector *data = (struct symtab_collector *) d; void **slot; slot = htab_find_slot (data->symtab_table, symtab, INSERT); @@ -3012,10 +3153,13 @@ add_symtabs_to_list (struct symtab *symtab, void *d) return 0; } -/* Given a file name, return a VEC of all matching symtabs. */ +/* Given a file name, return a VEC of all matching symtabs. If + SEARCH_PSPACE is not NULL, the search is restricted to just that + program space. */ static VEC (symtab_ptr) * -collect_symtabs_from_filename (const char *file) +collect_symtabs_from_filename (const char *file, + struct program_space *search_pspace) { struct symtab_collector collector; struct cleanup *cleanups; @@ -3027,27 +3171,37 @@ collect_symtabs_from_filename (const char *file) cleanups = make_cleanup_htab_delete (collector.symtab_table); /* Find that file's data. */ - ALL_PSPACES (pspace) - { - if (pspace->executing_startup) - continue; + if (search_pspace == NULL) + { + ALL_PSPACES (pspace) + { + if (pspace->executing_startup) + continue; - set_current_program_space (pspace); - iterate_over_symtabs (file, add_symtabs_to_list, &collector); - } + set_current_program_space (pspace); + iterate_over_symtabs (file, add_symtabs_to_list, &collector); + } + } + else + { + set_current_program_space (search_pspace); + iterate_over_symtabs (file, add_symtabs_to_list, &collector); + } do_cleanups (cleanups); return collector.symtabs; } -/* Return all the symtabs associated to the FILENAME. */ +/* Return all the symtabs associated to the FILENAME. If SEARCH_PSPACE is + not NULL, the search is restricted to just that program space. */ static VEC (symtab_ptr) * -symtabs_from_filename (const char *filename) +symtabs_from_filename (const char *filename, + struct program_space *search_pspace) { VEC (symtab_ptr) *result; - result = collect_symtabs_from_filename (filename); + result = collect_symtabs_from_filename (filename, search_pspace); if (VEC_empty (symtab_ptr, result)) { @@ -3055,7 +3209,7 @@ symtabs_from_filename (const char *filename) throw_error (NOT_FOUND_ERROR, _("No symbol table is loaded. " "Use the \"file\" command.")); - throw_error (NOT_FOUND_ERROR, _("No source file named %s."), filename); + source_file_not_found_error (filename); } return result; @@ -3084,9 +3238,10 @@ find_function_symbols (struct linespec_state *state, /* Try NAME as an Objective-C selector. */ find_imps (name, &symbol_names); if (!VEC_empty (const_char_ptr, symbol_names)) - add_all_symbol_names_from_pspace (&info, NULL, symbol_names); + add_all_symbol_names_from_pspace (&info, state->search_pspace, + symbol_names); else - add_matching_symbols_to_info (name, &info, NULL); + add_matching_symbols_to_info (name, &info, state->search_pspace); do_cleanups (cleanup); @@ -3189,14 +3344,14 @@ find_linespec_symbols (struct linespec_state *state, /* LOOKUP_NAME points to the class name. LAST points to the method name. */ - klass = xmalloc ((last - lookup_name + 1) * sizeof (char)); + klass = XNEWVEC (char, last - lookup_name + 1); make_cleanup (xfree, klass); strncpy (klass, lookup_name, last - lookup_name); klass[last - lookup_name] = '\0'; /* Skip past the scope operator. */ last += strlen (scope_op); - method = xmalloc ((strlen (last) + 1) * sizeof (char)); + method = XNEWVEC (char, strlen (last) + 1); make_cleanup (xfree, method); strcpy (method, last); @@ -3254,7 +3409,7 @@ find_label_symbols (struct linespec_state *self, return NULL; fn_sym = BLOCK_FUNCTION (block); - sym = lookup_symbol (name, block, LABEL_DOMAIN, 0); + sym = lookup_symbol (name, block, LABEL_DOMAIN, 0).symbol; if (sym != NULL) { @@ -3269,7 +3424,7 @@ find_label_symbols (struct linespec_state *self, { set_current_program_space (SYMTAB_PSPACE (symbol_symtab (fn_sym))); block = SYMBOL_BLOCK_VALUE (fn_sym); - sym = lookup_symbol (name, block, LABEL_DOMAIN, 0); + sym = lookup_symbol (name, block, LABEL_DOMAIN, 0).symbol; if (sym != NULL) { @@ -3422,7 +3577,7 @@ linespec_parse_variable (struct linespec_state *self, const char *variable) static int collect_symbols (struct symbol *sym, void *data) { - struct collect_info *info = data; + struct collect_info *info = (struct collect_info *) data; /* In list mode, add all matching symbols, regardless of class. This allows the user to type "list a_global_variable". */ @@ -3469,6 +3624,8 @@ minsym_found (struct linespec_state *self, struct objfile *objfile, sal.pc = MSYMBOL_VALUE_ADDRESS (objfile, msymbol); sal.pc = gdbarch_convert_from_func_ptr_addr (gdbarch, sal.pc, ¤t_target); + if (gdbarch_skip_entrypoint_p (gdbarch)) + sal.pc = gdbarch_skip_entrypoint (gdbarch, sal.pc); } else skip_prologue_sal (&sal); @@ -3528,8 +3685,8 @@ classify_mtype (enum minimal_symbol_type t) static int compare_msyms (const void *a, const void *b) { - const bound_minimal_symbol_d *moa = a; - const bound_minimal_symbol_d *mob = b; + const bound_minimal_symbol_d *moa = (const bound_minimal_symbol_d *) a; + const bound_minimal_symbol_d *mob = (const bound_minimal_symbol_d *) b; enum minimal_symbol_type ta = MSYMBOL_TYPE (moa->minsym); enum minimal_symbol_type tb = MSYMBOL_TYPE (mob->minsym); @@ -3542,7 +3699,7 @@ compare_msyms (const void *a, const void *b) static void add_minsym (struct minimal_symbol *minsym, void *d) { - struct collect_minsyms *info = d; + struct collect_minsyms *info = (struct collect_minsyms *) d; bound_minimal_symbol_d mo; mo.minsym = minsym; @@ -3782,7 +3939,7 @@ destroy_linespec_result (struct linespec_result *ls) int i; struct linespec_sals *lsal; - xfree (ls->addr_string); + delete_event_location (ls->location); for (i = 0; VEC_iterate (linespec_sals, ls->sals, i, lsal); ++i) { xfree (lsal->canonical); @@ -3796,7 +3953,7 @@ destroy_linespec_result (struct linespec_result *ls) static void cleanup_linespec_result (void *a) { - destroy_linespec_result (a); + destroy_linespec_result ((struct linespec_result *) a); } /* See the comment in linespec.h. */ @@ -3806,3 +3963,11 @@ make_cleanup_destroy_linespec_result (struct linespec_result *ls) { return make_cleanup (cleanup_linespec_result, ls); } + +/* Return the quote characters permitted by the linespec parser. */ + +const char * +get_gdb_linespec_parser_quote_characters (void) +{ + return linespec_quote_characters; +}