X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fax-gdb.c;h=54643dd79ba33a22454f47f7fec48c27aa461c16;hb=refs%2Fheads%2Fconcurrent-displaced-stepping-2020-04-01;hp=4196655e61d8a0409c9b69c0689930398cb0bed2;hpb=92bc6a206434a8b6922846d064e9c701a5a10a0e;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c index 4196655e61..54643dd79b 100644 --- a/gdb/ax-gdb.c +++ b/gdb/ax-gdb.c @@ -1,6 +1,6 @@ /* GDB-specific functions for operating on agent expressions. - Copyright (C) 1998-2013 Free Software Foundation, Inc. + Copyright (C) 1998-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -30,11 +30,9 @@ #include "target.h" #include "ax.h" #include "ax-gdb.h" -#include "gdb_string.h" #include "block.h" #include "regcache.h" #include "user-regs.h" -#include "language.h" #include "dictionary.h" #include "breakpoint.h" #include "tracepoint.h" @@ -42,11 +40,13 @@ #include "arch-utils.h" #include "cli/cli-utils.h" #include "linespec.h" - +#include "location.h" +#include "objfiles.h" +#include "typeprint.h" #include "valprint.h" #include "c-lang.h" -#include "format.h" +#include "gdbsupport/format.h" /* To make sense of this file, you should read doc/agentexpr.texi. Then look at the types and enums in ax-gdb.h. For the code itself, @@ -77,8 +77,7 @@ static struct value *const_var_ref (struct symbol *var); static struct value *const_expr (union exp_element **pc); static struct value *maybe_const_expr (union exp_element **pc); -static void gen_traced_pop (struct gdbarch *, struct agent_expr *, - struct axs_value *); +static void gen_traced_pop (struct agent_expr *, struct axs_value *); static void gen_sign_extend (struct agent_expr *, struct type *); static void gen_extend (struct agent_expr *, struct type *); @@ -86,31 +85,28 @@ static void gen_fetch (struct agent_expr *, struct type *); static void gen_left_shift (struct agent_expr *, int); -static void gen_frame_args_address (struct gdbarch *, struct agent_expr *); -static void gen_frame_locals_address (struct gdbarch *, struct agent_expr *); +static void gen_frame_args_address (struct agent_expr *); +static void gen_frame_locals_address (struct agent_expr *); static void gen_offset (struct agent_expr *ax, int offset); static void gen_sym_offset (struct agent_expr *, struct symbol *); -static void gen_var_ref (struct gdbarch *, struct agent_expr *ax, - struct axs_value *value, struct symbol *var); +static void gen_var_ref (struct agent_expr *ax, struct axs_value *value, + struct symbol *var); static void gen_int_literal (struct agent_expr *ax, struct axs_value *value, LONGEST k, struct type *type); -static void gen_usual_unary (struct expression *exp, struct agent_expr *ax, - struct axs_value *value); +static void gen_usual_unary (struct agent_expr *ax, struct axs_value *value); static int type_wider_than (struct type *type1, struct type *type2); static struct type *max_type (struct type *type1, struct type *type2); static void gen_conversion (struct agent_expr *ax, struct type *from, struct type *to); static int is_nontrivial_conversion (struct type *from, struct type *to); -static void gen_usual_arithmetic (struct expression *exp, - struct agent_expr *ax, +static void gen_usual_arithmetic (struct agent_expr *ax, struct axs_value *value1, struct axs_value *value2); -static void gen_integral_promotions (struct expression *exp, - struct agent_expr *ax, +static void gen_integral_promotions (struct agent_expr *ax, struct axs_value *value); static void gen_cast (struct agent_expr *ax, struct axs_value *value, struct type *type); @@ -128,30 +124,28 @@ static void gen_binop (struct agent_expr *ax, struct axs_value *value1, struct axs_value *value2, enum agent_op op, - enum agent_op op_unsigned, int may_carry, char *name); + enum agent_op op_unsigned, int may_carry, + const char *name); static void gen_logical_not (struct agent_expr *ax, struct axs_value *value, struct type *result_type); static void gen_complement (struct agent_expr *ax, struct axs_value *value); -static void gen_deref (struct agent_expr *, struct axs_value *); -static void gen_address_of (struct agent_expr *, struct axs_value *); -static void gen_bitfield_ref (struct expression *exp, struct agent_expr *ax, - struct axs_value *value, +static void gen_deref (struct axs_value *); +static void gen_address_of (struct axs_value *); +static void gen_bitfield_ref (struct agent_expr *ax, struct axs_value *value, struct type *type, int start, int end); -static void gen_primitive_field (struct expression *exp, - struct agent_expr *ax, +static void gen_primitive_field (struct agent_expr *ax, struct axs_value *value, int offset, int fieldno, struct type *type); -static int gen_struct_ref_recursive (struct expression *exp, - struct agent_expr *ax, +static int gen_struct_ref_recursive (struct agent_expr *ax, struct axs_value *value, - char *field, int offset, + const char *field, int offset, struct type *type); -static void gen_struct_ref (struct expression *exp, struct agent_expr *ax, +static void gen_struct_ref (struct agent_expr *ax, struct axs_value *value, - char *field, - char *operator_name, char *operand_name); -static void gen_static_field (struct gdbarch *gdbarch, - struct agent_expr *ax, struct axs_value *value, + const char *field, + const char *operator_name, + const char *operand_name); +static void gen_static_field (struct agent_expr *ax, struct axs_value *value, struct type *type, int fieldno); static void gen_repeat (struct expression *exp, union exp_element **pc, struct agent_expr *ax, struct axs_value *value); @@ -164,8 +158,6 @@ static void gen_expr_binop_rest (struct expression *exp, struct axs_value *value, struct axs_value *value1, struct axs_value *value2); - -static void agent_command (char *exp, int from_tty); /* Detecting constant expressions. */ @@ -316,20 +308,19 @@ maybe_const_expr (union exp_element **pc) classes, and generate tracing bytecodes for each. */ static void -gen_trace_static_fields (struct gdbarch *gdbarch, - struct agent_expr *ax, +gen_trace_static_fields (struct agent_expr *ax, struct type *type) { int i, nbases = TYPE_N_BASECLASSES (type); struct axs_value value; - CHECK_TYPEDEF (type); + type = check_typedef (type); - for (i = TYPE_NFIELDS (type) - 1; i >= nbases; i--) + for (i = type->num_fields () - 1; i >= nbases; i--) { - if (field_is_static (&TYPE_FIELD (type, i))) + if (field_is_static (&type->field (i))) { - gen_static_field (gdbarch, ax, &value, type, i); + gen_static_field (ax, &value, type, i); if (value.optimized_out) continue; switch (value.kind) @@ -359,7 +350,7 @@ gen_trace_static_fields (struct gdbarch *gdbarch, { struct type *basetype = check_typedef (TYPE_BASECLASS (type, i)); - gen_trace_static_fields (gdbarch, ax, basetype); + gen_trace_static_fields (ax, basetype); } } @@ -367,12 +358,11 @@ gen_trace_static_fields (struct gdbarch *gdbarch, the value. Useful on the left side of a comma, and at the end of an expression being used for tracing. */ static void -gen_traced_pop (struct gdbarch *gdbarch, - struct agent_expr *ax, struct axs_value *value) +gen_traced_pop (struct agent_expr *ax, struct axs_value *value) { int string_trace = 0; if (ax->trace_string - && TYPE_CODE (value->type) == TYPE_CODE_PTR + && value->type->code () == TYPE_CODE_PTR && c_textual_element_type (check_typedef (TYPE_TARGET_TYPE (value->type)), 's')) string_trace = 1; @@ -394,26 +384,25 @@ gen_traced_pop (struct gdbarch *gdbarch, case axs_lvalue_memory: { - if (string_trace) - ax_simple (ax, aop_dup); - /* Initialize the TYPE_LENGTH if it is a typedef. */ check_typedef (value->type); - /* There's no point in trying to use a trace_quick bytecode - here, since "trace_quick SIZE pop" is three bytes, whereas - "const8 SIZE trace" is also three bytes, does the same - thing, and the simplest code which generates that will also - work correctly for objects with large sizes. */ - ax_const_l (ax, TYPE_LENGTH (value->type)); - ax_simple (ax, aop_trace); - if (string_trace) { - ax_simple (ax, aop_ref32); + gen_fetch (ax, value->type); ax_const_l (ax, ax->trace_string); ax_simple (ax, aop_tracenz); } + else + { + /* There's no point in trying to use a trace_quick bytecode + here, since "trace_quick SIZE pop" is three bytes, whereas + "const8 SIZE trace" is also three bytes, does the same + thing, and the simplest code which generates that will also + work correctly for objects with large sizes. */ + ax_const_l (ax, TYPE_LENGTH (value->type)); + ax_simple (ax, aop_trace); + } } break; @@ -440,9 +429,9 @@ gen_traced_pop (struct gdbarch *gdbarch, /* To trace C++ classes with static fields stored elsewhere. */ if (ax->tracing - && (TYPE_CODE (value->type) == TYPE_CODE_STRUCT - || TYPE_CODE (value->type) == TYPE_CODE_UNION)) - gen_trace_static_fields (gdbarch, ax, value->type); + && (value->type->code () == TYPE_CODE_STRUCT + || value->type->code () == TYPE_CODE_UNION)) + gen_trace_static_fields (ax, value->type); } @@ -485,13 +474,14 @@ gen_fetch (struct agent_expr *ax, struct type *type) ax_trace_quick (ax, TYPE_LENGTH (type)); } - if (TYPE_CODE (type) == TYPE_CODE_RANGE) + if (type->code () == TYPE_CODE_RANGE) type = TYPE_TARGET_TYPE (type); - switch (TYPE_CODE (type)) + switch (type->code ()) { case TYPE_CODE_PTR: case TYPE_CODE_REF: + case TYPE_CODE_RVALUE_REF: case TYPE_CODE_ENUM: case TYPE_CODE_INT: case TYPE_CODE_CHAR: @@ -530,7 +520,7 @@ gen_fetch (struct agent_expr *ax, struct type *type) type. Error out and give callers a chance to handle the failure gracefully. */ error (_("gen_fetch: Unsupported type code `%s'."), - TYPE_NAME (type)); + type->name ()); } } @@ -560,12 +550,12 @@ gen_left_shift (struct agent_expr *ax, int distance) /* Generate code to push the base address of the argument portion of the top stack frame. */ static void -gen_frame_args_address (struct gdbarch *gdbarch, struct agent_expr *ax) +gen_frame_args_address (struct agent_expr *ax) { int frame_reg; LONGEST frame_offset; - gdbarch_virtual_frame_pointer (gdbarch, + gdbarch_virtual_frame_pointer (ax->gdbarch, ax->scope, &frame_reg, &frame_offset); ax_reg (ax, frame_reg); gen_offset (ax, frame_offset); @@ -575,12 +565,12 @@ gen_frame_args_address (struct gdbarch *gdbarch, struct agent_expr *ax) /* Generate code to push the base address of the locals portion of the top stack frame. */ static void -gen_frame_locals_address (struct gdbarch *gdbarch, struct agent_expr *ax) +gen_frame_locals_address (struct agent_expr *ax) { int frame_reg; LONGEST frame_offset; - gdbarch_virtual_frame_pointer (gdbarch, + gdbarch_virtual_frame_pointer (ax->gdbarch, ax->scope, &frame_reg, &frame_offset); ax_reg (ax, frame_reg); gen_offset (ax, frame_offset); @@ -625,8 +615,7 @@ gen_sym_offset (struct agent_expr *ax, struct symbol *var) symbol VAR. Set VALUE to describe the result. */ static void -gen_var_ref (struct gdbarch *gdbarch, struct agent_expr *ax, - struct axs_value *value, struct symbol *var) +gen_var_ref (struct agent_expr *ax, struct axs_value *value, struct symbol *var) { /* Dereference any typedefs. */ value->type = check_typedef (SYMBOL_TYPE (var)); @@ -634,7 +623,7 @@ gen_var_ref (struct gdbarch *gdbarch, struct agent_expr *ax, if (SYMBOL_COMPUTED_OPS (var) != NULL) { - SYMBOL_COMPUTED_OPS (var)->tracepoint_var_ref (var, gdbarch, ax, value); + SYMBOL_COMPUTED_OPS (var)->tracepoint_var_ref (var, ax, value); return; } @@ -664,33 +653,33 @@ gen_var_ref (struct gdbarch *gdbarch, struct agent_expr *ax, break; case LOC_ARG: /* var lives in argument area of frame */ - gen_frame_args_address (gdbarch, ax); + gen_frame_args_address (ax); gen_sym_offset (ax, var); value->kind = axs_lvalue_memory; break; case LOC_REF_ARG: /* As above, but the frame slot really holds the address of the variable. */ - gen_frame_args_address (gdbarch, ax); + gen_frame_args_address (ax); gen_sym_offset (ax, var); /* Don't assume any particular pointer size. */ - gen_fetch (ax, builtin_type (gdbarch)->builtin_data_ptr); + gen_fetch (ax, builtin_type (ax->gdbarch)->builtin_data_ptr); value->kind = axs_lvalue_memory; break; case LOC_LOCAL: /* var lives in locals area of frame */ - gen_frame_locals_address (gdbarch, ax); + gen_frame_locals_address (ax); gen_sym_offset (ax, var); value->kind = axs_lvalue_memory; break; case LOC_TYPEDEF: error (_("Cannot compute value of typedef `%s'."), - SYMBOL_PRINT_NAME (var)); + var->print_name ()); break; case LOC_BLOCK: - ax_const_l (ax, BLOCK_START (SYMBOL_BLOCK_VALUE (var))); + ax_const_l (ax, BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (var))); value->kind = axs_rvalue; break; @@ -699,7 +688,8 @@ gen_var_ref (struct gdbarch *gdbarch, struct agent_expr *ax, this as an lvalue or rvalue, the caller will generate the right code. */ value->kind = axs_lvalue_register; - value->u.reg = SYMBOL_REGISTER_OPS (var)->register_number (var, gdbarch); + value->u.reg + = SYMBOL_REGISTER_OPS (var)->register_number (var, ax->gdbarch); break; /* A lot like LOC_REF_ARG, but the pointer lives directly in a @@ -707,20 +697,21 @@ gen_var_ref (struct gdbarch *gdbarch, struct agent_expr *ax, because it's just like any other case where the thing has a real address. */ case LOC_REGPARM_ADDR: - ax_reg (ax, SYMBOL_REGISTER_OPS (var)->register_number (var, gdbarch)); + ax_reg (ax, + SYMBOL_REGISTER_OPS (var)->register_number (var, ax->gdbarch)); value->kind = axs_lvalue_memory; break; case LOC_UNRESOLVED: { - struct minimal_symbol *msym - = lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (var), NULL, NULL); + struct bound_minimal_symbol msym + = lookup_minimal_symbol (var->linkage_name (), NULL, NULL); - if (!msym) - error (_("Couldn't resolve symbol `%s'."), SYMBOL_PRINT_NAME (var)); + if (!msym.minsym) + error (_("Couldn't resolve symbol `%s'."), var->print_name ()); /* Push the address of the variable. */ - ax_const_l (ax, SYMBOL_VALUE_ADDRESS (msym)); + ax_const_l (ax, BMSYMBOL_VALUE_ADDRESS (msym)); value->kind = axs_lvalue_memory; } break; @@ -736,10 +727,27 @@ gen_var_ref (struct gdbarch *gdbarch, struct agent_expr *ax, default: error (_("Cannot find value of botched symbol `%s'."), - SYMBOL_PRINT_NAME (var)); + var->print_name ()); break; } } + +/* Generate code for a minimal symbol variable reference to AX. The + variable is the symbol MINSYM, of OBJFILE. Set VALUE to describe + the result. */ + +static void +gen_msym_var_ref (agent_expr *ax, axs_value *value, + minimal_symbol *msymbol, objfile *objf) +{ + CORE_ADDR address; + type *t = find_minsym_type_and_address (msymbol, objf, &address); + value->type = t; + value->optimized_out = false; + ax_const_l (ax, address); + value->kind = axs_lvalue_memory; +} + @@ -767,10 +775,10 @@ require_rvalue (struct agent_expr *ax, struct axs_value *value) /* Only deal with scalars, structs and such may be too large to fit in a stack entry. */ value->type = check_typedef (value->type); - if (TYPE_CODE (value->type) == TYPE_CODE_ARRAY - || TYPE_CODE (value->type) == TYPE_CODE_STRUCT - || TYPE_CODE (value->type) == TYPE_CODE_UNION - || TYPE_CODE (value->type) == TYPE_CODE_FUNC) + if (value->type->code () == TYPE_CODE_ARRAY + || value->type->code () == TYPE_CODE_STRUCT + || value->type->code () == TYPE_CODE_UNION + || value->type->code () == TYPE_CODE_FUNC) error (_("Value not scalar: cannot be an rvalue.")); switch (value->kind) @@ -816,15 +824,14 @@ require_rvalue (struct agent_expr *ax, struct axs_value *value) lvalue through unchanged, and let `+' raise an error. */ static void -gen_usual_unary (struct expression *exp, struct agent_expr *ax, - struct axs_value *value) +gen_usual_unary (struct agent_expr *ax, struct axs_value *value) { /* We don't have to generate any code for the usual integral conversions, since values are always represented as full-width on the stack. Should we tweak the type? */ /* Some types require special handling. */ - switch (TYPE_CODE (value->type)) + switch (value->type->code ()) { /* Functions get converted to a pointer to the function. */ case TYPE_CODE_FUNC: @@ -886,7 +893,7 @@ gen_conversion (struct agent_expr *ax, struct type *from, struct type *to) /* If we're converting to a narrower type, then we need to clear out the upper bits. */ if (TYPE_LENGTH (to) < TYPE_LENGTH (from)) - gen_extend (ax, from); + gen_extend (ax, to); /* If the two values have equal width, but different signednesses, then we need to extend. */ @@ -911,7 +918,7 @@ gen_conversion (struct agent_expr *ax, struct type *from, struct type *to) static int is_nontrivial_conversion (struct type *from, struct type *to) { - struct agent_expr *ax = new_agent_expr (NULL, 0); + agent_expr_up ax (new agent_expr (NULL, 0)); int nontrivial; /* Actually generate the code, and see if anything came out. At the @@ -920,9 +927,8 @@ is_nontrivial_conversion (struct type *from, struct type *to) floating point and the like, it may not be. Doing things this way allows this function to be independent of the logic in gen_conversion. */ - gen_conversion (ax, from, to); + gen_conversion (ax.get (), from, to); nontrivial = ax->len > 0; - free_agent_expr (ax); return nontrivial; } @@ -933,19 +939,19 @@ is_nontrivial_conversion (struct type *from, struct type *to) and promotes each argument to that type. *VALUE1 and *VALUE2 describe the values as they are passed in, and as they are left. */ static void -gen_usual_arithmetic (struct expression *exp, struct agent_expr *ax, - struct axs_value *value1, struct axs_value *value2) +gen_usual_arithmetic (struct agent_expr *ax, struct axs_value *value1, + struct axs_value *value2) { /* Do the usual binary conversions. */ - if (TYPE_CODE (value1->type) == TYPE_CODE_INT - && TYPE_CODE (value2->type) == TYPE_CODE_INT) + if (value1->type->code () == TYPE_CODE_INT + && value2->type->code () == TYPE_CODE_INT) { /* The ANSI integral promotions seem to work this way: Order the integer types by size, and then by signedness: an n-bit unsigned type is considered "wider" than an n-bit signed type. Promote to the "wider" of the two types, and always promote at least to int. */ - struct type *target = max_type (builtin_type (exp->gdbarch)->builtin_int, + struct type *target = max_type (builtin_type (ax->gdbarch)->builtin_int, max_type (value1->type, value2->type)); /* Deal with value2, on the top of the stack. */ @@ -970,10 +976,9 @@ gen_usual_arithmetic (struct expression *exp, struct agent_expr *ax, the value on the top of the stack, as described by VALUE. Assume the value has integral type. */ static void -gen_integral_promotions (struct expression *exp, struct agent_expr *ax, - struct axs_value *value) +gen_integral_promotions (struct agent_expr *ax, struct axs_value *value) { - const struct builtin_type *builtin = builtin_type (exp->gdbarch); + const struct builtin_type *builtin = builtin_type (ax->gdbarch); if (!type_wider_than (value->type, builtin->builtin_int)) { @@ -998,10 +1003,11 @@ gen_cast (struct agent_expr *ax, struct axs_value *value, struct type *type) /* Dereference typedefs. */ type = check_typedef (type); - switch (TYPE_CODE (type)) + switch (type->code ()) { case TYPE_CODE_PTR: case TYPE_CODE_REF: + case TYPE_CODE_RVALUE_REF: /* It's implementation-defined, and I'll bet this is what GCC does. */ break; @@ -1064,7 +1070,7 @@ gen_ptradd (struct agent_expr *ax, struct axs_value *value, struct axs_value *value1, struct axs_value *value2) { gdb_assert (pointer_type (value1->type)); - gdb_assert (TYPE_CODE (value2->type) == TYPE_CODE_INT); + gdb_assert (value2->type->code () == TYPE_CODE_INT); gen_scale (ax, aop_mul, value1->type); ax_simple (ax, aop_add); @@ -1080,7 +1086,7 @@ gen_ptrsub (struct agent_expr *ax, struct axs_value *value, struct axs_value *value1, struct axs_value *value2) { gdb_assert (pointer_type (value1->type)); - gdb_assert (TYPE_CODE (value2->type) == TYPE_CODE_INT); + gdb_assert (value2->type->code () == TYPE_CODE_INT); gen_scale (ax, aop_mul, value1->type); ax_simple (ax, aop_sub); @@ -1149,11 +1155,11 @@ static void gen_binop (struct agent_expr *ax, struct axs_value *value, struct axs_value *value1, struct axs_value *value2, enum agent_op op, enum agent_op op_unsigned, - int may_carry, char *name) + int may_carry, const char *name) { /* We only handle INT op INT. */ - if ((TYPE_CODE (value1->type) != TYPE_CODE_INT) - || (TYPE_CODE (value2->type) != TYPE_CODE_INT)) + if ((value1->type->code () != TYPE_CODE_INT) + || (value2->type->code () != TYPE_CODE_INT)) error (_("Invalid combination of types in %s."), name); ax_simple (ax, @@ -1169,8 +1175,8 @@ static void gen_logical_not (struct agent_expr *ax, struct axs_value *value, struct type *result_type) { - if (TYPE_CODE (value->type) != TYPE_CODE_INT - && TYPE_CODE (value->type) != TYPE_CODE_PTR) + if (value->type->code () != TYPE_CODE_INT + && value->type->code () != TYPE_CODE_PTR) error (_("Invalid type of operand to `!'.")); ax_simple (ax, aop_log_not); @@ -1181,7 +1187,7 @@ gen_logical_not (struct agent_expr *ax, struct axs_value *value, static void gen_complement (struct agent_expr *ax, struct axs_value *value) { - if (TYPE_CODE (value->type) != TYPE_CODE_INT) + if (value->type->code () != TYPE_CODE_INT) error (_("Invalid type of operand to `~'.")); ax_simple (ax, aop_bit_not); @@ -1194,7 +1200,7 @@ gen_complement (struct agent_expr *ax, struct axs_value *value) /* Dereference the value on the top of the stack. */ static void -gen_deref (struct agent_expr *ax, struct axs_value *value) +gen_deref (struct axs_value *value) { /* The caller should check the type, because several operators use this, and we don't know what error message to generate. */ @@ -1208,21 +1214,21 @@ gen_deref (struct agent_expr *ax, struct axs_value *value) T" to "T", and mark the value as an lvalue in memory. Leave it to the consumer to actually dereference it. */ value->type = check_typedef (TYPE_TARGET_TYPE (value->type)); - if (TYPE_CODE (value->type) == TYPE_CODE_VOID) + if (value->type->code () == TYPE_CODE_VOID) error (_("Attempt to dereference a generic pointer.")); - value->kind = ((TYPE_CODE (value->type) == TYPE_CODE_FUNC) + value->kind = ((value->type->code () == TYPE_CODE_FUNC) ? axs_rvalue : axs_lvalue_memory); } /* Produce the address of the lvalue on the top of the stack. */ static void -gen_address_of (struct agent_expr *ax, struct axs_value *value) +gen_address_of (struct axs_value *value) { /* Special case for taking the address of a function. The ANSI standard describes this as a special case, too, so this arrangement is not without motivation. */ - if (TYPE_CODE (value->type) == TYPE_CODE_FUNC) + if (value->type->code () == TYPE_CODE_FUNC) /* The value's already an rvalue on the stack, so we just need to change the type. */ value->type = lookup_pointer_type (value->type); @@ -1247,9 +1253,8 @@ gen_address_of (struct agent_expr *ax, struct axs_value *value) starting and one-past-ending *bit* numbers of the field within the structure. */ static void -gen_bitfield_ref (struct expression *exp, struct agent_expr *ax, - struct axs_value *value, struct type *type, - int start, int end) +gen_bitfield_ref (struct agent_expr *ax, struct axs_value *value, + struct type *type, int start, int end) { /* Note that ops[i] fetches 8 << i bits. */ static enum agent_op ops[] @@ -1374,7 +1379,7 @@ gen_bitfield_ref (struct expression *exp, struct agent_expr *ax, the sign/zero extension will wipe them out. - If we're in the interior of the word, then there is no garbage on either end, because the ref operators zero-extend. */ - if (gdbarch_byte_order (exp->gdbarch) == BFD_ENDIAN_BIG) + if (gdbarch_byte_order (ax->gdbarch) == BFD_ENDIAN_BIG) gen_left_shift (ax, end - (offset + op_size)); else gen_left_shift (ax, offset - start); @@ -1407,13 +1412,12 @@ gen_bitfield_ref (struct expression *exp, struct agent_expr *ax, generally follow value_primitive_field. */ static void -gen_primitive_field (struct expression *exp, - struct agent_expr *ax, struct axs_value *value, +gen_primitive_field (struct agent_expr *ax, struct axs_value *value, int offset, int fieldno, struct type *type) { /* Is this a bitfield? */ if (TYPE_FIELD_PACKED (type, fieldno)) - gen_bitfield_ref (exp, ax, value, TYPE_FIELD_TYPE (type, fieldno), + gen_bitfield_ref (ax, value, TYPE_FIELD_TYPE (type, fieldno), (offset * TARGET_CHAR_BIT + TYPE_FIELD_BITPOS (type, fieldno)), (offset * TARGET_CHAR_BIT @@ -1432,16 +1436,15 @@ gen_primitive_field (struct expression *exp, base classes. Return 1 if found, 0 if not. */ static int -gen_struct_ref_recursive (struct expression *exp, struct agent_expr *ax, - struct axs_value *value, - char *field, int offset, struct type *type) +gen_struct_ref_recursive (struct agent_expr *ax, struct axs_value *value, + const char *field, int offset, struct type *type) { int i, rslt; int nbases = TYPE_N_BASECLASSES (type); - CHECK_TYPEDEF (type); + type = check_typedef (type); - for (i = TYPE_NFIELDS (type) - 1; i >= nbases; i--) + for (i = type->num_fields () - 1; i >= nbases; i--) { const char *this_name = TYPE_FIELD_NAME (type, i); @@ -1453,9 +1456,9 @@ gen_struct_ref_recursive (struct expression *exp, struct agent_expr *ax, "this") will have been generated already, which will be unnecessary but not harmful if the static field is being handled as a global. */ - if (field_is_static (&TYPE_FIELD (type, i))) + if (field_is_static (&type->field (i))) { - gen_static_field (exp->gdbarch, ax, value, type, i); + gen_static_field (ax, value, type, i); if (value->optimized_out) error (_("static field `%s' has been " "optimized out, cannot use"), @@ -1463,7 +1466,7 @@ gen_struct_ref_recursive (struct expression *exp, struct agent_expr *ax, return 1; } - gen_primitive_field (exp, ax, value, offset, i, type); + gen_primitive_field (ax, value, offset, i, type); return 1; } #if 0 /* is this right? */ @@ -1479,7 +1482,7 @@ gen_struct_ref_recursive (struct expression *exp, struct agent_expr *ax, { struct type *basetype = check_typedef (TYPE_BASECLASS (type, i)); - rslt = gen_struct_ref_recursive (exp, ax, value, field, + rslt = gen_struct_ref_recursive (ax, value, field, offset + TYPE_BASECLASS_BITPOS (type, i) / TARGET_CHAR_BIT, basetype); @@ -1497,9 +1500,9 @@ gen_struct_ref_recursive (struct expression *exp, struct agent_expr *ax, the operator being compiled, and OPERAND_NAME is the kind of thing it operates on; we use them in error messages. */ static void -gen_struct_ref (struct expression *exp, struct agent_expr *ax, - struct axs_value *value, char *field, - char *operator_name, char *operand_name) +gen_struct_ref (struct agent_expr *ax, struct axs_value *value, + const char *field, const char *operator_name, + const char *operand_name) { struct type *type; int found; @@ -1510,13 +1513,13 @@ gen_struct_ref (struct expression *exp, struct agent_expr *ax, while (pointer_type (value->type)) { require_rvalue (ax, value); - gen_deref (ax, value); + gen_deref (value); } type = check_typedef (value->type); /* This must yield a structure or a union. */ - if (TYPE_CODE (type) != TYPE_CODE_STRUCT - && TYPE_CODE (type) != TYPE_CODE_UNION) + if (type->code () != TYPE_CODE_STRUCT + && type->code () != TYPE_CODE_UNION) error (_("The left operand of `%s' is not a %s."), operator_name, operand_name); @@ -1526,25 +1529,22 @@ gen_struct_ref (struct expression *exp, struct agent_expr *ax, error (_("Structure does not live in memory.")); /* Search through fields and base classes recursively. */ - found = gen_struct_ref_recursive (exp, ax, value, field, 0, type); + found = gen_struct_ref_recursive (ax, value, field, 0, type); if (!found) error (_("Couldn't find member named `%s' in struct/union/class `%s'"), - field, TYPE_TAG_NAME (type)); + field, type->name ()); } static int -gen_namespace_elt (struct expression *exp, - struct agent_expr *ax, struct axs_value *value, +gen_namespace_elt (struct agent_expr *ax, struct axs_value *value, const struct type *curtype, char *name); static int -gen_maybe_namespace_elt (struct expression *exp, - struct agent_expr *ax, struct axs_value *value, +gen_maybe_namespace_elt (struct agent_expr *ax, struct axs_value *value, const struct type *curtype, char *name); static void -gen_static_field (struct gdbarch *gdbarch, - struct agent_expr *ax, struct axs_value *value, +gen_static_field (struct agent_expr *ax, struct axs_value *value, struct type *type, int fieldno) { if (TYPE_FIELD_LOC_KIND (type, fieldno) == FIELD_LOC_KIND_PHYSADDR) @@ -1557,11 +1557,11 @@ gen_static_field (struct gdbarch *gdbarch, else { const char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (type, fieldno); - struct symbol *sym = lookup_symbol (phys_name, 0, VAR_DOMAIN, 0); + struct symbol *sym = lookup_symbol (phys_name, 0, VAR_DOMAIN, 0).symbol; if (sym) { - gen_var_ref (gdbarch, ax, value, sym); + gen_var_ref (ax, value, sym); /* Don't error if the value was optimized out, we may be scanning all static fields and just want to pass over this @@ -1577,27 +1577,26 @@ gen_static_field (struct gdbarch *gdbarch, } static int -gen_struct_elt_for_reference (struct expression *exp, - struct agent_expr *ax, struct axs_value *value, +gen_struct_elt_for_reference (struct agent_expr *ax, struct axs_value *value, struct type *type, char *fieldname) { struct type *t = type; int i; - if (TYPE_CODE (t) != TYPE_CODE_STRUCT - && TYPE_CODE (t) != TYPE_CODE_UNION) + if (t->code () != TYPE_CODE_STRUCT + && t->code () != TYPE_CODE_UNION) internal_error (__FILE__, __LINE__, _("non-aggregate type to gen_struct_elt_for_reference")); - for (i = TYPE_NFIELDS (t) - 1; i >= TYPE_N_BASECLASSES (t); i--) + for (i = t->num_fields () - 1; i >= TYPE_N_BASECLASSES (t); i--) { const char *t_field_name = TYPE_FIELD_NAME (t, i); if (t_field_name && strcmp (t_field_name, fieldname) == 0) { - if (field_is_static (&TYPE_FIELD (t, i))) + if (field_is_static (&t->field (i))) { - gen_static_field (exp->gdbarch, ax, value, t, i); + gen_static_field (ax, value, t, i); if (value->optimized_out) error (_("static field `%s' has been " "optimized out, cannot use"), @@ -1616,22 +1615,21 @@ gen_struct_elt_for_reference (struct expression *exp, /* FIXME add other scoped-reference cases here */ /* Do a last-ditch lookup. */ - return gen_maybe_namespace_elt (exp, ax, value, type, fieldname); + return gen_maybe_namespace_elt (ax, value, type, fieldname); } /* C++: Return the member NAME of the namespace given by the type CURTYPE. */ static int -gen_namespace_elt (struct expression *exp, - struct agent_expr *ax, struct axs_value *value, +gen_namespace_elt (struct agent_expr *ax, struct axs_value *value, const struct type *curtype, char *name) { - int found = gen_maybe_namespace_elt (exp, ax, value, curtype, name); + int found = gen_maybe_namespace_elt (ax, value, curtype, name); if (!found) error (_("No symbol \"%s\" in namespace \"%s\"."), - name, TYPE_TAG_NAME (curtype)); + name, curtype->name ()); return found; } @@ -1643,44 +1641,41 @@ gen_namespace_elt (struct expression *exp, to, say, some base class of CURTYPE). */ static int -gen_maybe_namespace_elt (struct expression *exp, - struct agent_expr *ax, struct axs_value *value, +gen_maybe_namespace_elt (struct agent_expr *ax, struct axs_value *value, const struct type *curtype, char *name) { - const char *namespace_name = TYPE_TAG_NAME (curtype); - struct symbol *sym; + const char *namespace_name = curtype->name (); + struct block_symbol sym; sym = cp_lookup_symbol_namespace (namespace_name, name, block_for_pc (ax->scope), VAR_DOMAIN); - if (sym == NULL) + if (sym.symbol == NULL) return 0; - gen_var_ref (exp->gdbarch, ax, value, sym); + gen_var_ref (ax, value, sym.symbol); if (value->optimized_out) error (_("`%s' has been optimized out, cannot use"), - SYMBOL_PRINT_NAME (sym)); + sym.symbol->print_name ()); return 1; } static int -gen_aggregate_elt_ref (struct expression *exp, - struct agent_expr *ax, struct axs_value *value, - struct type *type, char *field, - char *operator_name, char *operand_name) +gen_aggregate_elt_ref (struct agent_expr *ax, struct axs_value *value, + struct type *type, char *field) { - switch (TYPE_CODE (type)) + switch (type->code ()) { case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: - return gen_struct_elt_for_reference (exp, ax, value, type, field); + return gen_struct_elt_for_reference (ax, value, type, field); break; case TYPE_CODE_NAMESPACE: - return gen_namespace_elt (exp, ax, value, type, field); + return gen_namespace_elt (ax, value, type, field); break; default: internal_error (__FILE__, __LINE__, @@ -1721,7 +1716,7 @@ gen_repeat (struct expression *exp, union exp_element **pc, if (!v) error (_("Right operand of `@' must be a " "constant, in agent expressions.")); - if (TYPE_CODE (value_type (v)) != TYPE_CODE_INT) + if (value_type (v)->code () != TYPE_CODE_INT) error (_("Right operand of `@' must be an integer.")); length = value_as_long (v); if (length <= 0) @@ -1768,6 +1763,40 @@ gen_sizeof (struct expression *exp, union exp_element **pc, } +/* Generate bytecode for a cast to TO_TYPE. Advance *PC over the + subexpression. */ + +static void +gen_expr_for_cast (struct expression *exp, union exp_element **pc, + struct agent_expr *ax, struct axs_value *value, + struct type *to_type) +{ + enum exp_opcode op = (*pc)[0].opcode; + + /* Don't let symbols be handled with gen_expr because that throws an + "unknown type" error for no-debug data symbols. Instead, we want + the cast to reinterpret such symbols. */ + if (op == OP_VAR_MSYM_VALUE || op == OP_VAR_VALUE) + { + if (op == OP_VAR_VALUE) + { + gen_var_ref (ax, value, (*pc)[2].symbol); + + if (value->optimized_out) + error (_("`%s' has been optimized out, cannot use"), + (*pc)[2].symbol->print_name ()); + } + else + gen_msym_var_ref (ax, value, (*pc)[2].msymbol, (*pc)[1].objfile); + if (value->type->code () == TYPE_CODE_ERROR) + value->type = to_type; + (*pc) += 4; + } + else + gen_expr (exp, pc, ax, value); + gen_cast (ax, value, to_type); +} + /* Generating bytecode from GDB expressions: general recursive thingy */ /* XXX: i18n */ @@ -1781,7 +1810,7 @@ gen_expr (struct expression *exp, union exp_element **pc, struct axs_value value1, value2, value3; enum exp_opcode op = (*pc)[0].opcode, op2; int if1, go1, if2, go2, end; - struct type *int_type = builtin_type (exp->gdbarch)->builtin_int; + struct type *int_type = builtin_type (ax->gdbarch)->builtin_int; /* If we're looking at a constant expression, just push its value. */ { @@ -1819,7 +1848,7 @@ gen_expr (struct expression *exp, union exp_element **pc, case BINOP_GEQ: (*pc)++; gen_expr (exp, pc, ax, &value1); - gen_usual_unary (exp, ax, &value1); + gen_usual_unary (ax, &value1); gen_expr_binop_rest (exp, op, pc, ax, value, &value1, &value2); break; @@ -1827,12 +1856,12 @@ gen_expr (struct expression *exp, union exp_element **pc, (*pc)++; /* Generate the obvious sequence of tests and jumps. */ gen_expr (exp, pc, ax, &value1); - gen_usual_unary (exp, ax, &value1); + gen_usual_unary (ax, &value1); if1 = ax_goto (ax, aop_if_goto); go1 = ax_goto (ax, aop_goto); ax_label (ax, if1, ax->len); gen_expr (exp, pc, ax, &value2); - gen_usual_unary (exp, ax, &value2); + gen_usual_unary (ax, &value2); if2 = ax_goto (ax, aop_if_goto); go2 = ax_goto (ax, aop_goto); ax_label (ax, if2, ax->len); @@ -1850,10 +1879,10 @@ gen_expr (struct expression *exp, union exp_element **pc, (*pc)++; /* Generate the obvious sequence of tests and jumps. */ gen_expr (exp, pc, ax, &value1); - gen_usual_unary (exp, ax, &value1); + gen_usual_unary (ax, &value1); if1 = ax_goto (ax, aop_if_goto); gen_expr (exp, pc, ax, &value2); - gen_usual_unary (exp, ax, &value2); + gen_usual_unary (ax, &value2); if2 = ax_goto (ax, aop_if_goto); ax_const_l (ax, 0); end = ax_goto (ax, aop_goto); @@ -1868,7 +1897,7 @@ gen_expr (struct expression *exp, union exp_element **pc, case TERNOP_COND: (*pc)++; gen_expr (exp, pc, ax, &value1); - gen_usual_unary (exp, ax, &value1); + gen_usual_unary (ax, &value1); /* For (A ? B : C), it's easiest to generate subexpression bytecodes in order, but if_goto jumps on true, so we invert the sense of A. Then we can do B by dropping through, and @@ -1876,13 +1905,13 @@ gen_expr (struct expression *exp, union exp_element **pc, gen_logical_not (ax, &value1, int_type); if1 = ax_goto (ax, aop_if_goto); gen_expr (exp, pc, ax, &value2); - gen_usual_unary (exp, ax, &value2); + gen_usual_unary (ax, &value2); end = ax_goto (ax, aop_goto); ax_label (ax, if1, ax->len); gen_expr (exp, pc, ax, &value3); - gen_usual_unary (exp, ax, &value3); + gen_usual_unary (ax, &value3); ax_label (ax, end, ax->len); - /* This is arbitary - what if B and C are incompatible types? */ + /* This is arbitrary - what if B and C are incompatible types? */ value->type = value2.type; value->kind = value2.kind; break; @@ -1931,7 +1960,7 @@ gen_expr (struct expression *exp, union exp_element **pc, ax_tsv (ax, aop_tracev, tsv->number); /* Trace state variables are always 64-bit integers. */ value1.kind = axs_rvalue; - value1.type = builtin_type (exp->gdbarch)->builtin_long_long; + value1.type = builtin_type (ax->gdbarch)->builtin_long_long; /* Now do right half of expression. */ gen_expr_binop_rest (exp, op2, pc, ax, value, &value1, &value2); /* We have a result of the binary op, set the tsv. */ @@ -1959,7 +1988,7 @@ gen_expr (struct expression *exp, union exp_element **pc, /* Don't just dispose of the left operand. We might be tracing, in which case we want to emit code to trace it if it's an lvalue. */ - gen_traced_pop (exp->gdbarch, ax, &value1); + gen_traced_pop (ax, &value1); gen_expr (exp, pc, ax, value); /* It's the consumer's responsibility to trace the right operand. */ break; @@ -1975,11 +2004,23 @@ gen_expr (struct expression *exp, union exp_element **pc, break; case OP_VAR_VALUE: - gen_var_ref (exp->gdbarch, ax, value, (*pc)[2].symbol); + gen_var_ref (ax, value, (*pc)[2].symbol); if (value->optimized_out) error (_("`%s' has been optimized out, cannot use"), - SYMBOL_PRINT_NAME ((*pc)[2].symbol)); + (*pc)[2].symbol->print_name ()); + + if (value->type->code () == TYPE_CODE_ERROR) + error_unknown_type ((*pc)[2].symbol->print_name ()); + + (*pc) += 4; + break; + + case OP_VAR_MSYM_VALUE: + gen_msym_var_ref (ax, value, (*pc)[2].msymbol, (*pc)[1].objfile); + + if (value->type->code () == TYPE_CODE_ERROR) + error_unknown_type ((*pc)[2].msymbol->linkage_name ()); (*pc) += 4; break; @@ -1990,19 +2031,18 @@ gen_expr (struct expression *exp, union exp_element **pc, int reg; (*pc) += 4 + BYTES_TO_EXP_ELEM ((*pc)[1].longconst + 1); - reg = user_reg_map_name_to_regnum (exp->gdbarch, name, strlen (name)); + reg = user_reg_map_name_to_regnum (ax->gdbarch, name, strlen (name)); if (reg == -1) internal_error (__FILE__, __LINE__, _("Register $%s not available"), name); /* No support for tracing user registers yet. */ - if (reg >= gdbarch_num_regs (exp->gdbarch) - + gdbarch_num_pseudo_regs (exp->gdbarch)) + if (reg >= gdbarch_num_cooked_regs (ax->gdbarch)) error (_("'%s' is a user-register; " "GDB cannot yet trace user-register contents."), name); value->kind = axs_lvalue_register; value->u.reg = reg; - value->type = register_type (exp->gdbarch, reg); + value->type = register_type (ax->gdbarch, reg); } break; @@ -2021,7 +2061,7 @@ gen_expr (struct expression *exp, union exp_element **pc, ax_tsv (ax, aop_tracev, tsv->number); /* Trace state variables are always 64-bit integers. */ value->kind = axs_rvalue; - value->type = builtin_type (exp->gdbarch)->builtin_long_long; + value->type = builtin_type (ax->gdbarch)->builtin_long_long; } else if (! compile_internalvar_to_ax (var, ax, value)) error (_("$%s is not a trace state variable; GDB agent " @@ -2041,8 +2081,7 @@ gen_expr (struct expression *exp, union exp_element **pc, struct type *type = (*pc)[1].type; (*pc) += 3; - gen_expr (exp, pc, ax, value); - gen_cast (ax, value, type); + gen_expr_for_cast (exp, pc, ax, value, type); } break; @@ -2057,9 +2096,7 @@ gen_expr (struct expression *exp, union exp_element **pc, val = evaluate_subexp (NULL, exp, &offset, EVAL_AVOID_SIDE_EFFECTS); type = value_type (val); *pc = &exp->elts[offset]; - - gen_expr (exp, pc, ax, value); - gen_cast (ax, value, type); + gen_expr_for_cast (exp, pc, ax, value, type); } break; @@ -2110,49 +2147,49 @@ gen_expr (struct expression *exp, union exp_element **pc, (*pc)++; /* + FOO is equivalent to 0 + FOO, which can be optimized. */ gen_expr (exp, pc, ax, value); - gen_usual_unary (exp, ax, value); + gen_usual_unary (ax, value); break; case UNOP_NEG: (*pc)++; /* -FOO is equivalent to 0 - FOO. */ gen_int_literal (ax, &value1, 0, - builtin_type (exp->gdbarch)->builtin_int); - gen_usual_unary (exp, ax, &value1); /* shouldn't do much */ + builtin_type (ax->gdbarch)->builtin_int); + gen_usual_unary (ax, &value1); /* shouldn't do much */ gen_expr (exp, pc, ax, &value2); - gen_usual_unary (exp, ax, &value2); - gen_usual_arithmetic (exp, ax, &value1, &value2); + gen_usual_unary (ax, &value2); + gen_usual_arithmetic (ax, &value1, &value2); gen_binop (ax, value, &value1, &value2, aop_sub, aop_sub, 1, "negation"); break; case UNOP_LOGICAL_NOT: (*pc)++; gen_expr (exp, pc, ax, value); - gen_usual_unary (exp, ax, value); + gen_usual_unary (ax, value); gen_logical_not (ax, value, int_type); break; case UNOP_COMPLEMENT: (*pc)++; gen_expr (exp, pc, ax, value); - gen_usual_unary (exp, ax, value); - gen_integral_promotions (exp, ax, value); + gen_usual_unary (ax, value); + gen_integral_promotions (ax, value); gen_complement (ax, value); break; case UNOP_IND: (*pc)++; gen_expr (exp, pc, ax, value); - gen_usual_unary (exp, ax, value); + gen_usual_unary (ax, value); if (!pointer_type (value->type)) error (_("Argument of unary `*' is not a pointer.")); - gen_deref (ax, value); + gen_deref (value); break; case UNOP_ADDR: (*pc)++; gen_expr (exp, pc, ax, value); - gen_address_of (ax, value); + gen_address_of (value); break; case UNOP_SIZEOF: @@ -2161,7 +2198,7 @@ gen_expr (struct expression *exp, union exp_element **pc, of the other unary operator functions. This is because we have to throw away the code we generate. */ gen_sizeof (exp, pc, ax, value, - builtin_type (exp->gdbarch)->builtin_int); + builtin_type (ax->gdbarch)->builtin_int); break; case STRUCTOP_STRUCT: @@ -2173,9 +2210,9 @@ gen_expr (struct expression *exp, union exp_element **pc, (*pc) += 4 + BYTES_TO_EXP_ELEM (length + 1); gen_expr (exp, pc, ax, value); if (op == STRUCTOP_STRUCT) - gen_struct_ref (exp, ax, value, name, ".", "structure or union"); + gen_struct_ref (ax, value, name, ".", "structure or union"); else if (op == STRUCTOP_PTR) - gen_struct_ref (exp, ax, value, name, "->", + gen_struct_ref (ax, value, name, "->", "pointer to a structure or union"); else /* If this `if' chain doesn't handle it, then the case list @@ -2188,22 +2225,22 @@ gen_expr (struct expression *exp, union exp_element **pc, case OP_THIS: { struct symbol *sym, *func; - struct block *b; + const struct block *b; const struct language_defn *lang; b = block_for_pc (ax->scope); func = block_linkage_function (b); - lang = language_def (SYMBOL_LANGUAGE (func)); + lang = language_def (func->language ()); - sym = lookup_language_this (lang, b); + sym = lookup_language_this (lang, b).symbol; if (!sym) error (_("no `%s' found"), lang->la_name_of_this); - gen_var_ref (exp->gdbarch, ax, value, sym); + gen_var_ref (ax, value, sym); if (value->optimized_out) error (_("`%s' has been optimized out, cannot use"), - SYMBOL_PRINT_NAME (sym)); + sym->print_name ()); (*pc) += 2; } @@ -2216,8 +2253,7 @@ gen_expr (struct expression *exp, union exp_element **pc, char *name = &(*pc)[3].string; int found; - found = gen_aggregate_elt_ref (exp, ax, value, type, name, - "?", "??"); + found = gen_aggregate_elt_ref (ax, value, type, name); if (!found) error (_("There is no field named %s"), name); (*pc) += 5 + BYTES_TO_EXP_ELEM (length + 1); @@ -2245,15 +2281,15 @@ gen_expr_binop_rest (struct expression *exp, struct agent_expr *ax, struct axs_value *value, struct axs_value *value1, struct axs_value *value2) { - struct type *int_type = builtin_type (exp->gdbarch)->builtin_int; + struct type *int_type = builtin_type (ax->gdbarch)->builtin_int; gen_expr (exp, pc, ax, value2); - gen_usual_unary (exp, ax, value2); - gen_usual_arithmetic (exp, ax, value1, value2); + gen_usual_unary (ax, value2); + gen_usual_arithmetic (ax, value1, value2); switch (op) { case BINOP_ADD: - if (TYPE_CODE (value1->type) == TYPE_CODE_INT + if (value1->type->code () == TYPE_CODE_INT && pointer_type (value2->type)) { /* Swap the values and proceed normally. */ @@ -2261,7 +2297,7 @@ gen_expr_binop_rest (struct expression *exp, gen_ptradd (ax, value, value2, value1); } else if (pointer_type (value1->type) - && TYPE_CODE (value2->type) == TYPE_CODE_INT) + && value2->type->code () == TYPE_CODE_INT) gen_ptradd (ax, value, value1, value2); else gen_binop (ax, value, value1, value2, @@ -2269,13 +2305,13 @@ gen_expr_binop_rest (struct expression *exp, break; case BINOP_SUB: if (pointer_type (value1->type) - && TYPE_CODE (value2->type) == TYPE_CODE_INT) + && value2->type->code () == TYPE_CODE_INT) gen_ptrsub (ax,value, value1, value2); else if (pointer_type (value1->type) && pointer_type (value2->type)) /* FIXME --- result type should be ptrdiff_t */ gen_ptrdiff (ax, value, value1, value2, - builtin_type (exp->gdbarch)->builtin_long); + builtin_type (ax->gdbarch)->builtin_long); else gen_binop (ax, value, value1, value2, aop_sub, aop_sub, 1, "subtraction"); @@ -2315,12 +2351,12 @@ gen_expr_binop_rest (struct expression *exp, an array or pointer type (like a plain int variable for example), then report this as an error. */ type = check_typedef (value1->type); - if (TYPE_CODE (type) != TYPE_CODE_ARRAY - && TYPE_CODE (type) != TYPE_CODE_PTR) + if (type->code () != TYPE_CODE_ARRAY + && type->code () != TYPE_CODE_PTR) { - if (TYPE_NAME (type)) + if (type->name ()) error (_("cannot subscript something of type `%s'"), - TYPE_NAME (type)); + type->name ()); else error (_("cannot subscript requested type")); } @@ -2331,7 +2367,7 @@ gen_expr_binop_rest (struct expression *exp, "not a number or boolean.")); gen_ptradd (ax, value, value1, value2); - gen_deref (ax, value); + gen_deref (value); break; } case BINOP_BITWISE_AND: @@ -2392,38 +2428,28 @@ gen_expr_binop_rest (struct expression *exp, variable's name, and no parsed expression; for instance, when the name comes from a list of local variables of a function. */ -struct agent_expr * +agent_expr_up gen_trace_for_var (CORE_ADDR scope, struct gdbarch *gdbarch, struct symbol *var, int trace_string) { - struct cleanup *old_chain = 0; - struct agent_expr *ax = new_agent_expr (gdbarch, scope); + agent_expr_up ax (new agent_expr (gdbarch, scope)); struct axs_value value; - old_chain = make_cleanup_free_agent_expr (ax); - ax->tracing = 1; ax->trace_string = trace_string; - gen_var_ref (gdbarch, ax, &value, var); + gen_var_ref (ax.get (), &value, var); /* If there is no actual variable to trace, flag it by returning an empty agent expression. */ if (value.optimized_out) - { - do_cleanups (old_chain); - return NULL; - } + return agent_expr_up (); /* Make sure we record the final object, and get rid of it. */ - gen_traced_pop (gdbarch, ax, &value); + gen_traced_pop (ax.get (), &value); /* Oh, and terminate. */ - ax_simple (ax, aop_end); + ax_simple (ax.get (), aop_end); - /* We have successfully built the agent expr, so cancel the cleanup - request. If we add more cleanups that we always want done, this - will have to get more complicated. */ - discard_cleanups (old_chain); return ax; } @@ -2434,33 +2460,27 @@ gen_trace_for_var (CORE_ADDR scope, struct gdbarch *gdbarch, record the value of all memory touched by the expression. The caller can then use the ax_reqs function to discover which registers it relies upon. */ -struct agent_expr * + +agent_expr_up gen_trace_for_expr (CORE_ADDR scope, struct expression *expr, int trace_string) { - struct cleanup *old_chain = 0; - struct agent_expr *ax = new_agent_expr (expr->gdbarch, scope); + agent_expr_up ax (new agent_expr (expr->gdbarch, scope)); union exp_element *pc; struct axs_value value; - old_chain = make_cleanup_free_agent_expr (ax); - pc = expr->elts; ax->tracing = 1; ax->trace_string = trace_string; value.optimized_out = 0; - gen_expr (expr, &pc, ax, &value); + gen_expr (expr, &pc, ax.get (), &value); /* Make sure we record the final object, and get rid of it. */ - gen_traced_pop (expr->gdbarch, ax, &value); + gen_traced_pop (ax.get (), &value); /* Oh, and terminate. */ - ax_simple (ax, aop_end); + ax_simple (ax.get (), aop_end); - /* We have successfully built the agent expr, so cancel the cleanup - request. If we add more cleanups that we always want done, this - will have to get more complicated. */ - discard_cleanups (old_chain); return ax; } @@ -2471,58 +2491,44 @@ gen_trace_for_expr (CORE_ADDR scope, struct expression *expr, gen_trace_for_expr does. The generated bytecode sequence leaves the result of expression evaluation on the top of the stack. */ -struct agent_expr * +agent_expr_up gen_eval_for_expr (CORE_ADDR scope, struct expression *expr) { - struct cleanup *old_chain = 0; - struct agent_expr *ax = new_agent_expr (expr->gdbarch, scope); + agent_expr_up ax (new agent_expr (expr->gdbarch, scope)); union exp_element *pc; struct axs_value value; - old_chain = make_cleanup_free_agent_expr (ax); - pc = expr->elts; ax->tracing = 0; value.optimized_out = 0; - gen_expr (expr, &pc, ax, &value); + gen_expr (expr, &pc, ax.get (), &value); - require_rvalue (ax, &value); + require_rvalue (ax.get (), &value); /* Oh, and terminate. */ - ax_simple (ax, aop_end); + ax_simple (ax.get (), aop_end); - /* We have successfully built the agent expr, so cancel the cleanup - request. If we add more cleanups that we always want done, this - will have to get more complicated. */ - discard_cleanups (old_chain); return ax; } -struct agent_expr * +agent_expr_up gen_trace_for_return_address (CORE_ADDR scope, struct gdbarch *gdbarch, int trace_string) { - struct cleanup *old_chain = 0; - struct agent_expr *ax = new_agent_expr (gdbarch, scope); + agent_expr_up ax (new agent_expr (gdbarch, scope)); struct axs_value value; - old_chain = make_cleanup_free_agent_expr (ax); - ax->tracing = 1; ax->trace_string = trace_string; - gdbarch_gen_return_address (gdbarch, ax, &value, scope); + gdbarch_gen_return_address (gdbarch, ax.get (), &value, scope); /* Make sure we record the final object, and get rid of it. */ - gen_traced_pop (gdbarch, ax, &value); + gen_traced_pop (ax.get (), &value); /* Oh, and terminate. */ - ax_simple (ax, aop_end); + ax_simple (ax.get (), aop_end); - /* We have successfully built the agent expr, so cancel the cleanup - request. If we add more cleanups that we always want done, this - will have to get more complicated. */ - discard_cleanups (old_chain); return ax; } @@ -2530,21 +2536,17 @@ gen_trace_for_return_address (CORE_ADDR scope, struct gdbarch *gdbarch, evaluate the arguments and pass everything to a special bytecode. */ -struct agent_expr * +agent_expr_up gen_printf (CORE_ADDR scope, struct gdbarch *gdbarch, CORE_ADDR function, LONGEST channel, const char *format, int fmtlen, - struct format_piece *frags, int nargs, struct expression **exprs) { - struct cleanup *old_chain = 0; - struct agent_expr *ax = new_agent_expr (gdbarch, scope); + agent_expr_up ax (new agent_expr (gdbarch, scope)); union exp_element *pc; struct axs_value value; int tem; - old_chain = make_cleanup_free_agent_expr (ax); - /* We're computing values, not doing side effects. */ ax->tracing = 0; @@ -2554,26 +2556,21 @@ gen_printf (CORE_ADDR scope, struct gdbarch *gdbarch, { pc = exprs[tem]->elts; value.optimized_out = 0; - gen_expr (exprs[tem], &pc, ax, &value); - require_rvalue (ax, &value); + gen_expr (exprs[tem], &pc, ax.get (), &value); + require_rvalue (ax.get (), &value); } /* Push function and channel. */ - ax_const_l (ax, channel); - ax_const_l (ax, function); + ax_const_l (ax.get (), channel); + ax_const_l (ax.get (), function); /* Issue the printf bytecode proper. */ - ax_simple (ax, aop_printf); - ax_simple (ax, nargs); - ax_string (ax, format, fmtlen); + ax_simple (ax.get (), aop_printf); + ax_raw_byte (ax.get (), nargs); + ax_string (ax.get (), format, fmtlen); /* And terminate. */ - ax_simple (ax, aop_end); - - /* We have successfully built the agent expr, so cancel the cleanup - request. If we add more cleanups that we always want done, this - will have to get more complicated. */ - discard_cleanups (old_chain); + ax_simple (ax.get (), aop_end); return ax; } @@ -2581,9 +2578,6 @@ gen_printf (CORE_ADDR scope, struct gdbarch *gdbarch, static void agent_eval_command_one (const char *exp, int eval, CORE_ADDR pc) { - struct cleanup *old_chain = 0; - struct expression *expr; - struct agent_expr *agent; const char *arg; int trace_string = 0; @@ -2593,39 +2587,38 @@ agent_eval_command_one (const char *exp, int eval, CORE_ADDR pc) exp = decode_agent_options (exp, &trace_string); } + agent_expr_up agent; + arg = exp; if (!eval && strcmp (arg, "$_ret") == 0) { agent = gen_trace_for_return_address (pc, get_current_arch (), trace_string); - old_chain = make_cleanup_free_agent_expr (agent); } else { - expr = parse_exp_1 (&arg, pc, block_for_pc (pc), 0); - old_chain = make_cleanup (free_current_contents, &expr); + expression_up expr = parse_exp_1 (&arg, pc, block_for_pc (pc), 0); + if (eval) { gdb_assert (trace_string == 0); - agent = gen_eval_for_expr (pc, expr); + agent = gen_eval_for_expr (pc, expr.get ()); } else - agent = gen_trace_for_expr (pc, expr, trace_string); - make_cleanup_free_agent_expr (agent); + agent = gen_trace_for_expr (pc, expr.get (), trace_string); } - ax_reqs (agent); - ax_print (gdb_stdout, agent); + ax_reqs (agent.get ()); + ax_print (gdb_stdout, agent.get ()); /* It would be nice to call ax_reqs here to gather some general info about the expression, and then print out the result. */ - do_cleanups (old_chain); dont_repeat (); } static void -agent_command_1 (char *exp, int eval) +agent_command_1 (const char *exp, int eval) { /* We don't deal with overlay debugging at the moment. We need to think more carefully about this. If you copy this code into @@ -2640,30 +2633,21 @@ agent_command_1 (char *exp, int eval) if (check_for_argument (&exp, "-at", sizeof ("-at") - 1)) { struct linespec_result canonical; - int ix; - struct linespec_sals *iter; - struct cleanup *old_chain; - exp = skip_spaces (exp); - init_linespec_result (&canonical); - decode_line_full (&exp, DECODE_LINE_FUNFIRSTLINE, - (struct symtab *) NULL, 0, &canonical, + event_location_up location + = new_linespec_location (&exp, symbol_name_match_type::WILD); + decode_line_full (location.get (), DECODE_LINE_FUNFIRSTLINE, NULL, + NULL, 0, &canonical, NULL, NULL); - old_chain = make_cleanup_destroy_linespec_result (&canonical); exp = skip_spaces (exp); if (exp[0] == ',') { exp++; exp = skip_spaces (exp); } - for (ix = 0; VEC_iterate (linespec_sals, canonical.sals, ix, iter); ++ix) - { - int i; - - for (i = 0; i < iter->sals.nelts; i++) - agent_eval_command_one (exp, eval, iter->sals.sals[i].pc); - } - do_cleanups (old_chain); + for (const auto &lsal : canonical.lsals) + for (const auto &sal : lsal.sals) + agent_eval_command_one (exp, eval, sal.pc); } else agent_eval_command_one (exp, eval, get_frame_pc (get_current_frame ())); @@ -2672,7 +2656,7 @@ agent_command_1 (char *exp, int eval) } static void -agent_command (char *exp, int from_tty) +agent_command (const char *exp, int from_tty) { agent_command_1 (exp, 0); } @@ -2682,7 +2666,7 @@ agent_command (char *exp, int from_tty) expression. */ static void -agent_eval_command (char *exp, int from_tty) +agent_eval_command (const char *exp, int from_tty) { agent_command_1 (exp, 1); } @@ -2691,17 +2675,10 @@ agent_eval_command (char *exp, int from_tty) that does a printf, and display the resulting expression. */ static void -maint_agent_printf_command (char *exp, int from_tty) +maint_agent_printf_command (const char *cmdrest, int from_tty) { - struct cleanup *old_chain = 0; - struct expression *expr; - struct expression *argvec[100]; - struct agent_expr *agent; struct frame_info *fi = get_current_frame (); /* need current scope */ - const char *cmdrest; const char *format_start, *format_end; - struct format_piece *fpieces; - int nargs; /* We don't deal with overlay debugging at the moment. We need to think more carefully about this. If you copy this code into @@ -2710,45 +2687,40 @@ maint_agent_printf_command (char *exp, int from_tty) if (overlay_debugging) error (_("GDB can't do agent expression translation with overlays.")); - if (exp == 0) + if (cmdrest == 0) error_no_arg (_("expression to translate")); - cmdrest = exp; - - cmdrest = skip_spaces_const (cmdrest); + cmdrest = skip_spaces (cmdrest); if (*cmdrest++ != '"') error (_("Must start with a format string.")); format_start = cmdrest; - fpieces = parse_format_string (&cmdrest); - - old_chain = make_cleanup (free_format_pieces_cleanup, &fpieces); + format_pieces fpieces (&cmdrest); format_end = cmdrest; if (*cmdrest++ != '"') error (_("Bad format string, non-terminated '\"'.")); - cmdrest = skip_spaces_const (cmdrest); + cmdrest = skip_spaces (cmdrest); if (*cmdrest != ',' && *cmdrest != 0) error (_("Invalid argument syntax")); if (*cmdrest == ',') cmdrest++; - cmdrest = skip_spaces_const (cmdrest); + cmdrest = skip_spaces (cmdrest); - nargs = 0; + std::vector argvec; while (*cmdrest != '\0') { const char *cmd1; cmd1 = cmdrest; - expr = parse_exp_1 (&cmd1, 0, (struct block *) 0, 1); - argvec[nargs] = expr; - ++nargs; + expression_up expr = parse_exp_1 (&cmd1, 0, (struct block *) 0, 1); + argvec.push_back (expr.release ()); cmdrest = cmd1; if (*cmdrest == ',') ++cmdrest; @@ -2756,31 +2728,29 @@ maint_agent_printf_command (char *exp, int from_tty) } - agent = gen_printf (get_frame_pc (fi), get_current_arch (), 0, 0, - format_start, format_end - format_start, - fpieces, nargs, argvec); - make_cleanup_free_agent_expr (agent); - ax_reqs (agent); - ax_print (gdb_stdout, agent); + agent_expr_up agent = gen_printf (get_frame_pc (fi), get_current_arch (), + 0, 0, + format_start, format_end - format_start, + argvec.size (), argvec.data ()); + ax_reqs (agent.get ()); + ax_print (gdb_stdout, agent.get ()); /* It would be nice to call ax_reqs here to gather some general info about the expression, and then print out the result. */ - do_cleanups (old_chain); dont_repeat (); } - /* Initialization code. */ -void _initialize_ax_gdb (void); +void _initialize_ax_gdb (); void -_initialize_ax_gdb (void) +_initialize_ax_gdb () { add_cmd ("agent", class_maintenance, agent_command, _("\ Translate an expression into remote agent bytecode for tracing.\n\ -Usage: maint agent [-at location,] EXPRESSION\n\ +Usage: maint agent [-at LOCATION,] EXPRESSION\n\ If -at is given, generate remote agent bytecode for this location.\n\ If not, generate remote agent bytecode for current frame pc address."), &maintenancelist); @@ -2788,7 +2758,7 @@ If not, generate remote agent bytecode for current frame pc address."), add_cmd ("agent-eval", class_maintenance, agent_eval_command, _("\ Translate an expression into remote agent bytecode for evaluation.\n\ -Usage: maint agent-eval [-at location,] EXPRESSION\n\ +Usage: maint agent-eval [-at LOCATION,] EXPRESSION\n\ If -at is given, generate remote agent bytecode for this location.\n\ If not, generate remote agent bytecode for current frame pc address."), &maintenancelist);