This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Handle logical connectives in agent expressions


This fills another gap in agent expressions - &&, ||, and ?: .

Stan

2009-12-29 Stan Shebs <stan@codesourcery.com>

   * ax-gdb.c (gen_expr): Handle logical and, logical or, and
   conditional expressions.

Index: ax-gdb.c
===================================================================
RCS file: /cvs/src/src/gdb/ax-gdb.c,v
retrieving revision 1.57
diff -p -r1.57 ax-gdb.c
*** ax-gdb.c    28 Dec 2009 23:39:08 -0000    1.57
--- ax-gdb.c    29 Dec 2009 19:02:03 -0000
*************** gen_expr (struct expression *exp, union
*** 1447,1454 ****
       struct agent_expr *ax, struct axs_value *value)
 {
   /* Used to hold the descriptions of operand expressions.  */
!   struct axs_value value1, value2;
   enum exp_opcode op = (*pc)[0].opcode, op2;

   /* If we're looking at a constant expression, just push its value.  */
   {
--- 1447,1455 ----
       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;

   /* If we're looking at a constant expression, just push its value.  */
   {
*************** gen_expr (struct expression *exp, union
*** 1488,1493 ****
--- 1489,1559 ----
       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 (exp, 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);
+       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 = language_bool_type (exp->language_defn, exp->gdbarch);
+       break;
+
+     case BINOP_LOGICAL_OR:
+       (*pc)++;
+       /* Generate the obvious sequence of tests and jumps.  */
+       gen_expr (exp, pc, ax, &value1);
+       gen_usual_unary (exp, ax, &value1);
+       if1 = ax_goto (ax, aop_if_goto);
+       gen_expr (exp, pc, ax, &value2);
+       gen_usual_unary (exp, 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 = language_bool_type (exp->language_defn, exp->gdbarch);
+       break;
+
+     case TERNOP_COND:
+       (*pc)++;
+       gen_expr (exp, pc, ax, &value1);
+       gen_usual_unary (exp, 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,
+                language_bool_type (exp->language_defn, exp->gdbarch));
+       if1 = ax_goto (ax, aop_if_goto);
+       gen_expr (exp, pc, ax, &value2);
+       gen_usual_unary (exp, 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);
+       ax_label (ax, end, ax->len);
+       /* This is arbitary - 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)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]