+2019-01-06 Tom Tromey <tom@tromey.com>
+
+ * parser-defs.h (type_ptr): Remove typedef. Don't declare VEC.
+ (union type_stack_elt) <typelist_val>: Now a pointer to
+ std::vector.
+ (type_stack_cleanup): Don't declare.
+ (push_typelist): Update.
+ * parse.c (pop_typelist): Return a std::vector.
+ (push_typelist): Take a std::vector.
+ (follow_types): Update. Do not free args.
+ (type_stack_cleanup): Remove.
+ * c-exp.y (struct c_parse_state): New.
+ (cpstate): New global.
+ (type_aggregate_p, exp, ptr_operator, parameter_typelist)
+ (nonempty_typelist): Update.
+ (func_mod): Create a new vector.
+ (c_parse): Create a c_parse_state.
+ (check_parameter_typelist): Do not delete params.
+ (function_method): Update. Do not delete type_list.
+
2019-01-06 Tom Tromey <tom@tromey.com>
PR gdb/28155:
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);
enum exp_opcode opcode;
struct stoken_vector svec;
- VEC (type_ptr) *tvec;
+ std::vector<struct type *> *tvec;
struct type_stack *type_stack;
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);
;
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
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);
}
;
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 ($$);
}
;
;
func_mod: '(' ')'
- { $$ = NULL; }
+ {
+ $$ = new std::vector<struct type *>;
+ cpstate->type_lists.emplace_back ($$);
+ }
| '(' parameter_typelist ')'
{ $$ = $2; }
;
{ check_parameter_typelist ($1); }
| nonempty_typelist ',' DOTDOTDOT
{
- VEC_safe_push (type_ptr, $1, NULL);
+ $1->push_back (NULL);
check_parameter_typelist ($1);
$$ = $1;
}
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;
}
;
/* 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"));
}
}
}
gdb_assert (par_state != NULL);
pstate = par_state;
+ c_parse_state cstate;
+ scoped_restore cstate_restore = make_scoped_restore (&cpstate, &cstate);
+
gdb::unique_xmalloc_ptr<struct macro_scope> macro_scope;
if (expression_context_block)
/* 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 ());
/* 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)
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;
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;