Automatic date update in version.in
[deliverable/binutils-gdb.git] / gdb / ax-gdb.c
index f81e5b9ad29ad9b1d5b9e7af041e2a779d0d1b73..009c128c83c11e83405eb3c7137e58d8f2b46efe 100644 (file)
 /* Prototypes for local functions.  */
 
 /* There's a standard order to the arguments of these functions:
-   union exp_element ** --- pointer into expression
    struct agent_expr * --- agent expression buffer to generate code into
    struct axs_value * --- describes value left on top of stack  */
 
-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 agent_expr *, struct axs_value *);
 
 static void gen_sign_extend (struct agent_expr *, struct type *);
@@ -148,123 +143,13 @@ static void gen_struct_ref (struct agent_expr *ax,
                            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_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 gen_expr_binop_rest (struct expression *exp,
                                 enum exp_opcode op,
                                 struct agent_expr *ax,
                                 struct axs_value *value,
                                 struct axs_value *value1,
                                 struct axs_value *value2);
-\f
-
-/* Detecting constant expressions.  */
-
-/* If the variable reference at *PC is a constant, return its value.
-   Otherwise, return zero.
-
-   Hey, Wally!  How can a variable reference be a constant?
-
-   Well, Beav, this function really handles the OP_VAR_VALUE operator,
-   not specifically variable references.  GDB uses OP_VAR_VALUE to
-   refer to any kind of symbolic reference: function names, enum
-   elements, and goto labels are all handled through the OP_VAR_VALUE
-   operator, even though they're constants.  It makes sense given the
-   situation.
-
-   Gee, Wally, don'cha wonder sometimes if data representations that
-   subvert commonly accepted definitions of terms in favor of heavily
-   context-specific interpretations are really just a tool of the
-   programming hegemony to preserve their power and exclude the
-   proletariat?  */
-
-static struct value *
-const_var_ref (struct symbol *var)
-{
-  struct type *type = SYMBOL_TYPE (var);
-
-  switch (SYMBOL_CLASS (var))
-    {
-    case LOC_CONST:
-      return value_from_longest (type, (LONGEST) SYMBOL_VALUE (var));
-
-    case LOC_LABEL:
-      return value_from_pointer (type, (CORE_ADDR) SYMBOL_VALUE_ADDRESS (var));
-
-    default:
-      return 0;
-    }
-}
-
-
-/* If the expression starting at *PC has a constant value, return it.
-   Otherwise, return zero.  If we return a value, then *PC will be
-   advanced to the end of it.  If we return zero, *PC could be
-   anywhere.  */
-static struct value *
-const_expr (union exp_element **pc)
-{
-  enum exp_opcode op = (*pc)->opcode;
-  struct value *v1;
-
-  switch (op)
-    {
-    case OP_LONG:
-      {
-       struct type *type = (*pc)[1].type;
-       LONGEST k = (*pc)[2].longconst;
-
-       (*pc) += 4;
-       return value_from_longest (type, k);
-      }
-
-    case OP_VAR_VALUE:
-      {
-       struct value *v = const_var_ref ((*pc)[2].symbol);
-
-       (*pc) += 4;
-       return v;
-      }
-
-      /* We could add more operators in here.  */
-
-    case UNOP_NEG:
-      (*pc)++;
-      v1 = const_expr (pc);
-      if (v1)
-       return value_neg (v1);
-      else
-       return 0;
-
-    default:
-      return 0;
-    }
-}
-
-
-/* Like const_expr, but guarantee also that *PC is undisturbed if the
-   expression is not constant.  */
-static struct value *
-maybe_const_expr (union exp_element **pc)
-{
-  union exp_element *tentative_pc = *pc;
-  struct value *v = const_expr (&tentative_pc);
 
-  /* If we got a value, then update the real PC.  */
-  if (v)
-    *pc = tentative_pc;
-
-  return v;
-}
 \f
 
 /* Generating bytecode from GDB expressions: general assumptions */
@@ -1691,592 +1576,8 @@ gen_aggregate_elt_ref (struct agent_expr *ax, struct axs_value *value,
   return 0;
 }
 
-/* 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
-   of command-line arguments.
-
-   Unfortunately, because we have to know the types before we actually
-   have a value for the expression, we can't implement this perfectly
-   without changing the type system, having values that occupy two
-   stack slots, doing weird things with sizeof, etc.  So we require
-   the right operand to be a constant expression.  */
-static void
-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);
-  if (value1.kind != axs_lvalue_memory)
-    error (_("Left operand of `@' must be an object in memory."));
-
-  /* Evaluate the length; it had better be a constant.  */
-  {
-    struct value *v = const_expr (pc);
-    int length;
-
-    if (!v)
-      error (_("Right operand of `@' must be a "
-              "constant, in agent expressions."));
-    if (value_type (v)->code () != 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."));
-
-    /* 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 *array
-       = lookup_array_range_type (value1.type, 0, length - 1);
-
-      value->kind = axs_lvalue_memory;
-      value->type = array;
-    }
-  }
-}
-
-
-/* Emit code for the `sizeof' operator.
-   *PC should point at the start of the operand expression; we advance it
-   to the first instruction after the operand.  */
-static void
-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
-     only way to find an expression's type is to generate code for it.
-     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.  */
-  ax->len = start;
-
-  ax_const_l (ax, TYPE_LENGTH (value->type));
-  value->kind = axs_rvalue;
-  value->type = size_type;
-}
 \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 (value->type->code () == TYPE_CODE_ERROR)
-       value->type = to_type;
-      (*pc) += 4;
-    }
-  else
-    gen_expr (exp, pc, ax, value);
-  gen_cast (ax, value, to_type);
-}
-
-/* Generating bytecode from GDB expressions: general recursive thingy  */
-
-/* XXX: i18n */
-/* A gen_expr function written by a Gen-X'er guy.
-   Append code for the subexpression of EXPR starting at *POS_P to AX.  */
-void
-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, value3;
-  enum exp_opcode op = (*pc)[0].opcode, op2;
-  int if1, go1, if2, go2, end;
-  struct type *int_type = builtin_type (ax->gdbarch)->builtin_int;
-
-  /* If we're looking at a constant expression, just push its value.  */
-  {
-    struct value *v = maybe_const_expr (pc);
-
-    if (v)
-      {
-       ax_const_l (ax, value_as_long (v));
-       value->kind = axs_rvalue;
-       value->type = check_typedef (value_type (v));
-       return;
-      }
-  }
-
-  /* Otherwise, go ahead and generate code for it.  */
-  switch (op)
-    {
-      /* Binary arithmetic operators.  */
-    case BINOP_ADD:
-    case BINOP_SUB:
-    case BINOP_MUL:
-    case BINOP_DIV:
-    case BINOP_REM:
-    case BINOP_LSH:
-    case BINOP_RSH:
-    case BINOP_SUBSCRIPT:
-    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 (exp, pc, ax, &value1);
-      gen_usual_unary (ax, &value1);
-      gen_expr_binop_rest (exp, op, pc, ax, value, &value1, &value2);
-      break;
-
-    case BINOP_LOGICAL_AND:
-      (*pc)++;
-      /* Generate the obvious sequence of tests and jumps.  */
-      gen_expr (exp, pc, 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 (ax, &value2);
-      if2 = ax_goto (ax, aop_if_goto);
-      go2 = ax_goto (ax, aop_goto);
-      ax_label (ax, if2, ax->len);
-      ax_const_l (ax, 1);
-      end = ax_goto (ax, aop_goto);
-      ax_label (ax, go1, ax->len);
-      ax_label (ax, go2, ax->len);
-      ax_const_l (ax, 0);
-      ax_label (ax, end, ax->len);
-      value->kind = axs_rvalue;
-      value->type = int_type;
-      break;
-
-    case BINOP_LOGICAL_OR:
-      (*pc)++;
-      /* Generate the obvious sequence of tests and jumps.  */
-      gen_expr (exp, pc, ax, &value1);
-      gen_usual_unary (ax, &value1);
-      if1 = ax_goto (ax, aop_if_goto);
-      gen_expr (exp, pc, 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);
-      ax_label (ax, if1, ax->len);
-      ax_label (ax, if2, ax->len);
-      ax_const_l (ax, 1);
-      ax_label (ax, end, ax->len);
-      value->kind = axs_rvalue;
-      value->type = int_type;
-      break;
-
-    case TERNOP_COND:
-      (*pc)++;
-      gen_expr (exp, pc, 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
-        jump to do C.  */
-      gen_logical_not (ax, &value1, int_type);
-      if1 = ax_goto (ax, aop_if_goto);
-      gen_expr (exp, pc, 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 (ax, &value3);
-      ax_label (ax, end, ax->len);
-      /* This is arbitrary - what if B and C are incompatible types? */
-      value->type = value2.type;
-      value->kind = value2.kind;
-      break;
-
-    case BINOP_ASSIGN:
-      (*pc)++;
-      if ((*pc)[0].opcode == OP_INTERNALVAR)
-       {
-         const 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 (ax->tracing)
-               ax_tsv (ax, aop_tracev, tsv->number);
-           }
-         else
-           error (_("$%s is not a trace state variable, "
-                    "may not assign to it"), name);
-       }
-      else
-       error (_("May only assign to trace state variables"));
-      break;
-
-    case BINOP_ASSIGN_MODIFY:
-      (*pc)++;
-      op2 = (*pc)[0].opcode;
-      (*pc)++;
-      (*pc)++;
-      if ((*pc)[0].opcode == OP_INTERNALVAR)
-       {
-         const 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 (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 (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 (ax->tracing)
-               ax_tsv (ax, aop_tracev, tsv->number);
-           }
-         else
-           error (_("$%s is not a trace state variable, "
-                    "may not assign to it"), name);
-       }
-      else
-       error (_("May only assign to trace state variables"));
-      break;
-
-      /* Note that we need to be a little subtle about generating code
-        for comma.  In C, we can do some optimizations here because
-        we know the left operand is only being evaluated for effect.
-        However, if the tracing kludge is in effect, then we always
-        need to evaluate the left hand side fully, so that all the
-        variables it mentions get traced.  */
-    case BINOP_COMMA:
-      (*pc)++;
-      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 (exp, pc, ax, value);
-      /* It's the consumer's responsibility to trace the right operand.  */
-      break;
-
-    case OP_LONG:              /* some integer constant */
-      {
-       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 (ax, value, (*pc)[2].symbol);
-
-      if (value->optimized_out)
-       error (_("`%s' has been optimized out, cannot use"),
-              (*pc)[2].symbol->print_name ());
-
-      if (value->type->code () == TYPE_CODE_ERROR)
-       error_unknown_type ((*pc)[2].symbol->print_name ());
-
-      (*pc) += 4;
-      break;
-
-    case OP_VAR_MSYM_VALUE:
-      gen_msym_var_ref (ax, value, (*pc)[2].msymbol, (*pc)[1].objfile);
-
-      if (value->type->code () == TYPE_CODE_ERROR)
-       error_unknown_type ((*pc)[2].msymbol->linkage_name ());
-
-      (*pc) += 4;
-      break;
-
-    case OP_REGISTER:
-      {
-       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 (ax->gdbarch, name, strlen (name));
-       if (reg == -1)
-         internal_error (__FILE__, __LINE__,
-                         _("Register $%s not available"), name);
-       /* No support for tracing user registers yet.  */
-       if (reg >= gdbarch_num_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 (ax->gdbarch, reg);
-      }
-      break;
-
-    case OP_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 (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 (ax->gdbarch)->builtin_long_long;
-         }
-       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;
-
-      /* Weirdo operator: see comments for gen_repeat for details.  */
-    case BINOP_REPEAT:
-      /* Note that gen_repeat handles its own argument evaluation.  */
-      (*pc)++;
-      gen_repeat (exp, pc, ax, value);
-      break;
-
-    case UNOP_CAST:
-      {
-       struct type *type = (*pc)[1].type;
-
-       (*pc) += 3;
-       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);
-
-       /* 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;
-      }
-      break;
-
-    case UNOP_PLUS:
-      (*pc)++;
-      /* + FOO is equivalent to 0 + FOO, which can be optimized.  */
-      gen_expr (exp, pc, 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 (ax->gdbarch)->builtin_int);
-      gen_usual_unary (ax, &value1);   /* shouldn't do much */
-      gen_expr (exp, pc, ax, &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 (ax, value);
-      gen_logical_not (ax, value, int_type);
-      break;
-
-    case UNOP_COMPLEMENT:
-      (*pc)++;
-      gen_expr (exp, pc, 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 (ax, value);
-      if (!pointer_type (value->type))
-       error (_("Argument of unary `*' is not a pointer."));
-      gen_deref (value);
-      break;
-
-    case UNOP_ADDR:
-      (*pc)++;
-      gen_expr (exp, pc, ax, value);
-      gen_address_of (value);
-      break;
-
-    case UNOP_SIZEOF:
-      (*pc)++;
-      /* 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 (exp, pc, ax, value,
-                 builtin_type (ax->gdbarch)->builtin_int);
-      break;
-
-    case STRUCTOP_STRUCT:
-    case STRUCTOP_PTR:
-      {
-       int length = (*pc)[1].longconst;
-       const char *name = &(*pc)[2].string;
-
-       (*pc) += 4 + BYTES_TO_EXP_ELEM (length + 1);
-       gen_expr (exp, pc, ax, value);
-       if (op == STRUCTOP_STRUCT)
-         gen_struct_ref (ax, value, name, ".", "structure or union");
-       else if (op == STRUCTOP_PTR)
-         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
-            shouldn't mention it, and we shouldn't be here.  */
-         internal_error (__FILE__, __LINE__,
-                         _("gen_expr: unhandled struct case"));
-      }
-      break;
-
-    case OP_THIS:
-      {
-       struct symbol *sym, *func;
-       const struct block *b;
-       const struct language_defn *lang;
-
-       b = block_for_pc (ax->scope);
-       func = block_linkage_function (b);
-       lang = language_def (func->language ());
-
-       sym = lookup_language_this (lang, b).symbol;
-       if (!sym)
-         error (_("no `%s' found"), lang->name_of_this ());
-
-       gen_var_ref (ax, value, sym);
-
-       if (value->optimized_out)
-         error (_("`%s' has been optimized out, cannot use"),
-                sym->print_name ());
-
-       (*pc) += 2;
-      }
-      break;
-
-    case OP_SCOPE:
-      {
-       struct type *type = (*pc)[1].type;
-       int length = longest_to_int ((*pc)[2].longconst);
-       const char *name = &(*pc)[3].string;
-       int found;
-
-       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);
-      }
-      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_name (op), op);
-    }
-}
-
 namespace expr
 {
 
@@ -2330,13 +1631,13 @@ var_msym_value_operation::do_generate_ax (struct expression *exp,
                                          struct axs_value *value,
                                          struct type *cast_type)
 {
-  gen_msym_var_ref (ax, value, std::get<0> (m_storage),
-                   std::get<1> (m_storage));
+  const bound_minimal_symbol &b = std::get<0> (m_storage);
+  gen_msym_var_ref (ax, value, b.minsym, b.objfile);
 
   if (value->type->code () == TYPE_CODE_ERROR)
     {
       if (cast_type == nullptr)
-       error_unknown_type (std::get<0> (m_storage)->linkage_name ());
+       error_unknown_type (b.minsym->linkage_name ());
       value->type = cast_type;
     }
 }
@@ -2514,6 +1815,16 @@ unop_sizeof_operation::do_generate_ax (struct expression *exp,
   value->type = builtin_type (ax->gdbarch)->builtin_int;
 }
 
+void
+unop_cast_operation::do_generate_ax (struct expression *exp,
+                                    struct agent_expr *ax,
+                                    struct axs_value *value,
+                                    struct type *cast_type)
+{
+  std::get<0> (m_storage)->generate_ax (exp, ax, value,
+                                       std::get<1> (m_storage));
+}
+
 void
 unop_memval_operation::do_generate_ax (struct expression *exp,
                                       struct agent_expr *ax,
@@ -2651,6 +1962,94 @@ assign_modify_operation::do_generate_ax (struct expression *exp,
             "may not assign to it"), name);
 }
 
+void
+unop_cast_type_operation::do_generate_ax (struct expression *exp,
+                                         struct agent_expr *ax,
+                                         struct axs_value *value,
+                                         struct type *cast_type)
+{
+  struct value *val
+    = std::get<0> (m_storage)->evaluate (nullptr, exp,
+                                        EVAL_AVOID_SIDE_EFFECTS);
+  std::get<1> (m_storage)->generate_ax (exp, ax, value, value_type (val));
+}
+
+void
+var_value_operation::do_generate_ax (struct expression *exp,
+                                    struct agent_expr *ax,
+                                    struct axs_value *value,
+                                    struct type *cast_type)
+{
+  gen_var_ref (ax, value, std::get<0> (m_storage).symbol);
+
+  if (value->optimized_out)
+    error (_("`%s' has been optimized out, cannot use"),
+          std::get<0> (m_storage).symbol->print_name ());
+
+  if (value->type->code () == TYPE_CODE_ERROR)
+    {
+      if (cast_type == nullptr)
+       error_unknown_type (std::get<0> (m_storage).symbol->print_name ());
+      value->type = cast_type;
+    }
+}
+
+void
+logical_and_operation::do_generate_ax (struct expression *exp,
+                                      struct agent_expr *ax,
+                                      struct axs_value *value,
+                                      struct type *cast_type)
+{
+  struct axs_value value1, value2;
+  int if1, go1, if2, go2, end;
+
+  /* Generate the obvious sequence of tests and jumps.  */
+  std::get<0> (m_storage)->generate_ax (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);
+  std::get<1> (m_storage)->generate_ax (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);
+  ax_const_l (ax, 1);
+  end = ax_goto (ax, aop_goto);
+  ax_label (ax, go1, ax->len);
+  ax_label (ax, go2, ax->len);
+  ax_const_l (ax, 0);
+  ax_label (ax, end, ax->len);
+  value->kind = axs_rvalue;
+  value->type = builtin_type (ax->gdbarch)->builtin_int;
+}
+
+void
+logical_or_operation::do_generate_ax (struct expression *exp,
+                                     struct agent_expr *ax,
+                                     struct axs_value *value,
+                                     struct type *cast_type)
+{
+  struct axs_value value1, value2;
+  int if1, if2, end;
+
+  /* Generate the obvious sequence of tests and jumps.  */
+  std::get<0> (m_storage)->generate_ax (exp, ax, &value1);
+  gen_usual_unary (ax, &value1);
+  if1 = ax_goto (ax, aop_if_goto);
+  std::get<1> (m_storage)->generate_ax (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);
+  ax_label (ax, if1, ax->len);
+  ax_label (ax, if2, ax->len);
+  ax_const_l (ax, 1);
+  ax_label (ax, end, ax->len);
+  value->kind = axs_rvalue;
+  value->type = builtin_type (ax->gdbarch)->builtin_int;
+}
+
 }
 
 /* This handles the middle-to-right-side of code generation for binary
@@ -2803,19 +2202,6 @@ gen_expr_binop_rest (struct expression *exp,
     }
 }
 
-/* Variant of gen_expr_binop_rest that first generates the
-   right-hand-side.  */
-
-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)
-{
-  gen_expr (exp, pc, ax, value2);
-  gen_expr_binop_rest (exp, op, ax, value, value1, value2);
-}
-
 /* A helper function that emits a binop based on two operations.  */
 
 void
@@ -2959,14 +2345,12 @@ gen_trace_for_expr (CORE_ADDR scope, struct expression *expr,
                    int trace_string)
 {
   agent_expr_up ax (new agent_expr (expr->gdbarch, scope));
-  union exp_element *pc;
   struct axs_value value;
 
-  pc = expr->elts;
   ax->tracing = 1;
   ax->trace_string = trace_string;
   value.optimized_out = 0;
-  gen_expr (expr, &pc, ax.get (), &value);
+  expr->op->generate_ax (expr, ax.get (), &value);
 
   /* Make sure we record the final object, and get rid of it.  */
   gen_traced_pop (ax.get (), &value);
@@ -2988,13 +2372,11 @@ agent_expr_up
 gen_eval_for_expr (CORE_ADDR scope, struct expression *expr)
 {
   agent_expr_up ax (new agent_expr (expr->gdbarch, scope));
-  union exp_element *pc;
   struct axs_value value;
 
-  pc = expr->elts;
   ax->tracing = 0;
   value.optimized_out = 0;
-  gen_expr (expr, &pc, ax.get (), &value);
+  expr->op->generate_ax (expr, ax.get (), &value);
 
   require_rvalue (ax.get (), &value);
 
@@ -3036,7 +2418,6 @@ gen_printf (CORE_ADDR scope, struct gdbarch *gdbarch,
            int nargs, struct expression **exprs)
 {
   agent_expr_up ax (new agent_expr (gdbarch, scope));
-  union exp_element *pc;
   struct axs_value value;
   int tem;
 
@@ -3047,9 +2428,8 @@ gen_printf (CORE_ADDR scope, struct gdbarch *gdbarch,
      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);
+      exprs[tem]->op->generate_ax (exprs[tem], ax.get (), &value);
       require_rvalue (ax.get (), &value);
     }
 
This page took 0.052916 seconds and 4 git commands to generate.