Explicit locations: introduce new struct event_location-based API
[binutils-gdb.git] / gdb / linespec.c
index 82384cab6207efb62d632abf48741e74beea6e3d..5c4ed3f3ea9d04189299e3aae54541339692d0b0 100644 (file)
@@ -1,6 +1,6 @@
 /* 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.
 
@@ -246,6 +246,7 @@ typedef enum ls_token_type linespec_token_type;
 /* List of keywords  */
 
 static const char * const linespec_keywords[] = { "if", "thread", "task" };
+#define IF_KEYWORD_INDEX 0
 
 /* A token of the linespec lexer  */
 
@@ -290,11 +291,6 @@ struct ls_parser
   /* 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)
@@ -418,10 +414,9 @@ linespec_lexer_lex_number (linespec_parser *parser, linespec_token *tokenp)
   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;
@@ -433,11 +428,34 @@ linespec_lexer_lex_keyword (const char *p)
          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];
+           }
        }
     }
 
@@ -454,8 +472,7 @@ is_ada_operator (const char *string)
 
   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);
@@ -735,13 +752,16 @@ linespec_lexer_lex_one (linespec_parser *parser)
       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;
        }
 
@@ -1028,7 +1048,7 @@ iterate_over_all_matching_symtabs (struct linespec_state *state,
       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)
@@ -1109,7 +1129,7 @@ find_methods (struct type *t, const char *name,
     {
       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
@@ -1122,9 +1142,9 @@ find_methods (struct type *t, const char *name,
          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;
@@ -1210,7 +1230,7 @@ find_toplevel_string (const char *haystack, const char *needle)
       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
@@ -2011,7 +2031,7 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls)
 
       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))
@@ -2038,7 +2058,7 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls)
 
          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))
@@ -2154,7 +2174,7 @@ parse_linespec (linespec_parser *parser, const char **argptr)
 {
   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
@@ -2176,13 +2196,8 @@ parse_linespec (linespec_parser *parser, const char **argptr)
        }
     }
 
-  /* 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,
@@ -2252,9 +2267,6 @@ parse_linespec (linespec_parser *parser, const char **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);
@@ -2268,11 +2280,16 @@ parse_linespec (linespec_parser *parser, const char **argptr)
       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)
        {
@@ -2418,6 +2435,54 @@ 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;
+  volatile struct gdb_exception e;
+  const char *orig;
+
+  if (stringp == NULL || *stringp == NULL)
+    return;
+
+  linespec_parser_new (&parser, 0, current_language, 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;
+
+      /* For addresses advance the parser stream past
+        any parsed input and stop lexing.  */
+      if (token.type == LSTOKEN_STRING
+         && *LS_TOKEN_STOKEN (token).ptr == '*')
+       {
+         const char *arg;
+
+         arg = *stringp;
+         (void) linespec_expression_to_pc (&arg);
+         PARSER_STREAM (&parser) = arg;
+         break;
+       }
+
+      token = linespec_lexer_consume_token (&parser);
+    }
+  while (token.type != LSTOKEN_EOI && token.type != LSTOKEN_KEYWORD);
+
+  *stringp += PARSER_STREAM (&parser) - orig;
+  do_cleanups (cleanup);
+}
+
 /* See linespec.h.  */
 
 void
@@ -2700,7 +2765,7 @@ collect_one_symbol (struct symbol *sym, void *d)
     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)
@@ -2776,8 +2841,8 @@ compare_symbols (const void *a, const void *b)
   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;
@@ -2921,8 +2986,8 @@ find_method (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs,
 
       /* 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);
@@ -2931,7 +2996,7 @@ find_method (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs,
         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
@@ -3103,7 +3168,6 @@ find_linespec_symbols (struct linespec_state *state,
   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);
@@ -3191,7 +3255,7 @@ find_linespec_symbols (struct linespec_state *state,
       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);
@@ -3199,8 +3263,12 @@ find_linespec_symbols (struct linespec_state *state,
 
          /* 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
        }
     }
 
@@ -3234,7 +3302,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)
        {
@@ -3247,9 +3315,9 @@ find_label_symbols (struct linespec_state *self,
       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);
+         sym = lookup_symbol (name, block, LABEL_DOMAIN, 0).symbol;
 
          if (sym != NULL)
            {
@@ -3412,7 +3480,9 @@ collect_symbols (struct symbol *sym, void *data)
 }
 
 /* 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,
@@ -3434,7 +3504,23 @@ 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,
+                                                      &current_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);
@@ -3448,6 +3534,9 @@ struct collect_minsyms
   /* The objfile we're examining.  */
   struct objfile *objfile;
 
+  /* Only search the given symtab, or NULL to search for all symbols.  */
+  struct symtab *symtab;
+
   /* The funfirstline setting from the initial call.  */
   int funfirstline;
 
@@ -3507,6 +3596,24 @@ add_minsym (struct minimal_symbol *minsym, void *d)
   mo.minsym = minsym;
   mo.objfile = info->objfile;
 
+  if (info->symtab != NULL)
+    {
+      CORE_ADDR pc;
+      struct symtab_and_line sal;
+      struct gdbarch *gdbarch = get_objfile_arch (info->objfile);
+
+      sal = find_pc_sect_line (MSYMBOL_VALUE_ADDRESS (info->objfile, minsym),
+                              NULL, 0);
+      sal.section = MSYMBOL_OBJ_SECTION (info->objfile, minsym);
+      pc
+       = gdbarch_convert_from_func_ptr_addr (gdbarch, sal.pc, &current_target);
+      if (pc != sal.pc)
+       sal = find_pc_sect_line (pc, NULL, 0);
+
+      if (info->symtab != sal.symtab)
+       return;
+    }
+
   /* Exclude data symbols when looking for breakpoint locations.   */
   if (!info->list_mode)
     switch (minsym->type)
@@ -3533,40 +3640,59 @@ add_minsym (struct minimal_symbol *minsym, void *d)
   VEC_safe_push (bound_minimal_symbol_d, info->msyms, &mo);
 }
 
-/* Search minimal symbols in all objfiles for NAME.  If SEARCH_PSPACE
+/* Search for minimal symbols called NAME.  If SEARCH_PSPACE
    is not NULL, the search is restricted to just that program
-   space.  */
+   space.
+
+   If SYMTAB is NULL, search all objfiles, otherwise
+   restrict results to the given SYMTAB.  */
 
 static void
 search_minsyms_for_name (struct collect_info *info, const char *name,
-                        struct program_space *search_pspace)
+                        struct program_space *search_pspace,
+                        struct symtab *symtab)
 {
-  struct objfile *objfile;
-  struct program_space *pspace;
+  struct collect_minsyms local;
+  struct cleanup *cleanup;
 
-  ALL_PSPACES (pspace)
-  {
-    struct collect_minsyms local;
-    struct cleanup *cleanup;
+  memset (&local, 0, sizeof (local));
+  local.funfirstline = info->state->funfirstline;
+  local.list_mode = info->state->list_mode;
+  local.symtab = symtab;
 
-    if (search_pspace != NULL && search_pspace != pspace)
-      continue;
-    if (pspace->executing_startup)
-      continue;
+  cleanup = make_cleanup (VEC_cleanup (bound_minimal_symbol_d), &local.msyms);
 
-    set_current_program_space (pspace);
+  if (symtab == NULL)
+    {
+      struct program_space *pspace;
 
-    memset (&local, 0, sizeof (local));
-    local.funfirstline = info->state->funfirstline;
-    local.list_mode = info->state->list_mode;
+      ALL_PSPACES (pspace)
+      {
+       struct objfile *objfile;
 
-    cleanup = make_cleanup (VEC_cleanup (bound_minimal_symbol_d),
-                           &local.msyms);
+       if (search_pspace != NULL && search_pspace != pspace)
+         continue;
+       if (pspace->executing_startup)
+         continue;
 
-    ALL_OBJFILES (objfile)
+       set_current_program_space (pspace);
+
+       ALL_OBJFILES (objfile)
+       {
+         local.objfile = objfile;
+         iterate_over_minimal_symbols (objfile, name, add_minsym, &local);
+       }
+      }
+    }
+  else
     {
-      local.objfile = objfile;
-      iterate_over_minimal_symbols (objfile, name, add_minsym, &local);
+      if (search_pspace == NULL || SYMTAB_PSPACE (symtab) == search_pspace)
+       {
+         set_current_program_space (SYMTAB_PSPACE (symtab));
+         local.objfile = SYMTAB_OBJFILE(symtab);
+         iterate_over_minimal_symbols (local.objfile, name, add_minsym,
+                                       &local);
+       }
     }
 
     if (!VEC_empty (bound_minimal_symbol_d, local.msyms))
@@ -3599,7 +3725,6 @@ search_minsyms_for_name (struct collect_info *info, const char *name,
       }
 
     do_cleanups (cleanup);
-  }
 }
 
 /* A helper function to add all symbols matching NAME to INFO.  If
@@ -3621,16 +3746,26 @@ add_matching_symbols_to_info (const char *name,
          iterate_over_all_matching_symtabs (info->state, name, VAR_DOMAIN,
                                             collect_symbols, info,
                                             pspace, 1);
-         search_minsyms_for_name (info, name, pspace);
+         search_minsyms_for_name (info, name, pspace, NULL);
        }
       else if (pspace == NULL || pspace == SYMTAB_PSPACE (elt))
        {
+         int prev_len = VEC_length (symbolp, info->result.symbols);
+
          /* Program spaces that are executing startup should have
             been filtered out earlier.  */
          gdb_assert (!SYMTAB_PSPACE (elt)->executing_startup);
          set_current_program_space (SYMTAB_PSPACE (elt));
          iterate_over_file_blocks (elt, name, VAR_DOMAIN,
                                    collect_symbols, info);
+
+         /* If no new symbols were found in this iteration and this symtab
+            is in assembler, we might actually be looking for a label for
+            which we don't have debug info.  Check for a minimal symbol in
+            this case.  */
+         if (prev_len == VEC_length (symbolp, info->result.symbols)
+             && elt->language == language_asm)
+           search_minsyms_for_name (info, name, pspace, elt);
        }
     }
 }
@@ -3654,10 +3789,10 @@ symbol_to_sal (struct symtab_and_line *result,
       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;
        }
@@ -3669,9 +3804,9 @@ symbol_to_sal (struct symtab_and_line *result,
        {
          /* 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;
        }
     }