/* 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];
+ }
}
}
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;
}
{
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
}
}
- /* 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;
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);
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)
}
/* 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);