]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/parse.c
sim: bfin: initial bf60x support
[thirdparty/binutils-gdb.git] / gdb / parse.c
index 29d7bf172f8995b6d96c67e7b5fda54cb1fcb2cb..b57d112fafd9515ff9d2ea09af6e0be7ccdd2d74 100644 (file)
@@ -41,7 +41,7 @@
 #include "language.h"
 #include "parser-defs.h"
 #include "gdbcmd.h"
-#include "symfile.h"           /* for overlay functions */
+#include "symfile.h"
 #include "inferior.h"
 #include "target-float.h"
 #include "block.h"
@@ -49,7 +49,7 @@
 #include "objfiles.h"
 #include "user-regs.h"
 #include <algorithm>
-#include "gdbsupport/gdb_optional.h"
+#include <optional>
 #include "c-exp.h"
 
 static unsigned int expressiondebug = 0;
@@ -62,7 +62,7 @@ show_expressiondebug (struct ui_file *file, int from_tty,
 
 
 /* True if an expression parser should set yydebug.  */
-bool parser_debug;
+static bool parser_debug;
 
 static void
 show_parserdebug (struct ui_file *file, int from_tty,
@@ -72,12 +72,6 @@ show_parserdebug (struct ui_file *file, int from_tty,
 }
 
 
-static expression_up parse_exp_in_context
-     (const char **, CORE_ADDR,
-      const struct block *, int,
-      bool, innermost_block_tracker *,
-      std::unique_ptr<expr_completion_base> *);
-
 /* Documented at it's declaration.  */
 
 void
@@ -86,92 +80,12 @@ innermost_block_tracker::update (const struct block *b,
 {
   if ((m_types & t) != 0
       && (m_innermost_block == NULL
-         || contained_in (b, m_innermost_block)))
+         || m_innermost_block->contains (b)))
     m_innermost_block = b;
 }
 
 \f
 
-/* Return the type of MSYMBOL, a minimal symbol of OBJFILE.  If
-   ADDRESS_P is not NULL, set it to the MSYMBOL's resolved
-   address.  */
-
-type *
-find_minsym_type_and_address (minimal_symbol *msymbol,
-                             struct objfile *objfile,
-                             CORE_ADDR *address_p)
-{
-  bound_minimal_symbol bound_msym = {msymbol, objfile};
-  struct obj_section *section = msymbol->obj_section (objfile);
-  enum minimal_symbol_type type = msymbol->type ();
-
-  bool is_tls = (section != NULL
-                && section->the_bfd_section->flags & SEC_THREAD_LOCAL);
-
-  /* The minimal symbol might point to a function descriptor;
-     resolve it to the actual code address instead.  */
-  CORE_ADDR addr;
-  if (is_tls)
-    {
-      /* Addresses of TLS symbols are really offsets into a
-        per-objfile/per-thread storage block.  */
-      addr = bound_msym.minsym->value_raw_address ();
-    }
-  else if (msymbol_is_function (objfile, msymbol, &addr))
-    {
-      if (addr != bound_msym.value_address ())
-       {
-         /* This means we resolved a function descriptor, and we now
-            have an address for a code/text symbol instead of a data
-            symbol.  */
-         if (msymbol->type () == mst_data_gnu_ifunc)
-           type = mst_text_gnu_ifunc;
-         else
-           type = mst_text;
-         section = NULL;
-       }
-    }
-  else
-    addr = bound_msym.value_address ();
-
-  if (overlay_debugging)
-    addr = symbol_overlayed_address (addr, section);
-
-  if (is_tls)
-    {
-      /* Skip translation if caller does not need the address.  */
-      if (address_p != NULL)
-       *address_p = target_translate_tls_address (objfile, addr);
-      return objfile_type (objfile)->nodebug_tls_symbol;
-    }
-
-  if (address_p != NULL)
-    *address_p = addr;
-
-  switch (type)
-    {
-    case mst_text:
-    case mst_file_text:
-    case mst_solib_trampoline:
-      return objfile_type (objfile)->nodebug_text_symbol;
-
-    case mst_text_gnu_ifunc:
-      return objfile_type (objfile)->nodebug_text_gnu_ifunc_symbol;
-
-    case mst_data:
-    case mst_file_data:
-    case mst_bss:
-    case mst_file_bss:
-      return objfile_type (objfile)->nodebug_data_symbol;
-
-    case mst_slot_got_plt:
-      return objfile_type (objfile)->nodebug_got_plt_symbol;
-
-    default:
-      return objfile_type (objfile)->nodebug_unknown_symbol;
-    }
-}
-
 bool
 expr_complete_tag::complete (struct expression *exp,
                             completion_tracker &tracker)
@@ -268,7 +182,8 @@ parser_state::push_dollar (struct stoken str)
     {
       /* Just dollars (one or two).  */
       i = -negate;
-      goto handle_last;
+      push_new<expr::last_operation> (i);
+      return;
     }
   /* Is the rest of the token digits?  */
   for (; i < str.length; i++)
@@ -279,7 +194,8 @@ parser_state::push_dollar (struct stoken str)
       i = atoi (str.ptr + 1 + negate);
       if (negate)
        i = -i;
-      goto handle_last;
+      push_new<expr::last_operation> (i);
+      return;
     }
 
   /* Handle tokens that refer to machine registers:
@@ -287,7 +203,14 @@ parser_state::push_dollar (struct stoken str)
   i = user_reg_map_name_to_regnum (gdbarch (),
                                   str.ptr + 1, str.length - 1);
   if (i >= 0)
-    goto handle_register;
+    {
+      str.length--;
+      str.ptr++;
+      push_new<expr::register_operation> (copy_name (str));
+      block_tracker->update (expression_context_block,
+                            INNERMOST_BLOCK_FOR_REGISTERS);
+      return;
+    }
 
   /* Any names starting with $ are probably debugger internal variables.  */
 
@@ -319,17 +242,6 @@ parser_state::push_dollar (struct stoken str)
 
   push_new<expr::internalvar_operation>
     (create_internalvar (copy.c_str () + 1));
-  return;
-handle_last:
-  push_new<expr::last_operation> (i);
-  return;
-handle_register:
-  str.length--;
-  str.ptr++;
-  push_new<expr::register_operation> (copy_name (str));
-  block_tracker->update (expression_context_block,
-                        INNERMOST_BLOCK_FOR_REGISTERS);
-  return;
 }
 
 \f
@@ -410,31 +322,13 @@ copy_name (struct stoken token)
 }
 \f
 
-/* Read an expression from the string *STRINGPTR points to,
-   parse it, and return a pointer to a struct expression that we malloc.
-   Use block BLOCK as the lexical context for variable names;
-   if BLOCK is zero, use the block of the selected stack frame.
-   Meanwhile, advance *STRINGPTR to point after the expression,
-   at the first nonwhite character that is not part of the expression
-   (possibly a null character).
-
-   If COMMA is nonzero, stop if a comma is reached.  */
-
-expression_up
-parse_exp_1 (const char **stringptr, CORE_ADDR pc, const struct block *block,
-            int comma, innermost_block_tracker *tracker)
-{
-  return parse_exp_in_context (stringptr, pc, block, comma, false,
-                              tracker, nullptr);
-}
-
 /* As for parse_exp_1, except that if VOID_CONTEXT_P, then
    no value is expected from the expression.  */
 
 static expression_up
 parse_exp_in_context (const char **stringptr, CORE_ADDR pc,
                      const struct block *block,
-                     int comma, bool void_context_p,
+                     parser_flags flags,
                      innermost_block_tracker *tracker,
                      std::unique_ptr<expr_completion_base> *completer)
 {
@@ -450,26 +344,31 @@ parse_exp_in_context (const char **stringptr, CORE_ADDR pc,
   if (tracker == nullptr)
     tracker = &local_tracker;
 
-  /* If no context specified, try using the current frame, if any.  */
-  if (!expression_context_block)
-    expression_context_block = get_selected_block (&expression_context_pc);
-  else if (pc == 0)
-    expression_context_pc = expression_context_block->entry_pc ();
-  else
-    expression_context_pc = pc;
+  if ((flags & PARSER_LEAVE_BLOCK_ALONE) == 0)
+    {
+      /* If no context specified, try using the current frame, if any.  */
+      if (!expression_context_block)
+       expression_context_block
+         = get_selected_block (&expression_context_pc);
+      else if (pc == 0)
+       expression_context_pc = expression_context_block->entry_pc ();
+      else
+       expression_context_pc = pc;
 
-  /* Fall back to using the current source static context, if any.  */
+      /* Fall back to using the current source static context, if any.  */
 
-  if (!expression_context_block)
-    {
-      struct symtab_and_line cursal = get_current_source_symtab_and_line ();
+      if (!expression_context_block)
+       {
+         struct symtab_and_line cursal
+           = get_current_source_symtab_and_line ();
 
-      if (cursal.symtab)
-       expression_context_block
-         = cursal.symtab->compunit ()->blockvector ()->static_block ();
+         if (cursal.symtab)
+           expression_context_block
+             = cursal.symtab->compunit ()->blockvector ()->static_block ();
 
-      if (expression_context_block)
-       expression_context_pc = expression_context_block->entry_pc ();
+         if (expression_context_block)
+           expression_context_pc = expression_context_block->entry_pc ();
+       }
     }
 
   if (language_mode == language_mode_auto && block != NULL)
@@ -488,7 +387,7 @@ parse_exp_in_context (const char **stringptr, CORE_ADDR pc,
         the current frame language to parse the expression.  That's why
         we do the following language detection only if the context block
         has been specifically provided.  */
-      struct symbol *func = block_linkage_function (block);
+      struct symbol *func = block->linkage_function ();
 
       if (func != NULL)
        lang = language_def (func->language ());
@@ -504,8 +403,8 @@ parse_exp_in_context (const char **stringptr, CORE_ADDR pc,
      to the value matching SELECTED_FRAME as set by get_current_arch.  */
 
   parser_state ps (lang, get_current_arch (), expression_context_block,
-                  expression_context_pc, comma, *stringptr,
-                  completer != nullptr, tracker, void_context_p);
+                  expression_context_pc, flags, *stringptr,
+                  completer != nullptr, tracker);
 
   scoped_restore_current_language lang_saver;
   set_language (lang->la_language);
@@ -514,7 +413,7 @@ parse_exp_in_context (const char **stringptr, CORE_ADDR pc,
     {
       lang->parser (&ps);
     }
-  catch (const gdb_exception &except)
+  catch (const gdb_exception_error &except)
     {
       /* If parsing for completion, allow this to succeed; but if no
         expression elements have been written, then there's nothing
@@ -535,19 +434,31 @@ parse_exp_in_context (const char **stringptr, CORE_ADDR pc,
   return result;
 }
 
+/* Read an expression from the string *STRINGPTR points to,
+   parse it, and return a pointer to a struct expression that we malloc.
+   Use block BLOCK as the lexical context for variable names;
+   if BLOCK is zero, use the block of the selected stack frame.
+   Meanwhile, advance *STRINGPTR to point after the expression,
+   at the first nonwhite character that is not part of the expression
+   (possibly a null character).  FLAGS are passed to the parser.  */
+
+expression_up
+parse_exp_1 (const char **stringptr, CORE_ADDR pc, const struct block *block,
+            parser_flags flags, innermost_block_tracker *tracker)
+{
+  return parse_exp_in_context (stringptr, pc, block, flags,
+                              tracker, nullptr);
+}
+
 /* Parse STRING as an expression, and complain if this fails to use up
    all of the contents of STRING.  TRACKER, if non-null, will be
-   updated by the parser.  VOID_CONTEXT_P should be true to indicate
-   that the expression may be expected to return a value with void
-   type.  Parsers are free to ignore this, or to use it to help with
-   overload resolution decisions.  */
+   updated by the parser.  FLAGS are passed to the parser.  */
 
 expression_up
 parse_expression (const char *string, innermost_block_tracker *tracker,
-                 bool void_context_p)
+                 parser_flags flags)
 {
-  expression_up exp = parse_exp_in_context (&string, 0, nullptr, 0,
-                                           void_context_p,
+  expression_up exp = parse_exp_in_context (&string, 0, nullptr, flags,
                                            tracker, nullptr);
   if (*string)
     error (_("Junk after end of expression."));
@@ -560,7 +471,7 @@ parse_expression (const char *string, innermost_block_tracker *tracker,
 expression_up
 parse_expression_with_language (const char *string, enum language lang)
 {
-  gdb::optional<scoped_restore_current_language> lang_saver;
+  std::optional<scoped_restore_current_language> lang_saver;
   if (current_language->la_language != lang)
     {
       lang_saver.emplace ();
@@ -583,7 +494,7 @@ parse_expression_for_completion
 
   try
     {
-      exp = parse_exp_in_context (&string, 0, 0, 0, false, nullptr, completer);
+      exp = parse_exp_in_context (&string, 0, 0, 0, nullptr, completer);
     }
   catch (const gdb_exception_error &except)
     {
@@ -648,6 +559,32 @@ fits_in_type (int n_sign, ULONGEST n, int type_bits, bool type_signed_p)
   else
     gdb_assert_not_reached ("");
 }
+
+/* Return true if the number N_SIGN * N fits in a type with TYPE_BITS and
+   TYPE_SIGNED_P.  N_SIGNED is either 1 or -1.  */
+
+bool
+fits_in_type (int n_sign, const gdb_mpz &n, int type_bits, bool type_signed_p)
+{
+  /* N must be nonnegative.  */
+  gdb_assert (n.sgn () >= 0);
+
+  /* Zero always fits.  */
+  /* Normalize -0.  */
+  if (n.sgn () == 0)
+    return true;
+
+  if (n_sign == -1 && !type_signed_p)
+    /* Can't fit a negative number in an unsigned type.  */
+    return false;
+
+  gdb_mpz max = gdb_mpz::pow (2, (type_signed_p
+                                 ? type_bits - 1
+                                 : type_bits));
+  if (n_sign == -1)
+    return n <= max;
+  return n < max;
+}
 \f
 /* This function avoids direct calls to fprintf 
    in the parser generated debug code.  */
@@ -667,18 +604,6 @@ parser_fprintf (FILE *x, const char *y, ...)
   va_end (args);
 }
 
-/* Return rue if EXP uses OBJFILE (and will become dangling when
-   OBJFILE is unloaded), otherwise return false.  OBJFILE must not be
-   a separate debug info file.  */
-
-bool
-exp_uses_objfile (struct expression *exp, struct objfile *objfile)
-{
-  gdb_assert (objfile->separate_debug_objfile_backlink == NULL);
-
-  return exp->op->uses_objfile (objfile);
-}
-
 void _initialize_parse ();
 void
 _initialize_parse ()