Convert generic probe interface to C++ (and perform some cleanups)
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index d139747200e5be858a1529dab9421a603815579b..b48c405b08491a80008498e9e19d193abc8b0907 100644 (file)
@@ -1,6 +1,6 @@
 /* Everything about breakpoints, for GDB.
 
-   Copyright (C) 1986-2016 Free Software Foundation, Inc.
+   Copyright (C) 1986-2017 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -44,7 +44,6 @@
 #include "source.h"
 #include "linespec.h"
 #include "completer.h"
-#include "gdb.h"
 #include "ui-out.h"
 #include "cli/cli-script.h"
 #include "block.h"
@@ -67,7 +66,6 @@
 #include "dummy-frame.h"
 #include "interps.h"
 #include "format.h"
-#include "location.h"
 #include "thread-fsm.h"
 #include "tid-parse.h"
 
@@ -81,6 +79,9 @@
 #include "mi/mi-common.h"
 #include "extension.h"
 #include <algorithm>
+#include "progspace-and-thread.h"
+#include "common/array-view.h"
+#include "common/gdb_optional.h"
 
 /* Enums for exception-handling support.  */
 enum exception_event_kind
@@ -92,24 +93,8 @@ enum exception_event_kind
 
 /* Prototypes for local functions.  */
 
-static void enable_delete_command (char *, int);
-
-static void enable_once_command (char *, int);
-
-static void enable_count_command (char *, int);
-
-static void disable_command (char *, int);
-
-static void enable_command (char *, int);
-
 static void map_breakpoint_numbers (const char *,
-                                   void (*) (struct breakpoint *,
-                                             void *),
-                                   void *);
-
-static void ignore_command (char *, int);
-
-static int breakpoint_re_set_one (void *);
+                                   gdb::function_view<void (breakpoint *)>);
 
 static void breakpoint_re_set_default (struct breakpoint *);
 
@@ -120,25 +105,20 @@ static void
 
 static void create_breakpoints_sal_default (struct gdbarch *,
                                            struct linespec_result *,
-                                           char *, char *, enum bptype,
+                                           gdb::unique_xmalloc_ptr<char>,
+                                           gdb::unique_xmalloc_ptr<char>,
+                                           enum bptype,
                                            enum bpdisp, int, int,
                                            int,
                                            const struct breakpoint_ops *,
                                            int, int, int, unsigned);
 
-static void decode_location_default (struct breakpoint *b,
-                                    const struct event_location *location,
-                                    struct program_space *search_pspace,
-                                    struct symtabs_and_lines *sals);
-
-static void clear_command (char *, int);
-
-static void catch_command (char *, int);
+static std::vector<symtab_and_line> decode_location_default
+  (struct breakpoint *b, const struct event_location *location,
+   struct program_space *search_pspace);
 
 static int can_use_hardware_watchpoint (struct value *);
 
-static void break_command_1 (char *, int, int);
-
 static void mention (struct breakpoint *);
 
 static struct breakpoint *set_raw_breakpoint_without_location (struct gdbarch *,
@@ -174,37 +154,18 @@ static int watchpoint_locations_match (struct bp_location *loc1,
                                       struct bp_location *loc2);
 
 static int breakpoint_location_address_match (struct bp_location *bl,
-                                             struct address_space *aspace,
+                                             const struct address_space *aspace,
                                              CORE_ADDR addr);
 
 static int breakpoint_location_address_range_overlap (struct bp_location *,
-                                                     struct address_space *,
+                                                     const address_space *,
                                                      CORE_ADDR, int);
 
-static void breakpoints_info (char *, int);
-
-static void watchpoints_info (char *, int);
-
-static int breakpoint_1 (char *, int, 
-                        int (*) (const struct breakpoint *));
-
-static int breakpoint_cond_eval (void *);
-
-static void cleanup_executing_breakpoints (void *);
-
-static void commands_command (char *, int);
-
-static void condition_command (char *, int);
-
 static int remove_breakpoint (struct bp_location *);
 static int remove_breakpoint_1 (struct bp_location *, enum remove_bp_reason);
 
 static enum print_stop_action print_bp_stop_message (bpstat bs);
 
-static int watchpoint_check (void *);
-
-static void maintenance_info_breakpoints (char *, int);
-
 static int hw_breakpoint_used_count (void);
 
 static int hw_watchpoint_use_count (struct breakpoint *);
@@ -213,21 +174,9 @@ static int hw_watchpoint_used_count_others (struct breakpoint *except,
                                            enum bptype type,
                                            int *other_type_used);
 
-static void hbreak_command (char *, int);
-
-static void thbreak_command (char *, int);
-
 static void enable_breakpoint_disp (struct breakpoint *, enum bpdisp,
                                    int count);
 
-static void stop_command (char *arg, int from_tty);
-
-static void stopin_command (char *arg, int from_tty);
-
-static void stopat_command (char *arg, int from_tty);
-
-static void tcatch_command (char *arg, int from_tty);
-
 static void free_bp_location (struct bp_location *loc);
 static void incref_bp_location (struct bp_location *loc);
 static void decref_bp_location (struct bp_location **loc);
@@ -277,15 +226,7 @@ static int is_hardware_watchpoint (const struct breakpoint *bpt);
 
 static void insert_breakpoint_locations (void);
 
-static void tracepoints_info (char *, int);
-
-static void delete_trace_command (char *, int);
-
-static void enable_trace_command (char *, int);
-
-static void disable_trace_command (char *, int);
-
-static void trace_pass_command (char *, int);
+static void trace_pass_command (const char *, int);
 
 static void set_tracepoint_count (int num);
 
@@ -309,9 +250,6 @@ static struct breakpoint_ops internal_breakpoint_ops;
 /* Momentary breakpoints class type.  */
 static struct breakpoint_ops momentary_breakpoint_ops;
 
-/* Momentary breakpoints for bp_longjmp and bp_exception class type.  */
-static struct breakpoint_ops longjmp_breakpoint_ops;
-
 /* The breakpoint_ops structure to be used in regular user created
    breakpoints.  */
 struct breakpoint_ops bkpt_breakpoint_ops;
@@ -345,7 +283,7 @@ static const char *dprintf_style = dprintf_style_gdb;
    copied into the command, so it can be anything that GDB can
    evaluate to a callable address, not necessarily a function name.  */
 
-static char *dprintf_function = "";
+static char *dprintf_function;
 
 /* The channel to use for dynamic printf if the preferred style is to
    call into the inferior; if a nonempty string, it will be passed to
@@ -355,27 +293,16 @@ static char *dprintf_function = "";
    "stderr", this could be an app-specific expression like
    "mystreams[curlogger]".  */
 
-static char *dprintf_channel = "";
+static char *dprintf_channel;
 
 /* True if dprintf commands should continue to operate even if GDB
    has disconnected.  */
 static int disconnected_dprintf = 1;
 
-/* A reference-counted struct command_line.  This lets multiple
-   breakpoints share a single command list.  */
-struct counted_command_line
-{
-  /* The reference count.  */
-  int refc;
-
-  /* The command list.  */
-  struct command_line *commands;
-};
-
 struct command_line *
 breakpoint_commands (struct breakpoint *b)
 {
-  return b->commands ? b->commands->commands : NULL;
+  return b->commands ? b->commands.get () : NULL;
 }
 
 /* Flag indicating that a command has proceeded the inferior past the
@@ -552,8 +479,6 @@ gdb_evaluates_breakpoint_condition_p (void)
   return (mode == condition_evaluation_host);
 }
 
-void _initialize_breakpoint (void);
-
 /* Are we executing breakpoint commands?  */
 static int executing_breakpoint_commands;
 
@@ -579,8 +504,8 @@ int target_exact_watchpoints = 0;
    while executing the block of ALL_BP_LOCATIONS.  */
 
 #define ALL_BP_LOCATIONS(B,BP_TMP)                                     \
-       for (BP_TMP = bp_location                                     \
-            BP_TMP < bp_location + bp_location_count && (B = *BP_TMP); \
+       for (BP_TMP = bp_locations;                                     \
+            BP_TMP < bp_locations + bp_locations_count && (B = *BP_TMP);\
             BP_TMP++)
 
 /* Iterates through locations with address ADDRESS for the currently selected
@@ -593,7 +518,7 @@ int target_exact_watchpoints = 0;
        for (BP_LOCP_START = BP_LOCP_START == NULL ? get_first_locp_gte_addr (ADDRESS) : BP_LOCP_START, \
             BP_LOCP_TMP = BP_LOCP_START;                               \
             BP_LOCP_START                                              \
-            && (BP_LOCP_TMP < bp_location + bp_location_count          \
+            && (BP_LOCP_TMP < bp_locations + bp_locations_count        \
             && (*BP_LOCP_TMP)->address == ADDRESS);                    \
             BP_LOCP_TMP++)
 
@@ -607,33 +532,33 @@ int target_exact_watchpoints = 0;
 
 struct breakpoint *breakpoint_chain;
 
-/* Array is sorted by bp_location_compare - primarily by the ADDRESS.  */
+/* Array is sorted by bp_locations_compare - primarily by the ADDRESS.  */
 
-static struct bp_location **bp_location;
+static struct bp_location **bp_locations;
 
-/* Number of elements of BP_LOCATION.  */
+/* Number of elements of BP_LOCATIONS.  */
 
-static unsigned bp_location_count;
+static unsigned bp_locations_count;
 
 /* Maximum alignment offset between bp_target_info.PLACED_ADDRESS and
-   ADDRESS for the current elements of BP_LOCATION which get a valid
+   ADDRESS for the current elements of BP_LOCATIONS which get a valid
    result from bp_location_has_shadow.  You can use it for roughly
-   limiting the subrange of BP_LOCATION to scan for shadow bytes for
+   limiting the subrange of BP_LOCATIONS to scan for shadow bytes for
    an address you need to read.  */
 
-static CORE_ADDR bp_location_placed_address_before_address_max;
+static CORE_ADDR bp_locations_placed_address_before_address_max;
 
 /* Maximum offset plus alignment between bp_target_info.PLACED_ADDRESS
    + bp_target_info.SHADOW_LEN and ADDRESS for the current elements of
-   BP_LOCATION which get a valid result from bp_location_has_shadow.
-   You can use it for roughly limiting the subrange of BP_LOCATION to
+   BP_LOCATIONS which get a valid result from bp_location_has_shadow.
+   You can use it for roughly limiting the subrange of BP_LOCATIONS to
    scan for shadow bytes for an address you need to read.  */
 
-static CORE_ADDR bp_location_shadow_len_after_address_max;
+static CORE_ADDR bp_locations_shadow_len_after_address_max;
 
 /* The locations that no longer correspond to any breakpoint, unlinked
-   from bp_location array, but for which a hit may still be reported
-   by a target.  */
+   from the bp_locations array, but for which a hit may still be
+   reported by a target.  */
 VEC(bp_location_p) *moribund_locations = NULL;
 
 /* Number of last breakpoint made.  */
@@ -695,8 +620,7 @@ static int rbreak_start_breakpoint_count;
 /* Called at the start an "rbreak" command to record the first
    breakpoint made.  */
 
-void
-start_rbreak_breakpoints (void)
+scoped_rbreak_breakpoints::scoped_rbreak_breakpoints ()
 {
   rbreak_start_breakpoint_count = breakpoint_count;
 }
@@ -704,8 +628,7 @@ start_rbreak_breakpoints (void)
 /* Called at the end of an "rbreak" command to record the last
    breakpoint made.  */
 
-void
-end_rbreak_breakpoints (void)
+scoped_rbreak_breakpoints::~scoped_rbreak_breakpoints ()
 {
   prev_breakpoint_count = rbreak_start_breakpoint_count;
 }
@@ -721,64 +644,6 @@ clear_breakpoint_hit_counts (void)
     b->hit_count = 0;
 }
 
-/* Allocate a new counted_command_line with reference count of 1.
-   The new structure owns COMMANDS.  */
-
-static struct counted_command_line *
-alloc_counted_command_line (struct command_line *commands)
-{
-  struct counted_command_line *result = XNEW (struct counted_command_line);
-
-  result->refc = 1;
-  result->commands = commands;
-
-  return result;
-}
-
-/* Increment reference count.  This does nothing if CMD is NULL.  */
-
-static void
-incref_counted_command_line (struct counted_command_line *cmd)
-{
-  if (cmd)
-    ++cmd->refc;
-}
-
-/* Decrement reference count.  If the reference count reaches 0,
-   destroy the counted_command_line.  Sets *CMDP to NULL.  This does
-   nothing if *CMDP is NULL.  */
-
-static void
-decref_counted_command_line (struct counted_command_line **cmdp)
-{
-  if (*cmdp)
-    {
-      if (--(*cmdp)->refc == 0)
-       {
-         free_command_lines (&(*cmdp)->commands);
-         xfree (*cmdp);
-       }
-      *cmdp = NULL;
-    }
-}
-
-/* A cleanup function that calls decref_counted_command_line.  */
-
-static void
-do_cleanup_counted_command_line (void *arg)
-{
-  decref_counted_command_line ((struct counted_command_line **) arg);
-}
-
-/* Create a cleanup that calls decref_counted_command_line on the
-   argument.  */
-
-static struct cleanup *
-make_cleanup_decref_counted_command_line (struct counted_command_line **cmdp)
-{
-  return make_cleanup (do_cleanup_counted_command_line, cmdp);
-}
-
 \f
 /* Return the breakpoint with the specified number, or NULL
    if the number does not refer to an existing breakpoint.  */
@@ -845,7 +710,7 @@ mark_breakpoint_location_modified (struct bp_location *loc)
    condition_evaluation_mode.  */
 
 static void
-set_condition_evaluation_mode (char *args, int from_tty,
+set_condition_evaluation_mode (const char *args, int from_tty,
                               struct cmd_list_element *c)
 {
   const char *old_mode, *new_mode;
@@ -921,10 +786,10 @@ show_condition_evaluation_mode (struct ui_file *file, int from_tty,
 
 /* A comparison function for bp_location AP and BP that is used by
    bsearch.  This comparison function only cares about addresses, unlike
-   the more general bp_location_compare function.  */
+   the more general bp_locations_compare function.  */
 
 static int
-bp_location_compare_addrs (const void *ap, const void *bp)
+bp_locations_compare_addrs (const void *ap, const void *bp)
 {
   const struct bp_location *a = *(const struct bp_location **) ap;
   const struct bp_location *b = *(const struct bp_location **) bp;
@@ -948,14 +813,13 @@ get_first_locp_gte_addr (CORE_ADDR address)
   struct bp_location **locp_found = NULL;
 
   /* Initialize the dummy location's address field.  */
-  memset (&dummy_loc, 0, sizeof (struct bp_location));
   dummy_loc.address = address;
 
   /* Find a close match to the first location at ADDRESS.  */
   locp_found = ((struct bp_location **)
-               bsearch (&dummy_locp, bp_location, bp_location_count,
+               bsearch (&dummy_locp, bp_locations, bp_locations_count,
                         sizeof (struct bp_location **),
-                        bp_location_compare_addrs));
+                        bp_locations_compare_addrs));
 
   /* Nothing was found, nothing left to do.  */
   if (locp_found == NULL)
@@ -963,7 +827,7 @@ get_first_locp_gte_addr (CORE_ADDR address)
 
   /* We may have found a location that is at ADDRESS but is not the first in the
      location's list.  Go backwards (if possible) and locate the first one.  */
-  while ((locp_found - 1) >= bp_location
+  while ((locp_found - 1) >= bp_locations
         && (*(locp_found - 1))->address == address)
     locp_found--;
 
@@ -1044,14 +908,15 @@ set_breakpoint_condition (struct breakpoint *b, const char *exp,
 
 /* Completion for the "condition" command.  */
 
-static VEC (char_ptr) *
+static void
 condition_completer (struct cmd_list_element *cmd,
+                    completion_tracker &tracker,
                     const char *text, const char *word)
 {
   const char *space;
 
-  text = skip_spaces_const (text);
-  space = skip_to_space_const (text);
+  text = skip_spaces (text);
+  space = skip_to_space (text);
   if (*space == '\0')
     {
       int len;
@@ -1061,9 +926,9 @@ condition_completer (struct cmd_list_element *cmd,
       if (text[0] == '$')
        {
          /* We don't support completion of history indices.  */
-         if (isdigit (text[1]))
-           return NULL;
-         return complete_internalvar (&text[1]);
+         if (!isdigit (text[1]))
+           complete_internalvar (tracker, &text[1]);
+         return;
        }
 
       /* We're completing the breakpoint number.  */
@@ -1076,24 +941,27 @@ condition_completer (struct cmd_list_element *cmd,
          xsnprintf (number, sizeof (number), "%d", b->number);
 
          if (strncmp (number, text, len) == 0)
-           VEC_safe_push (char_ptr, result, xstrdup (number));
+           {
+             gdb::unique_xmalloc_ptr<char> copy (xstrdup (number));
+             tracker.add_completion (std::move (copy));
+           }
        }
 
-      return result;
+      return;
     }
 
   /* We're completing the expression part.  */
-  text = skip_spaces_const (space);
-  return expression_completer (cmd, text, word);
+  text = skip_spaces (space);
+  expression_completer (cmd, tracker, text, word);
 }
 
 /* condition N EXP -- set break condition of breakpoint N to EXP.  */
 
 static void
-condition_command (char *arg, int from_tty)
+condition_command (const char *arg, int from_tty)
 {
   struct breakpoint *b;
-  char *p;
+  const char *p;
   int bnum;
 
   if (arg == 0)
@@ -1161,22 +1029,51 @@ check_no_tracepoint_commands (struct command_line *commands)
     }
 }
 
+struct longjmp_breakpoint : public breakpoint
+{
+  ~longjmp_breakpoint () override;
+};
+
 /* Encapsulate tests for different types of tracepoints.  */
 
-static int
-is_tracepoint_type (enum bptype type)
+static bool
+is_tracepoint_type (bptype type)
 {
   return (type == bp_tracepoint
          || type == bp_fast_tracepoint
          || type == bp_static_tracepoint);
 }
 
+static bool
+is_longjmp_type (bptype type)
+{
+  return type == bp_longjmp || type == bp_exception;
+}
+
 int
 is_tracepoint (const struct breakpoint *b)
 {
   return is_tracepoint_type (b->type);
 }
 
+/* Factory function to create an appropriate instance of breakpoint given
+   TYPE.  */
+
+static std::unique_ptr<breakpoint>
+new_breakpoint_from_type (bptype type)
+{
+  breakpoint *b;
+
+  if (is_tracepoint_type (type))
+    b = new tracepoint ();
+  else if (is_longjmp_type (type))
+    b = new longjmp_breakpoint ();
+  else
+    b = new breakpoint ();
+
+  return std::unique_ptr<breakpoint> (b);
+}
+
 /* A helper function that validates that COMMANDS are valid for a
    breakpoint.  This function will throw an exception if a problem is
    found.  */
@@ -1271,12 +1168,11 @@ static_tracepoints_here (CORE_ADDR addr)
 
 void
 breakpoint_set_commands (struct breakpoint *b, 
-                        struct command_line *commands)
+                        command_line_up &&commands)
 {
-  validate_commands_for_breakpoint (b, commands);
+  validate_commands_for_breakpoint (b, commands.get ());
 
-  decref_counted_command_line (&b->commands);
-  b->commands = alloc_counted_command_line (commands);
+  b->commands = std::move (commands);
   observer_notify_breakpoint_modified (b);
 }
 
@@ -1328,88 +1224,11 @@ check_tracepoint_command (char *line, void *closure)
   validate_actionline (line, b);
 }
 
-/* A structure used to pass information through
-   map_breakpoint_numbers.  */
-
-struct commands_info
-{
-  /* True if the command was typed at a tty.  */
-  int from_tty;
-
-  /* The breakpoint range spec.  */
-  const char *arg;
-
-  /* Non-NULL if the body of the commands are being read from this
-     already-parsed command.  */
-  struct command_line *control;
-
-  /* The command lines read from the user, or NULL if they have not
-     yet been read.  */
-  struct counted_command_line *cmd;
-};
-
-/* A callback for map_breakpoint_numbers that sets the commands for
-   commands_command.  */
-
-static void
-do_map_commands_command (struct breakpoint *b, void *data)
-{
-  struct commands_info *info = (struct commands_info *) data;
-
-  if (info->cmd == NULL)
-    {
-      struct command_line *l;
-
-      if (info->control != NULL)
-       l = copy_command_lines (info->control->body_list[0]);
-      else
-       {
-         struct cleanup *old_chain;
-         char *str;
-
-         str = xstrprintf (_("Type commands for breakpoint(s) "
-                             "%s, one per line."),
-                           info->arg);
-
-         old_chain = make_cleanup (xfree, str);
-
-         l = read_command_lines (str,
-                                 info->from_tty, 1,
-                                 (is_tracepoint (b)
-                                  ? check_tracepoint_command : 0),
-                                 b);
-
-         do_cleanups (old_chain);
-       }
-
-      info->cmd = alloc_counted_command_line (l);
-    }
-
-  /* If a breakpoint was on the list more than once, we don't need to
-     do anything.  */
-  if (b->commands != info->cmd)
-    {
-      validate_commands_for_breakpoint (b, info->cmd->commands);
-      incref_counted_command_line (info->cmd);
-      decref_counted_command_line (&b->commands);
-      b->commands = info->cmd;
-      observer_notify_breakpoint_modified (b);
-    }
-}
-
 static void
 commands_command_1 (const char *arg, int from_tty,
                    struct command_line *control)
 {
-  struct cleanup *cleanups;
-  struct commands_info info;
-
-  info.from_tty = from_tty;
-  info.control = control;
-  info.cmd = NULL;
-  /* If we read command lines from the user, then `info' will hold an
-     extra reference to the commands that we must clean up.  */
-  cleanups = make_cleanup_decref_counted_command_line (&info.cmd);
+  counted_command_line cmd;
 
   std::string new_arg;
 
@@ -1420,22 +1239,47 @@ commands_command_1 (const char *arg, int from_tty,
                                 breakpoint_count);
       else if (breakpoint_count > 0)
        new_arg = string_printf ("%d", breakpoint_count);
-    }
-  else
-    new_arg = arg;
+      arg = new_arg.c_str ();
+    }
+
+  map_breakpoint_numbers
+    (arg, [&] (breakpoint *b)
+     {
+       if (cmd == NULL)
+        {
+          if (control != NULL)
+            cmd = copy_command_lines (control->body_list[0]);
+          else
+            {
+              std::string str
+                = string_printf (_("Type commands for breakpoint(s) "
+                                   "%s, one per line."),
+                                 arg);
+
+              cmd = read_command_lines (&str[0],
+                                        from_tty, 1,
+                                        (is_tracepoint (b)
+                                         ? check_tracepoint_command : 0),
+                                        b);
+            }
+        }
+
+       /* If a breakpoint was on the list more than once, we don't need to
+         do anything.  */
+       if (b->commands != cmd)
+        {
+          validate_commands_for_breakpoint (b, cmd.get ());
+          b->commands = cmd;
+          observer_notify_breakpoint_modified (b);
+        }
+     });
 
-  info.arg = new_arg.c_str ();
-
-  map_breakpoint_numbers (info.arg, do_map_commands_command, &info);
-
-  if (info.cmd == NULL)
+  if (cmd == NULL)
     error (_("No breakpoints specified."));
-
-  do_cleanups (cleanups);
 }
 
 static void
-commands_command (char *arg, int from_tty)
+commands_command (const char *arg, int from_tty)
 {
   commands_command_1 (arg, from_tty, NULL);
 }
@@ -1569,15 +1413,15 @@ one_breakpoint_xfer_memory (gdb_byte *readbuf, gdb_byte *writebuf,
    a failed assertion internal error will be raised.
 
    The range of shadowed area by each bp_location is:
-     bl->address - bp_location_placed_address_before_address_max
-     up to bl->address + bp_location_shadow_len_after_address_max
+     bl->address - bp_locations_placed_address_before_address_max
+     up to bl->address + bp_locations_shadow_len_after_address_max
    The range we were requested to resolve shadows for is:
      memaddr ... memaddr + len
    Thus the safe cutoff boundaries for performance optimization are
      memaddr + len <= (bl->address
-                      - bp_location_placed_address_before_address_max)
+                      - bp_locations_placed_address_before_address_max)
    and:
-     bl->address + bp_location_shadow_len_after_address_max <= memaddr  */
+     bl->address + bp_locations_shadow_len_after_address_max <= memaddr  */
 
 void
 breakpoint_xfer_memory (gdb_byte *readbuf, gdb_byte *writebuf,
@@ -1593,26 +1437,26 @@ breakpoint_xfer_memory (gdb_byte *readbuf, gdb_byte *writebuf,
      report higher one.  */
 
   bc_l = 0;
-  bc_r = bp_location_count;
+  bc_r = bp_locations_count;
   while (bc_l + 1 < bc_r)
     {
       struct bp_location *bl;
 
       bc = (bc_l + bc_r) / 2;
-      bl = bp_location[bc];
+      bl = bp_locations[bc];
 
       /* Check first BL->ADDRESS will not overflow due to the added
         constant.  Then advance the left boundary only if we are sure
         the BC element can in no way affect the BUF content (MEMADDR
         to MEMADDR + LEN range).
 
-        Use the BP_LOCATION_SHADOW_LEN_AFTER_ADDRESS_MAX safety
+        Use the BP_LOCATIONS_SHADOW_LEN_AFTER_ADDRESS_MAX safety
         offset so that we cannot miss a breakpoint with its shadow
         range tail still reaching MEMADDR.  */
 
-      if ((bl->address + bp_location_shadow_len_after_address_max
+      if ((bl->address + bp_locations_shadow_len_after_address_max
           >= bl->address)
-         && (bl->address + bp_location_shadow_len_after_address_max
+         && (bl->address + bp_locations_shadow_len_after_address_max
              <= memaddr))
        bc_l = bc;
       else
@@ -1633,14 +1477,14 @@ breakpoint_xfer_memory (gdb_byte *readbuf, gdb_byte *writebuf,
      on "master" locations, we'd forget to restore the shadow of L1
      and L2.  */
   while (bc_l > 0
-        && bp_location[bc_l]->address == bp_location[bc_l - 1]->address)
+        && bp_locations[bc_l]->address == bp_locations[bc_l - 1]->address)
     bc_l--;
 
   /* Now do full processing of the found relevant range of elements.  */
 
-  for (bc = bc_l; bc < bp_location_count; bc++)
+  for (bc = bc_l; bc < bp_locations_count; bc++)
   {
-    struct bp_location *bl = bp_location[bc];
+    struct bp_location *bl = bp_locations[bc];
 
     /* bp_location array has BL->OWNER always non-NULL.  */
     if (bl->owner->type == bp_none)
@@ -1650,9 +1494,9 @@ breakpoint_xfer_memory (gdb_byte *readbuf, gdb_byte *writebuf,
     /* Performance optimization: any further element can no longer affect BUF
        content.  */
 
-    if (bl->address >= bp_location_placed_address_before_address_max
-        && memaddr + len <= (bl->address
-                            - bp_location_placed_address_before_address_max))
+    if (bl->address >= bp_locations_placed_address_before_address_max
+       && memaddr + len <= (bl->address
+                            - bp_locations_placed_address_before_address_max))
       break;
 
     if (!bp_location_has_shadow (bl))
@@ -1708,7 +1552,7 @@ is_watchpoint (const struct breakpoint *bpt)
 static int
 watchpoint_in_thread_scope (struct watchpoint *b)
 {
-  return (b->base.pspace == current_program_space
+  return (b->pspace == current_program_space
          && (ptid_equal (b->watchpoint_thread, null_ptid)
              || (ptid_equal (inferior_ptid, b->watchpoint_thread)
                  && !is_executing (inferior_ptid))));
@@ -1720,17 +1564,15 @@ watchpoint_in_thread_scope (struct watchpoint *b)
 static void
 watchpoint_del_at_next_stop (struct watchpoint *w)
 {
-  struct breakpoint *b = &w->base;
-
-  if (b->related_breakpoint != b)
+  if (w->related_breakpoint != w)
     {
-      gdb_assert (b->related_breakpoint->type == bp_watchpoint_scope);
-      gdb_assert (b->related_breakpoint->related_breakpoint == b);
-      b->related_breakpoint->disposition = disp_del_at_next_stop;
-      b->related_breakpoint->related_breakpoint = b->related_breakpoint;
-      b->related_breakpoint = b;
+      gdb_assert (w->related_breakpoint->type == bp_watchpoint_scope);
+      gdb_assert (w->related_breakpoint->related_breakpoint == w);
+      w->related_breakpoint->disposition = disp_del_at_next_stop;
+      w->related_breakpoint->related_breakpoint = w->related_breakpoint;
+      w->related_breakpoint = w;
     }
-  b->disposition = disp_del_at_next_stop;
+  w->disposition = disp_del_at_next_stop;
 }
 
 /* Extract a bitfield value from value VAL using the bit parameters contained in
@@ -1851,7 +1693,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
   if (!watchpoint_in_thread_scope (b))
     return;
 
-  if (b->base.disposition == disp_del_at_next_stop)
+  if (b->disposition == disp_del_at_next_stop)
     return;
  
   frame_saved = 0;
@@ -1889,7 +1731,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
   /* We don't free locations.  They are stored in the bp_location array
      and update_global_location_list will eventually delete them and
      remove breakpoints if needed.  */
-  b->base.loc = NULL;
+  b->loc = NULL;
 
   if (within_current_scope && reparse)
     {
@@ -1909,11 +1751,11 @@ update_watchpoint (struct watchpoint *b, int reparse)
       /* Note that unlike with breakpoints, the watchpoint's condition
         expression is stored in the breakpoint object, not in the
         locations (re)created below.  */
-      if (b->base.cond_string != NULL)
+      if (b->cond_string != NULL)
        {
          b->cond_exp.reset ();
 
-         s = b->base.cond_string;
+         s = b->cond_string;
          b->cond_exp = parse_exp_1 (&s, 0, b->cond_exp_valid_block, 0);
        }
     }
@@ -1930,8 +1772,8 @@ update_watchpoint (struct watchpoint *b, int reparse)
         the target gains execution, through breakpoint_re_set.  */
       if (!can_use_hw_watchpoints)
        {
-         if (b->base.ops->works_in_software_mode (&b->base))
-           b->base.type = bp_watchpoint;
+         if (b->ops->works_in_software_mode (b))
+           b->type = bp_watchpoint;
          else
            error (_("Can't set read/access watchpoint when "
                     "hardware watchpoints are disabled."));
@@ -1951,7 +1793,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
         happens, the code that reports it updates b->val directly.
         We don't keep track of the memory value for masked
         watchpoints.  */
-      if (!b->val_valid && !is_masked_watchpoint (&b->base))
+      if (!b->val_valid && !is_masked_watchpoint (b))
        {
          if (b->val_bitsize != 0)
            {
@@ -2014,13 +1856,13 @@ update_watchpoint (struct watchpoint *b, int reparse)
                    }
 
                  type = hw_write;
-                 if (b->base.type == bp_read_watchpoint)
+                 if (b->type == bp_read_watchpoint)
                    type = hw_read;
-                 else if (b->base.type == bp_access_watchpoint)
+                 else if (b->type == bp_access_watchpoint)
                    type = hw_access;
 
-                 loc = allocate_bp_location (&b->base);
-                 for (tmp = &(b->base.loc); *tmp != NULL; tmp = &((*tmp)->next))
+                 loc = allocate_bp_location (b);
+                 for (tmp = &(b->loc); *tmp != NULL; tmp = &((*tmp)->next))
                    ;
                  *tmp = loc;
                  loc->gdbarch = get_type_arch (value_type (v));
@@ -2070,7 +1912,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
              /* If this is a software watchpoint, we try to turn it
                 to a hardware one -- count resources as if B was of
                 hardware watchpoint type.  */
-             type = b->base.type;
+             type = b->type;
              if (type == bp_watchpoint)
                type = bp_hardware_watchpoint;
 
@@ -2081,16 +1923,16 @@ update_watchpoint (struct watchpoint *b, int reparse)
                 manually.  */
 
              /* Count resources used by all watchpoints except B.  */
-             i = hw_watchpoint_used_count_others (&b->base, type, &other_type_used);
+             i = hw_watchpoint_used_count_others (b, type, &other_type_used);
 
              /* Add in the resources needed for B.  */
-             i += hw_watchpoint_use_count (&b->base);
+             i += hw_watchpoint_use_count (b);
 
              target_resources_ok
                = target_can_use_hardware_watchpoint (type, i, other_type_used);
              if (target_resources_ok <= 0)
                {
-                 int sw_mode = b->base.ops->works_in_software_mode (&b->base);
+                 int sw_mode = b->ops->works_in_software_mode (b);
 
                  if (target_resources_ok == 0 && !sw_mode)
                    error (_("Target does not support this type of "
@@ -2100,7 +1942,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
                             "resources for this watchpoint."));
 
                  /* Downgrade to software watchpoint.  */
-                 b->base.type = bp_watchpoint;
+                 b->type = bp_watchpoint;
                }
              else
                {
@@ -2108,10 +1950,10 @@ update_watchpoint (struct watchpoint *b, int reparse)
                     found we have enough resources to turn it to a
                     hardware watchpoint.  Otherwise, this is a
                     nop.  */
-                 b->base.type = type;
+                 b->type = type;
                }
            }
-         else if (!b->base.ops->works_in_software_mode (&b->base))
+         else if (!b->ops->works_in_software_mode (b))
            {
              if (!can_use_hw_watchpoints)
                error (_("Can't set read/access watchpoint when "
@@ -2121,11 +1963,11 @@ update_watchpoint (struct watchpoint *b, int reparse)
                         "read/access watchpoint."));
            }
          else
-           b->base.type = bp_watchpoint;
+           b->type = bp_watchpoint;
 
-         loc_type = (b->base.type == bp_watchpoint? bp_loc_other
+         loc_type = (b->type == bp_watchpoint? bp_loc_other
                      : bp_loc_hardware_watchpoint);
-         for (bl = b->base.loc; bl; bl = bl->next)
+         for (bl = b->loc; bl; bl = bl->next)
            bl->loc_type = loc_type;
        }
 
@@ -2140,15 +1982,15 @@ update_watchpoint (struct watchpoint *b, int reparse)
         above left it without any location set up.  But,
         bpstat_stop_status requires a location to be able to report
         stops, so make sure there's at least a dummy one.  */
-      if (b->base.type == bp_watchpoint && b->base.loc == NULL)
-       software_watchpoint_add_no_memory_location (&b->base, frame_pspace);
+      if (b->type == bp_watchpoint && b->loc == NULL)
+       software_watchpoint_add_no_memory_location (b, frame_pspace);
     }
   else if (!within_current_scope)
     {
       printf_filtered (_("\
 Watchpoint %d deleted because the program has left the block\n\
 in which its expression is valid.\n"),
-                      b->base.number);
+                      b->number);
       watchpoint_del_at_next_stop (b);
     }
 
@@ -2268,7 +2110,7 @@ parse_cond_to_aexpr (CORE_ADDR scope, struct expression *cond)
      that may show up.  */
   TRY
     {
-      aexpr = std::move (gen_eval_for_expr (scope, cond));
+      aexpr = gen_eval_for_expr (scope, cond);
     }
 
   CATCH (ex, RETURN_MASK_ERROR)
@@ -2403,7 +2245,7 @@ parse_cmd_to_aexpr (CORE_ADDR scope, char *cmd)
 
   if (*cmdrest == ',')
     ++cmdrest;
-  cmdrest = skip_spaces_const (cmdrest);
+  cmdrest = skip_spaces (cmdrest);
 
   if (*cmdrest++ != '"')
     error (_("No format string following the location"));
@@ -2419,14 +2261,14 @@ parse_cmd_to_aexpr (CORE_ADDR scope, char *cmd)
   if (*cmdrest++ != '"')
     error (_("Bad format string, non-terminated '\"'."));
   
-  cmdrest = skip_spaces_const (cmdrest);
+  cmdrest = skip_spaces (cmdrest);
 
   if (!(*cmdrest == ',' || *cmdrest == '\0'))
     error (_("Invalid argument syntax"));
 
   if (*cmdrest == ',')
     cmdrest++;
-  cmdrest = skip_spaces_const (cmdrest);
+  cmdrest = skip_spaces (cmdrest);
 
   /* For each argument, make an expression.  */
 
@@ -2452,9 +2294,9 @@ parse_cmd_to_aexpr (CORE_ADDR scope, char *cmd)
      that may show up.  */
   TRY
     {
-      aexpr = std::move (gen_printf (scope, gdbarch, 0, 0,
-                                    format_start, format_end - format_start,
-                                    fpieces, nargs, argvec));
+      aexpr = gen_printf (scope, gdbarch, 0, 0,
+                         format_start, format_end - format_start,
+                         fpieces, nargs, argvec);
     }
   CATCH (ex, RETURN_MASK_ERROR)
     {
@@ -2616,8 +2458,7 @@ insert_bp_location (struct bp_location *bl,
                    int *hw_breakpoint_error,
                    int *hw_bp_error_explained_already)
 {
-  enum errors bp_err = GDB_NO_ERROR;
-  const char *bp_err_message = NULL;
+  gdb_exception bp_excpt = exception_none;
 
   if (!should_be_inserted (bl) || (bl->inserted && !bl->needs_update))
     return 0;
@@ -2726,12 +2567,11 @@ insert_bp_location (struct bp_location *bl,
 
              val = bl->owner->ops->insert_location (bl);
              if (val)
-               bp_err = GENERIC_ERROR;
+               bp_excpt = gdb_exception {RETURN_ERROR, GENERIC_ERROR};
            }
          CATCH (e, RETURN_MASK_ALL)
            {
-             bp_err = e.error;
-             bp_err_message = e.message;
+             bp_excpt = e;
            }
          END_CATCH
        }
@@ -2766,16 +2606,16 @@ insert_bp_location (struct bp_location *bl,
                      val = target_insert_breakpoint (bl->gdbarch,
                                                      &bl->overlay_target_info);
                      if (val)
-                       bp_err = GENERIC_ERROR;
+                       bp_excpt
+                         = gdb_exception {RETURN_ERROR, GENERIC_ERROR};
                    }
                  CATCH (e, RETURN_MASK_ALL)
                    {
-                     bp_err = e.error;
-                     bp_err_message = e.message;
+                     bp_excpt = e;
                    }
                  END_CATCH
 
-                 if (bp_err != GDB_NO_ERROR)
+                 if (bp_excpt.reason != 0)
                    fprintf_unfiltered (tmp_error_stream,
                                        "Overlay breakpoint %d "
                                        "failed: in ROM?\n",
@@ -2792,12 +2632,11 @@ insert_bp_location (struct bp_location *bl,
 
                  val = bl->owner->ops->insert_location (bl);
                  if (val)
-                   bp_err = GENERIC_ERROR;
+                   bp_excpt = gdb_exception {RETURN_ERROR, GENERIC_ERROR};
                }
              CATCH (e, RETURN_MASK_ALL)
                {
-                 bp_err = e.error;
-                 bp_err_message = e.message;
+                 bp_excpt = e;
                }
              END_CATCH
            }
@@ -2809,7 +2648,7 @@ insert_bp_location (struct bp_location *bl,
            }
        }
 
-      if (bp_err != GDB_NO_ERROR)
+      if (bp_excpt.reason != 0)
        {
          /* Can't set the breakpoint.  */
 
@@ -2821,7 +2660,9 @@ insert_bp_location (struct bp_location *bl,
             breakpoint insertion failed (e.g., the remote target
             doesn't define error codes), so we must treat generic
             errors as memory errors.  */
-         if ((bp_err == GENERIC_ERROR || bp_err == MEMORY_ERROR)
+         if (bp_excpt.reason == RETURN_ERROR
+             && (bp_excpt.error == GENERIC_ERROR
+                 || bp_excpt.error == MEMORY_ERROR)
              && bl->loc_type == bp_loc_software_breakpoint
              && (solib_name_from_address (bl->pspace, bl->address)
                  || shared_objfile_contains_address_p (bl->pspace,
@@ -2849,34 +2690,34 @@ insert_bp_location (struct bp_location *bl,
              if (bl->loc_type == bp_loc_hardware_breakpoint)
                {
                  *hw_breakpoint_error = 1;
-                 *hw_bp_error_explained_already = bp_err_message != NULL;
+                 *hw_bp_error_explained_already = bp_excpt.message != NULL;
                   fprintf_unfiltered (tmp_error_stream,
                                       "Cannot insert hardware breakpoint %d%s",
-                                      bl->owner->number, bp_err_message ? ":" : ".\n");
-                  if (bp_err_message != NULL)
-                    fprintf_unfiltered (tmp_error_stream, "%s.\n", bp_err_message);
+                                      bl->owner->number,
+                                     bp_excpt.message ? ":" : ".\n");
+                  if (bp_excpt.message != NULL)
+                    fprintf_unfiltered (tmp_error_stream, "%s.\n",
+                                       bp_excpt.message);
                }
              else
                {
-                 if (bp_err_message == NULL)
+                 if (bp_excpt.message == NULL)
                    {
-                     char *message
+                     std::string message
                        = memory_error_message (TARGET_XFER_E_IO,
                                                bl->gdbarch, bl->address);
-                     struct cleanup *old_chain = make_cleanup (xfree, message);
 
                      fprintf_unfiltered (tmp_error_stream,
                                          "Cannot insert breakpoint %d.\n"
                                          "%s\n",
-                                         bl->owner->number, message);
-                     do_cleanups (old_chain);
+                                         bl->owner->number, message.c_str ());
                    }
                  else
                    {
                      fprintf_unfiltered (tmp_error_stream,
                                          "Cannot insert breakpoint %d: %s\n",
                                          bl->owner->number,
-                                         bp_err_message);
+                                         bp_excpt.message);
                    }
                }
              return 1;
@@ -3061,14 +2902,13 @@ update_inserted_breakpoint_locations (void)
   int hw_breakpoint_error = 0;
   int hw_bp_details_reported = 0;
 
-  struct ui_file *tmp_error_stream = mem_fileopen ();
-  struct cleanup *cleanups = make_cleanup_ui_file_delete (tmp_error_stream);
+  string_file tmp_error_stream;
 
   /* Explicitly mark the warning -- this will only be printed if
      there was an error.  */
-  fprintf_unfiltered (tmp_error_stream, "Warning:\n");
+  tmp_error_stream.puts ("Warning:\n");
 
-  save_current_space_and_thread ();
+  scoped_restore_current_pspace_and_thread restore_pspace_thread;
 
   ALL_BP_LOCATIONS (bl, blp_tmp)
     {
@@ -3093,7 +2933,7 @@ update_inserted_breakpoint_locations (void)
          && ptid_equal (inferior_ptid, null_ptid))
        continue;
 
-      val = insert_bp_location (bl, tmp_error_stream, &disabled_breaks,
+      val = insert_bp_location (bl, &tmp_error_stream, &disabled_breaks,
                                    &hw_breakpoint_error, &hw_bp_details_reported);
       if (val)
        error_flag = val;
@@ -3101,11 +2941,9 @@ update_inserted_breakpoint_locations (void)
 
   if (error_flag)
     {
-      target_terminal_ours_for_output ();
+      target_terminal::ours_for_output ();
       error_stream (tmp_error_stream);
     }
-
-  do_cleanups (cleanups);
 }
 
 /* Used when starting or continuing the program.  */
@@ -3121,14 +2959,13 @@ insert_breakpoint_locations (void)
   int hw_breakpoint_error = 0;
   int hw_bp_error_explained_already = 0;
 
-  struct ui_file *tmp_error_stream = mem_fileopen ();
-  struct cleanup *cleanups = make_cleanup_ui_file_delete (tmp_error_stream);
-  
+  string_file tmp_error_stream;
+
   /* Explicitly mark the warning -- this will only be printed if
      there was an error.  */
-  fprintf_unfiltered (tmp_error_stream, "Warning:\n");
+  tmp_error_stream.puts ("Warning:\n");
 
-  save_current_space_and_thread ();
+  scoped_restore_current_pspace_and_thread restore_pspace_thread;
 
   ALL_BP_LOCATIONS (bl, blp_tmp)
     {
@@ -3152,7 +2989,7 @@ insert_breakpoint_locations (void)
          && ptid_equal (inferior_ptid, null_ptid))
        continue;
 
-      val = insert_bp_location (bl, tmp_error_stream, &disabled_breaks,
+      val = insert_bp_location (bl, &tmp_error_stream, &disabled_breaks,
                                    &hw_breakpoint_error, &hw_bp_error_explained_already);
       if (val)
        error_flag = val;
@@ -3187,9 +3024,9 @@ insert_breakpoint_locations (void)
              remove_breakpoint (loc);
 
          hw_breakpoint_error = 1;
-         fprintf_unfiltered (tmp_error_stream,
-                             "Could not insert hardware watchpoint %d.\n", 
-                             bpt->number);
+         tmp_error_stream.printf ("Could not insert "
+                                  "hardware watchpoint %d.\n",
+                                  bpt->number);
          error_flag = -1;
        }
     }
@@ -3200,15 +3037,12 @@ insert_breakpoint_locations (void)
          message about possibly exhausted resources.  */
       if (hw_breakpoint_error && !hw_bp_error_explained_already)
        {
-         fprintf_unfiltered (tmp_error_stream, 
-                             "Could not insert hardware breakpoints:\n\
+         tmp_error_stream.printf ("Could not insert hardware breakpoints:\n\
 You may have requested too many hardware breakpoints/watchpoints.\n");
        }
-      target_terminal_ours_for_output ();
+      target_terminal::ours_for_output ();
       error_stream (tmp_error_stream);
     }
-
-  do_cleanups (cleanups);
 }
 
 /* Used when the program stops.
@@ -3277,49 +3111,6 @@ remove_breakpoints_pid (int pid)
   return 0;
 }
 
-int
-reattach_breakpoints (int pid)
-{
-  struct cleanup *old_chain;
-  struct bp_location *bl, **blp_tmp;
-  int val;
-  struct ui_file *tmp_error_stream;
-  int dummy1 = 0, dummy2 = 0, dummy3 = 0;
-  struct inferior *inf;
-  struct thread_info *tp;
-
-  tp = any_live_thread_of_process (pid);
-  if (tp == NULL)
-    return 1;
-
-  inf = find_inferior_pid (pid);
-  old_chain = save_inferior_ptid ();
-
-  inferior_ptid = tp->ptid;
-
-  tmp_error_stream = mem_fileopen ();
-  make_cleanup_ui_file_delete (tmp_error_stream);
-
-  ALL_BP_LOCATIONS (bl, blp_tmp)
-  {
-    if (bl->pspace != inf->pspace)
-      continue;
-
-    if (bl->inserted)
-      {
-       bl->inserted = 0;
-       val = insert_bp_location (bl, tmp_error_stream, &dummy1, &dummy2, &dummy3);
-       if (val != 0)
-         {
-           do_cleanups (old_chain);
-           return val;
-         }
-      }
-  }
-  do_cleanups (old_chain);
-  return 0;
-}
-
 static int internal_breakpoint_number = -1;
 
 /* Set the breakpoint number of B, depending on the value of INTERNAL.
@@ -3345,16 +3136,12 @@ create_internal_breakpoint (struct gdbarch *gdbarch,
                            CORE_ADDR address, enum bptype type,
                            const struct breakpoint_ops *ops)
 {
-  struct symtab_and_line sal;
-  struct breakpoint *b;
-
-  init_sal (&sal);             /* Initialize to zeroes.  */
-
+  symtab_and_line sal;
   sal.pc = address;
   sal.section = find_pc_overlay (sal.pc);
   sal.pspace = current_program_space;
 
-  b = set_raw_breakpoint (gdbarch, sal, type, ops);
+  breakpoint *b = set_raw_breakpoint (gdbarch, sal, type, ops);
   b->number = internal_breakpoint_number--;
   b->disposition = disp_donttouch;
 
@@ -3371,28 +3158,30 @@ static const char *const longjmp_names[] =
 struct breakpoint_objfile_data
 {
   /* Minimal symbol for "_ovly_debug_event" (if any).  */
-  struct bound_minimal_symbol overlay_msym;
+  struct bound_minimal_symbol overlay_msym {};
 
   /* Minimal symbol(s) for "longjmp", "siglongjmp", etc. (if any).  */
-  struct bound_minimal_symbol longjmp_msym[NUM_LONGJMP_NAMES];
+  struct bound_minimal_symbol longjmp_msym[NUM_LONGJMP_NAMES] {};
 
   /* True if we have looked for longjmp probes.  */
-  int longjmp_searched;
+  int longjmp_searched = 0;
 
-  /* SystemTap probe points for longjmp (if any).  */
-  VEC (probe_p) *longjmp_probes;
+  /* SystemTap probe points for longjmp (if any).  These are non-owning
+     references.  */
+  std::vector<probe *> longjmp_probes;
 
   /* Minimal symbol for "std::terminate()" (if any).  */
-  struct bound_minimal_symbol terminate_msym;
+  struct bound_minimal_symbol terminate_msym {};
 
   /* Minimal symbol for "_Unwind_DebugHook" (if any).  */
-  struct bound_minimal_symbol exception_msym;
+  struct bound_minimal_symbol exception_msym {};
 
   /* True if we have looked for exception probes.  */
-  int exception_searched;
+  int exception_searched = 0;
 
-  /* SystemTap probe points for unwinding (if any).  */
-  VEC (probe_p) *exception_probes;
+  /* SystemTap probe points for unwinding (if any).  These are non-owning
+     references.  */
+  std::vector<probe *> exception_probes;
 };
 
 static const struct objfile_data *breakpoint_objfile_key;
@@ -3420,23 +3209,19 @@ get_breakpoint_objfile_data (struct objfile *objfile)
                     objfile_data (objfile, breakpoint_objfile_key));
   if (bp_objfile_data == NULL)
     {
-      bp_objfile_data =
-       XOBNEW (&objfile->objfile_obstack, struct breakpoint_objfile_data);
-
-      memset (bp_objfile_data, 0, sizeof (*bp_objfile_data));
+      bp_objfile_data = new breakpoint_objfile_data ();
       set_objfile_data (objfile, breakpoint_objfile_key, bp_objfile_data);
     }
   return bp_objfile_data;
 }
 
 static void
-free_breakpoint_probes (struct objfile *obj, void *data)
+free_breakpoint_objfile_data (struct objfile *obj, void *data)
 {
   struct breakpoint_objfile_data *bp_objfile_data
     = (struct breakpoint_objfile_data *) data;
 
-  VEC_free (probe_p, bp_objfile_data->longjmp_probes);
-  VEC_free (probe_p, bp_objfile_data->exception_probes);
+  delete bp_objfile_data;
 }
 
 static void
@@ -3496,9 +3281,8 @@ static void
 create_longjmp_master_breakpoint (void)
 {
   struct program_space *pspace;
-  struct cleanup *old_chain;
 
-  old_chain = save_current_program_space ();
+  scoped_restore_current_program_space restore_pspace;
 
   ALL_PSPACES (pspace)
   {
@@ -3518,47 +3302,38 @@ create_longjmp_master_breakpoint (void)
 
       if (!bp_objfile_data->longjmp_searched)
        {
-         VEC (probe_p) *ret;
+         std::vector<probe *> ret
+           = find_probes_in_objfile (objfile, "libc", "longjmp");
 
-         ret = find_probes_in_objfile (objfile, "libc", "longjmp");
-         if (ret != NULL)
+         if (!ret.empty ())
            {
              /* We are only interested in checking one element.  */
-             struct probe *p = VEC_index (probe_p, ret, 0);
+             probe *p = ret[0];
 
-             if (!can_evaluate_probe_arguments (p))
+             if (!p->can_evaluate_arguments ())
                {
                  /* We cannot use the probe interface here, because it does
                     not know how to evaluate arguments.  */
-                 VEC_free (probe_p, ret);
-                 ret = NULL;
+                 ret.clear ();
                }
            }
          bp_objfile_data->longjmp_probes = ret;
          bp_objfile_data->longjmp_searched = 1;
        }
 
-      if (bp_objfile_data->longjmp_probes != NULL)
+      if (!bp_objfile_data->longjmp_probes.empty ())
        {
-         int i;
-         struct probe *probe;
          struct gdbarch *gdbarch = get_objfile_arch (objfile);
 
-         for (i = 0;
-              VEC_iterate (probe_p,
-                           bp_objfile_data->longjmp_probes,
-                           i, probe);
-              ++i)
+         for (probe *p : bp_objfile_data->longjmp_probes)
            {
              struct breakpoint *b;
 
              b = create_internal_breakpoint (gdbarch,
-                                             get_probe_address (probe,
-                                                                objfile),
+                                             p->get_relocated_address (objfile),
                                              bp_longjmp_master,
                                              &internal_breakpoint_ops);
-             b->location
-               = new_probe_location ("-probe-stap libc:longjmp");
+             b->location = new_probe_location ("-probe-stap libc:longjmp");
              b->enable_state = bp_disabled;
            }
 
@@ -3603,8 +3378,6 @@ create_longjmp_master_breakpoint (void)
        }
     }
   }
-
-  do_cleanups (old_chain);
 }
 
 /* Create a master std::terminate breakpoint.  */
@@ -3612,10 +3385,9 @@ static void
 create_std_terminate_master_breakpoint (void)
 {
   struct program_space *pspace;
-  struct cleanup *old_chain;
   const char *const func_name = "std::terminate()";
 
-  old_chain = save_current_program_space ();
+  scoped_restore_current_program_space restore_pspace;
 
   ALL_PSPACES (pspace)
   {
@@ -3660,8 +3432,6 @@ create_std_terminate_master_breakpoint (void)
       b->enable_state = bp_disabled;
     }
   }
-
-  do_cleanups (old_chain);
 }
 
 /* Install a master breakpoint on the unwinder's debug hook.  */
@@ -3685,48 +3455,38 @@ create_exception_master_breakpoint (void)
       /* We prefer the SystemTap probe point if it exists.  */
       if (!bp_objfile_data->exception_searched)
        {
-         VEC (probe_p) *ret;
+         std::vector<probe *> ret
+           = find_probes_in_objfile (objfile, "libgcc", "unwind");
 
-         ret = find_probes_in_objfile (objfile, "libgcc", "unwind");
-
-         if (ret != NULL)
+         if (!ret.empty ())
            {
              /* We are only interested in checking one element.  */
-             struct probe *p = VEC_index (probe_p, ret, 0);
+             probe *p = ret[0];
 
-             if (!can_evaluate_probe_arguments (p))
+             if (!p->can_evaluate_arguments ())
                {
                  /* We cannot use the probe interface here, because it does
                     not know how to evaluate arguments.  */
-                 VEC_free (probe_p, ret);
-                 ret = NULL;
+                 ret.clear ();
                }
            }
          bp_objfile_data->exception_probes = ret;
          bp_objfile_data->exception_searched = 1;
        }
 
-      if (bp_objfile_data->exception_probes != NULL)
+      if (!bp_objfile_data->exception_probes.empty ())
        {
          struct gdbarch *gdbarch = get_objfile_arch (objfile);
-         int i;
-         struct probe *probe;
-
-         for (i = 0;
-              VEC_iterate (probe_p,
-                           bp_objfile_data->exception_probes,
-                           i, probe);
-              ++i)
+
+         for (probe *p : bp_objfile_data->exception_probes)
            {
              struct breakpoint *b;
 
              b = create_internal_breakpoint (gdbarch,
-                                             get_probe_address (probe,
-                                                                objfile),
+                                             p->get_relocated_address (objfile),
                                              bp_exception_master,
                                              &internal_breakpoint_ops);
-             b->location
-               = new_probe_location ("-probe-stap libgcc:unwind");
+             b->location = new_probe_location ("-probe-stap libgcc:unwind");
              b->enable_state = bp_disabled;
            }
 
@@ -3771,7 +3531,7 @@ create_exception_master_breakpoint (void)
 static int
 breakpoint_event_location_empty_p (const struct breakpoint *b)
 {
-  return b->location != NULL && event_location_empty_p (b->location);
+  return b->location != NULL && event_location_empty_p (b->location.get ());
 }
 
 void
@@ -3901,7 +3661,7 @@ detach_breakpoints (ptid_t ptid)
 {
   struct bp_location *bl, **blp_tmp;
   int val = 0;
-  struct cleanup *old_chain = save_inferior_ptid ();
+  scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
   struct inferior *inf = current_inferior ();
 
   if (ptid_get_pid (ptid) == ptid_get_pid (inferior_ptid))
@@ -3927,7 +3687,6 @@ detach_breakpoints (ptid_t ptid)
       val |= remove_breakpoint_1 (bl, DETACH_BREAKPOINT);
   }
 
-  do_cleanups (old_chain);
   return val;
 }
 
@@ -4086,9 +3845,6 @@ remove_breakpoint_1 (struct bp_location *bl, enum remove_bp_reason reason)
 static int
 remove_breakpoint (struct bp_location *bl)
 {
-  int ret;
-  struct cleanup *old_chain;
-
   /* BL is never in moribund_locations by our callers.  */
   gdb_assert (bl->owner != NULL);
 
@@ -4096,14 +3852,11 @@ remove_breakpoint (struct bp_location *bl)
      This should not ever happen.  */
   gdb_assert (bl->owner->type != bp_none);
 
-  old_chain = save_current_space_and_thread ();
+  scoped_restore_current_pspace_and_thread restore_pspace_thread;
 
   switch_to_program_space_and_thread (bl->pspace);
 
-  ret = remove_breakpoint_1 (bl, REMOVE_BREAKPOINT);
-
-  do_cleanups (old_chain);
-  return ret;
+  return remove_breakpoint_1 (bl, REMOVE_BREAKPOINT);
 }
 
 /* Clear the "inserted" flag in all breakpoints.  */
@@ -4248,7 +4001,7 @@ breakpoint_init_inferior (enum inf_context context)
      the target, to advance the PC past the breakpoint.  */
 
 enum breakpoint_here
-breakpoint_here_p (struct address_space *aspace, CORE_ADDR pc)
+breakpoint_here_p (const address_space *aspace, CORE_ADDR pc)
 {
   struct bp_location *bl, **blp_tmp;
   int any_breakpoint_here = 0;
@@ -4281,7 +4034,7 @@ breakpoint_here_p (struct address_space *aspace, CORE_ADDR pc)
 /* See breakpoint.h.  */
 
 int
-breakpoint_in_range_p (struct address_space *aspace,
+breakpoint_in_range_p (const address_space *aspace,
                       CORE_ADDR addr, ULONGEST len)
 {
   struct bp_location *bl, **blp_tmp;
@@ -4315,7 +4068,7 @@ breakpoint_in_range_p (struct address_space *aspace,
 /* Return true if there's a moribund breakpoint at PC.  */
 
 int
-moribund_breakpoint_here_p (struct address_space *aspace, CORE_ADDR pc)
+moribund_breakpoint_here_p (const address_space *aspace, CORE_ADDR pc)
 {
   struct bp_location *loc;
   int ix;
@@ -4332,7 +4085,7 @@ moribund_breakpoint_here_p (struct address_space *aspace, CORE_ADDR pc)
 
 static int
 bp_location_inserted_here_p (struct bp_location *bl,
-                            struct address_space *aspace, CORE_ADDR pc)
+                            const address_space *aspace, CORE_ADDR pc)
 {
   if (bl->inserted
       && breakpoint_address_match (bl->pspace->aspace, bl->address,
@@ -4351,7 +4104,7 @@ bp_location_inserted_here_p (struct bp_location *bl,
 /* Returns non-zero iff there's a breakpoint inserted at PC.  */
 
 int
-breakpoint_inserted_here_p (struct address_space *aspace, CORE_ADDR pc)
+breakpoint_inserted_here_p (const address_space *aspace, CORE_ADDR pc)
 {
   struct bp_location **blp, **blp_tmp = NULL;
 
@@ -4373,7 +4126,7 @@ breakpoint_inserted_here_p (struct address_space *aspace, CORE_ADDR pc)
    inserted at PC.  */
 
 int
-software_breakpoint_inserted_here_p (struct address_space *aspace,
+software_breakpoint_inserted_here_p (const address_space *aspace,
                                     CORE_ADDR pc)
 {
   struct bp_location **blp, **blp_tmp = NULL;
@@ -4395,7 +4148,7 @@ software_breakpoint_inserted_here_p (struct address_space *aspace,
 /* See breakpoint.h.  */
 
 int
-hardware_breakpoint_inserted_here_p (struct address_space *aspace,
+hardware_breakpoint_inserted_here_p (const address_space *aspace,
                                     CORE_ADDR pc)
 {
   struct bp_location **blp, **blp_tmp = NULL;
@@ -4415,7 +4168,7 @@ hardware_breakpoint_inserted_here_p (struct address_space *aspace,
 }
 
 int
-hardware_watchpoint_inserted_in_range (struct address_space *aspace,
+hardware_watchpoint_inserted_in_range (const address_space *aspace,
                                       CORE_ADDR addr, ULONGEST len)
 {
   struct breakpoint *bpt;
@@ -4459,14 +4212,12 @@ is_catchpoint (struct breakpoint *ep)
 /* Frees any storage that is part of a bpstat.  Does not walk the
    'next' chain.  */
 
-static void
-bpstat_free (bpstat bs)
+bpstats::~bpstats ()
 {
-  if (bs->old_val != NULL)
-    value_free (bs->old_val);
-  decref_counted_command_line (&bs->commands);
-  decref_bp_location (&bs->bp_location_at);
-  xfree (bs);
+  if (old_val != NULL)
+    value_free (old_val);
+  if (bp_location_at != NULL)
+    decref_bp_location (&bp_location_at);
 }
 
 /* Clear a bpstat so that it says we are not at any breakpoint.
@@ -4484,12 +4235,30 @@ bpstat_clear (bpstat *bsp)
   while (p != NULL)
     {
       q = p->next;
-      bpstat_free (p);
+      delete p;
       p = q;
     }
   *bsp = NULL;
 }
 
+bpstats::bpstats (const bpstats &other)
+  : next (NULL),
+    bp_location_at (other.bp_location_at),
+    breakpoint_at (other.breakpoint_at),
+    commands (other.commands),
+    old_val (other.old_val),
+    print (other.print),
+    stop (other.stop),
+    print_it (other.print_it)
+{
+  if (old_val != NULL)
+    {
+      old_val = value_copy (old_val);
+      release_value (old_val);
+    }
+  incref_bp_location (bp_location_at);
+}
+
 /* Return a copy of a bpstat.  Like "bs1 = bs2" but all storage that
    is part of the bpstat is copied as well.  */
 
@@ -4505,15 +4274,7 @@ bpstat_copy (bpstat bs)
 
   for (; bs != NULL; bs = bs->next)
     {
-      tmp = (bpstat) xmalloc (sizeof (*tmp));
-      memcpy (tmp, bs, sizeof (*tmp));
-      incref_counted_command_line (tmp->commands);
-      incref_bp_location (tmp->bp_location_at);
-      if (bs->old_val != NULL)
-       {
-         tmp->old_val = value_copy (bs->old_val);
-         release_value (tmp->old_val);
-       }
+      tmp = new bpstats (*bs);
 
       if (p == NULL)
        /* This is the first thing in the chain.  */
@@ -4614,7 +4375,7 @@ bpstat_clear_actions (void)
 
   for (bs = tp->control.stop_bpstat; bs != NULL; bs = bs->next)
     {
-      decref_counted_command_line (&bs->commands);
+      bs->commands = NULL;
 
       if (bs->old_val != NULL)
        {
@@ -4644,14 +4405,6 @@ breakpoint_about_to_proceed (void)
   breakpoint_proceeded = 1;
 }
 
-/* Stub for cleaning up our state if we error-out of a breakpoint
-   command.  */
-static void
-cleanup_executing_breakpoints (void *ignore)
-{
-  executing_breakpoint_commands = 0;
-}
-
 /* Return non-zero iff CMD as the first line of a command sequence is `silent'
    or its equivalent.  */
 
@@ -4674,7 +4427,6 @@ static int
 bpstat_do_actions_1 (bpstat *bsp)
 {
   bpstat bs;
-  struct cleanup *old_chain;
   int again = 0;
 
   /* Avoid endless recursion if a `source' command is contained
@@ -4682,10 +4434,10 @@ bpstat_do_actions_1 (bpstat *bsp)
   if (executing_breakpoint_commands)
     return 0;
 
-  executing_breakpoint_commands = 1;
-  old_chain = make_cleanup (cleanup_executing_breakpoints, 0);
+  scoped_restore save_executing
+    = make_scoped_restore (&executing_breakpoint_commands, 1);
 
-  prevent_dont_repeat ();
+  scoped_restore preventer = prevent_dont_repeat ();
 
   /* This pointer will iterate over the list of bpstat's.  */
   bs = *bsp;
@@ -4693,9 +4445,7 @@ bpstat_do_actions_1 (bpstat *bsp)
   breakpoint_proceeded = 0;
   for (; bs != NULL; bs = bs->next)
     {
-      struct counted_command_line *ccmd;
-      struct command_line *cmd;
-      struct cleanup *this_cmd_tree_chain;
+      struct command_line *cmd = NULL;
 
       /* Take ownership of the BSP's command tree, if it has one.
 
@@ -4707,10 +4457,10 @@ bpstat_do_actions_1 (bpstat *bsp)
          commands are only executed once, we don't need to copy it; we
          can clear the pointer in the bpstat, and make sure we free
          the tree when we're done.  */
-      ccmd = bs->commands;
+      counted_command_line ccmd = bs->commands;
       bs->commands = NULL;
-      this_cmd_tree_chain = make_cleanup_decref_counted_command_line (&ccmd);
-      cmd = ccmd ? ccmd->commands : NULL;
+      if (ccmd != NULL)
+       cmd = ccmd.get ();
       if (command_line_is_silent (cmd))
        {
          /* The action has been already done by bpstat_stop_status.  */
@@ -4727,9 +4477,6 @@ bpstat_do_actions_1 (bpstat *bsp)
            cmd = cmd->next;
        }
 
-      /* We can free this command tree now.  */
-      do_cleanups (this_cmd_tree_chain);
-
       if (breakpoint_proceeded)
        {
          if (current_ui->async)
@@ -4755,7 +4502,6 @@ bpstat_do_actions_1 (bpstat *bsp)
          break;
        }
     }
-  do_cleanups (old_chain);
   return again;
 }
 
@@ -4800,28 +4546,28 @@ watchpoint_value_print (struct value *val, struct ui_file *stream)
 void
 maybe_print_thread_hit_breakpoint (struct ui_out *uiout)
 {
-  if (ui_out_is_mi_like_p (uiout))
+  if (uiout->is_mi_like_p ())
     return;
 
-  ui_out_text (uiout, "\n");
+  uiout->text ("\n");
 
   if (show_thread_that_caused_stop ())
     {
       const char *name;
       struct thread_info *thr = inferior_thread ();
 
-      ui_out_text (uiout, "Thread ");
-      ui_out_field_fmt (uiout, "thread-id", "%s", print_thread_id (thr));
+      uiout->text ("Thread ");
+      uiout->field_fmt ("thread-id", "%s", print_thread_id (thr));
 
       name = thr->name != NULL ? thr->name : target_thread_name (thr);
       if (name != NULL)
        {
-         ui_out_text (uiout, " \"");
-         ui_out_field_fmt (uiout, "name", "%s", name);
-         ui_out_text (uiout, "\"");
+         uiout->text (" \"");
+         uiout->field_fmt ("name", "%s", name);
+         uiout->text ("\"");
        }
 
-      ui_out_text (uiout, " hit ");
+      uiout->text (" hit ");
     }
 }
 
@@ -4881,62 +4627,52 @@ print_solib_event (int is_catchpoint)
   if (!is_catchpoint)
     {
       if (any_added || any_deleted)
-       ui_out_text (current_uiout,
-                    _("Stopped due to shared library event:\n"));
+       current_uiout->text (_("Stopped due to shared library event:\n"));
       else
-       ui_out_text (current_uiout,
-                    _("Stopped due to shared library event (no "
-                      "libraries added or removed)\n"));
+       current_uiout->text (_("Stopped due to shared library event (no "
+                              "libraries added or removed)\n"));
     }
 
-  if (ui_out_is_mi_like_p (current_uiout))
-    ui_out_field_string (current_uiout, "reason",
-                        async_reason_lookup (EXEC_ASYNC_SOLIB_EVENT));
+  if (current_uiout->is_mi_like_p ())
+    current_uiout->field_string ("reason",
+                                async_reason_lookup (EXEC_ASYNC_SOLIB_EVENT));
 
   if (any_deleted)
     {
-      struct cleanup *cleanup;
       char *name;
       int ix;
 
-      ui_out_text (current_uiout, _("  Inferior unloaded "));
-      cleanup = make_cleanup_ui_out_list_begin_end (current_uiout,
-                                                   "removed");
+      current_uiout->text (_("  Inferior unloaded "));
+      ui_out_emit_list list_emitter (current_uiout, "removed");
       for (ix = 0;
           VEC_iterate (char_ptr, current_program_space->deleted_solibs,
                        ix, name);
           ++ix)
        {
          if (ix > 0)
-           ui_out_text (current_uiout, "    ");
-         ui_out_field_string (current_uiout, "library", name);
-         ui_out_text (current_uiout, "\n");
+           current_uiout->text ("    ");
+         current_uiout->field_string ("library", name);
+         current_uiout->text ("\n");
        }
-
-      do_cleanups (cleanup);
     }
 
   if (any_added)
     {
       struct so_list *iter;
       int ix;
-      struct cleanup *cleanup;
 
-      ui_out_text (current_uiout, _("  Inferior loaded "));
-      cleanup = make_cleanup_ui_out_list_begin_end (current_uiout,
-                                                   "added");
+      current_uiout->text (_("  Inferior loaded "));
+      ui_out_emit_list list_emitter (current_uiout, "added");
       for (ix = 0;
           VEC_iterate (so_list_ptr, current_program_space->added_solibs,
                        ix, iter);
           ++ix)
        {
          if (ix > 0)
-           ui_out_text (current_uiout, "    ");
-         ui_out_field_string (current_uiout, "library", iter->so_name);
-         ui_out_text (current_uiout, "\n");
+           current_uiout->text ("    ");
+         current_uiout->field_string ("library", iter->so_name);
+         current_uiout->text ("\n");
        }
-
-      do_cleanups (cleanup);
     }
 }
 
@@ -4993,42 +4729,45 @@ bpstat_print (bpstat bs, int kind)
   return PRINT_UNKNOWN;
 }
 
-/* Evaluate the expression EXP and return 1 if value is zero.
-   This returns the inverse of the condition because it is called
-   from catch_errors which returns 0 if an exception happened, and if an
-   exception happens we want execution to stop.
-   The argument is a "struct expression *" that has been cast to a
-   "void *" to make it pass through catch_errors.  */
+/* Evaluate the boolean expression EXP and return the result.  */
 
-static int
-breakpoint_cond_eval (void *exp)
+static bool
+breakpoint_cond_eval (expression *exp)
 {
   struct value *mark = value_mark ();
-  int i = !value_true (evaluate_expression ((struct expression *) exp));
+  bool res = value_true (evaluate_expression (exp));
 
   value_free_to_mark (mark);
-  return i;
+  return res;
 }
 
 /* Allocate a new bpstat.  Link it to the FIFO list by BS_LINK_POINTER.  */
 
-static bpstat
-bpstat_alloc (struct bp_location *bl, bpstat **bs_link_pointer)
+bpstats::bpstats (struct bp_location *bl, bpstat **bs_link_pointer)
+  : next (NULL),
+    bp_location_at (bl),
+    breakpoint_at (bl->owner),
+    commands (NULL),
+    old_val (NULL),
+    print (0),
+    stop (0),
+    print_it (print_it_normal)
 {
-  bpstat bs;
-
-  bs = (bpstat) xmalloc (sizeof (*bs));
-  bs->next = NULL;
-  **bs_link_pointer = bs;
-  *bs_link_pointer = &bs->next;
-  bs->breakpoint_at = bl->owner;
-  bs->bp_location_at = bl;
   incref_bp_location (bl);
-  /* If the condition is false, etc., don't do the commands.  */
-  bs->commands = NULL;
-  bs->old_val = NULL;
-  bs->print_it = print_it_normal;
-  return bs;
+  **bs_link_pointer = this;
+  *bs_link_pointer = &next;
+}
+
+bpstats::bpstats ()
+  : next (NULL),
+    bp_location_at (NULL),
+    breakpoint_at (NULL),
+    commands (NULL),
+    old_val (NULL),
+    print (0),
+    stop (0),
+    print_it (print_it_normal)
+{
 }
 \f
 /* The target has stopped with waitstatus WS.  Check if any hardware
@@ -5109,30 +4848,31 @@ watchpoints_triggered (struct target_waitstatus *ws)
   return 1;
 }
 
-/* Possible return values for watchpoint_check (this can't be an enum
-   because of check_errors).  */
-/* The watchpoint has been deleted.  */
-#define WP_DELETED 1
-/* The value has changed.  */
-#define WP_VALUE_CHANGED 2
-/* The value has not changed.  */
-#define WP_VALUE_NOT_CHANGED 3
-/* Ignore this watchpoint, no matter if the value changed or not.  */
-#define WP_IGNORE 4
+/* Possible return values for watchpoint_check.  */
+enum wp_check_result
+  {
+    /* The watchpoint has been deleted.  */
+    WP_DELETED = 1,
+
+    /* The value has changed.  */
+    WP_VALUE_CHANGED = 2,
+
+    /* The value has not changed.  */
+    WP_VALUE_NOT_CHANGED = 3,
+
+    /* Ignore this watchpoint, no matter if the value changed or not.  */
+    WP_IGNORE = 4,
+  };
 
 #define BP_TEMPFLAG 1
 #define BP_HARDWAREFLAG 2
 
 /* Evaluate watchpoint condition expression and check if its value
-   changed.
-
-   P should be a pointer to struct bpstat, but is defined as a void *
-   in order for this function to be usable with catch_errors.  */
+   changed.  */
 
-static int
-watchpoint_check (void *p)
+static wp_check_result
+watchpoint_check (bpstat bs)
 {
-  bpstat bs = (bpstat) p;
   struct watchpoint *b;
   struct frame_info *fr;
   int within_current_scope;
@@ -5201,7 +4941,7 @@ watchpoint_check (void *p)
       struct value *mark;
       struct value *new_val;
 
-      if (is_masked_watchpoint (&b->base))
+      if (is_masked_watchpoint (b))
        /* Since we don't know the exact trigger address (from
           stopped_data_address), just tell the user we've triggered
           a mask watchpoint.  */
@@ -5257,18 +4997,17 @@ watchpoint_check (void *p)
         {
          struct ui_out *uiout = current_uiout;
 
-         if (ui_out_is_mi_like_p (uiout))
-           ui_out_field_string
-             (uiout, "reason", async_reason_lookup (EXEC_ASYNC_WATCHPOINT_SCOPE));
-         ui_out_text (uiout, "\nWatchpoint ");
-         ui_out_field_int (uiout, "wpnum", b->base.number);
-         ui_out_text (uiout,
-                      " deleted because the program has left the block in\n"
+         if (uiout->is_mi_like_p ())
+           uiout->field_string
+             ("reason", async_reason_lookup (EXEC_ASYNC_WATCHPOINT_SCOPE));
+         uiout->text ("\nWatchpoint ");
+         uiout->field_int ("wpnum", b->number);
+         uiout->text (" deleted because the program has left the block in\n"
                       "which its expression is valid.\n");
        }
 
       /* Make sure the watchpoint's commands aren't executed.  */
-      decref_counted_command_line (&b->base.commands);
+      b->commands = NULL;
       watchpoint_del_at_next_stop (b);
 
       return WP_DELETED;
@@ -5281,7 +5020,7 @@ watchpoint_check (void *p)
 
 static int
 bpstat_check_location (const struct bp_location *bl,
-                      struct address_space *aspace, CORE_ADDR bp_addr,
+                      const address_space *aspace, CORE_ADDR bp_addr,
                       const struct target_waitstatus *ws)
 {
   struct breakpoint *b = bl->owner;
@@ -5310,7 +5049,7 @@ bpstat_check_watchpoint (bpstat bs)
     {
       int must_check_value = 0;
       
-      if (b->base.type == bp_watchpoint)
+      if (b->type == bp_watchpoint)
        /* For a software watchpoint, we must always check the
           watched value.  */
        must_check_value = 1;
@@ -5320,7 +5059,7 @@ bpstat_check_watchpoint (bpstat bs)
           this watchpoint.  */
        must_check_value = 1;
       else if (b->watchpoint_triggered == watch_triggered_unknown
-              && b->base.type == bp_hardware_watchpoint)
+              && b->type == bp_hardware_watchpoint)
        /* We were stopped by a hardware watchpoint, but the target could
           not report the data address.  We must check the watchpoint's
           value.  Access and read watchpoints are out of luck; without
@@ -5329,13 +5068,29 @@ bpstat_check_watchpoint (bpstat bs)
 
       if (must_check_value)
        {
-         char *message
-           = xstrprintf ("Error evaluating expression for watchpoint %d\n",
-                         b->base.number);
-         struct cleanup *cleanups = make_cleanup (xfree, message);
-         int e = catch_errors (watchpoint_check, bs, message,
-                               RETURN_MASK_ALL);
-         do_cleanups (cleanups);
+         wp_check_result e;
+
+         TRY
+           {
+             e = watchpoint_check (bs);
+           }
+         CATCH (ex, RETURN_MASK_ALL)
+           {
+             exception_fprintf (gdb_stderr, ex,
+                                "Error evaluating expression "
+                                "for watchpoint %d\n",
+                                b->number);
+
+             SWITCH_THRU_ALL_UIS ()
+               {
+                 printf_filtered (_("Watchpoint %d deleted.\n"),
+                                  b->number);
+               }
+             watchpoint_del_at_next_stop (b);
+             e = WP_DELETED;
+           }
+         END_CATCH
+
          switch (e)
            {
            case WP_DELETED:
@@ -5348,7 +5103,7 @@ bpstat_check_watchpoint (bpstat bs)
              bs->stop = 0;
              break;
            case WP_VALUE_CHANGED:
-             if (b->base.type == bp_read_watchpoint)
+             if (b->type == bp_read_watchpoint)
                {
                  /* There are two cases to consider here:
 
@@ -5419,8 +5174,8 @@ bpstat_check_watchpoint (bpstat bs)
                }
              break;
            case WP_VALUE_NOT_CHANGED:
-             if (b->base.type == bp_hardware_watchpoint
-                 || b->base.type == bp_watchpoint)
+             if (b->type == bp_hardware_watchpoint
+                 || b->type == bp_watchpoint)
                {
                  /* Don't stop: write watchpoints shouldn't fire if
                     the value hasn't changed.  */
@@ -5431,18 +5186,6 @@ bpstat_check_watchpoint (bpstat bs)
              break;
            default:
              /* Can't happen.  */
-           case 0:
-             /* Error from catch_errors.  */
-             {
-               SWITCH_THRU_ALL_UIS ()
-                 {
-                   printf_filtered (_("Watchpoint %d deleted.\n"),
-                                    b->base.number);
-                 }
-               watchpoint_del_at_next_stop (b);
-               /* We've already printed what needs to be printed.  */
-               bs->print_it = print_it_done;
-             }
              break;
            }
        }
@@ -5468,7 +5211,8 @@ bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
 {
   const struct bp_location *bl;
   struct breakpoint *b;
-  int value_is_zero = 0;
+  /* Assume stop.  */
+  bool condition_result = true;
   struct expression *cond;
 
   gdb_assert (bs->stop);
@@ -5564,23 +5308,30 @@ bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
            within_current_scope = 0;
        }
       if (within_current_scope)
-       value_is_zero
-         = catch_errors (breakpoint_cond_eval, cond,
-                         "Error in testing breakpoint condition:\n",
-                         RETURN_MASK_ALL);
+       {
+         TRY
+           {
+             condition_result = breakpoint_cond_eval (cond);
+           }
+         CATCH (ex, RETURN_MASK_ALL)
+           {
+             exception_fprintf (gdb_stderr, ex,
+                                "Error in testing breakpoint condition:\n");
+           }
+         END_CATCH
+       }
       else
        {
          warning (_("Watchpoint condition cannot be tested "
                     "in the current scope"));
          /* If we failed to set the right context for this
             watchpoint, unconditionally report it.  */
-         value_is_zero = 0;
        }
       /* FIXME-someday, should give breakpoint #.  */
       value_free_to_mark (mark);
     }
 
-  if (cond && value_is_zero)
+  if (cond && !condition_result)
     {
       bs->stop = 0;
     }
@@ -5626,7 +5377,7 @@ need_moribund_for_location_type (struct bp_location *loc)
    commands, FIXME??? fields.  */
 
 bpstat
-bpstat_stop_status (struct address_space *aspace,
+bpstat_stop_status (const address_space *aspace,
                    CORE_ADDR bp_addr, ptid_t ptid,
                    const struct target_waitstatus *ws)
 {
@@ -5672,7 +5423,7 @@ bpstat_stop_status (struct address_space *aspace,
          /* Come here if it's a watchpoint, or if the break address
             matches.  */
 
-         bs = bpstat_alloc (bl, &bs_link);     /* Alloc a bpstat to
+         bs = new bpstats (bl, &bs_link);      /* Alloc a bpstat to
                                                   explain stop.  */
 
          /* Assume we stop.  Should we find a watchpoint that is not
@@ -5703,7 +5454,7 @@ bpstat_stop_status (struct address_space *aspace,
          if (breakpoint_location_address_match (loc, aspace, bp_addr)
              && need_moribund_for_location_type (loc))
            {
-             bs = bpstat_alloc (loc, &bs_link);
+             bs = new bpstats (loc, &bs_link);
              /* For hits of moribund locations, we should just proceed.  */
              bs->stop = 0;
              bs->print = 0;
@@ -5758,9 +5509,8 @@ bpstat_stop_status (struct address_space *aspace,
              if (b->silent)
                bs->print = 0;
              bs->commands = b->commands;
-             incref_counted_command_line (bs->commands);
              if (command_line_is_silent (bs->commands
-                                         ? bs->commands->commands : NULL))
+                                         ? bs->commands.get () : NULL))
                bs->print = 0;
 
              b->ops->after_condition_true (bs);
@@ -5810,14 +5560,14 @@ handle_jit_event (void)
 
   /* Switch terminal for any messages produced by
      breakpoint_re_set.  */
-  target_terminal_ours_for_output ();
+  target_terminal::ours_for_output ();
 
   frame = get_current_frame ();
   gdbarch = get_frame_arch (frame);
 
   jit_event_handler (gdbarch);
 
-  target_terminal_inferior ();
+  target_terminal::inferior ();
 }
 
 /* Prepare WHAT final decision for infrun.  */
@@ -6062,10 +5812,10 @@ wrap_indent_at_field (struct ui_out *uiout, const char *col_name)
 {
   static char wrap_indent[80];
   int i, total_width, width, align;
-  char *text;
+  const char *text;
 
   total_width = 0;
-  for (i = 1; ui_out_query_field (uiout, i, &width, &align, &text); i++)
+  for (i = 1; uiout->query_table_field (i, &width, &align, &text); i++)
     {
       if (strcmp (text, col_name) == 0)
        {
@@ -6149,7 +5899,8 @@ print_breakpoint_location (struct breakpoint *b,
                           struct bp_location *loc)
 {
   struct ui_out *uiout = current_uiout;
-  struct cleanup *old_chain = save_current_program_space ();
+
+  scoped_restore_current_program_space restore_pspace;
 
   if (loc != NULL && loc->shlib_disabled)
     loc = NULL;
@@ -6158,56 +5909,53 @@ print_breakpoint_location (struct breakpoint *b,
     set_current_program_space (loc->pspace);
 
   if (b->display_canonical)
-    ui_out_field_string (uiout, "what",
-                        event_location_to_string (b->location));
+    uiout->field_string ("what", event_location_to_string (b->location.get ()));
   else if (loc && loc->symtab)
     {
-      struct symbol *sym 
-       = find_pc_sect_function (loc->address, loc->section);
+      const struct symbol *sym = loc->symbol;
+
+      if (sym == NULL)
+       sym = find_pc_sect_function (loc->address, loc->section);
+
       if (sym)
        {
-         ui_out_text (uiout, "in ");
-         ui_out_field_string (uiout, "func",
-                              SYMBOL_PRINT_NAME (sym));
-         ui_out_text (uiout, " ");
-         ui_out_wrap_hint (uiout, wrap_indent_at_field (uiout, "what"));
-         ui_out_text (uiout, "at ");
+         uiout->text ("in ");
+         uiout->field_string ("func", SYMBOL_PRINT_NAME (sym));
+         uiout->text (" ");
+         uiout->wrap_hint (wrap_indent_at_field (uiout, "what"));
+         uiout->text ("at ");
        }
-      ui_out_field_string (uiout, "file",
+      uiout->field_string ("file",
                           symtab_to_filename_for_display (loc->symtab));
-      ui_out_text (uiout, ":");
+      uiout->text (":");
 
-      if (ui_out_is_mi_like_p (uiout))
-       ui_out_field_string (uiout, "fullname",
-                            symtab_to_fullname (loc->symtab));
+      if (uiout->is_mi_like_p ())
+       uiout->field_string ("fullname", symtab_to_fullname (loc->symtab));
       
-      ui_out_field_int (uiout, "line", loc->line_number);
+      uiout->field_int ("line", loc->line_number);
     }
   else if (loc)
     {
-      struct ui_file *stb = mem_fileopen ();
-      struct cleanup *stb_chain = make_cleanup_ui_file_delete (stb);
+      string_file stb;
 
-      print_address_symbolic (loc->gdbarch, loc->address, stb,
+      print_address_symbolic (loc->gdbarch, loc->address, &stb,
                              demangle, "");
-      ui_out_field_stream (uiout, "at", stb);
-
-      do_cleanups (stb_chain);
+      uiout->field_stream ("at", stb);
     }
   else
     {
-      ui_out_field_string (uiout, "pending",
-                          event_location_to_string (b->location));
+      uiout->field_string ("pending",
+                          event_location_to_string (b->location.get ()));
       /* If extra_string is available, it could be holding a condition
         or dprintf arguments.  In either case, make sure it is printed,
         too, but only for non-MI streams.  */
-      if (!ui_out_is_mi_like_p (uiout) && b->extra_string != NULL)
+      if (!uiout->is_mi_like_p () && b->extra_string != NULL)
        {
          if (b->type == bp_dprintf)
-           ui_out_text (uiout, ",");
+           uiout->text (",");
          else
-           ui_out_text (uiout, " ");
-         ui_out_text (uiout, b->extra_string);
+           uiout->text (" ");
+         uiout->text (b->extra_string);
        }
     }
 
@@ -6215,13 +5963,11 @@ print_breakpoint_location (struct breakpoint *b,
       && breakpoint_condition_evaluation_mode () == condition_evaluation_target
       && bp_condition_evaluator (b) == condition_evaluation_both)
     {
-      ui_out_text (uiout, " (");
-      ui_out_field_string (uiout, "evaluated-by",
+      uiout->text (" (");
+      uiout->field_string ("evaluated-by",
                           bp_location_condition_evaluator (loc));
-      ui_out_text (uiout, ")");
+      uiout->text (")");
     }
-
-  do_cleanups (old_chain);
 }
 
 static const char *
@@ -6230,7 +5976,7 @@ bptype_string (enum bptype type)
   struct ep_type_description
     {
       enum bptype type;
-      char *description;
+      const char *description;
     };
   static struct ep_type_description bptypes[] =
   {
@@ -6285,42 +6031,37 @@ bptype_string (enum bptype type)
 static void
 output_thread_groups (struct ui_out *uiout,
                      const char *field_name,
-                     VEC(int) *inf_num,
+                     const std::vector<int> &inf_nums,
                      int mi_only)
 {
-  struct cleanup *back_to;
-  int is_mi = ui_out_is_mi_like_p (uiout);
-  int inf;
-  int i;
+  int is_mi = uiout->is_mi_like_p ();
 
   /* For backward compatibility, don't display inferiors in CLI unless
      there are several.  Always display them for MI. */
   if (!is_mi && mi_only)
     return;
 
-  back_to = make_cleanup_ui_out_list_begin_end (uiout, field_name);
+  ui_out_emit_list list_emitter (uiout, field_name);
 
-  for (i = 0; VEC_iterate (int, inf_num, i, inf); ++i)
+  for (size_t i = 0; i < inf_nums.size (); i++)
     {
       if (is_mi)
        {
          char mi_group[10];
 
-         xsnprintf (mi_group, sizeof (mi_group), "i%d", inf);
-         ui_out_field_string (uiout, NULL, mi_group);
+         xsnprintf (mi_group, sizeof (mi_group), "i%d", inf_nums[i]);
+         uiout->field_string (NULL, mi_group);
        }
       else
        {
          if (i == 0)
-           ui_out_text (uiout, " inf ");
+           uiout->text (" inf ");
          else
-           ui_out_text (uiout, ", ");
+           uiout->text (", ");
        
-         ui_out_text (uiout, plongest (inf));
+         uiout->text (plongest (inf_nums[i]));
        }
     }
-
-  do_cleanups (back_to);
 }
 
 /* Print B to gdb_stdout.  */
@@ -6360,37 +6101,36 @@ print_one_breakpoint_location (struct breakpoint *b,
     {
       char *formatted;
       formatted = xstrprintf ("%d.%d", b->number, loc_number);
-      ui_out_field_string (uiout, "number", formatted);
+      uiout->field_string ("number", formatted);
       xfree (formatted);
     }
   else
     {
-      ui_out_field_int (uiout, "number", b->number);
+      uiout->field_int ("number", b->number);
     }
 
   /* 2 */
   annotate_field (1);
   if (part_of_multiple)
-    ui_out_field_skip (uiout, "type");
+    uiout->field_skip ("type");
   else
-    ui_out_field_string (uiout, "type", bptype_string (b->type));
+    uiout->field_string ("type", bptype_string (b->type));
 
   /* 3 */
   annotate_field (2);
   if (part_of_multiple)
-    ui_out_field_skip (uiout, "disp");
+    uiout->field_skip ("disp");
   else
-    ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
+    uiout->field_string ("disp", bpdisp_text (b->disposition));
 
 
   /* 4 */
   annotate_field (3);
   if (part_of_multiple)
-    ui_out_field_string (uiout, "enabled", loc->enabled ? "y" : "n");
+    uiout->field_string ("enabled", loc->enabled ? "y" : "n");
   else
-    ui_out_field_fmt (uiout, "enabled", "%c", 
-                     bpenables[(int) b->enable_state]);
-  ui_out_spaces (uiout, 2);
+    uiout->field_fmt ("enabled", "%c", bpenables[(int) b->enable_state]);
+  uiout->spaces (2);
 
   
   /* 5 and 6 */
@@ -6421,9 +6161,9 @@ print_one_breakpoint_location (struct breakpoint *b,
             not line up too nicely with the headers, but the effect
             is relatively readable).  */
          if (opts.addressprint)
-           ui_out_field_skip (uiout, "addr");
+           uiout->field_skip ("addr");
          annotate_field (5);
-         ui_out_field_string (uiout, "what", w->exp_string);
+         uiout->field_string ("what", w->exp_string);
        }
        break;
 
@@ -6459,11 +6199,11 @@ print_one_breakpoint_location (struct breakpoint *b,
          {
            annotate_field (4);
            if (header_of_multiple)
-             ui_out_field_string (uiout, "addr", "<MULTIPLE>");
+             uiout->field_string ("addr", "<MULTIPLE>");
            else if (b->loc == NULL || loc->shlib_disabled)
-             ui_out_field_string (uiout, "addr", "<PENDING>");
+             uiout->field_string ("addr", "<PENDING>");
            else
-             ui_out_field_core_addr (uiout, "addr",
+             uiout->field_core_addr ("addr",
                                      loc->gdbarch, loc->address);
          }
        annotate_field (5);
@@ -6478,13 +6218,13 @@ print_one_breakpoint_location (struct breakpoint *b,
   if (loc != NULL && !header_of_multiple)
     {
       struct inferior *inf;
-      VEC(int) *inf_num = NULL;
+      std::vector<int> inf_nums;
       int mi_only = 1;
 
       ALL_INFERIORS (inf)
        {
          if (inf->pspace == loc->pspace)
-           VEC_safe_push (int, inf_num, inf->num);
+           inf_nums.push_back (inf->num);
        }
 
         /* For backward compatibility, don't display inferiors in CLI unless
@@ -6497,8 +6237,7 @@ print_one_breakpoint_location (struct breakpoint *b,
                   moribund_locations and thus having NULL OWNER.  */
                && loc->owner->type != bp_catchpoint))
        mi_only = 0;
-      output_thread_groups (uiout, "thread-groups", inf_num, mi_only);
-      VEC_free (int, inf_num);
+      output_thread_groups (uiout, "thread-groups", inf_nums, mi_only);
     }
 
   if (!part_of_multiple)
@@ -6507,17 +6246,17 @@ print_one_breakpoint_location (struct breakpoint *b,
        {
          /* FIXME: This seems to be redundant and lost here; see the
             "stop only in" line a little further down.  */
-         ui_out_text (uiout, " thread ");
-         ui_out_field_int (uiout, "thread", b->thread);
+         uiout->text (" thread ");
+         uiout->field_int ("thread", b->thread);
        }
       else if (b->task != 0)
        {
-         ui_out_text (uiout, " task ");
-         ui_out_field_int (uiout, "task", b->task);
+         uiout->text (" task ");
+         uiout->field_int ("task", b->task);
        }
     }
 
-  ui_out_text (uiout, "\n");
+  uiout->text ("\n");
 
   if (!part_of_multiple)
     b->ops->print_one_detail (b, uiout);
@@ -6525,22 +6264,22 @@ print_one_breakpoint_location (struct breakpoint *b,
   if (part_of_multiple && frame_id_p (b->frame_id))
     {
       annotate_field (6);
-      ui_out_text (uiout, "\tstop only in stack frame at ");
+      uiout->text ("\tstop only in stack frame at ");
       /* FIXME: cagney/2002-12-01: Shouldn't be poking around inside
          the frame ID.  */
-      ui_out_field_core_addr (uiout, "frame",
+      uiout->field_core_addr ("frame",
                              b->gdbarch, b->frame_id.stack_addr);
-      ui_out_text (uiout, "\n");
+      uiout->text ("\n");
     }
   
   if (!part_of_multiple && b->cond_string)
     {
       annotate_field (7);
       if (is_tracepoint (b))
-       ui_out_text (uiout, "\ttrace only if ");
+       uiout->text ("\ttrace only if ");
       else
-       ui_out_text (uiout, "\tstop only if ");
-      ui_out_field_string (uiout, "cond", b->cond_string);
+       uiout->text ("\tstop only if ");
+      uiout->field_string ("cond", b->cond_string);
 
       /* Print whether the target is doing the breakpoint's condition
         evaluation.  If GDB is doing the evaluation, don't print anything.  */
@@ -6548,27 +6287,27 @@ print_one_breakpoint_location (struct breakpoint *b,
          && breakpoint_condition_evaluation_mode ()
          == condition_evaluation_target)
        {
-         ui_out_text (uiout, " (");
-         ui_out_field_string (uiout, "evaluated-by",
+         uiout->text (" (");
+         uiout->field_string ("evaluated-by",
                               bp_condition_evaluator (b));
-         ui_out_text (uiout, " evals)");
+         uiout->text (" evals)");
        }
-      ui_out_text (uiout, "\n");
+      uiout->text ("\n");
     }
 
   if (!part_of_multiple && b->thread != -1)
     {
       /* FIXME should make an annotation for this.  */
-      ui_out_text (uiout, "\tstop only in thread ");
-      if (ui_out_is_mi_like_p (uiout))
-       ui_out_field_int (uiout, "thread", b->thread);
+      uiout->text ("\tstop only in thread ");
+      if (uiout->is_mi_like_p ())
+       uiout->field_int ("thread", b->thread);
       else
        {
          struct thread_info *thr = find_thread_global_id (b->thread);
 
-         ui_out_field_string (uiout, "thread", print_thread_id (thr));
+         uiout->field_string ("thread", print_thread_id (thr));
        }
-      ui_out_text (uiout, "\n");
+      uiout->text ("\n");
     }
   
   if (!part_of_multiple)
@@ -6577,32 +6316,32 @@ print_one_breakpoint_location (struct breakpoint *b,
        {
          /* FIXME should make an annotation for this.  */
          if (is_catchpoint (b))
-           ui_out_text (uiout, "\tcatchpoint");
+           uiout->text ("\tcatchpoint");
          else if (is_tracepoint (b))
-           ui_out_text (uiout, "\ttracepoint");
+           uiout->text ("\ttracepoint");
          else
-           ui_out_text (uiout, "\tbreakpoint");
-         ui_out_text (uiout, " already hit ");
-         ui_out_field_int (uiout, "times", b->hit_count);
+           uiout->text ("\tbreakpoint");
+         uiout->text (" already hit ");
+         uiout->field_int ("times", b->hit_count);
          if (b->hit_count == 1)
-           ui_out_text (uiout, " time\n");
+           uiout->text (" time\n");
          else
-           ui_out_text (uiout, " times\n");
+           uiout->text (" times\n");
        }
       else
        {
          /* Output the count also if it is zero, but only if this is mi.  */
-         if (ui_out_is_mi_like_p (uiout))
-           ui_out_field_int (uiout, "times", b->hit_count);
+         if (uiout->is_mi_like_p ())
+           uiout->field_int ("times", b->hit_count);
        }
     }
 
   if (!part_of_multiple && b->ignore_count)
     {
       annotate_field (8);
-      ui_out_text (uiout, "\tignore next ");
-      ui_out_field_int (uiout, "ignore", b->ignore_count);
-      ui_out_text (uiout, " hits\n");
+      uiout->text ("\tignore next ");
+      uiout->field_int ("ignore", b->ignore_count);
+      uiout->text (" hits\n");
     }
 
   /* Note that an enable count of 1 corresponds to "enable once"
@@ -6611,15 +6350,15 @@ print_one_breakpoint_location (struct breakpoint *b,
   if (!part_of_multiple && b->enable_count > 1)
     {
       annotate_field (8);
-      ui_out_text (uiout, "\tdisable after ");
+      uiout->text ("\tdisable after ");
       /* Tweak the wording to clarify that ignore and enable counts
         are distinct, and have additive effect.  */
       if (b->ignore_count)
-       ui_out_text (uiout, "additional ");
+       uiout->text ("additional ");
       else
-       ui_out_text (uiout, "next ");
-      ui_out_field_int (uiout, "enable", b->enable_count);
-      ui_out_text (uiout, " hits\n");
+       uiout->text ("next ");
+      uiout->field_int ("enable", b->enable_count);
+      uiout->text (" hits\n");
     }
 
   if (!part_of_multiple && is_tracepoint (b))
@@ -6628,21 +6367,18 @@ print_one_breakpoint_location (struct breakpoint *b,
 
       if (tp->traceframe_usage)
        {
-         ui_out_text (uiout, "\ttrace buffer usage ");
-         ui_out_field_int (uiout, "traceframe-usage", tp->traceframe_usage);
-         ui_out_text (uiout, " bytes\n");
+         uiout->text ("\ttrace buffer usage ");
+         uiout->field_int ("traceframe-usage", tp->traceframe_usage);
+         uiout->text (" bytes\n");
        }
     }
 
-  l = b->commands ? b->commands->commands : NULL;
+  l = b->commands ? b->commands.get () : NULL;
   if (!part_of_multiple && l)
     {
-      struct cleanup *script_chain;
-
       annotate_field (9);
-      script_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "script");
+      ui_out_emit_tuple tuple_emitter (uiout, "script");
       print_command_lines (uiout, l, 4);
-      do_cleanups (script_chain);
     }
 
   if (is_tracepoint (b))
@@ -6652,9 +6388,9 @@ print_one_breakpoint_location (struct breakpoint *b,
       if (!part_of_multiple && t->pass_count)
        {
          annotate_field (10);
-         ui_out_text (uiout, "\tpass count ");
-         ui_out_field_int (uiout, "pass", t->pass_count);
-         ui_out_text (uiout, " \n");
+         uiout->text ("\tpass count ");
+         uiout->field_int ("pass", t->pass_count);
+         uiout->text (" \n");
        }
 
       /* Don't display it when tracepoint or tracepoint location is
@@ -6663,32 +6399,32 @@ print_one_breakpoint_location (struct breakpoint *b,
        {
          annotate_field (11);
 
-         if (ui_out_is_mi_like_p (uiout))
-           ui_out_field_string (uiout, "installed",
+         if (uiout->is_mi_like_p ())
+           uiout->field_string ("installed",
                                 loc->inserted ? "y" : "n");
          else
            {
              if (loc->inserted)
-               ui_out_text (uiout, "\t");
+               uiout->text ("\t");
              else
-               ui_out_text (uiout, "\tnot ");
-             ui_out_text (uiout, "installed on target\n");
+               uiout->text ("\tnot ");
+             uiout->text ("installed on target\n");
            }
        }
     }
 
-  if (ui_out_is_mi_like_p (uiout) && !part_of_multiple)
+  if (uiout->is_mi_like_p () && !part_of_multiple)
     {
       if (is_watchpoint (b))
        {
          struct watchpoint *w = (struct watchpoint *) b;
 
-         ui_out_field_string (uiout, "original-location", w->exp_string);
+         uiout->field_string ("original-location", w->exp_string);
        }
       else if (b->location != NULL
-              && event_location_to_string (b->location) != NULL)
-       ui_out_field_string (uiout, "original-location",
-                            event_location_to_string (b->location));
+              && event_location_to_string (b->location.get ()) != NULL)
+       uiout->field_string ("original-location",
+                            event_location_to_string (b->location.get ()));
     }
 }
 
@@ -6697,13 +6433,13 @@ print_one_breakpoint (struct breakpoint *b,
                      struct bp_location **last_loc, 
                      int allflag)
 {
-  struct cleanup *bkpt_chain;
   struct ui_out *uiout = current_uiout;
 
-  bkpt_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "bkpt");
+  {
+    ui_out_emit_tuple tuple_emitter (uiout, "bkpt");
 
-  print_one_breakpoint_location (b, NULL, 0, last_loc, allflag);
-  do_cleanups (bkpt_chain);
+    print_one_breakpoint_location (b, NULL, 0, last_loc, allflag);
+  }
 
   /* If this breakpoint has custom print function,
      it's already printed.  Otherwise, print individual
@@ -6726,10 +6462,8 @@ print_one_breakpoint (struct breakpoint *b,
 
          for (loc = b->loc; loc; loc = loc->next, ++n)
            {
-             struct cleanup *inner2 =
-               make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+             ui_out_emit_tuple tuple_emitter (uiout, NULL);
              print_one_breakpoint_location (b, loc, n, last_loc, allflag);
-             do_cleanups (inner2);
            }
        }
     }
@@ -6758,44 +6492,13 @@ breakpoint_address_bits (struct breakpoint *b)
   return print_address_bits;
 }
 
-struct captured_breakpoint_query_args
-  {
-    int bnum;
-  };
+/* See breakpoint.h.  */
 
-static int
-do_captured_breakpoint_query (struct ui_out *uiout, void *data)
+void
+print_breakpoint (breakpoint *b)
 {
-  struct captured_breakpoint_query_args *args
-    = (struct captured_breakpoint_query_args *) data;
-  struct breakpoint *b;
   struct bp_location *dummy_loc = NULL;
-
-  ALL_BREAKPOINTS (b)
-    {
-      if (args->bnum == b->number)
-       {
-         print_one_breakpoint (b, &dummy_loc, 0);
-         return GDB_RC_OK;
-       }
-    }
-  return GDB_RC_NONE;
-}
-
-enum gdb_rc
-gdb_breakpoint_query (struct ui_out *uiout, int bnum, 
-                     char **error_message)
-{
-  struct captured_breakpoint_query_args args;
-
-  args.bnum = bnum;
-  /* For the moment we don't trust print_one_breakpoint() to not throw
-     an error.  */
-  if (catch_exceptions_with_msg (uiout, do_captured_breakpoint_query, &args,
-                                error_message, RETURN_MASK_ALL) < 0)
-    return GDB_RC_FAIL;
-  else
-    return GDB_RC_OK;
+  print_one_breakpoint (b, &dummy_loc, 0);
 }
 
 /* Return true if this breakpoint was set by the user, false if it is
@@ -6823,13 +6526,12 @@ pending_breakpoint_p (struct breakpoint *b)
    breakpoints listed.  */
 
 static int
-breakpoint_1 (char *args, int allflag, 
+breakpoint_1 (const char *args, int allflag, 
              int (*filter) (const struct breakpoint *))
 {
   struct breakpoint *b;
   struct bp_location *last_loc = NULL;
   int nr_printable_breakpoints;
-  struct cleanup *bkpttbl_chain;
   struct value_print_options opts;
   int print_address_bits = 0;
   int print_type_col_width = 14;
@@ -6872,80 +6574,71 @@ breakpoint_1 (char *args, int allflag,
        }
     }
 
-  if (opts.addressprint)
-    bkpttbl_chain 
-      = make_cleanup_ui_out_table_begin_end (uiout, 6,
-                                            nr_printable_breakpoints,
-                                             "BreakpointTable");
-  else
-    bkpttbl_chain 
-      = make_cleanup_ui_out_table_begin_end (uiout, 5,
-                                            nr_printable_breakpoints,
-                                             "BreakpointTable");
-
-  if (nr_printable_breakpoints > 0)
-    annotate_breakpoints_headers ();
-  if (nr_printable_breakpoints > 0)
-    annotate_field (0);
-  ui_out_table_header (uiout, 7, ui_left, "number", "Num");    /* 1 */
-  if (nr_printable_breakpoints > 0)
-    annotate_field (1);
-  ui_out_table_header (uiout, print_type_col_width, ui_left,
-                      "type", "Type");                         /* 2 */
-  if (nr_printable_breakpoints > 0)
-    annotate_field (2);
-  ui_out_table_header (uiout, 4, ui_left, "disp", "Disp");     /* 3 */
-  if (nr_printable_breakpoints > 0)
-    annotate_field (3);
-  ui_out_table_header (uiout, 3, ui_left, "enabled", "Enb");   /* 4 */
-  if (opts.addressprint)
-    {
-      if (nr_printable_breakpoints > 0)
-       annotate_field (4);
-      if (print_address_bits <= 32)
-       ui_out_table_header (uiout, 10, ui_left, 
-                            "addr", "Address");                /* 5 */
-      else
-       ui_out_table_header (uiout, 18, ui_left, 
-                            "addr", "Address");                /* 5 */
-    }
-  if (nr_printable_breakpoints > 0)
-    annotate_field (5);
-  ui_out_table_header (uiout, 40, ui_noalign, "what", "What"); /* 6 */
-  ui_out_table_body (uiout);
-  if (nr_printable_breakpoints > 0)
-    annotate_breakpoints_table ();
-
-  ALL_BREAKPOINTS (b)
-    {
-      QUIT;
-      /* If we have a filter, only list the breakpoints it accepts.  */
-      if (filter && !filter (b))
-       continue;
-
-      /* If we have an "args" string, it is a list of breakpoints to 
-        accept.  Skip the others.  */
+  {
+    ui_out_emit_table table_emitter (uiout,
+                                    opts.addressprint ? 6 : 5,
+                                    nr_printable_breakpoints,
+                                    "BreakpointTable");
+
+    if (nr_printable_breakpoints > 0)
+      annotate_breakpoints_headers ();
+    if (nr_printable_breakpoints > 0)
+      annotate_field (0);
+    uiout->table_header (7, ui_left, "number", "Num"); /* 1 */
+    if (nr_printable_breakpoints > 0)
+      annotate_field (1);
+    uiout->table_header (print_type_col_width, ui_left, "type", "Type"); /* 2 */
+    if (nr_printable_breakpoints > 0)
+      annotate_field (2);
+    uiout->table_header (4, ui_left, "disp", "Disp"); /* 3 */
+    if (nr_printable_breakpoints > 0)
+      annotate_field (3);
+    uiout->table_header (3, ui_left, "enabled", "Enb"); /* 4 */
+    if (opts.addressprint)
+      {
+       if (nr_printable_breakpoints > 0)
+         annotate_field (4);
+       if (print_address_bits <= 32)
+         uiout->table_header (10, ui_left, "addr", "Address"); /* 5 */
+       else
+         uiout->table_header (18, ui_left, "addr", "Address"); /* 5 */
+      }
+    if (nr_printable_breakpoints > 0)
+      annotate_field (5);
+    uiout->table_header (40, ui_noalign, "what", "What"); /* 6 */
+    uiout->table_body ();
+    if (nr_printable_breakpoints > 0)
+      annotate_breakpoints_table ();
+
+    ALL_BREAKPOINTS (b)
+      {
+       QUIT;
+       /* If we have a filter, only list the breakpoints it accepts.  */
+       if (filter && !filter (b))
+         continue;
 
-      if (args != NULL && *args != '\0')
-       {
-         if (allflag)  /* maintenance info breakpoint */
-           {
-             if (parse_and_eval_long (args) != b->number)
-               continue;
-           }
-         else          /* all others */
-           {
-             if (!number_is_in_list (args, b->number))
-               continue;
-           }
-       }
-      /* We only print out user settable breakpoints unless the
-        allflag is set.  */
-      if (allflag || user_breakpoint_p (b))
-       print_one_breakpoint (b, &last_loc, allflag);
-    }
+       /* If we have an "args" string, it is a list of breakpoints to 
+          accept.  Skip the others.  */
 
-  do_cleanups (bkpttbl_chain);
+       if (args != NULL && *args != '\0')
+         {
+           if (allflag)        /* maintenance info breakpoint */
+             {
+               if (parse_and_eval_long (args) != b->number)
+                 continue;
+             }
+           else                /* all others */
+             {
+               if (!number_is_in_list (args, b->number))
+                 continue;
+             }
+         }
+       /* We only print out user settable breakpoints unless the
+          allflag is set.  */
+       if (allflag || user_breakpoint_p (b))
+         print_one_breakpoint (b, &last_loc, allflag);
+      }
+  }
 
   if (nr_printable_breakpoints == 0)
     {
@@ -6954,10 +6647,9 @@ breakpoint_1 (char *args, int allflag,
       if (!filter)
        {
          if (args == NULL || *args == '\0')
-           ui_out_message (uiout, 0, "No breakpoints or watchpoints.\n");
+           uiout->message ("No breakpoints or watchpoints.\n");
          else
-           ui_out_message (uiout, 0, 
-                           "No breakpoint or watchpoint matching '%s'.\n",
+           uiout->message ("No breakpoint or watchpoint matching '%s'.\n",
                            args);
        }
     }
@@ -6990,13 +6682,13 @@ default_collect_info (void)
 
   /* The following phrase lines up nicely with per-tracepoint collect
      actions.  */
-  ui_out_text (uiout, "default collect ");
-  ui_out_field_string (uiout, "default-collect", default_collect);
-  ui_out_text (uiout, " \n");
+  uiout->text ("default collect ");
+  uiout->field_string ("default-collect", default_collect);
+  uiout->text (" \n");
 }
   
 static void
-breakpoints_info (char *args, int from_tty)
+info_breakpoints_command (const char *args, int from_tty)
 {
   breakpoint_1 (args, 0, NULL);
 
@@ -7004,7 +6696,7 @@ breakpoints_info (char *args, int from_tty)
 }
 
 static void
-watchpoints_info (char *args, int from_tty)
+info_watchpoints_command (const char *args, int from_tty)
 {
   int num_printed = breakpoint_1 (args, 0, is_watchpoint);
   struct ui_out *uiout = current_uiout;
@@ -7012,14 +6704,14 @@ watchpoints_info (char *args, int from_tty)
   if (num_printed == 0)
     {
       if (args == NULL || *args == '\0')
-       ui_out_message (uiout, 0, "No watchpoints.\n");
+       uiout->message ("No watchpoints.\n");
       else
-       ui_out_message (uiout, 0, "No watchpoint matching '%s'.\n", args);
+       uiout->message ("No watchpoint matching '%s'.\n", args);
     }
 }
 
 static void
-maintenance_info_breakpoints (char *args, int from_tty)
+maintenance_info_breakpoints (const char *args, int from_tty)
 {
   breakpoint_1 (args, 1, NULL);
 
@@ -7158,8 +6850,8 @@ watchpoint_locations_match (struct bp_location *loc1,
 /* See breakpoint.h.  */
 
 int
-breakpoint_address_match (struct address_space *aspace1, CORE_ADDR addr1,
-                         struct address_space *aspace2, CORE_ADDR addr2)
+breakpoint_address_match (const address_space *aspace1, CORE_ADDR addr1,
+                         const address_space *aspace2, CORE_ADDR addr2)
 {
   return ((gdbarch_has_global_breakpoints (target_gdbarch ())
           || aspace1 == aspace2)
@@ -7172,8 +6864,9 @@ breakpoint_address_match (struct address_space *aspace1, CORE_ADDR addr1,
    space doesn't really matter.  */
 
 static int
-breakpoint_address_match_range (struct address_space *aspace1, CORE_ADDR addr1,
-                               int len1, struct address_space *aspace2,
+breakpoint_address_match_range (const address_space *aspace1,
+                               CORE_ADDR addr1,
+                               int len1, const address_space *aspace2,
                                CORE_ADDR addr2)
 {
   return ((gdbarch_has_global_breakpoints (target_gdbarch ())
@@ -7188,7 +6881,7 @@ breakpoint_address_match_range (struct address_space *aspace1, CORE_ADDR addr1,
 
 static int
 breakpoint_location_address_match (struct bp_location *bl,
-                                  struct address_space *aspace,
+                                  const address_space *aspace,
                                   CORE_ADDR addr)
 {
   return (breakpoint_address_match (bl->pspace->aspace, bl->address,
@@ -7207,7 +6900,7 @@ breakpoint_location_address_match (struct bp_location *bl,
 
 static int
 breakpoint_location_address_range_overlap (struct bp_location *bl,
-                                          struct address_space *aspace,
+                                          const address_space *aspace,
                                           CORE_ADDR addr, int len)
 {
   if (gdbarch_has_global_breakpoints (target_gdbarch ())
@@ -7338,11 +7031,9 @@ adjust_breakpoint_address (struct gdbarch *gdbarch,
     }
 }
 
-void
-init_bp_location (struct bp_location *loc, const struct bp_location_ops *ops,
-                 struct breakpoint *owner)
+bp_location::bp_location (const bp_location_ops *ops, breakpoint *owner)
 {
-  memset (loc, 0, sizeof (*loc));
+  bp_location *loc = this;
 
   gdb_assert (ops != NULL);
 
@@ -7442,23 +7133,26 @@ decref_bp_location (struct bp_location **blp)
 
 /* Add breakpoint B at the end of the global breakpoint chain.  */
 
-static void
-add_to_breakpoint_chain (struct breakpoint *b)
+static breakpoint *
+add_to_breakpoint_chain (std::unique_ptr<breakpoint> &&b)
 {
   struct breakpoint *b1;
+  struct breakpoint *result = b.get ();
 
   /* Add this breakpoint to the end of the chain so that a list of
      breakpoints will come out in order of increasing numbers.  */
 
   b1 = breakpoint_chain;
   if (b1 == 0)
-    breakpoint_chain = b;
+    breakpoint_chain = b.release ();
   else
     {
       while (b1->next)
        b1 = b1->next;
-      b1->next = b;
+      b1->next = b.release ();
     }
+
+  return result;
 }
 
 /* Initializes breakpoint B with type BPTYPE and no locations yet.  */
@@ -7469,8 +7163,6 @@ init_raw_breakpoint_without_location (struct breakpoint *b,
                                      enum bptype bptype,
                                      const struct breakpoint_ops *ops)
 {
-  memset (b, 0, sizeof (*b));
-
   gdb_assert (ops != NULL);
 
   b->ops = ops;
@@ -7478,17 +7170,7 @@ init_raw_breakpoint_without_location (struct breakpoint *b,
   b->gdbarch = gdbarch;
   b->language = current_language->la_language;
   b->input_radix = input_radix;
-  b->thread = -1;
-  b->enable_state = bp_enabled;
-  b->next = 0;
-  b->silent = 0;
-  b->ignore_count = 0;
-  b->commands = NULL;
-  b->frame_id = null_frame_id;
-  b->condition_not_parsed = 0;
-  b->py_bp_object = NULL;
   b->related_breakpoint = b;
-  b->location = NULL;
 }
 
 /* Helper to set_raw_breakpoint below.  Creates a breakpoint
@@ -7499,11 +7181,10 @@ set_raw_breakpoint_without_location (struct gdbarch *gdbarch,
                                     enum bptype bptype,
                                     const struct breakpoint_ops *ops)
 {
-  struct breakpoint *b = new breakpoint ();
+  std::unique_ptr<breakpoint> b = new_breakpoint_from_type (bptype);
 
-  init_raw_breakpoint_without_location (b, gdbarch, bptype, ops);
-  add_to_breakpoint_chain (b);
-  return b;
+  init_raw_breakpoint_without_location (b.get (), gdbarch, bptype, ops);
+  return add_to_breakpoint_chain (std::move (b));
 }
 
 /* Initialize loc->function_name.  EXPLICIT_LOC says no indirect function
@@ -7615,11 +7296,10 @@ set_raw_breakpoint (struct gdbarch *gdbarch,
                    struct symtab_and_line sal, enum bptype bptype,
                    const struct breakpoint_ops *ops)
 {
-  struct breakpoint *b = new breakpoint ();
+  std::unique_ptr<breakpoint> b = new_breakpoint_from_type (bptype);
 
-  init_raw_breakpoint (b, gdbarch, sal, bptype, ops);
-  add_to_breakpoint_chain (b);
-  return b;
+  init_raw_breakpoint (b.get (), gdbarch, sal, bptype, ops);
+  return add_to_breakpoint_chain (std::move (b));
 }
 
 /* Call this routine when stepping and nexting to enable a breakpoint
@@ -7647,7 +7327,7 @@ set_longjmp_breakpoint (struct thread_info *tp, struct frame_id frame)
        /* longjmp_breakpoint_ops ensures INITIATING_FRAME is cleared again
           after their removal.  */
        clone = momentary_breakpoint_from_master (b, type,
-                                                 &longjmp_breakpoint_ops, 1);
+                                                 &momentary_breakpoint_ops, 1);
        clone->thread = thread;
       }
 
@@ -7957,14 +7637,6 @@ disable_breakpoints_in_unloaded_shlib (struct so_list *solib)
   struct bp_location *loc, **locp_tmp;
   int disabled_shlib_breaks = 0;
 
-  /* SunOS a.out shared libraries are always mapped, so do not
-     disable breakpoints; they will only be reported as unloaded
-     through clear_solib when GDB discards its shared library
-     list.  See clear_solib for more information.  */
-  if (exec_bfd != NULL
-      && bfd_get_flavour (exec_bfd) == bfd_target_aout_flavour)
-    return;
-
   ALL_BP_LOCATIONS (loc, locp_tmp)
   {
     /* ALL_BP_LOCATIONS bp_location has LOC->OWNER always non-NULL.  */
@@ -7991,7 +7663,7 @@ disable_breakpoints_in_unloaded_shlib (struct so_list *solib)
 
        if (!disabled_shlib_breaks)
          {
-           target_terminal_ours_for_output ();
+           target_terminal::ours_for_output ();
            warning (_("Temporarily disabling breakpoints "
                       "for unloaded shared library \"%s\""),
                     solib->so_name);
@@ -8077,16 +7749,11 @@ disable_breakpoints_in_freed_objfile (struct objfile *objfile)
 /* FORK & VFORK catchpoints.  */
 
 /* An instance of this type is used to represent a fork or vfork
-   catchpoint.  It includes a "struct breakpoint" as a kind of base
-   class; users downcast to "struct breakpoint *" when needed.  A
-   breakpoint is really of this type iff its ops pointer points to
-   CATCH_FORK_BREAKPOINT_OPS.  */
+   catchpoint.  A breakpoint is really of this type iff its ops pointer points
+   to CATCH_FORK_BREAKPOINT_OPS.  */
 
-struct fork_catchpoint
+struct fork_catchpoint : public breakpoint
 {
-  /* The base class.  */
-  struct breakpoint base;
-
   /* Process id of a child process whose forking triggered this
      catchpoint.  This field is only valid immediately after this
      catchpoint has triggered.  */
@@ -8116,7 +7783,7 @@ remove_catch_fork (struct bp_location *bl, enum remove_bp_reason reason)
 
 static int
 breakpoint_hit_catch_fork (const struct bp_location *bl,
-                          struct address_space *aspace, CORE_ADDR bp_addr,
+                          const address_space *aspace, CORE_ADDR bp_addr,
                           const struct target_waitstatus *ws)
 {
   struct fork_catchpoint *c = (struct fork_catchpoint *) bl->owner;
@@ -8141,19 +7808,18 @@ print_it_catch_fork (bpstat bs)
   annotate_catchpoint (b->number);
   maybe_print_thread_hit_breakpoint (uiout);
   if (b->disposition == disp_del)
-    ui_out_text (uiout, "Temporary catchpoint ");
+    uiout->text ("Temporary catchpoint ");
   else
-    ui_out_text (uiout, "Catchpoint ");
-  if (ui_out_is_mi_like_p (uiout))
+    uiout->text ("Catchpoint ");
+  if (uiout->is_mi_like_p ())
     {
-      ui_out_field_string (uiout, "reason",
-                          async_reason_lookup (EXEC_ASYNC_FORK));
-      ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
+      uiout->field_string ("reason", async_reason_lookup (EXEC_ASYNC_FORK));
+      uiout->field_string ("disp", bpdisp_text (b->disposition));
     }
-  ui_out_field_int (uiout, "bkptno", b->number);
-  ui_out_text (uiout, " (forked process ");
-  ui_out_field_int (uiout, "newpid", ptid_get_pid (c->forked_inferior_pid));
-  ui_out_text (uiout, "), ");
+  uiout->field_int ("bkptno", b->number);
+  uiout->text (" (forked process ");
+  uiout->field_int ("newpid", ptid_get_pid (c->forked_inferior_pid));
+  uiout->text ("), ");
   return PRINT_SRC_AND_LOC;
 }
 
@@ -8173,19 +7839,18 @@ print_one_catch_fork (struct breakpoint *b, struct bp_location **last_loc)
      line up too nicely with the headers, but the effect is relatively
      readable).  */
   if (opts.addressprint)
-    ui_out_field_skip (uiout, "addr");
+    uiout->field_skip ("addr");
   annotate_field (5);
-  ui_out_text (uiout, "fork");
+  uiout->text ("fork");
   if (!ptid_equal (c->forked_inferior_pid, null_ptid))
     {
-      ui_out_text (uiout, ", process ");
-      ui_out_field_int (uiout, "what",
-                        ptid_get_pid (c->forked_inferior_pid));
-      ui_out_spaces (uiout, 1);
+      uiout->text (", process ");
+      uiout->field_int ("what", ptid_get_pid (c->forked_inferior_pid));
+      uiout->spaces (1);
     }
 
-  if (ui_out_is_mi_like_p (uiout))
-    ui_out_field_string (uiout, "catch-type", "fork");
+  if (uiout->is_mi_like_p ())
+    uiout->field_string ("catch-type", "fork");
 }
 
 /* Implement the "print_mention" breakpoint_ops method for fork
@@ -8234,7 +7899,7 @@ remove_catch_vfork (struct bp_location *bl, enum remove_bp_reason reason)
 
 static int
 breakpoint_hit_catch_vfork (const struct bp_location *bl,
-                           struct address_space *aspace, CORE_ADDR bp_addr,
+                           const address_space *aspace, CORE_ADDR bp_addr,
                            const struct target_waitstatus *ws)
 {
   struct fork_catchpoint *c = (struct fork_catchpoint *) bl->owner;
@@ -8259,19 +7924,18 @@ print_it_catch_vfork (bpstat bs)
   annotate_catchpoint (b->number);
   maybe_print_thread_hit_breakpoint (uiout);
   if (b->disposition == disp_del)
-    ui_out_text (uiout, "Temporary catchpoint ");
+    uiout->text ("Temporary catchpoint ");
   else
-    ui_out_text (uiout, "Catchpoint ");
-  if (ui_out_is_mi_like_p (uiout))
+    uiout->text ("Catchpoint ");
+  if (uiout->is_mi_like_p ())
     {
-      ui_out_field_string (uiout, "reason",
-                          async_reason_lookup (EXEC_ASYNC_VFORK));
-      ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
+      uiout->field_string ("reason", async_reason_lookup (EXEC_ASYNC_VFORK));
+      uiout->field_string ("disp", bpdisp_text (b->disposition));
     }
-  ui_out_field_int (uiout, "bkptno", b->number);
-  ui_out_text (uiout, " (vforked process ");
-  ui_out_field_int (uiout, "newpid", ptid_get_pid (c->forked_inferior_pid));
-  ui_out_text (uiout, "), ");
+  uiout->field_int ("bkptno", b->number);
+  uiout->text (" (vforked process ");
+  uiout->field_int ("newpid", ptid_get_pid (c->forked_inferior_pid));
+  uiout->text ("), ");
   return PRINT_SRC_AND_LOC;
 }
 
@@ -8290,19 +7954,18 @@ print_one_catch_vfork (struct breakpoint *b, struct bp_location **last_loc)
      line up too nicely with the headers, but the effect is relatively
      readable).  */
   if (opts.addressprint)
-    ui_out_field_skip (uiout, "addr");
+    uiout->field_skip ("addr");
   annotate_field (5);
-  ui_out_text (uiout, "vfork");
+  uiout->text ("vfork");
   if (!ptid_equal (c->forked_inferior_pid, null_ptid))
     {
-      ui_out_text (uiout, ", process ");
-      ui_out_field_int (uiout, "what",
-                        ptid_get_pid (c->forked_inferior_pid));
-      ui_out_spaces (uiout, 1);
+      uiout->text (", process ");
+      uiout->field_int ("what", ptid_get_pid (c->forked_inferior_pid));
+      uiout->spaces (1);
     }
 
-  if (ui_out_is_mi_like_p (uiout))
-    ui_out_field_string (uiout, "catch-type", "vfork");
+  if (uiout->is_mi_like_p ())
+    uiout->field_string ("catch-type", "vfork");
 }
 
 /* Implement the "print_mention" breakpoint_ops method for vfork
@@ -8329,15 +7992,12 @@ print_recreate_catch_vfork (struct breakpoint *b, struct ui_file *fp)
 static struct breakpoint_ops catch_vfork_breakpoint_ops;
 
 /* An instance of this type is used to represent an solib catchpoint.
-   It includes a "struct breakpoint" as a kind of base class; users
-   downcast to "struct breakpoint *" when needed.  A breakpoint is
-   really of this type iff its ops pointer points to
+   A breakpoint is really of this type iff its ops pointer points to
    CATCH_SOLIB_BREAKPOINT_OPS.  */
 
-struct solib_catchpoint
+struct solib_catchpoint : public breakpoint
 {
-  /* The base class.  */
-  struct breakpoint base;
+  ~solib_catchpoint () override;
 
   /* True for "catch load", false for "catch unload".  */
   unsigned char is_load;
@@ -8345,19 +8005,12 @@ struct solib_catchpoint
   /* Regular expression to match, if any.  COMPILED is only valid when
      REGEX is non-NULL.  */
   char *regex;
-  regex_t compiled;
+  std::unique_ptr<compiled_regex> compiled;
 };
 
-static void
-dtor_catch_solib (struct breakpoint *b)
+solib_catchpoint::~solib_catchpoint ()
 {
-  struct solib_catchpoint *self = (struct solib_catchpoint *) b;
-
-  if (self->regex)
-    regfree (&self->compiled);
-  xfree (self->regex);
-
-  base_breakpoint_ops.dtor (b);
+  xfree (this->regex);
 }
 
 static int
@@ -8374,7 +8027,7 @@ remove_catch_solib (struct bp_location *ignore, enum remove_bp_reason reason)
 
 static int
 breakpoint_hit_catch_solib (const struct bp_location *bl,
-                           struct address_space *aspace,
+                           const address_space *aspace,
                            CORE_ADDR bp_addr,
                            const struct target_waitstatus *ws)
 {
@@ -8394,7 +8047,7 @@ breakpoint_hit_catch_solib (const struct bp_location *bl,
     if (other->type != bp_shlib_event)
       continue;
 
-    if (self->base.pspace != NULL && other->pspace != self->base.pspace)
+    if (self->pspace != NULL && other->pspace != self->pspace)
       continue;
 
     for (other_bl = other->loc; other_bl != NULL; other_bl = other_bl->next)
@@ -8424,7 +8077,7 @@ check_status_catch_solib (struct bpstats *bs)
           ++ix)
        {
          if (!self->regex
-             || regexec (&self->compiled, iter->so_name, 0, NULL, 0) == 0)
+             || self->compiled->exec (iter->so_name, 0, NULL, 0) == 0)
            return;
        }
     }
@@ -8438,7 +8091,7 @@ check_status_catch_solib (struct bpstats *bs)
           ++ix)
        {
          if (!self->regex
-             || regexec (&self->compiled, iter, 0, NULL, 0) == 0)
+             || self->compiled->exec (iter, 0, NULL, 0) == 0)
            return;
        }
     }
@@ -8456,13 +8109,13 @@ print_it_catch_solib (bpstat bs)
   annotate_catchpoint (b->number);
   maybe_print_thread_hit_breakpoint (uiout);
   if (b->disposition == disp_del)
-    ui_out_text (uiout, "Temporary catchpoint ");
+    uiout->text ("Temporary catchpoint ");
   else
-    ui_out_text (uiout, "Catchpoint ");
-  ui_out_field_int (uiout, "bkptno", b->number);
-  ui_out_text (uiout, "\n");
-  if (ui_out_is_mi_like_p (uiout))
-    ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
+    uiout->text ("Catchpoint ");
+  uiout->field_int ("bkptno", b->number);
+  uiout->text ("\n");
+  if (uiout->is_mi_like_p ())
+    uiout->field_string ("disp", bpdisp_text (b->disposition));
   print_solib_event (1);
   return PRINT_SRC_AND_LOC;
 }
@@ -8482,7 +8135,7 @@ print_one_catch_solib (struct breakpoint *b, struct bp_location **locs)
   if (opts.addressprint)
     {
       annotate_field (4);
-      ui_out_field_skip (uiout, "addr");
+      uiout->field_skip ("addr");
     }
 
   annotate_field (5);
@@ -8500,12 +8153,11 @@ print_one_catch_solib (struct breakpoint *b, struct bp_location **locs)
       else
        msg = xstrdup (_("unload of library"));
     }
-  ui_out_field_string (uiout, "what", msg);
+  uiout->field_string ("what", msg);
   xfree (msg);
 
-  if (ui_out_is_mi_like_p (uiout))
-    ui_out_field_string (uiout, "catch-type",
-                        self->is_load ? "load" : "unload");
+  if (uiout->is_mi_like_p ())
+    uiout->field_string ("catch-type", self->is_load ? "load" : "unload");
 }
 
 static void
@@ -8540,49 +8192,37 @@ static struct breakpoint_ops catch_solib_breakpoint_ops;
    created in an enabled state.  */
 
 void
-add_solib_catchpoint (char *arg, int is_load, int is_temp, int enabled)
+add_solib_catchpoint (const char *arg, int is_load, int is_temp, int enabled)
 {
-  struct solib_catchpoint *c;
   struct gdbarch *gdbarch = get_current_arch ();
-  struct cleanup *cleanup;
 
   if (!arg)
     arg = "";
   arg = skip_spaces (arg);
 
-  c = new solib_catchpoint ();
-  cleanup = make_cleanup (xfree, c);
+  std::unique_ptr<solib_catchpoint> c (new solib_catchpoint ());
 
   if (*arg != '\0')
     {
-      int errcode;
-
-      errcode = regcomp (&c->compiled, arg, REG_NOSUB);
-      if (errcode != 0)
-       {
-         char *err = get_regcomp_error (errcode, &c->compiled);
-
-         make_cleanup (xfree, err);
-         error (_("Invalid regexp (%s): %s"), err, arg);
-       }
+      c->compiled.reset (new compiled_regex (arg, REG_NOSUB,
+                                            _("Invalid regexp")));
       c->regex = xstrdup (arg);
     }
 
   c->is_load = is_load;
-  init_catchpoint (&c->base, gdbarch, is_temp, NULL,
+  init_catchpoint (c.get (), gdbarch, is_temp, NULL,
                   &catch_solib_breakpoint_ops);
 
-  c->base.enable_state = enabled ? bp_enabled : bp_disabled;
+  c->enable_state = enabled ? bp_enabled : bp_disabled;
 
-  discard_cleanups (cleanup);
-  install_breakpoint (0, &c->base, 1);
+  install_breakpoint (0, std::move (c), 1);
 }
 
 /* A helper function that does all the work for "catch load" and
    "catch unload".  */
 
 static void
-catch_load_or_unload (char *arg, int from_tty, int is_load,
+catch_load_or_unload (const char *arg, int from_tty, int is_load,
                      struct cmd_list_element *command)
 {
   int tempflag;
@@ -8594,14 +8234,14 @@ catch_load_or_unload (char *arg, int from_tty, int is_load,
 }
 
 static void
-catch_load_command_1 (char *arg, int from_tty,
+catch_load_command_1 (const char *arg, int from_tty,
                      struct cmd_list_element *command)
 {
   catch_load_or_unload (arg, from_tty, 1, command);
 }
 
 static void
-catch_unload_command_1 (char *arg, int from_tty,
+catch_unload_command_1 (const char *arg, int from_tty,
                        struct cmd_list_element *command)
 {
   catch_load_or_unload (arg, from_tty, 0, command);
@@ -8615,12 +8255,10 @@ catch_unload_command_1 (char *arg, int from_tty,
 void
 init_catchpoint (struct breakpoint *b,
                 struct gdbarch *gdbarch, int tempflag,
-                char *cond_string,
+                const char *cond_string,
                 const struct breakpoint_ops *ops)
 {
-  struct symtab_and_line sal;
-
-  init_sal (&sal);
+  symtab_and_line sal;
   sal.pspace = current_program_space;
 
   init_raw_breakpoint (b, gdbarch, sal, bp_catchpoint, ops);
@@ -8630,9 +8268,9 @@ init_catchpoint (struct breakpoint *b,
 }
 
 void
-install_breakpoint (int internal, struct breakpoint *b, int update_gll)
+install_breakpoint (int internal, std::unique_ptr<breakpoint> &&arg, int update_gll)
 {
-  add_to_breakpoint_chain (b);
+  breakpoint *b = add_to_breakpoint_chain (std::move (arg));
   set_breakpoint_number (internal, b);
   if (is_tracepoint (b))
     set_tracepoint_count (breakpoint_count);
@@ -8646,30 +8284,27 @@ install_breakpoint (int internal, struct breakpoint *b, int update_gll)
 
 static void
 create_fork_vfork_event_catchpoint (struct gdbarch *gdbarch,
-                                   int tempflag, char *cond_string,
+                                   int tempflag, const char *cond_string,
                                     const struct breakpoint_ops *ops)
 {
-  struct fork_catchpoint *c = new fork_catchpoint ();
+  std::unique_ptr<fork_catchpoint> c (new fork_catchpoint ());
 
-  init_catchpoint (&c->base, gdbarch, tempflag, cond_string, ops);
+  init_catchpoint (c.get (), gdbarch, tempflag, cond_string, ops);
 
   c->forked_inferior_pid = null_ptid;
 
-  install_breakpoint (0, &c->base, 1);
+  install_breakpoint (0, std::move (c), 1);
 }
 
 /* Exec catchpoints.  */
 
 /* An instance of this type is used to represent an exec catchpoint.
-   It includes a "struct breakpoint" as a kind of base class; users
-   downcast to "struct breakpoint *" when needed.  A breakpoint is
-   really of this type iff its ops pointer points to
+   A breakpoint is really of this type iff its ops pointer points to
    CATCH_EXEC_BREAKPOINT_OPS.  */
 
-struct exec_catchpoint
+struct exec_catchpoint : public breakpoint
 {
-  /* The base class.  */
-  struct breakpoint base;
+  ~exec_catchpoint () override;
 
   /* Filename of a program whose exec triggered this catchpoint.
      This field is only valid immediately after this catchpoint has
@@ -8677,17 +8312,11 @@ struct exec_catchpoint
   char *exec_pathname;
 };
 
-/* Implement the "dtor" breakpoint_ops method for exec
-   catchpoints.  */
+/* Exec catchpoint destructor.  */
 
-static void
-dtor_catch_exec (struct breakpoint *b)
+exec_catchpoint::~exec_catchpoint ()
 {
-  struct exec_catchpoint *c = (struct exec_catchpoint *) b;
-
-  xfree (c->exec_pathname);
-
-  base_breakpoint_ops.dtor (b);
+  xfree (this->exec_pathname);
 }
 
 static int
@@ -8704,7 +8333,7 @@ remove_catch_exec (struct bp_location *bl, enum remove_bp_reason reason)
 
 static int
 breakpoint_hit_catch_exec (const struct bp_location *bl,
-                          struct address_space *aspace, CORE_ADDR bp_addr,
+                          const address_space *aspace, CORE_ADDR bp_addr,
                           const struct target_waitstatus *ws)
 {
   struct exec_catchpoint *c = (struct exec_catchpoint *) bl->owner;
@@ -8726,19 +8355,18 @@ print_it_catch_exec (bpstat bs)
   annotate_catchpoint (b->number);
   maybe_print_thread_hit_breakpoint (uiout);
   if (b->disposition == disp_del)
-    ui_out_text (uiout, "Temporary catchpoint ");
+    uiout->text ("Temporary catchpoint ");
   else
-    ui_out_text (uiout, "Catchpoint ");
-  if (ui_out_is_mi_like_p (uiout))
+    uiout->text ("Catchpoint ");
+  if (uiout->is_mi_like_p ())
     {
-      ui_out_field_string (uiout, "reason",
-                          async_reason_lookup (EXEC_ASYNC_EXEC));
-      ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
+      uiout->field_string ("reason", async_reason_lookup (EXEC_ASYNC_EXEC));
+      uiout->field_string ("disp", bpdisp_text (b->disposition));
     }
-  ui_out_field_int (uiout, "bkptno", b->number);
-  ui_out_text (uiout, " (exec'd ");
-  ui_out_field_string (uiout, "new-exec", c->exec_pathname);
-  ui_out_text (uiout, "), ");
+  uiout->field_int ("bkptno", b->number);
+  uiout->text (" (exec'd ");
+  uiout->field_string ("new-exec", c->exec_pathname);
+  uiout->text ("), ");
 
   return PRINT_SRC_AND_LOC;
 }
@@ -8756,18 +8384,18 @@ print_one_catch_exec (struct breakpoint *b, struct bp_location **last_loc)
      not line up too nicely with the headers, but the effect
      is relatively readable).  */
   if (opts.addressprint)
-    ui_out_field_skip (uiout, "addr");
+    uiout->field_skip ("addr");
   annotate_field (5);
-  ui_out_text (uiout, "exec");
+  uiout->text ("exec");
   if (c->exec_pathname != NULL)
     {
-      ui_out_text (uiout, ", program \"");
-      ui_out_field_string (uiout, "what", c->exec_pathname);
-      ui_out_text (uiout, "\" ");
+      uiout->text (", program \"");
+      uiout->field_string ("what", c->exec_pathname);
+      uiout->text ("\" ");
     }
 
-  if (ui_out_is_mi_like_p (uiout))
-    ui_out_field_string (uiout, "catch-type", "exec");
+  if (uiout->is_mi_like_p ())
+    uiout->field_string ("catch-type", "exec");
 }
 
 static void
@@ -8910,9 +8538,9 @@ enable_breakpoints_after_startup (void)
 static struct breakpoint *
 new_single_step_breakpoint (int thread, struct gdbarch *gdbarch)
 {
-  struct breakpoint *b = new breakpoint ();
+  std::unique_ptr<breakpoint> b (new breakpoint ());
 
-  init_raw_breakpoint_without_location (b, gdbarch, bp_single_step,
+  init_raw_breakpoint_without_location (b.get (), gdbarch, bp_single_step,
                                        &momentary_breakpoint_ops);
 
   b->disposition = disp_donttouch;
@@ -8921,16 +8549,14 @@ new_single_step_breakpoint (int thread, struct gdbarch *gdbarch)
   b->thread = thread;
   gdb_assert (b->thread != 0);
 
-  add_to_breakpoint_chain (b);
-
-  return b;
+  return add_to_breakpoint_chain (std::move (b));
 }
 
 /* Set a momentary breakpoint of type TYPE at address specified by
    SAL.  If FRAME_ID is valid, the breakpoint is restricted to that
    frame.  */
 
-struct breakpoint *
+breakpoint_up
 set_momentary_breakpoint (struct gdbarch *gdbarch, struct symtab_and_line sal,
                          struct frame_id frame_id, enum bptype type)
 {
@@ -8953,7 +8579,7 @@ set_momentary_breakpoint (struct gdbarch *gdbarch, struct symtab_and_line sal,
 
   update_global_location_list_nothrow (UGLL_MAY_INSERT);
 
-  return b;
+  return breakpoint_up (b);
 }
 
 /* Make a momentary breakpoint based on the master breakpoint ORIG.
@@ -9006,7 +8632,7 @@ clone_momentary_breakpoint (struct breakpoint *orig)
   return momentary_breakpoint_from_master (orig, orig->type, orig->ops, 0);
 }
 
-struct breakpoint *
+breakpoint_up
 set_momentary_breakpoint_at_pc (struct gdbarch *gdbarch, CORE_ADDR pc,
                                enum bptype type)
 {
@@ -9027,7 +8653,7 @@ static void
 mention (struct breakpoint *b)
 {
   b->ops->print_mention (b);
-  if (ui_out_is_mi_like_p (current_uiout))
+  if (current_uiout->is_mi_like_p ())
     return;
   printf_filtered ("\n");
 }
@@ -9066,13 +8692,14 @@ add_location_to_breakpoint (struct breakpoint *b,
   loc->requested_address = sal->pc;
   loc->address = adjusted_address;
   loc->pspace = sal->pspace;
-  loc->probe.probe = sal->probe;
+  loc->probe.prob = sal->prob;
   loc->probe.objfile = sal->objfile;
   gdb_assert (loc->pspace != NULL);
   loc->section = sal->section;
   loc->gdbarch = loc_gdbarch;
   loc->line_number = sal->line;
   loc->symtab = sal->symtab;
+  loc->symbol = sal->symbol;
 
   set_breakpoint_location_function (loc,
                                    sal->explicit_pc || sal->explicit_line);
@@ -9106,8 +8733,6 @@ program_breakpoint_here_p (struct gdbarch *gdbarch, CORE_ADDR address)
   CORE_ADDR addr;
   const gdb_byte *bpoint;
   gdb_byte *target_mem;
-  struct cleanup *cleanup;
-  int retval = 0;
 
   addr = address;
   bpoint = gdbarch_breakpoint_from_pc (gdbarch, &addr, &len);
@@ -9121,15 +8746,14 @@ program_breakpoint_here_p (struct gdbarch *gdbarch, CORE_ADDR address)
   /* Enable the automatic memory restoration from breakpoints while
      we read the memory.  Otherwise we could say about our temporary
      breakpoints they are permanent.  */
-  cleanup = make_show_memory_breakpoints_cleanup (0);
+  scoped_restore restore_memory
+    = make_scoped_restore_show_memory_breakpoints (0);
 
   if (target_read_memory (address, target_mem, len) == 0
       && memcmp (target_mem, bpoint, len) == 0)
-    retval = 1;
-
-  do_cleanups (cleanup);
+    return 1;
 
-  return retval;
+  return 0;
 }
 
 /* Return 1 if LOC is pointing to a permanent breakpoint,
@@ -9138,9 +8762,6 @@ program_breakpoint_here_p (struct gdbarch *gdbarch, CORE_ADDR address)
 static int
 bp_loc_is_permanent (struct bp_location *loc)
 {
-  struct cleanup *cleanup;
-  int retval;
-
   gdb_assert (loc != NULL);
 
   /* If we have a catchpoint or a watchpoint, just return 0.  We should not
@@ -9150,14 +8771,9 @@ bp_loc_is_permanent (struct bp_location *loc)
   if (!breakpoint_address_is_meaningful (loc->owner))
     return 0;
 
-  cleanup = save_current_space_and_thread ();
+  scoped_restore_current_pspace_and_thread restore_pspace_thread;
   switch_to_program_space_and_thread (loc->pspace);
-
-  retval = program_breakpoint_here_p (loc->gdbarch, loc->address);
-
-  do_cleanups (cleanup);
-
-  return retval;
+  return program_breakpoint_here_p (loc->gdbarch, loc->address);
 }
 
 /* Build a command list for the dprintf corresponding to the current
@@ -9225,7 +8841,7 @@ update_dprintf_command_list (struct breakpoint *b)
     printf_cmd_line->next = NULL;
     printf_cmd_line->line = printf_line;
 
-    breakpoint_set_commands (b, printf_cmd_line);
+    breakpoint_set_commands (b, command_line_up (printf_cmd_line));
   }
 }
 
@@ -9233,7 +8849,7 @@ update_dprintf_command_list (struct breakpoint *b)
    current style settings.  */
 
 static void
-update_dprintf_commands (char *args, int from_tty,
+update_dprintf_commands (const char *args, int from_tty,
                         struct cmd_list_element *c)
 {
   struct breakpoint *b;
@@ -9252,10 +8868,11 @@ update_dprintf_commands (char *args, int from_tty,
 
 static void
 init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
-                    struct symtabs_and_lines sals,
-                    struct event_location *location,
-                    char *filter, char *cond_string,
-                    char *extra_string,
+                    gdb::array_view<const symtab_and_line> sals,
+                    event_location_up &&location,
+                    gdb::unique_xmalloc_ptr<char> filter,
+                    gdb::unique_xmalloc_ptr<char> cond_string,
+                    gdb::unique_xmalloc_ptr<char> extra_string,
                     enum bptype type, enum bpdisp disposition,
                     int thread, int task, int ignore_count,
                     const struct breakpoint_ops *ops, int from_tty,
@@ -9278,11 +8895,10 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
        error (_("Hardware breakpoints used exceeds limit."));
     }
 
-  gdb_assert (sals.nelts > 0);
+  gdb_assert (!sals.empty ());
 
-  for (i = 0; i < sals.nelts; ++i)
+  for (const auto &sal : sals)
     {
-      struct symtab_and_line sal = sals.sals[i];
       struct bp_location *loc;
 
       if (from_tty)
@@ -9295,14 +8911,14 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
                                      sal.pspace, sal.pc, sal.section, thread);
        }
 
-      if (i == 0)
+      if (&sal == &sals[0])
        {
          init_raw_breakpoint (b, gdbarch, sal, type, ops);
          b->thread = thread;
          b->task = task;
 
-         b->cond_string = cond_string;
-         b->extra_string = extra_string;
+         b->cond_string = cond_string.release ();
+         b->extra_string = extra_string.release ();
          b->ignore_count = ignore_count;
          b->enable_state = enabled ? bp_enabled : bp_disabled;
          b->disposition = disposition;
@@ -9319,13 +8935,14 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
                {
                  /* We already know the marker exists, otherwise, we
                     wouldn't see a sal for it.  */
-                 const char *p = &event_location_to_string (b->location)[3];
+                 const char *p
+                   = &event_location_to_string (b->location.get ())[3];
                  const char *endp;
                  char *marker_str;
 
-                 p = skip_spaces_const (p);
+                 p = skip_spaces (p);
 
-                 endp = skip_to_space_const (p);
+                 endp = skip_to_space (p);
 
                  marker_str = savestring (p, endp - p);
                  t->static_trace_marker_id = marker_str;
@@ -9382,61 +8999,39 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
 
   b->display_canonical = display_canonical;
   if (location != NULL)
-    b->location = location;
+    b->location = std::move (location);
   else
-    {
-      const char *addr_string = NULL;
-      int addr_string_len = 0;
-
-      if (location != NULL)
-       addr_string = event_location_to_string (location);
-      if (addr_string != NULL)
-       addr_string_len = strlen (addr_string);
-
-      b->location = new_address_location (b->loc->address,
-                                         addr_string, addr_string_len);
-    }
-  b->filter = filter;
+    b->location = new_address_location (b->loc->address, NULL, 0);
+  b->filter = filter.release ();
 }
 
 static void
 create_breakpoint_sal (struct gdbarch *gdbarch,
-                      struct symtabs_and_lines sals,
-                      struct event_location *location,
-                      char *filter, char *cond_string,
-                      char *extra_string,
+                      gdb::array_view<const symtab_and_line> sals,
+                      event_location_up &&location,
+                      gdb::unique_xmalloc_ptr<char> filter,
+                      gdb::unique_xmalloc_ptr<char> cond_string,
+                      gdb::unique_xmalloc_ptr<char> extra_string,
                       enum bptype type, enum bpdisp disposition,
                       int thread, int task, int ignore_count,
                       const struct breakpoint_ops *ops, int from_tty,
                       int enabled, int internal, unsigned flags,
                       int display_canonical)
 {
-  struct breakpoint *b;
-  struct cleanup *old_chain;
-
-  if (is_tracepoint_type (type))
-    {
-      struct tracepoint *t;
-
-      t = new tracepoint ();
-      b = &t->base;
-    }
-  else
-    b = new breakpoint ();
-
-  old_chain = make_cleanup (xfree, b);
+  std::unique_ptr<breakpoint> b = new_breakpoint_from_type (type);
 
-  init_breakpoint_sal (b, gdbarch,
-                      sals, location,
-                      filter, cond_string, extra_string,
+  init_breakpoint_sal (b.get (), gdbarch,
+                      sals, std::move (location),
+                      std::move (filter),
+                      std::move (cond_string),
+                      std::move (extra_string),
                       type, disposition,
                       thread, task, ignore_count,
                       ops, from_tty,
                       enabled, internal, flags,
                       display_canonical);
-  discard_cleanups (old_chain);
 
-  install_breakpoint (internal, b, 0);
+  install_breakpoint (internal, std::move (b), 0);
 }
 
 /* Add SALS.nelts breakpoints to the breakpoint table.  For each
@@ -9457,38 +9052,35 @@ create_breakpoint_sal (struct gdbarch *gdbarch,
 static void
 create_breakpoints_sal (struct gdbarch *gdbarch,
                        struct linespec_result *canonical,
-                       char *cond_string, char *extra_string,
+                       gdb::unique_xmalloc_ptr<char> cond_string,
+                       gdb::unique_xmalloc_ptr<char> extra_string,
                        enum bptype type, enum bpdisp disposition,
                        int thread, int task, int ignore_count,
                        const struct breakpoint_ops *ops, int from_tty,
                        int enabled, int internal, unsigned flags)
 {
-  int i;
-  struct linespec_sals *lsal;
-
   if (canonical->pre_expanded)
-    gdb_assert (VEC_length (linespec_sals, canonical->sals) == 1);
+    gdb_assert (canonical->lsals.size () == 1);
 
-  for (i = 0; VEC_iterate (linespec_sals, canonical->sals, i, lsal); ++i)
+  for (const auto &lsal : canonical->lsals)
     {
       /* Note that 'location' can be NULL in the case of a plain
         'break', without arguments.  */
-      struct event_location *location
+      event_location_up location
        = (canonical->location != NULL
-          ? copy_event_location (canonical->location) : NULL);
-      char *filter_string = lsal->canonical ? xstrdup (lsal->canonical) : NULL;
-      struct cleanup *inner = make_cleanup_delete_event_location (location);
-
-      make_cleanup (xfree, filter_string);
-      create_breakpoint_sal (gdbarch, lsal->sals,
-                            location,
-                            filter_string,
-                            cond_string, extra_string,
+          ? copy_event_location (canonical->location.get ()) : NULL);
+      gdb::unique_xmalloc_ptr<char> filter_string
+       (lsal.canonical != NULL ? xstrdup (lsal.canonical) : NULL);
+
+      create_breakpoint_sal (gdbarch, lsal.sals,
+                            std::move (location),
+                            std::move (filter_string),
+                            std::move (cond_string),
+                            std::move (extra_string),
                             type, disposition,
                             thread, task, ignore_count, ops,
                             from_tty, enabled, internal, flags,
                             canonical->special_display);
-      discard_cleanups (inner);
     }
 }
 
@@ -9516,20 +9108,14 @@ parse_breakpoint_sals (const struct event_location *location,
             breakpoint address.  */
          if (last_displayed_sal_is_valid ())
            {
-             struct linespec_sals lsal;
-             struct symtab_and_line sal;
-             CORE_ADDR pc;
-
-             init_sal (&sal);          /* Initialize to zeroes.  */
-             lsal.sals.sals = XNEW (struct symtab_and_line);
-
              /* Set sal's pspace, pc, symtab, and line to the values
                 corresponding to the last call to print_frame_info.
                 Be sure to reinitialize LINE with NOTCURRENT == 0
                 as the breakpoint line number is inappropriate otherwise.
                 find_pc_line would adjust PC, re-set it back.  */
-             get_last_displayed_sal (&sal);
-             pc = sal.pc;
+             symtab_and_line sal = get_last_displayed_sal ();
+             CORE_ADDR pc = sal.pc;
+
              sal = find_pc_line (pc, 0);
 
              /* "break" without arguments is equivalent to "break *PC"
@@ -9540,11 +9126,11 @@ parse_breakpoint_sals (const struct event_location *location,
              sal.pc = pc;
              sal.explicit_pc = 1;
 
-             lsal.sals.sals[0] = sal;
-             lsal.sals.nelts = 1;
+             struct linespec_sals lsal;
+             lsal.sals = {sal};
              lsal.canonical = NULL;
 
-             VEC_safe_push (linespec_sals, canonical->sals, &lsal);
+             canonical->lsals.push_back (std::move (lsal));
              return;
            }
          else
@@ -9589,12 +9175,10 @@ parse_breakpoint_sals (const struct event_location *location,
    inserted as a breakpoint.  If it can't throw an error.  */
 
 static void
-breakpoint_sals_to_pc (struct symtabs_and_lines *sals)
+breakpoint_sals_to_pc (std::vector<symtab_and_line> &sals)
 {    
-  int i;
-
-  for (i = 0; i < sals->nelts; i++)
-    resolve_sal_pc (&sals->sals[i]);
+  for (auto &sal : sals)
+    resolve_sal_pc (&sal);
 }
 
 /* Fast tracepoints may have restrictions on valid locations.  For
@@ -9606,30 +9190,27 @@ breakpoint_sals_to_pc (struct symtabs_and_lines *sals)
 
 static void
 check_fast_tracepoint_sals (struct gdbarch *gdbarch,
-                           struct symtabs_and_lines *sals)
+                           gdb::array_view<const symtab_and_line> sals)
 {
-  int i, rslt;
-  struct symtab_and_line *sal;
+  int rslt;
   char *msg;
   struct cleanup *old_chain;
 
-  for (i = 0; i < sals->nelts; i++)
+  for (const auto &sal : sals)
     {
       struct gdbarch *sarch;
 
-      sal = &sals->sals[i];
-
-      sarch = get_sal_arch (*sal);
+      sarch = get_sal_arch (sal);
       /* We fall back to GDBARCH if there is no architecture
         associated with SAL.  */
       if (sarch == NULL)
        sarch = gdbarch;
-      rslt = gdbarch_fast_tracepoint_valid_at (sarch, sal->pc, &msg);
+      rslt = gdbarch_fast_tracepoint_valid_at (sarch, sal.pc, &msg);
       old_chain = make_cleanup (xfree, msg);
 
       if (!rslt)
        error (_("May not have a fast tracepoint at %s%s"),
-              paddress (sarch, sal->pc), (msg ? msg : ""));
+              paddress (sarch, sal.pc), (msg ? msg : ""));
 
       do_cleanups (old_chain);
     }
@@ -9659,7 +9240,7 @@ find_condition_and_thread (const char *tok, CORE_ADDR pc,
       const char *cond_start = NULL;
       const char *cond_end = NULL;
 
-      tok = skip_spaces_const (tok);
+      tok = skip_spaces (tok);
 
       if ((*tok == '"' || *tok == ',') && rest)
        {
@@ -9667,7 +9248,7 @@ find_condition_and_thread (const char *tok, CORE_ADDR pc,
          return;
        }
 
-      end_tok = skip_to_space_const (tok);
+      end_tok = skip_to_space (tok);
 
       toklen = end_tok - tok;
 
@@ -9714,47 +9295,41 @@ find_condition_and_thread (const char *tok, CORE_ADDR pc,
 
 /* Decode a static tracepoint marker spec.  */
 
-static struct symtabs_and_lines
+static std::vector<symtab_and_line>
 decode_static_tracepoint_spec (const char **arg_p)
 {
   VEC(static_tracepoint_marker_p) *markers = NULL;
-  struct symtabs_and_lines sals;
-  struct cleanup *old_chain;
   const char *p = &(*arg_p)[3];
   const char *endp;
-  char *marker_str;
   int i;
 
-  p = skip_spaces_const (p);
+  p = skip_spaces (p);
 
-  endp = skip_to_space_const (p);
+  endp = skip_to_space (p);
 
-  marker_str = savestring (p, endp - p);
-  old_chain = make_cleanup (xfree, marker_str);
+  std::string marker_str (p, endp - p);
 
-  markers = target_static_tracepoint_markers_by_strid (marker_str);
+  markers = target_static_tracepoint_markers_by_strid (marker_str.c_str ());
   if (VEC_empty(static_tracepoint_marker_p, markers))
-    error (_("No known static tracepoint marker named %s"), marker_str);
+    error (_("No known static tracepoint marker named %s"),
+          marker_str.c_str ());
 
-  sals.nelts = VEC_length(static_tracepoint_marker_p, markers);
-  sals.sals = XNEWVEC (struct symtab_and_line, sals.nelts);
+  std::vector<symtab_and_line> sals;
+  sals.reserve (VEC_length(static_tracepoint_marker_p, markers));
 
-  for (i = 0; i < sals.nelts; i++)
+  for (i = 0; i < VEC_length(static_tracepoint_marker_p, markers); i++)
     {
       struct static_tracepoint_marker *marker;
 
       marker = VEC_index (static_tracepoint_marker_p, markers, i);
 
-      init_sal (&sals.sals[i]);
-
-      sals.sals[i] = find_pc_line (marker->address, 0);
-      sals.sals[i].pc = marker->address;
+      symtab_and_line sal = find_pc_line (marker->address, 0);
+      sal.pc = marker->address;
+      sals.push_back (sal);
 
       release_static_tracepoint_marker (marker);
     }
 
-  do_cleanups (old_chain);
-
   *arg_p = endp;
   return sals;
 }
@@ -9763,8 +9338,9 @@ decode_static_tracepoint_spec (const char **arg_p)
 
 int
 create_breakpoint (struct gdbarch *gdbarch,
-                  const struct event_location *location, char *cond_string,
-                  int thread, char *extra_string,
+                  const struct event_location *location,
+                  const char *cond_string,
+                  int thread, const char *extra_string,
                   int parse_extra,
                   int tempflag, enum bptype type_wanted,
                   int ignore_count,
@@ -9774,7 +9350,6 @@ create_breakpoint (struct gdbarch *gdbarch,
                   unsigned flags)
 {
   struct linespec_result canonical;
-  struct cleanup *old_chain;
   struct cleanup *bkpt_chain = NULL;
   int pending = 0;
   int task = 0;
@@ -9786,8 +9361,6 @@ create_breakpoint (struct gdbarch *gdbarch,
   if (extra_string != NULL && *extra_string == '\0')
     extra_string = NULL;
 
-  init_linespec_result (&canonical);
-
   TRY
     {
       ops->create_sals_from_location (location, &canonical, type_wanted);
@@ -9824,12 +9397,9 @@ create_breakpoint (struct gdbarch *gdbarch,
     }
   END_CATCH
 
-  if (!pending && VEC_empty (linespec_sals, canonical.sals))
+  if (!pending && canonical.lsals.empty ())
     return 0;
 
-  /* Create a chain of things that always need to be cleaned up.  */
-  old_chain = make_cleanup_destroy_linespec_result (&canonical);
-
   /* ----------------------------- SNIP -----------------------------
      Anything added to the cleanup chain beyond this point is assumed
      to be part of a breakpoint.  If the breakpoint create succeeds
@@ -9840,21 +9410,15 @@ create_breakpoint (struct gdbarch *gdbarch,
      are ok for the target.  */
   if (!pending)
     {
-      int ix;
-      struct linespec_sals *iter;
-
-      for (ix = 0; VEC_iterate (linespec_sals, canonical.sals, ix, iter); ++ix)
-       breakpoint_sals_to_pc (&iter->sals);
+      for (auto &lsal : canonical.lsals)
+       breakpoint_sals_to_pc (lsal.sals);
     }
 
   /* Fast tracepoints may have additional restrictions on location.  */
   if (!pending && type_wanted == bp_fast_tracepoint)
     {
-      int ix;
-      struct linespec_sals *iter;
-
-      for (ix = 0; VEC_iterate (linespec_sals, canonical.sals, ix, iter); ++ix)
-       check_fast_tracepoint_sals (gdbarch, &iter->sals);
+      for (const auto &lsal : canonical.lsals)
+       check_fast_tracepoint_sals (gdbarch, lsal.sals);
     }
 
   /* Verify that condition can be parsed, before setting any
@@ -9862,28 +9426,25 @@ create_breakpoint (struct gdbarch *gdbarch,
      breakpoint.  */
   if (!pending)
     {
+      gdb::unique_xmalloc_ptr<char> cond_string_copy;
+      gdb::unique_xmalloc_ptr<char> extra_string_copy;
+
       if (parse_extra)
         {
          char *rest;
-         struct linespec_sals *lsal;
+         char *cond;
 
-         lsal = VEC_index (linespec_sals, canonical.sals, 0);
+         const linespec_sals &lsal = canonical.lsals[0];
 
          /* Here we only parse 'arg' to separate condition
             from thread number, so parsing in context of first
             sal is OK.  When setting the breakpoint we'll
             re-parse it in context of each sal.  */
 
-         find_condition_and_thread (extra_string, lsal->sals.sals[0].pc,
-                                    &cond_string, &thread, &task, &rest);
-         if (cond_string)
-           make_cleanup (xfree, cond_string);
-         if (rest)
-           make_cleanup (xfree, rest);
-         if (rest)
-           extra_string = rest;
-         else
-           extra_string = NULL;
+         find_condition_and_thread (extra_string, lsal.sals[0].pc,
+                                    &cond, &thread, &task, &rest);
+         cond_string_copy.reset (cond);
+         extra_string_copy.reset (rest);
         }
       else
         {
@@ -9893,39 +9454,25 @@ create_breakpoint (struct gdbarch *gdbarch,
 
          /* Create a private copy of condition string.  */
          if (cond_string)
-           {
-             cond_string = xstrdup (cond_string);
-             make_cleanup (xfree, cond_string);
-           }
+           cond_string_copy.reset (xstrdup (cond_string));
          /* Create a private copy of any extra string.  */
          if (extra_string)
-           {
-             extra_string = xstrdup (extra_string);
-             make_cleanup (xfree, extra_string);
-           }
+           extra_string_copy.reset (xstrdup (extra_string));
         }
 
       ops->create_breakpoints_sal (gdbarch, &canonical,
-                                  cond_string, extra_string, type_wanted,
+                                  std::move (cond_string_copy),
+                                  std::move (extra_string_copy),
+                                  type_wanted,
                                   tempflag ? disp_del : disp_donttouch,
                                   thread, task, ignore_count, ops,
                                   from_tty, enabled, internal, flags);
     }
   else
     {
-      struct breakpoint *b;
-
-      if (is_tracepoint_type (type_wanted))
-       {
-         struct tracepoint *t;
-
-         t = new tracepoint ();
-         b = &t->base;
-       }
-      else
-       b = new breakpoint ();
+      std::unique_ptr <breakpoint> b = new_breakpoint_from_type (type_wanted);
 
-      init_raw_breakpoint_without_location (b, gdbarch, type_wanted, ops);
+      init_raw_breakpoint_without_location (b.get (), gdbarch, type_wanted, ops);
       b->location = copy_event_location (location);
 
       if (parse_extra)
@@ -9933,22 +9480,12 @@ create_breakpoint (struct gdbarch *gdbarch,
       else
        {
          /* Create a private copy of condition string.  */
-         if (cond_string)
-           {
-             cond_string = xstrdup (cond_string);
-             make_cleanup (xfree, cond_string);
-           }
-         b->cond_string = cond_string;
+         b->cond_string = cond_string != NULL ? xstrdup (cond_string) : NULL;
          b->thread = thread;
        }
 
       /* Create a private copy of any extra string.  */
-      if (extra_string != NULL)
-       {
-         extra_string = xstrdup (extra_string);
-         make_cleanup (xfree, extra_string);
-       }
-      b->extra_string = extra_string;
+      b->extra_string = extra_string != NULL ? xstrdup (extra_string) : NULL;
       b->ignore_count = ignore_count;
       b->disposition = tempflag ? disp_del : disp_donttouch;
       b->condition_not_parsed = 1;
@@ -9957,10 +9494,10 @@ create_breakpoint (struct gdbarch *gdbarch,
            && type_wanted != bp_hardware_breakpoint) || thread != -1)
        b->pspace = current_program_space;
 
-      install_breakpoint (internal, b, 0);
+      install_breakpoint (internal, std::move (b), 0);
     }
   
-  if (VEC_length (linespec_sals, canonical.sals) > 1)
+  if (canonical.lsals.size () > 1)
     {
       warning (_("Multiple breakpoints were set.\nUse the "
                 "\"delete\" command to delete unwanted breakpoints."));
@@ -9970,8 +9507,6 @@ create_breakpoint (struct gdbarch *gdbarch,
   /* That's it.  Discard the cleanups for data inserted into the
      breakpoint.  */
   discard_cleanups (bkpt_chain);
-  /* But cleanup everything else.  */
-  do_cleanups (old_chain);
 
   /* error call may happen here - have BKPT_CHAIN already discarded.  */
   update_global_location_list (UGLL_MAY_INSERT);
@@ -9987,28 +9522,25 @@ create_breakpoint (struct gdbarch *gdbarch,
    and BP_TEMPFLAG.  */
 
 static void
-break_command_1 (char *arg, int flag, int from_tty)
+break_command_1 (const char *arg, int flag, int from_tty)
 {
   int tempflag = flag & BP_TEMPFLAG;
   enum bptype type_wanted = (flag & BP_HARDWAREFLAG
                             ? bp_hardware_breakpoint
                             : bp_breakpoint);
   struct breakpoint_ops *ops;
-  struct event_location *location;
-  struct cleanup *cleanup;
 
-  location = string_to_event_location (&arg, current_language);
-  cleanup = make_cleanup_delete_event_location (location);
+  event_location_up location = string_to_event_location (&arg, current_language);
 
   /* Matching breakpoints on probes.  */
   if (location != NULL
-      && event_location_type (location) == PROBE_LOCATION)
+      && event_location_type (location.get ()) == PROBE_LOCATION)
     ops = &bkpt_probe_breakpoint_ops;
   else
     ops = &bkpt_breakpoint_ops;
 
   create_breakpoint (get_current_arch (),
-                    location,
+                    location.get (),
                     NULL, 0, arg, 1 /* parse arg */,
                     tempflag, type_wanted,
                     0 /* Ignore count */,
@@ -10018,7 +9550,6 @@ break_command_1 (char *arg, int flag, int from_tty)
                     1 /* enabled */,
                     0 /* internal */,
                     0);
-  do_cleanups (cleanup);
 }
 
 /* Helper function for break_command_1 and disassemble_command.  */
@@ -10065,47 +9596,43 @@ resolve_sal_pc (struct symtab_and_line *sal)
                 if we have line numbers but no functions (as can
                 happen in assembly source).  */
 
-             struct bound_minimal_symbol msym;
-             struct cleanup *old_chain = save_current_space_and_thread ();
-
+             scoped_restore_current_pspace_and_thread restore_pspace_thread;
              switch_to_program_space_and_thread (sal->pspace);
 
-             msym = lookup_minimal_symbol_by_pc (sal->pc);
+             bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (sal->pc);
              if (msym.minsym)
                sal->section = MSYMBOL_OBJ_SECTION (msym.objfile, msym.minsym);
-
-             do_cleanups (old_chain);
            }
        }
     }
 }
 
 void
-break_command (char *arg, int from_tty)
+break_command (const char *arg, int from_tty)
 {
   break_command_1 (arg, 0, from_tty);
 }
 
 void
-tbreak_command (char *arg, int from_tty)
+tbreak_command (const char *arg, int from_tty)
 {
   break_command_1 (arg, BP_TEMPFLAG, from_tty);
 }
 
 static void
-hbreak_command (char *arg, int from_tty)
+hbreak_command (const char *arg, int from_tty)
 {
   break_command_1 (arg, BP_HARDWAREFLAG, from_tty);
 }
 
 static void
-thbreak_command (char *arg, int from_tty)
+thbreak_command (const char *arg, int from_tty)
 {
   break_command_1 (arg, (BP_TEMPFLAG | BP_HARDWAREFLAG), from_tty);
 }
 
 static void
-stop_command (char *arg, int from_tty)
+stop_command (const char *arg, int from_tty)
 {
   printf_filtered (_("Specify the type of breakpoint to set.\n\
 Usage: stop in <function | address>\n\
@@ -10113,7 +9640,7 @@ Usage: stop in <function | address>\n\
 }
 
 static void
-stopin_command (char *arg, int from_tty)
+stopin_command (const char *arg, int from_tty)
 {
   int badInput = 0;
 
@@ -10121,7 +9648,7 @@ stopin_command (char *arg, int from_tty)
     badInput = 1;
   else if (*arg != '*')
     {
-      char *argptr = arg;
+      const char *argptr = arg;
       int hasColon = 0;
 
       /* Look for a ':'.  If this is a line number specification, then
@@ -10146,7 +9673,7 @@ stopin_command (char *arg, int from_tty)
 }
 
 static void
-stopat_command (char *arg, int from_tty)
+stopat_command (const char *arg, int from_tty)
 {
   int badInput = 0;
 
@@ -10154,7 +9681,7 @@ stopat_command (char *arg, int from_tty)
     badInput = 1;
   else
     {
-      char *argptr = arg;
+      const char *argptr = arg;
       int hasColon = 0;
 
       /* Look for a ':'.  If there is a '::' then get out, otherwise
@@ -10183,13 +9710,9 @@ stopat_command (char *arg, int from_tty)
    line.  */
 
 static void
-dprintf_command (char *arg, int from_tty)
+dprintf_command (const char *arg, int from_tty)
 {
-  struct event_location *location;
-  struct cleanup *cleanup;
-
-  location = string_to_event_location (&arg, current_language);
-  cleanup = make_cleanup_delete_event_location (location);
+  event_location_up location = string_to_event_location (&arg, current_language);
 
   /* If non-NULL, ARG should have been advanced past the location;
      the next character must be ','.  */
@@ -10205,7 +9728,7 @@ dprintf_command (char *arg, int from_tty)
     }
 
   create_breakpoint (get_current_arch (),
-                    location,
+                    location.get (),
                     NULL, 0, arg, 1 /* parse arg */,
                     0, bp_dprintf,
                     0 /* Ignore count */,
@@ -10215,11 +9738,10 @@ dprintf_command (char *arg, int from_tty)
                     1 /* enabled */,
                     0 /* internal */,
                     0);
-  do_cleanups (cleanup);
 }
 
 static void
-agent_printf_command (char *arg, int from_tty)
+agent_printf_command (const char *arg, int from_tty)
 {
   error (_("May only run agent-printf on the target"));
 }
@@ -10229,7 +9751,7 @@ agent_printf_command (char *arg, int from_tty)
 
 static int
 breakpoint_hit_ranged_breakpoint (const struct bp_location *bl,
-                                 struct address_space *aspace,
+                                 const address_space *aspace,
                                  CORE_ADDR bp_addr,
                                  const struct target_waitstatus *ws)
 {
@@ -10270,17 +9792,17 @@ print_it_ranged_breakpoint (bpstat bs)
   maybe_print_thread_hit_breakpoint (uiout);
 
   if (b->disposition == disp_del)
-    ui_out_text (uiout, "Temporary ranged breakpoint ");
+    uiout->text ("Temporary ranged breakpoint ");
   else
-    ui_out_text (uiout, "Ranged breakpoint ");
-  if (ui_out_is_mi_like_p (uiout))
+    uiout->text ("Ranged breakpoint ");
+  if (uiout->is_mi_like_p ())
     {
-      ui_out_field_string (uiout, "reason",
+      uiout->field_string ("reason",
                      async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
-      ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
+      uiout->field_string ("disp", bpdisp_text (b->disposition));
     }
-  ui_out_field_int (uiout, "bkptno", b->number);
-  ui_out_text (uiout, ", ");
+  uiout->field_int ("bkptno", b->number);
+  uiout->text (", ");
 
   return PRINT_SRC_AND_LOC;
 }
@@ -10304,7 +9826,7 @@ print_one_ranged_breakpoint (struct breakpoint *b,
   if (opts.addressprint)
     /* We don't print the address range here, it will be printed later
        by print_one_detail_ranged_breakpoint.  */
-    ui_out_field_skip (uiout, "addr");
+    uiout->field_skip ("addr");
   annotate_field (5);
   print_breakpoint_location (b, bl);
   *last_loc = bl;
@@ -10319,22 +9841,19 @@ print_one_detail_ranged_breakpoint (const struct breakpoint *b,
 {
   CORE_ADDR address_start, address_end;
   struct bp_location *bl = b->loc;
-  struct ui_file *stb = mem_fileopen ();
-  struct cleanup *cleanup = make_cleanup_ui_file_delete (stb);
+  string_file stb;
 
   gdb_assert (bl);
 
   address_start = bl->address;
   address_end = address_start + bl->length - 1;
 
-  ui_out_text (uiout, "\taddress range: ");
-  fprintf_unfiltered (stb, "[%s, %s]",
-                     print_core_address (bl->gdbarch, address_start),
-                     print_core_address (bl->gdbarch, address_end));
-  ui_out_field_stream (uiout, "addr", stb);
-  ui_out_text (uiout, "\n");
-
-  do_cleanups (cleanup);
+  uiout->text ("\taddress range: ");
+  stb.printf ("[%s, %s]",
+             print_core_address (bl->gdbarch, address_start),
+             print_core_address (bl->gdbarch, address_end));
+  uiout->field_stream ("addr", stb);
+  uiout->text ("\n");
 }
 
 /* Implement the "print_mention" breakpoint_ops method for
@@ -10349,7 +9868,7 @@ print_mention_ranged_breakpoint (struct breakpoint *b)
   gdb_assert (bl);
   gdb_assert (b->type == bp_hardware_breakpoint);
 
-  if (ui_out_is_mi_like_p (uiout))
+  if (uiout->is_mi_like_p ())
     return;
 
   printf_filtered (_("Hardware assisted ranged breakpoint %d from %s to %s."),
@@ -10364,8 +9883,8 @@ static void
 print_recreate_ranged_breakpoint (struct breakpoint *b, struct ui_file *fp)
 {
   fprintf_unfiltered (fp, "break-range %s, %s",
-                     event_location_to_string (b->location),
-                     event_location_to_string (b->location_range_end));
+                     event_location_to_string (b->location.get ()),
+                     event_location_to_string (b->location_range_end.get ()));
   print_recreate_thread (b, fp);
 }
 
@@ -10406,17 +9925,13 @@ find_breakpoint_range_end (struct symtab_and_line sal)
 /* Implement the "break-range" CLI command.  */
 
 static void
-break_range_command (char *arg, int from_tty)
+break_range_command (const char *arg, int from_tty)
 {
-  char *arg_start, *addr_string_start;
+  const char *arg_start;
   struct linespec_result canonical_start, canonical_end;
   int bp_count, can_use_bp, length;
   CORE_ADDR end;
   struct breakpoint *b;
-  struct symtab_and_line sal_start, sal_end;
-  struct cleanup *cleanup_bkpt;
-  struct linespec_sals *lsal_start, *lsal_end;
-  struct event_location *start_location, *end_location;
 
   /* We don't support software ranged breakpoints.  */
   if (target_ranged_break_num_registers () < 0)
@@ -10433,35 +9948,30 @@ break_range_command (char *arg, int from_tty)
   if (arg == NULL || arg[0] == '\0')
     error(_("No address range specified."));
 
-  init_linespec_result (&canonical_start);
-
   arg_start = arg;
-  start_location = string_to_event_location (&arg, current_language);
-  cleanup_bkpt = make_cleanup_delete_event_location (start_location);
-  parse_breakpoint_sals (start_location, &canonical_start);
-  make_cleanup_destroy_linespec_result (&canonical_start);
+  event_location_up start_location = string_to_event_location (&arg,
+                                                              current_language);
+  parse_breakpoint_sals (start_location.get (), &canonical_start);
 
   if (arg[0] != ',')
     error (_("Too few arguments."));
-  else if (VEC_empty (linespec_sals, canonical_start.sals))
+  else if (canonical_start.lsals.empty ())
     error (_("Could not find location of the beginning of the range."));
 
-  lsal_start = VEC_index (linespec_sals, canonical_start.sals, 0);
+  const linespec_sals &lsal_start = canonical_start.lsals[0];
 
-  if (VEC_length (linespec_sals, canonical_start.sals) > 1
-      || lsal_start->sals.nelts != 1)
+  if (canonical_start.lsals.size () > 1
+      || lsal_start.sals.size () != 1)
     error (_("Cannot create a ranged breakpoint with multiple locations."));
 
-  sal_start = lsal_start->sals.sals[0];
-  addr_string_start = savestring (arg_start, arg - arg_start);
-  make_cleanup (xfree, addr_string_start);
+  const symtab_and_line &sal_start = lsal_start.sals[0];
+  std::string addr_string_start (arg_start, arg - arg_start);
 
   arg++;       /* Skip the comma.  */
   arg = skip_spaces (arg);
 
   /* Parse the end location.  */
 
-  init_linespec_result (&canonical_end);
   arg_start = arg;
 
   /* We call decode_line_full directly here instead of using
@@ -10469,23 +9979,21 @@ break_range_command (char *arg, int from_tty)
      symtab and line as the default symtab and line for the end of the
      range.  This makes it possible to have ranges like "foo.c:27, +14",
      where +14 means 14 lines from the start location.  */
-  end_location = string_to_event_location (&arg, current_language);
-  make_cleanup_delete_event_location (end_location);
-  decode_line_full (end_location, DECODE_LINE_FUNFIRSTLINE, NULL,
+  event_location_up end_location = string_to_event_location (&arg,
+                                                            current_language);
+  decode_line_full (end_location.get (), DECODE_LINE_FUNFIRSTLINE, NULL,
                    sal_start.symtab, sal_start.line,
                    &canonical_end, NULL, NULL);
 
-  make_cleanup_destroy_linespec_result (&canonical_end);
-
-  if (VEC_empty (linespec_sals, canonical_end.sals))
+  if (canonical_end.lsals.empty ())
     error (_("Could not find location of the end of the range."));
 
-  lsal_end = VEC_index (linespec_sals, canonical_end.sals, 0);
-  if (VEC_length (linespec_sals, canonical_end.sals) > 1
-      || lsal_end->sals.nelts != 1)
+  const linespec_sals &lsal_end = canonical_end.lsals[0];
+  if (canonical_end.lsals.size () > 1
+      || lsal_end.sals.size () != 1)
     error (_("Cannot create a ranged breakpoint with multiple locations."));
 
-  sal_end = lsal_end->sals.sals[0];
+  const symtab_and_line &sal_end = lsal_end.sals[0];
 
   end = find_breakpoint_range_end (sal_end);
   if (sal_start.pc > end)
@@ -10499,9 +10007,7 @@ break_range_command (char *arg, int from_tty)
     {
       /* This range is simple enough to be handled by
         the `hbreak' command.  */
-      hbreak_command (addr_string_start, 1);
-
-      do_cleanups (cleanup_bkpt);
+      hbreak_command (&addr_string_start[0], 1);
 
       return;
     }
@@ -10512,12 +10018,10 @@ break_range_command (char *arg, int from_tty)
   set_breakpoint_count (breakpoint_count + 1);
   b->number = breakpoint_count;
   b->disposition = disp_donttouch;
-  b->location = copy_event_location (start_location);
-  b->location_range_end = copy_event_location (end_location);
+  b->location = std::move (start_location);
+  b->location_range_end = std::move (end_location);
   b->loc->length = length;
 
-  do_cleanups (cleanup_bkpt);
-
   mention (b);
   observer_notify_breakpoint_created (b);
   update_global_location_list (UGLL_MAY_INSERT);
@@ -10573,8 +10077,7 @@ watchpoint_exp_is_const (const struct expression *exp)
        case TERNOP_SLICE:
 
        case OP_LONG:
-       case OP_DOUBLE:
-       case OP_DECFLOAT:
+       case OP_FLOAT:
        case OP_LAST:
        case OP_COMPLEX:
        case OP_STRING:
@@ -10637,18 +10140,13 @@ watchpoint_exp_is_const (const struct expression *exp)
   return 1;
 }
 
-/* Implement the "dtor" breakpoint_ops method for watchpoints.  */
+/* Watchpoint destructor.  */
 
-static void
-dtor_watchpoint (struct breakpoint *self)
+watchpoint::~watchpoint ()
 {
-  struct watchpoint *w = (struct watchpoint *) self;
-
-  xfree (w->exp_string);
-  xfree (w->exp_string_reparse);
-  value_free (w->val);
-
-  base_breakpoint_ops.dtor (self);
+  xfree (this->exp_string);
+  xfree (this->exp_string_reparse);
+  value_free (this->val);
 }
 
 /* Implement the "re_set" breakpoint_ops method for watchpoints.  */
@@ -10712,7 +10210,7 @@ remove_watchpoint (struct bp_location *bl, enum remove_bp_reason reason)
 
 static int
 breakpoint_hit_watchpoint (const struct bp_location *bl,
-                          struct address_space *aspace, CORE_ADDR bp_addr,
+                          const address_space *aspace, CORE_ADDR bp_addr,
                           const struct target_waitstatus *ws)
 {
   struct breakpoint *b = bl->owner;
@@ -10764,9 +10262,7 @@ works_in_software_mode_watchpoint (const struct breakpoint *b)
 static enum print_stop_action
 print_it_watchpoint (bpstat bs)
 {
-  struct cleanup *old_chain;
   struct breakpoint *b;
-  struct ui_file *stb;
   enum print_stop_action result;
   struct watchpoint *w;
   struct ui_out *uiout = current_uiout;
@@ -10776,81 +10272,78 @@ print_it_watchpoint (bpstat bs)
   b = bs->breakpoint_at;
   w = (struct watchpoint *) b;
 
-  stb = mem_fileopen ();
-  old_chain = make_cleanup_ui_file_delete (stb);
-
   annotate_watchpoint (b->number);
   maybe_print_thread_hit_breakpoint (uiout);
 
+  string_file stb;
+
+  gdb::optional<ui_out_emit_tuple> tuple_emitter;
   switch (b->type)
     {
     case bp_watchpoint:
     case bp_hardware_watchpoint:
-      if (ui_out_is_mi_like_p (uiout))
-       ui_out_field_string
-         (uiout, "reason",
-          async_reason_lookup (EXEC_ASYNC_WATCHPOINT_TRIGGER));
+      if (uiout->is_mi_like_p ())
+       uiout->field_string
+         ("reason", async_reason_lookup (EXEC_ASYNC_WATCHPOINT_TRIGGER));
       mention (b);
-      make_cleanup_ui_out_tuple_begin_end (uiout, "value");
-      ui_out_text (uiout, "\nOld value = ");
-      watchpoint_value_print (bs->old_val, stb);
-      ui_out_field_stream (uiout, "old", stb);
-      ui_out_text (uiout, "\nNew value = ");
-      watchpoint_value_print (w->val, stb);
-      ui_out_field_stream (uiout, "new", stb);
-      ui_out_text (uiout, "\n");
+      tuple_emitter.emplace (uiout, "value");
+      uiout->text ("\nOld value = ");
+      watchpoint_value_print (bs->old_val, &stb);
+      uiout->field_stream ("old", stb);
+      uiout->text ("\nNew value = ");
+      watchpoint_value_print (w->val, &stb);
+      uiout->field_stream ("new", stb);
+      uiout->text ("\n");
       /* More than one watchpoint may have been triggered.  */
       result = PRINT_UNKNOWN;
       break;
 
     case bp_read_watchpoint:
-      if (ui_out_is_mi_like_p (uiout))
-       ui_out_field_string
-         (uiout, "reason",
-          async_reason_lookup (EXEC_ASYNC_READ_WATCHPOINT_TRIGGER));
+      if (uiout->is_mi_like_p ())
+       uiout->field_string
+         ("reason", async_reason_lookup (EXEC_ASYNC_READ_WATCHPOINT_TRIGGER));
       mention (b);
-      make_cleanup_ui_out_tuple_begin_end (uiout, "value");
-      ui_out_text (uiout, "\nValue = ");
-      watchpoint_value_print (w->val, stb);
-      ui_out_field_stream (uiout, "value", stb);
-      ui_out_text (uiout, "\n");
+      tuple_emitter.emplace (uiout, "value");
+      uiout->text ("\nValue = ");
+      watchpoint_value_print (w->val, &stb);
+      uiout->field_stream ("value", stb);
+      uiout->text ("\n");
       result = PRINT_UNKNOWN;
       break;
 
     case bp_access_watchpoint:
       if (bs->old_val != NULL)
        {
-         if (ui_out_is_mi_like_p (uiout))
-           ui_out_field_string
-             (uiout, "reason",
+         if (uiout->is_mi_like_p ())
+           uiout->field_string
+             ("reason",
               async_reason_lookup (EXEC_ASYNC_ACCESS_WATCHPOINT_TRIGGER));
          mention (b);
-         make_cleanup_ui_out_tuple_begin_end (uiout, "value");
-         ui_out_text (uiout, "\nOld value = ");
-         watchpoint_value_print (bs->old_val, stb);
-         ui_out_field_stream (uiout, "old", stb);
-         ui_out_text (uiout, "\nNew value = ");
+         tuple_emitter.emplace (uiout, "value");
+         uiout->text ("\nOld value = ");
+         watchpoint_value_print (bs->old_val, &stb);
+         uiout->field_stream ("old", stb);
+         uiout->text ("\nNew value = ");
        }
       else
        {
          mention (b);
-         if (ui_out_is_mi_like_p (uiout))
-           ui_out_field_string
-             (uiout, "reason",
+         if (uiout->is_mi_like_p ())
+           uiout->field_string
+             ("reason",
               async_reason_lookup (EXEC_ASYNC_ACCESS_WATCHPOINT_TRIGGER));
-         make_cleanup_ui_out_tuple_begin_end (uiout, "value");
-         ui_out_text (uiout, "\nValue = ");
+         tuple_emitter.emplace (uiout, "value");
+         uiout->text ("\nValue = ");
        }
-      watchpoint_value_print (w->val, stb);
-      ui_out_field_stream (uiout, "new", stb);
-      ui_out_text (uiout, "\n");
+      watchpoint_value_print (w->val, &stb);
+      uiout->field_stream ("new", stb);
+      uiout->text ("\n");
       result = PRINT_UNKNOWN;
       break;
     default:
       result = PRINT_UNKNOWN;
     }
 
-  do_cleanups (old_chain);
   return result;
 }
 
@@ -10860,37 +10353,37 @@ print_it_watchpoint (bpstat bs)
 static void
 print_mention_watchpoint (struct breakpoint *b)
 {
-  struct cleanup *ui_out_chain;
   struct watchpoint *w = (struct watchpoint *) b;
   struct ui_out *uiout = current_uiout;
+  const char *tuple_name;
 
   switch (b->type)
     {
     case bp_watchpoint:
-      ui_out_text (uiout, "Watchpoint ");
-      ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "wpt");
+      uiout->text ("Watchpoint ");
+      tuple_name = "wpt";
       break;
     case bp_hardware_watchpoint:
-      ui_out_text (uiout, "Hardware watchpoint ");
-      ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "wpt");
+      uiout->text ("Hardware watchpoint ");
+      tuple_name = "wpt";
       break;
     case bp_read_watchpoint:
-      ui_out_text (uiout, "Hardware read watchpoint ");
-      ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "hw-rwpt");
+      uiout->text ("Hardware read watchpoint ");
+      tuple_name = "hw-rwpt";
       break;
     case bp_access_watchpoint:
-      ui_out_text (uiout, "Hardware access (read/write) watchpoint ");
-      ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "hw-awpt");
+      uiout->text ("Hardware access (read/write) watchpoint ");
+      tuple_name = "hw-awpt";
       break;
     default:
       internal_error (__FILE__, __LINE__,
                      _("Invalid hardware watchpoint type."));
     }
 
-  ui_out_field_int (uiout, "number", b->number);
-  ui_out_text (uiout, ": ");
-  ui_out_field_string (uiout, "exp", w->exp_string);
-  do_cleanups (ui_out_chain);
+  ui_out_emit_tuple tuple_emitter (uiout, tuple_name);
+  uiout->field_int ("number", b->number);
+  uiout->text (": ");
+  uiout->field_string ("exp", w->exp_string);
 }
 
 /* Implement the "print_recreate" breakpoint_ops method for
@@ -11002,23 +10495,21 @@ print_it_masked_watchpoint (bpstat bs)
   switch (b->type)
     {
     case bp_hardware_watchpoint:
-      if (ui_out_is_mi_like_p (uiout))
-       ui_out_field_string
-         (uiout, "reason",
-          async_reason_lookup (EXEC_ASYNC_WATCHPOINT_TRIGGER));
+      if (uiout->is_mi_like_p ())
+       uiout->field_string
+         ("reason", async_reason_lookup (EXEC_ASYNC_WATCHPOINT_TRIGGER));
       break;
 
     case bp_read_watchpoint:
-      if (ui_out_is_mi_like_p (uiout))
-       ui_out_field_string
-         (uiout, "reason",
-          async_reason_lookup (EXEC_ASYNC_READ_WATCHPOINT_TRIGGER));
+      if (uiout->is_mi_like_p ())
+       uiout->field_string
+         ("reason", async_reason_lookup (EXEC_ASYNC_READ_WATCHPOINT_TRIGGER));
       break;
 
     case bp_access_watchpoint:
-      if (ui_out_is_mi_like_p (uiout))
-       ui_out_field_string
-         (uiout, "reason",
+      if (uiout->is_mi_like_p ())
+       uiout->field_string
+         ("reason",
           async_reason_lookup (EXEC_ASYNC_ACCESS_WATCHPOINT_TRIGGER));
       break;
     default:
@@ -11027,10 +10518,10 @@ print_it_masked_watchpoint (bpstat bs)
     }
 
   mention (b);
-  ui_out_text (uiout, _("\n\
+  uiout->text (_("\n\
 Check the underlying instruction at PC for the memory\n\
 address and value which triggered this watchpoint.\n"));
-  ui_out_text (uiout, "\n");
+  uiout->text ("\n");
 
   /* More than one watchpoint may have been triggered.  */
   return PRINT_UNKNOWN;
@@ -11048,9 +10539,9 @@ print_one_detail_masked_watchpoint (const struct breakpoint *b,
   /* Masked watchpoints have only one location.  */
   gdb_assert (b->loc && b->loc->next == NULL);
 
-  ui_out_text (uiout, "\tmask ");
-  ui_out_field_core_addr (uiout, "mask", b->loc->gdbarch, w->hw_wp_mask);
-  ui_out_text (uiout, "\n");
+  uiout->text ("\tmask ");
+  uiout->field_core_addr ("mask", b->loc->gdbarch, w->hw_wp_mask);
+  uiout->text ("\n");
 }
 
 /* Implement the "print_mention" breakpoint_ops method for
@@ -11061,31 +10552,31 @@ print_mention_masked_watchpoint (struct breakpoint *b)
 {
   struct watchpoint *w = (struct watchpoint *) b;
   struct ui_out *uiout = current_uiout;
-  struct cleanup *ui_out_chain;
+  const char *tuple_name;
 
   switch (b->type)
     {
     case bp_hardware_watchpoint:
-      ui_out_text (uiout, "Masked hardware watchpoint ");
-      ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "wpt");
+      uiout->text ("Masked hardware watchpoint ");
+      tuple_name = "wpt";
       break;
     case bp_read_watchpoint:
-      ui_out_text (uiout, "Masked hardware read watchpoint ");
-      ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "hw-rwpt");
+      uiout->text ("Masked hardware read watchpoint ");
+      tuple_name = "hw-rwpt";
       break;
     case bp_access_watchpoint:
-      ui_out_text (uiout, "Masked hardware access (read/write) watchpoint ");
-      ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "hw-awpt");
+      uiout->text ("Masked hardware access (read/write) watchpoint ");
+      tuple_name = "hw-awpt";
       break;
     default:
       internal_error (__FILE__, __LINE__,
                      _("Invalid hardware watchpoint type."));
     }
 
-  ui_out_field_int (uiout, "number", b->number);
-  ui_out_text (uiout, ": ");
-  ui_out_field_string (uiout, "exp", w->exp_string);
-  do_cleanups (ui_out_chain);
+  ui_out_emit_tuple tuple_emitter (uiout, tuple_name);
+  uiout->field_int ("number", b->number);
+  uiout->text (": ");
+  uiout->field_string ("exp", w->exp_string);
 }
 
 /* Implement the "print_recreate" breakpoint_ops method for
@@ -11137,11 +10628,10 @@ static void
 watch_command_1 (const char *arg, int accessflag, int from_tty,
                 int just_location, int internal)
 {
-  struct breakpoint *b, *scope_breakpoint = NULL;
+  struct breakpoint *scope_breakpoint = NULL;
   const struct block *exp_valid_block = NULL, *cond_exp_valid_block = NULL;
   struct value *val, *mark, *result;
   int saved_bitpos = 0, saved_bitsize = 0;
-  struct frame_info *frame;
   const char *exp_start = NULL;
   const char *exp_end = NULL;
   const char *tok, *end_tok;
@@ -11155,9 +10645,6 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
      the hardware watchpoint.  */
   int use_mask = 0;
   CORE_ADDR mask = 0;
-  struct watchpoint *w;
-  char *expression;
-  struct cleanup *back_to;
 
   /* Make sure that we actually have parameters to parse.  */
   if (arg != NULL && arg[0] != '\0')
@@ -11246,9 +10733,8 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
      is in terms of a newly allocated string instead of the original
      ARG.  */
   innermost_block = NULL;
-  expression = savestring (arg, exp_end - arg);
-  back_to = make_cleanup (xfree, expression);
-  exp_start = arg = expression;
+  std::string expression (arg, exp_end - arg);
+  exp_start = arg = expression.c_str ();
   expression_up exp = parse_exp_1 (&arg, 0, 0, 0);
   exp_end = arg;
   /* Remove trailing whitespace from the expression before saving it.
@@ -11300,8 +10786,8 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
   else if (val != NULL)
     release_value (val);
 
-  tok = skip_spaces_const (arg);
-  end_tok = skip_to_space_const (tok);
+  tok = skip_spaces (arg);
+  end_tok = skip_to_space (tok);
 
   toklen = end_tok - tok;
   if (toklen >= 1 && strncmp (tok, "if", toklen) == 0)
@@ -11319,35 +10805,44 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
   if (*tok)
     error (_("Junk at end of command."));
 
-  frame = block_innermost_frame (exp_valid_block);
+  frame_info *wp_frame = block_innermost_frame (exp_valid_block);
+
+  /* Save this because create_internal_breakpoint below invalidates
+     'wp_frame'.  */
+  frame_id watchpoint_frame = get_frame_id (wp_frame);
 
   /* If the expression is "local", then set up a "watchpoint scope"
      breakpoint at the point where we've left the scope of the watchpoint
      expression.  Create the scope breakpoint before the watchpoint, so
      that we will encounter it first in bpstat_stop_status.  */
-  if (exp_valid_block && frame)
+  if (exp_valid_block != NULL && wp_frame != NULL)
     {
-      if (frame_id_p (frame_unwind_caller_id (frame)))
+      frame_id caller_frame_id = frame_unwind_caller_id (wp_frame);
+
+      if (frame_id_p (caller_frame_id))
        {
+         gdbarch *caller_arch = frame_unwind_caller_arch (wp_frame);
+         CORE_ADDR caller_pc = frame_unwind_caller_pc (wp_frame);
+
          scope_breakpoint
-           = create_internal_breakpoint (frame_unwind_caller_arch (frame),
-                                         frame_unwind_caller_pc (frame),
+           = create_internal_breakpoint (caller_arch, caller_pc,
                                          bp_watchpoint_scope,
                                          &momentary_breakpoint_ops);
 
+         /* create_internal_breakpoint could invalidate WP_FRAME.  */
+         wp_frame = NULL;
+
          scope_breakpoint->enable_state = bp_enabled;
 
          /* Automatically delete the breakpoint when it hits.  */
          scope_breakpoint->disposition = disp_del;
 
          /* Only break in the proper frame (help with recursion).  */
-         scope_breakpoint->frame_id = frame_unwind_caller_id (frame);
+         scope_breakpoint->frame_id = caller_frame_id;
 
          /* Set the address at which we will stop.  */
-         scope_breakpoint->loc->gdbarch
-           = frame_unwind_caller_arch (frame);
-         scope_breakpoint->loc->requested_address
-           = frame_unwind_caller_pc (frame);
+         scope_breakpoint->loc->gdbarch = caller_arch;
+         scope_breakpoint->loc->requested_address = caller_pc;
          scope_breakpoint->loc->address
            = adjust_breakpoint_address (scope_breakpoint->loc->gdbarch,
                                         scope_breakpoint->loc->requested_address,
@@ -11367,17 +10862,17 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
   else
     bp_type = bp_hardware_watchpoint;
 
-  w = new watchpoint ();
-  b = &w->base;
+  std::unique_ptr<watchpoint> w (new watchpoint ());
+
   if (use_mask)
-    init_raw_breakpoint_without_location (b, NULL, bp_type,
+    init_raw_breakpoint_without_location (w.get (), NULL, bp_type,
                                          &masked_watchpoint_breakpoint_ops);
   else
-    init_raw_breakpoint_without_location (b, NULL, bp_type,
+    init_raw_breakpoint_without_location (w.get (), NULL, bp_type,
                                          &watchpoint_breakpoint_ops);
-  b->thread = thread;
-  b->disposition = disp_donttouch;
-  b->pspace = current_program_space;
+  w->thread = thread;
+  w->disposition = disp_donttouch;
+  w->pspace = current_program_space;
   w->exp = std::move (exp);
   w->exp_valid_block = exp_valid_block;
   w->cond_exp_valid_block = cond_exp_valid_block;
@@ -11386,18 +10881,11 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
       struct type *t = value_type (val);
       CORE_ADDR addr = value_as_address (val);
 
-      t = check_typedef (TYPE_TARGET_TYPE (check_typedef (t)));
-
-      std::string name = type_to_string (t);
-
-      w->exp_string_reparse = xstrprintf ("* (%s *) %s", name.c_str (),
-                                         core_addr_to_string (addr));
+      w->exp_string_reparse
+       = current_language->la_watch_location_expression (t, addr).release ();
 
       w->exp_string = xstrprintf ("-location %.*s",
                                  (int) (exp_end - exp_start), exp_start);
-
-      /* The above expression is in C.  */
-      b->language = language_c;
     }
   else
     w->exp_string = savestring (exp_start, exp_end - exp_start);
@@ -11415,13 +10903,13 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
     }
 
   if (cond_start)
-    b->cond_string = savestring (cond_start, cond_end - cond_start);
+    w->cond_string = savestring (cond_start, cond_end - cond_start);
   else
-    b->cond_string = 0;
+    w->cond_string = 0;
 
-  if (frame)
+  if (frame_id_p (watchpoint_frame))
     {
-      w->watchpoint_frame = get_frame_id (frame);
+      w->watchpoint_frame = watchpoint_frame;
       w->watchpoint_thread = inferior_ptid;
     }
   else
@@ -11434,28 +10922,18 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
     {
       /* The scope breakpoint is related to the watchpoint.  We will
         need to act on them together.  */
-      b->related_breakpoint = scope_breakpoint;
-      scope_breakpoint->related_breakpoint = b;
+      w->related_breakpoint = scope_breakpoint;
+      scope_breakpoint->related_breakpoint = w.get ();
     }
 
   if (!just_location)
     value_free_to_mark (mark);
 
-  TRY
-    {
-      /* Finally update the new watchpoint.  This creates the locations
-        that should be inserted.  */
-      update_watchpoint (w, 1);
-    }
-  CATCH (e, RETURN_MASK_ALL)
-    {
-      delete_breakpoint (b);
-      throw_exception (e);
-    }
-  END_CATCH
+  /* Finally update the new watchpoint.  This creates the locations
+     that should be inserted.  */
+  update_watchpoint (w.get (), 1);
 
-  install_breakpoint (internal, b, 1);
-  do_cleanups (back_to);
+  install_breakpoint (internal, std::move (w), 1);
 }
 
 /* Return count of debug registers needed to watch the given expression.
@@ -11543,7 +11021,7 @@ can_use_hardware_watchpoint (struct value *v)
 }
 
 void
-watch_command_wrapper (char *arg, int from_tty, int internal)
+watch_command_wrapper (const char *arg, int from_tty, int internal)
 {
   watch_command_1 (arg, hw_write, from_tty, 0, internal);
 }
@@ -11552,7 +11030,7 @@ watch_command_wrapper (char *arg, int from_tty, int internal)
    calls watch_command_1.  */
 
 static void
-watch_maybe_just_location (char *arg, int accessflag, int from_tty)
+watch_maybe_just_location (const char *arg, int accessflag, int from_tty)
 {
   int just_location = 0;
 
@@ -11568,31 +11046,31 @@ watch_maybe_just_location (char *arg, int accessflag, int from_tty)
 }
 
 static void
-watch_command (char *arg, int from_tty)
+watch_command (const char *arg, int from_tty)
 {
   watch_maybe_just_location (arg, hw_write, from_tty);
 }
 
 void
-rwatch_command_wrapper (char *arg, int from_tty, int internal)
+rwatch_command_wrapper (const char *arg, int from_tty, int internal)
 {
   watch_command_1 (arg, hw_read, from_tty, 0, internal);
 }
 
 static void
-rwatch_command (char *arg, int from_tty)
+rwatch_command (const char *arg, int from_tty)
 {
   watch_maybe_just_location (arg, hw_read, from_tty);
 }
 
 void
-awatch_command_wrapper (char *arg, int from_tty, int internal)
+awatch_command_wrapper (const char *arg, int from_tty, int internal)
 {
   watch_command_1 (arg, hw_access, from_tty, 0, internal);
 }
 
 static void
-awatch_command (char *arg, int from_tty)
+awatch_command (const char *arg, int from_tty)
 {
   watch_maybe_just_location (arg, hw_access, from_tty);
 }
@@ -11640,8 +11118,8 @@ static struct thread_fsm_ops until_break_fsm_ops =
 
 static struct until_break_fsm *
 new_until_break_fsm (struct interp *cmd_interp, int thread,
-                    struct breakpoint *location_breakpoint,
-                    struct breakpoint *caller_breakpoint)
+                    breakpoint_up &&location_breakpoint,
+                    breakpoint_up &&caller_breakpoint)
 {
   struct until_break_fsm *sm;
 
@@ -11649,8 +11127,8 @@ new_until_break_fsm (struct interp *cmd_interp, int thread,
   thread_fsm_ctor (&sm->thread_fsm, &until_break_fsm_ops, cmd_interp);
 
   sm->thread = thread;
-  sm->location_breakpoint = location_breakpoint;
-  sm->caller_breakpoint = caller_breakpoint;
+  sm->location_breakpoint = location_breakpoint.release ();
+  sm->caller_breakpoint = caller_breakpoint.release ();
 
   return sm;
 }
@@ -11707,20 +11185,15 @@ until_break_fsm_async_reply_reason (struct thread_fsm *self)
 }
 
 void
-until_break_command (char *arg, int from_tty, int anywhere)
+until_break_command (const char *arg, int from_tty, int anywhere)
 {
-  struct symtabs_and_lines sals;
-  struct symtab_and_line sal;
   struct frame_info *frame;
   struct gdbarch *frame_gdbarch;
   struct frame_id stack_frame_id;
   struct frame_id caller_frame_id;
-  struct breakpoint *location_breakpoint;
-  struct breakpoint *caller_breakpoint = NULL;
-  struct cleanup *old_chain, *cleanup;
+  struct cleanup *old_chain;
   int thread;
   struct thread_info *tp;
-  struct event_location *location;
   struct until_break_fsm *sm;
 
   clear_proceed_status (0);
@@ -11728,22 +11201,20 @@ until_break_command (char *arg, int from_tty, int anywhere)
   /* Set a breakpoint where the user wants it and at return from
      this function.  */
 
-  location = string_to_event_location (&arg, current_language);
-  cleanup = make_cleanup_delete_event_location (location);
+  event_location_up location = string_to_event_location (&arg, current_language);
 
-  if (last_displayed_sal_is_valid ())
-    sals = decode_line_1 (location, DECODE_LINE_FUNFIRSTLINE, NULL,
-                         get_last_displayed_symtab (),
-                         get_last_displayed_line ());
-  else
-    sals = decode_line_1 (location, DECODE_LINE_FUNFIRSTLINE,
-                         NULL, (struct symtab *) NULL, 0);
+  std::vector<symtab_and_line> sals
+    = (last_displayed_sal_is_valid ()
+       ? decode_line_1 (location.get (), DECODE_LINE_FUNFIRSTLINE, NULL,
+                       get_last_displayed_symtab (),
+                       get_last_displayed_line ())
+       : decode_line_1 (location.get (), DECODE_LINE_FUNFIRSTLINE,
+                       NULL, (struct symtab *) NULL, 0));
 
-  if (sals.nelts != 1)
+  if (sals.size () != 1)
     error (_("Couldn't get information on specified line."));
 
-  sal = sals.sals[0];
-  xfree (sals.sals);   /* malloc'd, so freed.  */
+  symtab_and_line &sal = sals[0];
 
   if (*arg)
     error (_("Junk at end of arguments."));
@@ -11768,6 +11239,7 @@ until_break_command (char *arg, int from_tty, int anywhere)
   /* Keep within the current frame, or in frames called by the current
      one.  */
 
+  breakpoint_up caller_breakpoint;
   if (frame_id_p (caller_frame_id))
     {
       struct symtab_and_line sal2;
@@ -11780,7 +11252,6 @@ until_break_command (char *arg, int from_tty, int anywhere)
                                                    sal2,
                                                    caller_frame_id,
                                                    bp_until);
-      make_cleanup_delete_breakpoint (caller_breakpoint);
 
       set_longjmp_breakpoint (tp, caller_frame_id);
       make_cleanup (delete_longjmp_breakpoint_cleanup, &thread);
@@ -11789,6 +11260,7 @@ until_break_command (char *arg, int from_tty, int anywhere)
   /* set_momentary_breakpoint could invalidate FRAME.  */
   frame = NULL;
 
+  breakpoint_up location_breakpoint;
   if (anywhere)
     /* If the user told us to continue until a specified location,
        we don't specify a frame at which we need to stop.  */
@@ -11799,17 +11271,15 @@ until_break_command (char *arg, int from_tty, int anywhere)
        only at the very same frame.  */
     location_breakpoint = set_momentary_breakpoint (frame_gdbarch, sal,
                                                    stack_frame_id, bp_until);
-  make_cleanup_delete_breakpoint (location_breakpoint);
 
   sm = new_until_break_fsm (command_interp (), tp->global_num,
-                           location_breakpoint, caller_breakpoint);
+                           std::move (location_breakpoint),
+                           std::move (caller_breakpoint));
   tp->thread_fsm = &sm->thread_fsm;
 
   discard_cleanups (old_chain);
 
   proceed (-1, GDB_SIGNAL_DEFAULT);
-
-  do_cleanups (cleanup);
 }
 
 /* This function attempts to parse an optional "if <cond>" clause
@@ -11820,10 +11290,10 @@ until_break_command (char *arg, int from_tty, int anywhere)
    it updates arg to point to the first character following the parsed
    if clause in the arg string.  */
 
-char *
-ep_parse_optional_if_clause (char **arg)
+const char *
+ep_parse_optional_if_clause (const char **arg)
 {
-  char *cond_string;
+  const char *cond_string;
 
   if (((*arg)[0] != 'i') || ((*arg)[1] != 'f') || !isspace ((*arg)[2]))
     return NULL;
@@ -11854,11 +11324,11 @@ typedef enum
 catch_fork_kind;
 
 static void
-catch_fork_command_1 (char *arg, int from_tty, 
+catch_fork_command_1 (const char *arg, int from_tty,
                      struct cmd_list_element *command)
 {
   struct gdbarch *gdbarch = get_current_arch ();
-  char *cond_string = NULL;
+  const char *cond_string = NULL;
   catch_fork_kind fork_kind;
   int tempflag;
 
@@ -11901,13 +11371,12 @@ catch_fork_command_1 (char *arg, int from_tty,
 }
 
 static void
-catch_exec_command_1 (char *arg, int from_tty, 
+catch_exec_command_1 (const char *arg, int from_tty,
                      struct cmd_list_element *command)
 {
-  struct exec_catchpoint *c;
   struct gdbarch *gdbarch = get_current_arch ();
   int tempflag;
-  char *cond_string = NULL;
+  const char *cond_string = NULL;
 
   tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
 
@@ -11925,19 +11394,19 @@ catch_exec_command_1 (char *arg, int from_tty,
   if ((*arg != '\0') && !isspace (*arg))
     error (_("Junk at end of arguments."));
 
-  c = new exec_catchpoint ();
-  init_catchpoint (&c->base, gdbarch, tempflag, cond_string,
+  std::unique_ptr<exec_catchpoint> c (new exec_catchpoint ());
+  init_catchpoint (c.get (), gdbarch, tempflag, cond_string,
                   &catch_exec_breakpoint_ops);
   c->exec_pathname = NULL;
 
-  install_breakpoint (0, &c->base, 1);
+  install_breakpoint (0, std::move (c), 1);
 }
 
 void
 init_ada_exception_breakpoint (struct breakpoint *b,
                               struct gdbarch *gdbarch,
                               struct symtab_and_line sal,
-                              char *addr_string,
+                              const char *addr_string,
                               const struct breakpoint_ops *ops,
                               int tempflag,
                               int enabled,
@@ -11971,31 +11440,29 @@ init_ada_exception_breakpoint (struct breakpoint *b,
 }
 
 static void
-catch_command (char *arg, int from_tty)
+catch_command (const char *arg, int from_tty)
 {
   error (_("Catch requires an event name."));
 }
 \f
 
 static void
-tcatch_command (char *arg, int from_tty)
+tcatch_command (const char *arg, int from_tty)
 {
   error (_("Catch requires an event name."));
 }
 
-/* A qsort comparison function that sorts breakpoints in order.  */
+/* Compare two breakpoints and return a strcmp-like result.  */
 
 static int
-compare_breakpoints (const void *a, const void *b)
+compare_breakpoints (const breakpoint *a, const breakpoint *b)
 {
-  const breakpoint_p *ba = (const breakpoint_p *) a;
-  uintptr_t ua = (uintptr_t) *ba;
-  const breakpoint_p *bb = (const breakpoint_p *) b;
-  uintptr_t ub = (uintptr_t) *bb;
+  uintptr_t ua = (uintptr_t) a;
+  uintptr_t ub = (uintptr_t) b;
 
-  if ((*ba)->number < (*bb)->number)
+  if (a->number < b->number)
     return -1;
-  else if ((*ba)->number > (*bb)->number)
+  else if (a->number > b->number)
     return 1;
 
   /* Now sort by address, in case we see, e..g, two breakpoints with
@@ -12008,42 +11475,35 @@ compare_breakpoints (const void *a, const void *b)
 /* Delete breakpoints by address or line.  */
 
 static void
-clear_command (char *arg, int from_tty)
+clear_command (const char *arg, int from_tty)
 {
-  struct breakpoint *b, *prev;
-  VEC(breakpoint_p) *found = 0;
-  int ix;
+  struct breakpoint *b;
   int default_match;
-  struct symtabs_and_lines sals;
-  struct symtab_and_line sal;
   int i;
-  struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
 
+  std::vector<symtab_and_line> decoded_sals;
+  symtab_and_line last_sal;
+  gdb::array_view<symtab_and_line> sals;
   if (arg)
     {
-      sals = decode_line_with_current_source (arg,
-                                             (DECODE_LINE_FUNFIRSTLINE
-                                              | DECODE_LINE_LIST_MODE));
-      make_cleanup (xfree, sals.sals);
+      decoded_sals
+       = decode_line_with_current_source (arg,
+                                          (DECODE_LINE_FUNFIRSTLINE
+                                           | DECODE_LINE_LIST_MODE));
       default_match = 0;
+      sals = decoded_sals;
     }
   else
     {
-      sals.sals = XNEW (struct symtab_and_line);
-      make_cleanup (xfree, sals.sals);
-      init_sal (&sal);         /* Initialize to zeroes.  */
-
       /* Set sal's line, symtab, pc, and pspace to the values
         corresponding to the last call to print_frame_info.  If the
         codepoint is not valid, this will set all the fields to 0.  */
-      get_last_displayed_sal (&sal);
-      if (sal.symtab == 0)
+      last_sal = get_last_displayed_sal ();
+      if (last_sal.symtab == 0)
        error (_("No source file specified."));
 
-      sals.sals[0] = sal;
-      sals.nelts = 1;
-
       default_match = 1;
+      sals = last_sal;
     }
 
   /* We don't call resolve_sal_pc here.  That's not as bad as it
@@ -12068,9 +11528,8 @@ clear_command (char *arg, int from_tty)
      from_tty is forced true if we delete more than one
      breakpoint.  */
 
-  found = NULL;
-  make_cleanup (VEC_cleanup (breakpoint_p), &found);
-  for (i = 0; i < sals.nelts; i++)
+  std::vector<struct breakpoint *> found;
+  for (const auto &sal : sals)
     {
       const char *sal_fullname;
 
@@ -12086,7 +11545,6 @@ clear_command (char *arg, int from_tty)
          0              0             line
          1              0             <can't happen> */
 
-      sal = sals.sals[i];
       sal_fullname = (sal.symtab == NULL
                      ? NULL : symtab_to_fullname (sal.symtab));
 
@@ -12128,12 +11586,12 @@ clear_command (char *arg, int from_tty)
            }
 
          if (match)
-           VEC_safe_push(breakpoint_p, found, b);
+           found.push_back (b);
        }
     }
 
   /* Now go thru the 'found' chain and delete them.  */
-  if (VEC_empty(breakpoint_p, found))
+  if (found.empty ())
     {
       if (arg)
        error (_("No breakpoint at %s."), arg);
@@ -12142,40 +11600,36 @@ clear_command (char *arg, int from_tty)
     }
 
   /* Remove duplicates from the vec.  */
-  qsort (VEC_address (breakpoint_p, found),
-        VEC_length (breakpoint_p, found),
-        sizeof (breakpoint_p),
-        compare_breakpoints);
-  prev = VEC_index (breakpoint_p, found, 0);
-  for (ix = 1; VEC_iterate (breakpoint_p, found, ix, b); ++ix)
-    {
-      if (b == prev)
-       {
-         VEC_ordered_remove (breakpoint_p, found, ix);
-         --ix;
-       }
-    }
+  std::sort (found.begin (), found.end (),
+            [] (const breakpoint *a, const breakpoint *b)
+            {
+              return compare_breakpoints (a, b) < 0;
+            });
+  found.erase (std::unique (found.begin (), found.end (),
+                           [] (const breakpoint *a, const breakpoint *b)
+                           {
+                             return compare_breakpoints (a, b) == 0;
+                           }),
+              found.end ());
 
-  if (VEC_length(breakpoint_p, found) > 1)
+  if (found.size () > 1)
     from_tty = 1;      /* Always report if deleted more than one.  */
   if (from_tty)
     {
-      if (VEC_length(breakpoint_p, found) == 1)
+      if (found.size () == 1)
        printf_unfiltered (_("Deleted breakpoint "));
       else
        printf_unfiltered (_("Deleted breakpoints "));
     }
 
-  for (ix = 0; VEC_iterate(breakpoint_p, found, ix, b); ix++)
+  for (breakpoint *iter : found)
     {
       if (from_tty)
-       printf_unfiltered ("%d ", b->number);
-      delete_breakpoint (b);
+       printf_unfiltered ("%d ", iter->number);
+      delete_breakpoint (iter);
     }
   if (from_tty)
     putchar_unfiltered ('\n');
-
-  do_cleanups (cleanups);
 }
 \f
 /* Delete breakpoint in BS if they are `delete' breakpoints and
@@ -12208,7 +11662,7 @@ breakpoint_auto_delete (bpstat bs)
    qsort being an unstable algorithm.  */
 
 static int
-bp_location_compare (const void *ap, const void *bp)
+bp_locations_compare (const void *ap, const void *bp)
 {
   const struct bp_location *a = *(const struct bp_location **) ap;
   const struct bp_location *b = *(const struct bp_location **) bp;
@@ -12239,17 +11693,17 @@ bp_location_compare (const void *ap, const void *bp)
   return (a > b) - (a < b);
 }
 
-/* Set bp_location_placed_address_before_address_max and
-   bp_location_shadow_len_after_address_max according to the current
-   content of the bp_location array.  */
+/* Set bp_locations_placed_address_before_address_max and
+   bp_locations_shadow_len_after_address_max according to the current
+   content of the bp_locations array.  */
 
 static void
-bp_location_target_extensions_update (void)
+bp_locations_target_extensions_update (void)
 {
   struct bp_location *bl, **blp_tmp;
 
-  bp_location_placed_address_before_address_max = 0;
-  bp_location_shadow_len_after_address_max = 0;
+  bp_locations_placed_address_before_address_max = 0;
+  bp_locations_shadow_len_after_address_max = 0;
 
   ALL_BP_LOCATIONS (bl, blp_tmp)
     {
@@ -12263,15 +11717,15 @@ bp_location_target_extensions_update (void)
 
       gdb_assert (bl->address >= start);
       addr = bl->address - start;
-      if (addr > bp_location_placed_address_before_address_max)
-       bp_location_placed_address_before_address_max = addr;
+      if (addr > bp_locations_placed_address_before_address_max)
+       bp_locations_placed_address_before_address_max = addr;
 
       /* Zero SHADOW_LEN would not pass bp_location_has_shadow.  */
 
       gdb_assert (bl->address < end);
       addr = end - bl->address;
-      if (addr > bp_location_shadow_len_after_address_max)
-       bp_location_shadow_len_after_address_max = addr;
+      if (addr > bp_locations_shadow_len_after_address_max)
+       bp_locations_shadow_len_after_address_max = addr;
     }
 }
 
@@ -12281,10 +11735,9 @@ static void
 download_tracepoint_locations (void)
 {
   struct breakpoint *b;
-  struct cleanup *old_chain;
   enum tribool can_download_tracepoint = TRIBOOL_UNKNOWN;
 
-  old_chain = save_current_space_and_thread ();
+  scoped_restore_current_pspace_and_thread restore_pspace_thread;
 
   ALL_TRACEPOINTS (b)
     {
@@ -12328,8 +11781,6 @@ download_tracepoint_locations (void)
       if (bp_location_downloaded)
        observer_notify_breakpoint_modified (b);
     }
-
-  do_cleanups (old_chain);
 }
 
 /* Swap the insertion/duplication state between two locations.  */
@@ -12419,7 +11870,6 @@ update_global_location_list (enum ugll_insert_mode insert_mode)
 {
   struct breakpoint *b;
   struct bp_location **locp, *loc;
-  struct cleanup *cleanups;
   /* Last breakpoint location address that was marked for update.  */
   CORE_ADDR last_addr = 0;
   /* Last breakpoint location program space that was marked for update.  */
@@ -12436,30 +11886,29 @@ update_global_location_list (enum ugll_insert_mode insert_mode)
   struct bp_location *awp_loc_first; /* access watchpoint */
   struct bp_location *rwp_loc_first; /* read watchpoint */
 
-  /* Saved former bp_location array which we compare against the newly
-     built bp_location from the current state of ALL_BREAKPOINTS.  */
-  struct bp_location **old_location, **old_locp;
-  unsigned old_location_count;
+  /* Saved former bp_locations array which we compare against the newly
+     built bp_locations from the current state of ALL_BREAKPOINTS.  */
+  struct bp_location **old_locp;
+  unsigned old_locations_count;
+  gdb::unique_xmalloc_ptr<struct bp_location *> old_locations (bp_locations);
 
-  old_location = bp_location;
-  old_location_count = bp_location_count;
-  bp_location = NULL;
-  bp_location_count = 0;
-  cleanups = make_cleanup (xfree, old_location);
+  old_locations_count = bp_locations_count;
+  bp_locations = NULL;
+  bp_locations_count = 0;
 
   ALL_BREAKPOINTS (b)
     for (loc = b->loc; loc; loc = loc->next)
-      bp_location_count++;
+      bp_locations_count++;
 
-  bp_location = XNEWVEC (struct bp_location *, bp_location_count);
-  locp = bp_location;
+  bp_locations = XNEWVEC (struct bp_location *, bp_locations_count);
+  locp = bp_locations;
   ALL_BREAKPOINTS (b)
     for (loc = b->loc; loc; loc = loc->next)
       *locp++ = loc;
-  qsort (bp_location, bp_location_count, sizeof (*bp_location),
-        bp_location_compare);
+  qsort (bp_locations, bp_locations_count, sizeof (*bp_locations),
+        bp_locations_compare);
 
-  bp_location_target_extensions_update ();
+  bp_locations_target_extensions_update ();
 
   /* Identify bp_location instances that are no longer present in the
      new list, and therefore should be freed.  Note that it's not
@@ -12471,8 +11920,9 @@ update_global_location_list (enum ugll_insert_mode insert_mode)
      LOCP is kept in sync with OLD_LOCP, each pointing to the current
      and former bp_location array state respectively.  */
 
-  locp = bp_location;
-  for (old_locp = old_location; old_locp < old_location + old_location_count;
+  locp = bp_locations;
+  for (old_locp = old_locations.get ();
+       old_locp < old_locations.get () + old_locations_count;
        old_locp++)
     {
       struct bp_location *old_loc = *old_locp;
@@ -12487,12 +11937,12 @@ update_global_location_list (enum ugll_insert_mode insert_mode)
 
       /* Skip LOCP entries which will definitely never be needed.
         Stop either at or being the one matching OLD_LOC.  */
-      while (locp < bp_location + bp_location_count
+      while (locp < bp_locations + bp_locations_count
             && (*locp)->address < old_loc->address)
        locp++;
 
       for (loc2p = locp;
-          (loc2p < bp_location + bp_location_count
+          (loc2p < bp_locations + bp_locations_count
            && (*loc2p)->address == old_loc->address);
           loc2p++)
        {
@@ -12552,7 +12002,7 @@ update_global_location_list (enum ugll_insert_mode insert_mode)
              if (breakpoint_address_is_meaningful (old_loc->owner))
                {
                  for (loc2p = locp;
-                      (loc2p < bp_location + bp_location_count
+                      (loc2p < bp_locations + bp_locations_count
                        && (*loc2p)->address == old_loc->address);
                       loc2p++)
                    {
@@ -12755,8 +12205,6 @@ update_global_location_list (enum ugll_insert_mode insert_mode)
 
   if (insert_mode != UGLL_DONT_INSERT)
     download_tracepoint_locations ();
-
-  do_cleanups (cleanups);
 }
 
 void
@@ -12834,18 +12282,18 @@ say_where (struct breakpoint *b)
       if (b->extra_string == NULL)
        {
          printf_filtered (_(" (%s) pending."),
-                          event_location_to_string (b->location));
+                          event_location_to_string (b->location.get ()));
        }
       else if (b->type == bp_dprintf)
        {
          printf_filtered (_(" (%s,%s) pending."),
-                          event_location_to_string (b->location),
+                          event_location_to_string (b->location.get ()),
                           b->extra_string);
        }
       else
        {
          printf_filtered (_(" (%s %s) pending."),
-                          event_location_to_string (b->location),
+                          event_location_to_string (b->location.get ()),
                           b->extra_string);
        }
     }
@@ -12870,7 +12318,7 @@ say_where (struct breakpoint *b)
               different file name, and this at least reflects the
               real situation somewhat.  */
            printf_filtered (": %s.",
-                            event_location_to_string (b->location));
+                            event_location_to_string (b->location.get ()));
        }
 
       if (b->loc->next)
@@ -12897,28 +12345,19 @@ static const struct bp_location_ops bp_location_ops =
   bp_location_dtor
 };
 
-/* Default breakpoint_ops methods all breakpoint_ops ultimately
-   inherit from.  */
+/* Destructor for the breakpoint base class.  */
 
-static void
-base_breakpoint_dtor (struct breakpoint *self)
+breakpoint::~breakpoint ()
 {
-  decref_counted_command_line (&self->commands);
-  xfree (self->cond_string);
-  xfree (self->extra_string);
-  xfree (self->filter);
-  delete_event_location (self->location);
-  delete_event_location (self->location_range_end);
+  xfree (this->cond_string);
+  xfree (this->extra_string);
+  xfree (this->filter);
 }
 
 static struct bp_location *
 base_breakpoint_allocate_location (struct breakpoint *self)
 {
-  struct bp_location *loc;
-
-  loc = new struct bp_location ();
-  init_bp_location (loc, &bp_location_ops, self);
-  return loc;
+  return new bp_location (&bp_location_ops, self);
 }
 
 static void
@@ -12945,7 +12384,7 @@ base_breakpoint_remove_location (struct bp_location *bl,
 
 static int
 base_breakpoint_breakpoint_hit (const struct bp_location *bl,
-                               struct address_space *aspace,
+                               const address_space *aspace,
                                CORE_ADDR bp_addr,
                                const struct target_waitstatus *ws)
 {
@@ -13013,8 +12452,8 @@ base_breakpoint_create_sals_from_location
 static void
 base_breakpoint_create_breakpoints_sal (struct gdbarch *gdbarch,
                                        struct linespec_result *c,
-                                       char *cond_string,
-                                       char *extra_string,
+                                       gdb::unique_xmalloc_ptr<char> cond_string,
+                                       gdb::unique_xmalloc_ptr<char> extra_string,
                                        enum bptype type_wanted,
                                        enum bpdisp disposition,
                                        int thread,
@@ -13026,11 +12465,10 @@ base_breakpoint_create_breakpoints_sal (struct gdbarch *gdbarch,
   internal_error_pure_virtual_called ();
 }
 
-static void
+static std::vector<symtab_and_line>
 base_breakpoint_decode_location (struct breakpoint *b,
                                 const struct event_location *location,
-                                struct program_space *search_pspace,
-                                struct symtabs_and_lines *sals)
+                                struct program_space *search_pspace)
 {
   internal_error_pure_virtual_called ();
 }
@@ -13053,7 +12491,6 @@ base_breakpoint_after_condition_true (struct bpstats *bs)
 
 struct breakpoint_ops base_breakpoint_ops =
 {
-  base_breakpoint_dtor,
   base_breakpoint_allocate_location,
   base_breakpoint_re_set,
   base_breakpoint_insert_location,
@@ -13115,7 +12552,7 @@ bkpt_remove_location (struct bp_location *bl, enum remove_bp_reason reason)
 
 static int
 bkpt_breakpoint_hit (const struct bp_location *bl,
-                    struct address_space *aspace, CORE_ADDR bp_addr,
+                    const address_space *aspace, CORE_ADDR bp_addr,
                     const struct target_waitstatus *ws)
 {
   if (ws->kind != TARGET_WAITKIND_STOPPED
@@ -13136,7 +12573,7 @@ bkpt_breakpoint_hit (const struct bp_location *bl,
 
 static int
 dprintf_breakpoint_hit (const struct bp_location *bl,
-                       struct address_space *aspace, CORE_ADDR bp_addr,
+                       const address_space *aspace, CORE_ADDR bp_addr,
                        const struct target_waitstatus *ws)
 {
   if (dprintf_style == dprintf_style_agent
@@ -13181,17 +12618,17 @@ bkpt_print_it (bpstat bs)
   maybe_print_thread_hit_breakpoint (uiout);
 
   if (bp_temp)
-    ui_out_text (uiout, "Temporary breakpoint ");
+    uiout->text ("Temporary breakpoint ");
   else
-    ui_out_text (uiout, "Breakpoint ");
-  if (ui_out_is_mi_like_p (uiout))
+    uiout->text ("Breakpoint ");
+  if (uiout->is_mi_like_p ())
     {
-      ui_out_field_string (uiout, "reason",
+      uiout->field_string ("reason",
                           async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
-      ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
+      uiout->field_string ("disp", bpdisp_text (b->disposition));
     }
-  ui_out_field_int (uiout, "bkptno", b->number);
-  ui_out_text (uiout, ", ");
+  uiout->field_int ("bkptno", b->number);
+  uiout->text (", ");
 
   return PRINT_SRC_AND_LOC;
 }
@@ -13199,7 +12636,7 @@ bkpt_print_it (bpstat bs)
 static void
 bkpt_print_mention (struct breakpoint *b)
 {
-  if (ui_out_is_mi_like_p (current_uiout))
+  if (current_uiout->is_mi_like_p ())
     return;
 
   switch (b->type)
@@ -13242,7 +12679,7 @@ bkpt_print_recreate (struct breakpoint *tp, struct ui_file *fp)
                    _("unhandled breakpoint type %d"), (int) tp->type);
 
   fprintf_unfiltered (fp, " %s",
-                     event_location_to_string (tp->location));
+                     event_location_to_string (tp->location.get ()));
 
   /* Print out extra_string if this breakpoint is pending.  It might
      contain, for example, conditions that were set by the user.  */
@@ -13263,8 +12700,8 @@ bkpt_create_sals_from_location (const struct event_location *location,
 static void
 bkpt_create_breakpoints_sal (struct gdbarch *gdbarch,
                             struct linespec_result *canonical,
-                            char *cond_string,
-                            char *extra_string,
+                            gdb::unique_xmalloc_ptr<char> cond_string,
+                            gdb::unique_xmalloc_ptr<char> extra_string,
                             enum bptype type_wanted,
                             enum bpdisp disposition,
                             int thread,
@@ -13274,20 +12711,20 @@ bkpt_create_breakpoints_sal (struct gdbarch *gdbarch,
                             int internal, unsigned flags)
 {
   create_breakpoints_sal_default (gdbarch, canonical,
-                                 cond_string, extra_string,
+                                 std::move (cond_string),
+                                 std::move (extra_string),
                                  type_wanted,
                                  disposition, thread, task,
                                  ignore_count, ops, from_tty,
                                  enabled, internal, flags);
 }
 
-static void
+static std::vector<symtab_and_line>
 bkpt_decode_location (struct breakpoint *b,
                      const struct event_location *location,
-                     struct program_space *search_pspace,
-                     struct symtabs_and_lines *sals)
+                     struct program_space *search_pspace)
 {
-  decode_location_default (b, location, search_pspace, sals);
+  return decode_location_default (b, location, search_pspace);
 }
 
 /* Virtual table for internal breakpoints.  */
@@ -13421,15 +12858,12 @@ momentary_bkpt_print_mention (struct breakpoint *b)
    It gets cleared already on the removal of the first one of such placed
    breakpoints.  This is OK as they get all removed altogether.  */
 
-static void
-longjmp_bkpt_dtor (struct breakpoint *self)
+longjmp_breakpoint::~longjmp_breakpoint ()
 {
-  struct thread_info *tp = find_thread_global_id (self->thread);
+  thread_info *tp = find_thread_global_id (this->thread);
 
-  if (tp)
+  if (tp != NULL)
     tp->initiating_frame = null_frame_id;
-
-  momentary_breakpoint_ops.dtor (self);
 }
 
 /* Specific methods for probe breakpoints.  */
@@ -13443,10 +12877,7 @@ bkpt_probe_insert_location (struct bp_location *bl)
     {
       /* The insertion was successful, now let's set the probe's semaphore
         if needed.  */
-      if (bl->probe.probe->pops->set_semaphore != NULL)
-       bl->probe.probe->pops->set_semaphore (bl->probe.probe,
-                                             bl->probe.objfile,
-                                             bl->gdbarch);
+      bl->probe.prob->set_semaphore (bl->probe.objfile, bl->gdbarch);
     }
 
   return v;
@@ -13457,10 +12888,7 @@ bkpt_probe_remove_location (struct bp_location *bl,
                            enum remove_bp_reason reason)
 {
   /* Let's clear the semaphore before removing the location.  */
-  if (bl->probe.probe->pops->clear_semaphore != NULL)
-    bl->probe.probe->pops->clear_semaphore (bl->probe.probe,
-                                           bl->probe.objfile,
-                                           bl->gdbarch);
+  bl->probe.prob->clear_semaphore (bl->probe.objfile, bl->gdbarch);
 
   return bkpt_remove_location (bl, reason);
 }
@@ -13473,19 +12901,20 @@ bkpt_probe_create_sals_from_location (const struct event_location *location,
   struct linespec_sals lsal;
 
   lsal.sals = parse_probes (location, NULL, canonical);
-  lsal.canonical = xstrdup (event_location_to_string (canonical->location));
-  VEC_safe_push (linespec_sals, canonical->sals, &lsal);
+  lsal.canonical
+    = xstrdup (event_location_to_string (canonical->location.get ()));
+  canonical->lsals.push_back (std::move (lsal));
 }
 
-static void
+static std::vector<symtab_and_line>
 bkpt_probe_decode_location (struct breakpoint *b,
                            const struct event_location *location,
-                           struct program_space *search_pspace,
-                           struct symtabs_and_lines *sals)
+                           struct program_space *search_pspace)
 {
-  *sals = parse_probes (location, search_pspace, NULL);
-  if (!sals->sals)
+  std::vector<symtab_and_line> sals = parse_probes (location, search_pspace, NULL);
+  if (sals.empty ())
     error (_("probe not found"));
+  return sals;
 }
 
 /* The breakpoint_ops structure to be used in tracepoints.  */
@@ -13498,7 +12927,7 @@ tracepoint_re_set (struct breakpoint *b)
 
 static int
 tracepoint_breakpoint_hit (const struct bp_location *bl,
-                          struct address_space *aspace, CORE_ADDR bp_addr,
+                          const address_space *aspace, CORE_ADDR bp_addr,
                           const struct target_waitstatus *ws)
 {
   /* By definition, the inferior does not report stops at
@@ -13515,17 +12944,17 @@ tracepoint_print_one_detail (const struct breakpoint *self,
     {
       gdb_assert (self->type == bp_static_tracepoint);
 
-      ui_out_text (uiout, "\tmarker id is ");
-      ui_out_field_string (uiout, "static-tracepoint-marker-string-id",
+      uiout->text ("\tmarker id is ");
+      uiout->field_string ("static-tracepoint-marker-string-id",
                           tp->static_trace_marker_id);
-      ui_out_text (uiout, "\n");
+      uiout->text ("\n");
     }
 }
 
 static void
 tracepoint_print_mention (struct breakpoint *b)
 {
-  if (ui_out_is_mi_like_p (current_uiout))
+  if (current_uiout->is_mi_like_p ())
     return;
 
   switch (b->type)
@@ -13566,7 +12995,7 @@ tracepoint_print_recreate (struct breakpoint *self, struct ui_file *fp)
                    _("unhandled tracepoint type %d"), (int) self->type);
 
   fprintf_unfiltered (fp, " %s",
-                     event_location_to_string (self->location));
+                     event_location_to_string (self->location.get ()));
   print_recreate_thread (self, fp);
 
   if (tp->pass_count)
@@ -13584,8 +13013,8 @@ tracepoint_create_sals_from_location (const struct event_location *location,
 static void
 tracepoint_create_breakpoints_sal (struct gdbarch *gdbarch,
                                   struct linespec_result *canonical,
-                                  char *cond_string,
-                                  char *extra_string,
+                                  gdb::unique_xmalloc_ptr<char> cond_string,
+                                  gdb::unique_xmalloc_ptr<char> extra_string,
                                   enum bptype type_wanted,
                                   enum bpdisp disposition,
                                   int thread,
@@ -13595,20 +13024,20 @@ tracepoint_create_breakpoints_sal (struct gdbarch *gdbarch,
                                   int internal, unsigned flags)
 {
   create_breakpoints_sal_default (gdbarch, canonical,
-                                 cond_string, extra_string,
+                                 std::move (cond_string),
+                                 std::move (extra_string),
                                  type_wanted,
                                  disposition, thread, task,
                                  ignore_count, ops, from_tty,
                                  enabled, internal, flags);
 }
 
-static void
+static std::vector<symtab_and_line>
 tracepoint_decode_location (struct breakpoint *b,
                            const struct event_location *location,
-                           struct program_space *search_pspace,
-                           struct symtabs_and_lines *sals)
+                           struct program_space *search_pspace)
 {
-  decode_location_default (b, location, search_pspace, sals);
+  return decode_location_default (b, location, search_pspace);
 }
 
 struct breakpoint_ops tracepoint_breakpoint_ops;
@@ -13626,14 +13055,13 @@ tracepoint_probe_create_sals_from_location
   bkpt_probe_create_sals_from_location (location, canonical, type_wanted);
 }
 
-static void
+static std::vector<symtab_and_line>
 tracepoint_probe_decode_location (struct breakpoint *b,
                                  const struct event_location *location,
-                                 struct program_space *search_pspace,
-                                 struct symtabs_and_lines *sals)
+                                 struct program_space *search_pspace)
 {
   /* We use the same method for breakpoint on probes.  */
-  bkpt_probe_decode_location (b, location, search_pspace, sals);
+  return bkpt_probe_decode_location (b, location, search_pspace);
 }
 
 static struct breakpoint_ops tracepoint_probe_breakpoint_ops;
@@ -13668,7 +13096,7 @@ static void
 dprintf_print_recreate (struct breakpoint *tp, struct ui_file *fp)
 {
   fprintf_unfiltered (fp, "dprintf %s,%s",
-                     event_location_to_string (tp->location),
+                     event_location_to_string (tp->location.get ()),
                      tp->extra_string);
   print_recreate_thread (tp, fp);
 }
@@ -13685,8 +13113,7 @@ dprintf_print_recreate (struct breakpoint *tp, struct ui_file *fp)
 static void
 dprintf_after_condition_true (struct bpstats *bs)
 {
-  struct cleanup *old_chain;
-  struct bpstats tmp_bs = { NULL };
+  struct bpstats tmp_bs;
   struct bpstats *tmp_bs_p = &tmp_bs;
 
   /* dprintf's never cause a stop.  This wasn't set in the
@@ -13701,14 +13128,12 @@ dprintf_after_condition_true (struct bpstats *bs)
      commands here throws.  */
   tmp_bs.commands = bs->commands;
   bs->commands = NULL;
-  old_chain = make_cleanup_decref_counted_command_line (&tmp_bs.commands);
 
   bpstat_do_actions_1 (&tmp_bs_p);
 
   /* 'tmp_bs.commands' will usually be NULL by now, but
      bpstat_do_actions_1 may return early without processing the whole
      list.  */
-  do_cleanups (old_chain);
 }
 
 /* The breakpoint_ops structure to be used on static tracepoints with
@@ -13721,26 +13146,24 @@ strace_marker_create_sals_from_location (const struct event_location *location,
 {
   struct linespec_sals lsal;
   const char *arg_start, *arg;
-  char *str;
-  struct cleanup *cleanup;
 
   arg = arg_start = get_linespec_location (location);
   lsal.sals = decode_static_tracepoint_spec (&arg);
 
-  str = savestring (arg_start, arg - arg_start);
-  cleanup = make_cleanup (xfree, str);
-  canonical->location = new_linespec_location (&str);
-  do_cleanups (cleanup);
+  std::string str (arg_start, arg - arg_start);
+  const char *ptr = str.c_str ();
+  canonical->location = new_linespec_location (&ptr);
 
-  lsal.canonical = xstrdup (event_location_to_string (canonical->location));
-  VEC_safe_push (linespec_sals, canonical->sals, &lsal);
+  lsal.canonical
+    = xstrdup (event_location_to_string (canonical->location.get ()));
+  canonical->lsals.push_back (std::move (lsal));
 }
 
 static void
 strace_marker_create_breakpoints_sal (struct gdbarch *gdbarch,
                                      struct linespec_result *canonical,
-                                     char *cond_string,
-                                     char *extra_string,
+                                     gdb::unique_xmalloc_ptr<char> cond_string,
+                                     gdb::unique_xmalloc_ptr<char> extra_string,
                                      enum bptype type_wanted,
                                      enum bpdisp disposition,
                                      int thread,
@@ -13749,9 +13172,7 @@ strace_marker_create_breakpoints_sal (struct gdbarch *gdbarch,
                                      int from_tty, int enabled,
                                      int internal, unsigned flags)
 {
-  int i;
-  struct linespec_sals *lsal = VEC_index (linespec_sals,
-                                         canonical->sals, 0);
+  const linespec_sals &lsal = canonical->lsals[0];
 
   /* If the user is creating a static tracepoint by marker id
      (strace -m MARKER_ID), then store the sals index, so that
@@ -13760,23 +13181,16 @@ strace_marker_create_breakpoints_sal (struct gdbarch *gdbarch,
      expand multiple locations for each sal, given than SALS
      already should contain all sals for MARKER_ID.  */
 
-  for (i = 0; i < lsal->sals.nelts; ++i)
+  for (size_t i = 0; i < lsal.sals.size (); i++)
     {
-      struct symtabs_and_lines expanded;
-      struct tracepoint *tp;
-      struct cleanup *old_chain;
-      struct event_location *location;
-
-      expanded.nelts = 1;
-      expanded.sals = &lsal->sals.sals[i];
+      event_location_up location
+       = copy_event_location (canonical->location.get ());
 
-      location = copy_event_location (canonical->location);
-      old_chain = make_cleanup_delete_event_location (location);
-
-      tp = new tracepoint ();
-      init_breakpoint_sal (&tp->base, gdbarch, expanded,
-                          location, NULL,
-                          cond_string, extra_string,
+      std::unique_ptr<tracepoint> tp (new tracepoint ());
+      init_breakpoint_sal (tp.get (), gdbarch, lsal.sals[i],
+                          std::move (location), NULL,
+                          std::move (cond_string),
+                          std::move (extra_string),
                           type_wanted, disposition,
                           thread, task, ignore_count, ops,
                           from_tty, enabled, internal, flags,
@@ -13789,26 +13203,24 @@ strace_marker_create_breakpoints_sal (struct gdbarch *gdbarch,
         corresponds to this one  */
       tp->static_trace_marker_id_idx = i;
 
-      install_breakpoint (internal, &tp->base, 0);
-
-      discard_cleanups (old_chain);
+      install_breakpoint (internal, std::move (tp), 0);
     }
 }
 
-static void
+static std::vector<symtab_and_line>
 strace_marker_decode_location (struct breakpoint *b,
                               const struct event_location *location,
-                              struct program_space *search_pspace,
-                              struct symtabs_and_lines *sals)
+                              struct program_space *search_pspace)
 {
   struct tracepoint *tp = (struct tracepoint *) b;
   const char *s = get_linespec_location (location);
 
-  *sals = decode_static_tracepoint_spec (&s);
-  if (sals->nelts > tp->static_trace_marker_id_idx)
+  std::vector<symtab_and_line> sals = decode_static_tracepoint_spec (&s);
+  if (sals.size () > tp->static_trace_marker_id_idx)
     {
-      sals->sals[0] = sals->sals[tp->static_trace_marker_id_idx];
-      sals->nelts = 1;
+      sals[0] = sals[tp->static_trace_marker_id_idx];
+      sals.resize (1);
+      return sals;
     }
   else
     error (_("marker %s not found"), tp->static_trace_marker_id);
@@ -13911,33 +13323,18 @@ delete_breakpoint (struct breakpoint *bpt)
      self-contained, but it's not the case now.  */
   update_global_location_list (UGLL_DONT_INSERT);
 
-  bpt->ops->dtor (bpt);
   /* On the chance that someone will soon try again to delete this
      same bp, we mark it as deleted before freeing its storage.  */
   bpt->type = bp_none;
   delete bpt;
 }
 
-static void
-do_delete_breakpoint_cleanup (void *b)
-{
-  delete_breakpoint ((struct breakpoint *) b);
-}
-
-struct cleanup *
-make_cleanup_delete_breakpoint (struct breakpoint *b)
-{
-  return make_cleanup (do_delete_breakpoint_cleanup, b);
-}
-
 /* Iterator function to call a user-provided callback function once
    for each of B and its related breakpoints.  */
 
 static void
 iterate_over_related_breakpoints (struct breakpoint *b,
-                                 void (*function) (struct breakpoint *,
-                                                   void *),
-                                 void *data)
+                                 gdb::function_view<void (breakpoint *)> function)
 {
   struct breakpoint *related;
 
@@ -13952,7 +13349,7 @@ iterate_over_related_breakpoints (struct breakpoint *b,
       if (next == related)
        {
          /* RELATED is the last ring entry.  */
-         function (related, data);
+         function (related);
 
          /* FUNCTION may have deleted it, so we'd never reach back to
             B.  There's nothing left to do anyway, so just break
@@ -13960,7 +13357,7 @@ iterate_over_related_breakpoints (struct breakpoint *b,
          break;
        }
       else
-       function (related, data);
+       function (related);
 
       related = next;
     }
@@ -13968,22 +13365,7 @@ iterate_over_related_breakpoints (struct breakpoint *b,
 }
 
 static void
-do_delete_breakpoint (struct breakpoint *b, void *ignore)
-{
-  delete_breakpoint (b);
-}
-
-/* A callback for map_breakpoint_numbers that calls
-   delete_breakpoint.  */
-
-static void
-do_map_delete_breakpoint (struct breakpoint *b, void *ignore)
-{
-  iterate_over_related_breakpoints (b, do_delete_breakpoint, NULL);
-}
-
-void
-delete_command (char *arg, int from_tty)
+delete_command (const char *arg, int from_tty)
 {
   struct breakpoint *b, *b_tmp;
 
@@ -14013,7 +13395,11 @@ delete_command (char *arg, int from_tty)
        }
     }
   else
-    map_breakpoint_numbers (arg, do_map_delete_breakpoint, NULL);
+    map_breakpoint_numbers
+      (arg, [&] (breakpoint *b)
+       {
+        iterate_over_related_breakpoints (b, delete_breakpoint);
+       });
 }
 
 /* Return true if all locations of B bound to PSPACE are pending.  If
@@ -14144,7 +13530,6 @@ update_static_tracepoint (struct breakpoint *b, struct symtab_and_line sal)
 
       if (!VEC_empty(static_tracepoint_marker_p, markers))
        {
-         struct symtab_and_line sal2;
          struct symbol *sym;
          struct static_tracepoint_marker *tpmarker;
          struct ui_out *uiout = current_uiout;
@@ -14159,37 +13544,32 @@ update_static_tracepoint (struct breakpoint *b, struct symtab_and_line sal)
                     "found at previous line number"),
                   b->number, tp->static_trace_marker_id);
 
-         init_sal (&sal2);
-
-         sal2.pc = tpmarker->address;
-
-         sal2 = find_pc_line (tpmarker->address, 0);
+         symtab_and_line sal2 = find_pc_line (tpmarker->address, 0);
          sym = find_pc_sect_function (tpmarker->address, NULL);
-         ui_out_text (uiout, "Now in ");
+         uiout->text ("Now in ");
          if (sym)
            {
-             ui_out_field_string (uiout, "func",
-                                  SYMBOL_PRINT_NAME (sym));
-             ui_out_text (uiout, " at ");
+             uiout->field_string ("func", SYMBOL_PRINT_NAME (sym));
+             uiout->text (" at ");
            }
-         ui_out_field_string (uiout, "file",
+         uiout->field_string ("file",
                               symtab_to_filename_for_display (sal2.symtab));
-         ui_out_text (uiout, ":");
+         uiout->text (":");
 
-         if (ui_out_is_mi_like_p (uiout))
+         if (uiout->is_mi_like_p ())
            {
              const char *fullname = symtab_to_fullname (sal2.symtab);
 
-             ui_out_field_string (uiout, "fullname", fullname);
+             uiout->field_string ("fullname", fullname);
            }
 
-         ui_out_field_int (uiout, "line", sal2.line);
-         ui_out_text (uiout, "\n");
+         uiout->field_int ("line", sal2.line);
+         uiout->text ("\n");
 
          b->loc->line_number = sal2.line;
          b->loc->symtab = sym != NULL ? sal2.symtab : NULL;
 
-         delete_event_location (b->location);
+         b->location.reset (NULL);
          initialize_explicit_location (&explicit_loc);
          explicit_loc.source_filename
            = ASTRDUP (symtab_to_filename_for_display (sal2.symtab));
@@ -14280,13 +13660,13 @@ hoist_existing_locations (struct breakpoint *b, struct program_space *pspace)
 void
 update_breakpoint_locations (struct breakpoint *b,
                             struct program_space *filter_pspace,
-                            struct symtabs_and_lines sals,
-                            struct symtabs_and_lines sals_end)
+                            gdb::array_view<const symtab_and_line> sals,
+                            gdb::array_view<const symtab_and_line> sals_end)
 {
   int i;
   struct bp_location *existing_locations;
 
-  if (sals_end.nelts != 0 && (sals.nelts != 1 || sals_end.nelts != 1))
+  if (!sals_end.empty () && (sals.size () != 1 || sals_end.size () != 1))
     {
       /* Ranged breakpoints have only one start location and one end
         location.  */
@@ -14303,18 +13683,18 @@ update_breakpoint_locations (struct breakpoint *b,
      We'd like to retain the location, so that when the library is
      loaded again, we don't loose the enabled/disabled status of the
      individual locations.  */
-  if (all_locations_are_pending (b, filter_pspace) && sals.nelts == 0)
+  if (all_locations_are_pending (b, filter_pspace) && sals.empty ())
     return;
 
   existing_locations = hoist_existing_locations (b, filter_pspace);
 
-  for (i = 0; i < sals.nelts; ++i)
+  for (const auto &sal : sals)
     {
       struct bp_location *new_loc;
 
-      switch_to_program_space_and_thread (sals.sals[i].pspace);
+      switch_to_program_space_and_thread (sal.pspace);
 
-      new_loc = add_location_to_breakpoint (b, &(sals.sals[i]));
+      new_loc = add_location_to_breakpoint (b, &sal);
 
       /* Reparse conditions, they might contain references to the
         old symtab.  */
@@ -14325,8 +13705,8 @@ update_breakpoint_locations (struct breakpoint *b,
          s = b->cond_string;
          TRY
            {
-             new_loc->cond = parse_exp_1 (&s, sals.sals[i].pc,
-                                          block_for_pc (sals.sals[i].pc), 
+             new_loc->cond = parse_exp_1 (&s, sal.pc,
+                                          block_for_pc (sal.pc),
                                           0);
            }
          CATCH (e, RETURN_MASK_ERROR)
@@ -14339,11 +13719,11 @@ update_breakpoint_locations (struct breakpoint *b,
          END_CATCH
        }
 
-      if (sals_end.nelts)
+      if (!sals_end.empty ())
        {
-         CORE_ADDR end = find_breakpoint_range_end (sals_end.sals[0]);
+         CORE_ADDR end = find_breakpoint_range_end (sals_end[0]);
 
-         new_loc->length = end - sals.sals[0].pc + 1;
+         new_loc->length = end - sals[0].pc + 1;
        }
     }
 
@@ -14393,18 +13773,19 @@ update_breakpoint_locations (struct breakpoint *b,
 /* Find the SaL locations corresponding to the given LOCATION.
    On return, FOUND will be 1 if any SaL was found, zero otherwise.  */
 
-static struct symtabs_and_lines
+static std::vector<symtab_and_line>
 location_to_sals (struct breakpoint *b, struct event_location *location,
                  struct program_space *search_pspace, int *found)
 {
-  struct symtabs_and_lines sals = {0};
   struct gdb_exception exception = exception_none;
 
   gdb_assert (b->ops != NULL);
 
+  std::vector<symtab_and_line> sals;
+
   TRY
     {
-      b->ops->decode_location (b, location, search_pspace, &sals);
+      sals = b->ops->decode_location (b, location, search_pspace);
     }
   CATCH (e, RETURN_MASK_ERROR)
     {
@@ -14445,16 +13826,14 @@ location_to_sals (struct breakpoint *b, struct event_location *location,
 
   if (exception.reason == 0 || exception.error != NOT_FOUND_ERROR)
     {
-      int i;
-
-      for (i = 0; i < sals.nelts; ++i)
-       resolve_sal_pc (&sals.sals[i]);
+      for (auto &sal : sals)
+       resolve_sal_pc (&sal);
       if (b->condition_not_parsed && b->extra_string != NULL)
        {
          char *cond_string, *extra_string;
          int thread, task;
 
-         find_condition_and_thread (b->extra_string, sals.sals[0].pc,
+         find_condition_and_thread (b->extra_string, sals[0].pc,
                                     &cond_string, &thread, &task,
                                     &extra_string);
          gdb_assert (b->cond_string == NULL);
@@ -14471,7 +13850,7 @@ location_to_sals (struct breakpoint *b, struct event_location *location,
        }
 
       if (b->type == bp_static_tracepoint && !strace_marker_p (b))
-       sals.sals[0] = update_static_tracepoint (b, sals.sals[0]);
+       sals[0] = update_static_tracepoint (b, sals[0]);
 
       *found = 1;
     }
@@ -14488,28 +13867,22 @@ location_to_sals (struct breakpoint *b, struct event_location *location,
 static void
 breakpoint_re_set_default (struct breakpoint *b)
 {
-  int found;
-  struct symtabs_and_lines sals, sals_end;
-  struct symtabs_and_lines expanded = {0};
-  struct symtabs_and_lines expanded_end = {0};
   struct program_space *filter_pspace = current_program_space;
+  std::vector<symtab_and_line> expanded, expanded_end;
 
-  sals = location_to_sals (b, b->location, filter_pspace, &found);
+  int found;
+  std::vector<symtab_and_line> sals = location_to_sals (b, b->location.get (),
+                                                       filter_pspace, &found);
   if (found)
-    {
-      make_cleanup (xfree, sals.sals);
-      expanded = sals;
-    }
+    expanded = std::move (sals);
 
   if (b->location_range_end != NULL)
     {
-      sals_end = location_to_sals (b, b->location_range_end,
-                                  filter_pspace, &found);
+      std::vector<symtab_and_line> sals_end
+       = location_to_sals (b, b->location_range_end.get (),
+                           filter_pspace, &found);
       if (found)
-       {
-         make_cleanup (xfree, sals_end.sals);
-         expanded_end = sals_end;
-       }
+       expanded_end = std::move (sals_end);
     }
 
   update_breakpoint_locations (b, filter_pspace, expanded, expanded_end);
@@ -14533,8 +13906,8 @@ create_sals_from_location_default (const struct event_location *location,
 static void
 create_breakpoints_sal_default (struct gdbarch *gdbarch,
                                struct linespec_result *canonical,
-                               char *cond_string,
-                               char *extra_string,
+                               gdb::unique_xmalloc_ptr<char> cond_string,
+                               gdb::unique_xmalloc_ptr<char> extra_string,
                                enum bptype type_wanted,
                                enum bpdisp disposition,
                                int thread,
@@ -14543,8 +13916,9 @@ create_breakpoints_sal_default (struct gdbarch *gdbarch,
                                int from_tty, int enabled,
                                int internal, unsigned flags)
 {
-  create_breakpoints_sal (gdbarch, canonical, cond_string,
-                         extra_string,
+  create_breakpoints_sal (gdbarch, canonical,
+                         std::move (cond_string),
+                         std::move (extra_string),
                          type_wanted, disposition,
                          thread, task, ignore_count, ops, from_tty,
                          enabled, internal, flags);
@@ -14553,63 +13927,38 @@ create_breakpoints_sal_default (struct gdbarch *gdbarch,
 /* Decode the line represented by S by calling decode_line_full.  This is the
    default function for the `decode_location' method of breakpoint_ops.  */
 
-static void
+static std::vector<symtab_and_line>
 decode_location_default (struct breakpoint *b,
                         const struct event_location *location,
-                        struct program_space *search_pspace,
-                        struct symtabs_and_lines *sals)
+                        struct program_space *search_pspace)
 {
   struct linespec_result canonical;
 
-  init_linespec_result (&canonical);
   decode_line_full (location, DECODE_LINE_FUNFIRSTLINE, search_pspace,
                    (struct symtab *) NULL, 0,
                    &canonical, multiple_symbols_all,
                    b->filter);
 
   /* We should get 0 or 1 resulting SALs.  */
-  gdb_assert (VEC_length (linespec_sals, canonical.sals) < 2);
+  gdb_assert (canonical.lsals.size () < 2);
 
-  if (VEC_length (linespec_sals, canonical.sals) > 0)
+  if (!canonical.lsals.empty ())
     {
-      struct linespec_sals *lsal;
-
-      lsal = VEC_index (linespec_sals, canonical.sals, 0);
-      *sals = lsal->sals;
-      /* Arrange it so the destructor does not free the
-        contents.  */
-      lsal->sals.sals = NULL;
+      const linespec_sals &lsal = canonical.lsals[0];
+      return std::move (lsal.sals);
     }
-
-  destroy_linespec_result (&canonical);
+  return {};
 }
 
-/* Prepare the global context for a re-set of breakpoint B.  */
+/* Reset a breakpoint.  */
 
-static struct cleanup *
-prepare_re_set_context (struct breakpoint *b)
+static void
+breakpoint_re_set_one (breakpoint *b)
 {
   input_radix = b->input_radix;
   set_language (b->language);
 
-  return make_cleanup (null_cleanup, NULL);
-}
-
-/* Reset a breakpoint given it's struct breakpoint * BINT.
-   The value we return ends up being the return value from catch_errors.
-   Unused in this case.  */
-
-static int
-breakpoint_re_set_one (void *bint)
-{
-  /* Get past catch_errs.  */
-  struct breakpoint *b = (struct breakpoint *) bint;
-  struct cleanup *cleanups;
-
-  cleanups = prepare_re_set_context (b);
   b->ops->re_set (b);
-  do_cleanups (cleanups);
-  return 0;
 }
 
 /* Re-set breakpoint locations for the current program space.
@@ -14619,34 +13968,34 @@ void
 breakpoint_re_set (void)
 {
   struct breakpoint *b, *b_tmp;
-  enum language save_language;
-  int save_input_radix;
-  struct cleanup *old_chain;
-
-  save_language = current_language->la_language;
-  save_input_radix = input_radix;
-  old_chain = save_current_space_and_thread ();
 
-  /* Note: we must not try to insert locations until after all
-     breakpoints have been re-set.  Otherwise, e.g., when re-setting
-     breakpoint 1, we'd insert the locations of breakpoint 2, which
-     hadn't been re-set yet, and thus may have stale locations.  */
-
-  ALL_BREAKPOINTS_SAFE (b, b_tmp)
   {
-    /* Format possible error msg.  */
-    char *message = xstrprintf ("Error in re-setting breakpoint %d: ",
-                               b->number);
-    struct cleanup *cleanups = make_cleanup (xfree, message);
-    catch_errors (breakpoint_re_set_one, b, message, RETURN_MASK_ALL);
-    do_cleanups (cleanups);
-  }
-  set_language (save_language);
-  input_radix = save_input_radix;
+    scoped_restore_current_language save_language;
+    scoped_restore save_input_radix = make_scoped_restore (&input_radix);
+    scoped_restore_current_pspace_and_thread restore_pspace_thread;
+
+    /* Note: we must not try to insert locations until after all
+       breakpoints have been re-set.  Otherwise, e.g., when re-setting
+       breakpoint 1, we'd insert the locations of breakpoint 2, which
+       hadn't been re-set yet, and thus may have stale locations.  */
 
-  jit_breakpoint_re_set ();
+    ALL_BREAKPOINTS_SAFE (b, b_tmp)
+      {
+       TRY
+         {
+           breakpoint_re_set_one (b);
+         }
+       CATCH (ex, RETURN_MASK_ALL)
+         {
+           exception_fprintf (gdb_stderr, ex,
+                              "Error in re-setting breakpoint %d: ",
+                              b->number);
+         }
+       END_CATCH
+      }
 
-  do_cleanups (old_chain);
+    jit_breakpoint_re_set ();
+  }
 
   create_overlay_event_breakpoint ();
   create_longjmp_master_breakpoint ();
@@ -14725,9 +14074,9 @@ set_ignore_count (int bptnum, int count, int from_tty)
 /* Command to set ignore-count of breakpoint N to COUNT.  */
 
 static void
-ignore_command (char *args, int from_tty)
+ignore_command (const char *args, int from_tty)
 {
-  char *p = args;
+  const char *p = args;
   int num;
 
   if (p == 0)
@@ -14746,64 +14095,66 @@ ignore_command (char *args, int from_tty)
     printf_filtered ("\n");
 }
 \f
-/* Call FUNCTION on each of the breakpoints
-   whose numbers are given in ARGS.  */
+
+/* Call FUNCTION on each of the breakpoints with numbers in the range
+   defined by BP_NUM_RANGE (an inclusive range).  */
 
 static void
-map_breakpoint_numbers (const char *args,
-                       void (*function) (struct breakpoint *,
-                                         void *),
-                       void *data)
+map_breakpoint_number_range (std::pair<int, int> bp_num_range,
+                            gdb::function_view<void (breakpoint *)> function)
 {
-  int num;
-  struct breakpoint *b, *tmp;
-
-  if (args == 0 || *args == '\0')
-    error_no_arg (_("one or more breakpoint numbers"));
-
-  number_or_range_parser parser (args);
-
-  while (!parser.finished ())
+  if (bp_num_range.first == 0)
+    {
+      warning (_("bad breakpoint number at or near '%d'"),
+              bp_num_range.first);
+    }
+  else
     {
-      const char *p = parser.cur_tok ();
-      bool match = false;
+      struct breakpoint *b, *tmp;
 
-      num = parser.get_number ();
-      if (num == 0)
-       {
-         warning (_("bad breakpoint number at or near '%s'"), p);
-       }
-      else
+      for (int i = bp_num_range.first; i <= bp_num_range.second; i++)
        {
+         bool match = false;
+
          ALL_BREAKPOINTS_SAFE (b, tmp)
-           if (b->number == num)
+           if (b->number == i)
              {
                match = true;
-               function (b, data);
+               function (b);
                break;
              }
          if (!match)
-           printf_unfiltered (_("No breakpoint number %d.\n"), num);
+           printf_unfiltered (_("No breakpoint number %d.\n"), i);
        }
     }
 }
 
-static struct bp_location *
-find_location_by_number (char *number)
+/* Call FUNCTION on each of the breakpoints whose numbers are given in
+   ARGS.  */
+
+static void
+map_breakpoint_numbers (const char *args,
+                       gdb::function_view<void (breakpoint *)> function)
 {
-  char *dot = strchr (number, '.');
-  char *p1;
-  int bp_num;
-  int loc_num;
-  struct breakpoint *b;
-  struct bp_location *loc;  
+  if (args == NULL || *args == '\0')
+    error_no_arg (_("one or more breakpoint numbers"));
+
+  number_or_range_parser parser (args);
+
+  while (!parser.finished ())
+    {
+      int num = parser.get_number ();
+      map_breakpoint_number_range (std::make_pair (num, num), function);
+    }
+}
 
-  *dot = '\0';
+/* Return the breakpoint location structure corresponding to the
+   BP_NUM and LOC_NUM values.  */
 
-  p1 = number;
-  bp_num = get_number (&p1);
-  if (bp_num == 0)
-    error (_("Bad breakpoint number '%s'"), number);
+static struct bp_location *
+find_location_by_number (int bp_num, int loc_num)
+{
+  struct breakpoint *b;
 
   ALL_BREAKPOINTS (b)
     if (b->number == bp_num)
@@ -14812,23 +14163,180 @@ find_location_by_number (char *number)
       }
 
   if (!b || b->number != bp_num)
-    error (_("Bad breakpoint number '%s'"), number);
+    error (_("Bad breakpoint number '%d'"), bp_num);
   
-  p1 = dot+1;
-  loc_num = get_number (&p1);
   if (loc_num == 0)
-    error (_("Bad breakpoint location number '%s'"), number);
+    error (_("Bad breakpoint location number '%d'"), loc_num);
 
-  --loc_num;
-  loc = b->loc;
-  for (;loc_num && loc; --loc_num, loc = loc->next)
-    ;
-  if (!loc)
-    error (_("Bad breakpoint location number '%s'"), dot+1);
-    
-  return loc;  
+  int n = 0;
+  for (bp_location *loc = b->loc; loc != NULL; loc = loc->next)
+    if (++n == loc_num)
+      return loc;
+
+  error (_("Bad breakpoint location number '%d'"), loc_num);
+}
+
+/* Modes of operation for extract_bp_num.  */
+enum class extract_bp_kind
+{
+  /* Extracting a breakpoint number.  */
+  bp,
+
+  /* Extracting a location number.  */
+  loc,
+};
+
+/* Extract a breakpoint or location number (as determined by KIND)
+   from the string starting at START.  TRAILER is a character which
+   can be found after the number.  If you don't want a trailer, use
+   '\0'.  If END_OUT is not NULL, it is set to point after the parsed
+   string.  This always returns a positive integer.  */
+
+static int
+extract_bp_num (extract_bp_kind kind, const char *start,
+               int trailer, const char **end_out = NULL)
+{
+  const char *end = start;
+  int num = get_number_trailer (&end, trailer);
+  if (num < 0)
+    error (kind == extract_bp_kind::bp
+          ? _("Negative breakpoint number '%.*s'")
+          : _("Negative breakpoint location number '%.*s'"),
+          int (end - start), start);
+  if (num == 0)
+    error (kind == extract_bp_kind::bp
+          ? _("Bad breakpoint number '%.*s'")
+          : _("Bad breakpoint location number '%.*s'"),
+          int (end - start), start);
+
+  if (end_out != NULL)
+    *end_out = end;
+  return num;
+}
+
+/* Extract a breakpoint or location range (as determined by KIND) in
+   the form NUM1-NUM2 stored at &ARG[arg_offset].  Returns a std::pair
+   representing the (inclusive) range.  The returned pair's elements
+   are always positive integers.  */
+
+static std::pair<int, int>
+extract_bp_or_bp_range (extract_bp_kind kind,
+                       const std::string &arg,
+                       std::string::size_type arg_offset)
+{
+  std::pair<int, int> range;
+  const char *bp_loc = &arg[arg_offset];
+  std::string::size_type dash = arg.find ('-', arg_offset);
+  if (dash != std::string::npos)
+    {
+      /* bp_loc is a range (x-z).  */
+      if (arg.length () == dash + 1)
+       error (kind == extract_bp_kind::bp
+              ? _("Bad breakpoint number at or near: '%s'")
+              : _("Bad breakpoint location number at or near: '%s'"),
+              bp_loc);
+
+      const char *end;
+      const char *start_first = bp_loc;
+      const char *start_second = &arg[dash + 1];
+      range.first = extract_bp_num (kind, start_first, '-');
+      range.second = extract_bp_num (kind, start_second, '\0', &end);
+
+      if (range.first > range.second)
+       error (kind == extract_bp_kind::bp
+              ? _("Inverted breakpoint range at '%.*s'")
+              : _("Inverted breakpoint location range at '%.*s'"),
+              int (end - start_first), start_first);
+    }
+  else
+    {
+      /* bp_loc is a single value.  */
+      range.first = extract_bp_num (kind, bp_loc, '\0');
+      range.second = range.first;
+    }
+  return range;
+}
+
+/* Extract the breakpoint/location range specified by ARG.  Returns
+   the breakpoint range in BP_NUM_RANGE, and the location range in
+   BP_LOC_RANGE.
+
+   ARG may be in any of the following forms:
+
+   x     where 'x' is a breakpoint number.
+   x-y   where 'x' and 'y' specify a breakpoint numbers range.
+   x.y   where 'x' is a breakpoint number and 'y' a location number.
+   x.y-z where 'x' is a breakpoint number and 'y' and 'z' specify a
+        location number range.
+*/
+
+static void
+extract_bp_number_and_location (const std::string &arg,
+                               std::pair<int, int> &bp_num_range,
+                               std::pair<int, int> &bp_loc_range)
+{
+  std::string::size_type dot = arg.find ('.');
+
+  if (dot != std::string::npos)
+    {
+      /* Handle 'x.y' and 'x.y-z' cases.  */
+
+      if (arg.length () == dot + 1 || dot == 0)
+       error (_("Bad breakpoint number at or near: '%s'"), arg.c_str ());
+
+      bp_num_range.first
+       = extract_bp_num (extract_bp_kind::bp, arg.c_str (), '.');
+      bp_num_range.second = bp_num_range.first;
+
+      bp_loc_range = extract_bp_or_bp_range (extract_bp_kind::loc,
+                                            arg, dot + 1);
+    }
+  else
+    {
+      /* Handle x and x-y cases.  */
+
+      bp_num_range = extract_bp_or_bp_range (extract_bp_kind::bp, arg, 0);
+      bp_loc_range.first = 0;
+      bp_loc_range.second = 0;
+    }
 }
 
+/* Enable or disable a breakpoint location BP_NUM.LOC_NUM.  ENABLE
+   specifies whether to enable or disable.  */
+
+static void
+enable_disable_bp_num_loc (int bp_num, int loc_num, bool enable)
+{
+  struct bp_location *loc = find_location_by_number (bp_num, loc_num);
+  if (loc != NULL)
+    {
+      if (loc->enabled != enable)
+       {
+         loc->enabled = enable;
+         mark_breakpoint_location_modified (loc);
+       }
+      if (target_supports_enable_disable_tracepoint ()
+         && current_trace_status ()->running && loc->owner
+         && is_tracepoint (loc->owner))
+       target_disable_tracepoint (loc);
+    }
+  update_global_location_list (UGLL_DONT_INSERT);
+}
+
+/* Enable or disable a range of breakpoint locations.  BP_NUM is the
+   number of the breakpoint, and BP_LOC_RANGE specifies the
+   (inclusive) range of location numbers of that breakpoint to
+   enable/disable.  ENABLE specifies whether to enable or disable the
+   location.  */
+
+static void
+enable_disable_breakpoint_location_range (int bp_num,
+                                         std::pair<int, int> &bp_loc_range,
+                                         bool enable)
+{
+  for (int i = bp_loc_range.first; i <= bp_loc_range.second; i++)
+    enable_disable_bp_num_loc (bp_num, i, enable);
+}
 
 /* Set ignore-count of breakpoint number BPTNUM to COUNT.
    If from_tty is nonzero, it prints a message to that effect,
@@ -14862,25 +14370,13 @@ disable_breakpoint (struct breakpoint *bpt)
   observer_notify_breakpoint_modified (bpt);
 }
 
-/* A callback for iterate_over_related_breakpoints.  */
-
-static void
-do_disable_breakpoint (struct breakpoint *b, void *ignore)
-{
-  disable_breakpoint (b);
-}
-
-/* A callback for map_breakpoint_numbers that calls
-   disable_breakpoint.  */
-
-static void
-do_map_disable_breakpoint (struct breakpoint *b, void *ignore)
-{
-  iterate_over_related_breakpoints (b, do_disable_breakpoint, NULL);
-}
+/* Enable or disable the breakpoint(s) or breakpoint location(s)
+   specified in ARGS.  ARGS may be in any of the formats handled by
+   extract_bp_number_and_location.  ENABLE specifies whether to enable
+   or disable the breakpoints/locations.  */
 
 static void
-disable_command (char *args, int from_tty)
+enable_disable_command (const char *args, int from_tty, bool enable)
 {
   if (args == 0)
     {
@@ -14888,39 +14384,55 @@ disable_command (char *args, int from_tty)
 
       ALL_BREAKPOINTS (bpt)
        if (user_breakpoint_p (bpt))
-         disable_breakpoint (bpt);
+         {
+           if (enable)
+             enable_breakpoint (bpt);
+           else
+             disable_breakpoint (bpt);
+         }
     }
   else
     {
-      char *num = extract_arg (&args);
+      std::string num = extract_arg (&args);
 
-      while (num)
+      while (!num.empty ())
        {
-         if (strchr (num, '.'))
-           {
-             struct bp_location *loc = find_location_by_number (num);
+         std::pair<int, int> bp_num_range, bp_loc_range;
 
-             if (loc)
-               {
-                 if (loc->enabled)
-                   {
-                     loc->enabled = 0;
-                     mark_breakpoint_location_modified (loc);
-                   }
-                 if (target_supports_enable_disable_tracepoint ()
-                     && current_trace_status ()->running && loc->owner
-                     && is_tracepoint (loc->owner))
-                   target_disable_tracepoint (loc);
-               }
-             update_global_location_list (UGLL_DONT_INSERT);
+         extract_bp_number_and_location (num, bp_num_range, bp_loc_range);
+
+         if (bp_loc_range.first == bp_loc_range.second
+             && bp_loc_range.first == 0)
+           {
+             /* Handle breakpoint ids with formats 'x' or 'x-z'.  */
+             map_breakpoint_number_range (bp_num_range,
+                                          enable
+                                          ? enable_breakpoint
+                                          : disable_breakpoint);
            }
          else
-           map_breakpoint_numbers (num, do_map_disable_breakpoint, NULL);
+           {
+             /* Handle breakpoint ids with formats 'x.y' or
+                'x.y-z'.  */
+             enable_disable_breakpoint_location_range
+               (bp_num_range.first, bp_loc_range, enable);
+           }
          num = extract_arg (&args);
        }
     }
 }
 
+/* The disable command disables the specified breakpoints/locations
+   (or all defined breakpoints) so they're no longer effective in
+   stopping the inferior.  ARGS may be in any of the forms defined in
+   extract_bp_number_and_location.  */
+
+static void
+disable_command (const char *args, int from_tty)
+{
+  enable_disable_command (args, from_tty, false);
+}
+
 static void
 enable_breakpoint_disp (struct breakpoint *bpt, enum bpdisp disposition,
                        int count)
@@ -14991,108 +14503,33 @@ enable_breakpoint (struct breakpoint *bpt)
   enable_breakpoint_disp (bpt, bpt->disposition, 0);
 }
 
-static void
-do_enable_breakpoint (struct breakpoint *bpt, void *arg)
-{
-  enable_breakpoint (bpt);
-}
-
-/* A callback for map_breakpoint_numbers that calls
-   enable_breakpoint.  */
+/* The enable command enables the specified breakpoints/locations (or
+   all defined breakpoints) so they once again become (or continue to
+   be) effective in stopping the inferior.  ARGS may be in any of the
+   forms defined in extract_bp_number_and_location.  */
 
 static void
-do_map_enable_breakpoint (struct breakpoint *b, void *ignore)
+enable_command (const char *args, int from_tty)
 {
-  iterate_over_related_breakpoints (b, do_enable_breakpoint, NULL);
+  enable_disable_command (args, from_tty, true);
 }
 
-/* The enable command enables the specified breakpoints (or all defined
-   breakpoints) so they once again become (or continue to be) effective
-   in stopping the inferior.  */
-
 static void
-enable_command (char *args, int from_tty)
+enable_once_command (const char *args, int from_tty)
 {
-  if (args == 0)
-    {
-      struct breakpoint *bpt;
-
-      ALL_BREAKPOINTS (bpt)
-       if (user_breakpoint_p (bpt))
-         enable_breakpoint (bpt);
-    }
-  else
-    {
-      char *num = extract_arg (&args);
-
-      while (num)
-       {
-         if (strchr (num, '.'))
-           {
-             struct bp_location *loc = find_location_by_number (num);
-
-             if (loc)
-               {
-                 if (!loc->enabled)
-                   {
-                     loc->enabled = 1;
-                     mark_breakpoint_location_modified (loc);
-                   }
-                 if (target_supports_enable_disable_tracepoint ()
-                     && current_trace_status ()->running && loc->owner
-                     && is_tracepoint (loc->owner))
-                   target_enable_tracepoint (loc);
-               }
-             update_global_location_list (UGLL_MAY_INSERT);
-           }
-         else
-           map_breakpoint_numbers (num, do_map_enable_breakpoint, NULL);
-         num = extract_arg (&args);
-       }
-    }
-}
-
-/* This struct packages up disposition data for application to multiple
-   breakpoints.  */
-
-struct disp_data
-{
-  enum bpdisp disp;
-  int count;
-};
-
-static void
-do_enable_breakpoint_disp (struct breakpoint *bpt, void *arg)
-{
-  struct disp_data disp_data = *(struct disp_data *) arg;
-
-  enable_breakpoint_disp (bpt, disp_data.disp, disp_data.count);
-}
-
-static void
-do_map_enable_once_breakpoint (struct breakpoint *bpt, void *ignore)
-{
-  struct disp_data disp = { disp_disable, 1 };
-
-  iterate_over_related_breakpoints (bpt, do_enable_breakpoint_disp, &disp);
-}
-
-static void
-enable_once_command (char *args, int from_tty)
-{
-  map_breakpoint_numbers (args, do_map_enable_once_breakpoint, NULL);
-}
-
-static void
-do_map_enable_count_breakpoint (struct breakpoint *bpt, void *countptr)
-{
-  struct disp_data disp = { disp_disable, *(int *) countptr };
-
-  iterate_over_related_breakpoints (bpt, do_enable_breakpoint_disp, &disp);
+  map_breakpoint_numbers
+    (args, [&] (breakpoint *b)
+     {
+       iterate_over_related_breakpoints
+        (b, [&] (breakpoint *bpt)
+         {
+           enable_breakpoint_disp (bpt, disp_disable, 1);
+         });
+     });
 }
 
 static void
-enable_count_command (char *args, int from_tty)
+enable_count_command (const char *args, int from_tty)
 {
   int count;
 
@@ -15101,30 +14538,38 @@ enable_count_command (char *args, int from_tty)
 
   count = get_number (&args);
 
-  map_breakpoint_numbers (args, do_map_enable_count_breakpoint, &count);
-}
-
-static void
-do_map_enable_delete_breakpoint (struct breakpoint *bpt, void *ignore)
-{
-  struct disp_data disp = { disp_del, 1 };
-
-  iterate_over_related_breakpoints (bpt, do_enable_breakpoint_disp, &disp);
+  map_breakpoint_numbers
+    (args, [&] (breakpoint *b)
+     {
+       iterate_over_related_breakpoints
+        (b, [&] (breakpoint *bpt)
+         {
+           enable_breakpoint_disp (bpt, disp_disable, count);
+         });
+     });
 }
 
 static void
-enable_delete_command (char *args, int from_tty)
+enable_delete_command (const char *args, int from_tty)
 {
-  map_breakpoint_numbers (args, do_map_enable_delete_breakpoint, NULL);
+  map_breakpoint_numbers
+    (args, [&] (breakpoint *b)
+     {
+       iterate_over_related_breakpoints
+        (b, [&] (breakpoint *bpt)
+         {
+           enable_breakpoint_disp (bpt, disp_del, 1);
+         });
+     });
 }
 \f
 static void
-set_breakpoint_cmd (char *args, int from_tty)
+set_breakpoint_cmd (const char *args, int from_tty)
 {
 }
 
 static void
-show_breakpoint_cmd (char *args, int from_tty)
+show_breakpoint_cmd (const char *args, int from_tty)
 {
 }
 
@@ -15166,7 +14611,7 @@ invalidate_bp_value_on_memory_change (struct inferior *inferior,
 
 void
 insert_single_step_breakpoint (struct gdbarch *gdbarch,
-                              struct address_space *aspace, 
+                              const address_space *aspace,
                               CORE_ADDR next_pc)
 {
   struct thread_info *tp = inferior_thread ();
@@ -15193,22 +14638,19 @@ insert_single_step_breakpoint (struct gdbarch *gdbarch,
 int
 insert_single_step_breakpoints (struct gdbarch *gdbarch)
 {
-  struct frame_info *frame = get_current_frame ();
-  VEC (CORE_ADDR) * next_pcs;
+  struct regcache *regcache = get_current_regcache ();
+  std::vector<CORE_ADDR> next_pcs;
 
-  next_pcs = gdbarch_software_single_step (gdbarch, frame);
+  next_pcs = gdbarch_software_single_step (gdbarch, regcache);
 
-  if (next_pcs != NULL)
+  if (!next_pcs.empty ())
     {
-      int i;
-      CORE_ADDR pc;
-      struct address_space *aspace = get_frame_address_space (frame);
+      struct frame_info *frame = get_current_frame ();
+      const address_space *aspace = get_frame_address_space (frame);
 
-      for (i = 0; VEC_iterate (CORE_ADDR, next_pcs, i, pc); i++)
+      for (CORE_ADDR pc : next_pcs)
        insert_single_step_breakpoint (gdbarch, aspace, pc);
 
-      VEC_free (CORE_ADDR, next_pcs);
-
       return 1;
     }
   else
@@ -15219,7 +14661,7 @@ insert_single_step_breakpoints (struct gdbarch *gdbarch)
 
 int
 breakpoint_has_location_inserted_here (struct breakpoint *bp,
-                                      struct address_space *aspace,
+                                      const address_space *aspace,
                                       CORE_ADDR pc)
 {
   struct bp_location *loc;
@@ -15236,7 +14678,7 @@ breakpoint_has_location_inserted_here (struct breakpoint *bp,
    PC.  */
 
 int
-single_step_breakpoint_inserted_here_p (struct address_space *aspace,
+single_step_breakpoint_inserted_here_p (const address_space *aspace,
                                        CORE_ADDR pc)
 {
   struct breakpoint *bpt;
@@ -15261,22 +14703,20 @@ set_tracepoint_count (int num)
 }
 
 static void
-trace_command (char *arg, int from_tty)
+trace_command (const char *arg, int from_tty)
 {
   struct breakpoint_ops *ops;
-  struct event_location *location;
-  struct cleanup *back_to;
 
-  location = string_to_event_location (&arg, current_language);
-  back_to = make_cleanup_delete_event_location (location);
+  event_location_up location = string_to_event_location (&arg,
+                                                        current_language);
   if (location != NULL
-      && event_location_type (location) == PROBE_LOCATION)
+      && event_location_type (location.get ()) == PROBE_LOCATION)
     ops = &tracepoint_probe_breakpoint_ops;
   else
     ops = &tracepoint_breakpoint_ops;
 
   create_breakpoint (get_current_arch (),
-                    location,
+                    location.get (),
                     NULL, 0, arg, 1 /* parse arg */,
                     0 /* tempflag */,
                     bp_tracepoint /* type_wanted */,
@@ -15286,19 +14726,15 @@ trace_command (char *arg, int from_tty)
                     from_tty,
                     1 /* enabled */,
                     0 /* internal */, 0);
-  do_cleanups (back_to);
 }
 
 static void
-ftrace_command (char *arg, int from_tty)
+ftrace_command (const char *arg, int from_tty)
 {
-  struct event_location *location;
-  struct cleanup *back_to;
-
-  location = string_to_event_location (&arg, current_language);
-  back_to = make_cleanup_delete_event_location (location);
+  event_location_up location = string_to_event_location (&arg,
+                                                        current_language);
   create_breakpoint (get_current_arch (),
-                    location,
+                    location.get (),
                     NULL, 0, arg, 1 /* parse arg */,
                     0 /* tempflag */,
                     bp_fast_tracepoint /* type_wanted */,
@@ -15308,17 +14744,15 @@ ftrace_command (char *arg, int from_tty)
                     from_tty,
                     1 /* enabled */,
                     0 /* internal */, 0);
-  do_cleanups (back_to);
 }
 
 /* strace command implementation.  Creates a static tracepoint.  */
 
 static void
-strace_command (char *arg, int from_tty)
+strace_command (const char *arg, int from_tty)
 {
   struct breakpoint_ops *ops;
-  struct event_location *location;
-  struct cleanup *back_to;
+  event_location_up location;
 
   /* Decide if we are dealing with a static tracepoint marker (`-m'),
      or with a normal static tracepoint.  */
@@ -15333,9 +14767,8 @@ strace_command (char *arg, int from_tty)
       location = string_to_event_location (&arg, current_language);
     }
 
-  back_to = make_cleanup_delete_event_location (location);
   create_breakpoint (get_current_arch (),
-                    location,
+                    location.get (),
                     NULL, 0, arg, 1 /* parse arg */,
                     0 /* tempflag */,
                     bp_static_tracepoint /* type_wanted */,
@@ -15345,7 +14778,6 @@ strace_command (char *arg, int from_tty)
                     from_tty,
                     1 /* enabled */,
                     0 /* internal */, 0);
-  do_cleanups (back_to);
 }
 
 /* Set up a fake reader function that gets command lines from a linked
@@ -15375,10 +14807,9 @@ read_uploaded_action (void)
 struct tracepoint *
 create_tracepoint_from_upload (struct uploaded_tp *utp)
 {
-  char *addr_str, small_buf[100];
+  const char *addr_str;
+  char small_buf[100];
   struct tracepoint *tp;
-  struct event_location *location;
-  struct cleanup *cleanup;
 
   if (utp->at_string)
     addr_str = utp->at_string;
@@ -15401,10 +14832,10 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
               "has no source form, ignoring it"),
             utp->number);
 
-  location = string_to_event_location (&addr_str, current_language);
-  cleanup = make_cleanup_delete_event_location (location);
+  event_location_up location = string_to_event_location (&addr_str,
+                                                        current_language);
   if (!create_breakpoint (get_current_arch (),
-                         location,
+                         location.get (),
                          utp->cond_string, -1, addr_str,
                          0 /* parse cond/thread */,
                          0 /* tempflag */,
@@ -15416,12 +14847,7 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
                          utp->enabled /* enabled */,
                          0 /* internal */,
                          CREATE_BREAKPOINT_FLAGS_INSERTED))
-    {
-      do_cleanups (cleanup);
-      return NULL;
-    }
-
-  do_cleanups (cleanup);
+    return NULL;
 
   /* Get the tracepoint we just created.  */
   tp = get_tracepoint (tracepoint_count);
@@ -15430,7 +14856,7 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
   if (utp->pass > 0)
     {
       xsnprintf (small_buf, sizeof (small_buf), "%d %d", utp->pass,
-                tp->base.number);
+                tp->number);
 
       trace_pass_command (small_buf, 0);
     }
@@ -15441,14 +14867,14 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
      function.  */
   if (!VEC_empty (char_ptr, utp->cmd_strings))
     {
-      struct command_line *cmd_list;
+      command_line_up cmd_list;
 
       this_utp = utp;
       next_cmd = 0;
 
       cmd_list = read_command_lines_1 (read_uploaded_action, 1, NULL, NULL);
 
-      breakpoint_set_commands (&tp->base, cmd_list);
+      breakpoint_set_commands (tp, std::move (cmd_list));
     }
   else if (!VEC_empty (char_ptr, utp->actions)
           || !VEC_empty (char_ptr, utp->step_actions))
@@ -15457,7 +14883,7 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
             utp->number);
 
   /* Copy any status information that might be available.  */
-  tp->base.hit_count = utp->hit_count;
+  tp->hit_count = utp->hit_count;
   tp->traceframe_usage = utp->traceframe_usage;
 
   return tp;
@@ -15467,7 +14893,7 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
    omitted.  */
 
 static void
-tracepoints_info (char *args, int from_tty)
+info_tracepoints_command (const char *args, int from_tty)
 {
   struct ui_out *uiout = current_uiout;
   int num_printed;
@@ -15477,9 +14903,9 @@ tracepoints_info (char *args, int from_tty)
   if (num_printed == 0)
     {
       if (args == NULL || *args == '\0')
-       ui_out_message (uiout, 0, "No tracepoints.\n");
+       uiout->message ("No tracepoints.\n");
       else
-       ui_out_message (uiout, 0, "No tracepoint matching '%s'.\n", args);
+       uiout->message ("No tracepoint matching '%s'.\n", args);
     }
 
   default_collect_info ();
@@ -15488,7 +14914,7 @@ tracepoints_info (char *args, int from_tty)
 /* The 'enable trace' command enables tracepoints.
    Not supported by all targets.  */
 static void
-enable_trace_command (char *args, int from_tty)
+enable_trace_command (const char *args, int from_tty)
 {
   enable_command (args, from_tty);
 }
@@ -15496,14 +14922,14 @@ enable_trace_command (char *args, int from_tty)
 /* The 'disable trace' command disables tracepoints.
    Not supported by all targets.  */
 static void
-disable_trace_command (char *args, int from_tty)
+disable_trace_command (const char *args, int from_tty)
 {
   disable_command (args, from_tty);
 }
 
 /* Remove a tracepoint (or all if no argument).  */
 static void
-delete_trace_command (char *arg, int from_tty)
+delete_trace_command (const char *arg, int from_tty)
 {
   struct breakpoint *b, *b_tmp;
 
@@ -15534,7 +14960,11 @@ delete_trace_command (char *arg, int from_tty)
        }
     }
   else
-    map_breakpoint_numbers (arg, do_map_delete_breakpoint, NULL);
+    map_breakpoint_numbers
+      (arg, [&] (breakpoint *b)
+       {
+        iterate_over_related_breakpoints (b, delete_breakpoint);
+       });
 }
 
 /* Helper function for trace_pass_command.  */
@@ -15543,10 +14973,10 @@ static void
 trace_pass_set_count (struct tracepoint *tp, int count, int from_tty)
 {
   tp->pass_count = count;
-  observer_notify_breakpoint_modified (&tp->base);
+  observer_notify_breakpoint_modified (tp);
   if (from_tty)
     printf_filtered (_("Setting tracepoint %d's passcount to %d\n"),
-                    tp->base.number, count);
+                    tp->number, count);
 }
 
 /* Set passcount for tracepoint.
@@ -15556,16 +14986,16 @@ trace_pass_set_count (struct tracepoint *tp, int count, int from_tty)
    Also accepts special argument "all".  */
 
 static void
-trace_pass_command (char *args, int from_tty)
+trace_pass_command (const char *args, int from_tty)
 {
   struct tracepoint *t1;
-  unsigned int count;
+  ULONGEST count;
 
   if (args == 0 || *args == 0)
     error (_("passcount command requires an "
             "argument (count + optional TP num)"));
 
-  count = strtoul (args, &args, 10);   /* Count comes first, then TP num.  */
+  count = strtoulst (args, &args, 10); /* Count comes first, then TP num.  */
 
   args = skip_spaces (args);
   if (*args && strncasecmp (args, "all", 3) == 0)
@@ -15638,12 +15068,12 @@ get_tracepoint_by_number_on_target (int num)
    (tracepoint_count) is returned.  */
 
 struct tracepoint *
-get_tracepoint_by_number (char **arg,
+get_tracepoint_by_number (const char **arg,
                          number_or_range_parser *parser)
 {
   struct breakpoint *t;
   int tpnum;
-  char *instring = arg == NULL ? NULL : *arg;
+  const char *instring = arg == NULL ? NULL : *arg;
 
   if (parser != NULL)
     {
@@ -15693,13 +15123,11 @@ print_recreate_thread (struct breakpoint *b, struct ui_file *fp)
    non-zero.  */
 
 static void
-save_breakpoints (char *filename, int from_tty,
+save_breakpoints (const char *filename, int from_tty,
                  int (*filter) (const struct breakpoint *))
 {
   struct breakpoint *tp;
   int any = 0;
-  struct cleanup *cleanup;
-  struct ui_file *fp;
   int extra_trace_bits = 0;
 
   if (filename == 0 || *filename == 0)
@@ -15733,16 +15161,16 @@ save_breakpoints (char *filename, int from_tty,
       return;
     }
 
-  filename = tilde_expand (filename);
-  cleanup = make_cleanup (xfree, filename);
-  fp = gdb_fopen (filename, "w");
-  if (!fp)
+  gdb::unique_xmalloc_ptr<char> expanded_filename (tilde_expand (filename));
+
+  stdio_file fp;
+
+  if (!fp.open (expanded_filename.get (), "w"))
     error (_("Unable to open file '%s' for saving (%s)"),
-          filename, safe_strerror (errno));
-  make_cleanup_ui_file_delete (fp);
+          expanded_filename.get (), safe_strerror (errno));
 
   if (extra_trace_bits)
-    save_trace_state_variables (fp);
+    save_trace_state_variables (&fp);
 
   ALL_BREAKPOINTS (tp)
   {
@@ -15754,40 +15182,40 @@ save_breakpoints (char *filename, int from_tty,
     if (filter && !filter (tp))
       continue;
 
-    tp->ops->print_recreate (tp, fp);
+    tp->ops->print_recreate (tp, &fp);
 
     /* Note, we can't rely on tp->number for anything, as we can't
        assume the recreated breakpoint numbers will match.  Use $bpnum
        instead.  */
 
     if (tp->cond_string)
-      fprintf_unfiltered (fp, "  condition $bpnum %s\n", tp->cond_string);
+      fp.printf ("  condition $bpnum %s\n", tp->cond_string);
 
     if (tp->ignore_count)
-      fprintf_unfiltered (fp, "  ignore $bpnum %d\n", tp->ignore_count);
+      fp.printf ("  ignore $bpnum %d\n", tp->ignore_count);
 
     if (tp->type != bp_dprintf && tp->commands)
       {
-       fprintf_unfiltered (fp, "  commands\n");
+       fp.puts ("  commands\n");
        
-       ui_out_redirect (current_uiout, fp);
+       current_uiout->redirect (&fp);
        TRY
          {
-           print_command_lines (current_uiout, tp->commands->commands, 2);
+           print_command_lines (current_uiout, tp->commands.get (), 2);
          }
        CATCH (ex, RETURN_MASK_ALL)
          {
-           ui_out_redirect (current_uiout, NULL);
+         current_uiout->redirect (NULL);
            throw_exception (ex);
          }
        END_CATCH
 
-       ui_out_redirect (current_uiout, NULL);
-       fprintf_unfiltered (fp, "  end\n");
+       current_uiout->redirect (NULL);
+       fp.puts ("  end\n");
       }
 
     if (tp->enable_state == bp_disabled)
-      fprintf_unfiltered (fp, "disable $bpnum\n");
+      fp.puts ("disable $bpnum\n");
 
     /* If this is a multi-location breakpoint, check if the locations
        should be individually disabled.  Watchpoint locations are
@@ -15799,22 +15227,21 @@ save_breakpoints (char *filename, int from_tty,
 
        for (loc = tp->loc; loc != NULL; loc = loc->next, n++)
          if (!loc->enabled)
-           fprintf_unfiltered (fp, "disable $bpnum.%d\n", n);
+           fp.printf ("disable $bpnum.%d\n", n);
       }
   }
 
   if (extra_trace_bits && *default_collect)
-    fprintf_unfiltered (fp, "set default-collect %s\n", default_collect);
+    fp.printf ("set default-collect %s\n", default_collect);
 
   if (from_tty)
-    printf_filtered (_("Saved to file '%s'.\n"), filename);
-  do_cleanups (cleanup);
+    printf_filtered (_("Saved to file '%s'.\n"), expanded_filename.get ());
 }
 
 /* The `save breakpoints' command.  */
 
 static void
-save_breakpoints_command (char *args, int from_tty)
+save_breakpoints_command (const char *args, int from_tty)
 {
   save_breakpoints (args, from_tty, NULL);
 }
@@ -15822,7 +15249,7 @@ save_breakpoints_command (char *args, int from_tty)
 /* The `save tracepoints' command.  */
 
 static void
-save_tracepoints_command (char *args, int from_tty)
+save_tracepoints_command (const char *args, int from_tty)
 {
   save_breakpoints (args, from_tty, is_tracepoint);
 }
@@ -15896,21 +15323,21 @@ static struct cmd_list_element *catch_cmdlist;
 static struct cmd_list_element *tcatch_cmdlist;
 
 void
-add_catch_command (char *name, char *docstring,
-                  cmd_sfunc_ftype *sfunc,
+add_catch_command (const char *name, const char *docstring,
+                  cmd_const_sfunc_ftype *sfunc,
                   completer_ftype *completer,
                   void *user_data_catch,
                   void *user_data_tcatch)
 {
   struct cmd_list_element *command;
 
-  command = add_cmd (name, class_breakpoint, NULL, docstring,
+  command = add_cmd (name, class_breakpoint, docstring,
                     &catch_cmdlist);
   set_cmd_sfunc (command, sfunc);
   set_cmd_context (command, user_data_catch);
   set_cmd_completer (command, completer);
 
-  command = add_cmd (name, class_breakpoint, NULL, docstring,
+  command = add_cmd (name, class_breakpoint, docstring,
                     &tcatch_cmdlist);
   set_cmd_sfunc (command, sfunc);
   set_cmd_context (command, user_data_tcatch);
@@ -15918,7 +15345,7 @@ add_catch_command (char *name, char *docstring,
 }
 
 static void
-save_command (char *arg, int from_tty)
+save_command (const char *arg, int from_tty)
 {
   printf_unfiltered (_("\"save\" must be followed by "
                       "the name of a save subcommand.\n"));
@@ -15958,7 +15385,7 @@ is_non_inline_function (struct breakpoint *b)
    have been inlined.  */
 
 int
-pc_at_non_inline_function (struct address_space *aspace, CORE_ADDR pc,
+pc_at_non_inline_function (const address_space *aspace, CORE_ADDR pc,
                           const struct target_waitstatus *ws)
 {
   struct breakpoint *b;
@@ -16052,11 +15479,6 @@ initialize_breakpoint_ops (void)
   ops->print_it = momentary_bkpt_print_it;
   ops->print_mention = momentary_bkpt_print_mention;
 
-  /* Momentary breakpoints for bp_longjmp and bp_exception.  */
-  ops = &longjmp_breakpoint_ops;
-  *ops = momentary_breakpoint_ops;
-  ops->dtor = longjmp_bkpt_dtor;
-
   /* Probe breakpoints.  */
   ops = &bkpt_probe_breakpoint_ops;
   *ops = bkpt_breakpoint_ops;
@@ -16068,7 +15490,6 @@ initialize_breakpoint_ops (void)
   /* Watchpoints.  */
   ops = &watchpoint_breakpoint_ops;
   *ops = base_breakpoint_ops;
-  ops->dtor = dtor_watchpoint;
   ops->re_set = re_set_watchpoint;
   ops->insert_location = insert_watchpoint;
   ops->remove_location = remove_watchpoint;
@@ -16143,7 +15564,6 @@ initialize_breakpoint_ops (void)
   /* Exec catchpoints.  */
   ops = &catch_exec_breakpoint_ops;
   *ops = base_breakpoint_ops;
-  ops->dtor = dtor_catch_exec;
   ops->insert_location = insert_catch_exec;
   ops->remove_location = remove_catch_exec;
   ops->breakpoint_hit = breakpoint_hit_catch_exec;
@@ -16155,7 +15575,6 @@ initialize_breakpoint_ops (void)
   /* Solib-related catchpoints.  */
   ops = &catch_solib_breakpoint_ops;
   *ops = base_breakpoint_ops;
-  ops->dtor = dtor_catch_solib;
   ops->insert_location = insert_catch_solib;
   ops->remove_location = remove_catch_solib;
   ops->breakpoint_hit = breakpoint_hit_catch_solib;
@@ -16192,7 +15611,7 @@ _initialize_breakpoint (void)
   observer_attach_memory_changed (invalidate_bp_value_on_memory_change);
 
   breakpoint_objfile_key
-    = register_objfile_data_with_cleanup (NULL, free_breakpoint_probes);
+    = register_objfile_data_with_cleanup (NULL, free_breakpoint_objfile_data);
 
   breakpoint_chain = 0;
   /* Don't bother to call set_breakpoint_count.  $bpnum isn't useful
@@ -16206,8 +15625,10 @@ Set ignore-count of breakpoint number N to COUNT.\n\
 Usage is `ignore N COUNT'."));
 
   add_com ("commands", class_breakpoint, commands_command, _("\
-Set commands to be executed when a breakpoint is hit.\n\
-Give breakpoint number as argument after \"commands\".\n\
+Set commands to be executed when the given breakpoints are hit.\n\
+Give a space-separated breakpoint list as argument after \"commands\".\n\
+A list element can be a breakpoint number (e.g. `5') or a range of numbers\n\
+(e.g. `5-7').\n\
 With no argument, the targeted breakpoint is the last one set.\n\
 The commands themselves follow starting on the next line.\n\
 Type a line containing \"end\" to indicate the end of them.\n\
@@ -16358,7 +15779,7 @@ Break in function/address or break at a line in the current file."),
               _("Break in function or address."), &stoplist);
       add_cmd ("at", class_breakpoint, stopat_command,
               _("Break at a line in the current file."), &stoplist);
-      add_com ("status", class_info, breakpoints_info, _("\
+      add_com ("status", class_info, info_breakpoints_command, _("\
 Status of user-settable breakpoints, or breakpoint number NUMBER.\n\
 The \"Type\" column indicates one of:\n\
 \tbreakpoint     - normal breakpoint\n\
@@ -16375,7 +15796,7 @@ Convenience variable \"$bpnum\" contains the number of the last\n\
 breakpoint set."));
     }
 
-  add_info ("breakpoints", breakpoints_info, _("\
+  add_info ("breakpoints", info_breakpoints_command, _("\
 Status of specified breakpoints (all user-settable breakpoints if no argument).\n\
 The \"Type\" column indicates one of:\n\
 \tbreakpoint     - normal breakpoint\n\
@@ -16481,7 +15902,7 @@ If -l or -location is given, this evaluates EXPRESSION and watches\n\
 the memory to which it refers."));
   set_cmd_completer (c, expression_completer);
 
-  add_info ("watchpoints", watchpoints_info, _("\
+  add_info ("watchpoints", info_watchpoints_command, _("\
 Status of specified watchpoints (all watchpoints if no argument)."));
 
   /* XXX: cagney/2005-02-23: This should be a boolean, and should
@@ -16543,7 +15964,7 @@ Do \"help breakpoints\" for info on other commands dealing with breakpoints.\n\
 Do \"help tracepoints\" for info on other tracepoint commands."));
   set_cmd_completer (c, location_completer);
 
-  add_info ("tracepoints", tracepoints_info, _("\
+  add_info ("tracepoints", info_tracepoints_command, _("\
 Status of specified tracepoints (all tracepoints if no argument).\n\
 Convenience variable \"$tpnum\" contains the number of the\n\
 last tracepoint set."));
This page took 0.157014 seconds and 4 git commands to generate.