return ptid_t (-1);
 
   /* Check whether libpthdebug might be ready to be initialized.  */
-  if (!pd_active && status->kind == TARGET_WAITKIND_STOPPED
-      && status->value.sig == GDB_SIGNAL_TRAP)
+  if (!pd_active && status->kind () == TARGET_WAITKIND_STOPPED
+      && status->sig () == GDB_SIGNAL_TRAP)
     {
       process_stratum_target *proc_target
        = current_inferior ()->process_target ();
 
     = (const struct signal_catchpoint *) bl->owner;
   gdb_signal signal_number;
 
-  if (ws->kind != TARGET_WAITKIND_STOPPED)
+  if (ws->kind () != TARGET_WAITKIND_STOPPED)
     return 0;
 
-  signal_number = ws->value.sig;
+  signal_number = ws->sig ();
 
   /* If we are catching specific signals in this breakpoint, then we
      must guarantee that the called signal is the same signal we are
 
   get_last_target_status (nullptr, nullptr, &last);
 
-  signal_name = signal_to_name_or_int (last.value.sig);
+  signal_name = signal_to_name_or_int (last.sig ());
 
   annotate_catchpoint (b->number);
   maybe_print_thread_hit_breakpoint (uiout);
 
   const struct syscall_catchpoint *c
     = (const struct syscall_catchpoint *) bl->owner;
 
-  if (ws->kind != TARGET_WAITKIND_SYSCALL_ENTRY
-      && ws->kind != TARGET_WAITKIND_SYSCALL_RETURN)
+  if (ws->kind () != TARGET_WAITKIND_SYSCALL_ENTRY
+      && ws->kind () != TARGET_WAITKIND_SYSCALL_RETURN)
     return 0;
 
-  syscall_number = ws->value.syscall_number;
+  syscall_number = ws->syscall_number ();
 
   /* Now, checking if the syscall is the same.  */
   if (!c->syscalls_to_be_caught.empty ())
 
   get_last_target_status (nullptr, nullptr, &last);
 
-  get_syscall_by_number (gdbarch, last.value.syscall_number, &s);
+  get_syscall_by_number (gdbarch, last.syscall_number (), &s);
 
   annotate_catchpoint (b->number);
   maybe_print_thread_hit_breakpoint (uiout);
   if (uiout->is_mi_like_p ())
     {
       uiout->field_string ("reason",
-                          async_reason_lookup (last.kind == TARGET_WAITKIND_SYSCALL_ENTRY
+                          async_reason_lookup (last.kind () == TARGET_WAITKIND_SYSCALL_ENTRY
                                                ? EXEC_ASYNC_SYSCALL_ENTRY
                                                : EXEC_ASYNC_SYSCALL_RETURN));
       uiout->field_string ("disp", bpdisp_text (b->disposition));
     }
   uiout->field_signed ("bkptno", b->number);
 
-  if (last.kind == TARGET_WAITKIND_SYSCALL_ENTRY)
+  if (last.kind () == TARGET_WAITKIND_SYSCALL_ENTRY)
     uiout->text (" (call to syscall ");
   else
     uiout->text (" (returned from syscall ");
 
   if (s.name == NULL || uiout->is_mi_like_p ())
-    uiout->field_signed ("syscall-number", last.value.syscall_number);
+    uiout->field_signed ("syscall-number", last.syscall_number ());
   if (s.name != NULL)
     uiout->field_string ("syscall-name", s.name);
 
 
 {
   struct fork_catchpoint *c = (struct fork_catchpoint *) bl->owner;
 
-  if (ws->kind != TARGET_WAITKIND_FORKED)
+  if (ws->kind () != TARGET_WAITKIND_FORKED)
     return 0;
 
-  c->forked_inferior_pid = ws->value.related_pid;
+  c->forked_inferior_pid = ws->child_ptid ();
   return 1;
 }
 
 {
   struct fork_catchpoint *c = (struct fork_catchpoint *) bl->owner;
 
-  if (ws->kind != TARGET_WAITKIND_VFORKED)
+  if (ws->kind () != TARGET_WAITKIND_VFORKED)
     return 0;
 
-  c->forked_inferior_pid = ws->value.related_pid;
+  c->forked_inferior_pid = ws->child_ptid ();
   return 1;
 }
 
 {
   struct solib_catchpoint *self = (struct solib_catchpoint *) bl->owner;
 
-  if (ws->kind == TARGET_WAITKIND_LOADED)
+  if (ws->kind () == TARGET_WAITKIND_LOADED)
     return 1;
 
   for (breakpoint *other : all_breakpoints ())
 {
   struct exec_catchpoint *c = (struct exec_catchpoint *) bl->owner;
 
-  if (ws->kind != TARGET_WAITKIND_EXECD)
+  if (ws->kind () != TARGET_WAITKIND_EXECD)
     return 0;
 
-  c->exec_pathname = make_unique_xstrdup (ws->value.execd_pathname);
+  c->exec_pathname = make_unique_xstrdup (ws->execd_pathname ());
   return 1;
 }
 
                                  CORE_ADDR bp_addr,
                                  const struct target_waitstatus *ws)
 {
-  if (ws->kind != TARGET_WAITKIND_STOPPED
-      || ws->value.sig != GDB_SIGNAL_TRAP)
+  if (ws->kind () != TARGET_WAITKIND_STOPPED
+      || ws->sig () != GDB_SIGNAL_TRAP)
     return 0;
 
   return breakpoint_address_match_range (bl->pspace->aspace, bl->address,
                     const address_space *aspace, CORE_ADDR bp_addr,
                     const struct target_waitstatus *ws)
 {
-  if (ws->kind != TARGET_WAITKIND_STOPPED
-      || ws->value.sig != GDB_SIGNAL_TRAP)
+  if (ws->kind () != TARGET_WAITKIND_STOPPED
+      || ws->sig () != GDB_SIGNAL_TRAP)
     return 0;
 
   if (!breakpoint_address_match (bl->pspace->aspace, bl->address,
 
 
   /* If the process is no longer alive, there's no point in figuring
      out the thread ID.  It will fail anyway.  */
-  if (status->kind == TARGET_WAITKIND_SIGNALLED
-      || status->kind == TARGET_WAITKIND_EXITED)
+  if (status->kind () == TARGET_WAITKIND_SIGNALLED
+      || status->kind () == TARGET_WAITKIND_EXITED)
     return ptid;
 
   /* Fetch the corresponding thread ID, and augment the returned
 
          printf_unfiltered
            (_("darwin_wait: ill-formatted message (id=0x%x)\n"), hdr->msgh_id);
          /* FIXME: send a failure reply?  */
-         status->kind = TARGET_WAITKIND_IGNORE;
+         status->set_ignore ();
          return minus_one_ptid;
        }
       if (inf == NULL)
        {
-         status->kind = TARGET_WAITKIND_IGNORE;
+         status->set_ignore ();
          return minus_one_ptid;
        }
       *pinf = inf;
 
       priv->pending_messages++;
 
-      status->kind = TARGET_WAITKIND_STOPPED;
       thread->msg_state = DARWIN_MESSAGE;
 
       inferior_debug (4, _("darwin_wait: thread=0x%x, got %s\n"),
       switch (thread->event.ex_type)
        {
        case EXC_BAD_ACCESS:
-         status->value.sig = GDB_EXC_BAD_ACCESS;
+         status->set_stopped (GDB_EXC_BAD_ACCESS);
          break;
        case EXC_BAD_INSTRUCTION:
-         status->value.sig = GDB_EXC_BAD_INSTRUCTION;
+         status->set_stopped (GDB_EXC_BAD_INSTRUCTION);
          break;
        case EXC_ARITHMETIC:
-         status->value.sig = GDB_EXC_ARITHMETIC;
+         status->set_stopped (GDB_EXC_ARITHMETIC);
          break;
        case EXC_EMULATION:
-         status->value.sig = GDB_EXC_EMULATION;
+         status->set_stopped (GDB_EXC_EMULATION);
          break;
        case EXC_SOFTWARE:
          if (thread->event.ex_data[0] == EXC_SOFT_SIGNAL)
            {
-             status->value.sig =
-               gdb_signal_from_host (thread->event.ex_data[1]);
+             status->set_stopped
+               (gdb_signal_from_host (thread->event.ex_data[1]));
              inferior_debug (5, _("  (signal %d: %s)\n"),
                              thread->event.ex_data[1],
-                             gdb_signal_to_name (status->value.sig));
+                             gdb_signal_to_name (status->sig ()));
 
              /* If the thread is stopped because it has received a signal
                 that gdb has just sent, continue.  */
                  thread->signaled = 0;
                  darwin_send_reply (inf, thread);
                  thread->msg_state = DARWIN_RUNNING;
-                 status->kind = TARGET_WAITKIND_IGNORE;
+                 status->set_ignore ();
                }
            }
          else
-           status->value.sig = GDB_EXC_SOFTWARE;
+           status->set_stopped (GDB_EXC_SOFTWARE);
          break;
        case EXC_BREAKPOINT:
          /* Many internal GDB routines expect breakpoints to be reported
             as GDB_SIGNAL_TRAP, and will report GDB_EXC_BREAKPOINT
             as a spurious signal.  */
-         status->value.sig = GDB_SIGNAL_TRAP;
+         status->set_stopped (GDB_SIGNAL_TRAP);
          break;
        default:
-         status->value.sig = GDB_SIGNAL_UNKNOWN;
+         status->set_stopped (GDB_SIGNAL_UNKNOWN);
          break;
        }
 
 
       if (res < 0 || inf == NULL)
        {
-         status->kind = TARGET_WAITKIND_IGNORE;
+         status->set_ignore ();
          return minus_one_ptid;
        }
 
                {
                  printf_unfiltered (_("wait4: res=%d: %s\n"),
                                     res_pid, safe_strerror (errno));
-                 status->kind = TARGET_WAITKIND_IGNORE;
+                 status->set_ignore ();
                  return minus_one_ptid;
                }
              if (WIFEXITED (wstatus))
-               {
-                 status->kind = TARGET_WAITKIND_EXITED;
-                 status->value.integer = WEXITSTATUS (wstatus);
-               }
+               status->set_exited (WEXITSTATUS (wstatus));
              else
                {
-                 status->kind = TARGET_WAITKIND_SIGNALLED;
-                 status->value.sig = gdb_signal_from_host (WTERMSIG (wstatus));
+                 status->set_signalled
+                   (gdb_signal_from_host (WTERMSIG (wstatus)));
                }
 
              inferior_debug (4, _("darwin_wait: pid=%d exit, status=0x%x\n"),
          else
            {
              inferior_debug (4, _("darwin_wait: pid=%d\n"), inf->pid);
-             status->kind = TARGET_WAITKIND_EXITED;
-             status->value.integer = 0; /* Don't know.  */
+             status->set_exited (0 /* Don't know.  */);
              return ptid_t (inf->pid, 0, 0);
            }
        }
 
   /* Unknown message.  */
   warning (_("darwin: got unknown message, id: 0x%x"), hdr->msgh_id);
-  status->kind = TARGET_WAITKIND_IGNORE;
+  status->set_ignore ();
   return minus_one_ptid;
 }
 
 
       darwin_inferior *priv = get_darwin_inferior (inf);
 
-      status->kind = TARGET_WAITKIND_STOPPED;
-      status->value.sig = GDB_SIGNAL_TRAP;
+      status->set_stopped (GDB_SIGNAL_TRAP);
       thread = priv->threads[0];
       thread->msg_state = DARWIN_STOPPED;
       return ptid_t (inf->pid, 0, thread->gdb_port);
 
       if (kret == MACH_RCV_INTERRUPTED)
        {
-         status->kind = TARGET_WAITKIND_IGNORE;
+         status->set_ignore ();
          return minus_one_ptid;
        }
 
       if (kret != MACH_MSG_SUCCESS)
        {
          inferior_debug (5, _("mach_msg: ret=0x%x\n"), kret);
-         status->kind = TARGET_WAITKIND_SPURIOUS;
+         status->set_spurious ();
          return minus_one_ptid;
        }
 
       if (inf == NULL)
        return res;
     }
-  while (status->kind == TARGET_WAITKIND_IGNORE);
+  while (status->kind () == TARGET_WAITKIND_IGNORE);
 
   /* Stop all tasks.  */
   for (inferior *inf : all_inferiors (this))
   while (1)
     {
       ptid = wait_1 (ptid_t (inf->pid), &wstatus);
-      if (wstatus.kind == TARGET_WAITKIND_STOPPED
-         && wstatus.value.sig == GDB_SIGNAL_STOP)
+      if (wstatus.kind () == TARGET_WAITKIND_STOPPED
+         && wstatus.sig () == GDB_SIGNAL_STOP)
        break;
     }
 }
 
        }
 #endif
       wptid = inf_ptrace_target::wait (ptid, ourstatus, target_options);
-      if (ourstatus->kind == TARGET_WAITKIND_STOPPED)
+      if (ourstatus->kind () == TARGET_WAITKIND_STOPPED)
        {
          struct ptrace_lwpinfo pl;
          pid_t pid;
                                         pl.pl_lwpid);
                  add_thread (this, wptid);
                }
-             ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+             ourstatus->set_spurious ();
              return wptid;
            }
 #endif
 #ifndef PTRACE_VFORK
              struct kinfo_proc kp;
 #endif
+             bool is_vfork = false;
              ptid_t child_ptid;
              pid_t child;
 
              child = pl.pl_child_pid;
-             ourstatus->kind = TARGET_WAITKIND_FORKED;
 #ifdef PTRACE_VFORK
              if (pl.pl_flags & PL_FLAG_VFORKED)
-               ourstatus->kind = TARGET_WAITKIND_VFORKED;
+               is_vfork = true;
 #endif
 
              /* Make sure the other end of the fork is stopped too.  */
              if (fbsd_fetch_kinfo_proc (child, &kp))
                {
                  if (kp.ki_flag & P_PPWAIT)
-                   ourstatus->kind = TARGET_WAITKIND_VFORKED;
+                   is_vfork = true;
                }
              else
                warning (_("Failed to fetch process information"));
 #endif
-             ourstatus->value.related_pid = child_ptid;
+
+             if (is_vfork)
+               ourstatus->set_vforked (child_ptid);
+             else
+               ourstatus->set_forked (child_ptid);
 
              return wptid;
            }
 #ifdef PTRACE_VFORK
          if (pl.pl_flags & PL_FLAG_VFORK_DONE)
            {
-             ourstatus->kind = TARGET_WAITKIND_VFORK_DONE;
+             ourstatus->set_vfork_done ();
              return wptid;
            }
 #endif
 
          if (pl.pl_flags & PL_FLAG_EXEC)
            {
-             ourstatus->kind = TARGET_WAITKIND_EXECD;
-             ourstatus->value.execd_pathname
-               = xstrdup (pid_to_exec_file (pid));
+             ourstatus->set_execd
+               (make_unique_xstrdup (pid_to_exec_file (pid)));
              return wptid;
            }
 
             SIGTRAP, so only treat SIGTRAP events as system call
             entry/exit events.  */
          if (pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)
-             && ourstatus->value.sig == SIGTRAP)
+             && ourstatus->sig () == SIGTRAP)
            {
 #ifdef HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE
              if (catch_syscall_enabled ())
                  if (catching_syscall_number (pl.pl_syscall_code))
                    {
                      if (pl.pl_flags & PL_FLAG_SCE)
-                       ourstatus->kind = TARGET_WAITKIND_SYSCALL_ENTRY;
+                       ourstatus->set_syscall_entry (pl.pl_syscall_code);
                      else
-                       ourstatus->kind = TARGET_WAITKIND_SYSCALL_RETURN;
-                     ourstatus->value.syscall_number = pl.pl_syscall_code;
+                       ourstatus->set_syscall_return (pl.pl_syscall_code);
+
                      return wptid;
                    }
                }
        perror_with_name (("ptrace"));
 
 #ifndef PTRACE_VFORK
-      if (fork_kind == TARGET_WAITKIND_VFORKED)
+      if (fork_kind () == TARGET_WAITKIND_VFORKED)
        {
          /* We can't insert breakpoints until the child process has
             finished with the shared memory region.  The parent
 
   enum target_stop_reason stop_reason = TARGET_STOPPED_BY_NO_REASON;
 
   /* The waitstatus for this thread's last event.  */
-  struct target_waitstatus waitstatus {};
+  struct target_waitstatus waitstatus;
   /* If true WAITSTATUS hasn't been handled yet.  */
   int waitstatus_pending_p = 0;
 
 
 static struct inf *
 make_inf (void)
 {
-  struct inf *inf = XNEW (struct inf);
+  struct inf *inf = new struct inf;
 
   inf->task = 0;
   inf->threads = 0;
   inf->threads_up_to_date = 0;
   inf->pid = 0;
-  inf->wait.status.kind = TARGET_WAITKIND_SPURIOUS;
+  inf->wait.status.set_spurious ();
   inf->wait.thread = 0;
   inf->wait.exc.handler = MACH_PORT_NULL;
   inf->wait.exc.reply = MACH_PORT_NULL;
 gnu_nat_target::inf_clear_wait (struct inf *inf)
 {
   inf_debug (inf, "clearing wait");
-  inf->wait.status.kind = TARGET_WAITKIND_SPURIOUS;
+  inf->wait.status.set_spurious ();
   inf->wait.thread = 0;
   inf->wait.suppress = 0;
   if (inf->wait.exc.handler != MACH_PORT_NULL)
     {
       struct inf_wait *w = &inf->wait;
 
-      if (w->status.kind == TARGET_WAITKIND_STOPPED
-         && w->status.value.sig == sig
+      if (w->status.kind () == TARGET_WAITKIND_STOPPED
+         && w->status.sig () == sig
          && w->thread && !w->thread->aborted)
        /* We're passing through the last exception we received.  This is
           kind of bogus, because exceptions are per-thread whereas gdb
     /* We're waiting for the inferior to finish execing.  */
     {
       struct inf_wait *w = &inf->wait;
-      enum target_waitkind kind = w->status.kind;
+      enum target_waitkind kind = w->status.kind ();
 
       if (kind == TARGET_WAITKIND_SPURIOUS)
        /* Since gdb is actually counting the number of times the inferior
          inf_debug (inf, "pending_execs, ignoring minor event");
        }
       else if (kind == TARGET_WAITKIND_STOPPED
-              && w->status.value.sig == GDB_SIGNAL_TRAP)
+              && w->status.sig () == GDB_SIGNAL_TRAP)
        /* Ah hah!  A SIGTRAP from the inferior while starting up probably
           means we've succesfully completed an exec!  */
        {
     }
 
   /* Pass back out our results.  */
-  memcpy (status, &inf->wait.status, sizeof (*status));
+  *status = inf->wait.status;
 
   thread = inf->wait.thread;
   if (thread)
 
   if (thread
       && ptid != minus_one_ptid
-      && status->kind != TARGET_WAITKIND_SPURIOUS
+      && status->kind () != TARGET_WAITKIND_SPURIOUS
       && inf->pause_sc == 0 && thread->pause_sc == 0)
     /* If something actually happened to THREAD, make sure we
        suspend it.  */
       /* Store away the details; this will destroy any previous info.  */
       inf->wait.thread = thread;
 
-      inf->wait.status.kind = TARGET_WAITKIND_STOPPED;
-
       if (exception == EXC_BREAKPOINT)
        /* GDB likes to get SIGTRAP for breakpoints.  */
        {
-         inf->wait.status.value.sig = GDB_SIGNAL_TRAP;
+         inf->wait.status.set_stopped (GDB_SIGNAL_TRAP);
          mach_port_deallocate (mach_task_self (), reply_port);
        }
       else
          /* Exceptions are encoded in the signal space by putting
             them after _NSIG; this assumes they're positive (and not
             extremely large)!  */
-         inf->wait.status.value.sig =
-           gdb_signal_from_host (_NSIG + exception);
+         inf->wait.status.set_stopped
+           (gdb_signal_from_host (_NSIG + exception));
        }
     }
   else
 {
   warning (_("Pid %d died with unknown exit status, using SIGKILL."),
           inf->pid);
-  inf->wait.status.kind = TARGET_WAITKIND_SIGNALLED;
-  inf->wait.status.value.sig = GDB_SIGNAL_KILL;
+  inf->wait.status.set_signalled (GDB_SIGNAL_KILL);
 }
 
 /* Notify server routines.  The only real one is dead name notification.  */
   else if (pid == inf->pid)
     {
       store_waitstatus (&inf->wait.status, status);
-      if (inf->wait.status.kind == TARGET_WAITKIND_STOPPED)
+      if (inf->wait.status.kind () == TARGET_WAITKIND_STOPPED)
        /* The process has sent us a signal, and stopped itself in a sane
           state pending our actions.  */
        {
        like the process stopped (using a signal of 0 should mean that the
        *next* time the user continues, it will pass signal 0, which the crash
        server should like).  */
-    {
-      inf->wait.status.kind = TARGET_WAITKIND_STOPPED;
-      inf->wait.status.value.sig = GDB_SIGNAL_0;
-    }
+    inf->wait.status.set_stopped (GDB_SIGNAL_0);
   else if (err)
     warning (_("Signal delivery failed: %s"), safe_strerror (err));
 
       proc_abort (inf->wait.thread, 1);
       warning (_("Aborting %s with unforwarded exception %s."),
               proc_string (inf->wait.thread),
-              gdb_signal_to_name (inf->wait.status.value.sig));
+              gdb_signal_to_name (inf->wait.status.sig ()));
     }
 
   if (port_msgs_queued (inf->event_port))
 
     chdir (current_directory);
 
   if (a_tss.tss_irqn == 0x21)
-    {
-      status->kind = TARGET_WAITKIND_EXITED;
-      status->value.integer = a_tss.tss_eax & 0xff;
-    }
+    status->set_exited (a_tss.tss_eax & 0xff);
   else
     {
-      status->value.sig = GDB_SIGNAL_UNKNOWN;
-      status->kind = TARGET_WAITKIND_STOPPED;
+      status->set_stopped (GDB_SIGNAL_UNKNOWN);
       for (i = 0; sig_map[i].go32_sig != -1; i++)
        {
          if (a_tss.tss_irqn == sig_map[i].go32_sig)
            {
 #if __DJGPP_MINOR__ < 3
-             if ((status->value.sig = sig_map[i].gdb_sig) !=
-                 GDB_SIGNAL_TRAP)
-               status->kind = TARGET_WAITKIND_SIGNALLED;
+             status->set_stopped (sig_map[i].gdb_sig);
+             if (status->sig () != GDB_SIGNAL_TRAP)
+               status->set_signalled (status->sig ());
 #else
-             status->value.sig = sig_map[i].gdb_sig;
+             status->set_stopped (sig_map[i].gdb_sig);
 #endif
              break;
            }
 
 store_waitstatus (struct target_waitstatus *ourstatus, int hoststatus)
 {
   if (WIFEXITED (hoststatus))
-    {
-      ourstatus->kind = TARGET_WAITKIND_EXITED;
-      ourstatus->value.integer = WEXITSTATUS (hoststatus);
-    }
+    ourstatus->set_exited (WEXITSTATUS (hoststatus));
   else if (!WIFSTOPPED (hoststatus))
-    {
-      ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
-      ourstatus->value.sig = gdb_signal_from_host (WTERMSIG (hoststatus));
-    }
+    ourstatus->set_signalled (gdb_signal_from_host (WTERMSIG (hoststatus)));
   else
-    {
-      ourstatus->kind = TARGET_WAITKIND_STOPPED;
-      ourstatus->value.sig = gdb_signal_from_host (WSTOPSIG (hoststatus));
-    }
+    ourstatus->set_stopped (gdb_signal_from_host (WSTOPSIG (hoststatus)));
 }
 
 inf_child_target::~inf_child_target ()
 
                              safe_strerror (save_errno));
 
          /* Claim it exited with unknown signal.  */
-         ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
-         ourstatus->value.sig = GDB_SIGNAL_UNKNOWN;
+         ourstatus->set_signalled (GDB_SIGNAL_UNKNOWN);
          return inferior_ptid;
        }
 
 
     {
       thread_info *thr = inferior_thread ();
       target_waitstatus ws;
-      ws.kind = TARGET_WAITKIND_STOPPED;
-      ws.value.sig = GDB_SIGNAL_0;
+      ws.set_stopped (GDB_SIGNAL_0);
       thr->set_pending_waitstatus (ws);
     }
 
 
 static bool
 follow_fork_inferior (bool follow_child, bool detach_fork)
 {
-  target_waitkind fork_kind = inferior_thread ()->pending_follow.kind;
+  target_waitkind fork_kind = inferior_thread ()->pending_follow.kind ();
   gdb_assert (fork_kind == TARGET_WAITKIND_FORKED
              || fork_kind == TARGET_WAITKIND_VFORKED);
   bool has_vforked = fork_kind == TARGET_WAITKIND_VFORKED;
   ptid_t parent_ptid = inferior_ptid;
-  ptid_t child_ptid = inferior_thread ()->pending_follow.value.related_pid;
+  ptid_t child_ptid = inferior_thread ()->pending_follow.child_ptid ();
 
   if (has_vforked
       && !non_stop /* Non-stop always resumes both branches.  */
 
       /* If not stopped at a fork event, then there's nothing else to
         do.  */
-      if (wait_status.kind != TARGET_WAITKIND_FORKED
-         && wait_status.kind != TARGET_WAITKIND_VFORKED)
+      if (wait_status.kind () != TARGET_WAITKIND_FORKED
+         && wait_status.kind () != TARGET_WAITKIND_VFORKED)
        return 1;
 
       /* Check if we switched over from WAIT_PTID, since the event was
 
   /* If there were any forks/vforks that were caught and are now to be
      followed, then do so now.  */
-  switch (tp->pending_follow.kind)
+  switch (tp->pending_follow.kind ())
     {
     case TARGET_WAITKIND_FORKED:
     case TARGET_WAITKIND_VFORKED:
          }
 
        parent = inferior_ptid;
-       child = tp->pending_follow.value.related_pid;
+       child = tp->pending_follow.child_ptid ();
 
        process_stratum_target *parent_targ = tp->inf->process_target ();
        /* Set up inferior(s) as specified by the caller, and tell the
               to clear the pending follow request.  */
            tp = find_thread_ptid (parent_targ, parent);
            if (tp)
-             tp->pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
+             tp->pending_follow.set_spurious ();
 
            /* This makes sure we don't try to apply the "Switched
               over from WAIT_PID" logic above.  */
     default:
       internal_error (__FILE__, __LINE__,
                      "Unexpected pending_follow.kind %d\n",
-                     tp->pending_follow.kind);
+                     tp->pending_follow.kind ());
       break;
     }
 
    discarded between events.  */
 struct execution_control_state
 {
+  execution_control_state ()
+  {
+    this->reset ();
+  }
+
+  void reset ()
+  {
+    this->target = nullptr;
+    this->ptid = null_ptid;
+    this->event_thread = nullptr;
+    ws = target_waitstatus ();
+    stop_func_filled_in = 0;
+    stop_func_start = 0;
+    stop_func_end = 0;
+    stop_func_name = nullptr;
+    wait_some_more = 0;
+    hit_singlestep_breakpoint = 0;
+  }
+
   process_stratum_target *target;
   ptid_t ptid;
   /* The thread that got the event, if this was a thread event; NULL
 static void
 reset_ecs (struct execution_control_state *ecs, struct thread_info *tp)
 {
-  memset (ecs, 0, sizeof (*ecs));
+  ecs->reset ();
   ecs->event_thread = tp;
   ecs->ptid = tp->ptid;
 }
       if (!tp->has_pending_waitstatus ())
        {
          target_waitstatus ws;
-         ws.kind = TARGET_WAITKIND_STOPPED;
-         ws.value.sig = GDB_SIGNAL_0;
+         ws.set_stopped (GDB_SIGNAL_0);
          tp->set_pending_waitstatus (ws);
        }
 
 
          tp->clear_pending_waitstatus ();
          target_waitstatus ws;
-         ws.kind = TARGET_WAITKIND_SPURIOUS;
+         ws.set_spurious ();
          tp->set_pending_waitstatus (ws);
          tp->set_stop_reason (TARGET_STOPPED_BY_NO_REASON);
        }
 
   if (num_inferiors == 0)
     {
-      ecs->ws.kind = TARGET_WAITKIND_IGNORE;
+      ecs->ws.set_ignore ();
       return false;
     }
 
   {
     ecs->ptid = do_target_wait_1 (inf, minus_one_ptid, &ecs->ws, options);
     ecs->target = inf->process_target ();
-    return (ecs->ws.kind != TARGET_WAITKIND_IGNORE);
+    return (ecs->ws.kind () != TARGET_WAITKIND_IGNORE);
   };
 
   /* Needed in 'all-stop + target-non-stop' mode, because we end up
        return true;
     }
 
-  ecs->ws.kind = TARGET_WAITKIND_IGNORE;
+  ecs->ws.set_ignore ();
   return false;
 }
 
       struct execution_control_state ecss;
       struct execution_control_state *ecs = &ecss;
 
-      memset (ecs, 0, sizeof (*ecs));
-
       overlay_cache_invalid = 1;
 
       /* Flush target cache before starting to handle each event.
   struct execution_control_state *ecs = &ecss;
   int cmd_done = 0;
 
-  memset (ecs, 0, sizeof (*ecs));
-
   /* Events are always processed with the main UI as current UI.  This
      way, warnings, debug output, etc. are always consistently sent to
      the main console.  */
        return;
       }
 
-    gdb_assert (ecs->ws.kind != TARGET_WAITKIND_IGNORE);
+    gdb_assert (ecs->ws.kind () != TARGET_WAITKIND_IGNORE);
 
     /* Switch to the target that generated the event, so we can do
        target calls.  */
               selected.".  */
            if (!non_stop
                && cmd_done
-               && ecs->ws.kind != TARGET_WAITKIND_NO_RESUMED)
+               && ecs->ws.kind () != TARGET_WAITKIND_NO_RESUMED)
              restore_thread.dont_restore ();
          }
       }
 
 void
 set_last_target_status (process_stratum_target *target, ptid_t ptid,
-                       target_waitstatus status)
+                       const target_waitstatus &status)
 {
   target_last_proc_target = target;
   target_last_wait_ptid = ptid;
      target with both of these set in GDB history, and it seems unlikely to be
      correct, so gdbarch_have_nonsteppable_watchpoint is not checked here.  */
 
-  if (ws->kind != TARGET_WAITKIND_STOPPED)
+  if (ws->kind () != TARGET_WAITKIND_STOPPED)
     return;
 
-  if (ws->value.sig != GDB_SIGNAL_TRAP)
+  if (ws->sig () != GDB_SIGNAL_TRAP)
     return;
 
   /* In reverse execution, when a breakpoint is hit, the instruction
 {
   if (ecs->event_thread->stop_requested)
     {
-      ecs->ws.kind = TARGET_WAITKIND_STOPPED;
-      ecs->ws.value.sig = GDB_SIGNAL_0;
+      ecs->ws.set_stopped (GDB_SIGNAL_0);
       handle_signal_stop (ecs);
       return true;
     }
   context_switch (ecs);
 
   regcache = get_thread_regcache (ecs->event_thread);
-  syscall_number = ecs->ws.value.syscall_number;
+  syscall_number = ecs->ws.syscall_number ();
   ecs->event_thread->set_stop_pc (regcache_read_pc (regcache));
 
   if (catch_syscall_enabled () > 0
          event.target = target;
          event.ptid = poll_one_curr_target (&event.ws);
 
-         if (event.ws.kind == TARGET_WAITKIND_NO_RESUMED)
+         if (event.ws.kind () == TARGET_WAITKIND_NO_RESUMED)
            {
              /* If nothing is resumed, remove the target from the
                 event loop.  */
              target_async (0);
            }
-         else if (event.ws.kind != TARGET_WAITKIND_IGNORE)
+         else if (event.ws.kind () != TARGET_WAITKIND_IGNORE)
            return event;
        }
 
       if (nfds == 0)
        {
          /* No waitable targets left.  All must be stopped.  */
-         return {NULL, minus_one_ptid, {TARGET_WAITKIND_NO_RESUMED}};
+         target_waitstatus ws;
+         ws.set_no_resumed ();
+         return {NULL, minus_one_ptid, std::move (ws)};
        }
 
       QUIT;
   /* Record for later.  */
   tp->set_pending_waitstatus (*ws);
 
-  if (ws->kind == TARGET_WAITKIND_STOPPED
-      && ws->value.sig == GDB_SIGNAL_TRAP)
+  if (ws->kind () == TARGET_WAITKIND_STOPPED
+      && ws->sig () == GDB_SIGNAL_TRAP)
     {
       struct regcache *regcache = get_thread_regcache (tp);
       const address_space *aspace = regcache->aspace ();
 static void
 mark_non_executing_threads (process_stratum_target *target,
                            ptid_t event_ptid,
-                           struct target_waitstatus ws)
+                           const target_waitstatus &ws)
 {
   ptid_t mark_ptid;
 
   if (!target_is_non_stop_p ())
     mark_ptid = minus_one_ptid;
-  else if (ws.kind == TARGET_WAITKIND_SIGNALLED
-          || ws.kind == TARGET_WAITKIND_EXITED)
+  else if (ws.kind () == TARGET_WAITKIND_SIGNALLED
+          || ws.kind () == TARGET_WAITKIND_EXITED)
     {
       /* If we're handling a process exit in non-stop mode, even
         though threads haven't been deleted yet, one would think
     ("%s %s", target_waitstatus_to_string (&event.ws).c_str (),
      target_pid_to_str (event.ptid).c_str ());
 
-  if (event.ws.kind == TARGET_WAITKIND_NO_RESUMED)
+  if (event.ws.kind () == TARGET_WAITKIND_NO_RESUMED)
     {
       /* All resumed threads exited.  */
       return true;
     }
-  else if (event.ws.kind == TARGET_WAITKIND_THREAD_EXITED
-          || event.ws.kind == TARGET_WAITKIND_EXITED
-          || event.ws.kind == TARGET_WAITKIND_SIGNALLED)
+  else if (event.ws.kind () == TARGET_WAITKIND_THREAD_EXITED
+          || event.ws.kind () == TARGET_WAITKIND_EXITED
+          || event.ws.kind () == TARGET_WAITKIND_SIGNALLED)
     {
       /* One thread/process exited/signalled.  */
 
          /* Check if this is the first time we see this thread.
             Don't bother adding if it individually exited.  */
          if (t == nullptr
-             && event.ws.kind != TARGET_WAITKIND_THREAD_EXITED)
+             && event.ws.kind () != TARGET_WAITKIND_THREAD_EXITED)
            t = add_thread (event.target, event.ptid);
        }
 
          setup_inferior (0);
        }
 
-      if (event.ws.kind == TARGET_WAITKIND_STOPPED
-         && event.ws.value.sig == GDB_SIGNAL_0)
+      if (event.ws.kind () == TARGET_WAITKIND_STOPPED
+         && event.ws.sig () == GDB_SIGNAL_0)
        {
          /* We caught the event that we intended to catch, so
             there's no event to save as pending.  */
          /* Record for later.  */
          save_waitstatus (t, &event.ws);
 
-         sig = (event.ws.kind == TARGET_WAITKIND_STOPPED
-                ? event.ws.value.sig : GDB_SIGNAL_0);
+         sig = (event.ws.kind () == TARGET_WAITKIND_STOPPED
+                ? event.ws.sig () : GDB_SIGNAL_0);
 
          if (displaced_step_finish (t, sig)
              == DISPLACED_STEP_FINISH_STATUS_NOT_EXECUTED)
 
   infrun_debug_printf ("%s", target_waitstatus_to_string (&ecs->ws).c_str ());
 
-  if (ecs->ws.kind == TARGET_WAITKIND_IGNORE)
+  if (ecs->ws.kind () == TARGET_WAITKIND_IGNORE)
     {
       /* We had an event in the inferior, but we are not interested in
         handling it at this level.  The lower layers have already
       return;
     }
 
-  if (ecs->ws.kind == TARGET_WAITKIND_THREAD_EXITED)
+  if (ecs->ws.kind () == TARGET_WAITKIND_THREAD_EXITED)
     {
       prepare_to_wait (ecs);
       return;
     }
 
-  if (ecs->ws.kind == TARGET_WAITKIND_NO_RESUMED
+  if (ecs->ws.kind () == TARGET_WAITKIND_NO_RESUMED
       && handle_no_resumed (ecs))
     return;
 
   /* Always clear state belonging to the previous time we stopped.  */
   stop_stack_dummy = STOP_NONE;
 
-  if (ecs->ws.kind == TARGET_WAITKIND_NO_RESUMED)
+  if (ecs->ws.kind () == TARGET_WAITKIND_NO_RESUMED)
     {
       /* No unwaited-for children left.  IOW, all resumed children
         have exited.  */
       return;
     }
 
-  if (ecs->ws.kind != TARGET_WAITKIND_EXITED
-      && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED)
+  if (ecs->ws.kind () != TARGET_WAITKIND_EXITED
+      && ecs->ws.kind () != TARGET_WAITKIND_SIGNALLED)
     {
       ecs->event_thread = find_thread_ptid (ecs->target, ecs->ptid);
       /* If it's a new thread, add it to the thread database.  */
      non-executable stack.  This happens for call dummy breakpoints
      for architectures like SPARC that place call dummies on the
      stack.  */
-  if (ecs->ws.kind == TARGET_WAITKIND_STOPPED
-      && (ecs->ws.value.sig == GDB_SIGNAL_ILL
-         || ecs->ws.value.sig == GDB_SIGNAL_SEGV
-         || ecs->ws.value.sig == GDB_SIGNAL_EMT))
+  if (ecs->ws.kind () == TARGET_WAITKIND_STOPPED
+      && (ecs->ws.sig () == GDB_SIGNAL_ILL
+         || ecs->ws.sig () == GDB_SIGNAL_SEGV
+         || ecs->ws.sig () == GDB_SIGNAL_EMT))
     {
       struct regcache *regcache = get_thread_regcache (ecs->event_thread);
 
                                      regcache_read_pc (regcache)))
        {
          infrun_debug_printf ("Treating signal as SIGTRAP");
-         ecs->ws.value.sig = GDB_SIGNAL_TRAP;
+         ecs->ws.set_stopped (GDB_SIGNAL_TRAP);
        }
     }
 
   mark_non_executing_threads (ecs->target, ecs->ptid, ecs->ws);
 
-  switch (ecs->ws.kind)
+  switch (ecs->ws.kind ())
     {
     case TARGET_WAITKIND_LOADED:
       {
       /* Clearing any previous state of convenience variables.  */
       clear_exit_convenience_vars ();
 
-      if (ecs->ws.kind == TARGET_WAITKIND_EXITED)
+      if (ecs->ws.kind () == TARGET_WAITKIND_EXITED)
        {
          /* Record the exit code in the convenience variable $_exitcode, so
             that the user can inspect this again later.  */
          set_internalvar_integer (lookup_internalvar ("_exitcode"),
-                                  (LONGEST) ecs->ws.value.integer);
+                                  (LONGEST) ecs->ws.exit_status ());
 
          /* Also record this in the inferior itself.  */
          current_inferior ()->has_exit_code = 1;
-         current_inferior ()->exit_code = (LONGEST) ecs->ws.value.integer;
+         current_inferior ()->exit_code = (LONGEST) ecs->ws.exit_status ();
 
          /* Support the --return-child-result option.  */
-         return_child_result_value = ecs->ws.value.integer;
+         return_child_result_value = ecs->ws.exit_status ();
 
-         gdb::observers::exited.notify (ecs->ws.value.integer);
+         gdb::observers::exited.notify (ecs->ws.exit_status ());
        }
       else
        {
                 which holds the signal uncaught by the inferior.  */
              set_internalvar_integer (lookup_internalvar ("_exitsignal"),
                                       gdbarch_gdb_signal_to_target (gdbarch,
-                                                         ecs->ws.value.sig));
+                                                         ecs->ws.sig ()));
            }
          else
            {
                                   "signal number.");
            }
 
-         gdb::observers::signal_exited.notify (ecs->ws.value.sig);
+         gdb::observers::signal_exited.notify (ecs->ws.sig ());
        }
 
       gdb_flush (gdb_stdout);
           gdbarch_displaced_step_restore_all_in_ptid.  This is not
           enforced during gdbarch validation to support architectures
           which support displaced stepping but not forks.  */
-       if (ecs->ws.kind == TARGET_WAITKIND_FORKED
+       if (ecs->ws.kind () == TARGET_WAITKIND_FORKED
            && gdbarch_supports_displaced_stepping (gdbarch))
          gdbarch_displaced_step_restore_all_in_ptid
-           (gdbarch, parent_inf, ecs->ws.value.related_pid);
+           (gdbarch, parent_inf, ecs->ws.child_ptid ());
 
        /* If displaced stepping is supported, and thread ecs->ptid is
           displaced stepping.  */
 
            child_regcache
              = get_thread_arch_aspace_regcache (parent_inf->process_target (),
-                                                ecs->ws.value.related_pid,
+                                                ecs->ws.child_ptid (),
                                                 gdbarch,
                                                 parent_inf->aspace);
            /* Read PC value of parent process.  */
         need to unpatch at follow/detach time instead to be certain
         that new breakpoints added between catchpoint hit time and
         vfork follow are detached.  */
-      if (ecs->ws.kind != TARGET_WAITKIND_VFORKED)
+      if (ecs->ws.kind () != TARGET_WAITKIND_VFORKED)
        {
          /* This won't actually modify the breakpoint list, but will
             physically remove the breakpoints from the child.  */
-         detach_breakpoints (ecs->ws.value.related_pid);
+         detach_breakpoints (ecs->ws.child_ptid ());
        }
 
       delete_just_stopped_threads_single_step_breakpoints ();
          /* Note that one of these may be an invalid pointer,
             depending on detach_fork.  */
          thread_info *parent = ecs->event_thread;
-         thread_info *child
-           = find_thread_ptid (targ, ecs->ws.value.related_pid);
+         thread_info *child = find_thread_ptid (targ, ecs->ws.child_ptid ());
 
          /* At this point, the parent is marked running, and the
             child is marked stopped.  */
       /* This causes the eventpoints and symbol table to be reset.
         Must do this now, before trying to determine whether to
         stop.  */
-      follow_exec (inferior_ptid, ecs->ws.value.execd_pathname);
+      follow_exec (inferior_ptid, ecs->ws.execd_pathname ());
 
       /* In follow_exec we may have deleted the original thread and
         created a new one.  Make sure that the event thread is the
                              ecs->event_thread->stop_pc (),
                              ecs->event_thread, &ecs->ws);
 
-      /* Note that this may be referenced from inside
-        bpstat_stop_status above, through inferior_has_execd.  */
-      xfree (ecs->ws.value.execd_pathname);
-      ecs->ws.value.execd_pathname = NULL;
-
       if (handle_stop_requested (ecs))
        return;
 
   enum stop_kind stop_soon;
   int random_signal;
 
-  gdb_assert (ecs->ws.kind == TARGET_WAITKIND_STOPPED);
+  gdb_assert (ecs->ws.kind () == TARGET_WAITKIND_STOPPED);
 
-  ecs->event_thread->set_stop_signal (ecs->ws.value.sig);
+  ecs->event_thread->set_stop_signal (ecs->ws.sig ());
 
   /* Do we need to clean up the state of a thread that has
      completed a displaced single-step?  (Doing so usually affects
   int do_frame_printing = 1;
   struct thread_info *tp = inferior_thread ();
 
-  bpstat_ret = bpstat_print (tp->control.stop_bpstat, ws->kind);
+  bpstat_ret = bpstat_print (tp->control.stop_bpstat, ws->kind ());
   switch (bpstat_ret)
     {
     case PRINT_UNKNOWN:
 
   if (!non_stop)
     finish_ptid = minus_one_ptid;
-  else if (last.kind == TARGET_WAITKIND_SIGNALLED
-          || last.kind == TARGET_WAITKIND_EXITED)
+  else if (last.kind () == TARGET_WAITKIND_SIGNALLED
+          || last.kind () == TARGET_WAITKIND_EXITED)
     {
       /* On some targets, we may still have live threads in the
         inferior when we get a process exit event.  E.g., for
       if (inferior_ptid != null_ptid)
        finish_ptid = ptid_t (inferior_ptid.pid ());
     }
-  else if (last.kind != TARGET_WAITKIND_NO_RESUMED)
+  else if (last.kind () != TARGET_WAITKIND_NO_RESUMED)
     finish_ptid = inferior_ptid;
 
   gdb::optional<scoped_finish_thread_state> maybe_finish_thread_state;
      instead of after.  */
   update_thread_list ();
 
-  if (last.kind == TARGET_WAITKIND_STOPPED && stopped_by_random_signal)
+  if (last.kind () == TARGET_WAITKIND_STOPPED && stopped_by_random_signal)
     gdb::observers::signal_received.notify (inferior_thread ()->stop_signal ());
 
   /* As with the notification of thread events, we want to delay
   if (!non_stop
       && previous_inferior_ptid != inferior_ptid
       && target_has_execution ()
-      && last.kind != TARGET_WAITKIND_SIGNALLED
-      && last.kind != TARGET_WAITKIND_EXITED
-      && last.kind != TARGET_WAITKIND_NO_RESUMED)
+      && last.kind () != TARGET_WAITKIND_SIGNALLED
+      && last.kind () != TARGET_WAITKIND_EXITED
+      && last.kind () != TARGET_WAITKIND_NO_RESUMED)
     {
       SWITCH_THRU_ALL_UIS ()
        {
       previous_inferior_ptid = inferior_ptid;
     }
 
-  if (last.kind == TARGET_WAITKIND_NO_RESUMED)
+  if (last.kind () == TARGET_WAITKIND_NO_RESUMED)
     {
       SWITCH_THRU_ALL_UIS ()
        if (current_ui->prompt_state == PROMPT_BLOCKED)
 
   if (target_has_execution ())
     {
-      if (last.kind != TARGET_WAITKIND_SIGNALLED
-         && last.kind != TARGET_WAITKIND_EXITED
-         && last.kind != TARGET_WAITKIND_NO_RESUMED)
+      if (last.kind () != TARGET_WAITKIND_SIGNALLED
+         && last.kind () != TARGET_WAITKIND_EXITED
+         && last.kind () != TARGET_WAITKIND_NO_RESUMED)
        /* Delete the breakpoint we stopped at, if it wants to be deleted.
           Delete any breakpoint that is to be deleted at the next stop.  */
        breakpoint_auto_delete (inferior_thread ()->control.stop_bpstat);
 
 
 /* Set the cached copy of the last target/ptid/waitstatus.  */
 extern void set_last_target_status (process_stratum_target *target, ptid_t ptid,
-                                   struct target_waitstatus status);
+                                   const target_waitstatus &status);
 
 /* Clear the cached copy of the last ptid/waitstatus returned by
    target_wait().  */
 
                 will notice a pending event, and bypasses actually
                 resuming the inferior.  */
              parent_lp->status = 0;
-             parent_lp->waitstatus.kind = TARGET_WAITKIND_VFORK_DONE;
+             parent_lp->waitstatus.set_vfork_done ();
              parent_lp->stopped = 1;
 
              /* If we're in async mode, need to tell the event loop
      signal pass state).  Normally SIGTRAP isn't set to pass state, so
      this is really a corner case.  */
 
-  if (lp->waitstatus.kind != TARGET_WAITKIND_IGNORE)
+  if (lp->waitstatus.kind () != TARGET_WAITKIND_IGNORE)
     signo = GDB_SIGNAL_0; /* a pending ptrace event, not a real signal.  */
   else if (lp->status)
     signo = gdb_signal_from_host (WSTOPSIG (lp->status));
       if (target_is_non_stop_p () && !tp->executing ())
        {
          if (tp->has_pending_waitstatus ())
-           signo = tp->pending_waitstatus ().value.sig;
+           signo = tp->pending_waitstatus ().sig ();
          else
            signo = tp->stop_signal ();
        }
     {
       lp->stop_reason = TARGET_STOPPED_BY_NO_REASON;
       lp->status = 0;
-      lp->waitstatus.kind = TARGET_WAITKIND_IGNORE;
+      lp->waitstatus.set_ignore ();
       return 1;
     }
   return 0;
       if (catching_syscall_number (syscall_number))
        {
          /* Alright, an event to report.  */
-         ourstatus->kind = lp->syscall_state;
-         ourstatus->value.syscall_number = syscall_number;
+         if (lp->syscall_state == TARGET_WAITKIND_SYSCALL_ENTRY)
+           ourstatus->set_syscall_entry (syscall_number);
+         else if (lp->syscall_state == TARGET_WAITKIND_SYSCALL_RETURN)
+           ourstatus->set_syscall_return (syscall_number);
+         else
+           gdb_assert_not_reached ("unexpected syscall state");
 
          linux_nat_debug_printf
            ("stopping for %s of syscall %d for LWP %ld",
                            _("wait returned unexpected status 0x%x"), status);
        }
 
-      ourstatus->value.related_pid = ptid_t (new_pid, new_pid);
+      ptid_t child_ptid (new_pid, new_pid);
 
       if (event == PTRACE_EVENT_FORK || event == PTRACE_EVENT_VFORK)
        {
          /* Report as spurious, so that infrun doesn't want to follow
             this fork.  We're actually doing an infcall in
             linux-fork.c.  */
-         ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+         ourstatus->set_spurious ();
 
          /* Report the stop to the core.  */
          return 0;
        }
 
       if (event == PTRACE_EVENT_FORK)
-       ourstatus->kind = TARGET_WAITKIND_FORKED;
+       ourstatus->set_forked (child_ptid);
       else if (event == PTRACE_EVENT_VFORK)
-       ourstatus->kind = TARGET_WAITKIND_VFORKED;
+       ourstatus->set_vforked (child_ptid);
       else if (event == PTRACE_EVENT_CLONE)
        {
          struct lwp_info *new_lp;
 
-         ourstatus->kind = TARGET_WAITKIND_IGNORE;
+         ourstatus->set_ignore ();
 
          linux_nat_debug_printf
            ("Got clone event from LWP %d, new child is LWP %ld", pid, new_pid);
            }
          else if (report_thread_events)
            {
-             new_lp->waitstatus.kind = TARGET_WAITKIND_THREAD_CREATED;
+             new_lp->waitstatus.set_thread_created ();
              new_lp->status = status;
            }
 
         inferior.  */
       maybe_close_proc_mem_file (lp->ptid.pid ());
 
-      ourstatus->kind = TARGET_WAITKIND_EXECD;
-      ourstatus->value.execd_pathname
-       = xstrdup (linux_proc_pid_to_exec_file (pid));
+      ourstatus->set_execd
+       (make_unique_xstrdup (linux_proc_pid_to_exec_file (pid)));
 
       /* The thread that execed must have been resumed, but, when a
         thread execs, it changes its tid to the tgid, and the old
            ("Got expected PTRACE_EVENT_VFORK_DONE from LWP %ld: stopping",
             lp->ptid.lwp ());
 
-         ourstatus->kind = TARGET_WAITKIND_VFORK_DONE;
+         ourstatus->set_vfork_done ();
          return 0;
        }
 
   /* We check for lp->waitstatus in addition to lp->status, because we
      can have pending process exits recorded in lp->status and
      W_EXITCODE(0,0) happens to be 0.  */
-  return lp->status != 0 || lp->waitstatus.kind != TARGET_WAITKIND_IGNORE;
+  return lp->status != 0 || lp->waitstatus.kind () != TARGET_WAITKIND_IGNORE;
 }
 
 /* Select the Nth LWP that has had an event.  */
   if (num_lwps (ptid.pid ()) > 1)
     {
       if (report_thread_events)
-       ourstatus->kind = TARGET_WAITKIND_THREAD_EXITED;
+       ourstatus->set_thread_exited (0);
       else
-       ourstatus->kind = TARGET_WAITKIND_IGNORE;
+       ourstatus->set_ignore ();
 
       exit_lwp (event_child);
     }
        {
          linux_nat_debug_printf ("exit (no resumed LWP)");
 
-         ourstatus->kind = TARGET_WAITKIND_NO_RESUMED;
+         ourstatus->set_no_resumed ();
 
          restore_child_signals_mask (&prev_mask);
          return minus_one_ptid;
        {
          linux_nat_debug_printf ("exit (ignore)");
 
-         ourstatus->kind = TARGET_WAITKIND_IGNORE;
+         ourstatus->set_ignore ();
          restore_child_signals_mask (&prev_mask);
          return minus_one_ptid;
        }
                              target_pid_to_str (lp->ptid).c_str ());
     }
 
-  if (lp->waitstatus.kind != TARGET_WAITKIND_IGNORE)
+  if (lp->waitstatus.kind () != TARGET_WAITKIND_IGNORE)
     {
       *ourstatus = lp->waitstatus;
-      lp->waitstatus.kind = TARGET_WAITKIND_IGNORE;
+      lp->waitstatus.set_ignore ();
     }
   else
     store_waitstatus (ourstatus, status);
   restore_child_signals_mask (&prev_mask);
 
   if (last_resume_kind == resume_stop
-      && ourstatus->kind == TARGET_WAITKIND_STOPPED
+      && ourstatus->kind () == TARGET_WAITKIND_STOPPED
       && WSTOPSIG (status) == SIGSTOP)
     {
       /* A thread that has been requested to stop by GDB with
         target_stop, and it stopped cleanly, so report as SIG0.  The
         use of SIGSTOP is an implementation detail.  */
-      ourstatus->value.sig = GDB_SIGNAL_0;
+      ourstatus->set_stopped (GDB_SIGNAL_0);
     }
 
-  if (ourstatus->kind == TARGET_WAITKIND_EXITED
-      || ourstatus->kind == TARGET_WAITKIND_SIGNALLED)
+  if (ourstatus->kind () == TARGET_WAITKIND_EXITED
+      || ourstatus->kind () == TARGET_WAITKIND_SIGNALLED)
     lp->core = -1;
   else
     lp->core = linux_common_core_of_thread (lp->ptid);
 
-  if (ourstatus->kind == TARGET_WAITKIND_EXITED)
+  if (ourstatus->kind () == TARGET_WAITKIND_EXITED)
     return filter_exit_event (lp, ourstatus);
 
   return lp->ptid;
      may be more.  If we requested a specific lwp or process, also
      assume there may be more.  */
   if (target_is_async_p ()
-      && ((ourstatus->kind != TARGET_WAITKIND_IGNORE
-          && ourstatus->kind != TARGET_WAITKIND_NO_RESUMED)
+      && ((ourstatus->kind () != TARGET_WAITKIND_IGNORE
+          && ourstatus->kind () != TARGET_WAITKIND_NO_RESUMED)
          || ptid != minus_one_ptid))
     async_file_mark ();
 
     {
       struct target_waitstatus *ws = &thread->pending_follow;
 
-      if (ws->kind == TARGET_WAITKIND_FORKED
-         || ws->kind == TARGET_WAITKIND_VFORKED)
+      if (ws->kind () == TARGET_WAITKIND_FORKED
+         || ws->kind () == TARGET_WAITKIND_VFORKED)
        {
-         ptid_t child_ptid = ws->value.related_pid;
+         ptid_t child_ptid = ws->child_ptid ();
          int child_pid = child_ptid.pid ();
          int child_lwp = child_ptid.lwp ();
 
 
 {
   lwp_info (ptid_t ptid)
     : ptid (ptid)
-  {
-    waitstatus.kind = TARGET_WAITKIND_IGNORE;
-  }
+  {}
 
   ~lwp_info ();
 
 
   /* The process id of the LWP.  This is a combination of the LWP id
      and overall process id.  */
-  ptid_t ptid;
+  ptid_t ptid = null_ptid;
 
   /* If this flag is set, we need to set the event request flags the
      next time we see this LWP stop.  */
 
 
   ptid = beneath->wait (ptid, ourstatus, options);
 
-  switch (ourstatus->kind)
+  switch (ourstatus->kind ())
     {
     case TARGET_WAITKIND_IGNORE:
     case TARGET_WAITKIND_EXITED:
 
       ptid_t event_ptid;
 
       struct target_waitstatus ws;
-      memset (&ws, 0, sizeof (ws));
       event_ptid = target_wait (resume_ptid, &ws, 0);
 
       if (last_waitstatus != NULL)
       if (last_ptid != NULL)
        *last_ptid = event_ptid;
 
-      if (ws.kind == TARGET_WAITKIND_IGNORE)
+      if (ws.kind () == TARGET_WAITKIND_IGNORE)
        /* The inferior didn't really stop, keep waiting.  */
        continue;
 
-      switch (ws.kind)
+      switch (ws.kind ())
        {
          case TARGET_WAITKIND_SPURIOUS:
          case TARGET_WAITKIND_LOADED:
            target_terminal::ours ();
            target_mourn_inferior (event_ptid);
            error (_("During startup program terminated with signal %s, %s."),
-                  gdb_signal_to_name (ws.value.sig),
-                  gdb_signal_to_string (ws.value.sig));
+                  gdb_signal_to_name (ws.sig ()),
+                  gdb_signal_to_string (ws.sig ()));
            return resume_ptid;
 
          case TARGET_WAITKIND_EXITED:
            target_terminal::ours ();
            target_mourn_inferior (event_ptid);
-           if (ws.value.integer)
+           if (ws.exit_status ())
              error (_("During startup program exited with code %d."),
-                    ws.value.integer);
+                    ws.exit_status ());
            else
              error (_("During startup program exited normally."));
            return resume_ptid;
 
          case TARGET_WAITKIND_EXECD:
            /* Handle EXEC signals as if they were SIGTRAP signals.  */
-           /* Free the exec'ed pathname, but only if this isn't the
-              waitstatus we are returning to the caller.  */
-           if (pending_execs != 1)
-             xfree (ws.value.execd_pathname);
            resume_signal = GDB_SIGNAL_TRAP;
            switch_to_thread (proc_target, event_ptid);
            break;
 
          case TARGET_WAITKIND_STOPPED:
-           resume_signal = ws.value.sig;
+           resume_signal = ws.sig ();
            switch_to_thread (proc_target, event_ptid);
            break;
        }
 
 
   memcpy (&siginfo_er, rec, sizeof siginfo_er);
 
-  ourstatus->kind = TARGET_WAITKIND_STOPPED;
-
   /* Record the context of the current thread.  */
   thread_rec (ptid_t (current_event.dwProcessId, current_event.dwThreadId, 0),
              DONT_SUSPEND);
     {
     case EXCEPTION_ACCESS_VIOLATION:
       DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
-      ourstatus->value.sig = GDB_SIGNAL_SEGV;
+      ourstatus->set_stopped (GDB_SIGNAL_SEGV);
       if (handle_access_violation (rec))
        return HANDLE_EXCEPTION_UNHANDLED;
       break;
     case STATUS_STACK_OVERFLOW:
       DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
-      ourstatus->value.sig = GDB_SIGNAL_SEGV;
+      ourstatus->set_stopped (GDB_SIGNAL_SEGV);
       break;
     case STATUS_FLOAT_DENORMAL_OPERAND:
       DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
-      ourstatus->value.sig = GDB_SIGNAL_FPE;
+      ourstatus->set_stopped (GDB_SIGNAL_FPE);
       break;
     case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
       DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
-      ourstatus->value.sig = GDB_SIGNAL_FPE;
+      ourstatus->set_stopped (GDB_SIGNAL_FPE);
       break;
     case STATUS_FLOAT_INEXACT_RESULT:
       DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
-      ourstatus->value.sig = GDB_SIGNAL_FPE;
+      ourstatus->set_stopped (GDB_SIGNAL_FPE);
       break;
     case STATUS_FLOAT_INVALID_OPERATION:
       DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
-      ourstatus->value.sig = GDB_SIGNAL_FPE;
+      ourstatus->set_stopped (GDB_SIGNAL_FPE);
       break;
     case STATUS_FLOAT_OVERFLOW:
       DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
-      ourstatus->value.sig = GDB_SIGNAL_FPE;
+      ourstatus->set_stopped (GDB_SIGNAL_FPE);
       break;
     case STATUS_FLOAT_STACK_CHECK:
       DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
-      ourstatus->value.sig = GDB_SIGNAL_FPE;
+      ourstatus->set_stopped (GDB_SIGNAL_FPE);
       break;
     case STATUS_FLOAT_UNDERFLOW:
       DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
-      ourstatus->value.sig = GDB_SIGNAL_FPE;
+      ourstatus->set_stopped (GDB_SIGNAL_FPE);
       break;
     case STATUS_FLOAT_DIVIDE_BY_ZERO:
       DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
-      ourstatus->value.sig = GDB_SIGNAL_FPE;
+      ourstatus->set_stopped (GDB_SIGNAL_FPE);
       break;
     case STATUS_INTEGER_DIVIDE_BY_ZERO:
       DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
-      ourstatus->value.sig = GDB_SIGNAL_FPE;
+      ourstatus->set_stopped (GDB_SIGNAL_FPE);
       break;
     case STATUS_INTEGER_OVERFLOW:
       DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
-      ourstatus->value.sig = GDB_SIGNAL_FPE;
+      ourstatus->set_stopped (GDB_SIGNAL_FPE);
       break;
     case EXCEPTION_BREAKPOINT:
 #ifdef __x86_64__
             on startup, first a BREAKPOINT for the 64bit ntdll.dll,
             then a WX86_BREAKPOINT for the 32bit ntdll.dll.
             Here we only care about the WX86_BREAKPOINT's.  */
-         ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+         ourstatus->set_spurious ();
          ignore_first_breakpoint = false;
        }
       else if (wow64_process)
             unconditionally.  */
          DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
          rec->ExceptionCode = DBG_CONTROL_C;
-         ourstatus->value.sig = GDB_SIGNAL_INT;
+         ourstatus->set_stopped (GDB_SIGNAL_INT);
          break;
        }
 #endif
       /* FALLTHROUGH */
     case STATUS_WX86_BREAKPOINT:
       DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
-      ourstatus->value.sig = GDB_SIGNAL_TRAP;
+      ourstatus->set_stopped (GDB_SIGNAL_TRAP);
       break;
     case DBG_CONTROL_C:
       DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
-      ourstatus->value.sig = GDB_SIGNAL_INT;
+      ourstatus->set_stopped (GDB_SIGNAL_INT);
       break;
     case DBG_CONTROL_BREAK:
       DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
-      ourstatus->value.sig = GDB_SIGNAL_INT;
+      ourstatus->set_stopped (GDB_SIGNAL_INT);
       break;
     case EXCEPTION_SINGLE_STEP:
     case STATUS_WX86_SINGLE_STEP:
       DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
-      ourstatus->value.sig = GDB_SIGNAL_TRAP;
+      ourstatus->set_stopped (GDB_SIGNAL_TRAP);
       break;
     case EXCEPTION_ILLEGAL_INSTRUCTION:
       DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
-      ourstatus->value.sig = GDB_SIGNAL_ILL;
+      ourstatus->set_stopped (GDB_SIGNAL_ILL);
       break;
     case EXCEPTION_PRIV_INSTRUCTION:
       DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
-      ourstatus->value.sig = GDB_SIGNAL_ILL;
+      ourstatus->set_stopped (GDB_SIGNAL_ILL);
       break;
     case EXCEPTION_NONCONTINUABLE_EXCEPTION:
       DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
-      ourstatus->value.sig = GDB_SIGNAL_ILL;
+      ourstatus->set_stopped (GDB_SIGNAL_ILL);
       break;
     case MS_VC_EXCEPTION:
       DEBUG_EXCEPTION_SIMPLE ("MS_VC_EXCEPTION");
       if (handle_ms_vc_exception (rec))
        {
-         ourstatus->value.sig = GDB_SIGNAL_TRAP;
+         ourstatus->set_stopped (GDB_SIGNAL_TRAP);
          result = HANDLE_EXCEPTION_IGNORED;
          break;
        }
        (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionCode,
        host_address_to_string (
          current_event.u.Exception.ExceptionRecord.ExceptionAddress));
-      ourstatus->value.sig = GDB_SIGNAL_UNKNOWN;
+      ourstatus->set_stopped (GDB_SIGNAL_UNKNOWN);
       break;
     }
 
-  last_sig = ourstatus->value.sig;
+  if (ourstatus->kind () == TARGET_WAITKIND_STOPPED)
+    last_sig = ourstatus->sig ();
+
   return result;
 
 #undef DEBUG_EXCEPTION_SIMPLE
 
   ptid_t wptid = ptid_t (pid);
 
   /* If the child stopped, keep investigating its status.  */
-  if (ourstatus->kind != TARGET_WAITKIND_STOPPED)
+  if (ourstatus->kind () != TARGET_WAITKIND_STOPPED)
     return wptid;
 
   /* Extract the event and thread that received a signal.  */
         Ignore exited events for an unknown LWP.  */
       thread_info *thr = find_thread_ptid (this, wptid);
       if (thr == nullptr)
-         ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+         ourstatus->set_spurious ();
       else
        {
-         ourstatus->kind = TARGET_WAITKIND_THREAD_EXITED;
          /* NetBSD does not store an LWP exit status.  */
-         ourstatus->value.integer = 0;
+         ourstatus->set_thread_exited (0);
 
          if (print_thread_events)
            printf_unfiltered (_("[%s exited]\n"),
         not yet reported their PTRACE_LWP_CREATE event.  Ignore
         born events for an already-known LWP.  */
       if (in_thread_list (this, wptid))
-         ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+         ourstatus->set_spurious ();
       else
        {
          add_thread (this, wptid);
-         ourstatus->kind = TARGET_WAITKIND_THREAD_CREATED;
+         ourstatus->set_thread_created ();
        }
       return wptid;
     }
 
   if (code == TRAP_EXEC)
     {
-      ourstatus->kind = TARGET_WAITKIND_EXECD;
-      ourstatus->value.execd_pathname = xstrdup (pid_to_exec_file (pid));
+      ourstatus->set_execd (make_unique_xstrdup (pid_to_exec_file (pid)));
       return wptid;
     }
 
       if (!catch_syscall_enabled () || !catching_syscall_number (sysnum))
        {
          /* If the core isn't interested in this event, ignore it.  */
-         ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+         ourstatus->set_spurious ();
          return wptid;
        }
 
-      ourstatus->kind =
-       (code == TRAP_SCE) ? TARGET_WAITKIND_SYSCALL_ENTRY :
-       TARGET_WAITKIND_SYSCALL_RETURN;
-      ourstatus->value.syscall_number = sysnum;
+      if (code == TRAP_SCE)
+       ourstatus->set_syscall_entry (sysnum);
+      else
+       ourstatus->set_syscall_return (sysnum);
       return wptid;
     }
 
     }
 
   /* Unclassified SIGTRAP event.  */
-  ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+  ourstatus->set_spurious ();
   return wptid;
 }
 
 
   procfs_status status;
   static int exit_signo = 0;   /* To track signals that cause termination.  */
 
-  ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+  ourstatus->set_spurious ();
 
   if (inferior_ptid == null_ptid)
     {
-      ourstatus->kind = TARGET_WAITKIND_STOPPED;
-      ourstatus->value.sig = GDB_SIGNAL_0;
+      ourstatus->set_stopped (GDB_SIGNAL_0);
       exit_signo = 0;
       return null_ptid;
     }
   nto_inferior_data (NULL)->stopped_pc = status.ip;
 
   if (status.flags & _DEBUG_FLAG_SSTEP)
-    {
-      ourstatus->kind = TARGET_WAITKIND_STOPPED;
-      ourstatus->value.sig = GDB_SIGNAL_TRAP;
-    }
+    ourstatus->set_stopped (GDB_SIGNAL_TRAP);
   /* Was it a breakpoint?  */
   else if (status.flags & _DEBUG_FLAG_TRACE)
-    {
-      ourstatus->kind = TARGET_WAITKIND_STOPPED;
-      ourstatus->value.sig = GDB_SIGNAL_TRAP;
-    }
+    ourstatus->set_stopped (GDB_SIGNAL_TRAP);
   else if (status.flags & _DEBUG_FLAG_ISTOP)
     {
       switch (status.why)
        {
        case _DEBUG_WHY_SIGNALLED:
-         ourstatus->kind = TARGET_WAITKIND_STOPPED;
-         ourstatus->value.sig =
-           gdb_signal_from_host (status.info.si_signo);
+         ourstatus->set_stopped (gdb_signal_from_host (status.info.si_signo));
          exit_signo = 0;
          break;
        case _DEBUG_WHY_FAULTED:
-         ourstatus->kind = TARGET_WAITKIND_STOPPED;
          if (status.info.si_signo == SIGTRAP)
            {
-             ourstatus->value.sig = 0;
+             ourstatus->set_stopped (0);
              exit_signo = 0;
            }
          else
            {
-             ourstatus->value.sig =
-               gdb_signal_from_host (status.info.si_signo);
-             exit_signo = ourstatus->value.sig;
+             ourstatus->set_stopped
+               (gdb_signal_from_host (status.info.si_signo));
+             exit_signo = ourstatus->sig ();
            }
          break;
 
            if (exit_signo)
              {
                /* Abnormal death.  */
-               ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
-               ourstatus->value.sig = exit_signo;
+               ourstatus->set_signalled (exit_signo);
              }
            else
              {
                /* Normal death.  */
-               ourstatus->kind = TARGET_WAITKIND_EXITED;
-               ourstatus->value.integer = WEXITSTATUS (waitval);
+               ourstatus->set_exited (WEXITSTATUS (waitval));
              }
            exit_signo = 0;
            break;
 
        case _DEBUG_WHY_REQUESTED:
          /* We are assuming a requested stop is due to a SIGINT.  */
-         ourstatus->kind = TARGET_WAITKIND_STOPPED;
-         ourstatus->value.sig = GDB_SIGNAL_INT;
+         ourstatus->set_stopped (GDB_SIGNAL_INT);
          exit_signo = 0;
          break;
        }
 
                       target_wait_flags options)
 {
   ptid_t wptid = inf_ptrace_target::wait (ptid, ourstatus, options);
-  if (ourstatus->kind == TARGET_WAITKIND_STOPPED)
+  if (ourstatus->kind () == TARGET_WAITKIND_STOPPED)
     {
       ptrace_state_t pe;
 
       switch (pe.pe_report_event)
        {
        case PTRACE_FORK:
-         ourstatus->kind = TARGET_WAITKIND_FORKED;
-         ourstatus->value.related_pid = ptid_t (pe.pe_other_pid);
+         ourstatus->set_forked (ptid_t (pe.pe_other_pid));
 
          /* Make sure the other end of the fork is stopped too.  */
          pid_t fpid = waitpid (pe.pe_other_pid, nullptr, 0);
          gdb_assert (pe.pe_other_pid == pid);
          if (find_inferior_pid (this, fpid) != nullptr)
            {
-             ourstatus->value.related_pid = ptid_t (pe.pe_other_pid);
+             ourstatus->set_forked (ptid_t (pe.pe_other_pid));
              wptid = ptid_t (fpid, pe.pe_tid, 0);
            }
 
-         obsd_enable_proc_events (ourstatus->value.related_pid.pid ());
+         obsd_enable_proc_events (ourstatus->child_ptid ().pid ());
          break;
        }
 
 
   get_last_target_status (&wait_target, &wait_ptid, &wait_status);
   if (wait_target == &the_procfs_target
       && wait_ptid == inferior_ptid
-      && wait_status.kind == TARGET_WAITKIND_STOPPED
-      && wait_status.value.sig == gdb_signal_from_host (signo)
+      && wait_status.kind () == TARGET_WAITKIND_STOPPED
+      && wait_status.sig () == gdb_signal_from_host (signo)
       && proc_get_status (pi)
       && pi->prstatus.pr_lwp.pr_info.si_signo == signo
       )
                      printf_unfiltered (_("[%s exited]\n"),
                                         target_pid_to_str (retval).c_str ());
                    delete_thread (find_thread_ptid (this, retval));
-                   status->kind = TARGET_WAITKIND_SPURIOUS;
+                   status->set_spurious ();
                    return retval;
                  }
                else
                    if (!in_thread_list (this, temp_ptid))
                      add_thread (this, temp_ptid);
 
-                   status->kind = TARGET_WAITKIND_STOPPED;
-                   status->value.sig = GDB_SIGNAL_0;
+                   status->set_stopped (GDB_SIGNAL_0);
                    return retval;
                  }
 #endif
 
      this causes problems when debugging through the remote protocol,
      because we might try switching threads (and thus sending packets)
      after the remote has disconnected.  */
-  if (status->kind != TARGET_WAITKIND_EXITED
-      && status->kind != TARGET_WAITKIND_SIGNALLED
+  if (status->kind () != TARGET_WAITKIND_EXITED
+      && status->kind () != TARGET_WAITKIND_SIGNALLED
       && runtime_initialized ())
     {
       m_base_ptid = event_ptid;
 
 {
   struct target_waitstatus status;
 
-  status.kind = TARGET_WAITKIND_NO_HISTORY;
+  status.set_no_history ();
 
   return status;
 }
 {
   struct target_waitstatus status;
 
-  status.kind = TARGET_WAITKIND_STOPPED;
-  status.value.sig = GDB_SIGNAL_TRAP;
+  status.set_stopped (GDB_SIGNAL_TRAP);
 
   return status;
 }
 {
   struct target_waitstatus status;
 
-  status.kind = TARGET_WAITKIND_STOPPED;
-  status.value.sig = GDB_SIGNAL_0;
+  status.set_stopped (GDB_SIGNAL_0);
 
   return status;
 }
 {
   struct target_waitstatus status;
 
-  status.kind = TARGET_WAITKIND_SPURIOUS;
+  status.set_spurious ();
 
   return status;
 }
 {
   struct target_waitstatus status;
 
-  status.kind = TARGET_WAITKIND_NO_RESUMED;
+  status.set_no_resumed ();
 
   return status;
 }
 {
   struct target_waitstatus status;
 
-  status.kind = TARGET_WAITKIND_IGNORE;
+  status.set_ignore ();
 
   return status;
 }
 
     case BTHR_STEP:
       status = record_btrace_single_step_forward (tp);
-      if (status.kind != TARGET_WAITKIND_SPURIOUS)
+      if (status.kind () != TARGET_WAITKIND_SPURIOUS)
        break;
 
       return btrace_step_stopped ();
 
     case BTHR_RSTEP:
       status = record_btrace_single_step_backward (tp);
-      if (status.kind != TARGET_WAITKIND_SPURIOUS)
+      if (status.kind () != TARGET_WAITKIND_SPURIOUS)
        break;
 
       return btrace_step_stopped ();
 
     case BTHR_CONT:
       status = record_btrace_single_step_forward (tp);
-      if (status.kind != TARGET_WAITKIND_SPURIOUS)
+      if (status.kind () != TARGET_WAITKIND_SPURIOUS)
        break;
 
       btinfo->flags |= flags;
 
     case BTHR_RCONT:
       status = record_btrace_single_step_backward (tp);
-      if (status.kind != TARGET_WAITKIND_SPURIOUS)
+      if (status.kind () != TARGET_WAITKIND_SPURIOUS)
        break;
 
       btinfo->flags |= flags;
 
   /* We keep threads moving at the end of their execution history.  The wait
      method will stop the thread for whom the event is reported.  */
-  if (status.kind == TARGET_WAITKIND_NO_HISTORY)
+  if (status.kind () == TARGET_WAITKIND_NO_HISTORY)
     btinfo->flags |= flags;
 
   return status;
 
          *status = record_btrace_step_thread (tp);
 
-         switch (status->kind)
+         switch (status->kind ())
            {
            case TARGET_WAITKIND_IGNORE:
              ix++;
 
       gdb_assert ((options & TARGET_WNOHANG) != 0);
 
       /* No interesting event.  */
-      status->kind = TARGET_WAITKIND_IGNORE;
+      status->set_ignore ();
       return minus_one_ptid;
     }
 
          while (1)
            {
              ret = ops->beneath ()->wait (ptid, status, options);
-             if (status->kind == TARGET_WAITKIND_IGNORE)
+             if (status->kind () == TARGET_WAITKIND_IGNORE)
                {
                  if (record_debug)
                    fprintf_unfiltered (gdb_stdlog,
                return ret;
 
              /* Is this a SIGTRAP?  */
-             if (status->kind == TARGET_WAITKIND_STOPPED
-                 && status->value.sig == GDB_SIGNAL_TRAP)
+             if (status->kind () == TARGET_WAITKIND_STOPPED
+                 && status->sig () == GDB_SIGNAL_TRAP)
                {
                  struct regcache *regcache;
                  enum target_stop_reason *stop_reason_p
                      if (!record_full_message_wrapper_safe (regcache,
                                                             GDB_SIGNAL_0))
                        {
-                          status->kind = TARGET_WAITKIND_STOPPED;
-                          status->value.sig = GDB_SIGNAL_0;
+                          status->set_stopped (GDB_SIGNAL_0);
                           break;
                        }
 
          CORE_ADDR tmp_pc;
 
          record_full_stop_reason = TARGET_STOPPED_BY_NO_REASON;
-         status->kind = TARGET_WAITKIND_STOPPED;
+         status->set_stopped (GDB_SIGNAL_0);
 
          /* Check breakpoint when forward execute.  */
          if (execution_direction == EXEC_FORWARD)
                  && record_full_list == &record_full_first)
                {
                  /* Hit beginning of record log in reverse.  */
-                 status->kind = TARGET_WAITKIND_NO_HISTORY;
+                 status->set_no_history ();
                  break;
                }
              if (execution_direction != EXEC_REVERSE
                  && !record_full_list->next)
                {
                  /* Hit end of record log going forward.  */
-                 status->kind = TARGET_WAITKIND_NO_HISTORY;
+                 status->set_no_history ();
                  break;
                }
 
          while (continue_flag);
 
        replay_out:
-         if (record_full_get_sig)
-           status->value.sig = GDB_SIGNAL_INT;
-         else if (record_full_list->u.end.sigval != GDB_SIGNAL_0)
-           /* FIXME: better way to check */
-           status->value.sig = record_full_list->u.end.sigval;
-         else
-           status->value.sig = GDB_SIGNAL_TRAP;
+         if (status->kind () == TARGET_WAITKIND_STOPPED)
+           {
+             if (record_full_get_sig)
+               status->set_stopped (GDB_SIGNAL_INT);
+             else if (record_full_list->u.end.sigval != GDB_SIGNAL_0)
+               /* FIXME: better way to check */
+               status->set_stopped (record_full_list->u.end.sigval);
+             else
+               status->set_stopped (GDB_SIGNAL_TRAP);
+           }
        }
       catch (const gdb_exception &ex)
        {
   clear_async_event_handler (record_full_async_inferior_event_token);
 
   return_ptid = record_full_wait_1 (this, ptid, status, options);
-  if (status->kind != TARGET_WAITKIND_IGNORE)
+  if (status->kind () != TARGET_WAITKIND_IGNORE)
     {
       /* We're reporting a stop.  Make sure any spurious
         target_wait(WNOHANG) doesn't advance the target until the
 
        case GDB_SIGNAL_TRAP:
        default:
          status->kind = TARGET_WAITKIND_STOPPED;
-         status->value.sig = (enum gdb_signal) sigrc;
+         status->sig () = (enum gdb_signal) sigrc;
          break;
        }
       break;
     case sim_signalled:
       status->kind = TARGET_WAITKIND_SIGNALLED;
-      status->value.sig = (enum gdb_signal) sigrc;
+      status->sig () = (enum gdb_signal) sigrc;
       break;
     case sim_running:
     case sim_polling:
 
     }
   else
     {
-      ws.kind = TARGET_WAITKIND_STOPPED;
-      ws.value.sig = GDB_SIGNAL_0;
+      ws.set_stopped (GDB_SIGNAL_0);
     }
 
   switch_to_thread (thread);
   /* For "info program".  */
   set_last_target_status (this, thread->ptid, ws);
 
-  if (ws.kind == TARGET_WAITKIND_STOPPED)
+  if (ws.kind () == TARGET_WAITKIND_STOPPED)
     {
-      enum gdb_signal sig = ws.value.sig;
+      enum gdb_signal sig = ws.sig ();
 
       if (signal_print_state (sig))
        gdb::observers::signal_received.notify (sig);
       struct target_waitstatus ws;
       int ignore_event = 0;
 
-      memset (&ws, 0, sizeof (ws));
       event_ptid = target_wait (waiton_ptid, &ws, TARGET_WNOHANG);
       if (remote_debug)
        print_target_wait_results (waiton_ptid, event_ptid, &ws);
 
-      switch (ws.kind)
+      switch (ws.kind ())
        {
        case TARGET_WAITKIND_IGNORE:
        case TARGET_WAITKIND_NO_RESUMED:
          ignore_event = 1;
          break;
 
-       case TARGET_WAITKIND_EXECD:
-         xfree (ws.value.execd_pathname);
-         break;
        default:
          break;
        }
 
       thread_info *evthread = find_thread_ptid (this, event_ptid);
 
-      if (ws.kind == TARGET_WAITKIND_STOPPED)
+      if (ws.kind () == TARGET_WAITKIND_STOPPED)
        {
-         enum gdb_signal sig = ws.value.sig;
+         enum gdb_signal sig = ws.sig ();
 
          /* Stubs traditionally report SIGTRAP as initial signal,
             instead of signal 0.  Suppress it.  */
          if (sig == GDB_SIGNAL_TRAP)
            sig = GDB_SIGNAL_0;
          evthread->set_stop_signal (sig);
-         ws.value.sig = sig;
+         ws.set_stopped (sig);
        }
 
-      if (ws.kind != TARGET_WAITKIND_STOPPED
-         || ws.value.sig != GDB_SIGNAL_0)
+      if (ws.kind () != TARGET_WAITKIND_STOPPED
+         || ws.sig () != GDB_SIGNAL_0)
        evthread->set_pending_waitstatus (ws);
 
       set_executing (this, event_ptid, false);
   /* Check to see if we are detaching a fork parent.  Note that if we
      are detaching a fork child, tp == NULL.  */
   is_fork_parent = (tp != NULL
-                   && tp->pending_follow.kind == TARGET_WAITKIND_FORKED);
+                   && tp->pending_follow.kind () == TARGET_WAITKIND_FORKED);
 
   /* If doing detach-on-fork, we don't mourn, because that will delete
      breakpoints that should be available for the followed inferior.  */
            stop_reply *sr = new stop_reply ();
            sr->ptid = tp->ptid;
            sr->rs = rs;
-           sr->ws.kind = TARGET_WAITKIND_STOPPED;
-           sr->ws.value.sig = GDB_SIGNAL_0;
+           sr->ws.set_stopped (GDB_SIGNAL_0);
            sr->arch = tp->inf->gdbarch;
            sr->stop_reason = TARGET_STOPPED_BY_NO_REASON;
            sr->watch_data_address = 0;
   /* Kind can be TARGET_WAITKIND_IGNORE if we have meanwhile discarded
      the notification.  It was left in the queue because we need to
      acknowledge it and pull the rest of the notifications out.  */
-  if (stop_reply->ws.kind != TARGET_WAITKIND_IGNORE)
+  if (stop_reply->ws.kind () != TARGET_WAITKIND_IGNORE)
     remote->push_stop_reply (stop_reply);
 }
 
 is_pending_fork_parent (const target_waitstatus *ws, int event_pid,
                        ptid_t thread_ptid)
 {
-  if (ws->kind == TARGET_WAITKIND_FORKED
-      || ws->kind == TARGET_WAITKIND_VFORKED)
+  if (ws->kind () == TARGET_WAITKIND_FORKED
+      || ws->kind () == TARGET_WAITKIND_VFORKED)
     {
       if (event_pid == -1 || event_pid == thread_ptid.pid ())
        return 1;
       const target_waitstatus *ws = thread_pending_fork_status (thread);
 
       if (is_pending_fork_parent (ws, pid, thread->ptid))
-       context->remove_thread (ws->value.related_pid);
+       context->remove_thread (ws->child_ptid ());
     }
 
   /* Check for any pending fork events (not reported or processed yet)
      CONTEXT list as well.  */
   remote_notif_get_pending_events (notif);
   for (auto &event : get_remote_state ()->stop_reply_queue)
-    if (event->ws.kind == TARGET_WAITKIND_FORKED
-       || event->ws.kind == TARGET_WAITKIND_VFORKED
-       || event->ws.kind == TARGET_WAITKIND_THREAD_EXITED)
-      context->remove_thread (event->ws.value.related_pid);
+    if (event->ws.kind () == TARGET_WAITKIND_FORKED
+       || event->ws.kind () == TARGET_WAITKIND_VFORKED
+       || event->ws.kind () == TARGET_WAITKIND_THREAD_EXITED)
+      context->remove_thread (event->ws.child_ptid ());
 }
 
 /* Check whether any event pending in the vStopped queue would prevent a
   remote_notif_get_pending_events (notif);
   for (auto &event : get_remote_state ()->stop_reply_queue)
     {
-      if (event->ws.kind == TARGET_WAITKIND_NO_RESUMED
-         || event->ws.kind == TARGET_WAITKIND_NO_HISTORY)
+      if (event->ws.kind () == TARGET_WAITKIND_NO_RESUMED
+         || event->ws.kind () == TARGET_WAITKIND_NO_HISTORY)
        continue;
 
-      if (event->ws.kind == TARGET_WAITKIND_FORKED
-         || event->ws.kind == TARGET_WAITKIND_VFORKED)
+      if (event->ws.kind () == TARGET_WAITKIND_FORKED
+         || event->ws.kind () == TARGET_WAITKIND_VFORKED)
        *may_global_wildcard = false;
 
       /* This may be the first time we heard about this process.
       /* Leave the notification pending, since the server expects that
         we acknowledge it with vStopped.  But clear its contents, so
         that later on when we acknowledge it, we also discard it.  */
-      reply->ws.kind = TARGET_WAITKIND_IGNORE;
+      reply->ws.set_ignore ();
 
       if (remote_debug)
        fprintf_unfiltered (gdb_stdlog,
   remote_state *rs = get_remote_state ();
   for (auto &event : rs->stop_reply_queue)
     if (ptid == event->ptid
-       && event->ws.kind == TARGET_WAITKIND_STOPPED)
+       && event->ws.kind () == TARGET_WAITKIND_STOPPED)
       return 1;
   return 0;
 }
 
   event->ptid = null_ptid;
   event->rs = get_remote_state ();
-  event->ws.kind = TARGET_WAITKIND_IGNORE;
-  event->ws.value.integer = 0;
+  event->ws.set_ignore ();
   event->stop_reason = TARGET_STOPPED_BY_NO_REASON;
   event->regcache.clear ();
   event->core = -1;
            {
              ULONGEST sysno;
 
-             event->ws.kind = TARGET_WAITKIND_SYSCALL_ENTRY;
              p = unpack_varlen_hex (++p1, &sysno);
-             event->ws.value.syscall_number = (int) sysno;
+             event->ws.set_syscall_entry ((int) sysno);
            }
          else if (strprefix (p, p1, "syscall_return"))
            {
              ULONGEST sysno;
 
-             event->ws.kind = TARGET_WAITKIND_SYSCALL_RETURN;
              p = unpack_varlen_hex (++p1, &sysno);
-             event->ws.value.syscall_number = (int) sysno;
+             event->ws.set_syscall_return ((int) sysno);
            }
          else if (strprefix (p, p1, "watch")
                   || strprefix (p, p1, "rwatch")
            }
          else if (strprefix (p, p1, "library"))
            {
-             event->ws.kind = TARGET_WAITKIND_LOADED;
+             event->ws.set_loaded ();
              p = strchrnul (p1 + 1, ';');
            }
          else if (strprefix (p, p1, "replaylog"))
            {
-             event->ws.kind = TARGET_WAITKIND_NO_HISTORY;
+             event->ws.set_no_history ();
              /* p1 will indicate "begin" or "end", but it makes
                 no difference for now, so ignore it.  */
              p = strchrnul (p1 + 1, ';');
              event->core = c;
            }
          else if (strprefix (p, p1, "fork"))
-           {
-             event->ws.value.related_pid = read_ptid (++p1, &p);
-             event->ws.kind = TARGET_WAITKIND_FORKED;
-           }
+           event->ws.set_forked (read_ptid (++p1, &p));
          else if (strprefix (p, p1, "vfork"))
-           {
-             event->ws.value.related_pid = read_ptid (++p1, &p);
-             event->ws.kind = TARGET_WAITKIND_VFORKED;
-           }
+           event->ws.set_vforked (read_ptid (++p1, &p));
          else if (strprefix (p, p1, "vforkdone"))
            {
-             event->ws.kind = TARGET_WAITKIND_VFORK_DONE;
+             event->ws.set_vfork_done ();
              p = strchrnul (p1 + 1, ';');
            }
          else if (strprefix (p, p1, "exec"))
 
              /* Save the pathname for event reporting and for
                 the next run command.  */
-             gdb::unique_xmalloc_ptr<char[]> pathname
+             gdb::unique_xmalloc_ptr<char> pathname
                ((char *) xmalloc (pathlen + 1));
              hex2bin (p1, (gdb_byte *) pathname.get (), pathlen);
-             pathname[pathlen] = '\0';
+             pathname.get ()[pathlen] = '\0';
 
              /* This is freed during event handling.  */
-             event->ws.value.execd_pathname = pathname.release ();
-             event->ws.kind = TARGET_WAITKIND_EXECD;
+             event->ws.set_execd (std::move (pathname));
 
              /* Skip the registers included in this packet, since
                 they may be for an architecture different from the
            }
          else if (strprefix (p, p1, "create"))
            {
-             event->ws.kind = TARGET_WAITKIND_THREAD_CREATED;
+             event->ws.set_thread_created ();
              p = strchrnul (p1 + 1, ';');
            }
          else
          ++p;
        }
 
-      if (event->ws.kind != TARGET_WAITKIND_IGNORE)
+      if (event->ws.kind () != TARGET_WAITKIND_IGNORE)
        break;
 
       /* fall through */
       {
        int sig;
 
-       event->ws.kind = TARGET_WAITKIND_STOPPED;
        sig = (fromhex (buf[1]) << 4) + fromhex (buf[2]);
        if (GDB_SIGNAL_FIRST <= sig && sig < GDB_SIGNAL_LAST)
-         event->ws.value.sig = (enum gdb_signal) sig;
+         event->ws.set_stopped ((enum gdb_signal) sig);
        else
-         event->ws.value.sig = GDB_SIGNAL_UNKNOWN;
+         event->ws.set_stopped (GDB_SIGNAL_UNKNOWN);
       }
       break;
     case 'w':          /* Thread exited.  */
       {
        ULONGEST value;
 
-       event->ws.kind = TARGET_WAITKIND_THREAD_EXITED;
        p = unpack_varlen_hex (&buf[1], &value);
-       event->ws.value.integer = value;
+       event->ws.set_thread_exited (value);
        if (*p != ';')
          error (_("stop reply packet badly formatted: %s"), buf);
        event->ptid = read_ptid (++p, NULL);
        if (buf[0] == 'W')
          {
            /* The remote process exited.  */
-           event->ws.kind = TARGET_WAITKIND_EXITED;
-           event->ws.value.integer = value;
+           event->ws.set_exited (value);
          }
        else
          {
            /* The remote process exited with a signal.  */
-           event->ws.kind = TARGET_WAITKIND_SIGNALLED;
            if (GDB_SIGNAL_FIRST <= value && value < GDB_SIGNAL_LAST)
-             event->ws.value.sig = (enum gdb_signal) value;
+             event->ws.set_signalled ((enum gdb_signal) value);
            else
-             event->ws.value.sig = GDB_SIGNAL_UNKNOWN;
+             event->ws.set_signalled (GDB_SIGNAL_UNKNOWN);
          }
 
        /* If no process is specified, return null_ptid, and let the
       }
       break;
     case 'N':
-      event->ws.kind = TARGET_WAITKIND_NO_RESUMED;
+      event->ws.set_no_resumed ();
       event->ptid = minus_one_ptid;
       break;
     }
   /* Some stop events apply to all threads in an inferior, while others
      only apply to a single thread.  */
   bool process_wide_stop
-    = (status->kind == TARGET_WAITKIND_EXITED
-       || status->kind == TARGET_WAITKIND_SIGNALLED);
+    = (status->kind () == TARGET_WAITKIND_EXITED
+       || status->kind () == TARGET_WAITKIND_SIGNALLED);
 
   remote_debug_printf ("process_wide_stop = %d", process_wide_stop);
 
     ptid = select_thread_for_ambiguous_stop_reply (status);
   gdb_assert (ptid != null_ptid);
 
-  if (status->kind != TARGET_WAITKIND_EXITED
-      && status->kind != TARGET_WAITKIND_SIGNALLED
-      && status->kind != TARGET_WAITKIND_NO_RESUMED)
+  if (status->kind () != TARGET_WAITKIND_EXITED
+      && status->kind () != TARGET_WAITKIND_SIGNALLED
+      && status->kind () != TARGET_WAITKIND_NO_RESUMED)
     {
       /* Expedited registers.  */
       if (!stop_reply->regcache.empty ())
         return to the event loop.  */
       if (options & TARGET_WNOHANG)
        {
-         status->kind = TARGET_WAITKIND_IGNORE;
+         status->set_ignore ();
          return minus_one_ptid;
        }
 
 
  again:
 
-  status->kind = TARGET_WAITKIND_IGNORE;
-  status->value.integer = 0;
+  status->set_ignore ();
 
   stop_reply = queued_stop_reply (ptid);
   if (stop_reply != NULL)
 
       if (!rs->waiting_for_stop_reply)
        {
-         status->kind = TARGET_WAITKIND_NO_RESUMED;
+         status->set_no_resumed ();
          return minus_one_ptid;
        }
 
       rs->waiting_for_stop_reply = 0;
 
       warning (_("Remote failure reply: %s"), buf);
-      status->kind = TARGET_WAITKIND_STOPPED;
-      status->value.sig = GDB_SIGNAL_0;
+      status->set_stopped (GDB_SIGNAL_0);
       break;
     case 'F':          /* File-I/O request.  */
       /* GDB may access the inferior memory while handling the File-I/O
       break;
     }
 
-  if (status->kind == TARGET_WAITKIND_NO_RESUMED)
+  if (status->kind () == TARGET_WAITKIND_NO_RESUMED)
     return minus_one_ptid;
-  else if (status->kind == TARGET_WAITKIND_IGNORE)
+  else if (status->kind () == TARGET_WAITKIND_IGNORE)
     {
       /* Nothing interesting happened.  If we're doing a non-blocking
         poll, we're done.  Otherwise, go back to waiting.  */
       else
        goto again;
     }
-  else if (status->kind != TARGET_WAITKIND_EXITED
-          && status->kind != TARGET_WAITKIND_SIGNALLED)
+  else if (status->kind () != TARGET_WAITKIND_EXITED
+          && status->kind () != TARGET_WAITKIND_SIGNALLED)
     {
       if (event_ptid != null_ptid)
        record_currthread (rs, event_ptid);
 
       if (is_pending_fork_parent (ws, pid, thread->ptid))
        {
-         int child_pid = ws->value.related_pid.pid ();
+         int child_pid = ws->child_ptid ().pid ();
          int res;
 
          res = remote_vkill (child_pid);
   for (auto &event : rs->stop_reply_queue)
     if (is_pending_fork_parent (&event->ws, pid, event->ptid))
       {
-       int child_pid = event->ws.value.related_pid.pid ();
+       int child_pid = event->ws.child_ptid ().pid ();
        int res;
 
        res = remote_vkill (child_pid);
 
                              safe_strerror (save_errno));
 
          /* Claim it exited with unknown signal.  */
-         ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
-         ourstatus->value.sig = GDB_SIGNAL_UNKNOWN;
+         ourstatus->set_signalled (GDB_SIGNAL_UNKNOWN);
          return inferior_ptid;
        }
 
 
   /* stop after load" status.  */
   if (status == 0x57c)
-    ourstatus->kind = TARGET_WAITKIND_LOADED;
+    ourstatus->set_loaded ();
   /* signal 0.  I have no idea why wait(2) returns with this status word.  */
   else if (status == 0x7f)
-    ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+    ourstatus->set_spurious ();
   /* A normal waitstatus.  Let the usual macros deal with it.  */
   else
     store_waitstatus (ourstatus, status);
 
 
   ptid_t rtnval = beneath ()->wait (ptid, ourstatus, options);
 
-  if (ourstatus->kind != TARGET_WAITKIND_EXITED)
+  if (ourstatus->kind () != TARGET_WAITKIND_EXITED)
     {
       /* Map the LWP of interest back to the appropriate thread ID.  */
       ptid_t thr_ptid = lwp_to_thread (rtnval);
 
                     ptid_t ptid, struct target_waitstatus *status,
                     target_wait_flags options)
 {
-  status->kind = TARGET_WAITKIND_IGNORE;
+  status->set_ignore ();
   return minus_one_ptid;
 }
 
   non_stop = true;
   target_stop (ptid);
 
-  memset (&status, 0, sizeof (status));
   target_wait (ptid, &status, 0);
 
   non_stop = was_non_stop;
 
 {
   const char *kind_str = "status->kind = ";
 
-  switch (ws->kind)
+  switch (ws->kind ())
     {
     case TARGET_WAITKIND_EXITED:
       return string_printf ("%sexited, status = %d",
-                           kind_str, ws->value.integer);
+                           kind_str, ws->exit_status ());
 
     case TARGET_WAITKIND_STOPPED:
       return string_printf ("%sstopped, signal = %s",
                            kind_str,
-                           gdb_signal_to_symbol_string (ws->value.sig));
+                           gdb_signal_to_symbol_string (ws->sig ()));
 
     case TARGET_WAITKIND_SIGNALLED:
       return string_printf ("%ssignalled, signal = %s",
                            kind_str,
-                           gdb_signal_to_symbol_string (ws->value.sig));
+                           gdb_signal_to_symbol_string (ws->sig ()));
 
     case TARGET_WAITKIND_LOADED:
       return string_printf ("%sloaded", kind_str);
 
     case TARGET_WAITKIND_FORKED:
-      return string_printf ("%sforked, related_pid = %s", kind_str,
-                           ws->value.related_pid.to_string ().c_str ());
+      return string_printf ("%sforked, child_ptid = %s", kind_str,
+                           ws->child_ptid ().to_string ().c_str ());
 
     case TARGET_WAITKIND_VFORKED:
-      return string_printf ("%svforked, related_pid = %s", kind_str,
-                           ws->value.related_pid.to_string ().c_str ());
+      return string_printf ("%svforked, child_ptid = %s", kind_str,
+                           ws->child_ptid ().to_string ().c_str ());
 
     case TARGET_WAITKIND_EXECD:
       return string_printf ("%sexecd, execd_pathname = %s", kind_str,
-                           ws->value.execd_pathname);
+                           ws->execd_pathname ());
 
     case TARGET_WAITKIND_VFORK_DONE:
       return string_printf ("%svfork-done", kind_str);
 
     case TARGET_WAITKIND_THREAD_EXITED:
       return string_printf ("%sthread exited, status = %d",
-                           kind_str, ws->value.integer);
+                           kind_str, ws->exit_status ());
 
     default:
       return string_printf ("%sunknown???", kind_str);
 
 
 struct target_waitstatus
 {
-  enum target_waitkind kind;
+  /* Default constructor.  */
+  target_waitstatus () = default;
+
+  /* Copy constructor.  */
+
+  target_waitstatus (const target_waitstatus &other)
+  {
+    m_kind = other.m_kind;
+    m_value = other.m_value;
+
+    if (m_kind == TARGET_WAITKIND_EXECD)
+      m_value.execd_pathname = xstrdup (m_value.execd_pathname);
+  }
+
+  /* Move constructor.  */
+
+  target_waitstatus (target_waitstatus &&other)
+  {
+    m_kind = other.m_kind;
+    m_value = other.m_value;
+
+    if (m_kind == TARGET_WAITKIND_EXECD)
+      other.m_value.execd_pathname = nullptr;
+
+    other.reset ();
+  }
+
+  /* Copy assignment operator.  */
+
+  target_waitstatus &operator= (const target_waitstatus &rhs)
+  {
+    this->reset ();
+    m_kind = rhs.m_kind;
+    m_value = rhs.m_value;
+
+    if (m_kind == TARGET_WAITKIND_EXECD)
+      m_value.execd_pathname = xstrdup (m_value.execd_pathname);
+
+    return *this;
+  }
+
+  /* Move assignment operator.  */
+
+  target_waitstatus &operator= (target_waitstatus &&rhs)
+  {
+    this->reset ();
+    m_kind = rhs.m_kind;
+    m_value = rhs.m_value;
+
+    if (m_kind == TARGET_WAITKIND_EXECD)
+      rhs.m_value.execd_pathname = nullptr;
+
+    rhs.reset ();
+
+    return *this;
+  }
+
+  /* Destructor.  */
+
+  ~target_waitstatus ()
+  {
+    this->reset ();
+  }
+
+  /* Setters: set the wait status kind plus any associated data.  */
+
+  void set_exited (int exit_status)
+  {
+    this->reset ();
+    m_kind = TARGET_WAITKIND_EXITED;
+    m_value.exit_status = exit_status;
+  }
+
+  void set_stopped (gdb_signal sig)
+  {
+    this->reset ();
+    m_kind = TARGET_WAITKIND_STOPPED;
+    m_value.sig = sig;
+  }
+
+  void set_signalled (gdb_signal sig)
+  {
+    this->reset ();
+    m_kind = TARGET_WAITKIND_SIGNALLED;
+    m_value.sig = sig;
+  }
+
+  void set_loaded ()
+  {
+    this->reset ();
+    m_kind = TARGET_WAITKIND_LOADED;
+  }
+
+  void set_forked (ptid_t child_ptid)
+  {
+    this->reset ();
+    m_kind = TARGET_WAITKIND_FORKED;
+    m_value.child_ptid = child_ptid;
+  }
+
+  void set_vforked (ptid_t child_ptid)
+  {
+    this->reset ();
+    m_kind = TARGET_WAITKIND_VFORKED;
+    m_value.child_ptid = child_ptid;
+  }
+
+  void set_execd (gdb::unique_xmalloc_ptr<char> execd_pathname)
+  {
+    this->reset ();
+    m_kind = TARGET_WAITKIND_EXECD;
+    m_value.execd_pathname = execd_pathname.release ();
+  }
+
+  void set_vfork_done ()
+  {
+    this->reset ();
+    m_kind = TARGET_WAITKIND_VFORK_DONE;
+  }
+
+  void set_syscall_entry (int syscall_number)
+  {
+    this->reset ();
+    m_kind = TARGET_WAITKIND_SYSCALL_ENTRY;
+    m_value.syscall_number = syscall_number;
+  }
+
+  void set_syscall_return (int syscall_number)
+  {
+    this->reset ();
+    m_kind = TARGET_WAITKIND_SYSCALL_RETURN;
+    m_value.syscall_number = syscall_number;
+  }
+
+  void set_spurious ()
+  {
+    this->reset ();
+    m_kind = TARGET_WAITKIND_SPURIOUS;
+  }
+
+  void set_ignore ()
+  {
+    this->reset ();
+    m_kind = TARGET_WAITKIND_IGNORE;
+  }
+
+  void set_no_history ()
+  {
+    this->reset ();
+    m_kind = TARGET_WAITKIND_NO_HISTORY;
+  }
+
+  void set_no_resumed ()
+  {
+    this->reset ();
+    m_kind = TARGET_WAITKIND_NO_RESUMED;
+  }
+
+  void set_thread_created ()
+  {
+    this->reset ();
+    m_kind = TARGET_WAITKIND_THREAD_CREATED;
+  }
+
+  void set_thread_exited (int exit_status)
+  {
+    this->reset ();
+    m_kind = TARGET_WAITKIND_THREAD_EXITED;
+    m_value.exit_status = exit_status;
+  }
+
+  /* Get the kind of this wait status.  */
+
+  target_waitkind kind () const
+  {
+    return m_kind;
+  }
+
+  /* Getters for the associated data.
+
+     Getters can only be used if the wait status is of the appropriate kind.
+     See the setters above or the assertions below to know which data is
+     associated to which kind.  */
+
+  int exit_status () const
+  {
+    gdb_assert (m_kind == TARGET_WAITKIND_EXITED
+               || m_kind == TARGET_WAITKIND_THREAD_EXITED);
+    return m_value.exit_status;
+  }
+
+  gdb_signal sig () const
+  {
+    gdb_assert (m_kind == TARGET_WAITKIND_STOPPED
+               || m_kind == TARGET_WAITKIND_SIGNALLED);
+    return m_value.sig;
+  }
+
+  ptid_t child_ptid () const
+  {
+    gdb_assert (m_kind == TARGET_WAITKIND_FORKED
+               || m_kind == TARGET_WAITKIND_VFORKED);
+    return m_value.child_ptid;
+  }
+
+  const char *execd_pathname () const
+  {
+    gdb_assert (m_kind == TARGET_WAITKIND_EXECD);
+    return m_value.execd_pathname;
+  }
+
+  int syscall_number () const
+  {
+    gdb_assert (m_kind == TARGET_WAITKIND_SYSCALL_ENTRY
+               || m_kind == TARGET_WAITKIND_SYSCALL_RETURN);
+    return m_value.syscall_number;
+  }
+
+private:
+  /* Reset the wait status to its original state.  */
+  void reset ()
+  {
+    if (m_kind == TARGET_WAITKIND_EXECD)
+      xfree (m_value.execd_pathname);
+
+    m_kind = TARGET_WAITKIND_IGNORE;
+  }
+
+  target_waitkind m_kind = TARGET_WAITKIND_IGNORE;
 
   /* Additional information about the event.  */
   union
     {
       /* Exit status */
-      int integer;
+      int exit_status;
       /* Signal number */
       enum gdb_signal sig;
       /* Forked child pid */
-      ptid_t related_pid;
+      ptid_t child_ptid;
       /* execd pathname */
       char *execd_pathname;
       /* Syscall number */
       int syscall_number;
-    } value;
+    } m_value;
 };
 
 /* Extended reasons that can explain why a target/thread stopped for a
 
   this->per_inf_num = ++inf_->highest_thread_num;
 
   /* Nothing to follow yet.  */
-  memset (&this->pending_follow, 0, sizeof (this->pending_follow));
-  this->pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
-  this->m_suspend.waitstatus.kind = TARGET_WAITKIND_IGNORE;
+  this->pending_follow.set_spurious ();
 }
 
 /* See gdbthread.h.  */
 
       int sig = strtol (s.get () + sizeof (_CYGWIN_SIGNAL_STRING) - 1, &p, 0);
       gdb_signal gotasig = gdb_signal_from_host (sig);
 
-      ourstatus->value.sig = gotasig;
       if (gotasig)
        {
          LPCVOID x;
          SIZE_T n;
 
-         ourstatus->kind = TARGET_WAITKIND_STOPPED;
+         ourstatus->set_stopped (gotasig);
          retval = strtoul (p, &p, 0);
          if (!retval)
            retval = current_event.dwThreadId;
   continue_status = DBG_CONTINUE;
 
   event_code = current_event.dwDebugEventCode;
-  ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+  ourstatus->set_spurious ();
   have_saved_context = 0;
 
   switch (event_code)
          int exit_signal
            = WIFSIGNALED (exit_status) ? WTERMSIG (exit_status) : -1;
          if (exit_signal == -1)
-           {
-             ourstatus->kind = TARGET_WAITKIND_EXITED;
-             ourstatus->value.integer = exit_status;
-           }
+           ourstatus->set_exited (exit_status);
          else
-           {
-             ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
-             ourstatus->value.sig = gdb_signal_from_host (exit_signal);
-           }
+           ourstatus->set_signalled (gdb_signal_from_host (exit_signal));
+
          thread_id = current_event.dwThreadId;
        }
       break;
       if (saw_create != 1 || ! windows_initialization_done)
        break;
       catch_errors (dll_loaded_event);
-      ourstatus->kind = TARGET_WAITKIND_LOADED;
-      ourstatus->value.integer = 0;
+      ourstatus->set_loaded ();
       thread_id = current_event.dwThreadId;
       break;
 
       if (saw_create != 1 || ! windows_initialization_done)
        break;
       catch_errors (handle_unload_dll);
-      ourstatus->kind = TARGET_WAITKIND_LOADED;
-      ourstatus->value.integer = 0;
+      ourstatus->set_loaded ();
       thread_id = current_event.dwThreadId;
       break;
 
        {
          ptid_t result = ptid_t (current_event.dwProcessId, retval, 0);
 
-         if (ourstatus->kind != TARGET_WAITKIND_EXITED
-             && ourstatus->kind !=  TARGET_WAITKIND_SIGNALLED)
+         if (ourstatus->kind () != TARGET_WAITKIND_EXITED
+             && ourstatus->kind () !=  TARGET_WAITKIND_SIGNALLED)
            {
              windows_thread_info *th = thread_rec (result, INVALIDATE_CONTEXT);
 
 
       /* Note windows_wait returns TARGET_WAITKIND_SPURIOUS for thread
         events.  */
-      if (status.kind != TARGET_WAITKIND_LOADED
-         && status.kind != TARGET_WAITKIND_SPURIOUS)
+      if (status.kind () != TARGET_WAITKIND_LOADED
+         && status.kind () != TARGET_WAITKIND_SPURIOUS)
        break;
 
       this->resume (minus_one_ptid, 0, GDB_SIGNAL_0);
 
 {
   thread_info (ptid_t id, void *target_data)
     : id (id), target_data (target_data)
-  {
-    this->last_status.kind = TARGET_WAITKIND_IGNORE;
-  }
+  {}
 
   ~thread_info ()
   {
 
   struct thread_info *event_thr = get_lwp_thread (event_lwp);
   struct lwp_info *new_lwp;
 
-  gdb_assert (event_lwp->waitstatus.kind == TARGET_WAITKIND_IGNORE);
+  gdb_assert (event_lwp->waitstatus.kind () == TARGET_WAITKIND_IGNORE);
 
   /* All extended events we currently use are mid-syscall.  Only
      PTRACE_EVENT_STOP is delivered more like a signal-stop, but
          child_lwp->status_pending_p = 0;
          child_thr = get_lwp_thread (child_lwp);
          child_thr->last_resume_kind = resume_stop;
-         child_thr->last_status.kind = TARGET_WAITKIND_STOPPED;
+         child_thr->last_status.set_stopped (GDB_SIGNAL_0);
 
          /* If we're suspending all threads, leave this one suspended
             too.  If the fork/clone parent is stepping over a breakpoint,
 
          /* Save fork info in the parent thread.  */
          if (event == PTRACE_EVENT_FORK)
-           event_lwp->waitstatus.kind = TARGET_WAITKIND_FORKED;
+           event_lwp->waitstatus.set_forked (ptid);
          else if (event == PTRACE_EVENT_VFORK)
-           event_lwp->waitstatus.kind = TARGET_WAITKIND_VFORKED;
-
-         event_lwp->waitstatus.value.related_pid = ptid;
+           event_lwp->waitstatus.set_vforked (ptid);
 
          /* The status_pending field contains bits denoting the
             extended event, so when the pending event is handled,
        }
       else if (cs.report_thread_events)
        {
-         new_lwp->waitstatus.kind = TARGET_WAITKIND_THREAD_CREATED;
+         new_lwp->waitstatus.set_thread_created ();
          new_lwp->status_pending_p = 1;
          new_lwp->status_pending = status;
        }
     }
   else if (event == PTRACE_EVENT_VFORK_DONE)
     {
-      event_lwp->waitstatus.kind = TARGET_WAITKIND_VFORK_DONE;
+      event_lwp->waitstatus.set_vfork_done ();
 
       if (event_lwp->bp_reinsert != 0 && supports_software_single_step ())
        {
       arch_setup_thread (event_thr);
 
       /* Set the event status.  */
-      event_lwp->waitstatus.kind = TARGET_WAITKIND_EXECD;
-      event_lwp->waitstatus.value.execd_pathname
-       = xstrdup (linux_proc_pid_to_exec_file (lwpid_of (event_thr)));
+      event_lwp->waitstatus.set_execd
+       (make_unique_xstrdup
+          (linux_proc_pid_to_exec_file (lwpid_of (event_thr))));
 
       /* Mark the exec status as pending.  */
       event_lwp->stopped = 1;
       event_lwp->status_pending_p = 1;
       event_lwp->status_pending = wstat;
       event_thr->last_resume_kind = resume_continue;
-      event_thr->last_status.kind = TARGET_WAITKIND_IGNORE;
+      event_thr->last_status.set_ignore ();
 
       /* Update syscall state in the new lwp, effectively mid-syscall too.  */
       event_lwp->syscall_state = TARGET_WAITKIND_SYSCALL_ENTRY;
       /* If the thread had been suspended by gdbserver, and it stopped
         cleanly, then it'll have stopped with SIGSTOP.  But we don't
         want to deliver that SIGSTOP.  */
-      if (thread->last_status.kind != TARGET_WAITKIND_STOPPED
-         || thread->last_status.value.sig == GDB_SIGNAL_0)
+      if (thread->last_status.kind () != TARGET_WAITKIND_STOPPED
+         || thread->last_status.sig () == GDB_SIGNAL_0)
        return 0;
 
       /* Otherwise, we may need to deliver the signal we
      corresponding stop to gdb yet?  If so, the thread is still
      resumed/running from gdb's perspective.  */
   if (thread->last_resume_kind == resume_stop
-      && thread->last_status.kind == TARGET_WAITKIND_IGNORE)
+      && thread->last_status.kind () == TARGET_WAITKIND_IGNORE)
     return 1;
 
   return 0;
   if (lp->stopped
       && !lp->suspended
       && !lp->status_pending_p
-      && thread->last_status.kind == TARGET_WAITKIND_IGNORE)
+      && thread->last_status.kind () == TARGET_WAITKIND_IGNORE)
     {
       int step = 0;
 
        {
          lwp_info *lp = get_thread_lwp (thread);
 
-         return (thread->last_status.kind == TARGET_WAITKIND_IGNORE
+         return (thread->last_status.kind () == TARGET_WAITKIND_IGNORE
                  && thread->last_resume_kind == resume_step
                  && lp->status_pending_p);
        });
          lwp_info *lp = get_thread_lwp (thread);
 
          /* Only resumed LWPs that have an event pending. */
-         return (thread->last_status.kind == TARGET_WAITKIND_IGNORE
+         return (thread->last_status.kind () == TARGET_WAITKIND_IGNORE
                  && lp->status_pending_p);
        });
     }
         over internal breakpoints and such.  */
       wait_1 (minus_one_ptid, &ourstatus, 0);
 
-      if (ourstatus.kind == TARGET_WAITKIND_STOPPED)
+      if (ourstatus.kind () == TARGET_WAITKIND_STOPPED)
        {
          lwp = get_thread_lwp (current_thread);
 
          /* Lock it.  */
          lwp_suspended_inc (lwp);
 
-         if (ourstatus.value.sig != GDB_SIGNAL_0
+         if (ourstatus.sig () != GDB_SIGNAL_0
              || current_thread->last_resume_kind == resume_stop)
            {
-             wstat = W_STOPCODE (gdb_signal_to_host (ourstatus.value.sig));
+             wstat = W_STOPCODE (gdb_signal_to_host (ourstatus.sig ()));
              enqueue_one_deferred_signal (lwp, &wstat);
            }
        }
      another target_wait call.  */
   async_file_mark ();
 
-  ourstatus->kind = TARGET_WAITKIND_IGNORE;
+  ourstatus->set_ignore ();
   return null_ptid;
 }
 
   if (!last_thread_of_process_p (pid_of (thread)))
     {
       if (cs.report_thread_events)
-       ourstatus->kind = TARGET_WAITKIND_THREAD_EXITED;
+       ourstatus->set_thread_exited (0);
       else
-       ourstatus->kind = TARGET_WAITKIND_IGNORE;
+       ourstatus->set_ignore ();
 
       delete_lwp (event_child);
     }
   bp_explains_trap = 0;
   trace_event = 0;
   in_step_range = 0;
-  ourstatus->kind = TARGET_WAITKIND_IGNORE;
+  ourstatus->set_ignore ();
 
   auto status_pending_p_any = [&] (thread_info *thread)
     {
          debug_exit ();
        }
 
-      ourstatus->kind = TARGET_WAITKIND_IGNORE;
+      ourstatus->set_ignore ();
       return null_ptid;
     }
   else if (pid == -1)
          debug_exit ();
        }
 
-      ourstatus->kind = TARGET_WAITKIND_NO_RESUMED;
+      ourstatus->set_no_resumed ();
       return null_ptid;
     }
 
     {
       if (WIFEXITED (w))
        {
-         ourstatus->kind = TARGET_WAITKIND_EXITED;
-         ourstatus->value.integer = WEXITSTATUS (w);
+         ourstatus->set_exited (WEXITSTATUS (w));
 
          if (debug_threads)
            {
        }
       else
        {
-         ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
-         ourstatus->value.sig = gdb_signal_from_host (WTERMSIG (w));
+         ourstatus->set_signalled (gdb_signal_from_host (WTERMSIG (w)));
 
          if (debug_threads)
            {
            }
        }
 
-      if (ourstatus->kind == TARGET_WAITKIND_EXITED)
+      if (ourstatus->kind () == TARGET_WAITKIND_EXITED)
        return filter_exit_event (event_child, ourstatus);
 
       return ptid_of (current_thread);
 
              if (stabilizing_threads)
                {
-                 ourstatus->kind = TARGET_WAITKIND_STOPPED;
-                 ourstatus->value.sig = GDB_SIGNAL_0;
+                 ourstatus->set_stopped (GDB_SIGNAL_0);
 
                  if (debug_threads)
                    {
                   || (gdb_breakpoint_here (event_child->stop_pc)
                       && gdb_condition_true_at_breakpoint (event_child->stop_pc)
                       && gdb_no_commands_at_breakpoint (event_child->stop_pc))
-                  || event_child->waitstatus.kind != TARGET_WAITKIND_IGNORE);
+                  || event_child->waitstatus.kind () != TARGET_WAITKIND_IGNORE);
 
   run_breakpoint_commands (event_child->stop_pc);
 
 
   if (debug_threads)
     {
-      if (event_child->waitstatus.kind != TARGET_WAITKIND_IGNORE)
+      if (event_child->waitstatus.kind () != TARGET_WAITKIND_IGNORE)
        {
          std::string str
            = target_waitstatus_to_string (&event_child->waitstatus);
        unstop_all_lwps (1, event_child);
     }
 
-  if (event_child->waitstatus.kind != TARGET_WAITKIND_IGNORE)
+  if (event_child->waitstatus.kind () != TARGET_WAITKIND_IGNORE)
     {
       /* If the reported event is an exit, fork, vfork or exec, let
         GDB know.  */
 
       /* Break the unreported fork relationship chain.  */
-      if (event_child->waitstatus.kind == TARGET_WAITKIND_FORKED
-         || event_child->waitstatus.kind == TARGET_WAITKIND_VFORKED)
+      if (event_child->waitstatus.kind () == TARGET_WAITKIND_FORKED
+         || event_child->waitstatus.kind () == TARGET_WAITKIND_VFORKED)
        {
          event_child->fork_relative->fork_relative = NULL;
          event_child->fork_relative = NULL;
 
       *ourstatus = event_child->waitstatus;
       /* Clear the event lwp's waitstatus since we handled it already.  */
-      event_child->waitstatus.kind = TARGET_WAITKIND_IGNORE;
+      event_child->waitstatus.set_ignore ();
     }
   else
-    ourstatus->kind = TARGET_WAITKIND_STOPPED;
+    {
+      /* The actual stop signal is overwritten below.  */
+      ourstatus->set_stopped (GDB_SIGNAL_0);
+    }
 
   /* Now that we've selected our final event LWP, un-adjust its PC if
      it was a software breakpoint, and the client doesn't know we can
 
   if (WSTOPSIG (w) == SYSCALL_SIGTRAP)
     {
-      get_syscall_trapinfo (event_child,
-                           &ourstatus->value.syscall_number);
-      ourstatus->kind = event_child->syscall_state;
+      int syscall_number;
+
+      get_syscall_trapinfo (event_child, &syscall_number);
+      if (event_child->syscall_state == TARGET_WAITKIND_SYSCALL_ENTRY)
+       ourstatus->set_syscall_entry (syscall_number);
+      else if (event_child->syscall_state == TARGET_WAITKIND_SYSCALL_RETURN)
+       ourstatus->set_syscall_return (syscall_number);
+      else
+       gdb_assert_not_reached ("unexpected syscall state");
     }
   else if (current_thread->last_resume_kind == resume_stop
           && WSTOPSIG (w) == SIGSTOP)
       /* A thread that has been requested to stop by GDB with vCont;t,
         and it stopped cleanly, so report as SIG0.  The use of
         SIGSTOP is an implementation detail.  */
-      ourstatus->value.sig = GDB_SIGNAL_0;
+      ourstatus->set_stopped (GDB_SIGNAL_0);
     }
   else if (current_thread->last_resume_kind == resume_stop
           && WSTOPSIG (w) != SIGSTOP)
     {
       /* A thread that has been requested to stop by GDB with vCont;t,
         but, it stopped for other reasons.  */
-      ourstatus->value.sig = gdb_signal_from_host (WSTOPSIG (w));
-    }
-  else if (ourstatus->kind == TARGET_WAITKIND_STOPPED)
-    {
-      ourstatus->value.sig = gdb_signal_from_host (WSTOPSIG (w));
+      ourstatus->set_stopped (gdb_signal_from_host (WSTOPSIG (w)));
     }
+  else if (ourstatus->kind () == TARGET_WAITKIND_STOPPED)
+    ourstatus->set_stopped (gdb_signal_from_host (WSTOPSIG (w)));
 
   gdb_assert (step_over_bkpt == null_ptid);
 
     {
       debug_printf ("wait_1 ret = %s, %d, %d\n",
                    target_pid_to_str (ptid_of (current_thread)),
-                   ourstatus->kind, ourstatus->value.sig);
+                   ourstatus->kind (), ourstatus->sig ());
       debug_exit ();
     }
 
-  if (ourstatus->kind == TARGET_WAITKIND_EXITED)
+  if (ourstatus->kind () == TARGET_WAITKIND_EXITED)
     return filter_exit_event (event_child, ourstatus);
 
   return ptid_of (current_thread);
     }
   while ((target_options & TARGET_WNOHANG) == 0
         && event_ptid == null_ptid
-        && ourstatus->kind == TARGET_WAITKIND_IGNORE);
+        && ourstatus->kind () == TARGET_WAITKIND_IGNORE);
 
   /* If at least one stop was reported, there may be more.  A single
      SIGCHLD can signal more than one child stop.  */
   /* Store in waitstatus as well, as there's nothing else to process
      for this event.  */
   if (WIFEXITED (wstat))
-    {
-      lwp->waitstatus.kind = TARGET_WAITKIND_EXITED;
-      lwp->waitstatus.value.integer = WEXITSTATUS (wstat);
-    }
+    lwp->waitstatus.set_exited (WEXITSTATUS (wstat));
   else if (WIFSIGNALED (wstat))
-    {
-      lwp->waitstatus.kind = TARGET_WAITKIND_SIGNALLED;
-      lwp->waitstatus.value.sig = gdb_signal_from_host (WTERMSIG (wstat));
-    }
+    lwp->waitstatus.set_signalled (gdb_signal_from_host (WTERMSIG (wstat)));
 
   /* Prevent trying to stop it.  */
   lwp->stopped = 1;
   if (lwp->stopped == 0)
     return;
 
-  gdb_assert (lwp->waitstatus.kind == TARGET_WAITKIND_IGNORE);
+  gdb_assert (lwp->waitstatus.kind () == TARGET_WAITKIND_IGNORE);
 
   fast_tpoint_collect_result fast_tp_collecting
     = lwp->collecting_fast_tracepoint;
            {
              if (debug_threads)
                debug_printf ("already %s LWP %ld at GDB's request\n",
-                             (thread->last_status.kind
+                             (thread->last_status.kind ()
                               == TARGET_WAITKIND_STOPPED)
                              ? "stopped"
                              : "stopping",
              struct lwp_info *rel = lwp->fork_relative;
 
              if (rel->status_pending_p
-                 && (rel->waitstatus.kind == TARGET_WAITKIND_FORKED
-                     || rel->waitstatus.kind == TARGET_WAITKIND_VFORKED))
+                 && (rel->waitstatus.kind () == TARGET_WAITKIND_FORKED
+                     || rel->waitstatus.kind () == TARGET_WAITKIND_VFORKED))
                {
                  if (debug_threads)
                    debug_printf ("not resuming LWP %ld: has queued stop reply\n",
 
       /* For stop requests, we're done.  */
       lwp->resume = NULL;
-      thread->last_status.kind = TARGET_WAITKIND_IGNORE;
+      thread->last_status.set_ignore ();
       return;
     }
 
        debug_printf ("leaving LWP %ld stopped\n", lwpid_of (thread));
     }
 
-  thread->last_status.kind = TARGET_WAITKIND_IGNORE;
+  thread->last_status.set_ignore ();
   lwp->resume = NULL;
 }
 
     }
 
   if (thread->last_resume_kind == resume_stop
-      && thread->last_status.kind != TARGET_WAITKIND_IGNORE)
+      && thread->last_status.kind () != TARGET_WAITKIND_IGNORE)
     {
       if (debug_threads)
        debug_printf ("   client wants LWP to remain %ld stopped\n",
 
 
 struct lwp_info
 {
-  lwp_info ()
-  {
-    this->waitstatus.kind = TARGET_WAITKIND_IGNORE;
-  }
-
   /* Backlink to the parent object.  */
   struct thread_info *thread = nullptr;
 
 
 netbsd_store_waitstatus (struct target_waitstatus *ourstatus, int hoststatus)
 {
   if (WIFEXITED (hoststatus))
-    {
-      ourstatus->kind = TARGET_WAITKIND_EXITED;
-      ourstatus->value.integer = WEXITSTATUS (hoststatus);
-    }
+    ourstatus->set_exited (WEXITSTATUS (hoststatus));
   else if (!WIFSTOPPED (hoststatus))
-    {
-      ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
-      ourstatus->value.sig = gdb_signal_from_host (WTERMSIG (hoststatus));
-    }
+    ourstatus->set_signalled (gdb_signal_from_host (WTERMSIG (hoststatus)));
   else
-    {
-      ourstatus->kind = TARGET_WAITKIND_STOPPED;
-      ourstatus->value.sig = gdb_signal_from_host (WSTOPSIG (hoststatus));
-    }
+    ourstatus->set_stopped (gdb_signal_from_host (WSTOPSIG (hoststatus)));
 }
 
 /* Implement a safe wrapper around waitpid().  */
   if (pid == 0)
     {
       gdb_assert (target_options & TARGET_WNOHANG);
-      ourstatus->kind = TARGET_WAITKIND_IGNORE;
+      ourstatus->set_ignore ();
       return null_ptid;
     }
 
   gdb_assert (pid != -1);
 
   /* If the child stopped, keep investigating its status.  */
-  if (ourstatus->kind != TARGET_WAITKIND_STOPPED)
+  if (ourstatus->kind () != TARGET_WAITKIND_STOPPED)
     return wptid;
 
   /* Extract the event and thread that received a signal.  */
         Ignore exited events for an unknown LWP.  */
       thread_info *thr = find_thread_ptid (wptid);
       if (thr == nullptr)
-         ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+         ourstatus->set_spurious ();
       else
        {
-         ourstatus->kind = TARGET_WAITKIND_THREAD_EXITED;
          /* NetBSD does not store an LWP exit status.  */
-         ourstatus->value.integer = 0;
+         ourstatus->set_thread_exited (0);
 
          remove_thread (thr);
        }
         not yet reported their PTRACE_LWP_CREATE event.  Ignore
         born events for an already-known LWP.  */
       if (find_thread_ptid (wptid))
-         ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+       ourstatus->set_spurious ();
       else
        {
          add_thread (wptid, NULL);
-         ourstatus->kind = TARGET_WAITKIND_THREAD_CREATED;
+         ourstatus->set_thread_created ();
        }
       return wptid;
     }
 
   if (code == TRAP_EXEC)
     {
-      ourstatus->kind = TARGET_WAITKIND_EXECD;
-      ourstatus->value.execd_pathname
-       = xstrdup (netbsd_nat::pid_to_exec_file (pid));
+      ourstatus->set_execd
+       (make_unique_xstrdup (netbsd_nat::pid_to_exec_file (pid)));
       return wptid;
     }
 
       if (!netbsd_catch_this_syscall(sysnum))
        {
          /* If the core isn't interested in this event, ignore it.  */
-         ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+         ourstatus->set_spurious ();
          return wptid;
        }
 
-      ourstatus->kind
-       = ((code == TRAP_SCE) ? TARGET_WAITKIND_SYSCALL_ENTRY :
-          TARGET_WAITKIND_SYSCALL_RETURN);
-      ourstatus->value.syscall_number = sysnum;
+      if (code == TRAP_SCE)
+       ourstatus->set_syscall_entry (sysnum);
+      else
+       ourstatus->set_syscall_return (sysnum);
+
       return wptid;
     }
 
     }
 
   /* Unclassified SIGTRAP event.  */
-  ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+  ourstatus->set_spurious ();
   return wptid;
 }
 
         This may also happen on attach, when an event is registered on a thread
         that was not fully initialized during the attach stage.  */
       if (wptid.lwp () != 0 && !find_thread_ptid (wptid)
-         && ourstatus->kind != TARGET_WAITKIND_THREAD_EXITED)
+         && ourstatus->kind () != TARGET_WAITKIND_THREAD_EXITED)
        add_thread (wptid, nullptr);
 
-      switch (ourstatus->kind)
+      switch (ourstatus->kind ())
        {
        case TARGET_WAITKIND_EXITED:
        case TARGET_WAITKIND_STOPPED:
 
   client_state &cs = get_client_state ();
   if (debug_threads)
     debug_printf ("Writing resume reply for %s:%d\n",
-                 target_pid_to_str (ptid), status->kind);
+                 target_pid_to_str (ptid), status->kind ());
 
-  switch (status->kind)
+  switch (status->kind ())
     {
     case TARGET_WAITKIND_STOPPED:
     case TARGET_WAITKIND_FORKED:
        const char **regp;
        struct regcache *regcache;
 
-       if ((status->kind == TARGET_WAITKIND_FORKED && cs.report_fork_events)
-           || (status->kind == TARGET_WAITKIND_VFORKED 
+       if ((status->kind () == TARGET_WAITKIND_FORKED && cs.report_fork_events)
+           || (status->kind () == TARGET_WAITKIND_VFORKED
                && cs.report_vfork_events))
          {
            enum gdb_signal signal = GDB_SIGNAL_TRAP;
-           const char *event = (status->kind == TARGET_WAITKIND_FORKED
+           const char *event = (status->kind () == TARGET_WAITKIND_FORKED
                                 ? "fork" : "vfork");
 
            sprintf (buf, "T%02x%s:", signal, event);
            buf += strlen (buf);
-           buf = write_ptid (buf, status->value.related_pid);
+           buf = write_ptid (buf, status->child_ptid ());
            strcat (buf, ";");
          }
-       else if (status->kind == TARGET_WAITKIND_VFORK_DONE 
+       else if (status->kind () == TARGET_WAITKIND_VFORK_DONE
                 && cs.report_vfork_events)
          {
            enum gdb_signal signal = GDB_SIGNAL_TRAP;
 
            sprintf (buf, "T%02xvforkdone:;", signal);
          }
-       else if (status->kind == TARGET_WAITKIND_EXECD && cs.report_exec_events)
+       else if (status->kind () == TARGET_WAITKIND_EXECD && cs.report_exec_events)
          {
            enum gdb_signal signal = GDB_SIGNAL_TRAP;
            const char *event = "exec";
            buf += strlen (buf);
 
            /* Encode pathname to hexified format.  */
-           bin2hex ((const gdb_byte *) status->value.execd_pathname,
+           bin2hex ((const gdb_byte *) status->execd_pathname (),
                     hexified_pathname,
-                    strlen (status->value.execd_pathname));
+                    strlen (status->execd_pathname ()));
 
            sprintf (buf, "%s;", hexified_pathname);
-           xfree (status->value.execd_pathname);
-           status->value.execd_pathname = NULL;
            buf += strlen (buf);
          }
-       else if (status->kind == TARGET_WAITKIND_THREAD_CREATED
+       else if (status->kind () == TARGET_WAITKIND_THREAD_CREATED
                 && cs.report_thread_events)
          {
            enum gdb_signal signal = GDB_SIGNAL_TRAP;
 
            sprintf (buf, "T%02xcreate:;", signal);
          }
-       else if (status->kind == TARGET_WAITKIND_SYSCALL_ENTRY
-                || status->kind == TARGET_WAITKIND_SYSCALL_RETURN)
+       else if (status->kind () == TARGET_WAITKIND_SYSCALL_ENTRY
+                || status->kind () == TARGET_WAITKIND_SYSCALL_RETURN)
          {
            enum gdb_signal signal = GDB_SIGNAL_TRAP;
-           const char *event = (status->kind == TARGET_WAITKIND_SYSCALL_ENTRY
+           const char *event = (status->kind () == TARGET_WAITKIND_SYSCALL_ENTRY
                                 ? "syscall_entry" : "syscall_return");
 
            sprintf (buf, "T%02x%s:%x;", signal, event,
-                    status->value.syscall_number);
+                    status->syscall_number ());
          }
        else
-         sprintf (buf, "T%02x", status->value.sig);
+         sprintf (buf, "T%02x", status->sig ());
 
        if (disable_packet_T)
          {
     case TARGET_WAITKIND_EXITED:
       if (cs.multi_process)
        sprintf (buf, "W%x;process:%x",
-                status->value.integer, ptid.pid ());
+                status->exit_status (), ptid.pid ());
       else
-       sprintf (buf, "W%02x", status->value.integer);
+       sprintf (buf, "W%02x", status->exit_status ());
       break;
     case TARGET_WAITKIND_SIGNALLED:
       if (cs.multi_process)
        sprintf (buf, "X%x;process:%x",
-                status->value.sig, ptid.pid ());
+                status->sig (), ptid.pid ());
       else
-       sprintf (buf, "X%02x", status->value.sig);
+       sprintf (buf, "X%02x", status->sig ());
       break;
     case TARGET_WAITKIND_THREAD_EXITED:
-      sprintf (buf, "w%x;", status->value.integer);
+      sprintf (buf, "w%x;", status->exit_status ());
       buf += strlen (buf);
       buf = write_ptid (buf, ptid);
       break;
 
     return true;
 
   /* Don't resume fork children that GDB does not know about yet.  */
-  if ((vstop_event->status.kind == TARGET_WAITKIND_FORKED
-       || vstop_event->status.kind == TARGET_WAITKIND_VFORKED)
-      && vstop_event->status.value.related_pid.matches (filter_ptid))
+  if ((vstop_event->status.kind () == TARGET_WAITKIND_FORKED
+       || vstop_event->status.kind () == TARGET_WAITKIND_VFORKED)
+      && vstop_event->status.child_ptid ().matches (filter_ptid))
     return true;
 
   return false;
       /* GDB knows to ignore the first SIGSTOP after attaching to a running
         process using the "attach" command, but this is different; it's
         just using "target remote".  Pretend it's just starting up.  */
-      if (cs.last_status.kind == TARGET_WAITKIND_STOPPED
-         && cs.last_status.value.sig == GDB_SIGNAL_STOP)
-       cs.last_status.value.sig = GDB_SIGNAL_TRAP;
+      if (cs.last_status.kind () == TARGET_WAITKIND_STOPPED
+         && cs.last_status.sig () == GDB_SIGNAL_STOP)
+       cs.last_status.set_stopped (GDB_SIGNAL_TRAP);
 
       current_thread->last_resume_kind = resume_stop;
       current_thread->last_status = cs.last_status;
          /* There is still at least one inferior remaining or
             we are in extended mode, so don't terminate gdbserver,
             and instead treat this like a normal program exit.  */
-         cs.last_status.kind = TARGET_WAITKIND_EXITED;
-         cs.last_status.value.integer = 0;
+         cs.last_status.set_exited (0);
          cs.last_ptid = ptid_t (pid);
 
          current_thread = NULL;
     {
       cs.last_ptid = mywait (minus_one_ptid, &cs.last_status, 0, 1);
 
-      if (cs.last_status.kind == TARGET_WAITKIND_NO_RESUMED
+      if (cs.last_status.kind () == TARGET_WAITKIND_NO_RESUMED
          && !report_no_resumed)
        {
          /* The client does not support this stop reply.  At least
          return;
        }
 
-      if (cs.last_status.kind != TARGET_WAITKIND_EXITED
-         && cs.last_status.kind != TARGET_WAITKIND_SIGNALLED
-         && cs.last_status.kind != TARGET_WAITKIND_NO_RESUMED)
+      if (cs.last_status.kind () != TARGET_WAITKIND_EXITED
+         && cs.last_status.kind () != TARGET_WAITKIND_SIGNALLED
+         && cs.last_status.kind () != TARGET_WAITKIND_NO_RESUMED)
        current_thread->last_status = cs.last_status;
 
       /* From the client's perspective, all-stop mode always stops all
       prepare_resume_reply (cs.own_buf, cs.last_ptid, &cs.last_status);
       disable_async_io ();
 
-      if (cs.last_status.kind == TARGET_WAITKIND_EXITED
-         || cs.last_status.kind == TARGET_WAITKIND_SIGNALLED)
+      if (cs.last_status.kind () == TARGET_WAITKIND_EXITED
+         || cs.last_status.kind () == TARGET_WAITKIND_SIGNALLED)
        target_mourn_inferior (cs.last_ptid);
     }
 }
 
   target_create_inferior (program_path.get (), program_args);
 
-  if (cs.last_status.kind == TARGET_WAITKIND_STOPPED)
+  if (cs.last_status.kind () == TARGET_WAITKIND_STOPPED)
     {
       prepare_resume_reply (own_buf, cs.last_ptid, &cs.last_status);
 
 
   if (proc != nullptr && kill_inferior (proc) == 0)
     {
-      cs.last_status.kind = TARGET_WAITKIND_SIGNALLED;
-      cs.last_status.value.sig = GDB_SIGNAL_KILL;
+      cs.last_status.set_signalled (GDB_SIGNAL_KILL);
       cs.last_ptid = ptid_t (pid);
       discard_queued_stop_replies (cs.last_ptid);
       write_ok (own_buf);
                            status_string.c_str ());
            }
 
-         gdb_assert (thread->last_status.kind != TARGET_WAITKIND_IGNORE);
+         gdb_assert (thread->last_status.kind () != TARGET_WAITKIND_IGNORE);
 
          /* Pass the last stop reply back to GDB, but don't notify
             yet.  */
 {
   thread->last_resume_kind = resume_stop;
 
-  if (thread->last_status.kind == TARGET_WAITKIND_IGNORE)
+  if (thread->last_status.kind () == TARGET_WAITKIND_IGNORE)
     {
       /* Most threads are stopped implicitly (all-stop); tag that with
         signal 0.  */
-      thread->last_status.kind = TARGET_WAITKIND_STOPPED;
-      thread->last_status.value.sig = GDB_SIGNAL_0;
+      thread->last_status.set_stopped (GDB_SIGNAL_0);
     }
 }
 
 static void
 set_pending_status_callback (thread_info *thread)
 {
-  if (thread->last_status.kind != TARGET_WAITKIND_STOPPED
-      || (thread->last_status.value.sig != GDB_SIGNAL_0
+  if (thread->last_status.kind () != TARGET_WAITKIND_STOPPED
+      || (thread->last_status.sig () != GDB_SIGNAL_0
          /* A breakpoint, watchpoint or finished step from a previous
             GDB run isn't considered interesting for a new GDB run.
             If we left those pending, the new GDB could consider them
             random SIGTRAPs.  This leaves out real async traps.  We'd
             have to peek into the (target-specific) siginfo to
             distinguish those.  */
-         && thread->last_status.value.sig != GDB_SIGNAL_TRAP))
+         && thread->last_status.sig () != GDB_SIGNAL_TRAP))
     thread->status_pending_p = 1;
 }
 
 
       /* Prefer the last thread that reported an event to GDB (even if
         that was a GDB_SIGNAL_TRAP).  */
-      if (cs.last_status.kind != TARGET_WAITKIND_IGNORE
-         && cs.last_status.kind != TARGET_WAITKIND_EXITED
-         && cs.last_status.kind != TARGET_WAITKIND_SIGNALLED)
+      if (cs.last_status.kind () != TARGET_WAITKIND_IGNORE
+         && cs.last_status.kind () != TARGET_WAITKIND_EXITED
+         && cs.last_status.kind () != TARGET_WAITKIND_SIGNALLED)
        thread = find_thread_ptid (cs.last_ptid);
 
       /* If the last event thread is not found for some reason, look
          cs.general_thread = thread->id;
          set_desired_thread ();
 
-         gdb_assert (tp->last_status.kind != TARGET_WAITKIND_IGNORE);
+         gdb_assert (tp->last_status.kind () != TARGET_WAITKIND_IGNORE);
          prepare_resume_reply (own_buf, tp->id, &tp->last_status);
        }
       else
     }
   else
     {
-      cs.last_status.kind = TARGET_WAITKIND_EXITED;
-      cs.last_status.value.integer = 0;
+      cs.last_status.set_exited (0);
       cs.last_ptid = minus_one_ptid;
     }
 
   if (current_thread != nullptr)
     current_process ()->dlls_changed = false;
 
-  if (cs.last_status.kind == TARGET_WAITKIND_EXITED
-      || cs.last_status.kind == TARGET_WAITKIND_SIGNALLED)
+  if (cs.last_status.kind () == TARGET_WAITKIND_EXITED
+      || cs.last_status.kind () == TARGET_WAITKIND_SIGNALLED)
     was_running = 0;
   else
     was_running = 1;
         running.  The traditional protocol will exit instead.  */
       if (extended_protocol)
        {
-         cs.last_status.kind = TARGET_WAITKIND_EXITED;
-         cs.last_status.value.sig = GDB_SIGNAL_KILL;
+         cs.last_status.set_exited (GDB_SIGNAL_KILL);
          return 0;
        }
       else
            {
              target_create_inferior (program_path.get (), program_args);
 
-             if (cs.last_status.kind == TARGET_WAITKIND_STOPPED)
+             if (cs.last_status.kind () == TARGET_WAITKIND_STOPPED)
                {
                  /* Stopped at the first instruction of the target
                     process.  */
            }
          else
            {
-             cs.last_status.kind = TARGET_WAITKIND_EXITED;
-             cs.last_status.value.sig = GDB_SIGNAL_KILL;
+             cs.last_status.set_exited (GDB_SIGNAL_KILL);
            }
          return 0;
        }
   cs.last_ptid = mywait (minus_one_ptid, &cs.last_status,
                      TARGET_WNOHANG, 1);
 
-  if (cs.last_status.kind == TARGET_WAITKIND_NO_RESUMED)
+  if (cs.last_status.kind () == TARGET_WAITKIND_NO_RESUMED)
     {
       if (gdb_connected () && report_no_resumed)
        push_stop_notification (null_ptid, &cs.last_status);
     }
-  else if (cs.last_status.kind != TARGET_WAITKIND_IGNORE)
+  else if (cs.last_status.kind () != TARGET_WAITKIND_IGNORE)
     {
       int pid = cs.last_ptid.pid ();
       struct process_info *process = find_process_pid (pid);
       int forward_event = !gdb_connected () || process->gdb_detached;
 
-      if (cs.last_status.kind == TARGET_WAITKIND_EXITED
-         || cs.last_status.kind == TARGET_WAITKIND_SIGNALLED)
+      if (cs.last_status.kind () == TARGET_WAITKIND_EXITED
+         || cs.last_status.kind () == TARGET_WAITKIND_SIGNALLED)
        {
          mark_breakpoints_out (process);
          target_mourn_inferior (cs.last_ptid);
        }
-      else if (cs.last_status.kind == TARGET_WAITKIND_THREAD_EXITED)
+      else if (cs.last_status.kind () == TARGET_WAITKIND_THREAD_EXITED)
        ;
       else
        {
              exit (0);
            }
 
-         if (cs.last_status.kind == TARGET_WAITKIND_EXITED
-             || cs.last_status.kind == TARGET_WAITKIND_SIGNALLED
-             || cs.last_status.kind == TARGET_WAITKIND_THREAD_EXITED)
+         if (cs.last_status.kind () == TARGET_WAITKIND_EXITED
+             || cs.last_status.kind () == TARGET_WAITKIND_SIGNALLED
+             || cs.last_status.kind () == TARGET_WAITKIND_THREAD_EXITED)
            ;
          else
            {
              if (debug_threads)
                debug_printf ("GDB not connected; forwarding event %d for"
                              " [%s]\n",
-                             (int) cs.last_status.kind,
+                             (int) cs.last_status.kind (),
                              target_pid_to_str (cs.last_ptid));
 
-             if (cs.last_status.kind == TARGET_WAITKIND_STOPPED)
-               signal = cs.last_status.value.sig;
+             if (cs.last_status.kind () == TARGET_WAITKIND_STOPPED)
+               signal = cs.last_status.sig ();
              else
                signal = GDB_SIGNAL_0;
              target_continue (cs.last_ptid, signal);
 
 
   /* We don't expose _LOADED events to gdbserver core.  See the
      `dlls_changed' global.  */
-  if (ourstatus->kind == TARGET_WAITKIND_LOADED)
-    ourstatus->kind = TARGET_WAITKIND_STOPPED;
+  if (ourstatus->kind () == TARGET_WAITKIND_LOADED)
+    ourstatus->set_stopped (GDB_SIGNAL_0);
 
   /* If GDB is connected through TCP/serial, then GDBserver will most
      probably be running on its own terminal/console, so it's nice to
      regular GDB output, in that same terminal.  */
   if (!remote_connection_is_stdio ())
     {
-      if (ourstatus->kind == TARGET_WAITKIND_EXITED)
+      if (ourstatus->kind () == TARGET_WAITKIND_EXITED)
        fprintf (stderr,
-                "\nChild exited with status %d\n", ourstatus->value.integer);
-      else if (ourstatus->kind == TARGET_WAITKIND_SIGNALLED)
+                "\nChild exited with status %d\n", ourstatus->exit_status ());
+      else if (ourstatus->kind () == TARGET_WAITKIND_SIGNALLED)
        fprintf (stderr, "\nChild terminated with signal = 0x%x (%s)\n",
-                gdb_signal_to_host (ourstatus->value.sig),
-                gdb_signal_to_name (ourstatus->value.sig));
+                gdb_signal_to_host (ourstatus->sig ()),
+                gdb_signal_to_name (ourstatus->sig ()));
     }
 
   if (connected_wait)
 
   if (the_low_target.initial_stuff != NULL)
     (*the_low_target.initial_stuff) ();
 
-  cached_status.kind = TARGET_WAITKIND_IGNORE;
+  cached_status.set_ignore ();
 
   /* Flush all currently pending debug events (thread and dll list) up
      to the initial breakpoint.  */
       the_target->wait (minus_one_ptid, &status, 0);
 
       /* Note win32_wait doesn't return thread events.  */
-      if (status.kind != TARGET_WAITKIND_LOADED)
+      if (status.kind () != TARGET_WAITKIND_LOADED)
        {
          cached_status = status;
          break;
   ptid_t ptid;
 
   last_sig = GDB_SIGNAL_0;
-  ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+  ourstatus->set_spurious ();
   *continue_status = DBG_CONTINUE;
 
   /* Check if GDB sent us an interrupt request.  */
               load the application, e.g., if the main executable
               tries to pull in a non-existing export from a
               DLL.  */
-           ourstatus->kind = TARGET_WAITKIND_EXITED;
-           ourstatus->value.integer = 1;
+           ourstatus->set_exited (1);
            return 1;
          }
 
        int exit_signal
          = WIFSIGNALED (exit_status) ? WTERMSIG (exit_status) : -1;
        if (exit_signal == -1)
-         {
-           ourstatus->kind = TARGET_WAITKIND_EXITED;
-           ourstatus->value.integer = exit_status;
-         }
+         ourstatus->set_exited (exit_status);
        else
-         {
-           ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
-           ourstatus->value.sig = gdb_signal_from_host (exit_signal);
-         }
+         ourstatus->set_signalled (gdb_signal_from_host (exit_signal));
       }
       child_continue (DBG_CONTINUE, desired_stop_thread_id);
       break;
        break;
       dll_loaded_event ();
 
-      ourstatus->kind = TARGET_WAITKIND_LOADED;
-      ourstatus->value.sig = GDB_SIGNAL_TRAP;
+      ourstatus->set_loaded ();
       break;
 
     case UNLOAD_DLL_DEBUG_EVENT:
       if (! child_initialization_done)
        break;
       handle_unload_dll ();
-      ourstatus->kind = TARGET_WAITKIND_LOADED;
-      ourstatus->value.sig = GDB_SIGNAL_TRAP;
+      ourstatus->set_loaded ();
       break;
 
     case EXCEPTION_DEBUG_EVENT:
                ptid.lwp (), desired_stop_thread_id));
       maybe_adjust_pc ();
       pending_stops.push_back ({(DWORD) ptid.lwp (), *ourstatus, current_event});
-      ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+      ourstatus->set_spurious ();
     }
   else
     current_thread = find_thread_ptid (ptid);
 win32_process_target::wait (ptid_t ptid, target_waitstatus *ourstatus,
                            target_wait_flags options)
 {
-  if (cached_status.kind != TARGET_WAITKIND_IGNORE)
+  if (cached_status.kind () != TARGET_WAITKIND_IGNORE)
     {
       /* The core always does a wait after creating the inferior, and
         do_initial_child_stuff already ran the inferior to the
         initial breakpoint (or an exit, if creating the process
         fails).  Report it now.  */
       *ourstatus = cached_status;
-      cached_status.kind = TARGET_WAITKIND_IGNORE;
+      cached_status.set_ignore ();
       return debug_event_ptid (¤t_event);
     }
 
       if (!get_child_debug_event (&continue_status, ourstatus))
        continue;
 
-      switch (ourstatus->kind)
+      switch (ourstatus->kind ())
        {
        case TARGET_WAITKIND_EXITED:
          OUTMSG2 (("Child exited with retcode = %x\n",
-                   ourstatus->value.integer));
+                   ourstatus->exit_status ()));
          win32_clear_inferiors ();
          return ptid_t (current_event.dwProcessId);
        case TARGET_WAITKIND_STOPPED:
        case TARGET_WAITKIND_LOADED:
          {
            OUTMSG2 (("Child Stopped with signal = %d \n",
-                     ourstatus->value.sig));
+                     ourstatus->sig ()));
            maybe_adjust_pc ();
            return debug_event_ptid (¤t_event);
          }
        default:
-         OUTMSG (("Ignoring unknown internal event, %d\n", ourstatus->kind));
+         OUTMSG (("Ignoring unknown internal event, %d\n",
+                 ourstatus->kind ()));
          /* fall-through */
        case TARGET_WAITKIND_SPURIOUS:
          /* do nothing, just continue */