+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.
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;
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);
}
END_CATCH
- if (fieldname && type)
+ if (fieldname != nullptr && type)
{
for (;;)
{
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);
}
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;
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);
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;
\f
static unsigned int expressiondebug = 0;
|| 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));
}
\f
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;
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;
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);
}
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);