[gdb/symtab] Add get/set functions for per_cu->lang/unit_type
[binutils-gdb.git] / gdb / ada-lang.c
index bb9a16f8fe07ad1fe9d4e0d5b8dc3b74163889f2..93e0c67613f0a927416d5618abacce71013b65de 100644 (file)
@@ -4711,12 +4711,13 @@ cache_symbol (const char *name, domain_enum domain, struct symbol *sym,
      for that symbol depends on the context.  To determine whether
      the symbol is local or not, we check the block where we found it
      against the global and static blocks of its associated symtab.  */
-  if (sym
-      && BLOCKVECTOR_BLOCK (sym->symtab ()->compunit ()->blockvector (),
-                           GLOBAL_BLOCK) != block
-      && BLOCKVECTOR_BLOCK (sym->symtab ()->compunit ()->blockvector (),
-                           STATIC_BLOCK) != block)
-    return;
+  if (sym != nullptr)
+    {
+      const blockvector &bv = *sym->symtab ()->compunit ()->blockvector ();
+
+      if (bv.global_block () != block && bv.static_block () != block)
+       return;
+    }
 
   h = msymbol_hash (name) % HASH_SIZE;
   e = XOBNEW (&sym_cache->cache_space, cache_entry);
@@ -5331,10 +5332,10 @@ ada_add_local_symbols (std::vector<struct block_symbol> &result,
       /* If we found a non-function match, assume that's the one.  We
         only check this when finding a function boundary, so that we
         can accumulate all results from intervening blocks first.  */
-      if (BLOCK_FUNCTION (block) != nullptr && is_nonfunction (result))
+      if (block->function () != nullptr && is_nonfunction (result))
        return;
 
-      block = BLOCK_SUPERBLOCK (block);
+      block = block->superblock ();
     }
 }
 
@@ -5563,7 +5564,7 @@ map_matching_symbols (struct objfile *objfile,
   for (compunit_symtab *symtab : objfile->compunits ())
     {
       const struct block *block
-       = BLOCKVECTOR_BLOCK (symtab->blockvector (), block_kind);
+       = symtab->blockvector ()->block (block_kind);
       if (!iterate_over_symbols_terminated (block, lookup_name,
                                            domain, data))
        break;
@@ -5592,7 +5593,7 @@ add_nonlocal_symbols (std::vector<struct block_symbol> &result,
       for (compunit_symtab *cu : objfile->compunits ())
        {
          const struct block *global_block
-           = BLOCKVECTOR_BLOCK (cu->blockvector (), GLOBAL_BLOCK);
+           = cu->blockvector ()->global_block ();
 
          if (ada_add_block_renamings (result, global_block, lookup_name,
                                       domain))
@@ -6491,7 +6492,8 @@ ada_tag_value_at_base_address (struct value *obj)
       tem = value_cast (ptr_type, tem);
       offset_to_top = value_as_long (value_ind (tem));
     }
-  else if (offset_to_top > 0)
+
+  if (offset_to_top > 0)
     {
       /* OFFSET_TO_TOP used to be a positive value to be subtracted
         from the base address.  This was however incompatible with
@@ -11968,8 +11970,7 @@ ada_unhandled_exception_name_addr_from_raise (void)
    Return zero if the address could not be computed, or if not relevant.  */
 
 static CORE_ADDR
-ada_exception_name_addr_1 (enum ada_exception_catchpoint_kind ex,
-                          struct breakpoint *b)
+ada_exception_name_addr_1 (enum ada_exception_catchpoint_kind ex)
 {
   struct ada_inferior_data *data = get_ada_inferior_data (current_inferior ());
 
@@ -12067,14 +12068,13 @@ ada_exception_message (void)
    and zero is returned.  */
 
 static CORE_ADDR
-ada_exception_name_addr (enum ada_exception_catchpoint_kind ex,
-                        struct breakpoint *b)
+ada_exception_name_addr (enum ada_exception_catchpoint_kind ex)
 {
   CORE_ADDR result = 0;
 
   try
     {
-      result = ada_exception_name_addr_1 (ex, b);
+      result = ada_exception_name_addr_1 (ex);
     }
 
   catch (const gdb_exception_error &e)
@@ -12103,13 +12103,74 @@ static std::string ada_exception_catchpoint_cond_string
    exception, in order to be able to re-set the condition expression
    when symbols change.  */
 
+/* An instance of this type is used to represent an Ada catchpoint.  */
+
+struct ada_catchpoint : public code_breakpoint
+{
+  ada_catchpoint (struct gdbarch *gdbarch_,
+                 enum ada_exception_catchpoint_kind kind,
+                 struct symtab_and_line sal,
+                 const char *addr_string_,
+                 bool tempflag,
+                 bool enabled,
+                 bool from_tty)
+    : code_breakpoint (gdbarch_, bp_catchpoint),
+      m_kind (kind)
+  {
+    add_location (sal);
+
+    /* Unlike most code_breakpoint types, Ada catchpoints are
+       pspace-specific.  */
+    gdb_assert (sal.pspace != nullptr);
+    this->pspace = sal.pspace;
+
+    if (from_tty)
+      {
+       struct gdbarch *loc_gdbarch = get_sal_arch (sal);
+       if (!loc_gdbarch)
+         loc_gdbarch = gdbarch;
+
+       describe_other_breakpoints (loc_gdbarch,
+                                   sal.pspace, sal.pc, sal.section, -1);
+       /* FIXME: brobecker/2006-12-28: Actually, re-implement a special
+          version for exception catchpoints, because two catchpoints
+          used for different exception names will use the same address.
+          In this case, a "breakpoint ... also set at..." warning is
+          unproductive.  Besides, the warning phrasing is also a bit
+          inappropriate, we should use the word catchpoint, and tell
+          the user what type of catchpoint it is.  The above is good
+          enough for now, though.  */
+      }
+
+    enable_state = enabled ? bp_enabled : bp_disabled;
+    disposition = tempflag ? disp_del : disp_donttouch;
+    locspec = string_to_location_spec (&addr_string_,
+                                      language_def (language_ada));
+    language = language_ada;
+  }
+
+  struct bp_location *allocate_location () override;
+  void re_set () override;
+  void check_status (struct bpstat *bs) override;
+  enum print_stop_action print_it (const bpstat *bs) const override;
+  bool print_one (bp_location **) const override;
+  void print_mention () const override;
+  void print_recreate (struct ui_file *fp) const override;
+
+  /* The name of the specific exception the user specified.  */
+  std::string excep_string;
+
+  /* What kind of catchpoint this is.  */
+  enum ada_exception_catchpoint_kind m_kind;
+};
+
 /* An instance of this type is used to represent an Ada catchpoint
    breakpoint location.  */
 
 class ada_catchpoint_location : public bp_location
 {
 public:
-  ada_catchpoint_location (breakpoint *owner)
+  explicit ada_catchpoint_location (ada_catchpoint *owner)
     : bp_location (owner, bp_loc_software_breakpoint)
   {}
 
@@ -12119,22 +12180,6 @@ public:
   expression_up excep_cond_expr;
 };
 
-/* An instance of this type is used to represent an Ada catchpoint.  */
-
-struct ada_catchpoint : public breakpoint
-{
-  explicit ada_catchpoint (enum ada_exception_catchpoint_kind kind)
-    : m_kind (kind)
-  {
-  }
-
-  /* The name of the specific exception the user specified.  */
-  std::string excep_string;
-
-  /* What kind of catchpoint this is.  */
-  enum ada_exception_catchpoint_kind m_kind;
-};
-
 /* Parse the exception condition string in the context of each of the
    catchpoint's locations, and store them for later evaluation.  */
 
@@ -12186,30 +12231,28 @@ create_excep_cond_exprs (struct ada_catchpoint *c,
     }
 }
 
-/* Implement the ALLOCATE_LOCATION method in the breakpoint_ops
-   structure for all exception catchpoint kinds.  */
+/* Implement the ALLOCATE_LOCATION method in the structure for all
+   exception catchpoint kinds.  */
 
-static struct bp_location *
-allocate_location_exception (struct breakpoint *self)
+struct bp_location *
+ada_catchpoint::allocate_location ()
 {
-  return new ada_catchpoint_location (self);
+  return new ada_catchpoint_location (this);
 }
 
-/* Implement the RE_SET method in the breakpoint_ops structure for all
-   exception catchpoint kinds.  */
+/* Implement the RE_SET method in the structure for all exception
+   catchpoint kinds.  */
 
-static void
-re_set_exception (struct breakpoint *b)
+void
+ada_catchpoint::re_set ()
 {
-  struct ada_catchpoint *c = (struct ada_catchpoint *) b;
-
   /* Call the base class's method.  This updates the catchpoint's
      locations.  */
-  bkpt_breakpoint_ops.re_set (b);
+  this->code_breakpoint::re_set ();
 
   /* Reparse the exception conditional expressions.  One for each
      location.  */
-  create_excep_cond_exprs (c, c->m_kind);
+  create_excep_cond_exprs (this, m_kind);
 }
 
 /* Returns true if we should stop for this breakpoint hit.  If the
@@ -12277,36 +12320,35 @@ should_stop_exception (const struct bp_location *bl)
   return stop;
 }
 
-/* Implement the CHECK_STATUS method in the breakpoint_ops structure
-   for all exception catchpoint kinds.  */
+/* Implement the CHECK_STATUS method in the structure for all
+   exception catchpoint kinds.  */
 
-static void
-check_status_exception (bpstat *bs)
+void
+ada_catchpoint::check_status (bpstat *bs)
 {
   bs->stop = should_stop_exception (bs->bp_location_at.get ());
 }
 
-/* Implement the PRINT_IT method in the breakpoint_ops structure
-   for all exception catchpoint kinds.  */
+/* Implement the PRINT_IT method in the structure for all exception
+   catchpoint kinds.  */
 
-static enum print_stop_action
-print_it_exception (bpstat *bs)
+enum print_stop_action
+ada_catchpoint::print_it (const bpstat *bs) const
 {
   struct ui_out *uiout = current_uiout;
-  struct breakpoint *b = bs->breakpoint_at;
 
-  annotate_catchpoint (b->number);
+  annotate_catchpoint (number);
 
   if (uiout->is_mi_like_p ())
     {
       uiout->field_string ("reason",
                           async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
-      uiout->field_string ("disp", bpdisp_text (b->disposition));
+      uiout->field_string ("disp", bpdisp_text (disposition));
     }
 
-  uiout->text (b->disposition == disp_del
+  uiout->text (disposition == disp_del
               ? "\nTemporary catchpoint " : "\nCatchpoint ");
-  uiout->field_signed ("bkptno", b->number);
+  uiout->field_signed ("bkptno", number);
   uiout->text (", ");
 
   /* ada_exception_name_addr relies on the selected frame being the
@@ -12316,14 +12358,13 @@ print_it_exception (bpstat *bs)
      ada_find_printable_frame).  */
   select_frame (get_current_frame ());
 
-  struct ada_catchpoint *c = (struct ada_catchpoint *) b;
-  switch (c->m_kind)
+  switch (m_kind)
     {
       case ada_catch_exception:
       case ada_catch_exception_unhandled:
       case ada_catch_handlers:
        {
-         const CORE_ADDR addr = ada_exception_name_addr (c->m_kind, b);
+         const CORE_ADDR addr = ada_exception_name_addr (m_kind);
          char exception_name[256];
 
          if (addr != 0)
@@ -12347,7 +12388,7 @@ print_it_exception (bpstat *bs)
             it clearer to the user which kind of catchpoint just got
             hit.  We used ui_out_text to make sure that this extra
             info does not pollute the exception name in the MI case.  */
-         if (c->m_kind == ada_catch_exception_unhandled)
+         if (m_kind == ada_catch_exception_unhandled)
            uiout->text ("unhandled ");
          uiout->field_string ("exception-name", exception_name);
        }
@@ -12376,14 +12417,13 @@ print_it_exception (bpstat *bs)
   return PRINT_SRC_AND_LOC;
 }
 
-/* Implement the PRINT_ONE method in the breakpoint_ops structure
-   for all exception catchpoint kinds.  */
+/* Implement the PRINT_ONE method in the structure for all exception
+   catchpoint kinds.  */
 
-static void
-print_one_exception (struct breakpoint *b, struct bp_location **last_loc)
+bool
+ada_catchpoint::print_one (bp_location **last_loc) const
 { 
   struct ui_out *uiout = current_uiout;
-  struct ada_catchpoint *c = (struct ada_catchpoint *) b;
   struct value_print_options opts;
 
   get_user_print_options (&opts);
@@ -12392,13 +12432,13 @@ print_one_exception (struct breakpoint *b, struct bp_location **last_loc)
     uiout->field_skip ("addr");
 
   annotate_field (5);
-  switch (c->m_kind)
+  switch (m_kind)
     {
       case ada_catch_exception:
-       if (!c->excep_string.empty ())
+       if (!excep_string.empty ())
          {
            std::string msg = string_printf (_("`%s' Ada exception"),
-                                            c->excep_string.c_str ());
+                                            excep_string.c_str ());
 
            uiout->field_string ("what", msg);
          }
@@ -12412,11 +12452,11 @@ print_one_exception (struct breakpoint *b, struct bp_location **last_loc)
        break;
       
       case ada_catch_handlers:
-       if (!c->excep_string.empty ())
+       if (!excep_string.empty ())
          {
            uiout->field_fmt ("what",
                              _("`%s' Ada exception handlers"),
-                             c->excep_string.c_str ());
+                             excep_string.c_str ());
          }
        else
          uiout->field_string ("what", "all Ada exceptions handlers");
@@ -12430,29 +12470,30 @@ print_one_exception (struct breakpoint *b, struct bp_location **last_loc)
        internal_error (__FILE__, __LINE__, _("unexpected catchpoint type"));
        break;
     }
+
+  return true;
 }
 
 /* Implement the PRINT_MENTION method in the breakpoint_ops structure
    for all exception catchpoint kinds.  */
 
-static void
-print_mention_exception (struct breakpoint *b)
+void
+ada_catchpoint::print_mention () const
 {
-  struct ada_catchpoint *c = (struct ada_catchpoint *) b;
   struct ui_out *uiout = current_uiout;
 
-  uiout->text (b->disposition == disp_del ? _("Temporary catchpoint ")
+  uiout->text (disposition == disp_del ? _("Temporary catchpoint ")
                                                 : _("Catchpoint "));
-  uiout->field_signed ("bkptno", b->number);
+  uiout->field_signed ("bkptno", number);
   uiout->text (": ");
 
-  switch (c->m_kind)
+  switch (m_kind)
     {
       case ada_catch_exception:
-       if (!c->excep_string.empty ())
+       if (!excep_string.empty ())
          {
            std::string info = string_printf (_("`%s' Ada exception"),
-                                             c->excep_string.c_str ());
+                                             excep_string.c_str ());
            uiout->text (info);
          }
        else
@@ -12464,11 +12505,11 @@ print_mention_exception (struct breakpoint *b)
        break;
 
       case ada_catch_handlers:
-       if (!c->excep_string.empty ())
+       if (!excep_string.empty ())
          {
            std::string info
              = string_printf (_("`%s' Ada exception handlers"),
-                              c->excep_string.c_str ());
+                              excep_string.c_str ());
            uiout->text (info);
          }
        else
@@ -12485,20 +12526,18 @@ print_mention_exception (struct breakpoint *b)
     }
 }
 
-/* Implement the PRINT_RECREATE method in the breakpoint_ops structure
-   for all exception catchpoint kinds.  */
+/* Implement the PRINT_RECREATE method in the structure for all
+   exception catchpoint kinds.  */
 
-static void
-print_recreate_exception (struct breakpoint *b, struct ui_file *fp)
+void
+ada_catchpoint::print_recreate (struct ui_file *fp) const
 {
-  struct ada_catchpoint *c = (struct ada_catchpoint *) b;
-
-  switch (c->m_kind)
+  switch (m_kind)
     {
       case ada_catch_exception:
        gdb_printf (fp, "catch exception");
-       if (!c->excep_string.empty ())
-         gdb_printf (fp, " %s", c->excep_string.c_str ());
+       if (!excep_string.empty ())
+         gdb_printf (fp, " %s", excep_string.c_str ());
        break;
 
       case ada_catch_exception_unhandled:
@@ -12516,18 +12555,15 @@ print_recreate_exception (struct breakpoint *b, struct ui_file *fp)
       default:
        internal_error (__FILE__, __LINE__, _("unexpected catchpoint type"));
     }
-  print_recreate_thread (b, fp);
+  print_recreate_thread (fp);
 }
 
-/* Virtual table for breakpoint type.  */
-static struct breakpoint_ops catch_exception_breakpoint_ops;
-
 /* See ada-lang.h.  */
 
 bool
 is_ada_exception_catchpoint (breakpoint *bp)
 {
-  return bp->ops == &catch_exception_breakpoint_ops;
+  return dynamic_cast<ada_catchpoint *> (bp) != nullptr;
 }
 
 /* Split the arguments specified in a "catch exception" command.  
@@ -12707,7 +12743,7 @@ ada_exception_catchpoint_cond_string (const char *excep_string,
 
 static struct symtab_and_line
 ada_exception_sal (enum ada_exception_catchpoint_kind ex,
-                  std::string *addr_string, const struct breakpoint_ops **ops)
+                  std::string *addr_string)
 {
   const char *sym_name;
   struct symbol *sym;
@@ -12729,9 +12765,6 @@ ada_exception_sal (enum ada_exception_catchpoint_kind ex,
   /* Set ADDR_STRING.  */
   *addr_string = sym_name;
 
-  /* Set OPS.  */
-  *ops = &catch_exception_breakpoint_ops;
-
   return find_function_start_sal (sym, 1);
 }
 
@@ -12760,12 +12793,11 @@ create_ada_exception_catchpoint (struct gdbarch *gdbarch,
                                 int from_tty)
 {
   std::string addr_string;
-  const struct breakpoint_ops *ops = NULL;
-  struct symtab_and_line sal = ada_exception_sal (ex_kind, &addr_string, &ops);
+  struct symtab_and_line sal = ada_exception_sal (ex_kind, &addr_string);
 
-  std::unique_ptr<ada_catchpoint> c (new ada_catchpoint (ex_kind));
-  init_ada_exception_breakpoint (c.get (), gdbarch, sal, addr_string.c_str (),
-                                ops, tempflag, disabled, from_tty);
+  std::unique_ptr<ada_catchpoint> c
+    (new ada_catchpoint (gdbarch, ex_kind, sal, addr_string.c_str (),
+                        tempflag, disabled, from_tty));
   c->excep_string = excep_string;
   create_excep_cond_exprs (c.get (), ex_kind);
   if (!cond_string.empty ())
@@ -13038,9 +13070,9 @@ ada_add_exceptions_from_frame (compiled_regex *preg,
                }
            }
        }
-      if (BLOCK_FUNCTION (block) != NULL)
+      if (block->function () != NULL)
        break;
-      block = BLOCK_SUPERBLOCK (block);
+      block = block->superblock ();
     }
 }
 
@@ -13099,7 +13131,7 @@ ada_add_global_exceptions (compiled_regex *preg,
 
          for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++)
            {
-             const struct block *b = BLOCKVECTOR_BLOCK (bv, i);
+             const struct block *b = bv->block (i);
              struct block_iterator iter;
              struct symbol *sym;
 
@@ -13662,9 +13694,9 @@ public:
     /* Search upwards from currently selected frame (so that we can
        complete on local vars.  */
 
-    for (b = get_selected_block (0); b != NULL; b = BLOCK_SUPERBLOCK (b))
+    for (b = get_selected_block (0); b != NULL; b = b->superblock ())
       {
-       if (!BLOCK_SUPERBLOCK (b))
+       if (!b->superblock ())
          surrounding_static_block = b;   /* For elmin of dups */
 
        ALL_BLOCK_SYMBOLS (b, iter, sym)
@@ -13687,7 +13719,7 @@ public:
        for (compunit_symtab *s : objfile->compunits ())
          {
            QUIT;
-           b = BLOCKVECTOR_BLOCK (s->blockvector (), GLOBAL_BLOCK);
+           b = s->blockvector ()->global_block ();
            ALL_BLOCK_SYMBOLS (b, iter, sym)
              {
                if (completion_skip_symbol (mode, sym))
@@ -13706,7 +13738,7 @@ public:
        for (compunit_symtab *s : objfile->compunits ())
          {
            QUIT;
-           b = BLOCKVECTOR_BLOCK (s->blockvector (), STATIC_BLOCK);
+           b = s->blockvector ()->static_block ();
            /* Don't do this block twice.  */
            if (b == surrounding_static_block)
              continue;
@@ -13880,24 +13912,6 @@ static ada_language ada_language_defn;
 static struct cmd_list_element *set_ada_list;
 static struct cmd_list_element *show_ada_list;
 
-static void
-initialize_ada_catchpoint_ops (void)
-{
-  struct breakpoint_ops *ops;
-
-  initialize_breakpoint_ops ();
-
-  ops = &catch_exception_breakpoint_ops;
-  *ops = bkpt_breakpoint_ops;
-  ops->allocate_location = allocate_location_exception;
-  ops->re_set = re_set_exception;
-  ops->check_status = check_status_exception;
-  ops->print_it = print_it_exception;
-  ops->print_one = print_one_exception;
-  ops->print_mention = print_mention_exception;
-  ops->print_recreate = print_recreate_exception;
-}
-
 /* This module's 'new_objfile' observer.  */
 
 static void
@@ -13938,8 +13952,6 @@ void _initialize_ada_language ();
 void
 _initialize_ada_language ()
 {
-  initialize_ada_catchpoint_ops ();
-
   add_setshow_prefix_cmd
     ("ada", no_class,
      _("Prefix command for changing Ada-specific settings."),