diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index 3078702b75..eb6a6847cf 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -66,6 +66,20 @@
 
 static struct parser_state *pstate = NULL;
 
+/* Data that must be held for the duration of a parse.  */
+
+struct c_parse_state
+{
+  /* These are used to hold type lists and type stacks that are
+     allocated during the parse.  */
+  std::vector<std::unique_ptr<std::vector<struct type *>>> type_lists;
+  std::vector<std::unique_ptr<struct type_stack>> type_stacks;
+};
+
+/* This is set and cleared in c_parse.  */
+
+static struct c_parse_state *cpstate;
+
 int yyparse (void);
 
 static int yylex (void);
@@ -101,7 +115,7 @@ static int type_aggregate_p (struct type *);
     enum exp_opcode opcode;
 
     struct stoken_vector svec;
-    VEC (type_ptr) *tvec;
+    std::vector<struct type *> *tvec;
 
     struct type_stack *type_stack;
 
@@ -114,7 +128,7 @@ static int parse_number (struct parser_state *par_state,
 			 const char *, int, int, YYSTYPE *);
 static struct stoken operator_stoken (const char *);
 static struct stoken typename_stoken (const char *);
-static void check_parameter_typelist (VEC (type_ptr) *);
+static void check_parameter_typelist (std::vector<struct type *> *);
 static void write_destructor_name (struct parser_state *par_state,
 				   struct stoken);
 
@@ -552,10 +566,9 @@ arglist	:	arglist ',' exp   %prec ABOVE_COMMA
 	;
 
 function_method:       exp '(' parameter_typelist ')' const_or_volatile
-			{ int i;
-			  VEC (type_ptr) *type_list = $3;
-			  struct type *type_elt;
-			  LONGEST len = VEC_length (type_ptr, type_list);
+			{
+			  std::vector<struct type *> *type_list = $3;
+			  LONGEST len = type_list->size ();
 
 			  write_exp_elt_opcode (pstate, TYPE_INSTANCE);
 			  /* Save the const/volatile qualifiers as
@@ -564,13 +577,10 @@ function_method:       exp '(' parameter_typelist ')' const_or_volatile
 			  write_exp_elt_longcst (pstate,
 						 follow_type_instance_flags ());
 			  write_exp_elt_longcst (pstate, len);
-			  for (i = 0;
-			       VEC_iterate (type_ptr, type_list, i, type_elt);
-			       ++i)
+			  for (type *type_elt : *type_list)
 			    write_exp_elt_type (pstate, type_elt);
 			  write_exp_elt_longcst(pstate, len);
 			  write_exp_elt_opcode (pstate, TYPE_INSTANCE);
-			  VEC_free (type_ptr, type_list);
 			}
 	;
 
@@ -1157,9 +1167,7 @@ ptr_operator:
 ptr_operator_ts: ptr_operator
 			{
 			  $$ = get_type_stack ();
-			  /* This cleanup is eventually run by
-			     c_parse.  */
-			  make_cleanup (type_stack_cleanup, $$);
+			  cpstate->type_stacks.emplace_back ($$);
 			}
 	;
 
@@ -1209,7 +1217,10 @@ array_mod:	'[' ']'
 	;
 
 func_mod:	'(' ')'
-			{ $$ = NULL; }
+			{
+			  $$ = new std::vector<struct type *>;
+			  cpstate->type_lists.emplace_back ($$);
+			}
 	|	'(' parameter_typelist ')'
 			{ $$ = $2; }
 	;
@@ -1471,7 +1482,7 @@ parameter_typelist:
 			{ check_parameter_typelist ($1); }
 	|	nonempty_typelist ',' DOTDOTDOT
 			{
-			  VEC_safe_push (type_ptr, $1, NULL);
+			  $1->push_back (NULL);
 			  check_parameter_typelist ($1);
 			  $$ = $1;
 			}
@@ -1480,13 +1491,16 @@ parameter_typelist:
 nonempty_typelist
 	:	type
 		{
-		  VEC (type_ptr) *typelist = NULL;
-		  VEC_safe_push (type_ptr, typelist, $1);
+		  std::vector<struct type *> *typelist =
+		    new std::vector<struct type *>;
+		  cpstate->type_lists.emplace_back (typelist);
+
+		  typelist->push_back ($1);
 		  $$ = typelist;
 		}
 	|	nonempty_typelist ',' type
 		{
-		  VEC_safe_push (type_ptr, $1, $3);
+		  $1->push_back ($3);
 		  $$ = $1;
 		}
 	;
@@ -1758,30 +1772,27 @@ type_aggregate_p (struct type *type)
 /* Validate a parameter typelist.  */
 
 static void
-check_parameter_typelist (VEC (type_ptr) *params)
+check_parameter_typelist (std::vector<struct type *> *params)
 {
   struct type *type;
   int ix;
 
-  for (ix = 0; VEC_iterate (type_ptr, params, ix, type); ++ix)
+  for (ix = 0; ix < params->size (); ++ix)
     {
+      type = (*params)[ix];
       if (type != NULL && TYPE_CODE (check_typedef (type)) == TYPE_CODE_VOID)
 	{
 	  if (ix == 0)
 	    {
-	      if (VEC_length (type_ptr, params) == 1)
+	      if (params->size () == 1)
 		{
 		  /* Ok.  */
 		  break;
 		}
-	      VEC_free (type_ptr, params);
 	      error (_("parameter types following 'void'"));
 	    }
 	  else
-	    {
-	      VEC_free (type_ptr, params);
-	      error (_("'void' invalid as parameter type"));
-	    }
+	    error (_("'void' invalid as parameter type"));
 	}
     }
 }
@@ -3276,6 +3287,9 @@ c_parse (struct parser_state *par_state)
   gdb_assert (par_state != NULL);
   pstate = par_state;
 
+  c_parse_state cstate;
+  scoped_restore cstate_resotre = make_scoped_restore (&cpstate, &cstate);
+
   gdb::unique_xmalloc_ptr<struct macro_scope> macro_scope;
 
   if (expression_context_block)
diff --git a/gdb/parse.c b/gdb/parse.c
index de2d53b9de..e7168acf7a 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -1457,7 +1457,7 @@ pop_type_int (void)
 
 /* Pop a type list element from the global type stack.  */
 
-static VEC (type_ptr) *
+static std::vector<struct type *> *
 pop_typelist (void)
 {
   gdb_assert (!type_stack.elements.empty ());
@@ -1501,7 +1501,7 @@ push_type_stack (struct type_stack *stack)
 
 /* Copy the global type stack into a newly allocated type stack and
    return it.  The global stack is cleared.  The returned type stack
-   must be freed with type_stack_cleanup.  */
+   must be freed with delete.  */
 
 struct type_stack *
 get_type_stack (void)
@@ -1511,22 +1511,12 @@ get_type_stack (void)
   return result;
 }
 
-/* A cleanup function that destroys a single type stack.  */
-
-void
-type_stack_cleanup (void *arg)
-{
-  struct type_stack *stack = (struct type_stack *) arg;
-
-  delete stack;
-}
-
 /* Push a function type with arguments onto the global type stack.
    LIST holds the argument types.  If the final item in LIST is NULL,
    then the function will be varargs.  */
 
 void
-push_typelist (VEC (type_ptr) *list)
+push_typelist (std::vector<struct type *> *list)
 {
   type_stack_elt elt;
   elt.typelist_val = list;
@@ -1655,14 +1645,12 @@ follow_types (struct type *follow_type)
 
       case tp_function_with_arguments:
 	{
-	  VEC (type_ptr) *args = pop_typelist ();
+	  std::vector<struct type *> *args = pop_typelist ();
 
 	  follow_type
 	    = lookup_function_type_with_arguments (follow_type,
-						   VEC_length (type_ptr, args),
-						   VEC_address (type_ptr,
-								args));
-	  VEC_free (type_ptr, args);
+						   args->size (),
+						   args->data ());
 	}
 	break;
 
diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h
index 195264f48a..5b38477895 100644
--- a/gdb/parser-defs.h
+++ b/gdb/parser-defs.h
@@ -200,9 +200,6 @@ struct objc_class_str
     int theclass;
   };
 
-typedef struct type *type_ptr;
-DEF_VEC_P (type_ptr);
-
 /* For parsing of complicated types.
    An array should be preceded in the list by the size of the array.  */
 enum type_pieces
@@ -225,7 +222,7 @@ union type_stack_elt
     enum type_pieces piece;
     int int_val;
     struct type_stack *stack_val;
-    VEC (type_ptr) *typelist_val;
+    std::vector<struct type *> *typelist_val;
   };
 
 /* The type stack is an instance of this structure.  */
@@ -303,9 +300,7 @@ extern struct type_stack *append_type_stack (struct type_stack *to,
 
 extern void push_type_stack (struct type_stack *stack);
 
-extern void type_stack_cleanup (void *arg);
-
-extern void push_typelist (VEC (type_ptr) *typelist);
+extern void push_typelist (std::vector<struct type *> *typelist);
 
 extern int dump_subexp (struct expression *, struct ui_file *, int);
 
