public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* (no subject)
@ 2020-04-19 14:18 Tom Tromey
  2020-04-19 14:18 ` [PATCH 1/4] Remove ALL_EXTENSION_LANGUAGES and ALL_ENABLED_EXTENSION_LANGUAGES Tom Tromey
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Tom Tromey @ 2020-04-19 14:18 UTC (permalink / raw)
  To: gdb-patches

Eventually I'd like to remove all of the ALL_ iteration macros, and
also move gdb to use "external iterators" wherever possible.  I think
both the macros and the callback-style interal internal iterators are
harder to read.

This series removes a few of the ALL_ macros.

Regression tested by the buildbot.

Tom



^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/4] Remove ALL_EXTENSION_LANGUAGES and ALL_ENABLED_EXTENSION_LANGUAGES
  2020-04-19 14:18 Tom Tromey
@ 2020-04-19 14:18 ` Tom Tromey
  2020-04-19 14:18 ` [PATCH 2/4] Remove ALL_SO_LIBS and so_list_head Tom Tromey
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Tom Tromey @ 2020-04-19 14:18 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This removes the ALL_EXTENSION_LANGUAGES and
ALL_ENABLED_EXTENSION_LANGUAGES macros, in favor of ordinary
iterators.  For ALL_ENABLED_EXTENSION_LANGUAGES, I chose to simply
inline the check, as that seemed simpler than trying to make
filtered_iterator work for std::array.  (As an aside, this sort of
thing will be easier once we can use the ranges library...)

gdb/ChangeLog
2020-04-18  Tom Tromey  <tom@tromey.com>

	* extension.c (extension_languages): Now a std::array.
	(ALL_EXTENSION_LANGUAGES): Remove.
	(get_ext_lang_defn, get_ext_lang_of_file)
	(eval_ext_lang_from_control_command): Update.
	(finish_ext_lang_initialization)
	(auto_load_ext_lang_scripts_for_objfile)
	(ext_lang_type_printers::ext_lang_type_printers)
	(apply_ext_lang_type_printers)
	(ext_lang_type_printers::~ext_lang_type_printers)
	(apply_ext_lang_val_pretty_printer, apply_ext_lang_frame_filter)
	(preserve_ext_lang_values, get_breakpoint_cond_ext_lang)
	(breakpoint_ext_lang_cond_says_stop, check_quit_flag)
	(get_matching_xmethod_workers, ext_lang_colorize)
	(ext_lang_before_prompt): Update.
	(ALL_ENABLED_EXTENSION_LANGUAGES): Remove.
---
 gdb/ChangeLog   |  18 ++++++
 gdb/extension.c | 153 ++++++++++++++++--------------------------------
 2 files changed, 69 insertions(+), 102 deletions(-)

diff --git a/gdb/extension.c b/gdb/extension.c
index 09aa7d91c31..e4b3b3cbd12 100644
--- a/gdb/extension.c
+++ b/gdb/extension.c
@@ -32,24 +32,7 @@
 #include "cli/cli-script.h"
 #include "python/python.h"
 #include "guile/guile.h"
-
-/* Iterate over all external extension languages, regardless of whether the
-   support has been compiled in or not.
-   This does not include GDB's own scripting language.  */
-
-#define ALL_EXTENSION_LANGUAGES(i, extlang) \
-  for (/*int*/ i = 0, extlang = extension_languages[0]; \
-       extlang != NULL; \
-       extlang = extension_languages[++i])
-
-/* Iterate over all external extension languages that are supported.
-   This does not include GDB's own scripting language.  */
-
-#define ALL_ENABLED_EXTENSION_LANGUAGES(i, extlang) \
-  for (/*int*/ i = 0, extlang = extension_languages[0]; \
-       extlang != NULL; \
-       extlang = extension_languages[++i]) \
-    if (extlang->ops != NULL)
+#include <array>
 
 static script_sourcer_func source_gdb_script;
 static objfile_script_sourcer_func source_gdb_objfile_script;
@@ -99,12 +82,11 @@ const struct extension_language_defn extension_language_gdb =
    pretty-printed value is the one that is used.  This algorithm is employed
    throughout.  */
 
-static const struct extension_language_defn * const extension_languages[] =
+static const std::array<const extension_language_defn *, 2> extension_languages
 {
   /* To preserve existing behaviour, python should always appear first.  */
   &extension_language_python,
   &extension_language_guile,
-  NULL
 };
 
 /* Return a pointer to the struct extension_language_defn object of
@@ -115,15 +97,12 @@ static const struct extension_language_defn * const extension_languages[] =
 const struct extension_language_defn *
 get_ext_lang_defn (enum extension_language lang)
 {
-  int i;
-  const struct extension_language_defn *extlang;
-
   gdb_assert (lang != EXT_LANG_NONE);
 
   if (lang == EXT_LANG_GDB)
     return &extension_language_gdb;
 
-  ALL_EXTENSION_LANGUAGES (i, extlang)
+  for (const struct extension_language_defn *extlang : extension_languages)
     {
       if (extlang->language == lang)
 	return extlang;
@@ -151,13 +130,10 @@ has_extension (const char *file, const char *extension)
 const struct extension_language_defn *
 get_ext_lang_of_file (const char *file)
 {
-  int i;
-  const struct extension_language_defn *extlang;
-
   if (has_extension (file, extension_language_gdb.suffix))
     return &extension_language_gdb;
 
-  ALL_EXTENSION_LANGUAGES (i, extlang)
+  for (const struct extension_language_defn *extlang : extension_languages)
     {
       if (has_extension (file, extlang->suffix))
 	return extlang;
@@ -331,12 +307,10 @@ ext_lang_auto_load_enabled (const struct extension_language_defn *extlang)
 void
 finish_ext_lang_initialization (void)
 {
-  int i;
-  const struct extension_language_defn *extlang;
-
-  ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
+  for (const struct extension_language_defn *extlang : extension_languages)
     {
-      if (extlang->ops->finish_initialization != NULL)
+      if (extlang->ops != nullptr
+	  && extlang->ops->finish_initialization != NULL)
 	extlang->ops->finish_initialization (extlang);
     }
 }
@@ -355,10 +329,7 @@ finish_ext_lang_initialization (void)
 void
 eval_ext_lang_from_control_command (struct command_line *cmd)
 {
-  int i;
-  const struct extension_language_defn *extlang;
-
-  ALL_EXTENSION_LANGUAGES (i, extlang)
+  for (const struct extension_language_defn *extlang : extension_languages)
     {
       if (extlang->cli_control_type == cmd->control_type)
 	{
@@ -385,16 +356,14 @@ eval_ext_lang_from_control_command (struct command_line *cmd)
 void
 auto_load_ext_lang_scripts_for_objfile (struct objfile *objfile)
 {
-  int i;
-  const struct extension_language_defn *extlang;
-
-  extlang = &extension_language_gdb;
-  if (ext_lang_auto_load_enabled (extlang))
-    auto_load_objfile_script (objfile, extlang);
+  const struct extension_language_defn *gdb = &extension_language_gdb;
+  if (ext_lang_auto_load_enabled (gdb))
+    auto_load_objfile_script (objfile, gdb);
 
-  ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
+  for (const struct extension_language_defn *extlang : extension_languages)
     {
-      if (ext_lang_auto_load_enabled (extlang))
+      if (extlang->ops != nullptr
+	  && ext_lang_auto_load_enabled (extlang))
 	auto_load_objfile_script (objfile, extlang);
     }
 }
@@ -410,12 +379,10 @@ auto_load_ext_lang_scripts_for_objfile (struct objfile *objfile)
 
 ext_lang_type_printers::ext_lang_type_printers ()
 {
-  int i;
-  const struct extension_language_defn *extlang;
-
-  ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
+  for (const struct extension_language_defn *extlang : extension_languages)
     {
-      if (extlang->ops->start_type_printers != NULL)
+      if (extlang->ops != nullptr
+	  && extlang->ops->start_type_printers != NULL)
 	extlang->ops->start_type_printers (extlang, this);
     }
 }
@@ -429,15 +396,13 @@ char *
 apply_ext_lang_type_printers (struct ext_lang_type_printers *printers,
 			      struct type *type)
 {
-  int i;
-  const struct extension_language_defn *extlang;
-
-  ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
+  for (const struct extension_language_defn *extlang : extension_languages)
     {
       char *result = NULL;
       enum ext_lang_rc rc;
 
-      if (extlang->ops->apply_type_printers == NULL)
+      if (extlang->ops == nullptr
+	  || extlang->ops->apply_type_printers == NULL)
 	continue;
       rc = extlang->ops->apply_type_printers (extlang, printers, type,
 					      &result);
@@ -460,12 +425,10 @@ apply_ext_lang_type_printers (struct ext_lang_type_printers *printers,
 
 ext_lang_type_printers::~ext_lang_type_printers ()
 {
-  int i;
-  const struct extension_language_defn *extlang;
-
-  ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
+  for (const struct extension_language_defn *extlang : extension_languages)
     {
-      if (extlang->ops->free_type_printers != NULL)
+      if (extlang->ops != nullptr
+	  && extlang->ops->free_type_printers != NULL)
 	extlang->ops->free_type_printers (extlang, this);
     }
 }
@@ -490,14 +453,12 @@ apply_ext_lang_val_pretty_printer (struct value *val,
 				   const struct value_print_options *options,
 				   const struct language_defn *language)
 {
-  int i;
-  const struct extension_language_defn *extlang;
-
-  ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
+  for (const struct extension_language_defn *extlang : extension_languages)
     {
       enum ext_lang_rc rc;
 
-      if (extlang->ops->apply_val_pretty_printer == NULL)
+      if (extlang->ops == nullptr
+	  || extlang->ops->apply_val_pretty_printer == NULL)
 	continue;
       rc = extlang->ops->apply_val_pretty_printer (extlang, val, stream,
 						   recurse, options, language);
@@ -544,14 +505,12 @@ apply_ext_lang_frame_filter (struct frame_info *frame,
 			     struct ui_out *out,
 			     int frame_low, int frame_high)
 {
-  int i;
-  const struct extension_language_defn *extlang;
-
-  ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
+  for (const struct extension_language_defn *extlang : extension_languages)
     {
       enum ext_lang_bt_status status;
 
-      if (extlang->ops->apply_frame_filter == NULL)
+      if (extlang->ops == nullptr
+	  || extlang->ops->apply_frame_filter == NULL)
 	continue;
       status = extlang->ops->apply_frame_filter (extlang, frame, flags,
 					       args_type, out,
@@ -577,12 +536,10 @@ apply_ext_lang_frame_filter (struct frame_info *frame,
 void
 preserve_ext_lang_values (struct objfile *objfile, htab_t copied_types)
 {
-  int i;
-  const struct extension_language_defn *extlang;
-
-  ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
+  for (const struct extension_language_defn *extlang : extension_languages)
     {
-      if (extlang->ops->preserve_values != NULL)
+      if (extlang->ops != nullptr
+	  && extlang->ops->preserve_values != NULL)
 	extlang->ops->preserve_values (extlang, objfile, copied_types);
     }
 }
@@ -600,12 +557,10 @@ const struct extension_language_defn *
 get_breakpoint_cond_ext_lang (struct breakpoint *b,
 			      enum extension_language skip_lang)
 {
-  int i;
-  const struct extension_language_defn *extlang;
-
-  ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
+  for (const struct extension_language_defn *extlang : extension_languages)
     {
-      if (extlang->language != skip_lang
+      if (extlang->ops != nullptr
+	  && extlang->language != skip_lang
 	  && extlang->ops->breakpoint_has_cond != NULL
 	  && extlang->ops->breakpoint_has_cond (extlang, b))
 	return extlang;
@@ -620,18 +575,17 @@ get_breakpoint_cond_ext_lang (struct breakpoint *b,
 int
 breakpoint_ext_lang_cond_says_stop (struct breakpoint *b)
 {
-  int i;
-  const struct extension_language_defn *extlang;
   enum ext_lang_bp_stop stop = EXT_LANG_BP_STOP_UNSET;
 
-  ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
+  for (const struct extension_language_defn *extlang : extension_languages)
     {
       /* There is a rule that a breakpoint can have at most one of any of a
 	 CLI or extension language condition.  However, Python hacks in "finish
 	 breakpoints" on top of the "stop" check, so we have to call this for
 	 every language, even if we could first determine whether a "stop"
 	 method exists.  */
-      if (extlang->ops->breakpoint_cond_says_stop != NULL)
+      if (extlang->ops != nullptr
+	  && extlang->ops->breakpoint_cond_says_stop != NULL)
 	{
 	  enum ext_lang_bp_stop this_stop
 	    = extlang->ops->breakpoint_cond_says_stop (extlang, b);
@@ -813,12 +767,12 @@ set_quit_flag (void)
 int
 check_quit_flag (void)
 {
-  int i, result = 0;
-  const struct extension_language_defn *extlang;
+  int result = 0;
 
-  ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
+  for (const struct extension_language_defn *extlang : extension_languages)
     {
-      if (extlang->ops->check_quit_flag != NULL)
+      if (extlang->ops != nullptr
+	  && extlang->ops->check_quit_flag != NULL)
 	if (extlang->ops->check_quit_flag (extlang) != 0)
 	  result = 1;
     }
@@ -843,16 +797,14 @@ void
 get_matching_xmethod_workers (struct type *type, const char *method_name,
 			      std::vector<xmethod_worker_up> *workers)
 {
-  int i;
-  const struct extension_language_defn *extlang;
-
-  ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
+  for (const struct extension_language_defn *extlang : extension_languages)
     {
       enum ext_lang_rc rc;
 
       /* If an extension language does not support xmethods, ignore
 	 it.  */
-      if (extlang->ops->get_matching_xmethod_workers == NULL)
+      if (extlang->ops == nullptr
+	  || extlang->ops->get_matching_xmethod_workers == NULL)
 	continue;
 
       rc = extlang->ops->get_matching_xmethod_workers (extlang,
@@ -901,13 +853,12 @@ xmethod_worker::get_result_type (value *object, gdb::array_view<value *> args)
 gdb::optional<std::string>
 ext_lang_colorize (const std::string &filename, const std::string &contents)
 {
-  int i;
-  const struct extension_language_defn *extlang;
   gdb::optional<std::string> result;
 
-  ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
+  for (const struct extension_language_defn *extlang : extension_languages)
     {
-      if (extlang->ops->colorize == nullptr)
+      if (extlang->ops == nullptr
+	  || extlang->ops->colorize == nullptr)
 	continue;
       result = extlang->ops->colorize (filename, contents);
       if (result.has_value ())
@@ -925,14 +876,12 @@ ext_lang_colorize (const std::string &filename, const std::string &contents)
 static void
 ext_lang_before_prompt (const char *current_gdb_prompt)
 {
-  int i;
-  const struct extension_language_defn *extlang;
-
-  ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
+  for (const struct extension_language_defn *extlang : extension_languages)
     {
       enum ext_lang_rc rc;
 
-      if (extlang->ops->before_prompt == NULL)
+      if (extlang->ops == nullptr
+	  || extlang->ops->before_prompt == NULL)
 	continue;
       rc = extlang->ops->before_prompt (extlang, current_gdb_prompt);
       switch (rc)
-- 
2.17.2


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 2/4] Remove ALL_SO_LIBS and so_list_head
  2020-04-19 14:18 Tom Tromey
  2020-04-19 14:18 ` [PATCH 1/4] Remove ALL_EXTENSION_LANGUAGES and ALL_ENABLED_EXTENSION_LANGUAGES Tom Tromey
@ 2020-04-19 14:18 ` Tom Tromey
  2020-04-19 14:18 ` [PATCH 3/4] Remove ALL_PSPACES Tom Tromey
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Tom Tromey @ 2020-04-19 14:18 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This patch started as an attempt to replace ALL_SO_LIBS with an
ordinary C++ iterator.  However, then I tripped over the so_list_head
define again, and decided to remove it as well.

gdb/ChangeLog
2020-04-18  Tom Tromey  <tom@tromey.com>

	* mi/mi-cmd-file.c (mi_cmd_file_list_shared_libraries): Update.
	* solib-svr4.c (svr4_fetch_objfile_link_map): Update.
	(enable_break): Update.
	* solib-frv.c (frv_fdpic_find_global_pointer): Update.
	(frv_fdpic_find_canonical_descriptor): Update.
	(frv_fetch_objfile_link_map): Update.
	* progspace.c (program_space::free_all_objfiles): Update.
	(program_space::solibs): New method.
	* progspace.h (struct program_space) <solibs>: New method.
	* solist.h (master_so_list): Don't declare.
	(ALL_SO_LIBS): Remove.
	* solib.h (so_list_head): Remove.
	(update_solib_list): Update comment.
	* solib.c (master_so_list): Remove.
	(solib_used, update_solib_list, solib_add)
	(info_sharedlibrary_command, clear_solib)
	(reload_shared_libraries_1, remove_user_added_objfile): Update.
---
 gdb/ChangeLog        | 20 ++++++++++++++++++
 gdb/mi/mi-cmd-file.c |  3 +--
 gdb/progspace.c      | 12 ++++++++---
 gdb/progspace.h      |  7 +++++++
 gdb/solib-frv.c      | 18 +++-------------
 gdb/solib-svr4.c     |  8 ++-----
 gdb/solib.c          | 50 ++++++++++++++++----------------------------
 gdb/solib.h          |  9 +++-----
 gdb/solist.h         |  8 -------
 9 files changed, 63 insertions(+), 72 deletions(-)

diff --git a/gdb/mi/mi-cmd-file.c b/gdb/mi/mi-cmd-file.c
index b5835a52bf8..3b0261c6c9f 100644
--- a/gdb/mi/mi-cmd-file.c
+++ b/gdb/mi/mi-cmd-file.c
@@ -121,7 +121,6 @@ mi_cmd_file_list_shared_libraries (const char *command, char **argv, int argc)
 {
   struct ui_out *uiout = current_uiout;
   const char *pattern;
-  struct so_list *so = NULL;
 
   switch (argc)
     {
@@ -148,7 +147,7 @@ mi_cmd_file_list_shared_libraries (const char *command, char **argv, int argc)
   /* Print the table header.  */
   ui_out_emit_list list_emitter (uiout, "shared-libraries");
 
-  ALL_SO_LIBS (so)
+  for (struct so_list *so : current_program_space->solibs ())
     {
       if (so->so_name[0] == '\0')
 	continue;
diff --git a/gdb/progspace.c b/gdb/progspace.c
index 6419f017704..252b62e02d7 100644
--- a/gdb/progspace.c
+++ b/gdb/progspace.c
@@ -192,10 +192,8 @@ program_space::~program_space ()
 void
 program_space::free_all_objfiles ()
 {
-  struct so_list *so;
-
   /* Any objfile reference would become stale.  */
-  for (so = master_so_list (); so; so = so->next)
+  for (struct so_list *so : current_program_space->solibs ())
     gdb_assert (so->objfile == NULL);
 
   while (!objfiles_list.empty ())
@@ -239,6 +237,14 @@ program_space::remove_objfile (struct objfile *objfile)
     symfile_object_file = NULL;
 }
 
+/* See progspace.h.  */
+
+next_adapter<struct so_list>
+program_space::solibs () const
+{
+  return next_adapter<struct so_list> (this->so_list);
+}
+
 /* Copies program space SRC to DEST.  Copies the main executable file,
    and the main symbol file.  Returns DEST.  */
 
diff --git a/gdb/progspace.h b/gdb/progspace.h
index 2b887847e17..0e32224f02d 100644
--- a/gdb/progspace.h
+++ b/gdb/progspace.h
@@ -37,6 +37,7 @@ struct exec;
 struct address_space;
 struct program_space_data;
 struct address_space_data;
+struct so_list;
 
 typedef std::list<std::shared_ptr<objfile>> objfile_list;
 
@@ -264,6 +265,12 @@ struct program_space
   /* Free all the objfiles associated with this program space.  */
   void free_all_objfiles ();
 
+  /* Return a range adapter for iterating over all the solibs in this
+     program space.  Use it like:
+
+     for (so_list *so : pspace->solibs ()) { ... }  */
+  next_adapter<struct so_list> solibs () const;
+
 
   /* Pointer to next in linked list.  */
   struct program_space *next = NULL;
diff --git a/gdb/solib-frv.c b/gdb/solib-frv.c
index 582f2d5ede6..62e7b05b490 100644
--- a/gdb/solib-frv.c
+++ b/gdb/solib-frv.c
@@ -908,10 +908,7 @@ main_got (void)
 CORE_ADDR
 frv_fdpic_find_global_pointer (CORE_ADDR addr)
 {
-  struct so_list *so;
-
-  so = master_so_list ();
-  while (so)
+  for (struct so_list *so : current_program_space->solibs ())
     {
       int seg;
       lm_info_frv *li = (lm_info_frv *) so->lm_info;
@@ -923,8 +920,6 @@ frv_fdpic_find_global_pointer (CORE_ADDR addr)
 	      && addr < map->segs[seg].addr + map->segs[seg].p_memsz)
 	    return li->got_value;
 	}
-
-      so = so->next;
     }
 
   /* Didn't find it in any of the shared objects.  So assume it's in the
@@ -969,10 +964,7 @@ frv_fdpic_find_canonical_descriptor (CORE_ADDR entry_point)
      in list of shared objects.  */
   if (addr == 0)
     {
-      struct so_list *so;
-
-      so = master_so_list ();
-      while (so)
+      for (struct so_list *so : current_program_space->solibs ())
 	{
 	  lm_info_frv *li = (lm_info_frv *) so->lm_info;
 
@@ -981,8 +973,6 @@ frv_fdpic_find_canonical_descriptor (CORE_ADDR entry_point)
 
 	  if (addr != 0)
 	    break;
-
-	  so = so->next;
 	}
     }
 
@@ -1116,8 +1106,6 @@ find_canonical_descriptor_in_load_object
 CORE_ADDR
 frv_fetch_objfile_link_map (struct objfile *objfile)
 {
-  struct so_list *so;
-
   /* Cause frv_current_sos() to be run if it hasn't been already.  */
   if (main_lm_addr == 0)
     solib_add (0, 0, 1);
@@ -1128,7 +1116,7 @@ frv_fetch_objfile_link_map (struct objfile *objfile)
 
   /* The other link map addresses may be found by examining the list
      of shared libraries.  */
-  for (so = master_so_list (); so; so = so->next)
+  for (struct so_list *so : current_program_space->solibs ())
     {
       lm_info_frv *li = (lm_info_frv *) so->lm_info;
 
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 38c832f8f5a..19d1105ae95 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -1537,7 +1537,6 @@ svr4_current_sos (void)
 CORE_ADDR
 svr4_fetch_objfile_link_map (struct objfile *objfile)
 {
-  struct so_list *so;
   struct svr4_info *info = get_svr4_info (objfile->pspace);
 
   /* Cause svr4_current_sos() to be run if it hasn't been already.  */
@@ -1555,7 +1554,7 @@ svr4_fetch_objfile_link_map (struct objfile *objfile)
 
   /* The other link map addresses may be found by examining the list
      of shared libraries.  */
-  for (so = master_so_list (); so; so = so->next)
+  for (struct so_list *so : current_program_space->solibs ())
     if (so->objfile == objfile)
       {
 	lm_info_svr4 *li = (lm_info_svr4 *) so->lm_info;
@@ -2307,7 +2306,6 @@ enable_break (struct svr4_info *info, int from_tty)
       CORE_ADDR load_addr = 0;
       int load_addr_found = 0;
       int loader_found_in_list = 0;
-      struct so_list *so;
       struct target_ops *tmp_bfd_target;
 
       sym_addr = 0;
@@ -2340,8 +2338,7 @@ enable_break (struct svr4_info *info, int from_tty)
 
       /* On a running target, we can get the dynamic linker's base
          address from the shared library table.  */
-      so = master_so_list ();
-      while (so)
+      for (struct so_list *so : current_program_space->solibs ())
 	{
 	  if (svr4_same_1 (interp_name, so->so_original_name))
 	    {
@@ -2350,7 +2347,6 @@ enable_break (struct svr4_info *info, int from_tty)
 	      load_addr = lm_addr_check (so, tmp_bfd.get ());
 	      break;
 	    }
-	  so = so->next;
 	}
 
       /* If we were not able to find the base address of the loader
diff --git a/gdb/solib.c b/gdb/solib.c
index ba388d77e8d..cd410bb9e3e 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -647,13 +647,6 @@ free_so (struct so_list *so)
 }
 
 
-/* Return address of first so_list entry in master shared object list.  */
-struct so_list *
-master_so_list (void)
-{
-  return so_list_head;
-}
-
 /* Read in symbols for shared object SO.  If SYMFILE_VERBOSE is set in FLAGS,
    be chatty about it.  Return true if any symbols were actually loaded.  */
 
@@ -713,15 +706,13 @@ solib_read_symbols (struct so_list *so, symfile_add_flags flags)
   return false;
 }
 
-/* Return true if KNOWN->objfile is used by any other so_list object in the
-   SO_LIST_HEAD list.  Return false otherwise.  */
+/* Return true if KNOWN->objfile is used by any other so_list object
+   in the list of shared libraries.  Return false otherwise.  */
 
 static bool
 solib_used (const struct so_list *const known)
 {
-  const struct so_list *pivot;
-
-  for (pivot = so_list_head; pivot != NULL; pivot = pivot->next)
+  for (const struct so_list *pivot : current_program_space->solibs ())
     if (pivot != known && pivot->objfile == known->objfile)
       return true;
   return false;
@@ -784,8 +775,8 @@ update_solib_list (int from_tty)
      the time we're done walking GDB's list, the inferior's list
      contains only the new shared objects, which we then add.  */
 
-  gdb = so_list_head;
-  gdb_link = &so_list_head;
+  gdb = current_program_space->so_list;
+  gdb_link = &current_program_space->so_list;
   while (gdb)
     {
       struct so_list *i = inferior;
@@ -943,8 +934,6 @@ libpthread_solib_p (struct so_list *so)
 void
 solib_add (const char *pattern, int from_tty, int readsyms)
 {
-  struct so_list *gdb;
-
   if (print_symbol_loading_p (from_tty, 0, 0))
     {
       if (pattern != NULL)
@@ -979,7 +968,7 @@ solib_add (const char *pattern, int from_tty, int readsyms)
     if (from_tty)
         add_flags |= SYMFILE_VERBOSE;
 
-    for (gdb = so_list_head; gdb; gdb = gdb->next)
+    for (struct so_list *gdb : current_program_space->solibs ())
       if (! pattern || re_exec (gdb->so_name))
 	{
           /* Normally, we would read the symbols from that library
@@ -1030,7 +1019,6 @@ solib_add (const char *pattern, int from_tty, int readsyms)
 static void
 info_sharedlibrary_command (const char *pattern, int from_tty)
 {
-  struct so_list *so = NULL;	/* link map state variable */
   bool so_missing_debug_info = false;
   int addr_width;
   int nr_libs;
@@ -1053,7 +1041,8 @@ info_sharedlibrary_command (const char *pattern, int from_tty)
   /* ui_out_emit_table table_emitter needs to know the number of rows,
      so we need to make two passes over the libs.  */
 
-  for (nr_libs = 0, so = so_list_head; so; so = so->next)
+  nr_libs = 0;
+  for (struct so_list *so : current_program_space->solibs ())
     {
       if (so->so_name[0])
 	{
@@ -1074,7 +1063,7 @@ info_sharedlibrary_command (const char *pattern, int from_tty)
 
     uiout->table_body ();
 
-    ALL_SO_LIBS (so)
+    for (struct so_list *so : current_program_space->solibs ())
       {
 	if (! so->so_name[0])
 	  continue;
@@ -1185,11 +1174,11 @@ clear_solib (void)
 
   disable_breakpoints_in_shlibs ();
 
-  while (so_list_head)
+  while (current_program_space->so_list)
     {
-      struct so_list *so = so_list_head;
+      struct so_list *so = current_program_space->so_list;
 
-      so_list_head = so->next;
+      current_program_space->so_list = so->next;
       gdb::observers::solib_unloaded.notify (so);
       remove_target_sections (so);
       free_so (so);
@@ -1284,12 +1273,10 @@ handle_solib_event (void)
 static void
 reload_shared_libraries_1 (int from_tty)
 {
-  struct so_list *so;
-
   if (print_symbol_loading_p (from_tty, 0, 0))
     printf_unfiltered (_("Loading symbols for shared libraries.\n"));
 
-  for (so = so_list_head; so != NULL; so = so->next)
+  for (struct so_list *so : current_program_space->solibs ())
     {
       const char *found_pathname = NULL;
       bool was_loaded = so->symbols_loaded != 0;
@@ -1552,18 +1539,17 @@ gdb_bfd_lookup_symbol (bfd *abfd,
   return symaddr;
 }
 
-/* SO_LIST_HEAD may contain user-loaded object files that can be removed
-   out-of-band by the user.  So upon notification of free_objfile remove
-   all references to any user-loaded file that is about to be freed.  */
+/* The shared library list may contain user-loaded object files that
+   can be removed out-of-band by the user.  So upon notification of
+   free_objfile remove all references to any user-loaded file that is
+   about to be freed.  */
 
 static void
 remove_user_added_objfile (struct objfile *objfile)
 {
-  struct so_list *so;
-
   if (objfile != 0 && objfile->flags & OBJF_USERLOADED)
     {
-      for (so = so_list_head; so != NULL; so = so->next)
+      for (struct so_list *so : current_program_space->solibs ())
 	if (so->objfile == objfile)
 	  so->objfile = NULL;
     }
diff --git a/gdb/solib.h b/gdb/solib.h
index 2628ca0c2b7..801965fcd53 100644
--- a/gdb/solib.h
+++ b/gdb/solib.h
@@ -28,9 +28,6 @@ struct program_space;
 
 #include "symfile-add-flags.h"
 
-/* List of known shared objects */
-#define so_list_head current_program_space->so_list
-
 /* Called when we free all symtabs, to free the shared library information
    as well.  */
 
@@ -81,9 +78,9 @@ extern void set_solib_ops (struct gdbarch *gdbarch,
 /* Synchronize GDB's shared object list with inferior's.
 
    Extract the list of currently loaded shared objects from the
-   inferior, and compare it with the list of shared objects currently
-   in GDB's so_list_head list.  Edit so_list_head to bring it in sync
-   with the inferior's new list.
+   inferior, and compare it with the list of shared objects in the
+   current program space's list of shared libraries.  Edit
+   so_list_head to bring it in sync with the inferior's new list.
 
    If we notice that the inferior has unloaded some shared objects,
    free any symbolic info GDB had read about those shared objects.
diff --git a/gdb/solist.h b/gdb/solist.h
index 068aeba2f0e..0360d342ae8 100644
--- a/gdb/solist.h
+++ b/gdb/solist.h
@@ -24,11 +24,6 @@
 #include "symtab.h"
 #include "gdb_bfd.h"
 
-#define ALL_SO_LIBS(so) \
-    for (so = so_list_head; \
-	 so != NULL; \
-	 so = so->next)
-
 /* Base class for target-specific link map information.  */
 
 struct lm_info_base
@@ -183,9 +178,6 @@ struct so_deleter
 /* A unique pointer to a so_list.  */
 typedef std::unique_ptr<so_list, so_deleter> so_list_up;
 
-/* Return address of first so_list entry in master shared object list.  */
-struct so_list *master_so_list (void);
-
 /* Find main executable binary file.  */
 extern gdb::unique_xmalloc_ptr<char> exec_file_find (const char *in_pathname,
 						     int *fd);
-- 
2.17.2


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 3/4] Remove ALL_PSPACES
  2020-04-19 14:18 Tom Tromey
  2020-04-19 14:18 ` [PATCH 1/4] Remove ALL_EXTENSION_LANGUAGES and ALL_ENABLED_EXTENSION_LANGUAGES Tom Tromey
  2020-04-19 14:18 ` [PATCH 2/4] Remove ALL_SO_LIBS and so_list_head Tom Tromey
@ 2020-04-19 14:18 ` Tom Tromey
  2020-04-19 14:18 ` [PATCH 4/4] More C++-ification for struct display Tom Tromey
  2020-05-08 20:25 ` (unknown) Tom Tromey
  4 siblings, 0 replies; 7+ messages in thread
From: Tom Tromey @ 2020-04-19 14:18 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This removes the ALL_PSPACES macro.  In this case it seemed cleanest
to change how program spaces are stored -- instead of using a linked
list, they are now stored in a std::vector.

gdb/ChangeLog
2020-04-18  Tom Tromey  <tom@tromey.com>

	* symtab.c (set_symbol_cache_size)
	(maintenance_print_symbol_cache, maintenance_flush_symbol_cache)
	(maintenance_print_symbol_cache_statistics): Update.
	* symmisc.c (print_symbol_bcache_statistics)
	(print_objfile_statistics, maintenance_print_objfiles)
	(maintenance_info_symtabs, maintenance_check_symtabs)
	(maintenance_expand_symtabs, maintenance_info_line_tables):
	Update.
	* symfile-debug.c (set_debug_symfile): Update.
	* source.c (forget_cached_source_info): Update.
	* python/python.c (gdbpy_progspaces): Update.
	* psymtab.c (maintenance_info_psymtabs): Update.
	* probe.c (parse_probes): Update.
	* linespec.c (iterate_over_all_matching_symtabs)
	(collect_symtabs_from_filename, search_minsyms_for_name): Update.
	* guile/scm-progspace.c (gdbscm_progspaces): Update.
	* exec.c (exec_target::close): Update.
	* ada-tasks.c (ada_tasks_new_objfile_observer): Update.
	* breakpoint.c (print_one_breakpoint_location)
	(create_longjmp_master_breakpoint)
	(create_std_terminate_master_breakpoint): Update.
	* progspace.c (program_spaces): Now a std::vector.
	(maybe_new_address_space): Update.
	(add_program_space): Remove.
	(program_space::program_space): Update.
	(remove_program_space): Update.
	(number_of_program_spaces): Remove.
	(print_program_space, update_address_spaces): Update.
	* progspace.h (program_spaces): Change type.
	(ALL_PSPACES): Remove.
	(number_of_program_spaces): Don't declare.
	(struct program_space) <next>: Remove.
---
 gdb/ChangeLog             |  35 ++++++
 gdb/ada-tasks.c           |   4 +-
 gdb/breakpoint.c          | 228 +++++++++++++++++++-------------------
 gdb/exec.c                |   3 +-
 gdb/guile/scm-progspace.c |  11 +-
 gdb/linespec.c            | 136 +++++++++++------------
 gdb/probe.c               |   4 +-
 gdb/progspace.c           |  69 ++----------
 gdb/progspace.h           |  12 +-
 gdb/psymtab.c             |   4 +-
 gdb/python/python.c       |  14 +--
 gdb/source.c              |   4 +-
 gdb/symfile-debug.c       |   4 +-
 gdb/symmisc.c             | 134 ++++++++++------------
 gdb/symtab.c              |  16 +--
 15 files changed, 309 insertions(+), 369 deletions(-)

diff --git a/gdb/ada-tasks.c b/gdb/ada-tasks.c
index 589d5e84e0a..266335387a3 100644
--- a/gdb/ada-tasks.c
+++ b/gdb/ada-tasks.c
@@ -1433,9 +1433,7 @@ ada_tasks_new_objfile_observer (struct objfile *objfile)
     {
       /* All objfiles are being cleared, so we should clear all
 	 our caches for all program spaces.  */
-      struct program_space *pspace;
-
-      for (pspace = program_spaces; pspace != NULL; pspace = pspace->next)
+      for (struct program_space *pspace : program_spaces)
         ada_tasks_invalidate_pspace_data (pspace);
     }
   else
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 858f4c75691..a24426d5e89 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -3224,153 +3224,151 @@ create_overlay_event_breakpoint (void)
 static void
 create_longjmp_master_breakpoint (void)
 {
-  struct program_space *pspace;
-
   scoped_restore_current_program_space restore_pspace;
 
-  ALL_PSPACES (pspace)
-  {
-    set_current_program_space (pspace);
+  for (struct program_space *pspace : program_spaces)
+    {
+      set_current_program_space (pspace);
 
-    for (objfile *objfile : current_program_space->objfiles ())
-      {
-	int i;
-	struct gdbarch *gdbarch;
-	struct breakpoint_objfile_data *bp_objfile_data;
+      for (objfile *objfile : current_program_space->objfiles ())
+	{
+	  int i;
+	  struct gdbarch *gdbarch;
+	  struct breakpoint_objfile_data *bp_objfile_data;
 
-	gdbarch = objfile->arch ();
+	  gdbarch = objfile->arch ();
 
-	bp_objfile_data = get_breakpoint_objfile_data (objfile);
+	  bp_objfile_data = get_breakpoint_objfile_data (objfile);
 
-	if (!bp_objfile_data->longjmp_searched)
-	  {
-	    std::vector<probe *> ret
-	      = find_probes_in_objfile (objfile, "libc", "longjmp");
+	  if (!bp_objfile_data->longjmp_searched)
+	    {
+	      std::vector<probe *> ret
+		= find_probes_in_objfile (objfile, "libc", "longjmp");
 
-	    if (!ret.empty ())
-	      {
-		/* We are only interested in checking one element.  */
-		probe *p = ret[0];
+	      if (!ret.empty ())
+		{
+		  /* We are only interested in checking one element.  */
+		  probe *p = ret[0];
 
-		if (!p->can_evaluate_arguments ())
-		  {
-		    /* We cannot use the probe interface here, because it does
-		       not know how to evaluate arguments.  */
-		    ret.clear ();
-		  }
-	      }
-	    bp_objfile_data->longjmp_probes = ret;
-	    bp_objfile_data->longjmp_searched = 1;
-	  }
+		  if (!p->can_evaluate_arguments ())
+		    {
+		      /* We cannot use the probe interface here,
+			 because it does not know how to evaluate
+			 arguments.  */
+		      ret.clear ();
+		    }
+		}
+	      bp_objfile_data->longjmp_probes = ret;
+	      bp_objfile_data->longjmp_searched = 1;
+	    }
 
-	if (!bp_objfile_data->longjmp_probes.empty ())
-	  {
-	    for (probe *p : bp_objfile_data->longjmp_probes)
-	      {
-		struct breakpoint *b;
-
-		b = create_internal_breakpoint (gdbarch,
-						p->get_relocated_address (objfile),
-						bp_longjmp_master,
-						&internal_breakpoint_ops);
-		b->location = new_probe_location ("-probe-stap libc:longjmp");
-		b->enable_state = bp_disabled;
-	      }
+	  if (!bp_objfile_data->longjmp_probes.empty ())
+	    {
+	      for (probe *p : bp_objfile_data->longjmp_probes)
+		{
+		  struct breakpoint *b;
+
+		  b = create_internal_breakpoint (gdbarch,
+						  p->get_relocated_address (objfile),
+						  bp_longjmp_master,
+						  &internal_breakpoint_ops);
+		  b->location = new_probe_location ("-probe-stap libc:longjmp");
+		  b->enable_state = bp_disabled;
+		}
 
-	    continue;
-	  }
+	      continue;
+	    }
 
-	if (!gdbarch_get_longjmp_target_p (gdbarch))
-	  continue;
+	  if (!gdbarch_get_longjmp_target_p (gdbarch))
+	    continue;
 
-	for (i = 0; i < NUM_LONGJMP_NAMES; i++)
-	  {
-	    struct breakpoint *b;
-	    const char *func_name;
-	    CORE_ADDR addr;
-	    struct explicit_location explicit_loc;
+	  for (i = 0; i < NUM_LONGJMP_NAMES; i++)
+	    {
+	      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;
+	      if (msym_not_found_p (bp_objfile_data->longjmp_msym[i].minsym))
+		continue;
 
-	    func_name = longjmp_names[i];
-	    if (bp_objfile_data->longjmp_msym[i].minsym == NULL)
-	      {
-		struct bound_minimal_symbol m;
+	      func_name = longjmp_names[i];
+	      if (bp_objfile_data->longjmp_msym[i].minsym == NULL)
+		{
+		  struct bound_minimal_symbol m;
 
-		m = lookup_minimal_symbol_text (func_name, objfile);
-		if (m.minsym == NULL)
-		  {
-		    /* Prevent future lookups in this objfile.  */
-		    bp_objfile_data->longjmp_msym[i].minsym = &msym_not_found;
-		    continue;
-		  }
-		bp_objfile_data->longjmp_msym[i] = m;
-	      }
+		  m = lookup_minimal_symbol_text (func_name, objfile);
+		  if (m.minsym == NULL)
+		    {
+		      /* Prevent future lookups in this objfile.  */
+		      bp_objfile_data->longjmp_msym[i].minsym = &msym_not_found;
+		      continue;
+		    }
+		  bp_objfile_data->longjmp_msym[i] = m;
+		}
 
-	    addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->longjmp_msym[i]);
-	    b = create_internal_breakpoint (gdbarch, addr, bp_longjmp_master,
-					    &internal_breakpoint_ops);
-	    initialize_explicit_location (&explicit_loc);
-	    explicit_loc.function_name = ASTRDUP (func_name);
-	    b->location = new_explicit_location (&explicit_loc);
-	    b->enable_state = bp_disabled;
-	  }
-      }
-  }
+	      addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->longjmp_msym[i]);
+	      b = create_internal_breakpoint (gdbarch, addr, bp_longjmp_master,
+					      &internal_breakpoint_ops);
+	      initialize_explicit_location (&explicit_loc);
+	      explicit_loc.function_name = ASTRDUP (func_name);
+	      b->location = new_explicit_location (&explicit_loc);
+	      b->enable_state = bp_disabled;
+	    }
+	}
+    }
 }
 
 /* Create a master std::terminate breakpoint.  */
 static void
 create_std_terminate_master_breakpoint (void)
 {
-  struct program_space *pspace;
   const char *const func_name = "std::terminate()";
 
   scoped_restore_current_program_space restore_pspace;
 
-  ALL_PSPACES (pspace)
-  {
-    CORE_ADDR addr;
+  for (struct program_space *pspace : program_spaces)
+    {
+      CORE_ADDR addr;
 
-    set_current_program_space (pspace);
+      set_current_program_space (pspace);
 
-    for (objfile *objfile : current_program_space->objfiles ())
-      {
-	struct breakpoint *b;
-	struct breakpoint_objfile_data *bp_objfile_data;
-	struct explicit_location explicit_loc;
+      for (objfile *objfile : current_program_space->objfiles ())
+	{
+	  struct breakpoint *b;
+	  struct breakpoint_objfile_data *bp_objfile_data;
+	  struct explicit_location explicit_loc;
 
-	bp_objfile_data = get_breakpoint_objfile_data (objfile);
+	  bp_objfile_data = get_breakpoint_objfile_data (objfile);
 
-	if (msym_not_found_p (bp_objfile_data->terminate_msym.minsym))
-	  continue;
+	  if (msym_not_found_p (bp_objfile_data->terminate_msym.minsym))
+	    continue;
 
-	if (bp_objfile_data->terminate_msym.minsym == NULL)
-	  {
-	    struct bound_minimal_symbol m;
+	  if (bp_objfile_data->terminate_msym.minsym == NULL)
+	    {
+	      struct bound_minimal_symbol m;
 
-	    m = lookup_minimal_symbol (func_name, NULL, objfile);
-	    if (m.minsym == NULL || (MSYMBOL_TYPE (m.minsym) != mst_text
-				     && MSYMBOL_TYPE (m.minsym) != mst_file_text))
-	      {
-		/* Prevent future lookups in this objfile.  */
-		bp_objfile_data->terminate_msym.minsym = &msym_not_found;
-		continue;
-	      }
-	    bp_objfile_data->terminate_msym = m;
-	  }
+	      m = lookup_minimal_symbol (func_name, NULL, objfile);
+	      if (m.minsym == NULL || (MSYMBOL_TYPE (m.minsym) != mst_text
+				       && MSYMBOL_TYPE (m.minsym) != mst_file_text))
+		{
+		  /* Prevent future lookups in this objfile.  */
+		  bp_objfile_data->terminate_msym.minsym = &msym_not_found;
+		  continue;
+		}
+	      bp_objfile_data->terminate_msym = m;
+	    }
 
-	addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->terminate_msym);
-	b = create_internal_breakpoint (objfile->arch (), addr,
-					bp_std_terminate_master,
-					&internal_breakpoint_ops);
-	initialize_explicit_location (&explicit_loc);
-	explicit_loc.function_name = ASTRDUP (func_name);
-	b->location = new_explicit_location (&explicit_loc);
-	b->enable_state = bp_disabled;
-      }
-  }
+	  addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->terminate_msym);
+	  b = create_internal_breakpoint (objfile->arch (), addr,
+					  bp_std_terminate_master,
+					  &internal_breakpoint_ops);
+	  initialize_explicit_location (&explicit_loc);
+	  explicit_loc.function_name = ASTRDUP (func_name);
+	  b->location = new_explicit_location (&explicit_loc);
+	  b->enable_state = bp_disabled;
+	}
+    }
 }
 
 /* Install a master breakpoint on the unwinder's debug hook.  */
@@ -6088,7 +6086,7 @@ print_one_breakpoint_location (struct breakpoint *b,
 	   there are several.  Always display for MI. */
 	if (allflag
 	    || (!gdbarch_has_global_breakpoints (target_gdbarch ())
-		&& (number_of_program_spaces () > 1
+		&& (program_spaces.size () > 1
 		    || number_of_inferiors () > 1)
 		/* LOC is for existing B, it cannot be in
 		   moribund_locations and thus having NULL OWNER.  */
diff --git a/gdb/exec.c b/gdb/exec.c
index c885709c94e..a2added5e22 100644
--- a/gdb/exec.c
+++ b/gdb/exec.c
@@ -177,10 +177,9 @@ exec_close (void)
 void
 exec_target::close ()
 {
-  struct program_space *ss;
   scoped_restore_current_program_space restore_pspace;
 
-  ALL_PSPACES (ss)
+  for (struct program_space *ss : program_spaces)
     {
       set_current_program_space (ss);
       clear_section_table (current_target_sections);
diff --git a/gdb/guile/scm-progspace.c b/gdb/guile/scm-progspace.c
index 5a39780dcbc..49c3e36227f 100644
--- a/gdb/guile/scm-progspace.c
+++ b/gdb/guile/scm-progspace.c
@@ -353,17 +353,16 @@ gdbscm_current_progspace (void)
 static SCM
 gdbscm_progspaces (void)
 {
-  struct program_space *ps;
   SCM result;
 
   result = SCM_EOL;
 
-  ALL_PSPACES (ps)
-  {
-    SCM item = psscm_scm_from_pspace (ps);
+  for (struct program_space *ps : program_spaces)
+    {
+      SCM item = psscm_scm_from_pspace (ps);
 
-    result = scm_cons (item, result);
-  }
+      result = scm_cons (item, result);
+    }
 
   return scm_reverse_x (result, SCM_EOL);
 }
diff --git a/gdb/linespec.c b/gdb/linespec.c
index 0eb3bc5b8d4..7182f159034 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -1133,58 +1133,56 @@ iterate_over_all_matching_symtabs
    struct program_space *search_pspace, bool include_inline,
    gdb::function_view<symbol_found_callback_ftype> callback)
 {
-  struct program_space *pspace;
-
-  ALL_PSPACES (pspace)
-  {
-    if (search_pspace != NULL && search_pspace != pspace)
-      continue;
-    if (pspace->executing_startup)
-      continue;
+  for (struct program_space *pspace : program_spaces)
+    {
+      if (search_pspace != NULL && search_pspace != pspace)
+	continue;
+      if (pspace->executing_startup)
+	continue;
 
-    set_current_program_space (pspace);
+      set_current_program_space (pspace);
 
-    for (objfile *objfile : current_program_space->objfiles ())
-      {
-	if (objfile->sf)
-	  objfile->sf->qf->expand_symtabs_matching (objfile,
-						    NULL,
-						    &lookup_name,
-						    NULL, NULL,
-						    search_domain);
-
-	for (compunit_symtab *cu : objfile->compunits ())
-	  {
-	    struct symtab *symtab = COMPUNIT_FILETABS (cu);
+      for (objfile *objfile : current_program_space->objfiles ())
+	{
+	  if (objfile->sf)
+	    objfile->sf->qf->expand_symtabs_matching (objfile,
+						      NULL,
+						      &lookup_name,
+						      NULL, NULL,
+						      search_domain);
+
+	  for (compunit_symtab *cu : objfile->compunits ())
+	    {
+	      struct symtab *symtab = COMPUNIT_FILETABS (cu);
 
-	    iterate_over_file_blocks (symtab, lookup_name, name_domain,
-				      callback);
+	      iterate_over_file_blocks (symtab, lookup_name, name_domain,
+					callback);
 
-	    if (include_inline)
-	      {
-		const struct block *block;
-		int i;
+	      if (include_inline)
+		{
+		  const struct block *block;
+		  int i;
 
-		for (i = FIRST_LOCAL_BLOCK;
-		     i < BLOCKVECTOR_NBLOCKS (SYMTAB_BLOCKVECTOR (symtab));
-		     i++)
-		  {
-		    block = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (symtab), i);
-		    state->language->la_iterate_over_symbols
-		      (block, lookup_name, name_domain,
-		       [&] (block_symbol *bsym)
-		       {
-			 /* Restrict calls to CALLBACK to symbols
-			    representing inline symbols only.  */
-			 if (SYMBOL_INLINED (bsym->symbol))
-			   return callback (bsym);
-			 return true;
-		       });
-		  }
-	      }
-	  }
-      }
-  }
+		  for (i = FIRST_LOCAL_BLOCK;
+		       i < BLOCKVECTOR_NBLOCKS (SYMTAB_BLOCKVECTOR (symtab));
+		       i++)
+		    {
+		      block = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (symtab), i);
+		      state->language->la_iterate_over_symbols
+			(block, lookup_name, name_domain,
+			 [&] (block_symbol *bsym)
+			 {
+			   /* Restrict calls to CALLBACK to symbols
+			      representing inline symbols only.  */
+			   if (SYMBOL_INLINED (bsym->symbol))
+			     return callback (bsym);
+			   return true;
+			 });
+		    }
+		}
+	    }
+	}
+    }
 }
 
 /* Returns the block to be used for symbol searches from
@@ -3787,9 +3785,7 @@ collect_symtabs_from_filename (const char *file,
   /* Find that file's data.  */
   if (search_pspace == NULL)
     {
-      struct program_space *pspace;
-
-      ALL_PSPACES (pspace)
+      for (struct program_space *pspace : program_spaces)
         {
 	  if (pspace->executing_startup)
 	    continue;
@@ -4335,29 +4331,27 @@ search_minsyms_for_name (struct collect_info *info,
 
   if (symtab == NULL)
     {
-      struct program_space *pspace;
-
-      ALL_PSPACES (pspace)
-      {
-	if (search_pspace != NULL && search_pspace != pspace)
-	  continue;
-	if (pspace->executing_startup)
-	  continue;
+      for (struct program_space *pspace : program_spaces)
+	{
+	  if (search_pspace != NULL && search_pspace != pspace)
+	    continue;
+	  if (pspace->executing_startup)
+	    continue;
 
-	set_current_program_space (pspace);
+	  set_current_program_space (pspace);
 
-	for (objfile *objfile : current_program_space->objfiles ())
-	  {
-	    iterate_over_minimal_symbols (objfile, name,
-					  [&] (struct minimal_symbol *msym)
-					  {
-					    add_minsym (msym, objfile, nullptr,
-							info->state->list_mode,
-							&minsyms);
-					    return false;
-					  });
-	  }
-      }
+	  for (objfile *objfile : current_program_space->objfiles ())
+	    {
+	      iterate_over_minimal_symbols (objfile, name,
+					    [&] (struct minimal_symbol *msym)
+					    {
+					      add_minsym (msym, objfile, nullptr,
+							  info->state->list_mode,
+							  &minsyms);
+					      return false;
+					    });
+	    }
+	}
     }
   else
     {
diff --git a/gdb/probe.c b/gdb/probe.c
index a21df73d0ec..dca02f0780e 100644
--- a/gdb/probe.c
+++ b/gdb/probe.c
@@ -185,9 +185,7 @@ parse_probes (const struct event_location *location,
     }
   else
     {
-      struct program_space *pspace;
-
-      ALL_PSPACES (pspace)
+      for (struct program_space *pspace : program_spaces)
 	parse_probes_in_pspace (spops, pspace, objfile_namestr,
 				provider, name, &result);
     }
diff --git a/gdb/progspace.c b/gdb/progspace.c
index 252b62e02d7..a0b14a6d2eb 100644
--- a/gdb/progspace.c
+++ b/gdb/progspace.c
@@ -32,7 +32,7 @@
 int last_program_space_num = 0;
 
 /* The head of the program spaces list.  */
-struct program_space *program_spaces;
+std::vector<struct program_space *> program_spaces;
 
 /* Pointer to the current program space.  */
 struct program_space *current_program_space;
@@ -80,7 +80,7 @@ maybe_new_address_space (void)
   if (shared_aspace)
     {
       /* Just return the first in the list.  */
-      return program_spaces->aspace;
+      return program_spaces[0]->aspace;
     }
 
   return new_address_space ();
@@ -109,44 +109,17 @@ init_address_spaces (void)
 
 \f
 
-/* Add a program space from the program spaces list.  */
-
-static void
-add_program_space (program_space *pspace)
-{
-  if (program_spaces == NULL)
-    program_spaces = pspace;
-  else
-    {
-      program_space *last;
-
-      for (last = program_spaces; last->next != NULL; last = last->next)
-	;
-      last->next = pspace;
-    }
-}
-
 /* Remove a program space from the program spaces list.  */
 
 static void
 remove_program_space (program_space *pspace)
 {
-  program_space *ss, **ss_link;
   gdb_assert (pspace != NULL);
 
-  ss = program_spaces;
-  ss_link = &program_spaces;
-  while (ss != NULL)
-    {
-      if (ss == pspace)
-	{
-	  *ss_link = ss->next;
-	  return;
-	}
-
-      ss_link = &ss->next;
-      ss = *ss_link;
-    }
+  auto iter = std::find (program_spaces.begin (), program_spaces.end (),
+			 pspace);
+  gdb_assert (iter != program_spaces.end ());
+  program_spaces.erase (iter);
 }
 
 /* See progspace.h.  */
@@ -157,7 +130,7 @@ program_space::program_space (address_space *aspace_)
 {
   program_space_alloc_data (this);
 
-  add_program_space (this);
+  program_spaces.push_back (this);
 }
 
 /* See progspace.h.  */
@@ -301,11 +274,10 @@ program_space_empty_p (struct program_space *pspace)
 static void
 print_program_space (struct ui_out *uiout, int requested)
 {
-  struct program_space *pspace;
   int count = 0;
 
   /* Compute number of pspaces we will print.  */
-  ALL_PSPACES (pspace)
+  for (struct program_space *pspace : program_spaces)
     {
       if (requested != -1 && pspace->num != requested)
 	continue;
@@ -322,7 +294,7 @@ print_program_space (struct ui_out *uiout, int requested)
   uiout->table_header (17, ui_left, "exec", "Executable");
   uiout->table_body ();
 
-  ALL_PSPACES (pspace)
+  for (struct program_space *pspace : program_spaces)
     {
       struct inferior *inf;
       int printed_header;
@@ -375,9 +347,7 @@ print_program_space (struct ui_out *uiout, int requested)
 static int
 valid_program_space_id (int num)
 {
-  struct program_space *pspace;
-
-  ALL_PSPACES (pspace)
+  for (struct program_space *pspace : program_spaces)
     if (pspace->num == num)
       return 1;
 
@@ -403,20 +373,6 @@ maintenance_info_program_spaces_command (const char *args, int from_tty)
   print_program_space (current_uiout, requested);
 }
 
-/* Simply returns the count of program spaces.  */
-
-int
-number_of_program_spaces (void)
-{
-  struct program_space *pspace;
-  int count = 0;
-
-  ALL_PSPACES (pspace)
-    count++;
-
-  return count;
-}
-
 /* Update all program spaces matching to address spaces.  The user may
    have created several program spaces, and loaded executables into
    them before connecting to the target interface that will create the
@@ -432,7 +388,6 @@ void
 update_address_spaces (void)
 {
   int shared_aspace = gdbarch_has_shared_address_space (target_gdbarch ());
-  struct program_space *pspace;
   struct inferior *inf;
 
   init_address_spaces ();
@@ -442,11 +397,11 @@ update_address_spaces (void)
       struct address_space *aspace = new_address_space ();
 
       free_address_space (current_program_space->aspace);
-      ALL_PSPACES (pspace)
+      for (struct program_space *pspace : program_spaces)
 	pspace->aspace = aspace;
     }
   else
-    ALL_PSPACES (pspace)
+    for (struct program_space *pspace : program_spaces)
       {
 	free_address_space (pspace->aspace);
 	pspace->aspace = new_address_space ();
diff --git a/gdb/progspace.h b/gdb/progspace.h
index 0e32224f02d..099b4dc0b3a 100644
--- a/gdb/progspace.h
+++ b/gdb/progspace.h
@@ -28,6 +28,7 @@
 #include "gdbsupport/next-iterator.h"
 #include "gdbsupport/safe-iterator.h"
 #include <list>
+#include <vector>
 
 struct target_ops;
 struct bfd;
@@ -272,9 +273,6 @@ struct program_space
   next_adapter<struct so_list> solibs () const;
 
 
-  /* Pointer to next in linked list.  */
-  struct program_space *next = NULL;
-
   /* Unique ID number.  */
   int num = 0;
 
@@ -369,17 +367,11 @@ struct address_space
 #define current_target_sections (&current_program_space->target_sections)
 
 /* The list of all program spaces.  There's always at least one.  */
-extern struct program_space *program_spaces;
+extern std::vector<struct program_space *>program_spaces;
 
 /* The current program space.  This is always non-null.  */
 extern struct program_space *current_program_space;
 
-#define ALL_PSPACES(pspace) \
-  for ((pspace) = program_spaces; (pspace) != NULL; (pspace) = (pspace)->next)
-
-/* Returns the number of program spaces listed.  */
-extern int number_of_program_spaces (void);
-
 /* Returns true iff there's no inferior bound to PSPACE.  */
 extern int program_space_empty_p (struct program_space *pspace);
 
diff --git a/gdb/psymtab.c b/gdb/psymtab.c
index b156aa0e228..e0f4f425aeb 100644
--- a/gdb/psymtab.c
+++ b/gdb/psymtab.c
@@ -1991,12 +1991,10 @@ maintenance_print_psymbols (const char *args, int from_tty)
 static void
 maintenance_info_psymtabs (const char *regexp, int from_tty)
 {
-  struct program_space *pspace;
-
   if (regexp)
     re_comp (regexp);
 
-  ALL_PSPACES (pspace)
+  for (struct program_space *pspace : program_spaces)
     for (objfile *objfile : pspace->objfiles ())
       {
 	struct gdbarch *gdbarch = objfile->arch ();
diff --git a/gdb/python/python.c b/gdb/python/python.c
index d65cca403be..c4cb011c71c 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -1350,19 +1350,17 @@ gdbpy_print_stack_or_quit ()
 static PyObject *
 gdbpy_progspaces (PyObject *unused1, PyObject *unused2)
 {
-  struct program_space *ps;
-
   gdbpy_ref<> list (PyList_New (0));
   if (list == NULL)
     return NULL;
 
-  ALL_PSPACES (ps)
-  {
-    gdbpy_ref<> item = pspace_to_pspace_object (ps);
+  for (struct program_space *ps : program_spaces)
+    {
+      gdbpy_ref<> item = pspace_to_pspace_object (ps);
 
-    if (item == NULL || PyList_Append (list.get (), item.get ()) == -1)
-      return NULL;
-  }
+      if (item == NULL || PyList_Append (list.get (), item.get ()) == -1)
+	return NULL;
+    }
 
   return list.release ();
 }
diff --git a/gdb/source.c b/gdb/source.c
index 7d22bbb5db3..b94c6af487d 100644
--- a/gdb/source.c
+++ b/gdb/source.c
@@ -421,9 +421,7 @@ forget_cached_source_info_for_objfile (struct objfile *objfile)
 void
 forget_cached_source_info (void)
 {
-  struct program_space *pspace;
-
-  ALL_PSPACES (pspace)
+  for (struct program_space *pspace : program_spaces)
     for (objfile *objfile : pspace->objfiles ())
       {
 	forget_cached_source_info_for_objfile (objfile);
diff --git a/gdb/symfile-debug.c b/gdb/symfile-debug.c
index 75e6f2d0d89..203609c326b 100644
--- a/gdb/symfile-debug.c
+++ b/gdb/symfile-debug.c
@@ -621,9 +621,7 @@ objfile_set_sym_fns (struct objfile *objfile, const struct sym_fns *sf)
 static void
 set_debug_symfile (const char *args, int from_tty, struct cmd_list_element *c)
 {
-  struct program_space *pspace;
-
-  ALL_PSPACES (pspace)
+  for (struct program_space *pspace : program_spaces)
     for (objfile *objfile : pspace->objfiles ())
       {
 	if (debug_symfile)
diff --git a/gdb/symmisc.c b/gdb/symmisc.c
index f45364a8832..a00009fc066 100644
--- a/gdb/symmisc.c
+++ b/gdb/symmisc.c
@@ -61,9 +61,7 @@ static void print_symbol (struct gdbarch *gdbarch, struct symbol *symbol,
 void
 print_symbol_bcache_statistics (void)
 {
-  struct program_space *pspace;
-
-  ALL_PSPACES (pspace)
+  for (struct program_space *pspace : program_spaces)
     for (objfile *objfile : pspace->objfiles ())
       {
 	QUIT;
@@ -78,64 +76,63 @@ print_symbol_bcache_statistics (void)
 void
 print_objfile_statistics (void)
 {
-  struct program_space *pspace;
   int i, linetables, blockvectors;
 
-  ALL_PSPACES (pspace)
-  for (objfile *objfile : pspace->objfiles ())
-    {
-      QUIT;
-      printf_filtered (_("Statistics for '%s':\n"), objfile_name (objfile));
-      if (OBJSTAT (objfile, n_stabs) > 0)
-	printf_filtered (_("  Number of \"stab\" symbols read: %d\n"),
-			 OBJSTAT (objfile, n_stabs));
-      if (objfile->per_bfd->n_minsyms > 0)
-	printf_filtered (_("  Number of \"minimal\" symbols read: %d\n"),
-			 objfile->per_bfd->n_minsyms);
-      if (OBJSTAT (objfile, n_psyms) > 0)
-	printf_filtered (_("  Number of \"partial\" symbols read: %d\n"),
-			 OBJSTAT (objfile, n_psyms));
-      if (OBJSTAT (objfile, n_syms) > 0)
-	printf_filtered (_("  Number of \"full\" symbols read: %d\n"),
-			 OBJSTAT (objfile, n_syms));
-      if (OBJSTAT (objfile, n_types) > 0)
-	printf_filtered (_("  Number of \"types\" defined: %d\n"),
-			 OBJSTAT (objfile, n_types));
-      if (objfile->sf)
-	objfile->sf->qf->print_stats (objfile);
-      i = linetables = 0;
-      for (compunit_symtab *cu : objfile->compunits ())
-	{
-	  for (symtab *s : compunit_filetabs (cu))
-	    {
-	      i++;
-	      if (SYMTAB_LINETABLE (s) != NULL)
-		linetables++;
-	    }
-	}
-      blockvectors = std::distance (objfile->compunits ().begin (),
-				    objfile->compunits ().end ());
-      printf_filtered (_("  Number of symbol tables: %d\n"), i);
-      printf_filtered (_("  Number of symbol tables with line tables: %d\n"),
-		       linetables);
-      printf_filtered (_("  Number of symbol tables with blockvectors: %d\n"),
-		       blockvectors);
-
-      if (OBJSTAT (objfile, sz_strtab) > 0)
-	printf_filtered (_("  Space used by string tables: %d\n"),
-			 OBJSTAT (objfile, sz_strtab));
-      printf_filtered (_("  Total memory used for objfile obstack: %s\n"),
-		       pulongest (obstack_memory_used (&objfile
-						       ->objfile_obstack)));
-      printf_filtered (_("  Total memory used for BFD obstack: %s\n"),
-		       pulongest (obstack_memory_used (&objfile->per_bfd
-						       ->storage_obstack)));
-      printf_filtered
-	(_("  Total memory used for psymbol cache: %d\n"),
-	 objfile->partial_symtabs->psymbol_cache.memory_used ());
-      printf_filtered (_("  Total memory used for string cache: %d\n"),
-		       objfile->per_bfd->string_cache.memory_used ());
-    }
+  for (struct program_space *pspace : program_spaces)
+    for (objfile *objfile : pspace->objfiles ())
+      {
+	QUIT;
+	printf_filtered (_("Statistics for '%s':\n"), objfile_name (objfile));
+	if (OBJSTAT (objfile, n_stabs) > 0)
+	  printf_filtered (_("  Number of \"stab\" symbols read: %d\n"),
+			   OBJSTAT (objfile, n_stabs));
+	if (objfile->per_bfd->n_minsyms > 0)
+	  printf_filtered (_("  Number of \"minimal\" symbols read: %d\n"),
+			   objfile->per_bfd->n_minsyms);
+	if (OBJSTAT (objfile, n_psyms) > 0)
+	  printf_filtered (_("  Number of \"partial\" symbols read: %d\n"),
+			   OBJSTAT (objfile, n_psyms));
+	if (OBJSTAT (objfile, n_syms) > 0)
+	  printf_filtered (_("  Number of \"full\" symbols read: %d\n"),
+			   OBJSTAT (objfile, n_syms));
+	if (OBJSTAT (objfile, n_types) > 0)
+	  printf_filtered (_("  Number of \"types\" defined: %d\n"),
+			   OBJSTAT (objfile, n_types));
+	if (objfile->sf)
+	  objfile->sf->qf->print_stats (objfile);
+	i = linetables = 0;
+	for (compunit_symtab *cu : objfile->compunits ())
+	  {
+	    for (symtab *s : compunit_filetabs (cu))
+	      {
+		i++;
+		if (SYMTAB_LINETABLE (s) != NULL)
+		  linetables++;
+	      }
+	  }
+	blockvectors = std::distance (objfile->compunits ().begin (),
+				      objfile->compunits ().end ());
+	printf_filtered (_("  Number of symbol tables: %d\n"), i);
+	printf_filtered (_("  Number of symbol tables with line tables: %d\n"),
+			 linetables);
+	printf_filtered (_("  Number of symbol tables with blockvectors: %d\n"),
+			 blockvectors);
+
+	if (OBJSTAT (objfile, sz_strtab) > 0)
+	  printf_filtered (_("  Space used by string tables: %d\n"),
+			   OBJSTAT (objfile, sz_strtab));
+	printf_filtered (_("  Total memory used for objfile obstack: %s\n"),
+			 pulongest (obstack_memory_used (&objfile
+							 ->objfile_obstack)));
+	printf_filtered (_("  Total memory used for BFD obstack: %s\n"),
+			 pulongest (obstack_memory_used (&objfile->per_bfd
+							 ->storage_obstack)));
+	printf_filtered
+	  (_("  Total memory used for psymbol cache: %d\n"),
+	   objfile->partial_symtabs->psymbol_cache.memory_used ());
+	printf_filtered (_("  Total memory used for string cache: %d\n"),
+			 objfile->per_bfd->string_cache.memory_used ());
+      }
 }
 
 static void
@@ -762,14 +759,12 @@ maintenance_print_msymbols (const char *args, int from_tty)
 static void
 maintenance_print_objfiles (const char *regexp, int from_tty)
 {
-  struct program_space *pspace;
-
   dont_repeat ();
 
   if (regexp)
     re_comp (regexp);
 
-  ALL_PSPACES (pspace)
+  for (struct program_space *pspace : program_spaces)
     for (objfile *objfile : pspace->objfiles ())
       {
 	QUIT;
@@ -784,14 +779,12 @@ maintenance_print_objfiles (const char *regexp, int from_tty)
 static void
 maintenance_info_symtabs (const char *regexp, int from_tty)
 {
-  struct program_space *pspace;
-
   dont_repeat ();
 
   if (regexp)
     re_comp (regexp);
 
-  ALL_PSPACES (pspace)
+  for (struct program_space *pspace : program_spaces)
     for (objfile *objfile : pspace->objfiles ())
       {
 	/* We don't want to print anything for this objfile until we
@@ -896,9 +889,7 @@ maintenance_info_symtabs (const char *regexp, int from_tty)
 static void
 maintenance_check_symtabs (const char *ignore, int from_tty)
 {
-  struct program_space *pspace;
-
-  ALL_PSPACES (pspace)
+  for (struct program_space *pspace : program_spaces)
     for (objfile *objfile : pspace->objfiles ())
       {
 	/* We don't want to print anything for this objfile until we
@@ -944,7 +935,6 @@ maintenance_check_symtabs (const char *ignore, int from_tty)
 static void
 maintenance_expand_symtabs (const char *args, int from_tty)
 {
-  struct program_space *pspace;
   char *regexp = NULL;
 
   /* We use buildargv here so that we handle spaces in the regexp
@@ -964,7 +954,7 @@ maintenance_expand_symtabs (const char *args, int from_tty)
   if (regexp)
     re_comp (regexp);
 
-  ALL_PSPACES (pspace)
+  for (struct program_space *pspace : program_spaces)
     for (objfile *objfile : pspace->objfiles ())
       {
 	if (objfile->sf)
@@ -1065,14 +1055,12 @@ maintenance_print_one_line_table (struct symtab *symtab, void *data)
 static void
 maintenance_info_line_tables (const char *regexp, int from_tty)
 {
-  struct program_space *pspace;
-
   dont_repeat ();
 
   if (regexp != NULL)
     re_comp (regexp);
 
-  ALL_PSPACES (pspace)
+  for (struct program_space *pspace : program_spaces)
     for (objfile *objfile : pspace->objfiles ())
       {
 	for (compunit_symtab *cust : objfile->compunits ())
diff --git a/gdb/symtab.c b/gdb/symtab.c
index dc079efbc27..49d9fe3405d 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -1292,9 +1292,7 @@ get_symbol_cache (struct program_space *pspace)
 static void
 set_symbol_cache_size (unsigned int new_size)
 {
-  struct program_space *pspace;
-
-  ALL_PSPACES (pspace)
+  for (struct program_space *pspace : program_spaces)
     {
       struct symbol_cache *cache = symbol_cache_key.get (pspace);
 
@@ -1542,9 +1540,7 @@ symbol_cache_dump (const struct symbol_cache *cache)
 static void
 maintenance_print_symbol_cache (const char *args, int from_tty)
 {
-  struct program_space *pspace;
-
-  ALL_PSPACES (pspace)
+  for (struct program_space *pspace : program_spaces)
     {
       struct symbol_cache *cache;
 
@@ -1568,9 +1564,7 @@ maintenance_print_symbol_cache (const char *args, int from_tty)
 static void
 maintenance_flush_symbol_cache (const char *args, int from_tty)
 {
-  struct program_space *pspace;
-
-  ALL_PSPACES (pspace)
+  for (struct program_space *pspace : program_spaces)
     {
       symbol_cache_flush (pspace);
     }
@@ -1613,9 +1607,7 @@ symbol_cache_stats (struct symbol_cache *cache)
 static void
 maintenance_print_symbol_cache_statistics (const char *args, int from_tty)
 {
-  struct program_space *pspace;
-
-  ALL_PSPACES (pspace)
+  for (struct program_space *pspace : program_spaces)
     {
       struct symbol_cache *cache;
 
-- 
2.17.2


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 4/4] More C++-ification for struct display
  2020-04-19 14:18 Tom Tromey
                   ` (2 preceding siblings ...)
  2020-04-19 14:18 ` [PATCH 3/4] Remove ALL_PSPACES Tom Tromey
@ 2020-04-19 14:18 ` Tom Tromey
  2020-05-08 20:25 ` (unknown) Tom Tromey
  4 siblings, 0 replies; 7+ messages in thread
From: Tom Tromey @ 2020-04-19 14:18 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This changes displays to have a constructor, use bool and std::string,
and to be stored using std::vector.  The ALL_DISPLAYS and
ALL_DISPLAYS_SAFE macros are removed.  While internal iteration is
still done via map_display_numbers, this is updated to use a
function_view.  These changes simplify the code somewhat; for example,
free_display can now be removed in favor of ordinary destruction.

gdb/ChangeLog
2020-04-18  Tom Tromey  <tom@tromey.com>

	* printcmd.c (struct display) <next>: Remove.
	<display>: New constructor.
	<exp_string>: Now a std::string.
	<enabled_p>: Now a bool.
	(display_number): Move definition earlier.
	(displays): Rename from display_chain.  Now a std::vector.
	(ALL_DISPLAYS, ALL_DISPLAYS_SAFE): Remove.
	(display_command): Update.
	(do_one_display, disable_display)
	(enable_disable_display_command, do_enable_disable_display):
	Update.
	(free_display): Remove.
	(clear_displays): Rewrite.
	(delete_display): Update.
	(map_display_numbers): Use function_view.  Remove "data"
	parameter.  Update.
	(do_delete_display): Remove.
	(undisplay_command): Update.
	(do_one_display, do_displays, disable_display)
	(info_display_command): Update.
	(do_enable_disable_display): Remove.
	(enable_disable_display_command)
	(clear_dangling_display_expressions): Update.
---
 gdb/ChangeLog  |  26 +++++++
 gdb/printcmd.c | 193 +++++++++++++++++--------------------------------
 2 files changed, 93 insertions(+), 126 deletions(-)

diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index de6d3d43bb4..00320d20898 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -116,13 +116,27 @@ show_print_symbol_filename (struct ui_file *file, int from_tty,
 
 static int current_display_number;
 
+/* Last allocated display number.  */
+
+static int display_number;
+
 struct display
   {
-    /* Chain link to next auto-display item.  */
-    struct display *next;
+    display (const char *exp_string_, expression_up &&exp_,
+	     const struct format_data &format_, struct program_space *pspace_,
+	     const struct block *block_)
+      : exp_string (exp_string_),
+	exp (std::move (exp_)),
+	number (++display_number),
+	format (format_),
+	pspace (pspace_),
+	block (block_),
+	enabled_p (true)
+    {
+    }
 
     /* The expression as the user typed it.  */
-    char *exp_string;
+    std::string exp_string;
 
     /* Expression to be evaluated and displayed.  */
     expression_up exp;
@@ -140,27 +154,13 @@ struct display
     const struct block *block;
 
     /* Status of this display (enabled or disabled).  */
-    int enabled_p;
+    bool enabled_p;
   };
 
-/* Chain of expressions whose values should be displayed
-   automatically each time the program stops.  */
-
-static struct display *display_chain;
+/* Expressions whose values should be displayed automatically each
+   time the program stops.  */
 
-static int display_number;
-
-/* Walk the following statement or block through all displays.
-   ALL_DISPLAYS_SAFE does so even if the statement deletes the current
-   display.  */
-
-#define ALL_DISPLAYS(B)				\
-  for (B = display_chain; B; B = B->next)
-
-#define ALL_DISPLAYS_SAFE(B,TMP)		\
-  for (B = display_chain;			\
-       B ? (TMP = B->next, 1): 0;		\
-       B = TMP)
+static std::vector<std::unique_ptr<struct display>> all_displays;
 
 /* Prototypes for local functions.  */
 
@@ -1763,27 +1763,9 @@ display_command (const char *arg, int from_tty)
   innermost_block_tracker tracker;
   expression_up expr = parse_expression (exp, &tracker);
 
-  newobj = new display ();
-
-  newobj->exp_string = xstrdup (exp);
-  newobj->exp = std::move (expr);
-  newobj->block = tracker.block ();
-  newobj->pspace = current_program_space;
-  newobj->number = ++display_number;
-  newobj->format = fmt;
-  newobj->enabled_p = 1;
-  newobj->next = NULL;
-
-  if (display_chain == NULL)
-    display_chain = newobj;
-  else
-    {
-      struct display *last;
-
-      for (last = display_chain; last->next != NULL; last = last->next)
-	;
-      last->next = newobj;
-    }
+  newobj = new display (exp, std::move (expr), fmt,
+			current_program_space, tracker.block ());
+  all_displays.emplace_back (newobj);
 
   if (from_tty)
     do_one_display (newobj);
@@ -1791,26 +1773,13 @@ display_command (const char *arg, int from_tty)
   dont_repeat ();
 }
 
-static void
-free_display (struct display *d)
-{
-  xfree (d->exp_string);
-  delete d;
-}
-
 /* Clear out the display_chain.  Done when new symtabs are loaded,
    since this invalidates the types stored in many expressions.  */
 
 void
-clear_displays (void)
+clear_displays ()
 {
-  struct display *d;
-
-  while ((d = display_chain) != NULL)
-    {
-      display_chain = d->next;
-      free_display (d);
-    }
+  all_displays.clear ();
 }
 
 /* Delete the auto-display DISPLAY.  */
@@ -1818,21 +1787,16 @@ clear_displays (void)
 static void
 delete_display (struct display *display)
 {
-  struct display *d;
-
   gdb_assert (display != NULL);
 
-  if (display_chain == display)
-    display_chain = display->next;
-
-  ALL_DISPLAYS (d)
-    if (d->next == display)
-      {
-	d->next = display->next;
-	break;
-      }
-
-  free_display (display);
+  auto iter = std::find_if (all_displays.begin (),
+			    all_displays.end (),
+			    [=] (const std::unique_ptr<struct display> &item)
+			    {
+			      return item.get () == display;
+			    });
+  gdb_assert (iter != all_displays.end ());
+  all_displays.erase (iter);
 }
 
 /* Call FUNCTION on each of the displays whose numbers are given in
@@ -1840,9 +1804,7 @@ delete_display (struct display *display)
 
 static void
 map_display_numbers (const char *args,
-		     void (*function) (struct display *,
-				       void *),
-		     void *data)
+		     gdb::function_view<void (struct display *)> function)
 {
   int num;
 
@@ -1860,27 +1822,20 @@ map_display_numbers (const char *args,
 	warning (_("bad display number at or near '%s'"), p);
       else
 	{
-	  struct display *d, *tmp;
-
-	  ALL_DISPLAYS_SAFE (d, tmp)
-	    if (d->number == num)
-	      break;
-	  if (d == NULL)
+	  auto iter = std::find_if (all_displays.begin (),
+				    all_displays.end (),
+				    [=] (const std::unique_ptr<display> &item)
+				    {
+				      return item->number == num;
+				    });
+	  if (iter == all_displays.end ())
 	    printf_unfiltered (_("No display number %d.\n"), num);
 	  else
-	    function (d, data);
+	    function (iter->get ());
 	}
     }
 }
 
-/* Callback for map_display_numbers, that deletes a display.  */
-
-static void
-do_delete_display (struct display *d, void *data)
-{
-  delete_display (d);
-}
-
 /* "undisplay" command.  */
 
 static void
@@ -1894,7 +1849,7 @@ undisplay_command (const char *args, int from_tty)
       return;
     }
 
-  map_display_numbers (args, do_delete_display, NULL);
+  map_display_numbers (args, delete_display);
   dont_repeat ();
 }
 
@@ -1907,7 +1862,7 @@ do_one_display (struct display *d)
 {
   int within_current_scope;
 
-  if (d->enabled_p == 0)
+  if (!d->enabled_p)
     return;
 
   /* The expression carries the architecture that was used at parse time.
@@ -1929,15 +1884,15 @@ do_one_display (struct display *d)
       try
 	{
 	  innermost_block_tracker tracker;
-	  d->exp = parse_expression (d->exp_string, &tracker);
+	  d->exp = parse_expression (d->exp_string.c_str (), &tracker);
 	  d->block = tracker.block ();
 	}
       catch (const gdb_exception &ex)
 	{
 	  /* Can't re-parse the expression.  Disable this display item.  */
-	  d->enabled_p = 0;
+	  d->enabled_p = false;
 	  warning (_("Unable to display \"%s\": %s"),
-		   d->exp_string, ex.what ());
+		   d->exp_string.c_str (), ex.what ());
 	  return;
 	}
     }
@@ -1977,7 +1932,7 @@ do_one_display (struct display *d)
 
       annotate_display_expression ();
 
-      puts_filtered (d->exp_string);
+      puts_filtered (d->exp_string.c_str ());
       annotate_display_expression_end ();
 
       if (d->format.count != 1 || d->format.format == 'i')
@@ -2016,7 +1971,7 @@ do_one_display (struct display *d)
 
       annotate_display_expression ();
 
-      puts_filtered (d->exp_string);
+      puts_filtered (d->exp_string.c_str ());
       annotate_display_expression_end ();
 
       printf_filtered (" = ");
@@ -2053,10 +2008,8 @@ do_one_display (struct display *d)
 void
 do_displays (void)
 {
-  struct display *d;
-
-  for (d = display_chain; d; d = d->next)
-    do_one_display (d);
+  for (auto &d : all_displays)
+    do_one_display (d.get ());
 }
 
 /* Delete the auto-display which we were in the process of displaying.
@@ -2065,12 +2018,10 @@ do_displays (void)
 void
 disable_display (int num)
 {
-  struct display *d;
-
-  for (d = display_chain; d; d = d->next)
+  for (auto &d : all_displays)
     if (d->number == num)
       {
-	d->enabled_p = 0;
+	d->enabled_p = false;
 	return;
       }
   printf_unfiltered (_("No display number %d.\n"), num);
@@ -2093,15 +2044,13 @@ disable_current_display (void)
 static void
 info_display_command (const char *ignore, int from_tty)
 {
-  struct display *d;
-
-  if (!display_chain)
+  if (all_displays.empty ())
     printf_unfiltered (_("There are no auto-display expressions now.\n"));
   else
     printf_filtered (_("Auto-display expressions now in effect:\n\
 Num Enb Expression\n"));
 
-  for (d = display_chain; d; d = d->next)
+  for (auto &d : all_displays)
     {
       printf_filtered ("%d:   %c  ", d->number, "ny"[(int) d->enabled_p]);
       if (d->format.size)
@@ -2109,38 +2058,31 @@ Num Enb Expression\n"));
 			 d->format.format);
       else if (d->format.format)
 	printf_filtered ("/%c ", d->format.format);
-      puts_filtered (d->exp_string);
+      puts_filtered (d->exp_string.c_str ());
       if (d->block && !contained_in (get_selected_block (0), d->block, true))
 	printf_filtered (_(" (cannot be evaluated in the current context)"));
       printf_filtered ("\n");
     }
 }
 
-/* Callback fo map_display_numbers, that enables or disables the
-   passed in display D.  */
-
-static void
-do_enable_disable_display (struct display *d, void *data)
-{
-  d->enabled_p = *(int *) data;
-}
-
 /* Implementation of both the "disable display" and "enable display"
    commands.  ENABLE decides what to do.  */
 
 static void
-enable_disable_display_command (const char *args, int from_tty, int enable)
+enable_disable_display_command (const char *args, int from_tty, bool enable)
 {
   if (args == NULL)
     {
-      struct display *d;
-
-      ALL_DISPLAYS (d)
+      for (auto &d : all_displays)
 	d->enabled_p = enable;
       return;
     }
 
-  map_display_numbers (args, do_enable_disable_display, &enable);
+  map_display_numbers (args,
+		       [=] (struct display *d)
+		       {
+			 d->enabled_p = enable;
+		       });
 }
 
 /* The "enable display" command.  */
@@ -2148,7 +2090,7 @@ enable_disable_display_command (const char *args, int from_tty, int enable)
 static void
 enable_display_command (const char *args, int from_tty)
 {
-  enable_disable_display_command (args, from_tty, 1);
+  enable_disable_display_command (args, from_tty, true);
 }
 
 /* The "disable display" command.  */
@@ -2156,7 +2098,7 @@ enable_display_command (const char *args, int from_tty)
 static void
 disable_display_command (const char *args, int from_tty)
 {
-  enable_disable_display_command (args, from_tty, 0);
+  enable_disable_display_command (args, from_tty, false);
 }
 
 /* display_chain items point to blocks and expressions.  Some expressions in
@@ -2170,7 +2112,6 @@ disable_display_command (const char *args, int from_tty)
 static void
 clear_dangling_display_expressions (struct objfile *objfile)
 {
-  struct display *d;
   struct program_space *pspace;
 
   /* With no symbol file we cannot have a block or expression from it.  */
@@ -2183,7 +2124,7 @@ clear_dangling_display_expressions (struct objfile *objfile)
       gdb_assert (objfile->pspace == pspace);
     }
 
-  for (d = display_chain; d != NULL; d = d->next)
+  for (auto &d : all_displays)
     {
       if (d->pspace != pspace)
 	continue;
-- 
2.17.2


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: (unknown)
  2020-04-19 14:18 Tom Tromey
                   ` (3 preceding siblings ...)
  2020-04-19 14:18 ` [PATCH 4/4] More C++-ification for struct display Tom Tromey
@ 2020-05-08 20:25 ` Tom Tromey
  4 siblings, 0 replies; 7+ messages in thread
From: Tom Tromey @ 2020-05-08 20:25 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

>>>>> "Tom" == Tom Tromey <tom@tromey.com> writes:

Tom> Eventually I'd like to remove all of the ALL_ iteration macros, and
Tom> also move gdb to use "external iterators" wherever possible.  I think
Tom> both the macros and the callback-style interal internal iterators are
Tom> harder to read.

Tom> This series removes a few of the ALL_ macros.

Tom> Regression tested by the buildbot.

I'm checking these in now.

Tom

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: (unknown)
  2023-11-21 15:27 Tom Tromey
@ 2023-11-29 23:28 ` Tom Tromey
  0 siblings, 0 replies; 7+ messages in thread
From: Tom Tromey @ 2023-11-29 23:28 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

>>>>> Tom Tromey <tom@tromey.com> writes:

> I realized that I never sent v2 of my series to convert more code to
> C++17.

> Here it is.  Compared to v1, this just adds a single patch at the end,
> to remove gdb_static_assert.

Since most of this was approved, and the last patch is pretty trivial, I
am going to check this in now.

Tom

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2023-11-29 23:27 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-19 14:18 Tom Tromey
2020-04-19 14:18 ` [PATCH 1/4] Remove ALL_EXTENSION_LANGUAGES and ALL_ENABLED_EXTENSION_LANGUAGES Tom Tromey
2020-04-19 14:18 ` [PATCH 2/4] Remove ALL_SO_LIBS and so_list_head Tom Tromey
2020-04-19 14:18 ` [PATCH 3/4] Remove ALL_PSPACES Tom Tromey
2020-04-19 14:18 ` [PATCH 4/4] More C++-ification for struct display Tom Tromey
2020-05-08 20:25 ` (unknown) Tom Tromey
2023-11-21 15:27 Tom Tromey
2023-11-29 23:28 ` (unknown) Tom Tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).