Remove a cleanup from parse_expression_for_completion
This removes a cleanup from parse_expression_for_completion, by changing various expression-completion functions to use gdb::unique_xmalloc_ptry rather than explicit malloc+free. Regression tested by the buildbot. gdb/ChangeLog 2018-02-21 Tom Tromey <tom@tromey.com> * value.h: (extract_field_op): Update. * eval.c (extract_field_op): Return a const char *. * expression.h (parse_expression_for_completion): Update. * completer.c (complete_expression): Update. (add_struct_fields): Make fieldname const. * parse.c (expout_completion_name): Now a unique_xmalloc_ptr. (mark_completion_tag, parse_exp_in_context_1): Update. (parse_expression_for_completion): Change "name" to unique_xmalloc_ptr*.
This commit is contained in:
parent
6ccb583f75
commit
3eac2b6548
|
@ -1,3 +1,15 @@
|
|||
2018-02-21 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* value.h: (extract_field_op): Update.
|
||||
* eval.c (extract_field_op): Return a const char *.
|
||||
* expression.h (parse_expression_for_completion): Update.
|
||||
* completer.c (complete_expression): Update.
|
||||
(add_struct_fields): Make fieldname const.
|
||||
* parse.c (expout_completion_name): Now a unique_xmalloc_ptr.
|
||||
(mark_completion_tag, parse_exp_in_context_1): Update.
|
||||
(parse_expression_for_completion): Change "name" to
|
||||
unique_xmalloc_ptr*.
|
||||
|
||||
2018-02-21 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* infcall.c (call_function_by_hand_dummy): Use std::vector.
|
||||
|
|
|
@ -962,7 +962,7 @@ location_completer_handle_brkchars (struct cmd_list_element *ignore,
|
|||
|
||||
static void
|
||||
add_struct_fields (struct type *type, completion_list &output,
|
||||
char *fieldname, int namelen)
|
||||
const char *fieldname, int namelen)
|
||||
{
|
||||
int i;
|
||||
int computed_type_name = 0;
|
||||
|
@ -1016,12 +1016,11 @@ complete_expression (completion_tracker &tracker,
|
|||
const char *text, const char *word)
|
||||
{
|
||||
struct type *type = NULL;
|
||||
char *fieldname;
|
||||
gdb::unique_xmalloc_ptr<char> fieldname;
|
||||
enum type_code code = TYPE_CODE_UNDEF;
|
||||
|
||||
/* Perform a tentative parse of the expression, to see whether a
|
||||
field completion is required. */
|
||||
fieldname = NULL;
|
||||
TRY
|
||||
{
|
||||
type = parse_expression_for_completion (text, &fieldname, &code);
|
||||
|
@ -1032,7 +1031,7 @@ complete_expression (completion_tracker &tracker,
|
|||
}
|
||||
END_CATCH
|
||||
|
||||
if (fieldname && type)
|
||||
if (fieldname != nullptr && type)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
|
@ -1045,25 +1044,20 @@ complete_expression (completion_tracker &tracker,
|
|||
if (TYPE_CODE (type) == TYPE_CODE_UNION
|
||||
|| TYPE_CODE (type) == TYPE_CODE_STRUCT)
|
||||
{
|
||||
int flen = strlen (fieldname);
|
||||
completion_list result;
|
||||
|
||||
add_struct_fields (type, result, fieldname, flen);
|
||||
xfree (fieldname);
|
||||
add_struct_fields (type, result, fieldname.get (),
|
||||
strlen (fieldname.get ()));
|
||||
tracker.add_completions (std::move (result));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (fieldname && code != TYPE_CODE_UNDEF)
|
||||
else if (fieldname != nullptr && code != TYPE_CODE_UNDEF)
|
||||
{
|
||||
struct cleanup *cleanup = make_cleanup (xfree, fieldname);
|
||||
|
||||
collect_symbol_completion_matches_type (tracker, fieldname, fieldname,
|
||||
code);
|
||||
do_cleanups (cleanup);
|
||||
collect_symbol_completion_matches_type (tracker, fieldname.get (),
|
||||
fieldname.get (), code);
|
||||
return;
|
||||
}
|
||||
xfree (fieldname);
|
||||
|
||||
complete_files_symbols (tracker, text, word);
|
||||
}
|
||||
|
|
|
@ -272,7 +272,7 @@ fetch_subexp_value (struct expression *exp, int *pc, struct value **valp,
|
|||
subexpression of the left-hand-side of the dereference. This is
|
||||
used when completing field names. */
|
||||
|
||||
char *
|
||||
const char *
|
||||
extract_field_op (struct expression *exp, int *subexp)
|
||||
{
|
||||
int tem;
|
||||
|
|
|
@ -101,8 +101,8 @@ extern expression_up parse_expression (const char *);
|
|||
extern expression_up parse_expression_with_language (const char *string,
|
||||
enum language lang);
|
||||
|
||||
extern struct type *parse_expression_for_completion (const char *, char **,
|
||||
enum type_code *);
|
||||
extern struct type *parse_expression_for_completion
|
||||
(const char *, gdb::unique_xmalloc_ptr<char> *, enum type_code *);
|
||||
|
||||
extern expression_up parse_exp_1 (const char **, CORE_ADDR pc,
|
||||
const struct block *, int);
|
||||
|
|
30
gdb/parse.c
30
gdb/parse.c
|
@ -88,7 +88,7 @@ static int expout_last_struct = -1;
|
|||
static enum type_code expout_tag_completion_type = TYPE_CODE_UNDEF;
|
||||
|
||||
/* The token for tagged type name completion. */
|
||||
static char *expout_completion_name;
|
||||
static gdb::unique_xmalloc_ptr<char> expout_completion_name;
|
||||
|
||||
|
||||
static unsigned int expressiondebug = 0;
|
||||
|
@ -575,9 +575,7 @@ mark_completion_tag (enum type_code tag, const char *ptr, int length)
|
|||
|| tag == TYPE_CODE_STRUCT
|
||||
|| tag == TYPE_CODE_ENUM);
|
||||
expout_tag_completion_type = tag;
|
||||
expout_completion_name = (char *) xmalloc (length + 1);
|
||||
memcpy (expout_completion_name, ptr, length);
|
||||
expout_completion_name[length] = '\0';
|
||||
expout_completion_name.reset (xstrndup (ptr, length));
|
||||
}
|
||||
|
||||
|
||||
|
@ -1137,8 +1135,7 @@ parse_exp_in_context_1 (const char **stringptr, CORE_ADDR pc,
|
|||
type_stack.depth = 0;
|
||||
expout_last_struct = -1;
|
||||
expout_tag_completion_type = TYPE_CODE_UNDEF;
|
||||
xfree (expout_completion_name);
|
||||
expout_completion_name = NULL;
|
||||
expout_completion_name.reset ();
|
||||
|
||||
comma_terminates = comma;
|
||||
|
||||
|
@ -1277,11 +1274,11 @@ parse_expression_with_language (const char *string, enum language lang)
|
|||
reference; furthermore, if the parsing ends in the field name,
|
||||
return the field name in *NAME. If the parsing ends in the middle
|
||||
of a field reference, but the reference is somehow invalid, throw
|
||||
an exception. In all other cases, return NULL. Returned non-NULL
|
||||
*NAME must be freed by the caller. */
|
||||
an exception. In all other cases, return NULL. */
|
||||
|
||||
struct type *
|
||||
parse_expression_for_completion (const char *string, char **name,
|
||||
parse_expression_for_completion (const char *string,
|
||||
gdb::unique_xmalloc_ptr<char> *name,
|
||||
enum type_code *code)
|
||||
{
|
||||
expression_up exp;
|
||||
|
@ -1306,23 +1303,24 @@ parse_expression_for_completion (const char *string, char **name,
|
|||
if (expout_tag_completion_type != TYPE_CODE_UNDEF)
|
||||
{
|
||||
*code = expout_tag_completion_type;
|
||||
*name = expout_completion_name;
|
||||
expout_completion_name = NULL;
|
||||
*name = std::move (expout_completion_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (expout_last_struct == -1)
|
||||
return NULL;
|
||||
|
||||
*name = extract_field_op (exp.get (), &subexp);
|
||||
if (!*name)
|
||||
return NULL;
|
||||
const char *fieldname = extract_field_op (exp.get (), &subexp);
|
||||
if (fieldname == NULL)
|
||||
{
|
||||
name->reset ();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
name->reset (xstrdup (fieldname));
|
||||
/* This might throw an exception. If so, we want to let it
|
||||
propagate. */
|
||||
val = evaluate_subexpression_type (exp.get (), subexp);
|
||||
/* (*NAME) is a part of the EXP memory block freed below. */
|
||||
*name = xstrdup (*name);
|
||||
|
||||
return value_type (val);
|
||||
}
|
||||
|
|
|
@ -889,7 +889,7 @@ extern void fetch_subexp_value (struct expression *exp, int *pc,
|
|||
struct value **val_chain,
|
||||
int preserve_errors);
|
||||
|
||||
extern char *extract_field_op (struct expression *exp, int *subexp);
|
||||
extern const char *extract_field_op (struct expression *exp, int *subexp);
|
||||
|
||||
extern struct value *evaluate_subexp_with_coercion (struct expression *,
|
||||
int *, enum noside);
|
||||
|
|
Loading…
Reference in New Issue