Eliminate the two-level data structures behind location_specs
authorPedro Alves <pedro@palves.net>
Fri, 27 May 2022 12:13:41 +0000 (13:13 +0100)
committerPedro Alves <pedro@palves.net>
Fri, 17 Jun 2022 08:55:39 +0000 (09:55 +0100)
Currently, there's the location_spec hierarchy, and then some
location_spec subclasses have their own struct type holding all their
data fields.

I.e., there is this:

 location_spec
   explicit_location_spec
   linespec_location_spec
   address_location_spec
   probe_location_spec

and then these separate types:

  explicit_location
  linespec_location

where:

  explicit_location_spec
     has-a explicit_location
  linespec_location_spec
     has-a linespec_location

This patch eliminates explicit_location and linespec_location,
inlining their members in the corresponding location_spec type.

The location_spec subclasses were the ones currently defined in
location.c, so they are moved to the header.  Since the definitions of
the classes are now visible, we no longer need location_spec_deleter.

Some constructors that are used for cloning location_specs, like:

  explicit explicit_location_spec (const struct explicit_location *loc)

... were converted to proper copy ctors.

In the process, initialize_explicit_location is eliminated, and some
functions that returned the "data type behind a locspec", like
get_linespec_location are converted to downcast functions, like
as_linespec_location_spec.

Change-Id: Ia31ccef9382b25a52b00fa878c8df9b8cf2a6c5a

gdb/break-catch-throw.c
gdb/breakpoint.c
gdb/completer.c
gdb/linespec.c
gdb/location.c
gdb/location.h
gdb/mi/mi-cmd-break.c
gdb/probe.c
gdb/python/py-breakpoint.c

index 3ef4b972d4f9f90e642dd21b3d08460d218c342f..2eb24f3b76c7653b8a662fd70d8069a32971c1d4 100644 (file)
@@ -225,12 +225,9 @@ exception_catchpoint::re_set ()
         catchpoint mode.  */
       try
        {
-         struct explicit_location explicit_loc;
-
-         initialize_explicit_location (&explicit_loc);
-         explicit_loc.function_name
-           = ASTRDUP (exception_functions[kind].function);
-         location_spec_up locspec = new_explicit_location_spec (&explicit_loc);
+         location_spec_up locspec
+           = (new_explicit_location_spec_function
+              (exception_functions[kind].function));
          sals = this->decode_location_spec (locspec.get (), filter_pspace);
        }
       catch (const gdb_exception_error &ex)
index ab88a38e0a39bb6b962e02c059c0e4f3a97aeec0..82937a3b78a576024834fe75c2eb3e58ad2ad366 100644 (file)
@@ -3364,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);
 
@@ -3388,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->locspec = new_explicit_location_spec (&explicit_loc);
+      b->locspec = new_explicit_location_spec_function (func_name);
 
       if (overlay_debugging == ovly_auto)
        {
@@ -3473,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;
@@ -3495,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->locspec = new_explicit_location_spec (&explicit_loc);
+      b->locspec = new_explicit_location_spec_function (func_name);
       b->enable_state = bp_disabled;
       installed_bp++;
     }
@@ -3553,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);
 
@@ -3578,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->locspec = new_explicit_location_spec (&explicit_loc);
+         b->locspec = new_explicit_location_spec_function (func_name);
          b->enable_state = bp_disabled;
        }
     }
@@ -3648,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);
 
@@ -3675,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->locspec = new_explicit_location_spec (&explicit_loc);
+  b->locspec = new_explicit_location_spec_function (func_name);
   b->enable_state = bp_disabled;
 
   return true;
@@ -8467,7 +8455,7 @@ parse_breakpoint_sals (location_spec *locspec,
 
   if (location_spec_type (locspec) == LINESPEC_LOCATION_SPEC)
     {
-      const char *spec = get_linespec_location (locspec)->spec_string;
+      const char *spec = as_linespec_location_spec (locspec)->spec_string;
 
       if (spec == NULL)
        {
@@ -8518,7 +8506,7 @@ parse_breakpoint_sals (location_spec *locspec,
       const char *spec = NULL;
 
       if (location_spec_type (locspec) == LINESPEC_LOCATION_SPEC)
-       spec = get_linespec_location (locspec)->spec_string;
+       spec = as_linespec_location_spec (locspec)->spec_string;
 
       if (!cursal.symtab
          || (spec != NULL
@@ -12005,7 +11993,7 @@ strace_marker_create_sals_from_location_spec (location_spec *locspec,
   struct linespec_sals lsal;
   const char *arg_start, *arg;
 
-  arg = arg_start = get_linespec_location (locspec)->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);
@@ -12073,7 +12061,7 @@ std::vector<symtab_and_line>
 static_marker_tracepoint::decode_location_spec (location_spec *locspec,
                                                program_space *search_pspace)
 {
-  const char *s = get_linespec_location (locspec)->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)
@@ -12381,7 +12369,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];
 
@@ -12418,13 +12405,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->locspec.reset (nullptr);
-         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->locspec = new_explicit_location_spec (&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.  */
index 2ec8d2eb594a8fab4eed0c40e4d0eb0de0947d66..b68b6de20575b9685e063ecbce965a097812e1e6 100644 (file)
@@ -712,8 +712,8 @@ collect_explicit_location_matches (completion_tracker &tracker,
                                   const char *word,
                                   const struct language_defn *language)
 {
-  const struct explicit_location *explicit_loc
-    = get_explicit_location (locspec);
+  const explicit_location_spec *explicit_loc
+    = as_explicit_location_spec (locspec);
 
   /* True if the option expects an argument.  */
   bool needs_arg = true;
@@ -1008,7 +1008,7 @@ location_completer (struct cmd_list_element *ignore,
          text = copy;
 
          symbol_name_match_type match_type
-           = get_explicit_location (locspec.get ())->func_name_match_type;
+           = as_explicit_location_spec (locspec.get ())->func_name_match_type;
          complete_address_and_linespec_locations (tracker, text, match_type);
        }
     }
index b12f5c8773312065daed905b2bcc30445f747d49..063944bb9a139d194061a1505c32614f9f4a946c 100644 (file)
@@ -94,8 +94,8 @@ struct address_entry
 
 struct linespec
 {
-  /* An explicit location describing the SaLs.  */
-  struct explicit_location explicit_loc {};
+  /* An explicit location spec describing the SaLs.  */
+  explicit_location_spec explicit_loc;
 
   /* The list of symtabs to search to which to limit the search.
 
@@ -342,8 +342,8 @@ struct linespec_parser
   struct completion_tracker *completion_tracker = nullptr;
 };
 
-/* A convenience macro for accessing the explicit location result of
-   the parser.  */
+/* A convenience macro for accessing the explicit location spec result
+   of the parser.  */
 #define PARSER_EXPLICIT(PPTR) (&PARSER_RESULT ((PPTR))->explicit_loc)
 
 /* Prototypes for local functions.  */
@@ -1990,18 +1990,14 @@ linespec_parse_basic (linespec_parser *parser)
 static void
 canonicalize_linespec (struct linespec_state *state, const linespec *ls)
 {
-  location_spec *canon;
-  struct explicit_location *explicit_loc;
-
   /* If canonicalization was not requested, no need to do anything.  */
   if (!state->canonical)
     return;
 
   /* Save everything as an explicit location.  */
-  state->canonical->locspec
-    = new_explicit_location_spec (&ls->explicit_loc);
-  canon = state->canonical->locspec.get ();
-  explicit_loc = get_explicit_location (canon);
+  state->canonical->locspec = ls->explicit_loc.clone ();
+  explicit_location_spec *explicit_loc
+    = as_explicit_location_spec (state->canonical->locspec.get ());
 
   if (explicit_loc->label_name != NULL)
     {
@@ -2019,8 +2015,7 @@ canonicalize_linespec (struct linespec_state *state, const linespec *ls)
   /* If this location originally came from a linespec, save a string
      representation of it for display and saving to file.  */
   if (state->is_linespec)
-    set_location_spec_string (canon,
-                             explicit_location_to_linespec (explicit_loc));
+    set_location_spec_string (explicit_loc, explicit_loc->to_linespec ());
 }
 
 /* Given a line offset in LS, construct the relevant SALs.  */
@@ -2307,17 +2302,18 @@ convert_linespec_to_sals (struct linespec_state *state, linespec *ls)
   return sals;
 }
 
-/* Build RESULT from the explicit location components SOURCE_FILENAME,
-   FUNCTION_NAME, LABEL_NAME and LINE_OFFSET.  */
+/* Build RESULT from the explicit location spec components
+   SOURCE_FILENAME, FUNCTION_NAME, LABEL_NAME and LINE_OFFSET.  */
 
 static void
-convert_explicit_location_to_linespec (struct linespec_state *self,
-                                      linespec *result,
-                                      const char *source_filename,
-                                      const char *function_name,
-                                      symbol_name_match_type fname_match_type,
-                                      const char *label_name,
-                                      struct line_offset line_offset)
+convert_explicit_location_spec_to_linespec
+  (struct linespec_state *self,
+   linespec *result,
+   const char *source_filename,
+   const char *function_name,
+   symbol_name_match_type fname_match_type,
+   const char *label_name,
+   struct line_offset line_offset)
 {
   std::vector<bound_minimal_symbol> minimal_symbols;
 
@@ -2382,16 +2378,17 @@ convert_explicit_location_to_linespec (struct linespec_state *self,
 /* Convert the explicit location EXPLICIT_LOC into SaLs.  */
 
 static std::vector<symtab_and_line>
-convert_explicit_location_to_sals (struct linespec_state *self,
-                                  linespec *result,
-                                  const struct explicit_location *explicit_loc)
+convert_explicit_location_spec_to_sals
+  (struct linespec_state *self,
+   linespec *result,
+   const explicit_location_spec *explicit_spec)
 {
-  convert_explicit_location_to_linespec (self, result,
-                                        explicit_loc->source_filename,
-                                        explicit_loc->function_name,
-                                        explicit_loc->func_name_match_type,
-                                        explicit_loc->label_name,
-                                        explicit_loc->line_offset);
+  convert_explicit_location_spec_to_linespec (self, result,
+                                             explicit_spec->source_filename,
+                                             explicit_spec->function_name,
+                                             explicit_spec->func_name_match_type,
+                                             explicit_spec->label_name,
+                                             explicit_spec->line_offset);
   return convert_linespec_to_sals (self, result);
 }
 
@@ -2694,10 +2691,6 @@ linespec_state_destructor (struct linespec_state *self)
 
 linespec_parser::~linespec_parser ()
 {
-  xfree (PARSER_EXPLICIT (this)->source_filename);
-  xfree (PARSER_EXPLICIT (this)->label_name);
-  xfree (PARSER_EXPLICIT (this)->function_name);
-
   linespec_state_destructor (PARSER_STATE (this));
 }
 
@@ -2855,12 +2848,12 @@ linespec_complete_label (completion_tracker &tracker,
 
   try
     {
-      convert_explicit_location_to_linespec (PARSER_STATE (&parser),
-                                            PARSER_RESULT (&parser),
-                                            source_filename,
-                                            function_name,
-                                            func_name_match_type,
-                                            NULL, unknown_offset);
+      convert_explicit_location_spec_to_linespec (PARSER_STATE (&parser),
+                                                 PARSER_RESULT (&parser),
+                                                 source_filename,
+                                                 function_name,
+                                                 func_name_match_type,
+                                                 NULL, unknown_offset);
     }
   catch (const gdb_exception_error &ex)
     {
@@ -3073,24 +3066,18 @@ location_spec_to_sals (linespec_parser *parser,
     {
     case LINESPEC_LOCATION_SPEC:
       {
+       const linespec_location_spec *ls = as_linespec_location_spec (locspec);
        PARSER_STATE (parser)->is_linespec = 1;
-       try
-         {
-           const linespec_location *ls = get_linespec_location (locspec);
-           result = parse_linespec (parser,
-                                    ls->spec_string, ls->match_type);
-         }
-       catch (const gdb_exception_error &except)
-         {
-           throw;
-         }
+       result = parse_linespec (parser, ls->spec_string, ls->match_type);
       }
       break;
 
     case ADDRESS_LOCATION_SPEC:
       {
-       const char *addr_string = get_address_string_location (locspec);
-       CORE_ADDR addr = get_address_location (locspec);
+       const address_location_spec *addr_spec
+         = as_address_location_spec (locspec);
+       const char *addr_string = addr_spec->to_string ();
+       CORE_ADDR addr;
 
        if (addr_string != NULL)
          {
@@ -3099,6 +3086,8 @@ location_spec_to_sals (linespec_parser *parser,
              PARSER_STATE (parser)->canonical->locspec
                = copy_location_spec (locspec);
          }
+       else
+         addr = addr_spec->address;
 
        result = convert_address_location_to_sals (PARSER_STATE (parser),
                                                   addr);
@@ -3107,12 +3096,11 @@ location_spec_to_sals (linespec_parser *parser,
 
     case EXPLICIT_LOCATION_SPEC:
       {
-       const struct explicit_location *explicit_loc;
-
-       explicit_loc = get_explicit_location_const (locspec);
-       result = convert_explicit_location_to_sals (PARSER_STATE (parser),
-                                                   PARSER_RESULT (parser),
-                                                   explicit_loc);
+       const explicit_location_spec *explicit_locspec
+         = as_explicit_location_spec (locspec);
+       result = convert_explicit_location_spec_to_sals (PARSER_STATE (parser),
+                                                        PARSER_RESULT (parser),
+                                                        explicit_locspec);
       }
       break;
 
index 14a5aebff178d0a831e4e04e2a09c1a9159ea795..4d0b60ff9c7075a7b0d42e893bfa9a5549c769c1 100644 (file)
 #include <ctype.h>
 #include <string.h>
 
-static std::string explicit_location_to_string
-     (const struct explicit_location *explicit_loc);
+static std::string
+  explicit_to_string_internal (bool as_linespec,
+                              const explicit_location_spec *explicit_loc);
+
+/* Return a xstrdup of STR if not NULL, otherwise return NULL.  */
 
-/* The base class for all location specs used to match actual
-   locations in the inferior.  */
+static char *
+maybe_xstrdup (const char *str)
+{
+  return (str != nullptr ? xstrdup (str) : nullptr);
+}
+
+probe_location_spec::probe_location_spec (std::string &&probe)
+  : location_spec (PROBE_LOCATION_SPEC, std::move (probe))
+{
+}
 
-struct location_spec
+location_spec_up
+probe_location_spec::clone () const
 {
-  virtual ~location_spec () = default;
-
-  /* Clone this object.  */
-  virtual location_spec_up clone () const = 0;
-
-  /* Return true if this location spec is empty, false otherwise.  */
-  virtual bool empty_p () const = 0;
-
-  /* Return a string representation of this location.  */
-  const char *to_string () const
-  {
-    if (as_string.empty ())
-      as_string = compute_string ();
-    if (as_string.empty ())
-      return nullptr;
-    return as_string.c_str ();
-  }
-
-  DISABLE_COPY_AND_ASSIGN (location_spec);
-
-  /* The type of this location specification.  */
-  enum location_spec_type type;
-
-  /* Cached string representation of this location spec.  This is
-     used, e.g., to save location specs to file.  */
-  mutable std::string as_string;
-
-protected:
-
-  explicit location_spec (enum location_spec_type t)
-    : type (t)
-  {
-  }
-
-  location_spec (enum location_spec_type t, std::string &&str)
-    : type (t),
-      as_string (std::move (str))
-  {
-  }
-
-  explicit location_spec (const location_spec *to_clone)
-    : type (to_clone->type),
-      as_string (to_clone->as_string)
-  {
-  }
-
-  /* Compute the string representation of this object.  This is called
-     by to_string when needed.  */
-  virtual std::string compute_string () const = 0;
-};
-
-/* A probe.  */
-struct probe_location_spec : public location_spec
+  return location_spec_up (new probe_location_spec (*this));
+}
+
+bool
+probe_location_spec::empty_p () const
 {
-  explicit probe_location_spec (std::string &&probe)
-    : location_spec (PROBE_LOCATION_SPEC, std::move (probe))
-  {
-  }
-
-  location_spec_up clone () const override
-  {
-    return location_spec_up (new probe_location_spec (this));
-  }
-
-  bool empty_p () const override
-  {
-    return false;
-  }
-
-protected:
-
-  explicit probe_location_spec (const probe_location_spec *to_clone)
-    : location_spec (to_clone)
-  {
-  }
-
-  std::string compute_string () const override
-  {
-    return std::move (as_string);
-  }
-};
+  return false;
+}
+
+std::string probe_location_spec::compute_string () const
+{
+  return std::move (as_string);
+}
 
 /* A "normal" linespec.  */
-struct linespec_location_spec : public location_spec
+linespec_location_spec::linespec_location_spec
+  (const char **linespec, symbol_name_match_type match_type_)
+  : location_spec (LINESPEC_LOCATION_SPEC),
+    match_type (match_type_)
 {
-  linespec_location_spec (const char **linespec,
-                         symbol_name_match_type match_type)
-    : location_spec (LINESPEC_LOCATION_SPEC)
-  {
-    linespec_location.match_type = match_type;
-    if (*linespec != NULL)
-      {
-       const char *p;
-       const char *orig = *linespec;
-
-       linespec_lex_to_end (linespec);
-       p = remove_trailing_whitespace (orig, *linespec);
-
-       /* If there is no valid linespec then this will leave the
-          spec_string as nullptr.  This behaviour is relied on in the
-          breakpoint setting code, where spec_string being nullptr means
-          to use the default breakpoint location.  */
-       if ((p - orig) > 0)
-         linespec_location.spec_string = savestring (orig, p - orig);
-      }
-  }
-
-  ~linespec_location_spec ()
-  {
-    xfree (linespec_location.spec_string);
-  }
-
-  location_spec_up clone () const override
-  {
-    return location_spec_up (new linespec_location_spec (this));
-  }
-
-  bool empty_p () const override
-  {
-    return false;
-  }
-
-  struct linespec_location linespec_location {};
-
-protected:
-
-  explicit linespec_location_spec (const linespec_location_spec *to_clone)
-    : location_spec (to_clone),
-      linespec_location (to_clone->linespec_location)
-  {
-    if (linespec_location.spec_string != nullptr)
-      linespec_location.spec_string = xstrdup (linespec_location.spec_string);
-  }
-
-  std::string compute_string () const override
-  {
-    if (linespec_location.spec_string != nullptr)
-      {
-       const struct linespec_location *ls = &linespec_location;
-       if (ls->match_type == symbol_name_match_type::FULL)
-         return std::string ("-qualified ") + ls->spec_string;
-       else
-         return ls->spec_string;
-      }
-    return {};
-  }
-};
-
-/* An address in the inferior.  */
-struct address_location_spec : public location_spec
+  if (*linespec != NULL)
+    {
+      const char *p;
+      const char *orig = *linespec;
+
+      linespec_lex_to_end (linespec);
+      p = remove_trailing_whitespace (orig, *linespec);
+
+      /* If there is no valid linespec then this will leave the
+        spec_string as nullptr.  This behaviour is relied on in the
+        breakpoint setting code, where spec_string being nullptr means
+        to use the default breakpoint location.  */
+      if ((p - orig) > 0)
+       spec_string = savestring (orig, p - orig);
+    }
+}
+
+linespec_location_spec::~linespec_location_spec ()
 {
-  address_location_spec (CORE_ADDR addr, const char *addr_string,
-                        int addr_string_len)
-    : location_spec (ADDRESS_LOCATION_SPEC),
-      address (addr)
-  {
-    if (addr_string != nullptr)
-      as_string = std::string (addr_string, addr_string_len);
-  }
-
-  location_spec_up clone () const override
-  {
-    return location_spec_up (new address_location_spec (this));
-  }
-
-  bool empty_p () const override
-  {
-    return false;
-  }
-
-  CORE_ADDR address;
-
-protected:
-
-  address_location_spec (const address_location_spec *to_clone)
-    : location_spec (to_clone),
-      address (to_clone->address)
-  {
-  }
-
-  std::string compute_string () const override
-  {
-    const char *addr_string = core_addr_to_string (address);
-    return std::string ("*") + addr_string;
-  }
-};
-
-/* An explicit location spec.  */
-struct explicit_location_spec : public location_spec
+  xfree (spec_string);
+}
+
+location_spec_up
+linespec_location_spec::clone () const
 {
-  explicit explicit_location_spec (const struct explicit_location *loc)
-    : location_spec (EXPLICIT_LOCATION_SPEC)
-  {
-    copy_loc (loc);
-  }
-
-  ~explicit_location_spec ()
-  {
-    xfree (explicit_loc.source_filename);
-    xfree (explicit_loc.function_name);
-    xfree (explicit_loc.label_name);
-  }
-
-  location_spec_up clone () const override
-  {
-    return location_spec_up (new explicit_location_spec (this));
-  }
-
-  bool empty_p () const override
-  {
-    return (explicit_loc.source_filename == nullptr
-           && explicit_loc.function_name == nullptr
-           && explicit_loc.label_name == nullptr
-           && explicit_loc.line_offset.sign == LINE_OFFSET_UNKNOWN);
-  }
-
-  struct explicit_location explicit_loc;
-
-protected:
-
-  explicit explicit_location_spec (const explicit_location_spec *to_clone)
-    : location_spec (to_clone)
-  {
-    copy_loc (&to_clone->explicit_loc);
-  }
-
-  std::string compute_string () const override
-  {
-    return explicit_location_to_string (&explicit_loc);
-  }
-
-private:
-
-  void copy_loc (const struct explicit_location *loc)
-  {
-    initialize_explicit_location (&explicit_loc);
-    if (loc != nullptr)
-      {
-       explicit_loc.func_name_match_type = loc->func_name_match_type;
-       if (loc->source_filename != nullptr)
-         explicit_loc.source_filename = xstrdup (loc->source_filename);
-       if (loc->function_name != nullptr)
-         explicit_loc.function_name = xstrdup (loc->function_name);
-       if (loc->label_name != nullptr)
-         explicit_loc.label_name = xstrdup (loc->label_name);
-       explicit_loc.line_offset = loc->line_offset;
-      }
-  }
-};
+  return location_spec_up (new linespec_location_spec (*this));
+}
 
-/* See description in location.h.  */
+bool
+linespec_location_spec::empty_p () const
+{
+  return false;
+}
 
-enum location_spec_type
-location_spec_type (const location_spec *locspec)
+linespec_location_spec::linespec_location_spec
+  (const linespec_location_spec &other)
+  : location_spec (other),
+    match_type (other.match_type),
+    spec_string (maybe_xstrdup (other.spec_string))
 {
-  return locspec->type;
+}
+
+std::string
+linespec_location_spec::compute_string () const
+{
+  if (spec_string != nullptr)
+    {
+      if (match_type == symbol_name_match_type::FULL)
+       return std::string ("-qualified ") + spec_string;
+      else
+       return spec_string;
+    }
+  return {};
+}
+
+address_location_spec::address_location_spec (CORE_ADDR addr,
+                                             const char *addr_string,
+                                             int addr_string_len)
+  : location_spec (ADDRESS_LOCATION_SPEC),
+    address (addr)
+{
+  if (addr_string != nullptr)
+    as_string = std::string (addr_string, addr_string_len);
+}
+
+location_spec_up
+address_location_spec::clone () const
+{
+  return location_spec_up (new address_location_spec (*this));
+}
+
+bool
+address_location_spec::empty_p () const
+{
+  return false;
+}
+
+address_location_spec::address_location_spec
+  (const address_location_spec &other)
+  : location_spec (other),
+    address (other.address)
+{
+}
+
+std::string
+address_location_spec::compute_string () const
+{
+  const char *addr_string = core_addr_to_string (address);
+  return std::string ("*") + addr_string;
+}
+
+explicit_location_spec::explicit_location_spec ()
+  : location_spec (EXPLICIT_LOCATION_SPEC)
+{
+}
+
+explicit_location_spec::~explicit_location_spec ()
+{
+  xfree (source_filename);
+  xfree (function_name);
+  xfree (label_name);
+}
+
+explicit_location_spec::explicit_location_spec
+  (const explicit_location_spec &other)
+  : location_spec (other),
+    source_filename (maybe_xstrdup (other.source_filename)),
+    function_name (maybe_xstrdup (other.function_name)),
+    func_name_match_type (other.func_name_match_type),
+    label_name (maybe_xstrdup (other.label_name)),
+    line_offset (other.line_offset)
+{
+}
+
+location_spec_up
+explicit_location_spec::clone () const
+{
+  return location_spec_up (new explicit_location_spec (*this));
+}
+
+bool
+explicit_location_spec::empty_p () const
+{
+  return (source_filename == nullptr
+         && function_name == nullptr
+         && label_name == nullptr
+         && line_offset.sign == LINE_OFFSET_UNKNOWN);
+}
+
+std::string
+explicit_location_spec::compute_string () const
+{
+  return explicit_to_string_internal (false, this);
 }
 
 /* See description in location.h.  */
 
-void
-initialize_explicit_location (struct explicit_location *explicit_loc)
+enum location_spec_type
+location_spec_type (const location_spec *locspec)
 {
-  memset (explicit_loc, 0, sizeof (struct explicit_location));
-  explicit_loc->line_offset.sign = LINE_OFFSET_UNKNOWN;
-  explicit_loc->func_name_match_type = symbol_name_match_type::WILD;
+  return locspec->type;
 }
 
 /* See description in location.h.  */
@@ -317,11 +224,11 @@ new_linespec_location_spec (const char **linespec,
 
 /* See description in location.h.  */
 
-const linespec_location *
-get_linespec_location (const location_spec *locspec)
+const linespec_location_spec *
+as_linespec_location_spec (const location_spec *locspec)
 {
   gdb_assert (locspec->type == LINESPEC_LOCATION_SPEC);
-  return &((linespec_location_spec *) locspec)->linespec_location;
+  return static_cast<const linespec_location_spec *> (locspec);
 }
 
 /* See description in location.h.  */
@@ -336,20 +243,11 @@ new_address_location_spec (CORE_ADDR addr, const char *addr_string,
 
 /* See description in location.h.  */
 
-CORE_ADDR
-get_address_location (const location_spec *locspec)
+const address_location_spec *
+as_address_location_spec (const location_spec *locspec)
 {
   gdb_assert (locspec->type == ADDRESS_LOCATION_SPEC);
-  return ((address_location_spec *) locspec)->address;
-}
-
-/* See description in location.h.  */
-
-const char *
-get_address_string_location (const location_spec *locspec)
-{
-  gdb_assert (locspec->type == ADDRESS_LOCATION_SPEC);
-  return locspec->to_string ();
+  return static_cast<const address_location_spec *> (locspec);
 }
 
 /* See description in location.h.  */
@@ -362,37 +260,29 @@ new_probe_location_spec (std::string &&probe)
 
 /* See description in location.h.  */
 
-const char *
-get_probe_location_spec_string (const location_spec *locspec)
+const probe_location_spec *
+as_probe_location_spec (const location_spec *locspec)
 {
   gdb_assert (locspec->type == PROBE_LOCATION_SPEC);
-  return locspec->to_string ();
-}
-
-/* See description in location.h.  */
-
-location_spec_up
-new_explicit_location_spec (const explicit_location *explicit_loc)
-{
-  return location_spec_up (new explicit_location_spec (explicit_loc));
+  return static_cast<const probe_location_spec *> (locspec);
 }
 
 /* See description in location.h.  */
 
-struct explicit_location *
-get_explicit_location (location_spec *locspec)
+const explicit_location_spec *
+as_explicit_location_spec (const location_spec *locspec)
 {
   gdb_assert (locspec->type == EXPLICIT_LOCATION_SPEC);
-  return &((explicit_location_spec *) locspec)->explicit_loc;
+  return static_cast<const explicit_location_spec *> (locspec);
 }
 
 /* See description in location.h.  */
 
-const struct explicit_location *
-get_explicit_location_const (const location_spec *locspec)
+explicit_location_spec *
+as_explicit_location_spec (location_spec *locspec)
 {
   gdb_assert (locspec->type == EXPLICIT_LOCATION_SPEC);
-  return &((explicit_location_spec *) locspec)->explicit_loc;
+  return static_cast<explicit_location_spec *> (locspec);
 }
 
 /* Return a string representation of the explicit location spec in
@@ -403,7 +293,7 @@ get_explicit_location_const (const location_spec *locspec)
 
 static std::string
 explicit_to_string_internal (bool as_linespec,
-                            const struct explicit_location *explicit_loc)
+                            const explicit_location_spec *explicit_loc)
 {
   bool need_space = false;
   char space = as_linespec ? ':' : ' ';
@@ -457,18 +347,10 @@ explicit_to_string_internal (bool as_linespec,
 
 /* See description in location.h.  */
 
-static std::string
-explicit_location_to_string (const struct explicit_location *explicit_loc)
-{
-  return explicit_to_string_internal (false, explicit_loc);
-}
-
-/* See description in location.h.  */
-
 std::string
-explicit_location_to_linespec (const struct explicit_location *explicit_loc)
+explicit_location_spec::to_linespec () const
 {
-  return explicit_to_string_internal (true, explicit_loc);
+  return explicit_to_string_internal (true, this);
 }
 
 /* See description in location.h.  */
@@ -479,12 +361,6 @@ copy_location_spec (const location_spec *src)
   return src->clone ();
 }
 
-void
-location_spec_deleter::operator() (location_spec *locspec) const
-{
-  delete locspec;
-}
-
 /* See description in location.h.  */
 
 const char *
@@ -788,7 +664,7 @@ string_to_explicit_location_spec (const char **argp,
     return NULL;
 
   std::unique_ptr<explicit_location_spec> locspec
-    (new explicit_location_spec ((const explicit_location *) nullptr));
+    (new explicit_location_spec ());
 
   /* Process option/argument pairs.  dprintf_command
      requires that processing stop on ','.  */
@@ -857,18 +733,17 @@ string_to_explicit_location_spec (const char **argp,
        {
          set_oarg (explicit_location_spec_lex_one (argp, language,
                                                    completion_info));
-         locspec->explicit_loc.source_filename = oarg.release ();
+         locspec->source_filename = oarg.release ();
        }
       else if (strncmp (opt.get (), "-function", len) == 0)
        {
          set_oarg (explicit_location_spec_lex_one_function (argp, language,
                                                             completion_info));
-         locspec->explicit_loc.function_name = oarg.release ();
+         locspec->function_name = oarg.release ();
        }
       else if (strncmp (opt.get (), "-qualified", len) == 0)
        {
-         locspec->explicit_loc.func_name_match_type
-           = symbol_name_match_type::FULL;
+         locspec->func_name_match_type = symbol_name_match_type::FULL;
        }
       else if (strncmp (opt.get (), "-line", len) == 0)
        {
@@ -876,8 +751,7 @@ string_to_explicit_location_spec (const char **argp,
          *argp = skip_spaces (*argp);
          if (have_oarg)
            {
-             locspec->explicit_loc.line_offset
-               = linespec_parse_line_offset (oarg.get ());
+             locspec->line_offset = linespec_parse_line_offset (oarg.get ());
              continue;
            }
        }
@@ -885,7 +759,7 @@ string_to_explicit_location_spec (const char **argp,
        {
          set_oarg (explicit_location_spec_lex_one (argp, language,
                                                    completion_info));
-         locspec->explicit_loc.label_name = oarg.release ();
+         locspec->label_name = oarg.release ();
        }
       /* Only emit an "invalid argument" error for options
         that look like option strings.  */
@@ -915,10 +789,10 @@ string_to_explicit_location_spec (const char **argp,
 
   /* One special error check:  If a source filename was given
      without offset, function, or label, issue an error.  */
-  if (locspec->explicit_loc.source_filename != NULL
-      && locspec->explicit_loc.function_name == NULL
-      && locspec->explicit_loc.label_name == NULL
-      && (locspec->explicit_loc.line_offset.sign == LINE_OFFSET_UNKNOWN)
+  if (locspec->source_filename != NULL
+      && locspec->function_name == NULL
+      && locspec->label_name == NULL
+      && (locspec->line_offset.sign == LINE_OFFSET_UNKNOWN)
       && completion_info == NULL)
     {
       error (_("Source filename requires function, label, or "
@@ -1000,7 +874,7 @@ string_to_location_spec (const char **stringp,
       explicit_location_spec *xloc
        = dynamic_cast<explicit_location_spec *> (locspec.get ());
       gdb_assert (xloc != nullptr);
-      match_type = xloc->explicit_loc.func_name_match_type;
+      match_type = xloc->func_name_match_type;
     }
 
   /* Everything else is a "basic" linespec, address, or probe location
index 602998de2987a24978eee1ef1900a1334e1929fe..0a2f1799bc4d9f8304f3d6b4b3f7f52c85aeb2fb 100644 (file)
@@ -46,8 +46,8 @@ enum offset_relative_sign
 struct line_offset
 {
   /* Line offset and any specified sign.  */
-  int offset;
-  enum offset_relative_sign sign;
+  int offset = 0;
+  enum offset_relative_sign sign = LINE_OFFSET_UNKNOWN;
 };
 
 /* An enumeration of the various ways to specify a location spec.  */
@@ -67,15 +67,104 @@ enum location_spec_type
   PROBE_LOCATION_SPEC
 };
 
-/* A traditional linespec.  */
+/* A unique pointer for location_spec.  */
+typedef std::unique_ptr<location_spec> location_spec_up;
+
+/* The base class for all location specs used to resolve actual
+   locations in the inferior.  */
 
-struct linespec_location
+struct location_spec
 {
+  virtual ~location_spec () = default;
+
+  /* Clone this object.  */
+  virtual location_spec_up clone () const = 0;
+
+  /* Return true if this location spec is empty, false otherwise.  */
+  virtual bool empty_p () const = 0;
+
+  /* Return a string representation of this location.  */
+  const char *to_string () const
+  {
+    if (as_string.empty ())
+      as_string = compute_string ();
+    if (as_string.empty ())
+      return nullptr;
+    return as_string.c_str ();
+  }
+
+  /* The type of this location specification.  */
+  enum location_spec_type type;
+
+  /* Cached string representation of this location spec.  This is
+     used, e.g., to save location specs to file.  */
+  mutable std::string as_string;
+
+protected:
+
+  explicit location_spec (enum location_spec_type t)
+    : type (t)
+  {
+  }
+
+  location_spec (enum location_spec_type t, std::string &&str)
+    : type (t),
+      as_string (std::move (str))
+  {
+  }
+
+  location_spec (const location_spec &other)
+    : type (other.type),
+      as_string (other.as_string)
+  {
+  }
+
+  /* Compute the string representation of this object.  This is called
+     by to_string when needed.  */
+  virtual std::string compute_string () const = 0;
+};
+
+/* A "normal" linespec.  */
+
+struct linespec_location_spec : public location_spec
+{
+  linespec_location_spec (const char **linespec,
+                         symbol_name_match_type match_type);
+
+  ~linespec_location_spec ();
+
+  location_spec_up clone () const override;
+
+  bool empty_p () const override;
+
   /* Whether the function name is fully-qualified or not.  */
   symbol_name_match_type match_type;
 
   /* The linespec.  */
-  char *spec_string;
+  char *spec_string = nullptr;
+
+protected:
+  linespec_location_spec (const linespec_location_spec &other);
+
+  std::string compute_string () const override;
+};
+
+/* An address in the inferior.  */
+struct address_location_spec : public location_spec
+{
+  address_location_spec (CORE_ADDR addr, const char *addr_string,
+                        int addr_string_len);
+
+  location_spec_up clone () const override;
+
+  bool empty_p () const override;
+
+  CORE_ADDR address;
+
+protected:
+  address_location_spec (const address_location_spec &other);
+
+  std::string compute_string () const override;
 };
 
 /* An explicit location spec.  This structure is used to bypass the
@@ -83,24 +172,58 @@ struct linespec_location
    as linespecs, though.  For example, source_filename requires
    at least one other field.  */
 
-struct explicit_location
+struct explicit_location_spec : public location_spec
 {
+  explicit_location_spec ();
+
+  ~explicit_location_spec ();
+
+  location_spec_up clone () const override;
+
+  bool empty_p () const override;
+
+  /* Return a linespec string representation of this explicit location
+     spec.  The explicit location spec must already be
+     canonicalized/valid.  */
+  std::string to_linespec () const;
+
   /* The source filename. Malloc'd.  */
-  char *source_filename;
+  char *source_filename = nullptr;
 
   /* The function name.  Malloc'd.  */
-  char *function_name;
+  char *function_name = nullptr;
 
   /* Whether the function name is fully-qualified or not.  */
-  symbol_name_match_type func_name_match_type;
+  symbol_name_match_type func_name_match_type
+    = symbol_name_match_type::WILD;
 
   /* The name of a label.  Malloc'd.  */
-  char *label_name;
+  char *label_name = nullptr;
 
   /* A line offset relative to the start of the symbol
      identified by the above fields or the current symtab
      if the other fields are NULL.  */
-  struct line_offset line_offset;
+  struct line_offset line_offset = {0, LINE_OFFSET_UNKNOWN};
+
+protected:
+  explicit_location_spec (const explicit_location_spec &other);
+
+  std::string compute_string () const override;
+};
+
+/* A probe.  */
+struct probe_location_spec : public location_spec
+{
+  explicit probe_location_spec (std::string &&probe);
+
+  location_spec_up clone () const override;
+
+  bool empty_p () const override;
+
+protected:
+  probe_location_spec (const probe_location_spec &other) = default;
+
+  std::string compute_string () const override;
 };
 
 /* Return the type of the given location spec.  */
@@ -108,13 +231,6 @@ struct explicit_location
 extern enum location_spec_type
   location_spec_type (const location_spec *);
 
-/* Return a linespec string representation of the given explicit
-   location spec.  The location spec must already be
-   canonicalized/valid.  */
-
-extern std::string explicit_location_to_linespec
-  (const explicit_location *explicit_locspec);
-
 /* Return a string representation of LOCSPEC.
    This function may return NULL for unspecified linespecs,
    e.g, LINESPEC_LOCATION_SPEC and spec_string is NULL.
@@ -124,27 +240,16 @@ extern std::string explicit_location_to_linespec
 extern const char *
   location_spec_to_string (location_spec *locspec);
 
-/* A deleter for a struct location_spec.  */
-
-struct location_spec_deleter
-{
-  void operator() (location_spec *locspec) const;
-};
-
-/* A unique pointer for location_spec.  */
-typedef std::unique_ptr<location_spec, location_spec_deleter>
-     location_spec_up;
-
 /* Create a new linespec location spec.  */
 
 extern location_spec_up new_linespec_location_spec
   (const char **linespec, symbol_name_match_type match_type);
 
-/* Return the linespec location spec of the given location_spec (which
-   must be of type LINESPEC_LOCATION_SPEC).  */
+/* Return the given location_spec as a linespec_location_spec.
+   LOCSPEC must be of type LINESPEC_LOCATION_SPEC.  */
 
-extern const linespec_location *
-  get_linespec_location (const location_spec *locspec);
+extern const linespec_location_spec *
+  as_linespec_location_spec (const location_spec *locspec);
 
 /* Create a new address location spec.
    ADDR is the address corresponding to this location_spec.
@@ -155,50 +260,42 @@ extern location_spec_up new_address_location_spec (CORE_ADDR addr,
                                                   const char *addr_string,
                                                   int addr_string_len);
 
-/* Return the address (a CORE_ADDR) of the given location_spec, which
-   must be of type ADDRESS_LOCATION_SPEC.  */
-
-extern CORE_ADDR
-  get_address_location (const location_spec *locspec);
+/* Return the given location_spec as an address_location_spec.
+   LOCSPEC must be of type ADDRESS_LOCATION_SPEC.  */
 
-/* Return the expression (a string) that was used to compute the
-   address of the given location_spec, which must be of type
-   ADDRESS_LOCATION_SPEC.  */
-
-extern const char *
-  get_address_string_location (const location_spec *locspec);
+const address_location_spec *
+  as_address_location_spec (const location_spec *locspec);
 
 /* Create a new probe location.  */
 
 extern location_spec_up new_probe_location_spec (std::string &&probe);
 
-/* Return the probe location spec string of the given location_spec,
-   which must be of type PROBE_LOCATION_SPEC.  */
-
-extern const char *
-  get_probe_location_spec_string (const location_spec *locspec);
-
-/* Initialize the given explicit location.  */
+/* Assuming LOCSPEC is of type PROBE_LOCATION_SPEC, return LOCSPEC
+   cast to probe_location_spec.  */
 
-extern void
-  initialize_explicit_location (explicit_location *locspec);
+const probe_location_spec *
+  as_probe_location_spec (const location_spec *locspec);
 
-/* Create a new explicit location.  If not NULL, EXPLICIT is checked for
-   validity.  If invalid, an exception is thrown.  */
+/* Create a new explicit location with explicit FUNCTION_NAME.  All
+   other fields are defaulted.  */
 
-extern location_spec_up
-  new_explicit_location_spec (const explicit_location *locspec);
-
-/* Return the explicit location spec of the given location_spec, which
-   must be of type EXPLICIT_LOCATION.  */
-
-extern struct explicit_location *
-  get_explicit_location (location_spec *locspec);
-
-/* A const version of the above.  */
-
-extern const explicit_location *
-  get_explicit_location_const (const location_spec *locspec);
+static inline location_spec_up
+new_explicit_location_spec_function (const char *function_name)
+{
+  explicit_location_spec *spec
+    = new explicit_location_spec ();
+  spec->function_name
+    = (function_name != nullptr ? xstrdup (function_name) : nullptr);
+  return location_spec_up (spec);
+}
+
+/* Assuming LOCSPEC is of type EXPLICIT_LOCATION_SPEC, return LOCSPEC
+   cast to explicit_location_spec.  */
+
+const explicit_location_spec *
+  as_explicit_location_spec (const location_spec *locspec);
+explicit_location_spec *
+  as_explicit_location_spec (location_spec *locspec);
 
 /* Return a copy of the given SRC location spec.  */
 
index dab0a471abce60ee0e5d9600d83916f0d31576f0..408f582ebc5e1a074ff55fbba09819e4a0b54453 100644 (file)
@@ -182,7 +182,8 @@ mi_cmd_break_insert_1 (int dprintf, const char *command, char **argv, int argc)
   location_spec_up locspec;
   const struct breakpoint_ops *ops;
   int is_explicit = 0;
-  struct explicit_location explicit_loc;
+  std::unique_ptr<explicit_location_spec> explicit_loc
+    (new explicit_location_spec ());
   std::string extra_string;
   bool force_condition = false;
 
@@ -220,8 +221,6 @@ mi_cmd_break_insert_1 (int dprintf, const char *command, char **argv, int argc)
   int oind = 0;
   char *oarg;
 
-  initialize_explicit_location (&explicit_loc);
-
   while (1)
     {
       int opt = mi_getopt ("-break-insert", argc, argv,
@@ -259,19 +258,19 @@ mi_cmd_break_insert_1 (int dprintf, const char *command, char **argv, int argc)
          break;
        case EXPLICIT_SOURCE_OPT:
          is_explicit = 1;
-         explicit_loc.source_filename = oarg;
+         explicit_loc->source_filename = xstrdup (oarg);
          break;
        case EXPLICIT_FUNC_OPT:
          is_explicit = 1;
-         explicit_loc.function_name = oarg;
+         explicit_loc->function_name = xstrdup (oarg);
          break;
        case EXPLICIT_LABEL_OPT:
          is_explicit = 1;
-         explicit_loc.label_name = oarg;
+         explicit_loc->label_name = xstrdup (oarg);
          break;
        case EXPLICIT_LINE_OPT:
          is_explicit = 1;
-         explicit_loc.line_offset = linespec_parse_line_offset (oarg);
+         explicit_loc->line_offset = linespec_parse_line_offset (oarg);
          break;
        case FORCE_CONDITION_OPT:
          force_condition = true;
@@ -339,16 +338,16 @@ mi_cmd_break_insert_1 (int dprintf, const char *command, char **argv, int argc)
     {
       /* Error check -- we must have one of the other
         parameters specified.  */
-      if (explicit_loc.source_filename != NULL
-         && explicit_loc.function_name == NULL
-         && explicit_loc.label_name == NULL
-         && explicit_loc.line_offset.sign == LINE_OFFSET_UNKNOWN)
+      if (explicit_loc->source_filename != NULL
+         && explicit_loc->function_name == NULL
+         && explicit_loc->label_name == NULL
+         && explicit_loc->line_offset.sign == LINE_OFFSET_UNKNOWN)
        error (_("-%s-insert: --source option requires --function, --label,"
                 " or --line"), dprintf ? "dprintf" : "break");
 
-      explicit_loc.func_name_match_type = match_type;
+      explicit_loc->func_name_match_type = match_type;
 
-      locspec = new_explicit_location_spec (&explicit_loc);
+      locspec = std::move (explicit_loc);
     }
   else
     {
index 0b056eb88db8ebbcfb9cfe8ae311b738b0d463dd..5371b7eca460646a39a526889e44e8458562e50c 100644 (file)
@@ -123,7 +123,7 @@ parse_probes (const location_spec *locspec,
   const char *arg_start, *cs;
 
   gdb_assert (location_spec_type (locspec) == PROBE_LOCATION_SPEC);
-  arg_start = get_probe_location_spec_string (locspec);
+  arg_start = locspec->to_string ();
 
   cs = arg_start;
   const static_probe_ops *spops = probe_linespec_to_static_ops (&cs);
index 029ced741368b7a30b465c9ff252bda8b19ebb2a..bab1c60a43ecf644fb9e1ebb18afa7d2d513752c 100644 (file)
@@ -839,20 +839,23 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs)
              }
            else
              {
-               struct explicit_location explicit_loc;
+               std::unique_ptr<explicit_location_spec> explicit_loc
+                 (new explicit_location_spec ());
 
-               initialize_explicit_location (&explicit_loc);
-               explicit_loc.source_filename = source;
-               explicit_loc.function_name = function;
-               explicit_loc.label_name = label;
+               explicit_loc->source_filename
+                 = source != nullptr ? xstrdup (source) : nullptr;
+               explicit_loc->function_name
+                 = function != nullptr ? xstrdup (function) : nullptr;
+               explicit_loc->label_name
+                 = label != nullptr ? xstrdup (label) : nullptr;
 
                if (line != NULL)
-                 explicit_loc.line_offset =
-                   linespec_parse_line_offset (line.get ());
+                 explicit_loc->line_offset
+                   linespec_parse_line_offset (line.get ());
 
-               explicit_loc.func_name_match_type = func_name_match_type;
+               explicit_loc->func_name_match_type = func_name_match_type;
 
-               locspec = new_explicit_location_spec (&explicit_loc);
+               locspec.reset (explicit_loc.release ());
              }
 
            const struct breakpoint_ops *ops