From 02e12e3806bc60f66e3c446c4dfa9c06a400e604 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Wed, 2 Jan 2019 19:12:32 -0700 Subject: [PATCH] Use std::vector in type stacks This removes the use of VEC from parse.c and, at the same time, removes some related cleanups from c-exp.y. gdb/ChangeLog 2019-01-06 Tom Tromey * parser-defs.h (type_ptr): Remove typedef. Don't declare VEC. (union type_stack_elt) : 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. --- gdb/ChangeLog | 20 ++++++++++++++ gdb/c-exp.y | 66 ++++++++++++++++++++++++++++------------------- gdb/parse.c | 24 +++++------------ gdb/parser-defs.h | 9 ++----- 4 files changed, 68 insertions(+), 51 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 45490e9f1de..6ca534a0d24 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,23 @@ +2019-01-06 Tom Tromey + + * parser-defs.h (type_ptr): Remove typedef. Don't declare VEC. + (union type_stack_elt) : 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 PR gdb/28155: diff --git a/gdb/c-exp.y b/gdb/c-exp.y index 3078702b750..54eb38935bd 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>> type_lists; + std::vector> 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 *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 *); 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 *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; + 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 *typelist + = new std::vector; + 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 *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_restore = make_scoped_restore (&cpstate, &cstate); + gdb::unique_xmalloc_ptr macro_scope; if (expression_context_block) diff --git a/gdb/parse.c b/gdb/parse.c index de2d53b9de9..e7168acf7ab 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 * 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 *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 *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 195264f48a6..5b38477895a 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 *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 *typelist); extern int dump_subexp (struct expression *, struct ui_file *, int);