/* Parser for linespec for the GNU debugger, GDB.
- Copyright (C) 1986-2014 Free Software Foundation, Inc.
+ Copyright (C) 1986-2015 Free Software Foundation, Inc.
This file is part of GDB.
/* List of keywords */
static const char * const linespec_keywords[] = { "if", "thread", "task" };
+#define IF_KEYWORD_INDEX 0
/* A token of the linespec lexer */
/* Is the entire linespec quote-enclosed? */
int is_quote_enclosed;
- /* Is a keyword syntactically valid at this point?
- In, e.g., "break thread thread 1", the leading "keyword" must not
- be interpreted as such. */
- int keyword_ok;
-
/* The state of the parse. */
struct linespec_state state;
#define PARSER_STATE(PPTR) (&(PPTR)->state)
return 1;
}
-/* Does P represent one of the keywords? If so, return
- the keyword. If not, return NULL. */
+/* See linespec.h. */
-static const char *
+const char *
linespec_lexer_lex_keyword (const char *p)
{
int i;
int len = strlen (linespec_keywords[i]);
/* If P begins with one of the keywords and the next
- character is not a valid identifier character,
- we have found a keyword. */
+ character is whitespace, we may have found a keyword.
+ It is only a keyword if it is not followed by another
+ keyword. */
if (strncmp (p, linespec_keywords[i], len) == 0
- && !(isalnum (p[len]) || p[len] == '_'))
- return linespec_keywords[i];
+ && isspace (p[len]))
+ {
+ int j;
+
+ /* Special case: "if" ALWAYS stops the lexer, since it
+ is not possible to predict what is going to appear in
+ the condition, which can only be parsed after SaLs have
+ been found. */
+ if (i != IF_KEYWORD_INDEX)
+ {
+ p += len;
+ p = skip_spaces_const (p);
+ for (j = 0; j < ARRAY_SIZE (linespec_keywords); ++j)
+ {
+ int nextlen = strlen (linespec_keywords[j]);
+
+ if (strncmp (p, linespec_keywords[j], nextlen) == 0
+ && isspace (p[nextlen]))
+ return NULL;
+ }
+ }
+
+ return linespec_keywords[i];
+ }
}
}
for (mapping = ada_opname_table;
mapping->encoded != NULL
- && strncmp (mapping->decoded, string,
- strlen (mapping->decoded)) != 0; ++mapping)
+ && !startswith (string, mapping->decoded); ++mapping)
;
return mapping->decoded == NULL ? 0 : strlen (mapping->decoded);
PARSER_STREAM (parser) = skip_spaces_const (PARSER_STREAM (parser));
/* Check for a keyword, they end the linespec. */
- keyword = NULL;
- if (parser->keyword_ok)
- keyword = linespec_lexer_lex_keyword (PARSER_STREAM (parser));
+ keyword = linespec_lexer_lex_keyword (PARSER_STREAM (parser));
if (keyword != NULL)
{
parser->lexer.current.type = LSTOKEN_KEYWORD;
LS_TOKEN_KEYWORD (parser->lexer.current) = keyword;
+ /* We do not advance the stream here intentionally:
+ we would like lexing to stop when a keyword is seen.
+
+ PARSER_STREAM (parser) += strlen (keyword); */
+
return parser->lexer.current;
}
if (objfile->sf)
objfile->sf->qf->expand_symtabs_matching (objfile, NULL,
iterate_name_matcher,
- ALL_DOMAIN,
+ NULL, ALL_DOMAIN,
&matcher_data);
ALL_OBJFILE_COMPUNITS (objfile, cu)
{
int method_counter;
- CHECK_TYPEDEF (t);
+ t = check_typedef (t);
/* Loop over each method name. At this level, all overloads of a name
are counted as a single name. There is an inner loop which loops over
const char *method_name = TYPE_FN_FIELDLIST_NAME (t, method_counter);
char dem_opname[64];
- if (strncmp (method_name, "__", 2) == 0 ||
- strncmp (method_name, "op", 2) == 0 ||
- strncmp (method_name, "type", 4) == 0)
+ if (startswith (method_name, "__") ||
+ startswith (method_name, "op") ||
+ startswith (method_name, "type"))
{
if (cplus_demangle_opname (method_name, dem_opname, DMGL_ANSI))
method_name = dem_opname;
if (s != NULL)
{
/* Found first char in HAYSTACK; check rest of string. */
- if (strncmp (s, needle, strlen (needle)) == 0)
+ if (startswith (s, needle))
return s;
/* Didn't find it; loop over HAYSTACK, looking for the next
for (i = 0; VEC_iterate (symbolp, ls->labels.label_symbols, i, sym); ++i)
{
- struct program_space *pspace = SYMTAB_PSPACE (SYMBOL_SYMTAB (sym));
+ struct program_space *pspace = SYMTAB_PSPACE (symbol_symtab (sym));
if (symbol_to_sal (&sal, state->funfirstline, sym)
&& maybe_add_address (state->addr_set, pspace, sal.pc))
for (i = 0; VEC_iterate (symbolp, ls->function_symbols, i, sym); ++i)
{
- pspace = SYMTAB_PSPACE (SYMBOL_SYMTAB (sym));
+ pspace = SYMTAB_PSPACE (symbol_symtab (sym));
set_current_program_space (pspace);
if (symbol_to_sal (&sal, state->funfirstline, sym)
&& maybe_add_address (state->addr_set, pspace, sal.pc))
{
linespec_token token;
struct symtabs_and_lines values;
- volatile struct gdb_exception file_exception;
+ struct gdb_exception file_exception = exception_none;
struct cleanup *cleanup;
/* A special case to start. It has become quite popular for
}
}
- /* A keyword at the start cannot be interpreted as such.
- Consider "b thread thread 42". */
- parser->keyword_ok = 0;
-
parser->lexer.saved_arg = *argptr;
parser->lexer.stream = argptr;
- file_exception.reason = 0;
/* Initialize the default symtab and line offset. */
initialize_defaults (&PARSER_STATE (parser)->default_symtab,
else if (token.type != LSTOKEN_STRING && token.type != LSTOKEN_NUMBER)
unexpected_linespec_error (parser);
- /* Now we can recognize keywords. */
- parser->keyword_ok = 1;
-
/* Shortcut: If the next token is not LSTOKEN_COLON, we know that
this token cannot represent a filename. */
token = linespec_lexer_peek_token (parser);
user_filename = copy_token_string (token);
/* Check if the input is a filename. */
- TRY_CATCH (file_exception, RETURN_MASK_ERROR)
+ TRY
{
PARSER_RESULT (parser)->file_symtabs
= symtabs_from_filename (user_filename);
}
+ CATCH (ex, RETURN_MASK_ERROR)
+ {
+ file_exception = ex;
+ }
+ END_CATCH
if (file_exception.reason >= 0)
{
return 1; /* Continue iterating. */
t = SYMBOL_TYPE (sym);
- CHECK_TYPEDEF (t);
+ t = check_typedef (t);
if (TYPE_CODE (t) != TYPE_CODE_STRUCT
&& TYPE_CODE (t) != TYPE_CODE_UNION
&& TYPE_CODE (t) != TYPE_CODE_NAMESPACE)
struct symbol * const *sb = b;
uintptr_t uia, uib;
- uia = (uintptr_t) SYMTAB_PSPACE (SYMBOL_SYMTAB (*sa));
- uib = (uintptr_t) SYMTAB_PSPACE (SYMBOL_SYMTAB (*sb));
+ uia = (uintptr_t) SYMTAB_PSPACE (symbol_symtab (*sa));
+ uib = (uintptr_t) SYMTAB_PSPACE (symbol_symtab (*sb));
if (uia < uib)
return -1;
/* Program spaces that are executing startup should have
been filtered out earlier. */
- gdb_assert (!SYMTAB_PSPACE (SYMBOL_SYMTAB (sym))->executing_startup);
- pspace = SYMTAB_PSPACE (SYMBOL_SYMTAB (sym));
+ pspace = SYMTAB_PSPACE (symbol_symtab (sym));
+ gdb_assert (!pspace->executing_startup);
set_current_program_space (pspace);
t = check_typedef (SYMBOL_TYPE (sym));
find_methods (t, method_name, &result_names, &superclass_vec);
sure not to miss the last batch. */
if (ix == VEC_length (symbolp, sym_classes) - 1
|| (pspace
- != SYMTAB_PSPACE (SYMBOL_SYMTAB (VEC_index (symbolp, sym_classes,
+ != SYMTAB_PSPACE (symbol_symtab (VEC_index (symbolp, sym_classes,
ix + 1)))))
{
/* If we did not find a direct implementation anywhere in
struct cleanup *cleanup;
char *canon;
const char *lookup_name;
- volatile struct gdb_exception except;
cleanup = demangle_for_lookup (name, state->language->la_language,
&lookup_name);
if (!VEC_empty (symbolp, classes))
{
/* Now locate a list of suitable methods named METHOD. */
- TRY_CATCH (except, RETURN_MASK_ERROR)
+ TRY
{
find_method (state, file_symtabs, klass, method, classes,
symbols, minsyms);
/* If successful, we're done. If NOT_FOUND_ERROR
was not thrown, rethrow the exception that we did get. */
- if (except.reason < 0 && except.error != NOT_FOUND_ERROR)
- throw_exception (except);
+ CATCH (except, RETURN_MASK_ERROR)
+ {
+ if (except.error != NOT_FOUND_ERROR)
+ throw_exception (except);
+ }
+ END_CATCH
}
}
for (ix = 0;
VEC_iterate (symbolp, function_symbols, ix, fn_sym); ++ix)
{
- set_current_program_space (SYMTAB_PSPACE (SYMBOL_SYMTAB (fn_sym)));
+ set_current_program_space (SYMTAB_PSPACE (symbol_symtab (fn_sym)));
block = SYMBOL_BLOCK_VALUE (fn_sym);
sym = lookup_symbol (name, block, LABEL_DOMAIN, 0);
}
/* We've found a minimal symbol MSYMBOL in OBJFILE to associate with our
- linespec; return the SAL in RESULT. */
+ linespec; return the SAL in RESULT. This function should return SALs
+ matching those from find_function_start_sal, otherwise false
+ multiple-locations breakpoints could be placed. */
static void
minsym_found (struct linespec_state *self, struct objfile *objfile,
sal = find_pc_sect_line (pc, NULL, 0);
if (self->funfirstline)
- skip_prologue_sal (&sal);
+ {
+ if (sal.symtab != NULL
+ && (COMPUNIT_LOCATIONS_VALID (SYMTAB_COMPUNIT (sal.symtab))
+ || SYMTAB_LANGUAGE (sal.symtab) == language_asm))
+ {
+ /* If gdbarch_convert_from_func_ptr_addr does not apply then
+ sal.SECTION, sal.LINE&co. will stay correct from above.
+ If gdbarch_convert_from_func_ptr_addr applies then
+ sal.SECTION is cleared from above and sal.LINE&co. will
+ stay correct from the last find_pc_sect_line above. */
+ sal.pc = MSYMBOL_VALUE_ADDRESS (objfile, msymbol);
+ sal.pc = gdbarch_convert_from_func_ptr_addr (gdbarch, sal.pc,
+ ¤t_target);
+ }
+ else
+ skip_prologue_sal (&sal);
+ }
if (maybe_add_address (self->addr_set, objfile->pspace, sal.pc))
add_sal_to_sals (self, result, &sal, MSYMBOL_NATURAL_NAME (msymbol), 0);
if (SYMBOL_CLASS (sym) == LOC_LABEL && SYMBOL_VALUE_ADDRESS (sym) != 0)
{
init_sal (result);
- result->symtab = SYMBOL_SYMTAB (sym);
+ result->symtab = symbol_symtab (sym);
result->line = SYMBOL_LINE (sym);
result->pc = SYMBOL_VALUE_ADDRESS (sym);
- result->pspace = SYMTAB_PSPACE (SYMBOL_SYMTAB (sym));
+ result->pspace = SYMTAB_PSPACE (result->symtab);
result->explicit_pc = 1;
return 1;
}
{
/* We know its line number. */
init_sal (result);
- result->symtab = SYMBOL_SYMTAB (sym);
+ result->symtab = symbol_symtab (sym);
result->line = SYMBOL_LINE (sym);
- result->pspace = SYMTAB_PSPACE (SYMBOL_SYMTAB (sym));
+ result->pspace = SYMTAB_PSPACE (result->symtab);
return 1;
}
}