[3/4] Remove ALL_PSPACES

Message ID 20200419141805.24589-4-tom@tromey.com
State New
Headers show
Series
  • [1/4] Remove ALL_EXTENSION_LANGUAGES and ALL_ENABLED_EXTENSION_LANGUAGES
Related show

Commit Message

Tom Tromey April 19, 2020, 2:18 p.m.
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(-)

-- 
2.17.2

Patch

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)
 
 
 
-/* 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;