/* Parse expressions for GDB.
- Copyright (C) 1986-2020 Free Software Foundation, Inc.
+ Copyright (C) 1986-2021 Free Software Foundation, Inc.
Modified from expread.y by the Department of Computer Science at the
State University of New York at Buffalo, 1991.
print_subexp_standard,
operator_length_standard,
operator_check_standard,
- op_name_standard,
dump_subexp_body_standard,
evaluate_subexp_standard
};
static expression_up parse_exp_in_context (const char **, CORE_ADDR,
const struct block *, int,
- int, int *,
+ bool, int *,
innermost_block_tracker *,
expr_completion_state *);
expr_builder::expr_builder (const struct language_defn *lang,
struct gdbarch *gdbarch)
: expout_size (10),
- expout (XNEWVAR (expression,
- (sizeof (expression)
- + EXP_ELEM_TO_BYTES (expout_size)))),
+ expout (new expression (lang, gdbarch, expout_size)),
expout_ptr (0)
{
- expout->language_defn = lang;
- expout->gdbarch = gdbarch;
}
expression_up
excess elements. */
expout->nelts = expout_ptr;
- expout.reset (XRESIZEVAR (expression, expout.release (),
- (sizeof (expression)
- + EXP_ELEM_TO_BYTES (expout_ptr))));
+ expout->resize (expout_ptr);
return std::move (expout);
}
+expression::expression (const struct language_defn *lang, struct gdbarch *arch,
+ size_t n)
+ : language_defn (lang),
+ gdbarch (arch),
+ elts (nullptr)
+{
+ resize (n);
+}
+
+expression::~expression ()
+{
+ xfree (elts);
+}
+
+void
+expression::resize (size_t n)
+{
+ elts = XRESIZEVAR (union exp_element, elts, EXP_ELEM_TO_BYTES (n));
+}
+
/* This page contains the functions for adding data to the struct expression
being constructed. */
if (ps->expout_ptr >= ps->expout_size)
{
ps->expout_size *= 2;
- ps->expout.reset (XRESIZEVAR (expression, ps->expout.release (),
- (sizeof (expression)
- + EXP_ELEM_TO_BYTES (ps->expout_size))));
+ ps->expout->resize (ps->expout_size);
}
ps->expout->elts[ps->expout_ptr++] = *expelt;
}
prefixify_expression (struct expression *expr, int last_struct)
{
gdb_assert (expr->nelts > 0);
- int len = sizeof (struct expression) + EXP_ELEM_TO_BYTES (expr->nelts);
- struct expression *temp;
+ int len = EXP_ELEM_TO_BYTES (expr->nelts);
+ struct expression temp (expr->language_defn, expr->gdbarch, expr->nelts);
int inpos = expr->nelts, outpos = 0;
- temp = (struct expression *) alloca (len);
-
/* Copy the original expression into temp. */
- memcpy (temp, expr, len);
+ memcpy (temp.elts, expr->elts, len);
- return prefixify_subexp (temp, expr, inpos, outpos, last_struct);
+ return prefixify_subexp (&temp, expr, inpos, outpos, last_struct);
}
/* Return the number of exp_elements in the postfix subexpression
parse_exp_1 (const char **stringptr, CORE_ADDR pc, const struct block *block,
int comma, innermost_block_tracker *tracker)
{
- return parse_exp_in_context (stringptr, pc, block, comma, 0, NULL,
+ return parse_exp_in_context (stringptr, pc, block, comma, false, NULL,
tracker, nullptr);
}
static expression_up
parse_exp_in_context (const char **stringptr, CORE_ADDR pc,
const struct block *block,
- int comma, int void_context_p, int *out_subexp,
+ int comma, bool void_context_p, int *out_subexp,
innermost_block_tracker *tracker,
expr_completion_state *cstate)
{
parser_state ps (lang, get_current_arch (), expression_context_block,
expression_context_pc, comma, *stringptr,
- cstate != nullptr, tracker);
+ cstate != nullptr, tracker, void_context_p);
scoped_restore_current_language lang_saver;
set_language (lang->la_language);
if (out_subexp)
*out_subexp = subexp;
- lang->post_parser (&result, void_context_p, ps.parse_completion, tracker);
+ lang->post_parser (&result, &ps);
if (expressiondebug)
dump_prefix_expression (result.get (), gdb_stdlog);
return result;
}
-/* Parse STRING as an expression, and complain if this fails
- to use up all of the contents of STRING. */
+/* Parse STRING as an expression, and complain if this fails to use up
+ all of the contents of STRING. TRACKER, if non-null, will be
+ updated by the parser. VOID_CONTEXT_P should be true to indicate
+ that the expression may be expected to return a value with void
+ type. Parsers are free to ignore this, or to use it to help with
+ overload resolution decisions. */
expression_up
-parse_expression (const char *string, innermost_block_tracker *tracker)
+parse_expression (const char *string, innermost_block_tracker *tracker,
+ bool void_context_p)
{
- expression_up exp = parse_exp_1 (&string, 0, 0, 0, tracker);
+ expression_up exp = parse_exp_in_context (&string, 0, nullptr, 0,
+ void_context_p, nullptr,
+ tracker, nullptr);
if (*string)
error (_("Junk after end of expression."));
return exp;
try
{
- exp = parse_exp_in_context (&string, 0, 0, 0, 0, &subexp,
+ exp = parse_exp_in_context (&string, 0, 0, 0, false, &subexp,
nullptr, &cstate);
}
catch (const gdb_exception_error &except)
for (arg = 0; arg < nargs; arg++)
{
struct type *inst_type = elts[pos + 3 + arg].type;
- struct objfile *inst_objfile = TYPE_OBJFILE (inst_type);
+ struct objfile *inst_objfile = inst_type->objfile_owner ();
if (inst_objfile && (*objfile_func) (inst_objfile, data))
return 1;
/* Invoke callbacks for TYPE and OBJFILE if they were set as non-NULL. */
- if (type && TYPE_OBJFILE (type)
- && (*objfile_func) (TYPE_OBJFILE (type), data))
+ if (type != nullptr && type->objfile_owner () != nullptr
+ && objfile_func (type->objfile_owner (), data))
return 1;
+
if (objfile && (*objfile_func) (objfile, data))
return 1;
{
ps->expout_size = std::max (ps->expout_size * 2,
ps->expout_ptr + lenelt + 10);
- ps->expout.reset (XRESIZEVAR (expression,
- ps->expout.release (),
- (sizeof (struct expression)
- + EXP_ELEM_TO_BYTES (ps->expout_size))));
+ ps->expout->resize (ps->expout_size);
}
}