2009-12-23 Stan Shebs <stan@codesourcery.com>
[deliverable/binutils-gdb.git] / gdb / ax-gdb.c
index 8f23905a90d9331d6ac9df57af1aac191f56d0b5..4d3f3ace57c25b88831f712cee2bbd8729168fac 100644 (file)
@@ -1,11 +1,13 @@
-/* GDB-specific functions for operating on agent expressions
-   Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+/* GDB-specific functions for operating on agent expressions.
+
+   Copyright (C) 1998, 1999, 2000, 2001, 2003, 2007, 2008, 2009
+   Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -14,9 +16,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "symtab.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"
 
 /* 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,
@@ -69,11 +73,11 @@ 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 agent_expr *);
-static void gen_frame_locals_address (struct agent_expr *);
+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_offset (struct agent_expr *ax, int offset);
 static void gen_sym_offset (struct agent_expr *, struct symbol *);
-static void gen_var_ref (struct agent_expr *ax,
+static void gen_var_ref (struct gdbarch *, struct agent_expr *ax,
                         struct axs_value *value, struct symbol *var);
 
 
@@ -83,54 +87,58 @@ static void gen_int_literal (struct agent_expr *ax,
 
 
 static void require_rvalue (struct agent_expr *ax, struct axs_value *value);
-static void gen_usual_unary (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 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 agent_expr *ax,
+static void gen_usual_arithmetic (struct expression *exp,
+                                 struct agent_expr *ax,
                                  struct axs_value *value1,
                                  struct axs_value *value2);
-static void gen_integral_promotions (struct agent_expr *ax,
+static void gen_integral_promotions (struct expression *exp,
+                                    struct agent_expr *ax,
                                     struct axs_value *value);
 static void gen_cast (struct agent_expr *ax,
                      struct axs_value *value, struct type *type);
 static void gen_scale (struct agent_expr *ax,
                       enum agent_op op, struct type *type);
-static void gen_add (struct agent_expr *ax,
-                    struct axs_value *value,
-                    struct axs_value *value1,
-                    struct axs_value *value2, char *name);
-static void gen_sub (struct agent_expr *ax,
-                    struct axs_value *value,
-                    struct axs_value *value1, struct axs_value *value2);
+static void gen_ptradd (struct agent_expr *ax, struct axs_value *value,
+                       struct axs_value *value1, struct axs_value *value2);
+static void gen_ptrsub (struct agent_expr *ax, struct axs_value *value,
+                       struct axs_value *value1, struct axs_value *value2);
+static void gen_ptrdiff (struct agent_expr *ax, struct axs_value *value,
+                        struct axs_value *value1, struct axs_value *value2,
+                        struct type *result_type);
 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);
-static void gen_logical_not (struct agent_expr *ax, struct axs_value *value);
+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 int find_field (struct type *type, char *name);
-static void gen_bitfield_ref (struct agent_expr *ax,
+static void gen_bitfield_ref (struct expression *exp, struct agent_expr *ax,
                              struct axs_value *value,
                              struct type *type, int start, int end);
-static void gen_struct_ref (struct agent_expr *ax,
+static void gen_struct_ref (struct expression *exp, struct agent_expr *ax,
                            struct axs_value *value,
                            char *field,
                            char *operator_name, char *operand_name);
-static void gen_repeat (union exp_element **pc,
-                       struct agent_expr *ax, struct axs_value *value);
-static void gen_sizeof (union exp_element **pc,
+static void gen_repeat (struct expression *exp, union exp_element **pc,
                        struct agent_expr *ax, struct axs_value *value);
-static void gen_expr (union exp_element **pc,
+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 print_axs_value (struct ui_file *f, struct axs_value * value);
 static void agent_command (char *exp, int from_tty);
 \f
 
@@ -318,7 +326,7 @@ gen_traced_pop (struct agent_expr *ax, struct axs_value *value)
 
       case axs_lvalue_memory:
        {
-         int length = TYPE_LENGTH (value->type);
+         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
@@ -411,7 +419,7 @@ gen_fetch (struct agent_expr *ax, struct type *type)
             In any case, it's a bug the user shouldn't see.  */
        default:
          internal_error (__FILE__, __LINE__,
-                         "gen_fetch: strange size");
+                         _("gen_fetch: strange size"));
        }
 
       gen_sign_extend (ax, type);
@@ -423,7 +431,7 @@ gen_fetch (struct agent_expr *ax, struct type *type)
          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");
+                     _("gen_fetch: bad type code"));
     }
 }
 
@@ -453,12 +461,13 @@ 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 agent_expr *ax)
+gen_frame_args_address (struct gdbarch *gdbarch, struct agent_expr *ax)
 {
   int frame_reg;
   LONGEST frame_offset;
 
-  TARGET_VIRTUAL_FRAME_POINTER (ax->scope, &frame_reg, &frame_offset);
+  gdbarch_virtual_frame_pointer (gdbarch,
+                                ax->scope, &frame_reg, &frame_offset);
   ax_reg (ax, frame_reg);
   gen_offset (ax, frame_offset);
 }
@@ -467,12 +476,13 @@ gen_frame_args_address (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 agent_expr *ax)
+gen_frame_locals_address (struct gdbarch *gdbarch, struct agent_expr *ax)
 {
   int frame_reg;
   LONGEST frame_offset;
 
-  TARGET_VIRTUAL_FRAME_POINTER (ax->scope, &frame_reg, &frame_offset);
+  gdbarch_virtual_frame_pointer (gdbarch,
+                                ax->scope, &frame_reg, &frame_offset);
   ax_reg (ax, frame_reg);
   gen_offset (ax, frame_offset);
 }
@@ -516,7 +526,8 @@ gen_sym_offset (struct agent_expr *ax, struct symbol *var)
    symbol VAR.  Set VALUE to describe the result.  */
 
 static void
-gen_var_ref (struct agent_expr *ax, struct axs_value *value, struct symbol *var)
+gen_var_ref (struct gdbarch *gdbarch, struct agent_expr *ax,
+            struct axs_value *value, struct symbol *var)
 {
   /* Dereference any typedefs. */
   value->type = check_typedef (SYMBOL_TYPE (var));
@@ -536,7 +547,7 @@ gen_var_ref (struct agent_expr *ax, struct axs_value *value, struct symbol *var)
 
     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:
@@ -546,37 +557,29 @@ gen_var_ref (struct agent_expr *ax, struct axs_value *value, struct symbol *var)
       break;
 
     case LOC_ARG:              /* var lives in argument area of frame */
-      gen_frame_args_address (ax);
+      gen_frame_args_address (gdbarch, 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 (ax);
+      gen_frame_args_address (gdbarch, ax);
       gen_sym_offset (ax, var);
       /* Don't assume any particular pointer size.  */
-      gen_fetch (ax, lookup_pointer_type (builtin_type_void));
+      gen_fetch (ax, builtin_type (gdbarch)->builtin_data_ptr);
       value->kind = axs_lvalue_memory;
       break;
 
     case LOC_LOCAL:            /* var lives in locals area of frame */
-    case LOC_LOCAL_ARG:
-      gen_frame_locals_address (ax);
-      gen_sym_offset (ax, var);
-      value->kind = axs_lvalue_memory;
-      break;
-
-    case LOC_BASEREG:          /* relative to some base register */
-    case LOC_BASEREG_ARG:
-      ax_reg (ax, SYMBOL_BASEREG (var));
+      gen_frame_locals_address (gdbarch, ax);
       gen_sym_offset (ax, var);
       value->kind = axs_lvalue_memory;
       break;
 
     case LOC_TYPEDEF:
-      error ("Cannot compute value of typedef `%s'.",
-            SYMBOL_SOURCE_NAME (var));
+      error (_("Cannot compute value of typedef `%s'."),
+            SYMBOL_PRINT_NAME (var));
       break;
 
     case LOC_BLOCK:
@@ -585,29 +588,28 @@ gen_var_ref (struct agent_expr *ax, struct axs_value *value, struct symbol *var)
       break;
 
     case LOC_REGISTER:
-    case LOC_REGPARM:
       /* Don't generate any code at all; in the process of treating
          this as an lvalue or rvalue, the caller will generate the
          right code.  */
       value->kind = axs_lvalue_register;
-      value->u.reg = SYMBOL_VALUE (var);
+      value->u.reg = SYMBOL_REGISTER_OPS (var)->register_number (var, gdbarch);
       break;
 
       /* A lot like LOC_REF_ARG, but the pointer lives directly in a
-         register, not on the stack.  Simpler than LOC_REGISTER and
-         LOC_REGPARM, because it's just like any other case where the
-         thing has a real address.  */
+         register, not on the stack.  Simpler than LOC_REGISTER
+         because it's just like any other case where the thing
+        has a real address.  */
     case LOC_REGPARM_ADDR:
-      ax_reg (ax, SYMBOL_VALUE (var));
+      ax_reg (ax, SYMBOL_REGISTER_OPS (var)->register_number (var, gdbarch));
       value->kind = axs_lvalue_memory;
       break;
 
     case LOC_UNRESOLVED:
       {
        struct minimal_symbol *msym
-       = lookup_minimal_symbol (SYMBOL_NAME (var), NULL, NULL);
+         = lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (var), NULL, NULL);
        if (!msym)
-         error ("Couldn't resolve symbol `%s'.", SYMBOL_SOURCE_NAME (var));
+         error (_("Couldn't resolve symbol `%s'."), SYMBOL_PRINT_NAME (var));
 
        /* Push the address of the variable.  */
        ax_const_l (ax, SYMBOL_VALUE_ADDRESS (msym));
@@ -615,14 +617,23 @@ gen_var_ref (struct agent_expr *ax, struct axs_value *value, struct symbol *var)
       }
       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;
+
     case LOC_OPTIMIZED_OUT:
-      error ("The variable `%s' has been optimized out.",
-            SYMBOL_SOURCE_NAME (var));
+      error (_("The variable `%s' has been optimized out."),
+            SYMBOL_PRINT_NAME (var));
       break;
 
     default:
-      error ("Cannot find value of botched symbol `%s'.",
-            SYMBOL_SOURCE_NAME (var));
+      error (_("Cannot find value of botched symbol `%s'."),
+            SYMBOL_PRINT_NAME (var));
       break;
     }
 }
@@ -637,7 +648,7 @@ gen_int_literal (struct agent_expr *ax, struct axs_value *value, LONGEST k,
 {
   ax_const_l (ax, k);
   value->kind = axs_rvalue;
-  value->type = type;
+  value->type = check_typedef (type);
 }
 \f
 
@@ -693,7 +704,8 @@ require_rvalue (struct agent_expr *ax, struct axs_value *value)
    lvalue through unchanged, and let `+' raise an error.  */
 
 static void
-gen_usual_unary (struct agent_expr *ax, struct axs_value *value)
+gen_usual_unary (struct expression *exp, 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
@@ -728,7 +740,7 @@ gen_usual_unary (struct agent_expr *ax, struct axs_value *value)
 
       /* If the value is an enum, call it an integer.  */
     case TYPE_CODE_ENUM:
-      value->type = builtin_type_int;
+      value->type = builtin_type (exp->gdbarch)->builtin_int;
       break;
     }
 
@@ -813,8 +825,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 agent_expr *ax, struct axs_value *value1,
-                     struct axs_value *value2)
+gen_usual_arithmetic (struct expression *exp, 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
@@ -825,7 +837,7 @@ gen_usual_arithmetic (struct agent_expr *ax, struct axs_value *value1,
          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_int,
+      struct type *target = max_type (builtin_type (exp->gdbarch)->builtin_int,
                                      max_type (value1->type, value2->type));
 
       /* Deal with value2, on the top of the stack.  */
@@ -841,7 +853,7 @@ gen_usual_arithmetic (struct agent_expr *ax, struct axs_value *value1,
          ax_simple (ax, aop_swap);
        }
 
-      value1->type = value2->type = target;
+      value1->type = value2->type = check_typedef (target);
     }
 }
 
@@ -850,17 +862,20 @@ gen_usual_arithmetic (struct agent_expr *ax, struct axs_value *value1,
    the value on the top of the stack, as described by VALUE.  Assume
    the value has integral type.  */
 static void
-gen_integral_promotions (struct agent_expr *ax, struct axs_value *value)
+gen_integral_promotions (struct expression *exp, struct agent_expr *ax,
+                        struct axs_value *value)
 {
-  if (!type_wider_than (value->type, builtin_type_int))
+  const struct builtin_type *builtin = builtin_type (exp->gdbarch);
+
+  if (!type_wider_than (value->type, builtin->builtin_int))
     {
-      gen_conversion (ax, value->type, builtin_type_int);
-      value->type = builtin_type_int;
+      gen_conversion (ax, value->type, builtin->builtin_int);
+      value->type = builtin->builtin_int;
     }
-  else if (!type_wider_than (value->type, builtin_type_unsigned_int))
+  else if (!type_wider_than (value->type, builtin->builtin_unsigned_int))
     {
-      gen_conversion (ax, value->type, builtin_type_unsigned_int);
-      value->type = builtin_type_unsigned_int;
+      gen_conversion (ax, value->type, builtin->builtin_unsigned_int);
+      value->type = builtin->builtin_unsigned_int;
     }
 }
 
@@ -886,15 +901,14 @@ gen_cast (struct agent_expr *ax, struct axs_value *value, struct type *type)
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
     case TYPE_CODE_FUNC:
-      error ("Illegal type cast: intended type must be scalar.");
+      error (_("Invalid type cast: intended type must be scalar."));
 
     case TYPE_CODE_ENUM:
       /* We don't have to worry about the size of the value, because
          all our integral values are fully sign-extended, and when
          casting pointers we can do anything we like.  Is there any
-         way for us to actually know what GCC actually does with a
-         cast like this?  */
-      value->type = type;
+         way for us to know what GCC actually does with a cast like
+         this?  */
       break;
 
     case TYPE_CODE_INT:
@@ -909,7 +923,7 @@ gen_cast (struct agent_expr *ax, struct axs_value *value, struct type *type)
       break;
 
     default:
-      error ("Casts to requested type are not yet implemented.");
+      error (_("Casts to requested type are not yet implemented."));
     }
 
   value->type = type;
@@ -934,105 +948,60 @@ gen_scale (struct agent_expr *ax, enum agent_op op, struct type *type)
 }
 
 
-/* Generate code for an addition; non-trivial because we deal with
-   pointer arithmetic.  We set VALUE to describe the result value; we
-   assume VALUE1 and VALUE2 describe the two operands, and that
-   they've undergone the usual binary conversions.  Used by both
-   BINOP_ADD and BINOP_SUBSCRIPT.  NAME is used in error messages.  */
+/* Generate code for pointer arithmetic PTR + INT.  */
 static void
-gen_add (struct agent_expr *ax, struct axs_value *value,
-        struct axs_value *value1, struct axs_value *value2, char *name)
+gen_ptradd (struct agent_expr *ax, struct axs_value *value,
+           struct axs_value *value1, struct axs_value *value2)
 {
-  /* Is it INT+PTR?  */
-  if (TYPE_CODE (value1->type) == TYPE_CODE_INT
-      && TYPE_CODE (value2->type) == TYPE_CODE_PTR)
-    {
-      /* Swap the values and proceed normally.  */
-      ax_simple (ax, aop_swap);
-      gen_scale (ax, aop_mul, value2->type);
-      ax_simple (ax, aop_add);
-      gen_extend (ax, value2->type);   /* Catch overflow.  */
-      value->type = value2->type;
-    }
+  gdb_assert (TYPE_CODE (value1->type) == TYPE_CODE_PTR);
+  gdb_assert (TYPE_CODE (value2->type) == TYPE_CODE_INT);
 
-  /* Is it PTR+INT?  */
-  else if (TYPE_CODE (value1->type) == TYPE_CODE_PTR
-          && TYPE_CODE (value2->type) == TYPE_CODE_INT)
-    {
-      gen_scale (ax, aop_mul, value1->type);
-      ax_simple (ax, aop_add);
-      gen_extend (ax, value1->type);   /* Catch overflow.  */
-      value->type = value1->type;
-    }
+  gen_scale (ax, aop_mul, value1->type);
+  ax_simple (ax, aop_add);
+  gen_extend (ax, value1->type);       /* Catch overflow.  */
+  value->type = value1->type;
+  value->kind = axs_rvalue;
+}
 
-  /* Must be number + number; the usual binary conversions will have
-     brought them both to the same width.  */
-  else if (TYPE_CODE (value1->type) == TYPE_CODE_INT
-          && TYPE_CODE (value2->type) == TYPE_CODE_INT)
-    {
-      ax_simple (ax, aop_add);
-      gen_extend (ax, value1->type);   /* Catch overflow.  */
-      value->type = value1->type;
-    }
 
-  else
-    error ("Illegal combination of types in %s.", name);
+/* Generate code for pointer arithmetic PTR - INT.  */
+static void
+gen_ptrsub (struct agent_expr *ax, struct axs_value *value,
+           struct axs_value *value1, struct axs_value *value2)
+{
+  gdb_assert (TYPE_CODE (value1->type) == TYPE_CODE_PTR);
+  gdb_assert (TYPE_CODE (value2->type) == TYPE_CODE_INT);
 
+  gen_scale (ax, aop_mul, value1->type);
+  ax_simple (ax, aop_sub);
+  gen_extend (ax, value1->type);       /* Catch overflow.  */
+  value->type = value1->type;
   value->kind = axs_rvalue;
 }
 
 
-/* Generate code for an addition; non-trivial because we have to deal
-   with pointer arithmetic.  We set VALUE to describe the result
-   value; we assume VALUE1 and VALUE2 describe the two operands, and
-   that they've undergone the usual binary conversions.  */
+/* Generate code for pointer arithmetic PTR - PTR.  */
 static void
-gen_sub (struct agent_expr *ax, struct axs_value *value,
-        struct axs_value *value1, struct axs_value *value2)
+gen_ptrdiff (struct agent_expr *ax, struct axs_value *value,
+            struct axs_value *value1, struct axs_value *value2,
+            struct type *result_type)
 {
-  if (TYPE_CODE (value1->type) == TYPE_CODE_PTR)
-    {
-      /* Is it PTR - INT?  */
-      if (TYPE_CODE (value2->type) == TYPE_CODE_INT)
-       {
-         gen_scale (ax, aop_mul, value1->type);
-         ax_simple (ax, aop_sub);
-         gen_extend (ax, value1->type);        /* Catch overflow.  */
-         value->type = value1->type;
-       }
+  gdb_assert (TYPE_CODE (value1->type) == TYPE_CODE_PTR);
+  gdb_assert (TYPE_CODE (value2->type) == TYPE_CODE_PTR);
 
-      /* Is it PTR - PTR?  Strictly speaking, the types ought to
-         match, but this is what the normal GDB expression evaluator
-         tests for.  */
-      else if (TYPE_CODE (value2->type) == TYPE_CODE_PTR
-              && (TYPE_LENGTH (TYPE_TARGET_TYPE (value1->type))
-                  == TYPE_LENGTH (TYPE_TARGET_TYPE (value2->type))))
-       {
-         ax_simple (ax, aop_sub);
-         gen_scale (ax, aop_div_unsigned, value1->type);
-         value->type = builtin_type_long;      /* FIXME --- should be ptrdiff_t */
-       }
-      else
-       error ("\
+  if (TYPE_LENGTH (TYPE_TARGET_TYPE (value1->type))
+      != TYPE_LENGTH (TYPE_TARGET_TYPE (value2->type)))
+    error (_("\
 First argument of `-' is a pointer, but second argument is neither\n\
-an integer nor a pointer of the same type.");
-    }
-
-  /* Must be number + number.  */
-  else if (TYPE_CODE (value1->type) == TYPE_CODE_INT
-          && TYPE_CODE (value2->type) == TYPE_CODE_INT)
-    {
-      ax_simple (ax, aop_sub);
-      gen_extend (ax, value1->type);   /* Catch overflow.  */
-      value->type = value1->type;
-    }
-
-  else
-    error ("Illegal combination of types in subtraction.");
+an integer nor a pointer of the same type."));
 
+  ax_simple (ax, aop_sub);
+  gen_scale (ax, aop_div_unsigned, value1->type);
+  value->type = result_type;
   value->kind = axs_rvalue;
 }
 
+
 /* Generate code for a binary operator that doesn't do pointer magic.
    We set VALUE to describe the result value; we assume VALUE1 and
    VALUE2 describe the two operands, and that they've undergone the
@@ -1047,7 +1016,7 @@ gen_binop (struct agent_expr *ax, struct axs_value *value,
   /* We only handle INT op INT.  */
   if ((TYPE_CODE (value1->type) != TYPE_CODE_INT)
       || (TYPE_CODE (value2->type) != TYPE_CODE_INT))
-    error ("Illegal combination of types in %s.", name);
+    error (_("Invalid combination of types in %s."), name);
 
   ax_simple (ax,
             TYPE_UNSIGNED (value1->type) ? op_unsigned : op);
@@ -1059,15 +1028,15 @@ gen_binop (struct agent_expr *ax, struct axs_value *value,
 
 
 static void
-gen_logical_not (struct agent_expr *ax, struct axs_value *value)
+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)
-    error ("Illegal type of operand to `!'.");
+    error (_("Invalid type of operand to `!'."));
 
-  gen_usual_unary (ax, value);
   ax_simple (ax, aop_log_not);
-  value->type = builtin_type_int;
+  value->type = result_type;
 }
 
 
@@ -1075,10 +1044,8 @@ static void
 gen_complement (struct agent_expr *ax, struct axs_value *value)
 {
   if (TYPE_CODE (value->type) != TYPE_CODE_INT)
-    error ("Illegal type of operand to `~'.");
+    error (_("Invalid type of operand to `~'."));
 
-  gen_usual_unary (ax, value);
-  gen_integral_promotions (ax, value);
   ax_simple (ax, aop_bit_not);
   gen_extend (ax, value->type);
 }
@@ -1095,7 +1062,7 @@ gen_deref (struct agent_expr *ax, struct axs_value *value)
      this, and we don't know what error message to generate.  */
   if (TYPE_CODE (value->type) != TYPE_CODE_PTR)
     internal_error (__FILE__, __LINE__,
-                   "gen_deref: expected a pointer");
+                   _("gen_deref: expected a pointer"));
 
   /* We've got an rvalue now, which is a pointer.  We want to yield an
      lvalue, whose address is exactly that pointer.  So we don't
@@ -1123,10 +1090,10 @@ gen_address_of (struct agent_expr *ax, struct axs_value *value)
     switch (value->kind)
       {
       case axs_rvalue:
-       error ("Operand of `&' is an rvalue, which has no address.");
+       error (_("Operand of `&' is an rvalue, which has no address."));
 
       case axs_lvalue_register:
-       error ("Operand of `&' is in a register, and has no address.");
+       error (_("Operand of `&' is in a register, and has no address."));
 
       case axs_lvalue_memory:
        value->kind = axs_rvalue;
@@ -1151,21 +1118,24 @@ find_field (struct type *type, char *name)
   /* Make sure this isn't C++.  */
   if (TYPE_N_BASECLASSES (type) != 0)
     internal_error (__FILE__, __LINE__,
-                   "find_field: derived classes supported");
+                   _("find_field: derived classes supported"));
 
   for (i = 0; i < TYPE_NFIELDS (type); i++)
     {
       char *this_name = TYPE_FIELD_NAME (type, i);
 
-      if (this_name && STREQ (name, this_name))
-       return i;
+      if (this_name)
+       {
+         if (strcmp (name, this_name) == 0)
+           return i;
 
-      if (this_name[0] == '\0')
-       internal_error (__FILE__, __LINE__,
-                       "find_field: anonymous unions not supported");
+         if (this_name[0] == '\0')
+           internal_error (__FILE__, __LINE__,
+                           _("find_field: anonymous unions not supported"));
+       }
     }
 
-  error ("Couldn't find member named `%s' in struct/union `%s'",
+  error (_("Couldn't find member named `%s' in struct/union `%s'"),
         name, TYPE_TAG_NAME (type));
 
   return 0;
@@ -1177,8 +1147,9 @@ find_field (struct type *type, char *name)
    starting and one-past-ending *bit* numbers of the field within the
    structure.  */
 static void
-gen_bitfield_ref (struct agent_expr *ax, struct axs_value *value,
-                 struct type *type, int start, int end)
+gen_bitfield_ref (struct expression *exp, 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[]
@@ -1235,7 +1206,7 @@ gen_bitfield_ref (struct agent_expr *ax, struct axs_value *value,
   /* Can we fetch the number of bits requested at all?  */
   if ((end - start) > ((1 << num_ops) * 8))
     internal_error (__FILE__, __LINE__,
-                   "gen_bitfield_ref: bitfield too wide");
+                   _("gen_bitfield_ref: bitfield too wide"));
 
   /* Note that we know here that we only need to try each opcode once.
      That may not be true on machines with weird byte sizes.  */
@@ -1304,7 +1275,7 @@ gen_bitfield_ref (struct agent_expr *ax, struct axs_value *value,
             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 (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+         if (gdbarch_byte_order (exp->gdbarch) == BFD_ENDIAN_BIG)
            gen_left_shift (ax, end - (offset + op_size));
          else
            gen_left_shift (ax, offset - start);
@@ -1338,7 +1309,8 @@ gen_bitfield_ref (struct agent_expr *ax, struct axs_value *value,
    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 agent_expr *ax, struct axs_value *value, char *field,
+gen_struct_ref (struct expression *exp, struct agent_expr *ax,
+               struct axs_value *value, char *field,
                char *operator_name, char *operand_name)
 {
   struct type *type;
@@ -1349,7 +1321,7 @@ gen_struct_ref (struct agent_expr *ax, struct axs_value *value, char *field,
      should at least be consistent.  */
   while (TYPE_CODE (value->type) == TYPE_CODE_PTR)
     {
-      gen_usual_unary (ax, value);
+      require_rvalue (ax, value);
       gen_deref (ax, value);
     }
   type = check_typedef (value->type);
@@ -1357,19 +1329,19 @@ gen_struct_ref (struct agent_expr *ax, struct axs_value *value, char *field,
   /* This must yield a structure or a union.  */
   if (TYPE_CODE (type) != TYPE_CODE_STRUCT
       && TYPE_CODE (type) != TYPE_CODE_UNION)
-    error ("The left operand of `%s' is not a %s.",
+    error (_("The left operand of `%s' is not a %s."),
           operator_name, operand_name);
 
   /* And it must be in memory; we don't deal with structure rvalues,
      or structures living in registers.  */
   if (value->kind != axs_lvalue_memory)
-    error ("Structure does not live in memory.");
+    error (_("Structure does not live in memory."));
 
   i = find_field (type, field);
 
   /* Is this a bitfield?  */
   if (TYPE_FIELD_PACKED (type, i))
-    gen_bitfield_ref (ax, value, TYPE_FIELD_TYPE (type, i),
+    gen_bitfield_ref (exp, ax, value, TYPE_FIELD_TYPE (type, i),
                      TYPE_FIELD_BITPOS (type, i),
                      (TYPE_FIELD_BITPOS (type, i)
                       + TYPE_FIELD_BITSIZE (type, i)));
@@ -1394,15 +1366,15 @@ gen_struct_ref (struct agent_expr *ax, struct axs_value *value, char *field,
    stack slots, doing weird things with sizeof, etc.  So we require
    the right operand to be a constant expression.  */
 static void
-gen_repeat (union exp_element **pc, struct agent_expr *ax,
-           struct axs_value *value)
+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 (pc, ax, &value1);
+  gen_expr (exp, pc, ax, &value1);
   if (value1.kind != axs_lvalue_memory)
-    error ("Left operand of `@' must be an object in memory.");
+    error (_("Left operand of `@' must be an object in memory."));
 
   /* Evaluate the length; it had better be a constant.  */
   {
@@ -1410,21 +1382,20 @@ gen_repeat (union exp_element **pc, struct agent_expr *ax,
     int length;
 
     if (!v)
-      error ("Right operand of `@' must be a constant, in agent expressions.");
-    if (TYPE_CODE (v->type) != TYPE_CODE_INT)
-      error ("Right operand of `@' must be an integer.");
+      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);
     if (length <= 0)
-      error ("Right operand of `@' must be positive.");
+      error (_("Right operand of `@' must be positive."));
 
     /* The top of the stack is already the address of the object, so
        all we need to do is frob the type of the lvalue.  */
     {
       /* FIXME-type-allocation: need a way to free this type when we are
          done with it.  */
-      struct type *range
-      = create_range_type (0, builtin_type_int, 0, length - 1);
-      struct type *array = create_array_type (0, value1.type, range);
+      struct type *array
+       = lookup_array_range_type (value1.type, 0, length - 1);
 
       value->kind = axs_lvalue_memory;
       value->type = array;
@@ -1437,8 +1408,9 @@ gen_repeat (union exp_element **pc, struct agent_expr *ax,
    *PC should point at the start of the operand expression; we advance it
    to the first instruction after the operand.  */
 static void
-gen_sizeof (union exp_element **pc, struct agent_expr *ax,
-           struct axs_value *value)
+gen_sizeof (struct expression *exp, union exp_element **pc,
+           struct agent_expr *ax, struct axs_value *value,
+           struct type *size_type)
 {
   /* We don't care about the value of the operand expression; we only
      care about its type.  However, in the current arrangement, the
@@ -1446,24 +1418,25 @@ gen_sizeof (union exp_element **pc, struct agent_expr *ax,
      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 (pc, ax, value);
+  gen_expr (exp, pc, ax, value);
 
   /* Throw away the code we just generated.  */
   ax->len = start;
 
   ax_const_l (ax, TYPE_LENGTH (value->type));
   value->kind = axs_rvalue;
-  value->type = builtin_type_int;
+  value->type = size_type;
 }
 \f
 
 /* 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
-gen_expr (union exp_element **pc, struct agent_expr *ax,
-         struct axs_value *value)
+gen_expr (struct expression *exp, union exp_element **pc,
+         struct agent_expr *ax, struct axs_value *value)
 {
   /* Used to hold the descriptions of operand expressions.  */
   struct axs_value value1, value2;
@@ -1477,7 +1450,7 @@ gen_expr (union exp_element **pc, struct agent_expr *ax,
       {
        ax_const_l (ax, value_as_long (v));
        value->kind = axs_rvalue;
-       value->type = check_typedef (VALUE_TYPE (v));
+       value->type = check_typedef (value_type (v));
        return;
       }
   }
@@ -1495,19 +1468,47 @@ gen_expr (union exp_element **pc, struct agent_expr *ax,
     case BINOP_BITWISE_AND:
     case BINOP_BITWISE_IOR:
     case BINOP_BITWISE_XOR:
+    case BINOP_EQUAL:
+    case BINOP_NOTEQUAL:
+    case BINOP_LESS:
+    case BINOP_GTR:
+    case BINOP_LEQ:
+    case BINOP_GEQ:
       (*pc)++;
-      gen_expr (pc, ax, &value1);
-      gen_usual_unary (ax, &value1);
-      gen_expr (pc, ax, &value2);
-      gen_usual_unary (ax, &value2);
-      gen_usual_arithmetic (ax, &value1, &value2);
+      gen_expr (exp, pc, ax, &value1);
+      gen_usual_unary (exp, ax, &value1);
+      gen_expr (exp, pc, ax, &value2);
+      gen_usual_unary (exp, ax, &value2);
+      gen_usual_arithmetic (exp, ax, &value1, &value2);
       switch (op)
        {
        case BINOP_ADD:
-         gen_add (ax, value, &value1, &value2, "addition");
+         if (TYPE_CODE (value1.type) == TYPE_CODE_INT
+             && TYPE_CODE (value2.type) == TYPE_CODE_PTR)
+           {
+             /* Swap the values and proceed normally.  */
+             ax_simple (ax, aop_swap);
+             gen_ptradd (ax, value, &value2, &value1);
+           }
+         else if (TYPE_CODE (value1.type) == TYPE_CODE_PTR
+                  && TYPE_CODE (value2.type) == TYPE_CODE_INT)
+           gen_ptradd (ax, value, &value1, &value2);
+         else
+           gen_binop (ax, value, &value1, &value2,
+                      aop_add, aop_add, 1, "addition");
          break;
        case BINOP_SUB:
-         gen_sub (ax, value, &value1, &value2);
+         if (TYPE_CODE (value1.type) == TYPE_CODE_PTR
+             && TYPE_CODE (value2.type) == TYPE_CODE_INT)
+           gen_ptrsub (ax,value, &value1, &value2);
+         else if (TYPE_CODE (value1.type) == TYPE_CODE_PTR
+                  && TYPE_CODE (value2.type) == TYPE_CODE_PTR)
+           /* FIXME --- result type should be ptrdiff_t */
+           gen_ptrdiff (ax, value, &value1, &value2,
+                        builtin_type (exp->gdbarch)->builtin_long);
+         else
+           gen_binop (ax, value, &value1, &value2,
+                      aop_sub, aop_sub, 1, "subtraction");
          break;
        case BINOP_MUL:
          gen_binop (ax, value, &value1, &value2,
@@ -1522,9 +1523,9 @@ gen_expr (union exp_element **pc, struct agent_expr *ax,
                     aop_rem_signed, aop_rem_unsigned, 1, "remainder");
          break;
        case BINOP_SUBSCRIPT:
-         gen_add (ax, value, &value1, &value2, "array subscripting");
+         gen_ptradd (ax, value, &value1, &value2);
          if (TYPE_CODE (value->type) != TYPE_CODE_PTR)
-           error ("Illegal combination of types in array subscripting.");
+           error (_("Invalid combination of types in array subscripting."));
          gen_deref (ax, value);
          break;
        case BINOP_BITWISE_AND:
@@ -1542,11 +1543,52 @@ gen_expr (union exp_element **pc, struct agent_expr *ax,
                     aop_bit_xor, aop_bit_xor, 0, "bitwise exclusive-or");
          break;
 
+       case BINOP_EQUAL:
+         gen_binop (ax, value, &value1, &value2,
+                    aop_equal, aop_equal, 0, "equal");
+         break;
+
+       case BINOP_NOTEQUAL:
+         gen_binop (ax, value, &value1, &value2,
+                    aop_equal, aop_equal, 0, "equal");
+         gen_logical_not (ax, value,
+                          language_bool_type (exp->language_defn,
+                                              exp->gdbarch));
+         break;
+
+       case BINOP_LESS:
+         gen_binop (ax, value, &value1, &value2,
+                    aop_less_signed, aop_less_unsigned, 0, "less than");
+         break;
+
+       case BINOP_GTR:
+         ax_simple (ax, aop_swap);
+         gen_binop (ax, value, &value1, &value2,
+                    aop_less_signed, aop_less_unsigned, 0, "less than");
+         break;
+
+       case BINOP_LEQ:
+         ax_simple (ax, aop_swap);
+         gen_binop (ax, value, &value1, &value2,
+                    aop_less_signed, aop_less_unsigned, 0, "less than");
+         gen_logical_not (ax, value,
+                          language_bool_type (exp->language_defn,
+                                              exp->gdbarch));
+         break;
+
+       case BINOP_GEQ:
+         gen_binop (ax, value, &value1, &value2,
+                    aop_less_signed, aop_less_unsigned, 0, "less than");
+         gen_logical_not (ax, value,
+                          language_bool_type (exp->language_defn,
+                                              exp->gdbarch));
+         break;
+
        default:
          /* We should only list operators in the outer case statement
             that we actually handle in the inner case statement.  */
          internal_error (__FILE__, __LINE__,
-                         "gen_expr: op case sets don't match");
+                         _("gen_expr: op case sets don't match"));
        }
       break;
 
@@ -1558,12 +1600,12 @@ gen_expr (union exp_element **pc, struct agent_expr *ax,
          variables it mentions get traced.  */
     case BINOP_COMMA:
       (*pc)++;
-      gen_expr (pc, ax, &value1);
+      gen_expr (exp, pc, ax, &value1);
       /* 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 (ax, &value1);
-      gen_expr (pc, ax, value);
+      gen_expr (exp, pc, ax, value);
       /* It's the consumer's responsibility to trace the right operand.  */
       break;
 
@@ -1577,35 +1619,44 @@ gen_expr (union exp_element **pc, struct agent_expr *ax,
       break;
 
     case OP_VAR_VALUE:
-      gen_var_ref (ax, value, (*pc)[2].symbol);
+      gen_var_ref (exp->gdbarch, ax, value, (*pc)[2].symbol);
       (*pc) += 4;
       break;
 
     case OP_REGISTER:
       {
-       int reg = (int) (*pc)[1].longconst;
-       (*pc) += 3;
+       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));
+       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."),
+                name);
        value->kind = axs_lvalue_register;
        value->u.reg = reg;
-       value->type = REGISTER_VIRTUAL_TYPE (reg);
+       value->type = register_type (exp->gdbarch, reg);
       }
       break;
 
     case OP_INTERNALVAR:
-      error ("GDB agent expressions cannot use convenience variables.");
+      error (_("GDB agent expressions cannot use convenience variables."));
 
       /* Weirdo operator: see comments for gen_repeat for details.  */
     case BINOP_REPEAT:
       /* Note that gen_repeat handles its own argument evaluation.  */
       (*pc)++;
-      gen_repeat (pc, ax, value);
+      gen_repeat (exp, pc, ax, value);
       break;
 
     case UNOP_CAST:
       {
        struct type *type = (*pc)[1].type;
        (*pc) += 3;
-       gen_expr (pc, ax, value);
+       gen_expr (exp, pc, ax, value);
        gen_cast (ax, value, type);
       }
       break;
@@ -1614,7 +1665,7 @@ gen_expr (union exp_element **pc, struct agent_expr *ax,
       {
        struct type *type = check_typedef ((*pc)[1].type);
        (*pc) += 3;
-       gen_expr (pc, ax, value);
+       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
@@ -1622,47 +1673,59 @@ gen_expr (union exp_element **pc, struct agent_expr *ax,
        if (value->kind != axs_rvalue)
          /* This would be weird.  */
          internal_error (__FILE__, __LINE__,
-                         "gen_expr: OP_MEMVAL operand isn't an rvalue???");
+                         _("gen_expr: OP_MEMVAL operand isn't an rvalue???"));
        value->type = type;
        value->kind = axs_lvalue_memory;
       }
       break;
 
+    case UNOP_PLUS:
+      (*pc)++;
+      /* + FOO is equivalent to 0 + FOO, which can be optimized. */
+      gen_expr (exp, pc, ax, value);
+      gen_usual_unary (exp, ax, value);
+      break;
+      
     case UNOP_NEG:
       (*pc)++;
       /* -FOO is equivalent to 0 - FOO.  */
-      gen_int_literal (ax, &value1, (LONGEST) 0, builtin_type_int);
-      gen_usual_unary (ax, &value1);   /* shouldn't do much */
-      gen_expr (pc, ax, &value2);
-      gen_usual_unary (ax, &value2);
-      gen_usual_arithmetic (ax, &value1, &value2);
-      gen_sub (ax, value, &value1, &value2);
+      gen_int_literal (ax, &value1, 0,
+                      builtin_type (exp->gdbarch)->builtin_int);
+      gen_usual_unary (exp, 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_binop (ax, value, &value1, &value2, aop_sub, aop_sub, 1, "negation");
       break;
 
     case UNOP_LOGICAL_NOT:
       (*pc)++;
-      gen_expr (pc, ax, value);
-      gen_logical_not (ax, value);
+      gen_expr (exp, pc, ax, value);
+      gen_usual_unary (exp, ax, value);
+      gen_logical_not (ax, value,
+                      language_bool_type (exp->language_defn, exp->gdbarch));
       break;
 
     case UNOP_COMPLEMENT:
       (*pc)++;
-      gen_expr (pc, ax, value);
+      gen_expr (exp, pc, ax, value);
+      gen_usual_unary (exp, ax, value);
+      gen_integral_promotions (exp, ax, value);
       gen_complement (ax, value);
       break;
 
     case UNOP_IND:
       (*pc)++;
-      gen_expr (pc, ax, value);
-      gen_usual_unary (ax, value);
+      gen_expr (exp, pc, ax, value);
+      gen_usual_unary (exp, ax, value);
       if (TYPE_CODE (value->type) != TYPE_CODE_PTR)
-       error ("Argument of unary `*' is not a pointer.");
+       error (_("Argument of unary `*' is not a pointer."));
       gen_deref (ax, value);
       break;
 
     case UNOP_ADDR:
       (*pc)++;
-      gen_expr (pc, ax, value);
+      gen_expr (exp, pc, ax, value);
       gen_address_of (ax, value);
       break;
 
@@ -1671,7 +1734,8 @@ gen_expr (union exp_element **pc, struct agent_expr *ax,
       /* Notice that gen_sizeof handles its own operand, unlike most
          of the other unary operator functions.  This is because we
          have to throw away the code we generate.  */
-      gen_sizeof (pc, ax, value);
+      gen_sizeof (exp, pc, ax, value,
+                 builtin_type (exp->gdbarch)->builtin_int);
       break;
 
     case STRUCTOP_STRUCT:
@@ -1681,47 +1745,51 @@ gen_expr (union exp_element **pc, struct agent_expr *ax,
        char *name = &(*pc)[2].string;
 
        (*pc) += 4 + BYTES_TO_EXP_ELEM (length + 1);
-       gen_expr (pc, ax, value);
+       gen_expr (exp, pc, ax, value);
        if (op == STRUCTOP_STRUCT)
-         gen_struct_ref (ax, value, name, ".", "structure or union");
+         gen_struct_ref (exp, ax, value, name, ".", "structure or union");
        else if (op == STRUCTOP_PTR)
-         gen_struct_ref (ax, value, name, "->",
+         gen_struct_ref (exp, ax, value, name, "->",
                          "pointer to a structure or union");
        else
          /* If this `if' chain doesn't handle it, then the case list
             shouldn't mention it, and we shouldn't be here.  */
          internal_error (__FILE__, __LINE__,
-                         "gen_expr: unhandled struct case");
+                         _("gen_expr: unhandled struct case"));
       }
       break;
 
     case OP_TYPE:
-      error ("Attempt to use a type name as an expression.");
+      error (_("Attempt to use a type name as an expression."));
 
     default:
-      error ("Unsupported operator in expression.");
+      error (_("Unsupported operator in expression."));
     }
 }
 \f
 
+/* Given a single variable and a scope, generate bytecodes to trace
+   its value.  This is for use in situations where we have only a
+   variable's name, and no parsed expression; for instance, when the
+   name comes from a list of local variables of a function.  */
 
-/* Generating bytecode from GDB expressions: driver */
-
-/* Given a GDB expression EXPR, produce a string of agent bytecode
-   which computes its value.  Return the agent expression, and set
-   *VALUE to describe its type, and whether it's an lvalue or rvalue.  */
 struct agent_expr *
-expr_to_agent (struct expression *expr, struct axs_value *value)
+gen_trace_for_var (CORE_ADDR scope, struct symbol *var)
 {
   struct cleanup *old_chain = 0;
-  struct agent_expr *ax = new_agent_expr (0);
-  union exp_element *pc;
+  struct agent_expr *ax = new_agent_expr (scope);
+  struct axs_value value;
 
   old_chain = make_cleanup_free_agent_expr (ax);
 
-  pc = expr->elts;
-  trace_kludge = 0;
-  gen_expr (&pc, ax, value);
+  trace_kludge = 1;
+  gen_var_ref (NULL, ax, &value, var);
+
+  /* Make sure we record the final object, and get rid of it.  */
+  gen_traced_pop (ax, &value);
+
+  /* Oh, 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
@@ -1730,32 +1798,7 @@ expr_to_agent (struct expression *expr, struct axs_value *value)
   return ax;
 }
 
-
-#if 0                          /* not used */
-/* Given a GDB expression EXPR denoting an lvalue in memory, produce a
-   string of agent bytecode which will leave its address and size on
-   the top of stack.  Return the agent expression.
-
-   Not sure this function is useful at all.  */
-struct agent_expr *
-expr_to_address_and_size (struct expression *expr)
-{
-  struct axs_value value;
-  struct agent_expr *ax = expr_to_agent (expr, &value);
-
-  /* Complain if the result is not a memory lvalue.  */
-  if (value.kind != axs_lvalue_memory)
-    {
-      free_agent_expr (ax);
-      error ("Expression does not denote an object in memory.");
-    }
-
-  /* Push the object's size on the stack.  */
-  ax_const_l (ax, TYPE_LENGTH (value.type));
-
-  return ax;
-}
-#endif
+/* Generating bytecode from GDB expressions: driver */
 
 /* Given a GDB expression EXPR, return bytecode to trace its value.
    The result will use the `trace' and `trace_quick' bytecodes to
@@ -1774,7 +1817,7 @@ gen_trace_for_expr (CORE_ADDR scope, struct expression *expr)
 
   pc = expr->elts;
   trace_kludge = 1;
-  gen_expr (&pc, ax, &value);
+  gen_expr (expr, &pc, ax, &value);
 
   /* Make sure we record the final object, and get rid of it.  */
   gen_traced_pop (ax, &value);
@@ -1788,36 +1831,75 @@ gen_trace_for_expr (CORE_ADDR scope, struct expression *expr)
   discard_cleanups (old_chain);
   return ax;
 }
-\f
 
+/* Given a GDB expression EXPR, return a bytecode sequence that will
+   evaluate and return a result.  The bytecodes will do a direct
+   evaluation, using the current data on the target, rather than
+   recording blocks of memory and registers for later use, as
+   gen_trace_for_expr does.  The generated bytecode sequence leaves
+   the result of expression evaluation on the top of the stack.  */
 
-/* The "agent" command, for testing: compile and disassemble an expression.  */
+struct agent_expr *
+gen_eval_for_expr (CORE_ADDR scope, struct expression *expr)
+{
+  struct cleanup *old_chain = 0;
+  struct agent_expr *ax = new_agent_expr (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);
+
+  /* Oh, 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);
+  return ax;
+}
 
 static void
-print_axs_value (struct ui_file *f, struct axs_value *value)
+agent_command (char *exp, int from_tty)
 {
-  switch (value->kind)
-    {
-    case axs_rvalue:
-      fputs_filtered ("rvalue", f);
-      break;
+  struct cleanup *old_chain = 0;
+  struct expression *expr;
+  struct agent_expr *agent;
+  struct frame_info *fi = get_current_frame ();        /* need current scope */
 
-    case axs_lvalue_memory:
-      fputs_filtered ("memory lvalue", f);
-      break;
+  /* 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
+     have to know anything about agent expressions.  */
+  if (overlay_debugging)
+    error (_("GDB can't do agent expression translation with overlays."));
 
-    case axs_lvalue_register:
-      fprintf_filtered (f, "register %d lvalue", value->u.reg);
-      break;
-    }
+  if (exp == 0)
+    error_no_arg (_("expression to translate"));
 
-  fputs_filtered (" : ", f);
-  type_print (value->type, "", f, -1);
+  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.  */
+
+  do_cleanups (old_chain);
+  dont_repeat ();
 }
 
+/* Parse the given expression, compile it into an agent expression
+   that does direct evaluation, and display the resulting
+   expression.  */
 
 static void
-agent_command (char *exp, int from_tty)
+agent_eval_command (char *exp, int from_tty)
 {
   struct cleanup *old_chain = 0;
   struct expression *expr;
@@ -1829,14 +1911,14 @@ agent_command (char *exp, int from_tty)
      another command, change the error message; the user shouldn't
      have to know anything about agent expressions.  */
   if (overlay_debugging)
-    error ("GDB can't do agent expression translation with overlays.");
+    error (_("GDB can't do agent expression translation with overlays."));
 
   if (exp == 0)
-    error_no_arg ("expression to translate");
+    error_no_arg (_("expression to translate"));
 
   expr = parse_expression (exp);
   old_chain = make_cleanup (free_current_contents, &expr);
-  agent = gen_trace_for_expr (fi->pc, expr);
+  agent = gen_eval_for_expr (get_frame_pc (fi), expr);
   make_cleanup_free_agent_expr (agent);
   ax_print (gdb_stdout, agent);
 
@@ -1855,6 +1937,10 @@ void
 _initialize_ax_gdb (void)
 {
   add_cmd ("agent", class_maintenance, agent_command,
-          "Translate an expression into remote agent bytecode.",
+          _("Translate an expression into remote agent bytecode for tracing."),
+          &maintenancelist);
+
+  add_cmd ("agent-eval", class_maintenance, agent_eval_command,
+          _("Translate an expression into remote agent bytecode for evaluation."),
           &maintenancelist);
 }
This page took 0.041112 seconds and 4 git commands to generate.