diff --git a/gdb/darwin-nat-info.c b/gdb/darwin-nat-info.c
index 44782bf..feab181 100644
--- a/gdb/darwin-nat-info.c
+++ b/gdb/darwin-nat-info.c
@@ -118,7 +118,11 @@ get_task_from_args (const char *args)
     {
       if (ptid_equal (inferior_ptid, null_ptid))
 	printf_unfiltered (_("No inferior running\n"));
-      return current_inferior ()->priv->task;
+
+      darwin_inferior *priv
+	= (darwin_inferior *) current_inferior ()->priv.get ();
+
+      return priv->task;
     }
   if (strcmp (args, "gdb") == 0)
     return mach_task_self ();
@@ -257,36 +261,31 @@ info_mach_ports_command (const char *args, int from_tty)
 	  else if (!ptid_equal (inferior_ptid, null_ptid))
 	    {
 	      struct inferior *inf = current_inferior ();
+	      darwin_inferior *priv = (darwin_inferior *) inf->priv.get ();
 
-	      if (port == inf->priv->task)
+	      if (port == priv->task)
 		printf_unfiltered (_(" inferior-task"));
-	      else if (port == inf->priv->notify_port)
+	      else if (port == priv->notify_port)
 		printf_unfiltered (_(" inferior-notify"));
 	      else
 		{
-		  int k;
-		  darwin_thread_t *t;
-
-		  for (k = 0; k < inf->priv->exception_info.count; k++)
-		    if (port == inf->priv->exception_info.ports[k])
+		  for (int k = 0; k < priv->exception_info.count; k++)
+		    if (port == priv->exception_info.ports[k])
 		      {
 			printf_unfiltered (_(" inferior-excp-port"));
 			break;
 		      }
 
-		  if (inf->priv->threads)
+		  for (darwin_thread_t *t : priv->threads)
 		    {
-		      for (k = 0;
-			   VEC_iterate(darwin_thread_t,
-				       inf->priv->threads, k, t);
-			   k++)
-			if (port == t->gdb_port)
-			  {
-			    printf_unfiltered (_(" inferior-thread for 0x%x"),
-					       inf->priv->task);
-			    break;
-			  }
+		      if (port == t->gdb_port)
+			{
+			  printf_unfiltered (_(" inferior-thread for 0x%x"),
+					     priv->task);
+			  break;
+			}
 		    }
+
 		}
 	    }
 	}
@@ -738,7 +737,8 @@ info_mach_region_command (const char *exp, int from_tty)
     error (_("Inferior not available"));
 
   inf = current_inferior ();
-  darwin_debug_region (inf->priv->task, address);
+  darwin_inferior *priv = (darwin_inferior *) inf->priv.get ();
+  darwin_debug_region (priv->task, address);
 }
 
 static void
@@ -807,7 +807,11 @@ info_mach_exceptions_command (const char *args, int from_tty)
 	{
 	  if (ptid_equal (inferior_ptid, null_ptid))
 	    printf_unfiltered (_("No inferior running\n"));
-	  disp_exception (&current_inferior ()->priv->exception_info);
+
+	  darwin_inferior *priv
+	    = (darwin_inferior *) current_inferior ()->priv.get ();
+
+	  disp_exception (&priv->exception_info);
 	  return;
 	}
       else if (strcmp (args, "host") == 0)
@@ -830,8 +834,10 @@ info_mach_exceptions_command (const char *args, int from_tty)
 	printf_unfiltered (_("No inferior running\n"));
       inf = current_inferior ();
       
+      darwin_inferior *priv = (darwin_inferior *) inf->priv.get ();
+
       kret = task_get_exception_ports
-	(inf->priv->task, EXC_MASK_ALL, info.masks,
+	(priv->task, EXC_MASK_ALL, info.masks,
 	 &info.count, info.ports, info.behaviors, info.flavors);
       MACH_CHECK_ERROR (kret);
       disp_exception (&info);
diff --git a/gdb/darwin-nat.c b/gdb/darwin-nat.c
index 6e420c4..f4ed455 100644
--- a/gdb/darwin-nat.c
+++ b/gdb/darwin-nat.c
@@ -279,13 +279,12 @@ static void
 darwin_check_new_threads (struct inferior *inf)
 {
   kern_return_t kret;
-  unsigned int i;
   thread_array_t thread_list;
   unsigned int new_nbr;
   unsigned int old_nbr;
   unsigned int new_ix, old_ix;
-  darwin_inferior *darwin_inf = inf->priv;
-  VEC (darwin_thread_t) *thread_vec;
+  darwin_inferior *darwin_inf = (darwin_inferior *) inf->priv.get ();
+  std::vector<darwin_thread_t *> new_thread_vec;
 
   /* Get list of threads.  */
   kret = task_threads (darwin_inf->task, &thread_list, &new_nbr);
@@ -297,17 +296,15 @@ darwin_check_new_threads (struct inferior *inf)
   if (new_nbr > 1)
     qsort (thread_list, new_nbr, sizeof (thread_t), cmp_thread_t);
 
-  if (darwin_inf->threads)
-    old_nbr = VEC_length (darwin_thread_t, darwin_inf->threads);
-  else
-    old_nbr = 0;
+  old_nbr = darwin_inf->threads.size ();
 
   /* Quick check for no changes.  */
   if (old_nbr == new_nbr)
     {
+      size_t i;
+
       for (i = 0; i < new_nbr; i++)
-	if (thread_list[i]
-	    != VEC_index (darwin_thread_t, darwin_inf->threads, i)->gdb_port)
+	if (thread_list[i] != darwin_inf->threads[i]->gdb_port)
 	  break;
       if (i == new_nbr)
 	{
@@ -328,15 +325,15 @@ darwin_check_new_threads (struct inferior *inf)
     }
 
   /* Full handling: detect new threads, remove dead threads.  */
-  thread_vec = VEC_alloc (darwin_thread_t, new_nbr);
+
+  new_thread_vec.reserve (new_nbr);
 
   for (new_ix = 0, old_ix = 0; new_ix < new_nbr || old_ix < old_nbr;)
     {
-      thread_t new_id = (new_ix < new_nbr) ?
-	thread_list[new_ix] : THREAD_NULL;
-      darwin_thread_t *old = (old_ix < old_nbr) ?
-	VEC_index (darwin_thread_t, darwin_inf->threads, old_ix) : NULL;
-      thread_t old_id = old ? old->gdb_port : THREAD_NULL;
+      thread_t new_id = (new_ix < new_nbr) ? thread_list[new_ix] : THREAD_NULL;
+      darwin_thread_t *old
+	= (old_ix < old_nbr) ? darwin_inf->threads[old_ix] : NULL;
+      thread_t old_id = old != NULL ? old->gdb_port : THREAD_NULL;
 
       inferior_debug
 	(12, _(" new_ix:%d/%d, old_ix:%d/%d, new_id:0x%x old_id:0x%x\n"),
@@ -345,7 +342,7 @@ darwin_check_new_threads (struct inferior *inf)
       if (old_id == new_id)
 	{
 	  /* Thread still exist.  */
-	  VEC_safe_push (darwin_thread_t, thread_vec, old);
+	  new_thread_vec.push_back (old);
 	  new_ix++;
 	  old_ix++;
 
@@ -368,13 +365,13 @@ darwin_check_new_threads (struct inferior *inf)
 	  /* A thread was created.  */
 	  struct private_thread_info *pti;
 
-	  pti = XCNEW (struct private_thread_info);
+	  pti = XCNEW (darwin_thread_t);
 	  pti->gdb_port = new_id;
 	  pti->msg_state = DARWIN_RUNNING;
 
 	  /* Add the new thread.  */
 	  add_thread_with_info (ptid_build (inf->pid, 0, new_id), pti);
-	  VEC_safe_push (darwin_thread_t, thread_vec, pti);
+	  new_thread_vec.push_back (pti);
 	  new_ix++;
 	  continue;
 	}
@@ -390,9 +387,7 @@ darwin_check_new_threads (struct inferior *inf)
       gdb_assert_not_reached ("unexpected thread case");
     }
 
-  if (darwin_inf->threads)
-    VEC_free (darwin_thread_t, darwin_inf->threads);
-  darwin_inf->threads = thread_vec;
+  darwin_inf->threads = std::move (new_thread_vec);
 
   /* Deallocate the buffer.  */
   kret = vm_deallocate (gdb_task, (vm_address_t) thread_list,
@@ -403,7 +398,9 @@ darwin_check_new_threads (struct inferior *inf)
 static int
 find_inferior_task_it (struct inferior *inf, void *port_ptr)
 {
-  return inf->priv->task == *(task_t *)port_ptr;
+  darwin_inferior *priv = (darwin_inferior *) inf->priv.get ();
+
+  return priv->task == *(task_t *)port_ptr;
 }
 
 static int
@@ -430,14 +427,14 @@ darwin_find_inferior_by_pid (int pid)
 static darwin_thread_t *
 darwin_find_thread (struct inferior *inf, thread_t thread)
 {
-  darwin_thread_t *t;
-  int k;
+  darwin_inferior *priv = (darwin_inferior *) inf->priv.get ();
+
+  for (darwin_thread_t *t : priv->threads)
+    {
+      if (t->gdb_port == thread)
+	return t;
+    }
 
-  for (k = 0;
-       VEC_iterate (darwin_thread_t, inf->priv->threads, k, t);
-       k++)
-    if (t->gdb_port == thread)
-      return t;
   return NULL;
 }
 
@@ -446,14 +443,16 @@ darwin_find_thread (struct inferior *inf, thread_t thread)
 static void
 darwin_suspend_inferior (struct inferior *inf)
 {
-  if (!inf->priv->suspended)
+  darwin_inferior *priv = (darwin_inferior *) inf->priv.get ();
+
+  if (!priv->suspended)
     {
       kern_return_t kret;
 
-      kret = task_suspend (inf->priv->task);
+      kret = task_suspend (priv->task);
       MACH_CHECK_ERROR (kret);
 
-      inf->priv->suspended = 1;
+      priv->suspended = 1;
     }
 }
 
@@ -462,14 +461,16 @@ darwin_suspend_inferior (struct inferior *inf)
 static void
 darwin_resume_inferior (struct inferior *inf)
 {
-  if (inf->priv->suspended)
+  darwin_inferior *priv = (darwin_inferior *) inf->priv.get ();
+
+  if (priv->suspended)
     {
       kern_return_t kret;
 
-      kret = task_resume (inf->priv->task);
+      kret = task_resume (priv->task);
       MACH_CHECK_ERROR (kret);
 
-      inf->priv->suspended = 0;
+      priv->suspended = 0;
     }
 }
 
@@ -580,11 +581,13 @@ darwin_find_new_inferior (task_t task_port, thread_t thread_port)
   if (inf == NULL)
     return NULL;
 
+  darwin_inferior *priv = (darwin_inferior *) inf->priv.get ();
+
   /* Deallocate saved exception ports.  */
-  darwin_deallocate_exception_ports (inf->priv);
+  darwin_deallocate_exception_ports (priv);
 
   /* No need to remove dead_name notification, but still...  */
-  kret = mach_port_request_notification (gdb_task, inf->priv->task,
+  kret = mach_port_request_notification (gdb_task, priv->task,
 					 MACH_NOTIFY_DEAD_NAME, 0,
 					 MACH_PORT_NULL,
 					 MACH_MSG_TYPE_MAKE_SEND_ONCE,
@@ -593,9 +596,9 @@ darwin_find_new_inferior (task_t task_port, thread_t thread_port)
     MACH_CHECK_ERROR (kret);
 
   /* Replace old task port.  */
-  kret = mach_port_deallocate (gdb_task, inf->priv->task);
+  kret = mach_port_deallocate (gdb_task, priv->task);
   MACH_CHECK_ERROR (kret);
-  inf->priv->task = task_port;
+  priv->task = task_port;
 
   darwin_setup_request_notification (inf);
   darwin_setup_exceptions (inf);
@@ -789,8 +792,10 @@ darwin_decode_notify_message (mach_msg_header_t *hdr, struct inferior **pinf)
   inf = darwin_find_inferior_by_task (task_port);
   *pinf = inf;
 
+  darwin_inferior *priv = (darwin_inferior *) inf->priv.get ();
+
   /* Check message destination.  */
-  if (inf != NULL && hdr->msgh_local_port != inf->priv->notify_port)
+  if (inf != NULL && hdr->msgh_local_port != priv->notify_port)
     return -4;
 
   return 0;
@@ -817,6 +822,7 @@ darwin_send_reply (struct inferior *inf, darwin_thread_t *thread)
 {
   kern_return_t kret;
   mig_reply_error_t reply;
+  darwin_inferior *priv = (darwin_inferior *) inf->priv.get ();
 
   darwin_encode_reply (&reply, &thread->event.header, KERN_SUCCESS);
 
@@ -826,7 +832,7 @@ darwin_send_reply (struct inferior *inf, darwin_thread_t *thread)
 		   MACH_PORT_NULL);
   MACH_CHECK_ERROR (kret);
 
-  inf->priv->pending_messages--;
+  priv->pending_messages--;
 }
 
 static void
@@ -889,12 +895,9 @@ darwin_resume_thread (struct inferior *inf, darwin_thread_t *thread,
 static void
 darwin_resume_inferior_threads (struct inferior *inf, int step, int nsignal)
 {
-  darwin_thread_t *thread;
-  int k;
+  darwin_inferior *priv = (darwin_inferior *) inf->priv.get ();
 
-  for (k = 0;
-       VEC_iterate (darwin_thread_t, inf->priv->threads, k, thread);
-       k++)
+  for (darwin_thread_t *thread : priv->threads)
     darwin_resume_thread (inf, thread, step, nsignal);
 }
 
@@ -920,24 +923,24 @@ darwin_resume_inferior_threads_it (struct inferior *inf, void *param)
 static void
 darwin_suspend_inferior_threads (struct inferior *inf)
 {
-  darwin_thread_t *thread;
-  kern_return_t kret;
-  int k;
+  darwin_inferior *priv = (darwin_inferior *) inf->priv.get ();
 
-  for (k = 0;
-       VEC_iterate (darwin_thread_t, inf->priv->threads, k, thread);
-       k++)
-    switch (thread->msg_state)
-      {
-      case DARWIN_STOPPED:
-      case DARWIN_MESSAGE:
-	break;
-      case DARWIN_RUNNING:
-	kret = thread_suspend (thread->gdb_port);
-	MACH_CHECK_ERROR (kret);
-	thread->msg_state = DARWIN_STOPPED;
-	break;
-      }
+  for (darwin_thread_t *thread : priv->threads)
+    {
+      switch (thread->msg_state)
+	{
+	case DARWIN_STOPPED:
+	case DARWIN_MESSAGE:
+	  break;
+	case DARWIN_RUNNING:
+	  {
+	    kern_return_t kret = thread_suspend (thread->gdb_port);
+	    MACH_CHECK_ERROR (kret);
+	    thread->msg_state = DARWIN_STOPPED;
+	    break;
+	  }
+	}
+    }
 }
 
 static void
@@ -1045,7 +1048,10 @@ darwin_decode_message (mach_msg_header_t *hdr,
 	}
       *pinf = inf;
       *pthread = thread;
-      inf->priv->pending_messages++;
+
+      darwin_inferior *priv = (darwin_inferior *) inf->priv.get ();
+
+      priv->pending_messages++;
 
       status->kind = TARGET_WAITKIND_STOPPED;
       thread->msg_state = DARWIN_MESSAGE;
@@ -1129,7 +1135,9 @@ darwin_decode_message (mach_msg_header_t *hdr,
 
       if (inf != NULL)
 	{
-	  if (!inf->priv->no_ptrace)
+	  darwin_inferior *priv = (darwin_inferior *) inf->priv.get ();
+
+	  if (!priv->no_ptrace)
 	    {
 	      pid_t res;
 	      int wstatus;
@@ -1232,9 +1240,11 @@ darwin_wait (ptid_t ptid, struct target_waitstatus *status)
       inf = darwin_inf_fake_stop;
       darwin_inf_fake_stop = NULL;
 
+      darwin_inferior *priv = (darwin_inferior *) inf->priv.get ();
+
       status->kind = TARGET_WAITKIND_STOPPED;
       status->value.sig = GDB_SIGNAL_TRAP;
-      thread = VEC_index (darwin_thread_t, inf->priv->threads, 0);
+      thread = priv->threads[0];
       thread->msg_state = DARWIN_STOPPED;
       return ptid_build (inf->pid, 0, thread->gdb_port);
     }
@@ -1336,9 +1346,10 @@ static void
 darwin_interrupt (struct target_ops *self, ptid_t t)
 {
   struct inferior *inf = current_inferior ();
+  darwin_inferior *priv = (darwin_inferior *) inf->priv.get ();
 
   /* FIXME: handle in no_ptrace mode.  */
-  gdb_assert (!inf->priv->no_ptrace);
+  gdb_assert (!priv->no_ptrace);
   kill (inf->pid, SIGINT);
 }
 
@@ -1347,27 +1358,22 @@ darwin_interrupt (struct target_ops *self, ptid_t t)
 static void
 darwin_deallocate_threads (struct inferior *inf)
 {
-  if (inf->priv->threads)
+  darwin_inferior *priv = (darwin_inferior *) inf->priv.get ();
+
+  for (darwin_thread_t *t : priv->threads)
     {
-      kern_return_t kret;
-      int k;
-      darwin_thread_t *t;
-      for (k = 0;
-	   VEC_iterate (darwin_thread_t, inf->priv->threads, k, t);
-	   k++)
-	{
-	  kret = mach_port_deallocate (gdb_task, t->gdb_port);
-	  MACH_CHECK_ERROR (kret);
-	}
-      VEC_free (darwin_thread_t, inf->priv->threads);
-      inf->priv->threads = NULL;
+      kern_return_t kret = mach_port_deallocate (gdb_task, t->gdb_port);
+      MACH_CHECK_ERROR (kret);
     }
+
+  priv->threads.clear ();
 }
 
 static void
 darwin_mourn_inferior (struct target_ops *ops)
 {
   struct inferior *inf = current_inferior ();
+  darwin_inferior *priv = (darwin_inferior *) inf->priv.get ();
   kern_return_t kret;
   mach_port_t prev;
   int i;
@@ -1377,18 +1383,18 @@ darwin_mourn_inferior (struct target_ops *ops)
 
   /* Remove notify_port from darwin_port_set.  */
   kret = mach_port_move_member (gdb_task,
-				inf->priv->notify_port, MACH_PORT_NULL);
+				priv->notify_port, MACH_PORT_NULL);
   MACH_CHECK_ERROR (kret);
 
   /* Remove task port dead_name notification.  */
-  kret = mach_port_request_notification (gdb_task, inf->priv->task,
+  kret = mach_port_request_notification (gdb_task, priv->task,
 					 MACH_NOTIFY_DEAD_NAME, 0,
 					 MACH_PORT_NULL,
 					 MACH_MSG_TYPE_MAKE_SEND_ONCE,
 					 &prev);
   /* This can fail if the task is dead.  */
   inferior_debug (4, "task=0x%x, prev=0x%x, notify_port=0x%x\n",
-		  inf->priv->task, prev, inf->priv->notify_port);
+		  priv->task, prev, priv->notify_port);
 
   if (kret == KERN_SUCCESS)
     {
@@ -1397,17 +1403,16 @@ darwin_mourn_inferior (struct target_ops *ops)
     }
 
   /* Destroy notify_port.  */
-  kret = mach_port_destroy (gdb_task, inf->priv->notify_port);
+  kret = mach_port_destroy (gdb_task, priv->notify_port);
   MACH_CHECK_ERROR (kret);
 
   /* Deallocate saved exception ports.  */
-  darwin_deallocate_exception_ports (inf->priv);
+  darwin_deallocate_exception_ports (priv);
 
   /* Deallocate task port.  */
-  kret = mach_port_deallocate (gdb_task, inf->priv->task);
+  kret = mach_port_deallocate (gdb_task, priv->task);
   MACH_CHECK_ERROR (kret);
 
-  xfree (inf->priv);
   inf->priv = NULL;
 
   inf_child_mourn_inferior (ops);
@@ -1416,12 +1421,9 @@ darwin_mourn_inferior (struct target_ops *ops)
 static void
 darwin_reply_to_all_pending_messages (struct inferior *inf)
 {
-  int k;
-  darwin_thread_t *t;
+  darwin_inferior *priv = (darwin_inferior *) inf->priv.get ();
 
-  for (k = 0;
-       VEC_iterate (darwin_thread_t, inf->priv->threads, k, t);
-       k++)
+  for (darwin_thread_t *t : priv->threads)
     {
       if (t->msg_state == DARWIN_MESSAGE)
 	darwin_resume_thread (inf, t, 0, 0);
@@ -1436,6 +1438,7 @@ darwin_stop_inferior (struct inferior *inf)
   kern_return_t kret;
   int status;
   int res;
+  darwin_inferior *priv = (darwin_inferior *) inf->priv.get ();
 
   gdb_assert (inf != NULL);
 
@@ -1443,7 +1446,7 @@ darwin_stop_inferior (struct inferior *inf)
 
   darwin_reply_to_all_pending_messages (inf);
 
-  if (inf->priv->no_ptrace)
+  if (priv->no_ptrace)
     return;
 
   res = kill (inf->pid, SIGSTOP);
@@ -1512,11 +1515,12 @@ darwin_deallocate_exception_ports (darwin_inferior *inf)
 static void
 darwin_setup_exceptions (struct inferior *inf)
 {
+  darwin_inferior *priv = (darwin_inferior *) inf->priv.get ();
   kern_return_t kret;
   int traps_expected;
   exception_mask_t mask;
 
-  kret = darwin_save_exception_ports (inf->priv);
+  kret = darwin_save_exception_ports (priv);
   if (kret != KERN_SUCCESS)
     error (_("Unable to save exception ports, task_get_exception_ports"
 	     "returned: %d"),
@@ -1527,7 +1531,7 @@ darwin_setup_exceptions (struct inferior *inf)
     mask = EXC_MASK_ALL;
   else
     mask = EXC_MASK_SOFTWARE | EXC_MASK_BREAKPOINT;
-  kret = task_set_exception_ports (inf->priv->task, mask, darwin_ex_port,
+  kret = task_set_exception_ports (priv->task, mask, darwin_ex_port,
 				   EXCEPTION_DEFAULT, THREAD_STATE_NONE);
   if (kret != KERN_SUCCESS)
     error (_("Unable to set exception ports, task_set_exception_ports"
@@ -1539,6 +1543,7 @@ static void
 darwin_kill_inferior (struct target_ops *ops)
 {
   struct inferior *inf = current_inferior ();
+  darwin_inferior *priv = (darwin_inferior *) inf->priv.get ();
   struct target_waitstatus wstatus;
   ptid_t ptid;
   kern_return_t kret;
@@ -1550,7 +1555,7 @@ darwin_kill_inferior (struct target_ops *ops)
 
   gdb_assert (inf != NULL);
 
-  kret = darwin_restore_exception_ports (inf->priv);
+  kret = darwin_restore_exception_ports (priv);
   MACH_CHECK_ERROR (kret);
 
   darwin_reply_to_all_pending_messages (inf);
@@ -1573,12 +1578,13 @@ darwin_kill_inferior (struct target_ops *ops)
 static void
 darwin_setup_request_notification (struct inferior *inf)
 {
+  darwin_inferior *priv = (darwin_inferior *) inf->priv.get ();
   kern_return_t kret;
   mach_port_t prev_not;
 
-  kret = mach_port_request_notification (gdb_task, inf->priv->task,
+  kret = mach_port_request_notification (gdb_task, priv->task,
 					 MACH_NOTIFY_DEAD_NAME, 0,
-					 inf->priv->notify_port,
+					 priv->notify_port,
 					 MACH_MSG_TYPE_MAKE_SEND_ONCE,
 					 &prev_not);
   if (kret != KERN_SUCCESS)
@@ -1607,9 +1613,10 @@ darwin_attach_pid (struct inferior *inf)
   mach_port_t prev_not;
   exception_mask_t mask;
 
-  inf->priv = XCNEW (darwin_inferior);
+  darwin_inferior *priv = new darwin_inferior;
+  inf->priv.reset (priv);
 
-  kret = task_for_pid (gdb_task, inf->pid, &inf->priv->task);
+  kret = task_for_pid (gdb_task, inf->pid, &priv->task);
   if (kret != KERN_SUCCESS)
     {
       int status;
@@ -1626,7 +1633,7 @@ darwin_attach_pid (struct inferior *inf)
     }
 
   inferior_debug (2, _("inferior task: 0x%x, pid: %d\n"),
-		  inf->priv->task, inf->pid);
+		  priv->task, inf->pid);
 
   if (darwin_ex_port == MACH_PORT_NULL)
     {
@@ -1663,14 +1670,14 @@ darwin_attach_pid (struct inferior *inf)
 
   /* Create a port to be notified when the child task terminates.  */
   kret = mach_port_allocate (gdb_task, MACH_PORT_RIGHT_RECEIVE,
-			     &inf->priv->notify_port);
+			     &priv->notify_port);
   if (kret != KERN_SUCCESS)
     error (_("Unable to create notification port, mach_port_allocate "
 	     "returned: %d"),
 	   kret);
 
   kret = mach_port_move_member (gdb_task,
-				inf->priv->notify_port, darwin_port_set);
+				priv->notify_port, darwin_port_set);
   if (kret != KERN_SUCCESS)
     error (_("Unable to move notification port into new port set, "
 	     "mach_port_move_member\n"
@@ -1708,11 +1715,11 @@ darwin_init_thread_list (struct inferior *inf)
 {
   darwin_check_new_threads (inf);
 
-  gdb_assert (inf->priv->threads != NULL);
-  gdb_assert (VEC_length (darwin_thread_t, inf->priv->threads) > 0);
+  darwin_inferior *priv = (darwin_inferior *) inf->priv.get ();
 
-  private_thread_info *first_pti
-    = VEC_index (darwin_thread_t, inf->priv->threads, 0);
+  gdb_assert (!priv->threads.empty ());
+
+  private_thread_info *first_pti = priv->threads.front ();
   struct thread_info *first_thread
     = thread_info_from_private_thread_info (first_pti);
 
@@ -1849,6 +1856,7 @@ darwin_create_inferior (struct target_ops *ops,
 static void
 darwin_setup_fake_stop_event (struct inferior *inf)
 {
+  darwin_inferior *priv = (darwin_inferior *) inf->priv.get ();
   darwin_thread_t *thread;
   kern_return_t kret;
 
@@ -1861,7 +1869,7 @@ darwin_setup_fake_stop_event (struct inferior *inf)
      as well.  Otherwise, we'll try resuming it when resuming the
      inferior, and get a warning because the thread's suspend count
      is already zero, making the resume request useless.  */
-  thread = VEC_index (darwin_thread_t, inf->priv->threads, 0);
+  thread = priv->threads[0];
   kret = thread_suspend (thread->gdb_port);
   MACH_CHECK_ERROR (kret);
 }
@@ -1912,11 +1920,13 @@ darwin_attach (struct target_ops *ops, const char *args, int from_tty)
 
   darwin_init_thread_list (inf);
 
-  darwin_check_osabi (inf->priv, ptid_get_tid (inferior_ptid));
+  darwin_inferior *priv = (darwin_inferior *) inf->priv.get ();
+
+  darwin_check_osabi (priv, ptid_get_tid (inferior_ptid));
 
   darwin_setup_fake_stop_event (inf);
 
-  inf->priv->no_ptrace = 1;
+  priv->no_ptrace = 1;
 }
 
 /* Take a program previously attached to and detaches it.
@@ -1931,6 +1941,7 @@ darwin_detach (struct target_ops *ops, const char *args, int from_tty)
 {
   pid_t pid = ptid_get_pid (inferior_ptid);
   struct inferior *inf = current_inferior ();
+  darwin_inferior *priv = (darwin_inferior *) inf->priv.get ();
   kern_return_t kret;
   int res;
 
@@ -1938,13 +1949,13 @@ darwin_detach (struct target_ops *ops, const char *args, int from_tty)
   target_announce_detach (from_tty);
 
   /* If ptrace() is in use, stop the process.  */
-  if (!inf->priv->no_ptrace)
+  if (!priv->no_ptrace)
     darwin_stop_inferior (inf);
 
-  kret = darwin_restore_exception_ports (inf->priv);
+  kret = darwin_restore_exception_ports (priv);
   MACH_CHECK_ERROR (kret);
 
-  if (!inf->priv->no_ptrace)
+  if (!priv->no_ptrace)
     {
       res = PTRACE (PT_DETACH, inf->pid, 0, 0);
       if (res != 0)
@@ -1957,7 +1968,7 @@ darwin_detach (struct target_ops *ops, const char *args, int from_tty)
   /* When using ptrace, we have just performed a PT_DETACH, which
      resumes the inferior.  On the other hand, when we are not using
      ptrace, we need to resume its execution ourselves.  */
-  if (inf->priv->no_ptrace)
+  if (priv->no_ptrace)
     darwin_resume_inferior (inf);
 
   darwin_mourn_inferior (ops);
@@ -2189,6 +2200,7 @@ darwin_xfer_partial (struct target_ops *ops,
 		     ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
 {
   struct inferior *inf = current_inferior ();
+  darwin_inferior *priv = (darwin_inferior *) inf->priv.get ();
 
   inferior_debug
     (8, _("darwin_xfer_partial(%s, %s, rbuf=%s, wbuf=%s) pid=%u\n"),
@@ -2200,7 +2212,7 @@ darwin_xfer_partial (struct target_ops *ops,
     {
     case TARGET_OBJECT_MEMORY:
       {
-	int l = darwin_read_write_inferior (inf->priv->task, offset,
+	int l = darwin_read_write_inferior (priv->task, offset,
 					    readbuf, writebuf, len);
 
 	if (l == 0)
@@ -2219,7 +2231,7 @@ darwin_xfer_partial (struct target_ops *ops,
           /* Support only read.  */
           return TARGET_XFER_E_IO;
         }
-      return darwin_read_dyld_info (inf->priv->task, offset, readbuf, len,
+      return darwin_read_dyld_info (priv->task, offset, readbuf, len,
 				    xfered_len);
 #endif
     default:
@@ -2235,6 +2247,7 @@ set_enable_mach_exceptions (const char *args, int from_tty,
   if (!ptid_equal (inferior_ptid, null_ptid))
     {
       struct inferior *inf = current_inferior ();
+      darwin_inferior *priv = (darwin_inferior *) inf->priv.get ();
       exception_mask_t mask;
       kern_return_t kret;
 
@@ -2242,10 +2255,10 @@ set_enable_mach_exceptions (const char *args, int from_tty,
 	mask = EXC_MASK_ALL;
       else
 	{
-	  darwin_restore_exception_ports (inf->priv);
+	  darwin_restore_exception_ports (priv);
 	  mask = EXC_MASK_SOFTWARE | EXC_MASK_BREAKPOINT;
 	}
-      kret = task_set_exception_ports (inf->priv->task, mask, darwin_ex_port,
+      kret = task_set_exception_ports (priv->task, mask, darwin_ex_port,
 				       EXCEPTION_DEFAULT, THREAD_STATE_NONE);
       MACH_CHECK_ERROR (kret);
     }
@@ -2267,10 +2280,8 @@ darwin_pid_to_exec_file (struct target_ops *self, int pid)
 static ptid_t
 darwin_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
 {
-  int i;
-  darwin_thread_t *t;
-  int k;
   struct inferior *inf = current_inferior ();
+  darwin_inferior *priv = (darwin_inferior *) inf->priv.get ();
   kern_return_t kret;
   mach_port_name_array_t names;
   mach_msg_type_number_t names_count;
@@ -2279,16 +2290,16 @@ darwin_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
   long res = 0;
 
   /* First linear search.  */
-  for (k = 0;
-       VEC_iterate (darwin_thread_t, inf->priv->threads, k, t);
-       k++)
-    if (t->inf_port == lwp)
-      return ptid_build (ptid_get_pid (inferior_ptid), 0, t->gdb_port);
+  for (darwin_thread_t *t : priv->threads)
+    {
+      if (t->inf_port == lwp)
+	return ptid_build (ptid_get_pid (inferior_ptid), 0, t->gdb_port);
+    }
 
   /* Maybe the port was never extract.  Do it now.  */
 
   /* First get inferior port names.  */
-  kret = mach_port_names (inf->priv->task, &names, &names_count, &types,
+  kret = mach_port_names (priv->task, &names, &names_count, &types,
 			  &types_count);
   MACH_CHECK_ERROR (kret);
   if (kret != KERN_SUCCESS)
@@ -2297,29 +2308,29 @@ darwin_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
   /* For each name, copy the right in the gdb space and then compare with
      our view of the inferior threads.  We don't forget to deallocate the
      right.  */
-  for (i = 0; i < names_count; i++)
+  for (int i = 0; i < names_count; i++)
     {
       mach_port_t local_name;
       mach_msg_type_name_t local_type;
 
       /* We just need to know the corresponding name in gdb name space.
 	 So extract and deallocate the right.  */
-      kret = mach_port_extract_right (inf->priv->task, names[i],
+      kret = mach_port_extract_right (priv->task, names[i],
 				      MACH_MSG_TYPE_COPY_SEND,
 				      &local_name, &local_type);
       if (kret != KERN_SUCCESS)
 	continue;
       mach_port_deallocate (gdb_task, local_name);
 
-      for (k = 0;
-	   VEC_iterate (darwin_thread_t, inf->priv->threads, k, t);
-	   k++)
-	if (t->gdb_port == local_name)
-	  {
-	    t->inf_port = names[i];
-	    if (names[i] == lwp)
-	      res = t->gdb_port;
-	  }
+      for (darwin_thread_t *t : priv->threads)
+	{
+	  if (t->gdb_port == local_name)
+	    {
+	      t->inf_port = names[i];
+	      if (names[i] == lwp)
+		res = t->gdb_port;
+	    }
+	}
     }
 
   vm_deallocate (gdb_task, (vm_address_t) names,
diff --git a/gdb/darwin-nat.h b/gdb/darwin-nat.h
index 77feb0e..24c10b5 100644
--- a/gdb/darwin-nat.h
+++ b/gdb/darwin-nat.h
@@ -26,21 +26,20 @@
 struct darwin_exception_info
 {
   /* Exceptions handled by the port.  */
-  exception_mask_t masks[EXC_TYPES_COUNT];
+  exception_mask_t masks[EXC_TYPES_COUNT] {};
 
   /* Ports receiving exception messages.  */
-  mach_port_t ports[EXC_TYPES_COUNT];
+  mach_port_t ports[EXC_TYPES_COUNT] {};
 
   /* Type of messages sent.  */
-  exception_behavior_t behaviors[EXC_TYPES_COUNT];
+  exception_behavior_t behaviors[EXC_TYPES_COUNT] {};
 
   /* Type of state to be sent.  */
-  thread_state_flavor_t flavors[EXC_TYPES_COUNT];
+  thread_state_flavor_t flavors[EXC_TYPES_COUNT] {};
 
   /* Number of elements set.  */
-  mach_msg_type_number_t count;
+  mach_msg_type_number_t count = 0;
 };
-typedef struct darwin_exception_info darwin_exception_info;
 
 struct darwin_exception_msg
 {
@@ -95,36 +94,31 @@ struct private_thread_info
 };
 typedef struct private_thread_info darwin_thread_t;
 
-/* Define the threads vector type.  */
-DEF_VEC_O (darwin_thread_t);
-
-
 /* Describe an inferior.  */
-struct private_inferior
+struct darwin_inferior : public private_inferior
 {
   /* Corresponding task port.  */
-  task_t task;
+  task_t task = 0;
 
   /* Port which will receive the dead-name notification for the task port.
      This is used to detect the death of the task.  */
-  mach_port_t notify_port;
+  mach_port_t notify_port = 0;
 
   /* Initial exception handling.  */
   darwin_exception_info exception_info;
 
   /* Number of messages that have been received but not yet replied.  */
-  unsigned int pending_messages;
+  unsigned int pending_messages = 0;
 
   /* Set if inferior is not controlled by ptrace(2) but through Mach.  */
-  unsigned char no_ptrace;
+  bool no_ptrace = false;
 
   /* True if this task is suspended.  */
-  unsigned char suspended;
+  bool suspended = false;
 
   /* Sorted vector of known threads.  */
-  VEC(darwin_thread_t) *threads;
+  std::vector<darwin_thread_t *> threads;
 };
-typedef struct private_inferior darwin_inferior;
 
 /* Exception port.  */
 extern mach_port_t darwin_ex_port;
diff --git a/gdb/inferior.c b/gdb/inferior.c
index bcac981..9b3043d 100644
--- a/gdb/inferior.c
+++ b/gdb/inferior.c
@@ -71,6 +71,8 @@ set_current_inferior (struct inferior *inf)
   current_inferior_ = inf;
 }
 
+private_inferior::~private_inferior () = default;
+
 inferior::~inferior ()
 {
   inferior *inf = this;
@@ -80,7 +82,6 @@ inferior::~inferior ()
   xfree (inf->args);
   xfree (inf->terminal);
   target_desc_info_free (inf->tdesc_info);
-  xfree (inf->priv);
 }
 
 inferior::inferior (int pid_)
@@ -209,7 +210,6 @@ exit_inferior_1 (struct inferior *inftoex, int silent)
 
   inf->pid = 0;
   inf->fake_pid_p = 0;
-  xfree (inf->priv);
   inf->priv = NULL;
 
   if (inf->vfork_parent != NULL)
diff --git a/gdb/inferior.h b/gdb/inferior.h
index 37252a6..0705dd9 100644
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -263,7 +263,12 @@ enum stop_kind
 #define ON_STACK 1
 #define AT_ENTRY_POINT 4
 
-struct private_inferior;
+/* Base class for target-specific inferior data.  */
+
+struct private_inferior
+{
+  virtual ~private_inferior () = 0;
+};
 
 /* Inferior process specific part of `struct infcall_control_state'.
 
@@ -403,7 +408,7 @@ public:
   bool needs_setup = false;
 
   /* Private data used by the target vector implementation.  */
-  private_inferior *priv = NULL;
+  std::unique_ptr<private_inferior> priv;
 
   /* HAS_EXIT_CODE is true if the inferior exited with an exit code.
      In this case, the EXIT_CODE field is also valid.  */
diff --git a/gdb/remote.c b/gdb/remote.c
index 62ac055..f328080 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -5826,12 +5826,22 @@ static int is_pending_fork_parent_thread (struct thread_info *thread);
 
 /* Private per-inferior info for target remote processes.  */
 
-struct private_inferior
+struct remote_inferior : public private_inferior
 {
   /* Whether we can send a wildcard vCont for this process.  */
-  int may_wildcard_vcont;
+  bool may_wildcard_vcont = true;
 };
 
+/* Get the remote private inferior data associated to INF.  */
+
+static remote_inferior *get_remote_inferior (inferior *inf)
+{
+  if (inf->priv == NULL)
+    inf->priv.reset (new remote_inferior);
+
+  return (remote_inferior *) inf->priv.get ();
+}
+
 /* Structure used to track the construction of a vCont packet in the
    outgoing packet buffer.  This is used to send multiple vCont
    packets if we have more actions than would fit a single packet.  */
@@ -5993,9 +6003,9 @@ remote_commit_resume (struct target_ops *ops)
   /* And assume every process is individually wildcard-able too.  */
   ALL_NON_EXITED_INFERIORS (inf)
     {
-      if (inf->priv == NULL)
-	inf->priv = XNEW (struct private_inferior);
-      inf->priv->may_wildcard_vcont = 1;
+      remote_inferior *priv = get_remote_inferior (inf);
+
+      priv->may_wildcard_vcont = true;
     }
 
   /* Check for any pending events (not reported or processed yet) and
@@ -6008,7 +6018,7 @@ remote_commit_resume (struct target_ops *ops)
 	 can't wildcard that process.  */
       if (!tp->executing)
 	{
-	  tp->inf->priv->may_wildcard_vcont = 0;
+	  get_remote_inferior (tp->inf)->may_wildcard_vcont = false;
 
 	  /* And if we can't wildcard a process, we can't wildcard
 	     everything either.  */
@@ -6042,7 +6052,7 @@ remote_commit_resume (struct target_ops *ops)
 
       if (!remote_thr->last_resume_step
 	  && remote_thr->last_resume_sig == GDB_SIGNAL_0
-	  && tp->inf->priv->may_wildcard_vcont)
+	  && get_remote_inferior (tp->inf)->may_wildcard_vcont)
 	{
 	  /* We'll send a wildcard resume instead.  */
 	  remote_thr->vcont_resumed = 1;
@@ -6062,7 +6072,7 @@ remote_commit_resume (struct target_ops *ops)
 
   ALL_NON_EXITED_INFERIORS (inf)
     {
-      if (inf->priv->may_wildcard_vcont)
+      if (get_remote_inferior (inf)->may_wildcard_vcont)
 	{
 	  any_process_wildcard = 1;
 	  break;
@@ -6083,7 +6093,7 @@ remote_commit_resume (struct target_ops *ops)
 	{
 	  ALL_NON_EXITED_INFERIORS (inf)
 	    {
-	      if (inf->priv->may_wildcard_vcont)
+	      if (get_remote_inferior (inf)->may_wildcard_vcont)
 		{
 		  vcont_builder_push_action (&vcont_builder,
 					     pid_to_ptid (inf->pid),
@@ -6579,7 +6589,7 @@ check_pending_event_prevents_wildcard_vcont_callback
      we'd resume this process too.  */
   *may_global_wildcard_vcont = 0;
   if (inf != NULL)
-    inf->priv->may_wildcard_vcont = 0;
+    get_remote_inferior (inf)->may_wildcard_vcont = false;
 
   return 1;
 }
