Use an accessor function for general_symbol_info::language
[deliverable/binutils-gdb.git] / gdb / ax-gdb.c
index e79fe3895fc8a1777e2f54d1a43f47ba5b356c00..d25413ea1f2f15ac1d05353865a9425e4c088b7b 100644 (file)
@@ -1,7 +1,6 @@
 /* GDB-specific functions for operating on agent expressions.
 
-   Copyright (C) 1998, 1999, 2000, 2001, 2003, 2007, 2008, 2009, 2010
-   Free Software Foundation, Inc.
+   Copyright (C) 1998-2019 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #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"
 #include "cp-support.h"
+#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 "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,
@@ -59,7 +66,7 @@
 \f
 
 
-/* Prototypes for local functions. */
+/* Prototypes for local functions.  */
 
 /* There's a standard order to the arguments of these functions:
    union exp_element ** --- pointer into expression
@@ -70,7 +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 *);
@@ -78,33 +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 require_rvalue (struct agent_expr *ax, struct axs_value *value);
-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);
@@ -122,46 +124,40 @@ 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);
 static void gen_sizeof (struct expression *exp, union exp_element **pc,
                        struct agent_expr *ax, struct axs_value *value,
                        struct type *size_type);
-static void gen_expr (struct expression *exp, union exp_element **pc,
-                     struct agent_expr *ax, struct axs_value *value);
 static void gen_expr_binop_rest (struct expression *exp,
                                 enum exp_opcode op, union exp_element **pc,
                                 struct agent_expr *ax,
                                 struct axs_value *value,
                                 struct axs_value *value1,
                                 struct axs_value *value2);
-
-static void agent_command (char *exp, int from_tty);
 \f
 
 /* Detecting constant expressions.  */
@@ -219,6 +215,7 @@ const_expr (union exp_element **pc)
       {
        struct type *type = (*pc)[1].type;
        LONGEST k = (*pc)[2].longconst;
+
        (*pc) += 4;
        return value_from_longest (type, k);
       }
@@ -226,6 +223,7 @@ const_expr (union exp_element **pc)
     case OP_VAR_VALUE:
       {
        struct value *v = const_var_ref ((*pc)[2].symbol);
+
        (*pc) += 4;
        return v;
       }
@@ -306,67 +304,40 @@ maybe_const_expr (union exp_element **pc)
    sizes), and this is simpler.)  */
 \f
 
-/* Generating bytecode from GDB expressions: the `trace' kludge  */
-
-/* The compiler in this file is a general-purpose mechanism for
-   translating GDB expressions into bytecode.  One ought to be able to
-   find a million and one uses for it.
-
-   However, at the moment it is HOPELESSLY BRAIN-DAMAGED for the sake
-   of expediency.  Let he who is without sin cast the first stone.
-
-   For the data tracing facility, we need to insert `trace' bytecodes
-   before each data fetch; this records all the memory that the
-   expression touches in the course of evaluation, so that memory will
-   be available when the user later tries to evaluate the expression
-   in GDB.
-
-   This should be done (I think) in a post-processing pass, that walks
-   an arbitrary agent expression and inserts `trace' operations at the
-   appropriate points.  But it's much faster to just hack them
-   directly into the code.  And since we're in a crunch, that's what
-   I've done.
-
-   Setting the flag trace_kludge to non-zero enables the code that
-   emits the trace bytecodes at the appropriate points.  */
-static int trace_kludge;
-
 /* Scan for all static fields in the given class, including any base
    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--)
     {
       if (field_is_static (&TYPE_FIELD (type, i)))
        {
-         gen_static_field (gdbarch, ax, &value, type, i);
+         gen_static_field (ax, &value, type, i);
          if (value.optimized_out)
            continue;
          switch (value.kind)
            {
            case axs_lvalue_memory:
              {
-               int length = TYPE_LENGTH (check_typedef (value.type));
-
-               ax_const_l (ax, length);
+               /* Initialize the TYPE_LENGTH if it is a typedef.  */
+               check_typedef (value.type);
+               ax_const_l (ax, TYPE_LENGTH (value.type));
                ax_simple (ax, aop_trace);
              }
              break;
 
            case axs_lvalue_register:
-             /* We need to mention the register somewhere in the bytecode,
-                so ax_reqs will pick it up and add it to the mask of
-                registers used.  */
-             ax_reg (ax, value.u.reg);
+             /* We don't actually need the register's value to be pushed,
+                just note that we need it to be collected.  */
+             ax_reg_mask (ax, value.u.reg);
 
            default:
              break;
@@ -379,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);
     }
 }
 
@@ -387,38 +358,69 @@ 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)
 {
-  if (trace_kludge)
+  int string_trace = 0;
+  if (ax->trace_string
+      && TYPE_CODE (value->type) == TYPE_CODE_PTR
+      && c_textual_element_type (check_typedef (TYPE_TARGET_TYPE (value->type)),
+                                's'))
+    string_trace = 1;
+
+  if (ax->tracing)
     switch (value->kind)
       {
       case axs_rvalue:
-       /* We don't trace rvalues, just the lvalues necessary to
-          produce them.  So just dispose of this value.  */
-       ax_simple (ax, aop_pop);
+       if (string_trace)
+         {
+           ax_const_l (ax, ax->trace_string);
+           ax_simple (ax, aop_tracenz);
+         }
+       else
+         /* We don't trace rvalues, just the lvalues necessary to
+            produce them.  So just dispose of this value.  */
+         ax_simple (ax, aop_pop);
        break;
 
       case axs_lvalue_memory:
        {
-         int length = TYPE_LENGTH (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, length);
-         ax_simple (ax, aop_trace);
+         /* Initialize the TYPE_LENGTH if it is a typedef.  */
+         check_typedef (value->type);
+
+         if (string_trace)
+           {
+             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;
 
       case axs_lvalue_register:
-       /* We need to mention the register somewhere in the bytecode,
-          so ax_reqs will pick it up and add it to the mask of
-          registers used.  */
-       ax_reg (ax, value->u.reg);
-       ax_simple (ax, aop_pop);
+       /* We don't actually need the register's value to be on the
+          stack, and the target will get heartburn if the register is
+          larger than will fit in a stack, so just mark it for
+          collection and be done with it.  */
+       ax_reg_mask (ax, value->u.reg);
+       
+       /* But if the register points to a string, assume the value
+          will fit on the stack and push it anyway.  */
+       if (string_trace)
+         {
+           ax_reg (ax, value->u.reg);
+           ax_const_l (ax, ax->trace_string);
+           ax_simple (ax, aop_tracenz);
+         }
        break;
       }
   else
@@ -426,10 +428,10 @@ gen_traced_pop (struct gdbarch *gdbarch,
     ax_simple (ax, aop_pop);
 
   /* To trace C++ classes with static fields stored elsewhere.  */
-  if (trace_kludge
+  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);
+    gen_trace_static_fields (ax, value->type);
 }
 \f
 
@@ -454,6 +456,7 @@ static void
 gen_extend (struct agent_expr *ax, struct type *type)
 {
   int bits = TYPE_LENGTH (type) * TARGET_CHAR_BIT;
+
   /* I just had to.  */
   ((TYPE_UNSIGNED (type) ? ax_zero_ext : ax_ext) (ax, bits));
 }
@@ -465,16 +468,20 @@ gen_extend (struct agent_expr *ax, struct type *type)
 static void
 gen_fetch (struct agent_expr *ax, struct type *type)
 {
-  if (trace_kludge)
+  if (ax->tracing)
     {
       /* Record the area of memory we're about to fetch.  */
       ax_trace_quick (ax, TYPE_LENGTH (type));
     }
 
+  if (TYPE_CODE (type) == TYPE_CODE_RANGE)
+    type = TYPE_TARGET_TYPE (type);
+
   switch (TYPE_CODE (type))
     {
     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:
@@ -509,12 +516,11 @@ gen_fetch (struct agent_expr *ax, struct type *type)
       break;
 
     default:
-      /* Either our caller shouldn't have asked us to dereference that
-         pointer (other code's fault), or we're not implementing
-         something we should be (this code's fault).  In any case,
-         it's a bug the user shouldn't see.  */
-      internal_error (__FILE__, __LINE__,
-                     _("gen_fetch: bad type code"));
+      /* Our caller requested us to dereference a pointer from an unsupported
+        type.  Error out and give callers a chance to handle the failure
+        gracefully.  */
+      error (_("gen_fetch: Unsupported type code `%s'."),
+            TYPE_NAME (type));
     }
 }
 
@@ -544,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);
@@ -559,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);
@@ -609,13 +615,18 @@ 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. */
+  /* Dereference any typedefs.  */
   value->type = check_typedef (SYMBOL_TYPE (var));
   value->optimized_out = 0;
 
+  if (SYMBOL_COMPUTED_OPS (var) != NULL)
+    {
+      SYMBOL_COMPUTED_OPS (var)->tracepoint_var_ref (var, ax, value);
+      return;
+    }
+
   /* I'm imitating the code in read_var_value.  */
   switch (SYMBOL_CLASS (var))
     {
@@ -631,7 +642,8 @@ gen_var_ref (struct gdbarch *gdbarch, struct agent_expr *ax,
 
     case LOC_CONST_BYTES:
       internal_error (__FILE__, __LINE__,
-                     _("gen_var_ref: LOC_CONST_BYTES symbols are not supported"));
+                     _("gen_var_ref: LOC_CONST_BYTES "
+                       "symbols are not supported"));
 
       /* Variable at a fixed location in memory.  Easy.  */
     case LOC_STATIC:
@@ -641,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;
 
@@ -676,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
@@ -684,31 +697,27 @@ 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);
-       if (!msym)
-         error (_("Couldn't resolve symbol `%s'."), SYMBOL_PRINT_NAME (var));
+       struct bound_minimal_symbol msym
+         = lookup_minimal_symbol (var->linkage_name (), NULL, NULL);
+
+       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;
 
     case LOC_COMPUTED:
-      /* FIXME: cagney/2004-01-26: It should be possible to
-        unconditionally call the SYMBOL_COMPUTED_OPS method when available.
-        Unfortunately DWARF 2 stores the frame-base (instead of the
-        function) location in a function's symbol.  Oops!  For the
-        moment enable this when/where applicable.  */
-      SYMBOL_COMPUTED_OPS (var)->tracepoint_var_ref (var, gdbarch, ax, value);
-      break;
+      gdb_assert_not_reached (_("LOC_COMPUTED variable missing a method"));
 
     case LOC_OPTIMIZED_OUT:
       /* Flag this, but don't say anything; leave it up to callers to
@@ -718,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;
+}
+
 \f
 
 
@@ -743,7 +769,7 @@ gen_int_literal (struct agent_expr *ax, struct axs_value *value, LONGEST k,
 /* Take what's on the top of the stack (as described by VALUE), and
    try to make an rvalue out of it.  Signal an error if we can't do
    that.  */
-static void
+void
 require_rvalue (struct agent_expr *ax, struct axs_value *value)
 {
   /* Only deal with scalars, structs and such may be too large
@@ -798,8 +824,7 @@ 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
@@ -819,6 +844,7 @@ gen_usual_unary (struct expression *exp, struct agent_expr *ax,
     case TYPE_CODE_ARRAY:
       {
        struct type *elements = TYPE_TARGET_TYPE (value->type);
+
        value->type = lookup_pointer_type (elements);
        value->kind = axs_rvalue;
        /* We don't need to generate any code; the address of the array
@@ -831,12 +857,6 @@ gen_usual_unary (struct expression *exp, struct agent_expr *ax,
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
       return;
-
-      /* If the value is an enum or a bool, call it an integer.  */
-    case TYPE_CODE_ENUM:
-    case TYPE_CODE_BOOL:
-      value->type = builtin_type (exp->gdbarch)->builtin_int;
-      break;
     }
 
   /* If the value is an lvalue, dereference it.  */
@@ -873,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.  */
@@ -898,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 (0);
+  agent_expr_up ax (new agent_expr (NULL, 0));
   int nontrivial;
 
   /* Actually generate the code, and see if anything came out.  At the
@@ -907,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;
 }
 
@@ -920,8 +939,8 @@ 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
@@ -932,7 +951,7 @@ gen_usual_arithmetic (struct expression *exp, struct agent_expr *ax,
          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.  */
@@ -957,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))
     {
@@ -982,13 +1000,14 @@ gen_cast (struct agent_expr *ax, struct axs_value *value, struct type *type)
   /* GCC does allow casts to yield lvalues, so this should be fixed
      before merging these changes into the trunk.  */
   require_rvalue (ax, value);
-  /* Dereference typedefs. */
+  /* Dereference typedefs.  */
   type = check_typedef (type);
 
   switch (TYPE_CODE (type))
     {
     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;
@@ -1134,8 +1153,9 @@ gen_less (struct agent_expr *ax, struct axs_value *value,
    operator, used in error messages */
 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)
+          struct axs_value *value1, struct axs_value *value2,
+          enum agent_op op, enum agent_op op_unsigned,
+          int may_carry, const char *name)
 {
   /* We only handle INT op INT.  */
   if ((TYPE_CODE (value1->type) != TYPE_CODE_INT)
@@ -1180,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.  */
@@ -1203,7 +1223,7 @@ gen_deref (struct agent_expr *ax, struct axs_value *value)
 
 /* 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
@@ -1233,14 +1253,12 @@ 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[]
-  =
-  {aop_ref8, aop_ref16, aop_ref32, aop_ref64};
+    = {aop_ref8, aop_ref16, aop_ref32, aop_ref64};
   static int num_ops = (sizeof (ops) / sizeof (ops[0]));
 
   /* We don't want to touch any byte that the bitfield doesn't
@@ -1286,7 +1304,7 @@ gen_bitfield_ref (struct expression *exp, struct agent_expr *ax,
      equal to the number of `one' bits in bytesize, but who cares?  */
   int fragment_count;
 
-  /* Dereference any typedefs. */
+  /* Dereference any typedefs.  */
   type = check_typedef (type);
 
   /* Can we fetch the number of bits requested at all?  */
@@ -1318,7 +1336,7 @@ gen_bitfield_ref (struct expression *exp, struct agent_expr *ax,
          /* Add the offset.  */
          gen_offset (ax, offset / TARGET_CHAR_BIT);
 
-         if (trace_kludge)
+         if (ax->tracing)
            {
              /* Record the area of memory we're about to fetch.  */
              ax_trace_quick (ax, op_size / TARGET_CHAR_BIT);
@@ -1361,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);
@@ -1394,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
@@ -1419,18 +1436,17 @@ 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--)
     {
-      char *this_name = TYPE_FIELD_NAME (type, i);
+      const char *this_name = TYPE_FIELD_NAME (type, i);
 
       if (this_name)
        {
@@ -1442,14 +1458,15 @@ gen_struct_ref_recursive (struct expression *exp, struct agent_expr *ax,
                 being handled as a global.  */
              if (field_is_static (&TYPE_FIELD (type, 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"),
+                   error (_("static field `%s' has been "
+                            "optimized out, cannot use"),
                           field);
                  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? */
@@ -1465,8 +1482,9 @@ 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,
-                                      offset + TYPE_BASECLASS_BITPOS (type, i) / TARGET_CHAR_BIT,
+      rslt = gen_struct_ref_recursive (ax, value, field,
+                                      offset + TYPE_BASECLASS_BITPOS (type, i)
+                                      / TARGET_CHAR_BIT,
                                       basetype);
       if (rslt)
        return 1;
@@ -1482,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;
@@ -1495,7 +1513,7 @@ 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);
 
@@ -1511,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 (type));
 }
 
 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)
@@ -1541,12 +1556,12 @@ gen_static_field (struct gdbarch *gdbarch,
     }
   else
     {
-      char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (type, fieldno);
-      struct symbol *sym = lookup_symbol (phys_name, 0, VAR_DOMAIN, 0);
+      const char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (type, fieldno);
+      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
@@ -1562,13 +1577,11 @@ 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;
-  struct value *v, *result;
 
   if (TYPE_CODE (t) != TYPE_CODE_STRUCT
       && TYPE_CODE (t) != TYPE_CODE_UNION)
@@ -1577,15 +1590,16 @@ gen_struct_elt_for_reference (struct expression *exp,
 
   for (i = TYPE_NFIELDS (t) - 1; i >= TYPE_N_BASECLASSES (t); i--)
     {
-      char *t_field_name = TYPE_FIELD_NAME (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)))
            {
-             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"),
+               error (_("static field `%s' has been "
+                        "optimized out, cannot use"),
                       fieldname);
              return 1;
            }
@@ -1601,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, TYPE_NAME (curtype));
 
   return found;
 }
@@ -1628,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 = TYPE_NAME (curtype);
+  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))
     {
     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__,
@@ -1675,7 +1685,7 @@ gen_aggregate_elt_ref (struct expression *exp,
   return 0;
 }
 
-/* Generate code for GDB's magical `repeat' operator.  
+/* Generate code for GDB's magical `repeat' operator.
    LVALUE @ INT creates an array INT elements long, and whose elements
    have the same type as LVALUE, located in memory so that LVALUE is
    its first element.  For example, argv[0]@argc gives you the array
@@ -1691,6 +1701,7 @@ gen_repeat (struct expression *exp, union exp_element **pc,
            struct agent_expr *ax, struct axs_value *value)
 {
   struct axs_value value1;
+
   /* We don't want to turn this into an rvalue, so no conversions
      here.  */
   gen_expr (exp, pc, ax, &value1);
@@ -1703,7 +1714,8 @@ gen_repeat (struct expression *exp, union exp_element **pc,
     int length;
 
     if (!v)
-      error (_("Right operand of `@' must be a constant, in agent expressions."));
+      error (_("Right operand of `@' must be a "
+              "constant, in agent expressions."));
     if (TYPE_CODE (value_type (v)) != TYPE_CODE_INT)
       error (_("Right operand of `@' must be an integer."));
     length = value_as_long (v);
@@ -1739,6 +1751,7 @@ gen_sizeof (struct expression *exp, union exp_element **pc,
      So we generate code for the operand, and then throw it away,
      replacing it with code that simply pushes its size.  */
   int start = ax->len;
+
   gen_expr (exp, pc, ax, value);
 
   /* Throw away the code we just generated.  */
@@ -1750,12 +1763,46 @@ gen_sizeof (struct expression *exp, union exp_element **pc,
 }
 \f
 
+/* 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 (TYPE_CODE (value->type) == 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 */
 /* A gen_expr function written by a Gen-X'er guy.
    Append code for the subexpression of EXPR starting at *POS_P to AX.  */
-static void
+void
 gen_expr (struct expression *exp, union exp_element **pc,
          struct agent_expr *ax, struct axs_value *value)
 {
@@ -1763,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.  */
   {
@@ -1801,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;
 
@@ -1809,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);
@@ -1832,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);
@@ -1850,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
@@ -1858,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;
@@ -1875,17 +1922,19 @@ gen_expr (struct expression *exp, union exp_element **pc,
        {
          char *name = internalvar_name ((*pc)[1].internalvar);
          struct trace_state_variable *tsv;
+
          (*pc) += 3;
          gen_expr (exp, pc, ax, value);
          tsv = find_trace_state_variable (name);
          if (tsv)
            {
              ax_tsv (ax, aop_setv, tsv->number);
-             if (trace_kludge)
+             if (ax->tracing)
                ax_tsv (ax, aop_tracev, tsv->number);
            }
          else
-           error (_("$%s is not a trace state variable, may not assign to it"), name);
+           error (_("$%s is not a trace state variable, "
+                    "may not assign to it"), name);
        }
       else
        error (_("May only assign to trace state variables"));
@@ -1900,26 +1949,28 @@ gen_expr (struct expression *exp, union exp_element **pc,
        {
          char *name = internalvar_name ((*pc)[1].internalvar);
          struct trace_state_variable *tsv;
+
          (*pc) += 3;
          tsv = find_trace_state_variable (name);
          if (tsv)
            {
              /* The tsv will be the left half of the binary operation.  */
              ax_tsv (ax, aop_getv, tsv->number);
-             if (trace_kludge)
+             if (ax->tracing)
                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.  */
              ax_tsv (ax, aop_setv, tsv->number);
-             if (trace_kludge)
+             if (ax->tracing)
                ax_tsv (ax, aop_tracev, tsv->number);
            }
          else
-           error (_("$%s is not a trace state variable, may not assign to it"), name);
+           error (_("$%s is not a trace state variable, "
+                    "may not assign to it"), name);
        }
       else
        error (_("May only assign to trace state variables"));
@@ -1937,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;
@@ -1946,17 +1997,30 @@ gen_expr (struct expression *exp, union exp_element **pc,
       {
        struct type *type = (*pc)[1].type;
        LONGEST k = (*pc)[2].longconst;
+
        (*pc) += 4;
        gen_int_literal (ax, value, k, type);
       }
       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 (TYPE_CODE (value->type) == 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 (TYPE_CODE (value->type) == TYPE_CODE_ERROR)
+       error_unknown_type ((*pc)[2].msymbol->linkage_name ());
 
       (*pc) += 4;
       break;
@@ -1965,38 +2029,43 @@ gen_expr (struct expression *exp, union exp_element **pc,
       {
        const char *name = &(*pc)[2].string;
        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);
-       if (reg >= gdbarch_num_regs (exp->gdbarch))
-         error (_("'%s' is a pseudo-register; "
-                  "GDB cannot yet trace pseudoregister contents."),
+       /* No support for tracing user registers yet.  */
+       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;
 
     case OP_INTERNALVAR:
       {
-       const char *name = internalvar_name ((*pc)[1].internalvar);
+       struct internalvar *var = (*pc)[1].internalvar;
+       const char *name = internalvar_name (var);
        struct trace_state_variable *tsv;
+
        (*pc) += 3;
        tsv = find_trace_state_variable (name);
        if (tsv)
          {
            ax_tsv (ax, aop_getv, tsv->number);
-           if (trace_kludge)
+           if (ax->tracing)
              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
-         error (_("$%s is not a trace state variable; GDB agent expressions cannot use convenience variables."), name);
+       else if (! compile_internalvar_to_ax (var, ax, value))
+         error (_("$%s is not a trace state variable; GDB agent "
+                  "expressions cannot use convenience variables."), name);
       }
       break;
 
@@ -2010,25 +2079,65 @@ gen_expr (struct expression *exp, union exp_element **pc,
     case UNOP_CAST:
       {
        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;
+
+    case UNOP_CAST_TYPE:
+      {
+       int offset;
+       struct value *val;
+       struct type *type;
+
+       ++*pc;
+       offset = *pc - exp->elts;
+       val = evaluate_subexp (NULL, exp, &offset, EVAL_AVOID_SIDE_EFFECTS);
+       type = value_type (val);
+       *pc = &exp->elts[offset];
+       gen_expr_for_cast (exp, pc, ax, value, type);
       }
       break;
 
     case UNOP_MEMVAL:
       {
        struct type *type = check_typedef ((*pc)[1].type);
+
        (*pc) += 3;
        gen_expr (exp, pc, ax, value);
-       /* I'm not sure I understand UNOP_MEMVAL entirely.  I think
-          it's just a hack for dealing with minsyms; you take some
-          integer constant, pretend it's the address of an lvalue of
-          the given type, and dereference it.  */
-       if (value->kind != axs_rvalue)
-         /* This would be weird.  */
-         internal_error (__FILE__, __LINE__,
-                         _("gen_expr: OP_MEMVAL operand isn't an rvalue???"));
+
+       /* If we have an axs_rvalue or an axs_lvalue_memory, then we
+          already have the right value on the stack.  For
+          axs_lvalue_register, we must convert.  */
+       if (value->kind == axs_lvalue_register)
+         require_rvalue (ax, value);
+
+       value->type = type;
+       value->kind = axs_lvalue_memory;
+      }
+      break;
+
+    case UNOP_MEMVAL_TYPE:
+      {
+       int offset;
+       struct value *val;
+       struct type *type;
+
+       ++*pc;
+       offset = *pc - exp->elts;
+       val = evaluate_subexp (NULL, exp, &offset, EVAL_AVOID_SIDE_EFFECTS);
+       type = value_type (val);
+       *pc = &exp->elts[offset];
+
+       gen_expr (exp, pc, ax, value);
+
+       /* If we have an axs_rvalue or an axs_lvalue_memory, then we
+          already have the right value on the stack.  For
+          axs_lvalue_register, we must convert.  */
+       if (value->kind == axs_lvalue_register)
+         require_rvalue (ax, value);
+
        value->type = type;
        value->kind = axs_lvalue_memory;
       }
@@ -2036,51 +2145,51 @@ gen_expr (struct expression *exp, union exp_element **pc,
 
     case UNOP_PLUS:
       (*pc)++;
-      /* + FOO is equivalent to 0 + FOO, which can be optimized. */
+      /* + 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:
@@ -2089,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:
@@ -2101,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
@@ -2115,25 +2224,23 @@ gen_expr (struct expression *exp, union exp_element **pc,
 
     case OP_THIS:
       {
-       char *this_name;
-       struct symbol *func, *sym;
-       struct block *b;
+       struct symbol *sym, *func;
+       const struct block *b;
+       const struct language_defn *lang;
 
-       func = block_linkage_function (block_for_pc (ax->scope));
-       this_name = language_def (SYMBOL_LANGUAGE (func))->la_name_of_this;
-       b = SYMBOL_BLOCK_VALUE (func);
+       b = block_for_pc (ax->scope);
+       func = block_linkage_function (b);
+       lang = language_def (func->language ());
 
-       /* Calling lookup_block_symbol is necessary to get the LOC_REGISTER
-          symbol instead of the LOC_ARG one (if both exist).  */
-       sym = lookup_block_symbol (b, this_name, VAR_DOMAIN);
+       sym = lookup_language_this (lang, b).symbol;
        if (!sym)
-         error (_("no `%s' found"), this_name);
+         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;
       }
@@ -2146,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);
@@ -2155,11 +2261,13 @@ gen_expr (struct expression *exp, union exp_element **pc,
       break;
 
     case OP_TYPE:
+    case OP_TYPEOF:
+    case OP_DECLTYPE:
       error (_("Attempt to use a type name as an expression."));
 
     default:
       error (_("Unsupported operator %s (%d) in expression."),
-            op_string (op), op);
+            op_name (exp, op), op);
     }
 }
 
@@ -2173,11 +2281,11 @@ 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:
@@ -2203,7 +2311,7 @@ gen_expr_binop_rest (struct expression *exp,
               && 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");
@@ -2234,8 +2342,8 @@ gen_expr_binop_rest (struct expression *exp,
 
        if (binop_types_user_defined_p (op, value1->type, value2->type))
          {
-           error (_("\
-cannot subscript requested type: cannot call user defined functions"));
+           error (_("cannot subscript requested type: "
+                    "cannot call user defined functions"));
          }
        else
          {
@@ -2255,10 +2363,11 @@ cannot subscript requested type: cannot call user defined functions"));
          }
 
        if (!is_integral_type (value2->type))
-         error (_("Argument to arithmetic operation not a number or boolean."));
+         error (_("Argument to arithmetic operation "
+                  "not a number or boolean."));
 
        gen_ptradd (ax, value, value1, value2);
-       gen_deref (ax, value);
+       gen_deref (value);
        break;
       }
     case BINOP_BITWISE_AND:
@@ -2319,37 +2428,28 @@ cannot subscript requested type: cannot call user defined functions"));
    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)
+                  struct symbol *var, int trace_string)
 {
-  struct cleanup *old_chain = 0;
-  struct agent_expr *ax = new_agent_expr (scope);
+  agent_expr_up ax (new agent_expr (gdbarch, scope));
   struct axs_value value;
 
-  old_chain = make_cleanup_free_agent_expr (ax);
-
-  trace_kludge = 1;
-  gen_var_ref (gdbarch, ax, &value, var);
+  ax->tracing = 1;
+  ax->trace_string = trace_string;
+  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;
 }
 
@@ -2360,30 +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 *
-gen_trace_for_expr (CORE_ADDR scope, struct expression *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 (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;
-  trace_kludge = 1;
-  gen_expr (expr, &pc, ax, &value);
+  ax->tracing = 1;
+  ax->trace_string = trace_string;
+  value.optimized_out = 0;
+  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;
 }
 
@@ -2394,38 +2491,135 @@ 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 (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;
-  trace_kludge = 0;
-  gen_expr (expr, &pc, ax, &value);
+  ax->tracing = 0;
+  value.optimized_out = 0;
+  gen_expr (expr, &pc, ax.get (), &value);
+
+  require_rvalue (ax.get (), &value);
+
+  /* Oh, and terminate.  */
+  ax_simple (ax.get (), aop_end);
+
+  return ax;
+}
+
+agent_expr_up
+gen_trace_for_return_address (CORE_ADDR scope, struct gdbarch *gdbarch,
+                             int trace_string)
+{
+  agent_expr_up ax (new agent_expr (gdbarch, scope));
+  struct axs_value value;
+
+  ax->tracing = 1;
+  ax->trace_string = trace_string;
+
+  gdbarch_gen_return_address (gdbarch, ax.get (), &value, scope);
+
+  /* Make sure we record the final object, and get rid of it.  */
+  gen_traced_pop (ax.get (), &value);
 
   /* Oh, and terminate.  */
-  ax_simple (ax, aop_end);
+  ax_simple (ax.get (), aop_end);
+
+  return ax;
+}
+
+/* Given a collection of printf-style arguments, generate code to
+   evaluate the arguments and pass everything to a special
+   bytecode.  */
+
+agent_expr_up
+gen_printf (CORE_ADDR scope, struct gdbarch *gdbarch,
+           CORE_ADDR function, LONGEST channel,
+           const char *format, int fmtlen,
+           int nargs, struct expression **exprs)
+{
+  agent_expr_up ax (new agent_expr (gdbarch, scope));
+  union exp_element *pc;
+  struct axs_value value;
+  int tem;
+
+  /* We're computing values, not doing side effects.  */
+  ax->tracing = 0;
+
+  /* Evaluate and push the args on the stack in reverse order,
+     for simplicity of collecting them on the target side.  */
+  for (tem = nargs - 1; tem >= 0; --tem)
+    {
+      pc = exprs[tem]->elts;
+      value.optimized_out = 0;
+      gen_expr (exprs[tem], &pc, ax.get (), &value);
+      require_rvalue (ax.get (), &value);
+    }
+
+  /* Push function and channel.  */
+  ax_const_l (ax.get (), channel);
+  ax_const_l (ax.get (), function);
+
+  /* Issue the printf bytecode proper.  */
+  ax_simple (ax.get (), aop_printf);
+  ax_raw_byte (ax.get (), nargs);
+  ax_string (ax.get (), format, fmtlen);
+
+  /* And terminate.  */
+  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;
 }
 
 static void
-agent_command (char *exp, int from_tty)
+agent_eval_command_one (const char *exp, int eval, CORE_ADDR pc)
 {
-  struct cleanup *old_chain = 0;
-  struct expression *expr;
-  struct agent_expr *agent;
-  struct frame_info *fi = get_current_frame ();        /* need current scope */
+  const char *arg;
+  int trace_string = 0;
+
+  if (!eval)
+    {
+      if (*exp == '/')
+        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);
+    }
+  else
+    {
+      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.get ());
+       }
+      else
+       agent = gen_trace_for_expr (pc, expr.get (), trace_string);
+    }
 
+  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.  */
+
+  dont_repeat ();
+}
+
+static void
+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
      another command, change the error message; the user shouldn't
@@ -2436,30 +2630,55 @@ agent_command (char *exp, int from_tty)
   if (exp == 0)
     error_no_arg (_("expression to translate"));
 
-  expr = parse_expression (exp);
-  old_chain = make_cleanup (free_current_contents, &expr);
-  agent = gen_trace_for_expr (get_frame_pc (fi), expr);
-  make_cleanup_free_agent_expr (agent);
-  ax_print (gdb_stdout, agent);
-
-  /* It would be nice to call ax_reqs here to gather some general info
-     about the expression, and then print out the result.  */
+  if (check_for_argument (&exp, "-at", sizeof ("-at") - 1))
+    {
+      struct linespec_result 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);
+      exp = skip_spaces (exp);
+      if (exp[0] == ',')
+        {
+         exp++;
+         exp = skip_spaces (exp);
+       }
+      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 ()));
 
-  do_cleanups (old_chain);
   dont_repeat ();
 }
 
+static void
+agent_command (const char *exp, int from_tty)
+{
+  agent_command_1 (exp, 0);
+}
+
 /* Parse the given expression, compile it into an agent expression
    that does direct evaluation, and display the resulting
    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);
+}
+
+/* Parse the given expression, compile it into an agent expression
+   that does a printf, and display the resulting expression.  */
+
+static void
+maint_agent_printf_command (const char *cmdrest, int from_tty)
 {
-  struct cleanup *old_chain = 0;
-  struct expression *expr;
-  struct agent_expr *agent;
   struct frame_info *fi = get_current_frame ();        /* need current scope */
+  const char *format_start, *format_end;
 
   /* We don't deal with overlay debugging at the moment.  We need to
      think more carefully about this.  If you copy this code into
@@ -2468,34 +2687,83 @@ agent_eval_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"));
 
-  expr = parse_expression (exp);
-  old_chain = make_cleanup (free_current_contents, &expr);
-  agent = gen_eval_for_expr (get_frame_pc (fi), expr);
-  make_cleanup_free_agent_expr (agent);
-  ax_print (gdb_stdout, agent);
+  cmdrest = skip_spaces (cmdrest);
+
+  if (*cmdrest++ != '"')
+    error (_("Must start with a format string."));
+
+  format_start = cmdrest;
+
+  format_pieces fpieces (&cmdrest);
+
+  format_end = cmdrest;
+
+  if (*cmdrest++ != '"')
+    error (_("Bad format string, non-terminated '\"'."));
+  
+  cmdrest = skip_spaces (cmdrest);
+
+  if (*cmdrest != ',' && *cmdrest != 0)
+    error (_("Invalid argument syntax"));
+
+  if (*cmdrest == ',')
+    cmdrest++;
+  cmdrest = skip_spaces (cmdrest);
+
+  std::vector<struct expression *> argvec;
+  while (*cmdrest != '\0')
+    {
+      const char *cmd1;
+
+      cmd1 = cmdrest;
+      expression_up expr = parse_exp_1 (&cmd1, 0, (struct block *) 0, 1);
+      argvec.push_back (expr.release ());
+      cmdrest = cmd1;
+      if (*cmdrest == ',')
+       ++cmdrest;
+      /* else complain? */
+    }
+
+
+  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 ();
 }
-\f
 
 /* Initialization code.  */
 
-void _initialize_ax_gdb (void);
 void
 _initialize_ax_gdb (void)
 {
   add_cmd ("agent", class_maintenance, agent_command,
-          _("Translate an expression into remote agent bytecode for tracing."),
+          _("\
+Translate an expression into remote agent bytecode for tracing.\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);
 
   add_cmd ("agent-eval", class_maintenance, agent_eval_command,
-          _("Translate an expression into remote agent bytecode for evaluation."),
+          _("\
+Translate an expression into remote agent bytecode for evaluation.\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);
+
+  add_cmd ("agent-printf", class_maintenance, maint_agent_printf_command,
+          _("Translate an expression into remote "
+            "agent bytecode for evaluation and display the bytecodes."),
           &maintenancelist);
 }
This page took 0.049227 seconds and 4 git commands to generate.