* ax-gdb.c (gen_expr): Handle UNOP_CAST_TYPE, UNOP_MEMVAL_TYPE.
authorTom Tromey <tromey@redhat.com>
Thu, 19 Jul 2012 15:33:25 +0000 (15:33 +0000)
committerTom Tromey <tromey@redhat.com>
Thu, 19 Jul 2012 15:33:25 +0000 (15:33 +0000)
* breakpoint.c (watchpoint_exp_is_const): Handle UNOP_CAST_TYPE,
UNOP_REINTERPRET_CAST, UNOP_DYNAMIC_CAST.
* c-exp.y (exp): Emit UNOP_MEMVAL_TYPE, UNOP_CAST_TYPE.  Update
for changes to UNOP_REINTERPRET_CAST, UNOP_DYNAMIC_CAST.  Use
type_exp production where appropriate.
* eval.c (evaluate_subexp_standard) <UNOP_CAST_TYPE>: New case.
<UNOP_DYNAMIC_CAST, UNOP_REINTERPRET_CAST>: Update.
<UNOP_MEMVAL_TYPE>: New case.
(evaluate_subexp_for_address) <UNOP_MEMVAL_TYPE>: New case.
(evaluate_subexp_for_sizeof) <UNOP_MEMVAL_TYPE>: New case.
* expprint.c (print_subexp_standard) <UNOP_CAST_TYPE>: New case.
<UNOP_MEMVAL_TYPE>: New case.
(dump_subexp_body_standard) <UNOP_DYNAMIC_CAST,
UNOP_REINTERPRET_CAST>: Update.
<UNOP_CAST_TYPE, UNOP_MEMVAL_TYPE>: New cases.
* parse.c (operator_length_standard) <UNOP_DYNAMIC_CAST,
UNOP_REINTERPRET_CAST>: Update.
<UNOP_CAST_TYPE, UNOP_MEMVAL_TYPE>: New cases.
* stack.c (return_command): Also check for UNOP_CAST_TYPE.
* std-operator.def (UNOP_CAST_TYPE, UNOP_MEMVAL_TYPE): New
constants.

gdb/ChangeLog
gdb/ax-gdb.c
gdb/breakpoint.c
gdb/c-exp.y
gdb/eval.c
gdb/expprint.c
gdb/parse.c
gdb/stack.c
gdb/std-operator.def

index ffaeb2209d74bffcfed903777b0a8a7f9fbce830..7fa978016163fab6193c55fbab1437603d5542d2 100644 (file)
@@ -1,3 +1,28 @@
+2012-07-19  Tom Tromey  <tromey@redhat.com>
+
+       * ax-gdb.c (gen_expr): Handle UNOP_CAST_TYPE, UNOP_MEMVAL_TYPE.
+       * breakpoint.c (watchpoint_exp_is_const): Handle UNOP_CAST_TYPE,
+       UNOP_REINTERPRET_CAST, UNOP_DYNAMIC_CAST.
+       * c-exp.y (exp): Emit UNOP_MEMVAL_TYPE, UNOP_CAST_TYPE.  Update
+       for changes to UNOP_REINTERPRET_CAST, UNOP_DYNAMIC_CAST.  Use
+       type_exp production where appropriate.
+       * eval.c (evaluate_subexp_standard) <UNOP_CAST_TYPE>: New case.
+       <UNOP_DYNAMIC_CAST, UNOP_REINTERPRET_CAST>: Update.
+       <UNOP_MEMVAL_TYPE>: New case.
+       (evaluate_subexp_for_address) <UNOP_MEMVAL_TYPE>: New case.
+       (evaluate_subexp_for_sizeof) <UNOP_MEMVAL_TYPE>: New case.
+       * expprint.c (print_subexp_standard) <UNOP_CAST_TYPE>: New case.
+       <UNOP_MEMVAL_TYPE>: New case.
+       (dump_subexp_body_standard) <UNOP_DYNAMIC_CAST,
+       UNOP_REINTERPRET_CAST>: Update.
+       <UNOP_CAST_TYPE, UNOP_MEMVAL_TYPE>: New cases.
+       * parse.c (operator_length_standard) <UNOP_DYNAMIC_CAST,
+       UNOP_REINTERPRET_CAST>: Update.
+       <UNOP_CAST_TYPE, UNOP_MEMVAL_TYPE>: New cases.
+       * stack.c (return_command): Also check for UNOP_CAST_TYPE.
+       * std-operator.def (UNOP_CAST_TYPE, UNOP_MEMVAL_TYPE): New
+       constants.
+
 2012-07-19  Yao Qi  <yao@codesourcery.com>
            Jan Kratochvil <jan.kratochvil@redhat.com>
 
index 845153da8c9272385ee9b4a546b858ad30860d54..2db56bffa49813b06bc41ed5e08424efc2319390 100644 (file)
@@ -2076,6 +2076,23 @@ gen_expr (struct expression *exp, union exp_element **pc,
       }
       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 (exp, pc, ax, value);
+       gen_cast (ax, value, type);
+      }
+      break;
+
     case UNOP_MEMVAL:
       {
        struct type *type = check_typedef ((*pc)[1].type);
@@ -2094,6 +2111,31 @@ gen_expr (struct expression *exp, union exp_element **pc,
       }
       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.  */
index 63cd8de45dee5f5acae3f87de7cd8ba868afc2c1..a122f6f4d0c9717440cdd92d0c5220bfe1e298c9 100644 (file)
@@ -10171,6 +10171,10 @@ watchpoint_exp_is_const (const struct expression *exp)
        case UNOP_ADDR:
        case UNOP_HIGH:
        case UNOP_CAST:
+
+       case UNOP_CAST_TYPE:
+       case UNOP_REINTERPRET_CAST:
+       case UNOP_DYNAMIC_CAST:
          /* Unary, binary and ternary operators: We have to check
             their operands.  If they are constant, then so is the
             result of that operation.  For instance, if A and B are
index 0613799c27e27006c2751e5713024193a245b0a6..e36a0fb96850964f4ddefbf1d204ef63229dc39f 100644 (file)
@@ -471,16 +471,12 @@ exp       :       lcurly arglist rcurly   %prec ARROW
                          write_exp_elt_opcode (OP_ARRAY); }
        ;
 
-exp    :       lcurly type rcurly exp  %prec UNARY
-                       { write_exp_elt_opcode (UNOP_MEMVAL);
-                         write_exp_elt_type ($2);
-                         write_exp_elt_opcode (UNOP_MEMVAL); }
+exp    :       lcurly type_exp rcurly exp  %prec UNARY
+                       { write_exp_elt_opcode (UNOP_MEMVAL_TYPE); }
        ;
 
-exp    :       '(' type ')' exp  %prec UNARY
-                       { write_exp_elt_opcode (UNOP_CAST);
-                         write_exp_elt_type ($2);
-                         write_exp_elt_opcode (UNOP_CAST); }
+exp    :       '(' type_exp ')' exp  %prec UNARY
+                       { write_exp_elt_opcode (UNOP_CAST_TYPE); }
        ;
 
 exp    :       '(' exp1 ')'
@@ -639,30 +635,22 @@ exp       :       SIZEOF '(' type ')'     %prec UNARY
                          write_exp_elt_opcode (OP_LONG); }
        ;
 
-exp    :       REINTERPRET_CAST '<' type '>' '(' exp ')' %prec UNARY
-                       { write_exp_elt_opcode (UNOP_REINTERPRET_CAST);
-                         write_exp_elt_type ($3);
-                         write_exp_elt_opcode (UNOP_REINTERPRET_CAST); }
+exp    :       REINTERPRET_CAST '<' type_exp '>' '(' exp ')' %prec UNARY
+                       { write_exp_elt_opcode (UNOP_REINTERPRET_CAST); }
        ;
 
-exp    :       STATIC_CAST '<' type '>' '(' exp ')' %prec UNARY
-                       { write_exp_elt_opcode (UNOP_CAST);
-                         write_exp_elt_type ($3);
-                         write_exp_elt_opcode (UNOP_CAST); }
+exp    :       STATIC_CAST '<' type_exp '>' '(' exp ')' %prec UNARY
+                       { write_exp_elt_opcode (UNOP_CAST_TYPE); }
        ;
 
-exp    :       DYNAMIC_CAST '<' type '>' '(' exp ')' %prec UNARY
-                       { write_exp_elt_opcode (UNOP_DYNAMIC_CAST);
-                         write_exp_elt_type ($3);
-                         write_exp_elt_opcode (UNOP_DYNAMIC_CAST); }
+exp    :       DYNAMIC_CAST '<' type_exp '>' '(' exp ')' %prec UNARY
+                       { write_exp_elt_opcode (UNOP_DYNAMIC_CAST); }
        ;
 
-exp    :       CONST_CAST '<' type '>' '(' exp ')' %prec UNARY
+exp    :       CONST_CAST '<' type_exp '>' '(' exp ')' %prec UNARY
                        { /* We could do more error checking here, but
                             it doesn't seem worthwhile.  */
-                         write_exp_elt_opcode (UNOP_CAST);
-                         write_exp_elt_type ($3);
-                         write_exp_elt_opcode (UNOP_CAST); }
+                         write_exp_elt_opcode (UNOP_CAST_TYPE); }
        ;
 
 string_exp:
index 7d3a8b96e3628237b7e644008ed3470538f0a2ec..a012873c461f26e28c2305063a2beb41bf2664c5 100644 (file)
@@ -2707,17 +2707,27 @@ evaluate_subexp_standard (struct type *expect_type,
        arg1 = value_cast (type, arg1);
       return arg1;
 
+    case UNOP_CAST_TYPE:
+      arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
+      type = value_type (arg1);
+      arg1 = evaluate_subexp (type, exp, pos, noside);
+      if (noside == EVAL_SKIP)
+       goto nosideret;
+      if (type != value_type (arg1))
+       arg1 = value_cast (type, arg1);
+      return arg1;
+
     case UNOP_DYNAMIC_CAST:
-      (*pos) += 2;
-      type = exp->elts[pc + 1].type;
+      arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
+      type = value_type (arg1);
       arg1 = evaluate_subexp (type, exp, pos, noside);
       if (noside == EVAL_SKIP)
        goto nosideret;
       return value_dynamic_cast (type, arg1);
 
     case UNOP_REINTERPRET_CAST:
-      (*pos) += 2;
-      type = exp->elts[pc + 1].type;
+      arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
+      type = value_type (arg1);
       arg1 = evaluate_subexp (type, exp, pos, noside);
       if (noside == EVAL_SKIP)
        goto nosideret;
@@ -2734,6 +2744,18 @@ evaluate_subexp_standard (struct type *expect_type,
        return value_at_lazy (exp->elts[pc + 1].type,
                              value_as_address (arg1));
 
+    case UNOP_MEMVAL_TYPE:
+      arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
+      type = value_type (arg1);
+      arg1 = evaluate_subexp (expect_type, exp, pos, noside);
+      if (noside == EVAL_SKIP)
+       goto nosideret;
+      if (noside == EVAL_AVOID_SIDE_EFFECTS)
+       return value_zero (exp->elts[pc + 1].type, lval_memory);
+      else
+       return value_at_lazy (exp->elts[pc + 1].type,
+                             value_as_address (arg1));
+
     case UNOP_MEMVAL_TLS:
       (*pos) += 3;
       arg1 = evaluate_subexp (expect_type, exp, pos, noside);
@@ -2936,6 +2958,17 @@ evaluate_subexp_for_address (struct expression *exp, int *pos,
       return value_cast (lookup_pointer_type (exp->elts[pc + 1].type),
                         evaluate_subexp (NULL_TYPE, exp, pos, noside));
 
+    case UNOP_MEMVAL_TYPE:
+      {
+       struct type *type;
+
+       (*pos) += 1;
+       x = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
+       type = value_type (x);
+       return value_cast (lookup_pointer_type (type),
+                          evaluate_subexp (NULL_TYPE, exp, pos, noside));
+      }
+
     case OP_VAR_VALUE:
       var = exp->elts[pc + 2].symbol;
 
@@ -3078,6 +3111,12 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos)
       type = check_typedef (exp->elts[pc + 1].type);
       return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type));
 
+    case UNOP_MEMVAL_TYPE:
+      (*pos) += 1;
+      val = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
+      type = check_typedef (value_type (val));
+      return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type));
+
     case OP_VAR_VALUE:
       (*pos) += 4;
       type = check_typedef (SYMBOL_TYPE (exp->elts[pc + 2].symbol));
index 6915d43f03e42ae1967e54246135762d8a9072a2..c3f6697f62dae7890fd8c792d0c1ad68ccc69ed2 100644 (file)
@@ -429,13 +429,25 @@ print_subexp_standard (struct expression *exp, int *pos,
        fputs_filtered (")", stream);
       return;
 
+    case UNOP_CAST_TYPE:
+      (*pos) += 1;
+      if ((int) prec > (int) PREC_PREFIX)
+       fputs_filtered ("(", stream);
+      fputs_filtered ("(", stream);
+      print_subexp (exp, pos, stream, PREC_PREFIX);
+      fputs_filtered (") ", stream);
+      print_subexp (exp, pos, stream, PREC_PREFIX);
+      if ((int) prec > (int) PREC_PREFIX)
+       fputs_filtered (")", stream);
+      return;
+
     case UNOP_DYNAMIC_CAST:
     case UNOP_REINTERPRET_CAST:
       fputs_filtered (opcode == UNOP_DYNAMIC_CAST ? "dynamic_cast"
                      : "reinterpret_cast", stream);
       fputs_filtered ("<", stream);
-      (*pos) += 2;
-      type_print (exp->elts[pc + 1].type, "", stream, 0);
+      (*pos) += 1;
+      print_subexp (exp, pos, stream, PREC_PREFIX);
       fputs_filtered ("> (", stream);
       print_subexp (exp, pos, stream, PREC_PREFIX);
       fputs_filtered (")", stream);
@@ -471,6 +483,18 @@ print_subexp_standard (struct expression *exp, int *pos,
        fputs_filtered (")", stream);
       return;
 
+    case UNOP_MEMVAL_TYPE:
+      (*pos) += 1;
+      if ((int) prec > (int) PREC_PREFIX)
+       fputs_filtered ("(", stream);
+      fputs_filtered ("{", stream);
+      print_subexp (exp, pos, stream, PREC_PREFIX);
+      fputs_filtered ("} ", stream);
+      print_subexp (exp, pos, stream, PREC_PREFIX);
+      if ((int) prec > (int) PREC_PREFIX)
+       fputs_filtered (")", stream);
+      return;
+
     case UNOP_MEMVAL_TLS:
       (*pos) += 3;
       if ((int) prec > (int) PREC_PREFIX)
@@ -910,10 +934,18 @@ dump_subexp_body_standard (struct expression *exp,
          elt = dump_subexp (exp, stream, elt);
       }
       break;
-    case UNOP_MEMVAL:
-    case UNOP_CAST:
     case UNOP_DYNAMIC_CAST:
     case UNOP_REINTERPRET_CAST:
+    case UNOP_CAST_TYPE:
+    case UNOP_MEMVAL_TYPE:
+      ++elt;
+      fprintf_filtered (stream, " (");
+      elt = dump_subexp (exp, stream, elt);
+      fprintf_filtered (stream, ")");
+      elt = dump_subexp (exp, stream, elt);
+      break;
+    case UNOP_MEMVAL:
+    case UNOP_CAST:
       fprintf_filtered (stream, "Type @");
       gdb_print_host_address (exp->elts[elt].type, stream);
       fprintf_filtered (stream, " (");
index 529c517c25e612486575390ba4da5b113095f214..1f9addf79d9f044ba98b757825cfcb20b9a472d4 100644 (file)
@@ -910,10 +910,16 @@ operator_length_standard (const struct expression *expr, int endpos,
       oplen = 3;
       break;
 
-    case BINOP_VAL:
-    case UNOP_CAST:
+    case UNOP_CAST_TYPE:
     case UNOP_DYNAMIC_CAST:
     case UNOP_REINTERPRET_CAST:
+    case UNOP_MEMVAL_TYPE:
+      oplen = 1;
+      args = 2;
+      break;
+
+    case BINOP_VAL:
+    case UNOP_CAST:
     case UNOP_MEMVAL:
       oplen = 3;
       args = 1;
@@ -1732,8 +1738,6 @@ operator_check_standard (struct expression *exp, int pos,
     case OP_SCOPE:
     case OP_TYPE:
     case UNOP_CAST:
-    case UNOP_DYNAMIC_CAST:
-    case UNOP_REINTERPRET_CAST:
     case UNOP_MAX:
     case UNOP_MEMVAL:
     case UNOP_MIN:
index 35d379d55ec24e9561b7992ce8e0e2aea37790ff..51747ead38e78028bd31962d5a77589d349c662c 100644 (file)
@@ -2308,7 +2308,8 @@ return_command (char *retval_exp, int from_tty)
        return_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (thisfun));
       if (return_type == NULL)
        {
-         if (retval_expr->elts[0].opcode != UNOP_CAST)
+         if (retval_expr->elts[0].opcode != UNOP_CAST
+             && retval_expr->elts[0].opcode != UNOP_CAST_TYPE)
            error (_("Return value type not available for selected "
                     "stack frame.\n"
                     "Please use an explicit cast of the value to return."));
index f2f650b01baa82e0073a9900f23b4f2782dd9b53..9c6a01be329485261516f820f18d5b0517afa91f 100644 (file)
@@ -216,6 +216,9 @@ OP (OP_ARRAY)
    It casts the value of the following subexpression.  */
 OP (UNOP_CAST)
 
+/* Like UNOP_CAST, but the type is a subexpression.  */
+OP (UNOP_CAST_TYPE)
+
 /* The C++ dynamic_cast operator.  */
 OP (UNOP_DYNAMIC_CAST)
 
@@ -235,6 +238,9 @@ OP (UNOP_MEMVAL)
    following subexpression from the TLS specified by `struct objfile'.  */
 OP (UNOP_MEMVAL_TLS)
 
+/* Like UNOP_MEMVAL, but the type is supplied as a subexpression.  */
+OP (UNOP_MEMVAL_TYPE)
+
 /* UNOP_... operate on one value from a following subexpression
    and replace it with a result.  They take no immediate arguments.  */