Convert location_spec_empty_p to a method
[binutils-gdb.git] / gdb / breakpoint.c
index 9abc1443d968f4c2ad9937c4ff23c90f38aa40a0..bfa9e68fdbe72a0459627cd7e2bbf71b48cc9e37 100644 (file)
 static void map_breakpoint_numbers (const char *,
                                    gdb::function_view<void (breakpoint *)>);
 
-static void breakpoint_re_set_default (struct breakpoint *);
+static void breakpoint_re_set_default (code_breakpoint *);
 
 static void
-  create_sals_from_location_default (struct event_location *location,
-                                    struct linespec_result *canonical);
+  create_sals_from_location_spec_default (location_spec *locspec,
+                                         linespec_result *canonical);
 
 static void create_breakpoints_sal (struct gdbarch *,
                                    struct linespec_result *,
@@ -100,11 +100,10 @@ static void create_breakpoints_sal (struct gdbarch *,
                                    enum bptype,
                                    enum bpdisp, int, int,
                                    int,
-                                   const struct breakpoint_ops *,
                                    int, int, int, unsigned);
 
-static std::vector<symtab_and_line> decode_location_default
-  (struct breakpoint *b, struct event_location *location,
+static std::vector<symtab_and_line> decode_location_spec_default
+  (struct breakpoint *b, struct location_spec *locspec,
    struct program_space *search_pspace);
 
 static int can_use_hardware_watchpoint
@@ -112,21 +111,14 @@ static int can_use_hardware_watchpoint
 
 static void mention (const breakpoint *);
 
-static struct breakpoint *set_raw_breakpoint_without_location (struct gdbarch *,
-                                                              enum bptype);
-static struct bp_location *add_location_to_breakpoint (struct breakpoint *,
-                                                      const struct symtab_and_line *);
+static breakpoint *add_to_breakpoint_chain (std::unique_ptr<breakpoint> &&b);
 
-/* This function is used in gdbtk sources and thus can not be made
-   static.  */
-static struct breakpoint *set_raw_breakpoint (struct gdbarch *gdbarch,
-                                             struct symtab_and_line,
-                                             enum bptype);
+static breakpoint *add_to_breakpoint_chain (std::unique_ptr<breakpoint> &&b);
 
 static struct breakpoint *
   momentary_breakpoint_from_master (struct breakpoint *orig,
                                    enum bptype type,
-                                   int loc_enabled);
+                                   int loc_enabled, int thread);
 
 static void breakpoint_adjustment_warning (CORE_ADDR, CORE_ADDR, int, int);
 
@@ -134,10 +126,6 @@ static CORE_ADDR adjust_breakpoint_address (struct gdbarch *gdbarch,
                                            CORE_ADDR bpaddr,
                                            enum bptype bptype);
 
-static void describe_other_breakpoints (struct gdbarch *,
-                                       struct program_space *, CORE_ADDR,
-                                       struct obj_section *, int);
-
 static int watchpoint_locations_match (struct bp_location *loc1,
                                       struct bp_location *loc2);
 
@@ -171,11 +159,13 @@ static void enable_breakpoint_disp (struct breakpoint *, enum bpdisp,
 
 static void decref_bp_location (struct bp_location **loc);
 
-static std::vector<symtab_and_line> bkpt_probe_decode_location
+static std::vector<symtab_and_line> bkpt_probe_decode_location_spec
      (struct breakpoint *b,
-      struct event_location *location,
+      location_spec *locspec,
       struct program_space *search_pspace);
 
+static bool bl_address_is_meaningful (bp_location *loc);
+
 /* update_global_location_list's modes of operation wrt to whether to
    insert locations now.  */
 enum ugll_insert_mode
@@ -228,37 +218,52 @@ static bool is_masked_watchpoint (const struct breakpoint *b);
 
 static int strace_marker_p (struct breakpoint *b);
 
-static void bkpt_probe_create_sals_from_location
-     (struct event_location *location,
+static void bkpt_probe_create_sals_from_location_spec
+     (location_spec *locspec,
       struct linespec_result *canonical);
-static void tracepoint_probe_create_sals_from_location
-     (struct event_location *location,
+static void tracepoint_probe_create_sals_from_location_spec
+     (location_spec *locspec,
       struct linespec_result *canonical);
 
-const struct breakpoint_ops base_breakpoint_ops =
+const struct breakpoint_ops code_breakpoint_ops =
 {
-  create_sals_from_location_default,
+  create_sals_from_location_spec_default,
   create_breakpoints_sal,
 };
 
 /* Breakpoints set on probes.  */
 static const struct breakpoint_ops bkpt_probe_breakpoint_ops =
 {
-  bkpt_probe_create_sals_from_location,
+  bkpt_probe_create_sals_from_location_spec,
   create_breakpoints_sal,
 };
 
 /* Tracepoints set on probes.  */
 static const struct breakpoint_ops tracepoint_probe_breakpoint_ops =
 {
-  tracepoint_probe_create_sals_from_location,
+  tracepoint_probe_create_sals_from_location_spec,
   create_breakpoints_sal,
 };
 
+/* Implementation of abstract dtors.  These must exist to satisfy the
+   linker.  */
+
+breakpoint::~breakpoint ()
+{
+}
+
+code_breakpoint::~code_breakpoint ()
+{
+}
+
+catchpoint::~catchpoint ()
+{
+}
+
 /* The structure to be used in regular breakpoints.  */
-struct ordinary_breakpoint : public base_breakpoint
+struct ordinary_breakpoint : public code_breakpoint
 {
-  using base_breakpoint::base_breakpoint;
+  using code_breakpoint::code_breakpoint;
 
   int resources_needed (const struct bp_location *) override;
   enum print_stop_action print_it (const bpstat *bs) const override;
@@ -266,10 +271,25 @@ struct ordinary_breakpoint : public base_breakpoint
   void print_recreate (struct ui_file *fp) const override;
 };
 
-/* Internal breakpoints.  */
-struct internal_breakpoint : public base_breakpoint
+/* Internal breakpoints.  These typically have a lifetime the same as
+   the program, and they end up installed on the breakpoint chain with
+   a negative breakpoint number.  They're visible in "maint info
+   breakpoints", but not "info breakpoints".  */
+struct internal_breakpoint : public code_breakpoint
 {
-  using base_breakpoint::base_breakpoint;
+  internal_breakpoint (struct gdbarch *gdbarch,
+                      enum bptype type, CORE_ADDR address)
+    : code_breakpoint (gdbarch, type)
+  {
+    symtab_and_line sal;
+    sal.pc = address;
+    sal.section = find_pc_overlay (sal.pc);
+    sal.pspace = current_program_space;
+    add_location (sal);
+
+    pspace = current_program_space;
+    disposition = disp_donttouch;
+  }
 
   void re_set () override;
   void check_status (struct bpstat *bs) override;
@@ -277,10 +297,33 @@ struct internal_breakpoint : public base_breakpoint
   void print_mention () const override;
 };
 
-/* Momentary breakpoints.  */
-struct momentary_breakpoint : public base_breakpoint
-{
-  using base_breakpoint::base_breakpoint;
+/* Momentary breakpoints.  These typically have a lifetime of some run
+   control command only, are always thread-specific, and have 0 for
+   breakpoint number.  I.e., there can be many momentary breakpoints
+   on the breakpoint chain and they all same the same number (zero).
+   They're visible in "maint info breakpoints", but not "info
+   breakpoints".  */
+struct momentary_breakpoint : public code_breakpoint
+{
+  momentary_breakpoint (struct gdbarch *gdbarch_, enum bptype bptype,
+                       program_space *pspace_,
+                       const struct frame_id &frame_id_,
+                       int thread_)
+    : code_breakpoint (gdbarch_, bptype)
+  {
+    /* If FRAME_ID is valid, it should be a real frame, not an inlined
+       or tail-called one.  */
+    gdb_assert (!frame_id_artificial_p (frame_id));
+
+    /* Momentary breakpoints are always thread-specific.  */
+    gdb_assert (thread_ > 0);
+
+    pspace = pspace_;
+    enable_state = bp_enabled;
+    disposition = disp_donttouch;
+    frame_id = frame_id_;
+    thread = thread_;
+  }
 
   void re_set () override;
   void check_status (struct bpstat *bs) override;
@@ -305,9 +348,20 @@ struct dprintf_breakpoint : public ordinary_breakpoint
 /* Ranged breakpoints.  */
 struct ranged_breakpoint : public ordinary_breakpoint
 {
-  explicit ranged_breakpoint (struct gdbarch *gdbarch)
+  explicit ranged_breakpoint (struct gdbarch *gdbarch,
+                             const symtab_and_line &sal_start,
+                             int length,
+                             location_spec_up start_locspec,
+                             location_spec_up end_locspec)
     : ordinary_breakpoint (gdbarch, bp_hardware_breakpoint)
   {
+    bp_location *bl = add_location (sal_start);
+    bl->length = length;
+
+    disposition = disp_donttouch;
+
+    locspec = std::move (start_locspec);
+    locspec_range_end = std::move (end_locspec);
   }
 
   int breakpoint_hit (const struct bp_location *bl,
@@ -327,8 +381,8 @@ struct static_marker_tracepoint : public tracepoint
 {
   using tracepoint::tracepoint;
 
-  std::vector<symtab_and_line> decode_location
-       (struct event_location *location,
+  std::vector<symtab_and_line> decode_location_spec
+       (struct location_spec *locspec,
        struct program_space *search_pspace) override;
 };
 
@@ -1235,66 +1289,43 @@ is_tracepoint (const struct breakpoint *b)
 /* Factory function to create an appropriate instance of breakpoint given
    TYPE.  */
 
-static std::unique_ptr<breakpoint>
-new_breakpoint_from_type (struct gdbarch *gdbarch, bptype type)
+template<typename... Arg>
+static std::unique_ptr<code_breakpoint>
+new_breakpoint_from_type (struct gdbarch *gdbarch, bptype type,
+                         Arg&&... args)
 {
-  breakpoint *b;
+  code_breakpoint *b;
 
   switch (type)
     {
     case bp_breakpoint:
     case bp_hardware_breakpoint:
-      b = new ordinary_breakpoint (gdbarch, type);
+      b = new ordinary_breakpoint (gdbarch, type,
+                                  std::forward<Arg> (args)...);
       break;
 
     case bp_fast_tracepoint:
     case bp_static_tracepoint:
     case bp_tracepoint:
-      b = new tracepoint (gdbarch, type);
+      b = new tracepoint (gdbarch, type,
+                         std::forward<Arg> (args)...);
       break;
 
     case bp_static_marker_tracepoint:
-      b = new static_marker_tracepoint (gdbarch, type);
+      b = new static_marker_tracepoint (gdbarch, type,
+                                       std::forward<Arg> (args)...);
       break;
 
     case bp_dprintf:
-      b = new dprintf_breakpoint (gdbarch, type);
-      break;
-
-    case bp_overlay_event:
-    case bp_longjmp_master:
-    case bp_std_terminate_master:
-    case bp_exception_master:
-    case bp_thread_event:
-    case bp_jit_event:
-    case bp_shlib_event:
-      b = new internal_breakpoint (gdbarch, type);
-      break;
-
-    case bp_longjmp:
-    case bp_exception:
-      b = new longjmp_breakpoint (gdbarch, type);
-      break;
-
-    case bp_watchpoint_scope:
-    case bp_finish:
-    case bp_gnu_ifunc_resolver_return:
-    case bp_step_resume:
-    case bp_hp_step_resume:
-    case bp_longjmp_resume:
-    case bp_longjmp_call_dummy:
-    case bp_exception_resume:
-    case bp_call_dummy:
-    case bp_until:
-    case bp_std_terminate:
-      b = new momentary_breakpoint (gdbarch, type);
+      b = new dprintf_breakpoint (gdbarch, type,
+                                 std::forward<Arg> (args)...);
       break;
 
     default:
       gdb_assert_not_reached ("invalid type");
     }
 
-  return std::unique_ptr<breakpoint> (b);
+  return std::unique_ptr<code_breakpoint> (b);
 }
 
 /* A helper function that validates that COMMANDS are valid for a
@@ -1827,34 +1858,18 @@ extract_bitfield_from_watchpoint_value (struct watchpoint *w, struct value *val)
   return bit_val;
 }
 
-/* Allocate a dummy location and add it to B, which must be a software
-   watchpoint.  This is required because even if a software watchpoint
-   is not watching any memory, bpstat_stop_status requires a location
-   to be able to report stops.  */
+/* Allocate a dummy location and add it to B.  This is required
+   because bpstat_stop_status requires a location to be able to report
+   stops.  */
 
 static void
-software_watchpoint_add_no_memory_location (struct breakpoint *b,
-                                           struct program_space *pspace)
+add_dummy_location (struct breakpoint *b,
+                   struct program_space *pspace)
 {
-  gdb_assert (b->type == bp_watchpoint && b->loc == NULL);
+  gdb_assert (b->loc == NULL);
 
-  b->loc = b->allocate_location ();
+  b->loc = new bp_location (b, bp_loc_other);
   b->loc->pspace = pspace;
-  b->loc->address = -1;
-  b->loc->length = -1;
-}
-
-/* Returns true if B is a software watchpoint that is not watching any
-   memory (e.g., "watch $pc").  */
-
-static bool
-is_no_memory_software_watchpoint (struct breakpoint *b)
-{
-  return (b->type == bp_watchpoint
-         && b->loc != NULL
-         && b->loc->next == NULL
-         && b->loc->address == -1
-         && b->loc->length == -1);
 }
 
 /* Assuming that B is a watchpoint:
@@ -2194,7 +2209,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
          else
            b->type = bp_watchpoint;
 
-         loc_type = (b->type == bp_watchpoint? bp_loc_other
+         loc_type = (b->type == bp_watchpoint? bp_loc_software_watchpoint
                      : bp_loc_hardware_watchpoint);
          for (bp_location *bl : b->locations ())
            bl->loc_type = loc_type;
@@ -2205,7 +2220,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
         bpstat_stop_status requires a location to be able to report
         stops, so make sure there's at least a dummy one.  */
       if (b->type == bp_watchpoint && b->loc == NULL)
-       software_watchpoint_add_no_memory_location (b, frame_pspace);
+       add_dummy_location (b, frame_pspace);
     }
   else if (!within_current_scope)
     {
@@ -3267,16 +3282,12 @@ static struct breakpoint *
 create_internal_breakpoint (struct gdbarch *gdbarch,
                            CORE_ADDR address, enum bptype type)
 {
-  symtab_and_line sal;
-  sal.pc = address;
-  sal.section = find_pc_overlay (sal.pc);
-  sal.pspace = current_program_space;
+  std::unique_ptr<internal_breakpoint> b
+    (new internal_breakpoint (gdbarch, type, address));
 
-  breakpoint *b = set_raw_breakpoint (gdbarch, sal, type);
   b->number = internal_breakpoint_number--;
-  b->disposition = disp_donttouch;
 
-  return b;
+  return add_to_breakpoint_chain (std::move (b));
 }
 
 static const char *const longjmp_names[] =
@@ -3353,7 +3364,6 @@ create_overlay_event_breakpoint (void)
       struct breakpoint *b;
       struct breakpoint_objfile_data *bp_objfile_data;
       CORE_ADDR addr;
-      struct explicit_location explicit_loc;
 
       bp_objfile_data = get_breakpoint_objfile_data (objfile);
 
@@ -3377,9 +3387,7 @@ create_overlay_event_breakpoint (void)
       addr = bp_objfile_data->overlay_msym.value_address ();
       b = create_internal_breakpoint (objfile->arch (), addr,
                                      bp_overlay_event);
-      initialize_explicit_location (&explicit_loc);
-      explicit_loc.function_name = ASTRDUP (func_name);
-      b->location = new_explicit_location (&explicit_loc);
+      b->locspec = new_explicit_location_spec_function (func_name);
 
       if (overlay_debugging == ovly_auto)
        {
@@ -3436,7 +3444,7 @@ create_longjmp_master_breakpoint_probe (objfile *objfile)
       b = create_internal_breakpoint (gdbarch,
                                      p->get_relocated_address (objfile),
                                      bp_longjmp_master);
-      b->location = new_probe_location ("-probe-stap libc:longjmp");
+      b->locspec = new_probe_location_spec ("-probe-stap libc:longjmp");
       b->enable_state = bp_disabled;
     }
 
@@ -3462,7 +3470,6 @@ create_longjmp_master_breakpoint_names (objfile *objfile)
       struct breakpoint *b;
       const char *func_name;
       CORE_ADDR addr;
-      struct explicit_location explicit_loc;
 
       if (msym_not_found_p (bp_objfile_data->longjmp_msym[i].minsym))
        continue;
@@ -3484,9 +3491,7 @@ create_longjmp_master_breakpoint_names (objfile *objfile)
 
       addr = bp_objfile_data->longjmp_msym[i].value_address ();
       b = create_internal_breakpoint (gdbarch, addr, bp_longjmp_master);
-      initialize_explicit_location (&explicit_loc);
-      explicit_loc.function_name = ASTRDUP (func_name);
-      b->location = new_explicit_location (&explicit_loc);
+      b->locspec = new_explicit_location_spec_function (func_name);
       b->enable_state = bp_disabled;
       installed_bp++;
     }
@@ -3542,7 +3547,6 @@ create_std_terminate_master_breakpoint (void)
        {
          struct breakpoint *b;
          struct breakpoint_objfile_data *bp_objfile_data;
-         struct explicit_location explicit_loc;
 
          bp_objfile_data = get_breakpoint_objfile_data (objfile);
 
@@ -3567,9 +3571,7 @@ create_std_terminate_master_breakpoint (void)
          addr = bp_objfile_data->terminate_msym.value_address ();
          b = create_internal_breakpoint (objfile->arch (), addr,
                                          bp_std_terminate_master);
-         initialize_explicit_location (&explicit_loc);
-         explicit_loc.function_name = ASTRDUP (func_name);
-         b->location = new_explicit_location (&explicit_loc);
+         b->locspec = new_explicit_location_spec_function (func_name);
          b->enable_state = bp_disabled;
        }
     }
@@ -3619,7 +3621,7 @@ create_exception_master_breakpoint_probe (objfile *objfile)
       b = create_internal_breakpoint (gdbarch,
                                      p->get_relocated_address (objfile),
                                      bp_exception_master);
-      b->location = new_probe_location ("-probe-stap libgcc:unwind");
+      b->locspec = new_probe_location_spec ("-probe-stap libgcc:unwind");
       b->enable_state = bp_disabled;
     }
 
@@ -3637,7 +3639,6 @@ create_exception_master_breakpoint_hook (objfile *objfile)
   struct gdbarch *gdbarch;
   struct breakpoint_objfile_data *bp_objfile_data;
   CORE_ADDR addr;
-  struct explicit_location explicit_loc;
 
   bp_objfile_data = get_breakpoint_objfile_data (objfile);
 
@@ -3664,9 +3665,7 @@ create_exception_master_breakpoint_hook (objfile *objfile)
   addr = gdbarch_convert_from_func_ptr_addr
     (gdbarch, addr, current_inferior ()->top_target ());
   b = create_internal_breakpoint (gdbarch, addr, bp_exception_master);
-  initialize_explicit_location (&explicit_loc);
-  explicit_loc.function_name = ASTRDUP (func_name);
-  b->location = new_explicit_location (&explicit_loc);
+  b->locspec = new_explicit_location_spec_function (func_name);
   b->enable_state = bp_disabled;
 
   return true;
@@ -3698,9 +3697,9 @@ create_exception_master_breakpoint (void)
 /* Does B have a location spec?  */
 
 static int
-breakpoint_event_location_empty_p (const struct breakpoint *b)
+breakpoint_location_spec_empty_p (const struct breakpoint *b)
 {
-  return b->location != NULL && event_location_empty_p (b->location.get ());
+  return (b->locspec != nullptr && b->locspec->empty_p ());
 }
 
 void
@@ -3814,7 +3813,7 @@ update_breakpoints_after_exec (void)
       /* Without a symbolic address, we have little hope of the
         pre-exec() address meaning the same thing in the post-exec()
         a.out.  */
-      if (breakpoint_event_location_empty_p (b))
+      if (breakpoint_location_spec_empty_p (b))
        {
          delete_breakpoint (b);
          continue;
@@ -3841,11 +3840,12 @@ detach_breakpoints (ptid_t ptid)
 
       /* This function must physically remove breakpoints locations
         from the specified ptid, without modifying the breakpoint
-        package's state.  Locations of type bp_loc_other are only
-        maintained at GDB side.  So, there is no need to remove
-        these bp_loc_other locations.  Moreover, removing these
+        package's state.  Locations of type bp_loc_other and
+        bp_loc_software_watchpoint are only maintained at GDB side,
+        so there is no need to remove them.  Moreover, removing these
         would modify the breakpoint package's state.  */
-      if (bl->loc_type == bp_loc_other)
+      if (bl->loc_type == bp_loc_other
+         || bl->loc_type == bp_loc_software_watchpoint)
        continue;
 
       if (bl->inserted)
@@ -5799,7 +5799,8 @@ bpstat_what (bpstat *bs_head)
            {
              /* Some catchpoints are implemented with breakpoints.
                 For those, we need to step over the breakpoint.  */
-             if (bs->bp_location_at->loc_type != bp_loc_other)
+             if (bs->bp_location_at->loc_type == bp_loc_software_breakpoint
+                 || bs->bp_location_at->loc_type == bp_loc_hardware_breakpoint)
                this_action = BPSTAT_WHAT_SINGLE;
            }
          break;
@@ -5873,10 +5874,10 @@ bpstat_run_callbacks (bpstat *bs_head)
          handle_jit_event (bs->bp_location_at->address);
          break;
        case bp_gnu_ifunc_resolver:
-         gnu_ifunc_resolver_stop (b);
+         gnu_ifunc_resolver_stop ((code_breakpoint *) b);
          break;
        case bp_gnu_ifunc_resolver_return:
-         gnu_ifunc_resolver_return_stop (b);
+         gnu_ifunc_resolver_return_stop ((code_breakpoint *) b);
          break;
        }
     }
@@ -6006,7 +6007,8 @@ print_breakpoint_location (const breakpoint *b,
     set_current_program_space (loc->pspace);
 
   if (b->display_canonical)
-    uiout->field_string ("what", event_location_to_string (b->location.get ()));
+    uiout->field_string ("what",
+                        location_spec_to_string (b->locspec.get ()));
   else if (loc && loc->symtab)
     {
       const struct symbol *sym = loc->symbol;
@@ -6041,7 +6043,7 @@ print_breakpoint_location (const breakpoint *b,
   else
     {
       uiout->field_string ("pending",
-                          event_location_to_string (b->location.get ()));
+                          location_spec_to_string (b->locspec.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.  */
@@ -6221,13 +6223,38 @@ print_one_breakpoint_location (struct breakpoint *b,
 
   /* 4 */
   annotate_field (3);
-  /* For locations that are disabled because of an invalid condition,
-     display "N*" on CLI, where "*" refers to a footnote below the
-     table.  For MI, simply display a "N" without a footnote.  */
-  const char *N = (uiout->is_mi_like_p ()) ? "N" : "N*";
   if (part_of_multiple)
-    uiout->field_string ("enabled", (loc->disabled_by_cond ? N
-                                    : (loc->enabled ? "y" : "n")));
+    {
+      /* For locations that are disabled because of an invalid
+        condition, display "N*" on the CLI, where "*" refers to a
+        footnote below the table.  For MI, simply display a "N"
+        without a footnote.  On the CLI, for enabled locations whose
+        breakpoint is disabled, display "y-".  */
+      auto get_enable_state = [uiout, loc] () -> const char *
+        {
+         if (uiout->is_mi_like_p ())
+           {
+             if (loc->disabled_by_cond)
+               return "N";
+             else if (!loc->enabled)
+               return "n";
+             else
+               return "y";
+           }
+         else
+           {
+             if (loc->disabled_by_cond)
+               return "N*";
+             else if (!loc->enabled)
+               return "n";
+             else if (!breakpoint_enabled (loc->owner))
+               return "y-";
+             else
+               return "y";
+           }
+       };
+      uiout->field_string ("enabled", get_enable_state ());
+    }
   else
     uiout->field_fmt ("enabled", "%c", bpenables[(int) b->enable_state]);
 
@@ -6476,10 +6503,12 @@ print_one_breakpoint_location (struct breakpoint *b,
 
          uiout->field_string ("original-location", w->exp_string.get ());
        }
-      else if (b->location != NULL
-              && event_location_to_string (b->location.get ()) != NULL)
-       uiout->field_string ("original-location",
-                            event_location_to_string (b->location.get ()));
+      else if (b->locspec != nullptr)
+       {
+         const char *str = location_spec_to_string (b->locspec.get ());
+         if (str != nullptr)
+           uiout->field_string ("original-location", str);
+       }
     }
 
   return result;
@@ -6558,16 +6587,12 @@ breakpoint_address_bits (struct breakpoint *b)
 {
   int print_address_bits = 0;
 
-  /* Software watchpoints that aren't watching memory don't have an
-     address to print.  */
-  if (is_no_memory_software_watchpoint (b))
-    return 0;
-
   for (bp_location *loc : b->locations ())
     {
-      int addr_bit;
+      if (!bl_address_is_meaningful (loc))
+       continue;
 
-      addr_bit = gdbarch_addr_bit (loc->gdbarch);
+      int addr_bit = gdbarch_addr_bit (loc->gdbarch);
       if (addr_bit > print_address_bits)
        print_address_bits = addr_bit;
     }
@@ -6831,11 +6856,9 @@ breakpoint_has_pc (struct breakpoint *b,
   return 0;
 }
 
-/* Print a message describing any user-breakpoints set at PC.  This
-   concerns with logical breakpoints, so we match program spaces, not
-   address spaces.  */
+/* See breakpoint.h.  */
 
-static void
+void
 describe_other_breakpoints (struct gdbarch *gdbarch,
                            struct program_space *pspace, CORE_ADDR pc,
                            struct obj_section *section, int thread)
@@ -7164,6 +7187,7 @@ bp_location_from_bp_type (bptype type)
     case bp_access_watchpoint:
       return bp_loc_hardware_watchpoint;
     case bp_watchpoint:
+      return bp_loc_software_watchpoint;
     case bp_catchpoint:
     case bp_tracepoint:
     case bp_fast_tracepoint:
@@ -7232,18 +7256,6 @@ add_to_breakpoint_chain (std::unique_ptr<breakpoint> &&b)
   return result;
 }
 
-/* Helper to set_raw_breakpoint below.  Creates a breakpoint
-   that has type BPTYPE and has no locations as yet.  */
-
-static struct breakpoint *
-set_raw_breakpoint_without_location (struct gdbarch *gdbarch,
-                                    enum bptype bptype)
-{
-  std::unique_ptr<breakpoint> b = new_breakpoint_from_type (gdbarch, bptype);
-
-  return add_to_breakpoint_chain (std::move (b));
-}
-
 /* Initialize loc->function_name.  */
 
 static void
@@ -7296,55 +7308,6 @@ get_sal_arch (struct symtab_and_line sal)
   return NULL;
 }
 
-/* Low level routine for partially initializing a breakpoint of type
-   BPTYPE.  The newly created breakpoint's address, section, source
-   file name, and line number are provided by SAL.
-
-   It is expected that the caller will complete the initialization of
-   the newly created breakpoint struct as well as output any status
-   information regarding the creation of a new breakpoint.  */
-
-static void
-init_raw_breakpoint (struct breakpoint *b, struct symtab_and_line sal,
-                    enum bptype bptype)
-{
-  add_location_to_breakpoint (b, &sal);
-
-  if (bptype != bp_catchpoint)
-    gdb_assert (sal.pspace != NULL);
-
-  /* Store the program space that was used to set the breakpoint,
-     except for ordinary breakpoints, which are independent of the
-     program space.  */
-  if (bptype != bp_breakpoint && bptype != bp_hardware_breakpoint)
-    b->pspace = sal.pspace;
-}
-
-/* set_raw_breakpoint is a low level routine for allocating and
-   partially initializing a breakpoint of type BPTYPE.  The newly
-   created breakpoint's address, section, source file name, and line
-   number are provided by SAL.  The newly created and partially
-   initialized breakpoint is added to the breakpoint chain and
-   is also returned as the value of this function.
-
-   It is expected that the caller will complete the initialization of
-   the newly created breakpoint struct as well as output any status
-   information regarding the creation of a new breakpoint.  In
-   particular, set_raw_breakpoint does NOT set the breakpoint
-   number!  Care should be taken to not allow an error to occur
-   prior to completing the initialization of the breakpoint.  If this
-   should happen, a bogus breakpoint will be left on the chain.  */
-
-static struct breakpoint *
-set_raw_breakpoint (struct gdbarch *gdbarch,
-                   struct symtab_and_line sal, enum bptype bptype)
-{
-  std::unique_ptr<breakpoint> b = new_breakpoint_from_type (gdbarch, bptype);
-
-  init_raw_breakpoint (b.get (), sal, bptype);
-  return add_to_breakpoint_chain (std::move (b));
-}
-
 /* Call this routine when stepping and nexting to enable a breakpoint
    if we do a longjmp() or 'throw' in TP.  FRAME is the frame which
    initiated the operation.  */
@@ -7364,12 +7327,9 @@ set_longjmp_breakpoint (struct thread_info *tp, struct frame_id frame)
            || b->type == bp_exception_master))
       {
        enum bptype type = b->type == bp_longjmp_master ? bp_longjmp : bp_exception;
-       struct breakpoint *clone;
-
        /* longjmp_breakpoint_ops ensures INITIATING_FRAME is cleared again
           after their removal.  */
-       clone = momentary_breakpoint_from_master (b, type, 1);
-       clone->thread = thread;
+       momentary_breakpoint_from_master (b, type, 1, thread);
       }
 
   tp->initiating_frame = frame;
@@ -7411,11 +7371,10 @@ set_longjmp_breakpoint_for_call_dummy (void)
   for (breakpoint *b : all_breakpoints ())
     if (b->pspace == current_program_space && b->type == bp_longjmp_master)
       {
-       struct breakpoint *new_b;
-
-       new_b = momentary_breakpoint_from_master (b, bp_longjmp_call_dummy,
-                                                 1);
-       new_b->thread = inferior_thread ()->global_num;
+       int thread = inferior_thread ()->global_num;
+       breakpoint *new_b
+         = momentary_breakpoint_from_master (b, bp_longjmp_call_dummy,
+                                             1, thread);
 
        /* Link NEW_B into the chain of RETVAL breakpoints.  */
 
@@ -7544,7 +7503,8 @@ set_std_terminate_breakpoint (void)
     if (b->pspace == current_program_space
        && b->type == bp_std_terminate_master)
       {
-       momentary_breakpoint_from_master (b, bp_std_terminate, 1);
+       momentary_breakpoint_from_master (b, bp_std_terminate, 1,
+                                         inferior_thread ()->global_num);
       }
 }
 
@@ -7565,8 +7525,8 @@ create_thread_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address)
   b = create_internal_breakpoint (gdbarch, address, bp_thread_event);
 
   b->enable_state = bp_enabled;
-  /* location has to be used or breakpoint_re_set will delete me.  */
-  b->location = new_address_location (b->loc->address, NULL, 0);
+  /* locspec has to be used or breakpoint_re_set will delete me.  */
+  b->locspec = new_address_location_spec (b->loc->address, NULL, 0);
 
   update_global_location_list_nothrow (UGLL_MAY_INSERT);
 
@@ -7804,18 +7764,29 @@ disable_breakpoints_in_freed_objfile (struct objfile *objfile)
 
 /* See breakpoint.h.  */
 
-catchpoint::catchpoint (struct gdbarch *gdbarch, bool temp,
-                       const char *cond_string_)
-  : base_breakpoint (gdbarch, bp_catchpoint)
+breakpoint::breakpoint (struct gdbarch *gdbarch_, enum bptype bptype,
+                       bool temp, const char *cond_string_)
+  : type (bptype),
+    disposition (temp ? disp_del : disp_donttouch),
+    gdbarch (gdbarch_),
+    language (current_language->la_language),
+    input_radix (::input_radix),
+    cond_string (cond_string_ != nullptr
+                ? make_unique_xstrdup (cond_string_)
+                : nullptr),
+    related_breakpoint (this)
 {
-  symtab_and_line sal;
-  sal.pspace = current_program_space;
+}
 
-  init_raw_breakpoint (this, sal, bp_catchpoint);
+/* See breakpoint.h.  */
+
+catchpoint::catchpoint (struct gdbarch *gdbarch, bool temp,
+                       const char *cond_string)
+  : breakpoint (gdbarch, bp_catchpoint, temp, cond_string)
+{
+  add_dummy_location (this, current_program_space);
 
-  if (cond_string_ != nullptr)
-    cond_string = make_unique_xstrdup (cond_string_);
-  disposition = temp ? disp_del : disp_donttouch;
+  pspace = current_program_space;
 }
 
 void
@@ -7935,22 +7906,19 @@ enable_breakpoints_after_startup (void)
   breakpoint_re_set ();
 }
 
-/* Create a new single-step breakpoint for thread THREAD, with no
-   locations.  */
+/* Allocate a new momentary breakpoint.  */
 
-static struct breakpoint *
-new_single_step_breakpoint (int thread, struct gdbarch *gdbarch)
+template<typename... Arg>
+static momentary_breakpoint *
+new_momentary_breakpoint (struct gdbarch *gdbarch, enum bptype type,
+                         Arg&&... args)
 {
-  std::unique_ptr<breakpoint> b (new momentary_breakpoint (gdbarch,
-                                                          bp_single_step));
-
-  b->disposition = disp_donttouch;
-  b->frame_id = null_frame_id;
-
-  b->thread = thread;
-  gdb_assert (b->thread != 0);
-
-  return add_to_breakpoint_chain (std::move (b));
+  if (type == bp_longjmp || type == bp_exception)
+    return new longjmp_breakpoint (gdbarch, type,
+                                  std::forward<Arg> (args)...);
+  else
+    return new momentary_breakpoint (gdbarch, type,
+                                    std::forward<Arg> (args)...);
 }
 
 /* Set a momentary breakpoint of type TYPE at address specified by
@@ -7961,22 +7929,21 @@ breakpoint_up
 set_momentary_breakpoint (struct gdbarch *gdbarch, struct symtab_and_line sal,
                          struct frame_id frame_id, enum bptype type)
 {
-  struct breakpoint *b;
-
   /* If FRAME_ID is valid, it should be a real frame, not an inlined or
      tail-called one.  */
   gdb_assert (!frame_id_artificial_p (frame_id));
 
-  b = set_raw_breakpoint (gdbarch, sal, type);
-  b->enable_state = bp_enabled;
-  b->disposition = disp_donttouch;
-  b->frame_id = frame_id;
+  std::unique_ptr<momentary_breakpoint> b
+    (new_momentary_breakpoint (gdbarch, type, sal.pspace, frame_id,
+                              inferior_thread ()->global_num));
 
-  b->thread = inferior_thread ()->global_num;
+  b->add_location (sal);
+
+  breakpoint_up bp (add_to_breakpoint_chain (std::move (b)));
 
   update_global_location_list_nothrow (UGLL_MAY_INSERT);
 
-  return breakpoint_up (b);
+  return bp;
 }
 
 /* Make a momentary breakpoint based on the master breakpoint ORIG.
@@ -7986,11 +7953,12 @@ set_momentary_breakpoint (struct gdbarch *gdbarch, struct symtab_and_line sal,
 static struct breakpoint *
 momentary_breakpoint_from_master (struct breakpoint *orig,
                                  enum bptype type,
-                                 int loc_enabled)
+                                 int loc_enabled,
+                                 int thread)
 {
-  struct breakpoint *copy;
-
-  copy = set_raw_breakpoint_without_location (orig->gdbarch, type);
+  std::unique_ptr<breakpoint> copy
+    (new_momentary_breakpoint (orig->gdbarch, type, orig->pspace,
+                              orig->frame_id, thread));
   copy->loc = copy->allocate_location ();
   set_breakpoint_location_function (copy->loc);
 
@@ -8003,16 +7971,10 @@ momentary_breakpoint_from_master (struct breakpoint *orig,
   copy->loc->line_number = orig->loc->line_number;
   copy->loc->symtab = orig->loc->symtab;
   copy->loc->enabled = loc_enabled;
-  copy->frame_id = orig->frame_id;
-  copy->thread = orig->thread;
-  copy->pspace = orig->pspace;
-
-  copy->enable_state = bp_enabled;
-  copy->disposition = disp_donttouch;
-  copy->number = internal_breakpoint_number--;
 
+  breakpoint *b = add_to_breakpoint_chain (std::move (copy));
   update_global_location_list_nothrow (UGLL_DONT_INSERT);
-  return copy;
+  return b;
 }
 
 /* Make a deep copy of momentary breakpoint ORIG.  Returns NULL if
@@ -8025,7 +7987,8 @@ clone_momentary_breakpoint (struct breakpoint *orig)
   if (orig == NULL)
     return NULL;
 
-  return momentary_breakpoint_from_master (orig, orig->type, 0);
+  return momentary_breakpoint_from_master (orig, orig->type, 0,
+                                          orig->thread);
 }
 
 breakpoint_up
@@ -8109,16 +8072,15 @@ handle_automatic_hardware_breakpoints (bp_location *bl)
     }
 }
 
-static struct bp_location *
-add_location_to_breakpoint (struct breakpoint *b,
-                           const struct symtab_and_line *sal)
+bp_location *
+code_breakpoint::add_location (const symtab_and_line &sal)
 {
-  struct bp_location *loc, **tmp;
+  struct bp_location *new_loc, **tmp;
   CORE_ADDR adjusted_address;
-  struct gdbarch *loc_gdbarch = get_sal_arch (*sal);
+  struct gdbarch *loc_gdbarch = get_sal_arch (sal);
 
   if (loc_gdbarch == NULL)
-    loc_gdbarch = b->gdbarch;
+    loc_gdbarch = gdbarch;
 
   /* Adjust the breakpoint's address prior to allocating a location.
      Once we call allocate_location(), that mostly uninitialized
@@ -8127,31 +8089,31 @@ add_location_to_breakpoint (struct breakpoint *b,
      not want its scan of the location chain to find a breakpoint and
      location that's only been partially initialized.  */
   adjusted_address = adjust_breakpoint_address (loc_gdbarch,
-                                               sal->pc, b->type);
+                                               sal.pc, type);
 
   /* Sort the locations by their ADDRESS.  */
-  loc = b->allocate_location ();
-  for (tmp = &(b->loc); *tmp != NULL && (*tmp)->address <= adjusted_address;
+  new_loc = allocate_location ();
+  for (tmp = &(loc); *tmp != NULL && (*tmp)->address <= adjusted_address;
        tmp = &((*tmp)->next))
     ;
-  loc->next = *tmp;
-  *tmp = loc;
-
-  loc->requested_address = sal->pc;
-  loc->address = adjusted_address;
-  loc->pspace = sal->pspace;
-  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;
-  loc->msymbol = sal->msymbol;
-  loc->objfile = sal->objfile;
-
-  set_breakpoint_location_function (loc);
+  new_loc->next = *tmp;
+  *tmp = new_loc;
+
+  new_loc->requested_address = sal.pc;
+  new_loc->address = adjusted_address;
+  new_loc->pspace = sal.pspace;
+  new_loc->probe.prob = sal.prob;
+  new_loc->probe.objfile = sal.objfile;
+  gdb_assert (new_loc->pspace != NULL);
+  new_loc->section = sal.section;
+  new_loc->gdbarch = loc_gdbarch;
+  new_loc->line_number = sal.line;
+  new_loc->symtab = sal.symtab;
+  new_loc->symbol = sal.symbol;
+  new_loc->msymbol = sal.msymbol;
+  new_loc->objfile = sal.objfile;
+
+  set_breakpoint_location_function (new_loc);
 
   /* While by definition, permanent breakpoints are already present in the
      code, we don't mark the location as inserted.  Normally one would expect
@@ -8166,10 +8128,10 @@ add_location_to_breakpoint (struct breakpoint *b,
      (If GDB later needs to continue execution past the permanent breakpoint,
      it manually increments the PC, thus avoiding executing the breakpoint
      instruction.)  */
-  if (bp_loc_is_permanent (loc))
-    loc->permanent = 1;
+  if (bp_loc_is_permanent (new_loc))
+    new_loc->permanent = 1;
 
-  return loc;
+  return new_loc;
 }
 \f
 
@@ -8269,23 +8231,19 @@ update_dprintf_commands (const char *args, int from_tty,
        update_dprintf_command_list (b);
 }
 
-/* Create a breakpoint with SAL as location.  Use LOCATION
-   as a description of the location, and COND_STRING
-   as condition expression.  If LOCATION is NULL then create an
-   "address location" from the address in the SAL.  */
-
-static void
-init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
-                    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)
+code_breakpoint::code_breakpoint (struct gdbarch *gdbarch_,
+                                 enum bptype type_,
+                                 gdb::array_view<const symtab_and_line> sals,
+                                 location_spec_up &&locspec_,
+                                 gdb::unique_xmalloc_ptr<char> filter_,
+                                 gdb::unique_xmalloc_ptr<char> cond_string_,
+                                 gdb::unique_xmalloc_ptr<char> extra_string_,
+                                 enum bpdisp disposition_,
+                                 int thread_, int task_, int ignore_count_,
+                                 int from_tty,
+                                 int enabled_, unsigned flags,
+                                 int display_canonical_)
+  : breakpoint (gdbarch_, type_)
 {
   int i;
 
@@ -8305,81 +8263,64 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
 
   gdb_assert (!sals.empty ());
 
-  for (const auto &sal : sals)
-    {
-      struct bp_location *loc;
+  thread = thread_;
+  task = task_;
 
-      if (from_tty)
-       {
-         struct gdbarch *loc_gdbarch = get_sal_arch (sal);
-         if (!loc_gdbarch)
-           loc_gdbarch = gdbarch;
+  cond_string = std::move (cond_string_);
+  extra_string = std::move (extra_string_);
+  ignore_count = ignore_count_;
+  enable_state = enabled_ ? bp_enabled : bp_disabled;
+  disposition = disposition_;
 
-         describe_other_breakpoints (loc_gdbarch,
-                                     sal.pspace, sal.pc, sal.section, thread);
-       }
+  if (type == bp_static_tracepoint
+      || type == bp_static_marker_tracepoint)
+    {
+      auto *t = static_cast<struct tracepoint *> (this);
+      struct static_tracepoint_marker marker;
 
-      if (&sal == &sals[0])
+      if (strace_marker_p (this))
        {
-         init_raw_breakpoint (b, sal, type);
-         b->thread = thread;
-         b->task = task;
-
-         b->cond_string = std::move (cond_string);
-         b->extra_string = std::move (extra_string);
-         b->ignore_count = ignore_count;
-         b->enable_state = enabled ? bp_enabled : bp_disabled;
-         b->disposition = disposition;
-
-         if ((flags & CREATE_BREAKPOINT_FLAGS_INSERTED) != 0)
-           b->loc->inserted = 1;
-
-         if (type == bp_static_tracepoint
-             || type == bp_static_marker_tracepoint)
-           {
-             struct tracepoint *t = (struct tracepoint *) b;
-             struct static_tracepoint_marker marker;
-
-             if (strace_marker_p (b))
-               {
-                 /* We already know the marker exists, otherwise, we
-                    wouldn't see a sal for it.  */
-                 const char *p
-                   = &event_location_to_string (b->location.get ())[3];
-                 const char *endp;
-
-                 p = skip_spaces (p);
+         /* We already know the marker exists, otherwise, we wouldn't
+            see a sal for it.  */
+         const char *p = &location_spec_to_string (locspec_.get ())[3];
+         const char *endp;
 
-                 endp = skip_to_space (p);
+         p = skip_spaces (p);
 
-                 t->static_trace_marker_id.assign (p, endp - p);
+         endp = skip_to_space (p);
 
-                 gdb_printf (_("Probed static tracepoint "
-                               "marker \"%s\"\n"),
-                             t->static_trace_marker_id.c_str ());
-               }
-             else if (target_static_tracepoint_marker_at (sal.pc, &marker))
-               {
-                 t->static_trace_marker_id = std::move (marker.str_id);
+         t->static_trace_marker_id.assign (p, endp - p);
 
-                 gdb_printf (_("Probed static tracepoint "
-                               "marker \"%s\"\n"),
-                             t->static_trace_marker_id.c_str ());
-               }
-             else
-               warning (_("Couldn't determine the static "
-                          "tracepoint marker to probe"));
-           }
+         gdb_printf (_("Probed static tracepoint marker \"%s\"\n"),
+                     t->static_trace_marker_id.c_str ());
+       }
+      else if (target_static_tracepoint_marker_at (sals[0].pc, &marker))
+       {
+         t->static_trace_marker_id = std::move (marker.str_id);
 
-         loc = b->loc;
+         gdb_printf (_("Probed static tracepoint marker \"%s\"\n"),
+                     t->static_trace_marker_id.c_str ());
        }
       else
+       warning (_("Couldn't determine the static tracepoint marker to probe"));
+    }
+
+  for (const auto &sal : sals)
+    {
+      if (from_tty)
        {
-         loc = add_location_to_breakpoint (b, &sal);
-         if ((flags & CREATE_BREAKPOINT_FLAGS_INSERTED) != 0)
-           loc->inserted = 1;
+         struct gdbarch *loc_gdbarch = get_sal_arch (sal);
+         if (loc_gdbarch == nullptr)
+           loc_gdbarch = gdbarch;
+
+         describe_other_breakpoints (loc_gdbarch,
+                                     sal.pspace, sal.pc, sal.section, thread);
        }
 
+      bp_location *new_loc = add_location (sal);
+      if ((flags & CREATE_BREAKPOINT_FLAGS_INSERTED) != 0)
+       new_loc->inserted = 1;
+
       /* Do not set breakpoint locations conditions yet.  As locations
         are inserted, they get sorted based on their addresses.  Let
         the list stabilize to have reliable location numbers.  */
@@ -8388,61 +8329,61 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
         command line, otherwise it's an error.  */
       if (type == bp_dprintf)
        {
-         if (b->extra_string)
-           update_dprintf_command_list (b);
+         if (extra_string != nullptr)
+           update_dprintf_command_list (this);
          else
            error (_("Format string required"));
        }
-      else if (b->extra_string)
-       error (_("Garbage '%s' at end of command"), b->extra_string.get ());
+      else if (extra_string != nullptr)
+       error (_("Garbage '%s' at end of command"), extra_string.get ());
     }
 
-
   /* The order of the locations is now stable.  Set the location
      condition using the location's number.  */
   int loc_num = 1;
-  for (bp_location *loc : b->locations ())
+  for (bp_location *bl : locations ())
     {
-      if (b->cond_string != nullptr)
-       set_breakpoint_location_condition (b->cond_string.get (), loc,
-                                          b->number, loc_num);
+      if (cond_string != nullptr)
+       set_breakpoint_location_condition (cond_string.get (), bl,
+                                          number, loc_num);
 
       ++loc_num;
     }
 
-  b->display_canonical = display_canonical;
-  if (location != NULL)
-    b->location = std::move (location);
+  display_canonical = display_canonical_;
+  if (locspec_ != nullptr)
+    locspec = std::move (locspec_);
   else
-    b->location = new_address_location (b->loc->address, NULL, 0);
-  b->filter = std::move (filter);
+    locspec = new_address_location_spec (this->loc->address, NULL, 0);
+  filter = std::move (filter_);
 }
 
 static void
 create_breakpoint_sal (struct gdbarch *gdbarch,
                       gdb::array_view<const symtab_and_line> sals,
-                      event_location_up &&location,
+                      location_spec_up &&locspec,
                       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 from_tty,
                       int enabled, int internal, unsigned flags,
                       int display_canonical)
 {
-  std::unique_ptr<breakpoint> b = new_breakpoint_from_type (gdbarch, type);
-
-  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);
+  std::unique_ptr<code_breakpoint> b
+    = new_breakpoint_from_type (gdbarch,
+                               type,
+                               sals,
+                               std::move (locspec),
+                               std::move (filter),
+                               std::move (cond_string),
+                               std::move (extra_string),
+                               disposition,
+                               thread, task, ignore_count,
+                               from_tty,
+                               enabled, flags,
+                               display_canonical);
 
   install_breakpoint (internal, std::move (b), 0);
 }
@@ -8469,7 +8410,7 @@ create_breakpoints_sal (struct gdbarch *gdbarch,
                        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 from_tty,
                        int enabled, int internal, unsigned flags)
 {
   if (canonical->pre_expanded)
@@ -8479,41 +8420,42 @@ create_breakpoints_sal (struct gdbarch *gdbarch,
     {
       /* Note that 'location' can be NULL in the case of a plain
         'break', without arguments.  */
-      event_location_up location
-       = (canonical->location != NULL
-          ? copy_event_location (canonical->location.get ()) : NULL);
+      location_spec_up locspec
+       = (canonical->locspec != nullptr
+          ? canonical->locspec->clone ()
+          : nullptr);
       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 (locspec),
                             std::move (filter_string),
                             std::move (cond_string),
                             std::move (extra_string),
                             type, disposition,
-                            thread, task, ignore_count, ops,
+                            thread, task, ignore_count,
                             from_tty, enabled, internal, flags,
                             canonical->special_display);
     }
 }
 
-/* Parse LOCATION which is assumed to be a SAL specification possibly
+/* Parse LOCSPEC which is assumed to be a SAL specification possibly
    followed by conditionals.  On return, SALS contains an array of SAL
-   addresses found.  LOCATION points to the end of the SAL (for
-   linespec locations).
+   addresses found.  LOCSPEC points to the end of the SAL (for
+   linespec locspecs).
 
    The array and the line spec strings are allocated on the heap, it is
    the caller's responsibility to free them.  */
 
 static void
-parse_breakpoint_sals (struct event_location *location,
+parse_breakpoint_sals (location_spec *locspec,
                       struct linespec_result *canonical)
 {
   struct symtab_and_line cursal;
 
-  if (event_location_type (location) == LINESPEC_LOCATION)
+  if (location_spec_type (locspec) == LINESPEC_LOCATION_SPEC)
     {
-      const char *spec = get_linespec_location (location)->spec_string;
+      const char *spec = as_linespec_location_spec (locspec)->spec_string;
 
       if (spec == NULL)
        {
@@ -8563,15 +8505,15 @@ parse_breakpoint_sals (struct event_location *location,
     {
       const char *spec = NULL;
 
-      if (event_location_type (location) == LINESPEC_LOCATION)
-       spec = get_linespec_location (location)->spec_string;
+      if (location_spec_type (locspec) == LINESPEC_LOCATION_SPEC)
+       spec = as_linespec_location_spec (locspec)->spec_string;
 
       if (!cursal.symtab
          || (spec != NULL
              && strchr ("+-", spec[0]) != NULL
              && spec[1] != '['))
        {
-         decode_line_full (location, DECODE_LINE_FUNFIRSTLINE, NULL,
+         decode_line_full (locspec, DECODE_LINE_FUNFIRSTLINE, NULL,
                            get_last_displayed_symtab (),
                            get_last_displayed_line (),
                            canonical, NULL, NULL);
@@ -8579,7 +8521,7 @@ parse_breakpoint_sals (struct event_location *location,
        }
     }
 
-  decode_line_full (location, DECODE_LINE_FUNFIRSTLINE, NULL,
+  decode_line_full (locspec, DECODE_LINE_FUNFIRSTLINE, NULL,
                    cursal.symtab, cursal.line, canonical, NULL, NULL);
 }
 
@@ -8799,42 +8741,42 @@ decode_static_tracepoint_spec (const char **arg_p)
    according to IS_TRACEPOINT.  */
 
 static const struct breakpoint_ops *
-breakpoint_ops_for_event_location_type (enum event_location_type location_type,
-                                       bool is_tracepoint)
+breakpoint_ops_for_location_spec_type (enum location_spec_type locspec_type,
+                                      bool is_tracepoint)
 {
   if (is_tracepoint)
     {
-      if (location_type == PROBE_LOCATION)
+      if (locspec_type == PROBE_LOCATION_SPEC)
        return &tracepoint_probe_breakpoint_ops;
       else
-       return &base_breakpoint_ops;
+       return &code_breakpoint_ops;
     }
   else
     {
-      if (location_type == PROBE_LOCATION)
+      if (locspec_type == PROBE_LOCATION_SPEC)
        return &bkpt_probe_breakpoint_ops;
       else
-       return &base_breakpoint_ops;
+       return &code_breakpoint_ops;
     }
 }
 
 /* See breakpoint.h.  */
 
 const struct breakpoint_ops *
-breakpoint_ops_for_event_location (const struct event_location *location,
-                                  bool is_tracepoint)
+breakpoint_ops_for_location_spec (const location_spec *locspec,
+                                 bool is_tracepoint)
 {
-  if (location != nullptr)
-    return breakpoint_ops_for_event_location_type
-      (event_location_type (location), is_tracepoint);
-  return &base_breakpoint_ops;
+  if (locspec != nullptr)
+    return (breakpoint_ops_for_location_spec_type
+           (location_spec_type (locspec), is_tracepoint));
+  return &code_breakpoint_ops;
 }
 
 /* See breakpoint.h.  */
 
 int
 create_breakpoint (struct gdbarch *gdbarch,
-                  struct event_location *location,
+                  location_spec *locspec,
                   const char *cond_string,
                   int thread, const char *extra_string,
                   bool force_condition, int parse_extra,
@@ -8858,7 +8800,7 @@ create_breakpoint (struct gdbarch *gdbarch,
 
   try
     {
-      ops->create_sals_from_location (location, &canonical);
+      ops->create_sals_from_location_spec (locspec, &canonical);
     }
   catch (const gdb_exception_error &e)
     {
@@ -8975,14 +8917,14 @@ create_breakpoint (struct gdbarch *gdbarch,
                                   std::move (extra_string_copy),
                                   type_wanted,
                                   tempflag ? disp_del : disp_donttouch,
-                                  thread, task, ignore_count, ops,
+                                  thread, task, ignore_count,
                                   from_tty, enabled, internal, flags);
     }
   else
     {
       std::unique_ptr <breakpoint> b = new_breakpoint_from_type (gdbarch,
                                                                 type_wanted);
-      b->location = copy_event_location (location);
+      b->locspec = locspec->clone ();
 
       if (parse_extra)
        b->cond_string = NULL;
@@ -9037,12 +8979,13 @@ break_command_1 (const char *arg, int flag, int from_tty)
                             ? bp_hardware_breakpoint
                             : bp_breakpoint);
 
-  event_location_up location = string_to_event_location (&arg, current_language);
-  const struct breakpoint_ops *ops = breakpoint_ops_for_event_location
-    (location.get (), false /* is_tracepoint */);
+  location_spec_up locspec = string_to_location_spec (&arg, current_language);
+  const struct breakpoint_ops *ops
+    = breakpoint_ops_for_location_spec (locspec.get (),
+                                       false /* is_tracepoint */);
 
   create_breakpoint (get_current_arch (),
-                    location.get (),
+                    locspec.get (),
                     NULL, 0, arg, false, 1 /* parse arg */,
                     tempflag, type_wanted,
                     0 /* Ignore count */,
@@ -9141,7 +9084,7 @@ thbreak_command (const char *arg, int from_tty)
 static void
 dprintf_command (const char *arg, int from_tty)
 {
-  event_location_up location = string_to_event_location (&arg, current_language);
+  location_spec_up locspec = string_to_location_spec (&arg, current_language);
 
   /* If non-NULL, ARG should have been advanced past the location;
      the next character must be ','.  */
@@ -9157,12 +9100,12 @@ dprintf_command (const char *arg, int from_tty)
     }
 
   create_breakpoint (get_current_arch (),
-                    location.get (),
+                    locspec.get (),
                     NULL, 0, arg, false, 1 /* parse arg */,
                     0, bp_dprintf,
                     0 /* Ignore count */,
                     pending_break_support,
-                    &base_breakpoint_ops,
+                    &code_breakpoint_ops,
                     from_tty,
                     1 /* enabled */,
                     0 /* internal */,
@@ -9301,8 +9244,8 @@ void
 ranged_breakpoint::print_recreate (struct ui_file *fp) const
 {
   gdb_printf (fp, "break-range %s, %s",
-             event_location_to_string (location.get ()),
-             event_location_to_string (location_range_end.get ()));
+             location_spec_to_string (locspec.get ()),
+             location_spec_to_string (locspec_range_end.get ()));
   print_recreate_thread (fp);
 }
 
@@ -9345,7 +9288,6 @@ break_range_command (const char *arg, int from_tty)
   struct linespec_result canonical_start, canonical_end;
   int bp_count, can_use_bp, length;
   CORE_ADDR end;
-  struct breakpoint *b;
 
   /* We don't support software ranged breakpoints.  */
   if (target_ranged_break_num_registers () < 0)
@@ -9363,9 +9305,9 @@ break_range_command (const char *arg, int from_tty)
     error(_("No address range specified."));
 
   arg_start = arg;
-  event_location_up start_location = string_to_event_location (&arg,
-                                                              current_language);
-  parse_breakpoint_sals (start_location.get (), &canonical_start);
+  location_spec_up start_locspec
+    = string_to_location_spec (&arg, current_language);
+  parse_breakpoint_sals (start_locspec.get (), &canonical_start);
 
   if (arg[0] != ',')
     error (_("Too few arguments."));
@@ -9384,18 +9326,19 @@ break_range_command (const char *arg, int from_tty)
   arg++;       /* Skip the comma.  */
   arg = skip_spaces (arg);
 
-  /* Parse the end location.  */
+  /* Parse the end location specification.  */
 
   arg_start = arg;
 
   /* We call decode_line_full directly here instead of using
-     parse_breakpoint_sals because we need to specify the start location's
-     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.  */
-  event_location_up end_location = string_to_event_location (&arg,
-                                                            current_language);
-  decode_line_full (end_location.get (), DECODE_LINE_FUNFIRSTLINE, NULL,
+     parse_breakpoint_sals because we need to specify the start
+     location spec's 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 spec.  */
+  location_spec_up end_locspec
+    = string_to_location_spec (&arg, current_language);
+  decode_line_full (end_locspec.get (), DECODE_LINE_FUNFIRSTLINE, NULL,
                    sal_start.symtab, sal_start.line,
                    &canonical_end, NULL, NULL);
 
@@ -9426,21 +9369,15 @@ break_range_command (const char *arg, int from_tty)
       return;
     }
 
-  /* Now set up the breakpoint.  */
-  std::unique_ptr<breakpoint> br (new ranged_breakpoint (get_current_arch ()));
-  init_raw_breakpoint (br.get (), sal_start, bp_hardware_breakpoint);
-  b = add_to_breakpoint_chain (std::move (br));
+  /* Now set up the breakpoint and install it.  */
 
-  set_breakpoint_count (breakpoint_count + 1);
-  b->number = breakpoint_count;
-  b->disposition = disp_donttouch;
-  b->location = std::move (start_location);
-  b->location_range_end = std::move (end_location);
-  b->loc->length = length;
+  std::unique_ptr<breakpoint> br
+    (new ranged_breakpoint (get_current_arch (),
+                           sal_start, length,
+                           std::move (start_locspec),
+                           std::move (end_locspec)));
 
-  mention (b);
-  gdb::observers::breakpoint_created.notify (b);
-  update_global_location_list (UGLL_MAY_INSERT);
+  install_breakpoint (false, std::move (br), true);
 }
 
 /*  Return non-zero if EXP is verified as constant.  Returned zero
@@ -10504,14 +10441,14 @@ until_break_command (const char *arg, int from_tty, int anywhere)
   /* Set a breakpoint where the user wants it and at return from
      this function.  */
 
-  event_location_up location = string_to_event_location (&arg, current_language);
+  location_spec_up locspec = string_to_location_spec (&arg, current_language);
 
   std::vector<symtab_and_line> sals
     = (last_displayed_sal_is_valid ()
-       ? decode_line_1 (location.get (), DECODE_LINE_FUNFIRSTLINE, NULL,
+       ? decode_line_1 (locspec.get (), DECODE_LINE_FUNFIRSTLINE, NULL,
                        get_last_displayed_symtab (),
                        get_last_displayed_line ())
-       : decode_line_1 (location.get (), DECODE_LINE_FUNFIRSTLINE,
+       : decode_line_1 (locspec.get (), DECODE_LINE_FUNFIRSTLINE,
                        NULL, NULL, 0));
 
   if (sals.empty ())
@@ -10588,42 +10525,6 @@ until_break_command (const char *arg, int from_tty, int anywhere)
   proceed (-1, GDB_SIGNAL_DEFAULT);
 }
 
-void
-init_ada_exception_breakpoint (struct breakpoint *b,
-                              struct gdbarch *gdbarch,
-                              struct symtab_and_line sal,
-                              const char *addr_string,
-                              int tempflag,
-                              int enabled,
-                              int from_tty)
-{
-  if (from_tty)
-    {
-      struct gdbarch *loc_gdbarch = get_sal_arch (sal);
-      if (!loc_gdbarch)
-       loc_gdbarch = gdbarch;
-
-      describe_other_breakpoints (loc_gdbarch,
-                                 sal.pspace, sal.pc, sal.section, -1);
-      /* FIXME: brobecker/2006-12-28: Actually, re-implement a special
-        version for exception catchpoints, because two catchpoints
-        used for different exception names will use the same address.
-        In this case, a "breakpoint ... also set at..." warning is
-        unproductive.  Besides, the warning phrasing is also a bit
-        inappropriate, we should use the word catchpoint, and tell
-        the user what type of catchpoint it is.  The above is good
-        enough for now, though.  */
-    }
-
-  init_raw_breakpoint (b, sal, bp_catchpoint);
-
-  b->enable_state = enabled ? bp_enabled : bp_disabled;
-  b->disposition = tempflag ? disp_del : disp_donttouch;
-  b->location = string_to_event_location (&addr_string,
-                                         language_def (language_ada));
-  b->language = language_ada;
-}
-
 \f
 
 /* Compare two breakpoints and return a strcmp-like result.  */
@@ -11453,18 +11354,18 @@ say_where (const breakpoint *b)
       if (b->extra_string == NULL)
        {
          gdb_printf (_(" (%s) pending."),
-                     event_location_to_string (b->location.get ()));
+                     location_spec_to_string (b->locspec.get ()));
        }
       else if (b->type == bp_dprintf)
        {
          gdb_printf (_(" (%s,%s) pending."),
-                     event_location_to_string (b->location.get ()),
+                     location_spec_to_string (b->locspec.get ()),
                      b->extra_string.get ());
        }
       else
        {
          gdb_printf (_(" (%s %s) pending."),
-                     event_location_to_string (b->location.get ()),
+                     location_spec_to_string (b->locspec.get ()),
                      b->extra_string.get ());
        }
     }
@@ -11493,7 +11394,7 @@ say_where (const breakpoint *b)
               different file name, and this at least reflects the
               real situation somewhat.  */
            gdb_printf (": %s.",
-                       event_location_to_string (b->location.get ()));
+                       location_spec_to_string (b->locspec.get ()));
        }
 
       if (b->loc->next)
@@ -11570,8 +11471,8 @@ breakpoint::print_recreate (struct ui_file *fp) const
 }
 
 std::vector<symtab_and_line>
-breakpoint::decode_location (struct event_location *location,
-                            struct program_space *search_pspace)
+breakpoint::decode_location_spec (location_spec *locspec,
+                                 program_space *search_pspace)
 {
   internal_error_pure_virtual_called ();
 }
@@ -11579,10 +11480,10 @@ breakpoint::decode_location (struct event_location *location,
 /* Default breakpoint_ops methods.  */
 
 void
-base_breakpoint::re_set ()
+code_breakpoint::re_set ()
 {
   /* FIXME: is this still reachable?  */
-  if (breakpoint_event_location_empty_p (this))
+  if (breakpoint_location_spec_empty_p (this))
     {
       /* Anything without a location can't be re-set.  */
       delete_breakpoint (this);
@@ -11593,7 +11494,7 @@ base_breakpoint::re_set ()
 }
 
 int
-base_breakpoint::insert_location (struct bp_location *bl)
+code_breakpoint::insert_location (struct bp_location *bl)
 {
   CORE_ADDR addr = bl->target_info.reqstd_address;
 
@@ -11617,7 +11518,7 @@ base_breakpoint::insert_location (struct bp_location *bl)
 }
 
 int
-base_breakpoint::remove_location (struct bp_location *bl,
+code_breakpoint::remove_location (struct bp_location *bl,
                                  enum remove_bp_reason reason)
 {
   if (bl->probe.prob != nullptr)
@@ -11633,7 +11534,7 @@ base_breakpoint::remove_location (struct bp_location *bl,
 }
 
 int
-base_breakpoint::breakpoint_hit (const struct bp_location *bl,
+code_breakpoint::breakpoint_hit (const struct bp_location *bl,
                                 const address_space *aspace,
                                 CORE_ADDR bp_addr,
                                 const target_waitstatus &ws)
@@ -11758,7 +11659,7 @@ ordinary_breakpoint::print_recreate (struct ui_file *fp) const
     internal_error (__FILE__, __LINE__,
                    _("unhandled breakpoint type %d"), (int) type);
 
-  gdb_printf (fp, " %s", event_location_to_string (location.get ()));
+  gdb_printf (fp, " %s", location_spec_to_string (locspec.get ()));
 
   /* Print out extra_string if this breakpoint is pending.  It might
      contain, for example, conditions that were set by the user.  */
@@ -11769,13 +11670,13 @@ ordinary_breakpoint::print_recreate (struct ui_file *fp) const
 }
 
 std::vector<symtab_and_line>
-base_breakpoint::decode_location (struct event_location *location,
-                                 struct program_space *search_pspace)
+code_breakpoint::decode_location_spec (location_spec *locspec,
+                                      program_space *search_pspace)
 {
-  if (event_location_type (location) == PROBE_LOCATION)
-    return bkpt_probe_decode_location (this, location, search_pspace);
+  if (location_spec_type (locspec) == PROBE_LOCATION_SPEC)
+    return bkpt_probe_decode_location_spec (this, locspec, search_pspace);
 
-  return decode_location_default (this, location, search_pspace);
+  return decode_location_spec_default (this, locspec, search_pspace);
 }
 
 /* Virtual table for internal breakpoints.  */
@@ -11914,37 +11815,30 @@ longjmp_breakpoint::~longjmp_breakpoint ()
 }
 
 static void
-bkpt_probe_create_sals_from_location (struct event_location *location,
-                                     struct linespec_result *canonical)
+bkpt_probe_create_sals_from_location_spec (location_spec *locspec,
+                                          struct linespec_result *canonical)
 
 {
   struct linespec_sals lsal;
 
-  lsal.sals = parse_probes (location, NULL, canonical);
+  lsal.sals = parse_probes (locspec, NULL, canonical);
   lsal.canonical
-    = xstrdup (event_location_to_string (canonical->location.get ()));
+    = xstrdup (location_spec_to_string (canonical->locspec.get ()));
   canonical->lsals.push_back (std::move (lsal));
 }
 
 static std::vector<symtab_and_line>
-bkpt_probe_decode_location (struct breakpoint *b,
-                           struct event_location *location,
-                           struct program_space *search_pspace)
+bkpt_probe_decode_location_spec (struct breakpoint *b,
+                                location_spec *locspec,
+                                program_space *search_pspace)
 {
-  std::vector<symtab_and_line> sals = parse_probes (location, search_pspace, NULL);
+  std::vector<symtab_and_line> sals
+    = parse_probes (locspec, search_pspace, NULL);
   if (sals.empty ())
     error (_("probe not found"));
   return sals;
 }
 
-/* The breakpoint_ops structure to be used in tracepoints.  */
-
-void
-tracepoint::re_set ()
-{
-  breakpoint_re_set_default (this);
-}
-
 int
 tracepoint::breakpoint_hit (const struct bp_location *bl,
                            const address_space *aspace, CORE_ADDR bp_addr,
@@ -12012,32 +11906,22 @@ tracepoint::print_recreate (struct ui_file *fp) const
     internal_error (__FILE__, __LINE__,
                    _("unhandled tracepoint type %d"), (int) type);
 
-  gdb_printf (fp, " %s", event_location_to_string (location.get ()));
+  gdb_printf (fp, " %s", location_spec_to_string (locspec.get ()));
   print_recreate_thread (fp);
 
   if (pass_count)
     gdb_printf (fp, "  passcount %d\n", pass_count);
 }
 
-std::vector<symtab_and_line>
-tracepoint::decode_location (struct event_location *location,
-                            struct program_space *search_pspace)
-{
-  if (event_location_type (location) == PROBE_LOCATION)
-    return bkpt_probe_decode_location (this, location, search_pspace);
-
-  return decode_location_default (this, location, search_pspace);
-}
-
 /* Virtual table for tracepoints on static probes.  */
 
 static void
-tracepoint_probe_create_sals_from_location
-  (struct event_location *location,
+tracepoint_probe_create_sals_from_location_spec
+  (location_spec *locspec,
    struct linespec_result *canonical)
 {
   /* We use the same method for breakpoint on probes.  */
-  bkpt_probe_create_sals_from_location (location, canonical);
+  bkpt_probe_create_sals_from_location_spec (locspec, canonical);
 }
 
 void
@@ -12068,7 +11952,7 @@ void
 dprintf_breakpoint::print_recreate (struct ui_file *fp) const
 {
   gdb_printf (fp, "dprintf %s,%s",
-             event_location_to_string (location.get ()),
+             location_spec_to_string (locspec.get ()),
              extra_string.get ());
   print_recreate_thread (fp);
 }
@@ -12103,22 +11987,22 @@ dprintf_breakpoint::after_condition_true (struct bpstat *bs)
    markers (`-m').  */
 
 static void
-strace_marker_create_sals_from_location (struct event_location *location,
-                                        struct linespec_result *canonical)
+strace_marker_create_sals_from_location_spec (location_spec *locspec,
+                                             struct linespec_result *canonical)
 {
   struct linespec_sals lsal;
   const char *arg_start, *arg;
 
-  arg = arg_start = get_linespec_location (location)->spec_string;
+  arg = arg_start = as_linespec_location_spec (locspec)->spec_string;
   lsal.sals = decode_static_tracepoint_spec (&arg);
 
   std::string str (arg_start, arg - arg_start);
   const char *ptr = str.c_str ();
-  canonical->location
-    = new_linespec_location (&ptr, symbol_name_match_type::FULL);
+  canonical->locspec
+    = new_linespec_location_spec (&ptr, symbol_name_match_type::FULL);
 
   lsal.canonical
-    = xstrdup (event_location_to_string (canonical->location.get ()));
+    = xstrdup (location_spec_to_string (canonical->locspec.get ()));
   canonical->lsals.push_back (std::move (lsal));
 }
 
@@ -12131,7 +12015,6 @@ strace_marker_create_breakpoints_sal (struct gdbarch *gdbarch,
                                      enum bpdisp disposition,
                                      int thread,
                                      int task, int ignore_count,
-                                     const struct breakpoint_ops *ops,
                                      int from_tty, int enabled,
                                      int internal, unsigned flags)
 {
@@ -12146,19 +12029,21 @@ strace_marker_create_breakpoints_sal (struct gdbarch *gdbarch,
 
   for (size_t i = 0; i < lsal.sals.size (); i++)
     {
-      event_location_up location
-       = copy_event_location (canonical->location.get ());
-
-      std::unique_ptr<tracepoint> tp (new tracepoint (gdbarch,
-                                                     type_wanted));
-      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,
-                          canonical->special_display);
+      location_spec_up locspec = canonical->locspec->clone ();
+
+      std::unique_ptr<tracepoint> tp
+       (new tracepoint (gdbarch,
+                        type_wanted,
+                        lsal.sals[i],
+                        std::move (locspec),
+                        NULL,
+                        std::move (cond_string),
+                        std::move (extra_string),
+                        disposition,
+                        thread, task, ignore_count,
+                        from_tty, enabled, flags,
+                        canonical->special_display));
+
       /* Given that its possible to have multiple markers with
         the same string id, if the user is creating a static
         tracepoint by marker id ("strace -m MARKER_ID"), then
@@ -12172,10 +12057,10 @@ strace_marker_create_breakpoints_sal (struct gdbarch *gdbarch,
 }
 
 std::vector<symtab_and_line>
-static_marker_tracepoint::decode_location (struct event_location *location,
-                                          struct program_space *search_pspace)
+static_marker_tracepoint::decode_location_spec (location_spec *locspec,
+                                               program_space *search_pspace)
 {
-  const char *s = get_linespec_location (location)->spec_string;
+  const char *s = as_linespec_location_spec (locspec)->spec_string;
 
   std::vector<symtab_and_line> sals = decode_static_tracepoint_spec (&s);
   if (sals.size () > static_trace_marker_id_idx)
@@ -12191,7 +12076,7 @@ static_marker_tracepoint::decode_location (struct event_location *location,
 /* Static tracepoints with marker (`-m').  */
 static struct breakpoint_ops strace_marker_breakpoint_ops =
 {
-  strace_marker_create_sals_from_location,
+  strace_marker_create_sals_from_location_spec,
   strace_marker_create_breakpoints_sal,
 };
 
@@ -12483,7 +12368,6 @@ update_static_tracepoint (struct breakpoint *b, struct symtab_and_line sal)
          struct symbol *sym;
          struct static_tracepoint_marker *tpmarker;
          struct ui_out *uiout = current_uiout;
-         struct explicit_location explicit_loc;
 
          tpmarker = &markers[0];
 
@@ -12520,13 +12404,14 @@ update_static_tracepoint (struct breakpoint *b, struct symtab_and_line sal)
          b->loc->line_number = sal2.line;
          b->loc->symtab = sym != NULL ? sal2.symtab : NULL;
 
-         b->location.reset (NULL);
-         initialize_explicit_location (&explicit_loc);
-         explicit_loc.source_filename
-           = ASTRDUP (symtab_to_filename_for_display (sal2.symtab));
-         explicit_loc.line_offset.offset = b->loc->line_number;
-         explicit_loc.line_offset.sign = LINE_OFFSET_NONE;
-         b->location = new_explicit_location (&explicit_loc);
+         std::unique_ptr<explicit_location_spec> els
+           (new explicit_location_spec ());
+         els->source_filename
+           = xstrdup (symtab_to_filename_for_display (sal2.symtab));
+         els->line_offset.offset = b->loc->line_number;
+         els->line_offset.sign = LINE_OFFSET_NONE;
+
+         b->locspec = std::move (els);
 
          /* Might be nice to check if function changed, and warn if
             so.  */
@@ -12610,7 +12495,7 @@ hoist_existing_locations (struct breakpoint *b, struct program_space *pspace)
    untouched.  */
 
 void
-update_breakpoint_locations (struct breakpoint *b,
+update_breakpoint_locations (code_breakpoint *b,
                             struct program_space *filter_pspace,
                             gdb::array_view<const symtab_and_line> sals,
                             gdb::array_view<const symtab_and_line> sals_end)
@@ -12646,7 +12531,7 @@ update_breakpoint_locations (struct breakpoint *b,
 
       switch_to_program_space_and_thread (sal.pspace);
 
-      new_loc = add_location_to_breakpoint (b, &sal);
+      new_loc = b->add_location (sal);
 
       /* Reparse conditions, they might contain references to the
         old symtab.  */
@@ -12729,12 +12614,12 @@ update_breakpoint_locations (struct breakpoint *b,
     gdb::observers::breakpoint_modified.notify (b);
 }
 
-/* Find the SaL locations corresponding to the given LOCATION.
+/* Find the SaL locations corresponding to the given LOCSPEC.
    On return, FOUND will be 1 if any SaL was found, zero otherwise.  */
 
 static std::vector<symtab_and_line>
-location_to_sals (struct breakpoint *b, struct event_location *location,
-                 struct program_space *search_pspace, int *found)
+location_spec_to_sals (struct breakpoint *b, location_spec *locspec,
+                      struct program_space *search_pspace, int *found)
 {
   struct gdb_exception exception;
 
@@ -12742,7 +12627,7 @@ location_to_sals (struct breakpoint *b, struct event_location *location,
 
   try
     {
-      sals = b->decode_location (location, search_pspace);
+      sals = b->decode_location_spec (locspec, search_pspace);
     }
   catch (gdb_exception_error &e)
     {
@@ -12818,22 +12703,22 @@ location_to_sals (struct breakpoint *b, struct event_location *location,
    locations.  */
 
 static void
-breakpoint_re_set_default (struct breakpoint *b)
+breakpoint_re_set_default (code_breakpoint *b)
 {
   struct program_space *filter_pspace = current_program_space;
   std::vector<symtab_and_line> expanded, expanded_end;
 
   int found;
-  std::vector<symtab_and_line> sals = location_to_sals (b, b->location.get (),
-                                                       filter_pspace, &found);
+  std::vector<symtab_and_line> sals
+    = location_spec_to_sals (b, b->locspec.get (), filter_pspace, &found);
   if (found)
     expanded = std::move (sals);
 
-  if (b->location_range_end != NULL)
+  if (b->locspec_range_end != nullptr)
     {
       std::vector<symtab_and_line> sals_end
-       = location_to_sals (b, b->location_range_end.get (),
-                           filter_pspace, &found);
+       = location_spec_to_sals (b, b->locspec_range_end.get (),
+                                filter_pspace, &found);
       if (found)
        expanded_end = std::move (sals_end);
     }
@@ -12845,23 +12730,23 @@ breakpoint_re_set_default (struct breakpoint *b)
    calls parse_breakpoint_sals.  Return 1 for success, zero for failure.  */
 
 static void
-create_sals_from_location_default (struct event_location *location,
-                                  struct linespec_result *canonical)
+create_sals_from_location_spec_default (location_spec *locspec,
+                                       struct linespec_result *canonical)
 {
-  parse_breakpoint_sals (location, canonical);
+  parse_breakpoint_sals (locspec, canonical);
 }
 
 /* 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 std::vector<symtab_and_line>
-decode_location_default (struct breakpoint *b,
-                        struct event_location *location,
-                        struct program_space *search_pspace)
+decode_location_spec_default (struct breakpoint *b,
+                             location_spec *locspec,
+                             program_space *search_pspace)
 {
   struct linespec_result canonical;
 
-  decode_line_full (location, DECODE_LINE_FUNFIRSTLINE, search_pspace,
+  decode_line_full (locspec, DECODE_LINE_FUNFIRSTLINE, search_pspace,
                    NULL, 0, &canonical, multiple_symbols_all,
                    b->filter.get ());
 
@@ -13529,15 +13414,24 @@ insert_single_step_breakpoint (struct gdbarch *gdbarch,
 
   if (tp->control.single_step_breakpoints == NULL)
     {
+      std::unique_ptr<breakpoint> b
+       (new momentary_breakpoint (gdbarch, bp_single_step,
+                                  current_program_space,
+                                  null_frame_id,
+                                  tp->global_num));
+
       tp->control.single_step_breakpoints
-       = new_single_step_breakpoint (tp->global_num, gdbarch);
+       = add_to_breakpoint_chain (std::move (b));
     }
 
   sal = find_pc_line (pc, 0);
   sal.pc = pc;
   sal.section = find_pc_overlay (pc);
   sal.explicit_pc = 1;
-  add_location_to_breakpoint (tp->control.single_step_breakpoints, &sal);
+
+  auto *ss_bp
+    = static_cast<momentary_breakpoint *> (tp->control.single_step_breakpoints);
+  ss_bp->add_location (sal);
 
   update_global_location_list (UGLL_INSERT);
 }
@@ -13610,13 +13504,13 @@ set_tracepoint_count (int num)
 static void
 trace_command (const char *arg, int from_tty)
 {
-  event_location_up location = string_to_event_location (&arg,
-                                                        current_language);
-  const struct breakpoint_ops *ops = breakpoint_ops_for_event_location
-    (location.get (), true /* is_tracepoint */);
+  location_spec_up locspec = string_to_location_spec (&arg,
+                                                     current_language);
+  const struct breakpoint_ops *ops = breakpoint_ops_for_location_spec
+    (locspec.get (), true /* is_tracepoint */);
 
   create_breakpoint (get_current_arch (),
-                    location.get (),
+                    locspec.get (),
                     NULL, 0, arg, false, 1 /* parse arg */,
                     0 /* tempflag */,
                     bp_tracepoint /* type_wanted */,
@@ -13631,16 +13525,16 @@ trace_command (const char *arg, int from_tty)
 static void
 ftrace_command (const char *arg, int from_tty)
 {
-  event_location_up location = string_to_event_location (&arg,
-                                                        current_language);
+  location_spec_up locspec = string_to_location_spec (&arg,
+                                                     current_language);
   create_breakpoint (get_current_arch (),
-                    location.get (),
+                    locspec.get (),
                     NULL, 0, arg, false, 1 /* parse arg */,
                     0 /* tempflag */,
                     bp_fast_tracepoint /* type_wanted */,
                     0 /* Ignore count */,
                     pending_break_support,
-                    &base_breakpoint_ops,
+                    &code_breakpoint_ops,
                     from_tty,
                     1 /* enabled */,
                     0 /* internal */, 0);
@@ -13652,7 +13546,7 @@ static void
 strace_command (const char *arg, int from_tty)
 {
   const struct breakpoint_ops *ops;
-  event_location_up location;
+  location_spec_up locspec;
   enum bptype type;
 
   /* Decide if we are dealing with a static tracepoint marker (`-m'),
@@ -13660,18 +13554,19 @@ strace_command (const char *arg, int from_tty)
   if (arg && startswith (arg, "-m") && isspace (arg[2]))
     {
       ops = &strace_marker_breakpoint_ops;
-      location = new_linespec_location (&arg, symbol_name_match_type::FULL);
+      locspec = new_linespec_location_spec (&arg,
+                                           symbol_name_match_type::FULL);
       type = bp_static_marker_tracepoint;
     }
   else
     {
-      ops = &base_breakpoint_ops;
-      location = string_to_event_location (&arg, current_language);
+      ops = &code_breakpoint_ops;
+      locspec = string_to_location_spec (&arg, current_language);
       type = bp_static_tracepoint;
     }
 
   create_breakpoint (get_current_arch (),
-                    location.get (),
+                    locspec.get (),
                     NULL, 0, arg, false, 1 /* parse arg */,
                     0 /* tempflag */,
                     type /* type_wanted */,
@@ -13737,10 +13632,10 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
               "has no source form, ignoring it"),
             utp->number);
 
-  event_location_up location = string_to_event_location (&addr_str,
-                                                        current_language);
+  location_spec_up locspec = string_to_location_spec (&addr_str,
+                                                     current_language);
   if (!create_breakpoint (get_current_arch (),
-                         location.get (),
+                         locspec.get (),
                          utp->cond_string.get (), -1, addr_str,
                          false /* force_condition */,
                          0 /* parse cond/thread */,
@@ -13748,7 +13643,7 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
                          utp->type /* type_wanted */,
                          0 /* Ignore count */,
                          pending_break_support,
-                         &base_breakpoint_ops,
+                         &code_breakpoint_ops,
                          0 /* from_tty */,
                          utp->enabled /* enabled */,
                          0 /* internal */,
@@ -14154,7 +14049,7 @@ save_tracepoints_command (const char *args, int from_tty)
 /* This help string is used to consolidate all the help string for specifying
    locations used by several commands.  */
 
-#define LOCATION_HELP_STRING \
+#define LOCATION_SPEC_HELP_STRING \
 "Linespecs are colon-separated lists of location parameters, such as\n\
 source filename, function name, label name, and line number.\n\
 Example: To specify the start of a label named \"the_top\" in the\n\
@@ -14201,7 +14096,7 @@ CONDITION is a boolean expression.\n\
 \n\
 With the \"-force-condition\" flag, the condition is defined even when\n\
 it is invalid for all current locations.\n\
-\n" LOCATION_HELP_STRING "\n\n\
+\n" LOCATION_SPEC_HELP_STRING "\n\n\
 Multiple breakpoints at one place are permitted, and useful if their\n\
 conditions are different.\n\
 \n\
@@ -14470,7 +14365,7 @@ Argument may be a linespec, explicit, or address location as described below.\n\
 \n\
 With no argument, clears all breakpoints in the line that the selected frame\n\
 is executing in.\n"
-"\n" LOCATION_HELP_STRING "\n\n\
+"\n" LOCATION_SPEC_HELP_STRING "\n\n\
 See also the \"delete\" command which clears breakpoints by number."));
   add_com_alias ("cl", clear_cmd, class_breakpoint, 1);
 
@@ -14631,7 +14526,7 @@ tracing library.  You can inspect it when analyzing the trace buffer,\n\
 by printing the $_sdata variable like any other convenience variable.\n\
 \n\
 CONDITION is a boolean expression.\n\
-\n" LOCATION_HELP_STRING "\n\n\
+\n" LOCATION_SPEC_HELP_STRING "\n\n\
 Multiple tracepoints at one place are permitted, and useful if their\n\
 conditions are different.\n\
 \n\
@@ -14788,7 +14683,7 @@ range (including START-LOCATION and END-LOCATION)."));
 Set a dynamic printf at specified location.\n\
 dprintf location,format string,arg1,arg2,...\n\
 location may be a linespec, explicit, or address location.\n"
-"\n" LOCATION_HELP_STRING));
+"\n" LOCATION_SPEC_HELP_STRING));
   set_cmd_completer (c, location_completer);
 
   add_setshow_enum_cmd ("dprintf-style", class_support,