diff options
author | Stan Shebs <shebs@codesourcery.com> | 2009-12-29 23:21:38 +0000 |
---|---|---|
committer | Stan Shebs <shebs@codesourcery.com> | 2009-12-29 23:21:38 +0000 |
commit | 09d559e4e07c6f766fafbfddbf9212e9d9e7b777 (patch) | |
tree | 8571761aba5e9b39be1072ad38c8b953368f08df /gdb/ax-gdb.c | |
parent | 3dcad3765dd25e9f675683cd720524899930abfc (diff) | |
download | gdb-09d559e4e07c6f766fafbfddbf9212e9d9e7b777.zip gdb-09d559e4e07c6f766fafbfddbf9212e9d9e7b777.tar.gz gdb-09d559e4e07c6f766fafbfddbf9212e9d9e7b777.tar.bz2 |
* ax-gdb.c (gen_expr): Handle logical and, logical or, and
conditional expressions.
Diffstat (limited to 'gdb/ax-gdb.c')
-rw-r--r-- | gdb/ax-gdb.c | 68 |
1 files changed, 67 insertions, 1 deletions
diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c index ee1f515..34e8128 100644 --- a/gdb/ax-gdb.c +++ b/gdb/ax-gdb.c @@ -1447,8 +1447,9 @@ 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; + 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. */ { @@ -1488,6 +1489,71 @@ gen_expr (struct expression *exp, union exp_element **pc, 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) |