ODR warning for "enum string_repr_result"
[binutils-gdb.git] / gdb / inferior.h
index 253077733a8e1455207da5947eab220d30841c92..f6e26a32febab7aae163b2458237bc8fadce7db7 100644 (file)
@@ -1,7 +1,7 @@
 /* Variables that describe the inferior process running under GDB:
    Where it is, why it stopped, and how to step it.
 
-   Copyright (C) 1986-2015 Free Software Foundation, Inc.
+   Copyright (C) 1986-2022 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -21,6 +21,9 @@
 #if !defined (INFERIOR_H)
 #define INFERIOR_H 1
 
+#include <exception>
+#include <list>
+
 struct target_waitstatus;
 struct frame_info;
 struct ui_file;
@@ -30,6 +33,8 @@ struct regcache;
 struct ui_out;
 struct terminal_info;
 struct target_desc_info;
+struct inferior;
+struct thread_info;
 
 /* For bpstat.  */
 #include "breakpoint.h"
@@ -40,45 +45,93 @@ struct target_desc_info;
 /* For struct frame_id.  */
 #include "frame.h"
 
+/* For gdb_environ.  */
+#include "gdbsupport/environ.h"
+
 #include "progspace.h"
 #include "registry.h"
 
+#include "symfile-add-flags.h"
+#include "gdbsupport/refcounted-object.h"
+#include "gdbsupport/forward-scope-exit.h"
+#include "gdbsupport/gdb_unique_ptr.h"
+#include "gdbsupport/intrusive_list.h"
+
+#include "gdbsupport/common-inferior.h"
+#include "gdbthread.h"
+
+#include "process-stratum-target.h"
+#include "displaced-stepping.h"
+
+#include <unordered_map>
+
 struct infcall_suspend_state;
 struct infcall_control_state;
 
-extern struct infcall_suspend_state *save_infcall_suspend_state (void);
-extern struct infcall_control_state *save_infcall_control_state (void);
-
 extern void restore_infcall_suspend_state (struct infcall_suspend_state *);
 extern void restore_infcall_control_state (struct infcall_control_state *);
 
-extern struct cleanup *make_cleanup_restore_infcall_suspend_state
-                                           (struct infcall_suspend_state *);
-extern struct cleanup *make_cleanup_restore_infcall_control_state
-                                           (struct infcall_control_state *);
+/* A deleter for infcall_suspend_state that calls
+   restore_infcall_suspend_state.  */
+struct infcall_suspend_state_deleter
+{
+  void operator() (struct infcall_suspend_state *state) const
+  {
+    try
+      {
+       restore_infcall_suspend_state (state);
+      }
+    catch (const gdb_exception_error &e)
+      {
+       /* If we are restoring the inferior state due to an exception,
+          some error message will be printed.  So, only warn the user
+          when we cannot restore during normal execution.  */
+       bool unwinding;
+#if __cpp_lib_uncaught_exceptions
+       unwinding = std::uncaught_exceptions () > 0;
+#else
+       unwinding = std::uncaught_exception ();
+#endif
+       if (!unwinding)
+         warning (_("Failed to restore inferior state: %s"), e.what ());
+      }
+  }
+};
+
+/* A unique_ptr specialization for infcall_suspend_state.  */
+typedef std::unique_ptr<infcall_suspend_state, infcall_suspend_state_deleter>
+    infcall_suspend_state_up;
+
+extern infcall_suspend_state_up save_infcall_suspend_state ();
+
+/* A deleter for infcall_control_state that calls
+   restore_infcall_control_state.  */
+struct infcall_control_state_deleter
+{
+  void operator() (struct infcall_control_state *state) const
+  {
+    restore_infcall_control_state (state);
+  }
+};
+
+/* A unique_ptr specialization for infcall_control_state.  */
+typedef std::unique_ptr<infcall_control_state, infcall_control_state_deleter>
+    infcall_control_state_up;
+
+extern infcall_control_state_up save_infcall_control_state ();
 
 extern void discard_infcall_suspend_state (struct infcall_suspend_state *);
 extern void discard_infcall_control_state (struct infcall_control_state *);
 
-extern struct regcache *
+extern readonly_detached_regcache *
   get_infcall_suspend_state_regcache (struct infcall_suspend_state *);
 
-/* Save value of inferior_ptid so that it may be restored by
-   a later call to do_cleanups().  Returns the struct cleanup
-   pointer needed for later doing the cleanup.  */
-extern struct cleanup * save_inferior_ptid (void);
-
 extern void set_sigint_trap (void);
 
 extern void clear_sigint_trap (void);
 
-/* Set/get file name for default use for standard in/out in the inferior.  */
-
-extern void set_inferior_io_terminal (const char *terminal_name);
-extern const char *get_inferior_io_terminal (void);
-
 /* Collected pid, tid, etc. of the debugged inferior.  When there's
-   no inferior, ptid_get_pid (inferior_ptid) will be 0.  */
+   no inferior, inferior_ptid.pid () will be 0.  */
 
 extern ptid_t inferior_ptid;
 
@@ -116,57 +169,64 @@ extern void default_print_float_info (struct gdbarch *gdbarch,
 
 extern void child_terminal_info (struct target_ops *self, const char *, int);
 
-extern void term_info (char *, int);
-
 extern void child_terminal_ours (struct target_ops *self);
 
 extern void child_terminal_ours_for_output (struct target_ops *self);
 
 extern void child_terminal_inferior (struct target_ops *self);
 
+extern void child_terminal_save_inferior (struct target_ops *self);
+
 extern void child_terminal_init (struct target_ops *self);
 
 extern void child_terminal_init_with_pgrp (int pgrp);
 
-/* From fork-child.c */
-
-extern int fork_inferior (char *, char *, char **,
-                         void (*)(void),
-                         void (*)(int), void (*)(void), char *,
-                          void (*)(const char *,
-                                   char * const *, char * const *));
+extern void child_pass_ctrlc (struct target_ops *self);
 
+extern void child_interrupt (struct target_ops *self);
 
-extern void startup_inferior (int);
+/* From fork-child.c */
 
-extern char *construct_inferior_arguments (int, char **);
+/* Helper function to call STARTUP_INFERIOR with PID and NUM_TRAPS.
+   This function already calls set_executing.  Return the ptid_t from
+   STARTUP_INFERIOR.  */
+extern ptid_t gdb_startup_inferior (pid_t pid, int num_traps);
 
 /* From infcmd.c */
 
-extern void post_create_inferior (struct target_ops *, int);
+/* Initial inferior setup.  Determines the exec file is not yet known,
+   takes any necessary post-attaching actions, fetches the target
+   description and syncs the shared library list.  */
 
-extern void attach_command (char *, int);
+extern void setup_inferior (int from_tty);
 
-extern char *get_inferior_args (void);
+extern void post_create_inferior (int from_tty);
 
-extern void set_inferior_args (char *);
+extern void attach_command (const char *, int);
 
 extern void set_inferior_args_vector (int, char **);
 
-extern void registers_info (char *, int);
+extern void registers_info (const char *, int);
 
 extern void continue_1 (int all_threads);
 
-extern void interrupt_target_1 (int all_threads);
+extern void interrupt_target_1 (bool all_threads);
+
+using delete_longjmp_breakpoint_cleanup
+  = FORWARD_SCOPE_EXIT (delete_longjmp_breakpoint);
+
+extern void detach_command (const char *, int);
 
-extern void delete_longjmp_breakpoint_cleanup (void *arg);
+extern void notice_new_inferior (struct thread_info *, bool, int);
 
-extern void detach_command (char *, int);
+/* Return the value of the result of a function at the end of a 'finish'
+   command/BP.  If the result's value cannot be retrieved, return NULL.
 
-extern void notice_new_inferior (ptid_t, int, int);
+   FUNC_SYMBOL is the symbol of the function being returned from.  FUNCTION is
+   a value containing the address of the function.  */
 
-extern struct value *get_return_value (struct value *function,
-                                       struct type *value_type);
+extern struct value *get_return_value (struct symbol *func_symbol,
+                                      struct value *function);
 
 /* Prepare for execution command.  TARGET is the target that will run
    the command.  BACKGROUND determines whether this is a foreground
@@ -175,29 +235,6 @@ extern struct value *get_return_value (struct value *function,
 extern void prepare_execution_command (struct target_ops *target,
                                       int background);
 
-/* Whether to start up the debuggee under a shell.
-
-   If startup-with-shell is set, GDB's "run" will attempt to start up
-   the debuggee under a shell.
-
-   This is in order for argument-expansion to occur.  E.g.,
-
-   (gdb) run *
-
-   The "*" gets expanded by the shell into a list of files.
-
-   While this is a nice feature, it may be handy to bypass the shell
-   in some cases.  To disable this feature, do "set startup-with-shell
-   false".
-
-   The catch-exec traps expected during start-up will be one more if
-   the target is started up with a shell.  */
-extern int startup_with_shell;
-
-/* Address at which inferior stopped.  */
-
-extern CORE_ADDR stop_pc;
-
 /* Nonzero if stopped due to completion of a stack dummy routine.  */
 
 extern enum stop_stack_kind stop_stack_dummy;
@@ -207,16 +244,9 @@ extern enum stop_stack_kind stop_stack_dummy;
 
 extern int stopped_by_random_signal;
 
-/* STEP_OVER_ALL means step over all subroutine calls.
-   STEP_OVER_UNDEBUGGABLE means step over calls to undebuggable functions.
-   STEP_OVER_NONE means don't step over any subroutine calls.  */
-
-enum step_over_calls_kind
-  {
-    STEP_OVER_NONE,
-    STEP_OVER_ALL,
-    STEP_OVER_UNDEBUGGABLE
-  };
+/* Print notices on inferior events (attach, detach, etc.), set with
+   `set print inferior-events'.  */
+extern bool print_inferior_events;
 
 /* Anything but NO_STOP_QUIETLY means we expect a trap and the caller
    will handle it themselves.  STOP_QUIETLY is used when running in
@@ -256,13 +286,12 @@ enum stop_kind
 #define ON_STACK 1
 #define AT_ENTRY_POINT 4
 
-/* Number of traps that happen between exec'ing the shell to run an
-   inferior and when we finally get to the inferior code, not counting
-   the exec for the shell.  This is 1 on all supported
-   implementations.  */
-#define START_INFERIOR_TRAPS_EXPECTED  1
+/* Base class for target-specific inferior data.  */
 
-struct private_inferior;
+struct private_inferior
+{
+  virtual ~private_inferior () = 0;
+};
 
 /* Inferior process specific part of `struct infcall_control_state'.
 
@@ -270,19 +299,28 @@ struct private_inferior;
 
 struct inferior_control_state
 {
+  inferior_control_state ()
+    : stop_soon (NO_STOP_QUIETLY)
+  {
+  }
+
+  explicit inferior_control_state (enum stop_kind when)
+    : stop_soon (when)
+  {
+  }
+
   /* See the definition of stop_kind above.  */
   enum stop_kind stop_soon;
 };
 
-/* Inferior process specific part of `struct infcall_suspend_state'.
+/* Return a pointer to the current inferior.  */
+extern inferior *current_inferior ();
 
-   Inferior thread counterpart is `struct thread_suspend_state'.  */
+extern void set_current_inferior (inferior *);
 
-#if 0 /* Currently unused and empty structures are not valid C.  */
-struct inferior_suspend_state
-{
-};
-#endif
+/* Switch inferior (and program space) to INF, and switch to no thread
+   selected.  */
+extern void switch_to_inferior_no_thread (inferior *inf);
 
 /* GDB represents the state of each program execution with an object
    called an inferior.  An inferior typically corresponds to a process
@@ -291,111 +329,247 @@ struct inferior_suspend_state
    inferior, as does each attachment to an existing process.
    Inferiors have unique internal identifiers that are different from
    target process ids.  Each inferior may in turn have multiple
-   threads running in it.  */
-
-struct inferior
+   threads running in it.
+
+   Inferiors are intrusively refcounted objects.  Unlike thread
+   objects, being the user-selected inferior is considered a strong
+   reference and is thus accounted for in the inferior object's
+   refcount (see set_current_inferior).  When GDB needs to remember
+   the selected inferior to later restore it, GDB temporarily bumps
+   the inferior object's refcount, to prevent something deleting the
+   inferior object before reverting back (e.g., due to a
+   "remove-inferiors" command (see
+   scoped_restore_current_inferior).  All other inferior
+   references are considered weak references.  Inferiors are always
+   listed exactly once in the inferior list, so placing an inferior in
+   the inferior list is an implicit, not counted strong reference.  */
+
+class inferior : public refcounted_object,
+                public intrusive_list_node<inferior>
 {
-  /* Pointer to next inferior in singly-linked list of inferiors.  */
-  struct inferior *next;
+public:
+  explicit inferior (int pid);
+  ~inferior ();
+
+  /* Returns true if we can delete this inferior.  */
+  bool deletable () const { return refcount () == 0; }
+
+  /* Push T in this inferior's target stack.  */
+  void push_target (struct target_ops *t)
+  { m_target_stack.push (t); }
+
+  /* An overload that deletes the target on failure.  */
+  void push_target (target_ops_up &&t)
+  {
+    m_target_stack.push (t.get ());
+    t.release ();
+  }
+
+  /* Unpush T from this inferior's target stack.  */
+  int unpush_target (struct target_ops *t);
+
+  /* Returns true if T is pushed in this inferior's target stack.  */
+  bool target_is_pushed (target_ops *t)
+  { return m_target_stack.is_pushed (t); }
+
+  /* Find the target beneath T in this inferior's target stack.  */
+  target_ops *find_target_beneath (const target_ops *t)
+  { return m_target_stack.find_beneath (t); }
+
+  /* Return the target at the top of this inferior's target stack.  */
+  target_ops *top_target ()
+  { return m_target_stack.top (); }
+
+  /* Return the target at process_stratum level in this inferior's
+     target stack.  */
+  struct process_stratum_target *process_target ()
+  { return (process_stratum_target *) m_target_stack.at (process_stratum); }
+
+  /* Return the target at STRATUM in this inferior's target stack.  */
+  target_ops *target_at (enum strata stratum)
+  { return m_target_stack.at (stratum); }
+
+  bool has_execution ()
+  { return target_has_execution (this); }
+
+  /* This inferior's thread list, sorted by creation order.  */
+  intrusive_list<thread_info> thread_list;
+
+  /* A map of ptid_t to thread_info*, for average O(1) ptid_t lookup.
+     Exited threads do not appear in the map.  */
+  std::unordered_map<ptid_t, thread_info *, hash_ptid> ptid_thread_map;
+
+  /* Returns a range adapter covering the inferior's threads,
+     including exited threads.  Used like this:
+
+       for (thread_info *thr : inf->threads ())
+        { .... }
+  */
+  inf_threads_range threads ()
+  { return inf_threads_range (this->thread_list.begin ()); }
+
+  /* Returns a range adapter covering the inferior's non-exited
+     threads.  Used like this:
+
+       for (thread_info *thr : inf->non_exited_threads ())
+        { .... }
+  */
+  inf_non_exited_threads_range non_exited_threads ()
+  { return inf_non_exited_threads_range (this->thread_list.begin ()); }
+
+  /* Like inferior::threads(), but returns a range adapter that can be
+     used with range-for, safely.  I.e., it is safe to delete the
+     currently-iterated thread, like this:
+
+     for (thread_info *t : inf->threads_safe ())
+       if (some_condition ())
+        delete f;
+  */
+  inline safe_inf_threads_range threads_safe ()
+  { return safe_inf_threads_range (this->thread_list.begin ()); }
+
+  /* Delete all threads in the thread list.  If SILENT, exit threads
+     silently.  */
+  void clear_thread_list (bool silent);
+
+  /* Continuations-related methods.  A continuation is an std::function
+     to be called to finish the execution of a command when running
+     GDB asynchronously.  A continuation is executed after any thread
+     of this inferior stops.  Continuations are used by the attach
+     command and the remote target when a new inferior is detected.  */
+  void add_continuation (std::function<void ()> &&cont);
+  void do_all_continuations ();
+
+  /* Set/get file name for default use for standard in/out in the inferior.
+
+     On Unix systems, we try to make TERMINAL_NAME the inferior's controlling
+     terminal.
+
+     If TERMINAL_NAME is the empty string, then the inferior inherits GDB's
+     terminal (or GDBserver's if spawning a remote process).  */
+  void set_tty (std::string terminal_name);
+  const std::string &tty ();
+
+  /* Set the argument string to use when running this inferior.
+
+     An empty string can be used to represent "no arguments".  */
+  void set_args (std::string args)
+  {
+    m_args = std::move (args);
+  };
+
+  /* Get the argument string to use when running this inferior.
+
+     No arguments is represented by an empty string.  */
+  const std::string &args () const
+  {
+    return m_args;
+  }
+
+  /* Set the inferior current working directory.
+
+     If CWD is empty, unset the directory.  */
+  void set_cwd (std::string cwd)
+  {
+    m_cwd = std::move (cwd);
+  }
+
+  /* Get the inferior current working directory.
+
+     Return an empty string if the current working directory is not
+     specified.  */
+  const std::string &cwd () const
+  {
+    return m_cwd;
+  }
 
   /* Convenient handle (GDB inferior id).  Unique across all
      inferiors.  */
-  int num;
+  int num = 0;
 
   /* Actual target inferior id, usually, a process id.  This matches
      the ptid_t.pid member of threads of this inferior.  */
-  int pid;
+  int pid = 0;
   /* True if the PID was actually faked by GDB.  */
-  int fake_pid_p;
+  bool fake_pid_p = false;
+
+  /* The highest thread number this inferior ever had.  */
+  int highest_thread_num = 0;
 
   /* State of GDB control of inferior process execution.
      See `struct inferior_control_state'.  */
-  struct inferior_control_state control;
-
-  /* State of inferior process to restore after GDB is done with an inferior
-     call.  See `struct inferior_suspend_state'.  */
-#if 0 /* Currently unused and empty structures are not valid C.  */
-  struct inferior_suspend_state suspend;
-#endif
+  inferior_control_state control;
 
   /* True if this was an auto-created inferior, e.g. created from
      following a fork; false, if this inferior was manually added by
      the user, and we should not attempt to prune it
      automatically.  */
-  int removable;
+  bool removable = false;
 
   /* The address space bound to this inferior.  */
-  struct address_space *aspace;
+  struct address_space *aspace = NULL;
 
   /* The program space bound to this inferior.  */
-  struct program_space *pspace;
-
-  /* The arguments string to use when running.  */
-  char *args;
-
-  /* The size of elements in argv.  */
-  int argc;
+  struct program_space *pspace = NULL;
 
-  /* The vector version of arguments.  If ARGC is nonzero,
-     then we must compute ARGS from this (via the target).
-     This is always coming from main's argv and therefore
-     should never be freed.  */
-  char **argv;
-
-  /* The name of terminal device to use for I/O.  */
-  char *terminal;
+  /* The terminal state as set by the last target_terminal::terminal_*
+     call.  */
+  target_terminal_state terminal_state = target_terminal_state::is_ours;
 
   /* Environment to use for running inferior,
      in format described in environ.h.  */
-  struct gdb_environ *environment;
+  gdb_environ environment;
 
-  /* Nonzero if this child process was attached rather than
-     forked.  */
-  int attach_flag;
+  /* True if this child process was attached rather than forked.  */
+  bool attach_flag = false;
 
   /* If this inferior is a vfork child, then this is the pointer to
      its vfork parent, if GDB is still attached to it.  */
-  struct inferior *vfork_parent;
+  inferior *vfork_parent = NULL;
 
   /* If this process is a vfork parent, this is the pointer to the
      child.  Since a vfork parent is left frozen by the kernel until
      the child execs or exits, a process can only have one vfork child
      at a given time.  */
-  struct inferior *vfork_child;
+  inferior *vfork_child = NULL;
 
   /* True if this inferior should be detached when it's vfork sibling
      exits or execs.  */
-  int pending_detach;
+  bool pending_detach = false;
 
-  /* True if this inferior is a vfork parent waiting for a vfork child
-     not under our control to be done with the shared memory region,
-     either by exiting or execing.  */
-  int waiting_for_vfork_done;
+  /* If non-nullptr, points to a thread that called vfork and is now waiting
+     for a vfork child not under our control to be done with the shared memory
+     region, either by exiting or execing.  */
+  thread_info *thread_waiting_for_vfork_done = nullptr;
 
   /* True if we're in the process of detaching from this inferior.  */
-  int detaching;
+  bool detaching = false;
 
-  /* What is left to do for an execution command after any thread of
-     this inferior stops.  For continuations associated with a
-     specific thread, see `struct thread_info'.  */
-  struct continuation *continuations;
+  /* True if setup_inferior wasn't called for this inferior yet.
+     Until that is done, we must not access inferior memory or
+     registers, as we haven't determined the target
+     architecture/description.  */
+  bool needs_setup = false;
+
+  /* True when we are reading the library list of the inferior during an
+     attach or handling a fork child.  */
+  bool in_initial_library_scan = false;
 
   /* Private data used by the target vector implementation.  */
-  struct private_inferior *priv;
+  std::unique_ptr<private_inferior> priv;
 
   /* HAS_EXIT_CODE is true if the inferior exited with an exit code.
      In this case, the EXIT_CODE field is also valid.  */
-  int has_exit_code;
-  LONGEST exit_code;
+  bool has_exit_code = false;
+  LONGEST exit_code = 0;
 
   /* Default flags to pass to the symbol reading functions.  These are
-     used whenever a new objfile is created.  The valid values come
-     from enum symfile_add_flags.  */
-  int symfile_flags;
+     used whenever a new objfile is created.  */
+  symfile_add_flags symfile_flags = 0;
 
   /* Info about an inferior's target description (if it's fetched; the
      user supplied description's filename, if any; etc.).  */
-  struct target_desc_info *tdesc_info;
+  target_desc_info *tdesc_info = NULL;
 
   /* The architecture associated with the inferior through the
      connection to the target.
@@ -408,10 +582,30 @@ struct inferior
      per-thread/per-frame/per-objfile properties, accesses to
      per-inferior/target properties should be made through
      this gdbarch.  */
-  struct gdbarch *gdbarch;
+  struct gdbarch *gdbarch = NULL;
+
+  /* Data related to displaced stepping.  */
+  displaced_step_inferior_state displaced_step_state;
 
   /* Per inferior data-pointers required by other GDB modules.  */
   REGISTRY_FIELDS;
+
+private:
+  /* The inferior's target stack.  */
+  target_stack m_target_stack;
+
+  /* The name of terminal device to use for I/O.  */
+  std::string m_terminal;
+
+  /* The list of continuations.  */
+  std::list<std::function<void ()>> m_continuations;
+
+  /* The arguments string to use when running.  */
+  std::string m_args;
+
+  /* The current working directory that will be used when starting
+     this inferior.  */
+  std::string m_cwd;
 };
 
 /* Keep a registry of per-inferior data-pointers required by other GDB
@@ -419,9 +613,6 @@ struct inferior
 
 DECLARE_REGISTRY (inferior);
 
-/* Create an empty inferior list, or empty the existing one.  */
-extern void init_inferior_list (void);
-
 /* Add an inferior to the inferior list, print a message that a new
    inferior is found, and return the pointer to the new inferior.
    Caller may use this pointer to initialize the private inferior
@@ -432,49 +623,27 @@ extern struct inferior *add_inferior (int pid);
    the CLI.  */
 extern struct inferior *add_inferior_silent (int pid);
 
-/* Delete an existing inferior list entry, due to inferior exit.  */
-extern void delete_inferior (int pid);
-
-extern void delete_inferior_1 (struct inferior *todel, int silent);
-
-/* Same as delete_inferior, but don't print new inferior notifications
-   to the CLI.  */
-extern void delete_inferior_silent (int pid);
+extern void delete_inferior (struct inferior *todel);
 
 /* Delete an existing inferior list entry, due to inferior detaching.  */
-extern void detach_inferior (int pid);
+extern void detach_inferior (inferior *inf);
 
-extern void exit_inferior (int pid);
+extern void exit_inferior (inferior *inf);
 
-extern void exit_inferior_silent (int pid);
+extern void exit_inferior_silent (inferior *inf);
 
 extern void exit_inferior_num_silent (int num);
 
 extern void inferior_appeared (struct inferior *inf, int pid);
 
-/* Get rid of all inferiors.  */
-extern void discard_all_inferiors (void);
+/* Search function to lookup an inferior of TARG by target 'pid'.  */
+extern struct inferior *find_inferior_pid (process_stratum_target *targ,
+                                          int pid);
 
-/* Translate the integer inferior id (GDB's homegrown id, not the system's)
-   into a "pid" (which may be overloaded with extra inferior information).  */
-extern int gdb_inferior_id_to_pid (int);
-
-/* Translate a target 'pid' into the integer inferior id (GDB's
-   homegrown id, not the system's).  */
-extern int pid_to_gdb_inferior_id (int pid);
-
-/* Boolean test for an already-known pid.  */
-extern int in_inferior_list (int pid);
-
-/* Boolean test for an already-known inferior id (GDB's homegrown id,
-   not the system's).  */
-extern int valid_gdb_inferior_id (int num);
-
-/* Search function to lookup an inferior by target 'pid'.  */
-extern struct inferior *find_inferior_pid (int pid);
-
-/* Search function to lookup an inferior whose pid is equal to 'ptid.pid'. */
-extern struct inferior *find_inferior_ptid (ptid_t ptid);
+/* Search function to lookup an inferior of TARG whose pid is equal to
+   'ptid.pid'. */
+extern struct inferior *find_inferior_ptid (process_stratum_target *targ,
+                                           ptid_t ptid);
 
 /* Search function to lookup an inferior by GDB 'num'.  */
 extern struct inferior *find_inferior_id (int num);
@@ -484,41 +653,81 @@ extern struct inferior *find_inferior_id (int num);
 extern struct inferior *
   find_inferior_for_program_space (struct program_space *pspace);
 
-/* Inferior iterator function.
-
-   Calls a callback function once for each inferior, so long as the
-   callback function returns false.  If the callback function returns
-   true, the iteration will end and the current inferior will be
-   returned.  This can be useful for implementing a search for a
-   inferior with arbitrary attributes, or for applying some operation
-   to every inferior.
-
-   It is safe to delete the iterated inferior from the callback.  */
-extern struct inferior *iterate_over_inferiors (int (*) (struct inferior *,
-                                                        void *),
-                                               void *);
-
 /* Returns true if the inferior list is not empty.  */
 extern int have_inferiors (void);
 
+/* Returns the number of live inferiors running on PROC_TARGET (real
+   live processes with execution).  */
+extern int number_of_live_inferiors (process_stratum_target *proc_target);
+
 /* Returns true if there are any live inferiors in the inferior list
    (not cores, not executables, real live processes).  */
 extern int have_live_inferiors (void);
 
-/* Return a pointer to the current inferior.  It is an error to call
-   this if there is no current inferior.  */
-extern struct inferior *current_inferior (void);
+/* Save/restore the current inferior.  */
+
+class scoped_restore_current_inferior
+{
+public:
+  scoped_restore_current_inferior ()
+    : m_saved_inf (current_inferior ())
+  {}
 
-extern void set_current_inferior (struct inferior *);
+  ~scoped_restore_current_inferior ()
+  { set_current_inferior (m_saved_inf); }
+
+  DISABLE_COPY_AND_ASSIGN (scoped_restore_current_inferior);
+
+private:
+  inferior *m_saved_inf;
+};
 
-extern struct cleanup *save_current_inferior (void);
 
 /* Traverse all inferiors.  */
 
-#define ALL_INFERIORS(I) \
-  for ((I) = inferior_list; (I); (I) = (I)->next)
+extern intrusive_list<inferior> inferior_list;
 
-extern struct inferior *inferior_list;
+/* Pull in the internals of the inferiors ranges and iterators.  Must
+   be done after struct inferior is defined.  */
+#include "inferior-iter.h"
+
+/* Return a range that can be used to walk over all inferiors
+   inferiors, with range-for, safely.  I.e., it is safe to delete the
+   currently-iterated inferior.  When combined with range-for, this
+   allow convenient patterns like this:
+
+     for (inferior *inf : all_inferiors_safe ())
+       if (some_condition ())
+        delete inf;
+*/
+
+inline all_inferiors_safe_range
+all_inferiors_safe ()
+{
+  return all_inferiors_safe_range (nullptr, inferior_list);
+}
+
+/* Returns a range representing all inferiors, suitable to use with
+   range-for, like this:
+
+   for (inferior *inf : all_inferiors ())
+     [...]
+*/
+
+inline all_inferiors_range
+all_inferiors (process_stratum_target *proc_target = nullptr)
+{
+  return all_inferiors_range (proc_target, inferior_list);
+}
+
+/* Return a range that can be used to walk over all inferiors with PID
+   not zero, with range-for.  */
+
+inline all_non_exited_inferiors_range
+all_non_exited_inferiors (process_stratum_target *proc_target = nullptr)
+{
+  return all_non_exited_inferiors_range (proc_target, inferior_list);
+}
 
 /* Prune away automatically added inferiors that aren't required
    anymore.  */
@@ -528,4 +737,14 @@ extern int number_of_inferiors (void);
 
 extern struct inferior *add_inferior_with_spaces (void);
 
+/* Print the current selected inferior.  */
+extern void print_selected_inferior (struct ui_out *uiout);
+
+/* Switch to inferior NEW_INF, a new inferior, and unless
+   NO_CONNECTION is true, push the process_stratum_target of ORG_INF
+   to NEW_INF.  */
+
+extern void switch_to_inferior_and_push_target
+  (inferior *new_inf, bool no_connection, inferior *org_inf);
+
 #endif /* !defined (INFERIOR_H) */