Implement binary comparison operations
[deliverable/binutils-gdb.git] / gdb / eval.c
index 7645291a8017dc72811d81b7074482cc2e98e962..83d0147f96e4efce3f6b291467d8b7494c1117a0 100644 (file)
@@ -41,6 +41,7 @@
 #include "typeprint.h"
 #include <ctype.h>
 #include "expop.h"
+#include "c-exp.h"
 
 /* Prototypes for local functions.  */
 
@@ -1237,7 +1238,7 @@ eval_op_var_msym_value (struct type *expect_type, struct expression *exp,
 
 /* Helper function that implements the body of OP_FUNC_STATIC_VAR.  */
 
-static struct value *
+struct value *
 eval_op_func_static_var (struct type *expect_type, struct expression *exp,
                         enum noside noside,
                         value *func, const char *var)
@@ -1254,7 +1255,7 @@ eval_op_func_static_var (struct type *expect_type, struct expression *exp,
 
 /* Helper function that implements the body of OP_REGISTER.  */
 
-static struct value *
+struct value *
 eval_op_register (struct type *expect_type, struct expression *exp,
                  enum noside noside, const char *name)
 {
@@ -1284,7 +1285,7 @@ eval_op_register (struct type *expect_type, struct expression *exp,
 
 /* Helper function that implements the body of OP_STRING.  */
 
-static struct value *
+struct value *
 eval_op_string (struct type *expect_type, struct expression *exp,
                enum noside noside, int len, const char *string)
 {
@@ -1297,7 +1298,7 @@ eval_op_string (struct type *expect_type, struct expression *exp,
 
 /* Helper function that implements the body of OP_OBJC_SELECTOR.  */
 
-static struct value *
+struct value *
 eval_op_objc_selector (struct type *expect_type, struct expression *exp,
                       enum noside noside,
                       const char *sel)
@@ -1312,22 +1313,21 @@ eval_op_objc_selector (struct type *expect_type, struct expression *exp,
 
 /* Helper function that implements the body of BINOP_CONCAT.  */
 
-static struct value *
+struct value *
 eval_op_concat (struct type *expect_type, struct expression *exp,
-               enum noside noside,
-               enum exp_opcode op, struct value *arg1, struct value *arg2)
+               enum noside noside, struct value *arg1, struct value *arg2)
 {
   if (noside == EVAL_SKIP)
     return eval_skip_value (exp);
-  if (binop_user_defined_p (op, arg1, arg2))
-    return value_x_binop (arg1, arg2, op, OP_NULL, noside);
+  if (binop_user_defined_p (BINOP_CONCAT, arg1, arg2))
+    return value_x_binop (arg1, arg2, BINOP_CONCAT, OP_NULL, noside);
   else
     return value_concat (arg1, arg2);
 }
 
 /* A helper function for TERNOP_SLICE.  */
 
-static struct value *
+struct value *
 eval_op_ternop (struct type *expect_type, struct expression *exp,
                enum noside noside,
                struct value *array, struct value *low, struct value *upper)
@@ -1341,7 +1341,7 @@ eval_op_ternop (struct type *expect_type, struct expression *exp,
 
 /* A helper function for STRUCTOP_STRUCT.  */
 
-static struct value *
+struct value *
 eval_op_structop_struct (struct type *expect_type, struct expression *exp,
                         enum noside noside,
                         struct value *arg1, const char *string)
@@ -1357,9 +1357,9 @@ eval_op_structop_struct (struct type *expect_type, struct expression *exp,
 
 /* A helper function for STRUCTOP_PTR.  */
 
-static struct value *
+struct value *
 eval_op_structop_ptr (struct type *expect_type, struct expression *exp,
-                     enum noside noside, enum exp_opcode op,
+                     enum noside noside,
                      struct value *arg1, const char *string)
 {
   if (noside == EVAL_SKIP)
@@ -1367,12 +1367,12 @@ eval_op_structop_ptr (struct type *expect_type, struct expression *exp,
 
   /* Check to see if operator '->' has been overloaded.  If so replace
      arg1 with the value returned by evaluating operator->().  */
-  while (unop_user_defined_p (op, arg1))
+  while (unop_user_defined_p (STRUCTOP_PTR, arg1))
     {
       struct value *value = NULL;
       try
        {
-         value = value_x_unop (arg1, op, noside);
+         value = value_x_unop (arg1, STRUCTOP_PTR, noside);
        }
 
       catch (const gdb_exception_error &except)
@@ -1416,7 +1416,7 @@ eval_op_structop_ptr (struct type *expect_type, struct expression *exp,
 
 /* A helper function for STRUCTOP_MEMBER.  */
 
-static struct value *
+struct value *
 eval_op_member (struct type *expect_type, struct expression *exp,
                enum noside noside,
                struct value *arg1, struct value *arg2)
@@ -1459,15 +1459,15 @@ eval_op_member (struct type *expect_type, struct expression *exp,
 
 /* A helper function for BINOP_ADD.  */
 
-static struct value *
+struct value *
 eval_op_add (struct type *expect_type, struct expression *exp,
-            enum noside noside, enum exp_opcode op,
+            enum noside noside,
             struct value *arg1, struct value *arg2)
 {
   if (noside == EVAL_SKIP)
     return eval_skip_value (exp);
-  if (binop_user_defined_p (op, arg1, arg2))
-    return value_x_binop (arg1, arg2, op, OP_NULL, noside);
+  if (binop_user_defined_p (BINOP_ADD, arg1, arg2))
+    return value_x_binop (arg1, arg2, BINOP_ADD, OP_NULL, noside);
   else if (ptrmath_type_p (exp->language_defn, value_type (arg1))
           && is_integral_or_integral_reference (value_type (arg2)))
     return value_ptradd (arg1, value_as_long (arg2));
@@ -1483,15 +1483,15 @@ eval_op_add (struct type *expect_type, struct expression *exp,
 
 /* A helper function for BINOP_SUB.  */
 
-static struct value *
+struct value *
 eval_op_sub (struct type *expect_type, struct expression *exp,
-            enum noside noside, enum exp_opcode op,
+            enum noside noside,
             struct value *arg1, struct value *arg2)
 {
   if (noside == EVAL_SKIP)
     return eval_skip_value (exp);
-  if (binop_user_defined_p (op, arg1, arg2))
-    return value_x_binop (arg1, arg2, op, OP_NULL, noside);
+  if (binop_user_defined_p (BINOP_SUB, arg1, arg2))
+    return value_x_binop (arg1, arg2, BINOP_SUB, OP_NULL, noside);
   else if (ptrmath_type_p (exp->language_defn, value_type (arg1))
           && ptrmath_type_p (exp->language_defn, value_type (arg2)))
     {
@@ -1511,7 +1511,7 @@ eval_op_sub (struct type *expect_type, struct expression *exp,
 
 /* Helper function for several different binary operations.  */
 
-static struct value *
+struct value *
 eval_op_binary (struct type *expect_type, struct expression *exp,
                enum noside noside, enum exp_opcode op,
                struct value *arg1, struct value *arg2)
@@ -1558,7 +1558,7 @@ eval_op_binary (struct type *expect_type, struct expression *exp,
 
 /* A helper function for BINOP_SUBSCRIPT.  */
 
-static struct value *
+struct value *
 eval_op_subscript (struct type *expect_type, struct expression *exp,
                   enum noside noside, enum exp_opcode op,
                   struct value *arg1, struct value *arg2)
@@ -1594,7 +1594,7 @@ eval_op_subscript (struct type *expect_type, struct expression *exp,
 
 /* A helper function for BINOP_EQUAL.  */
 
-static struct value *
+struct value *
 eval_op_equal (struct type *expect_type, struct expression *exp,
               enum noside noside, enum exp_opcode op,
               struct value *arg1, struct value *arg2)
@@ -1617,7 +1617,7 @@ eval_op_equal (struct type *expect_type, struct expression *exp,
 
 /* A helper function for BINOP_NOTEQUAL.  */
 
-static struct value *
+struct value *
 eval_op_notequal (struct type *expect_type, struct expression *exp,
                  enum noside noside, enum exp_opcode op,
                  struct value *arg1, struct value *arg2)
@@ -1640,7 +1640,7 @@ eval_op_notequal (struct type *expect_type, struct expression *exp,
 
 /* A helper function for BINOP_LESS.  */
 
-static struct value *
+struct value *
 eval_op_less (struct type *expect_type, struct expression *exp,
              enum noside noside, enum exp_opcode op,
              struct value *arg1, struct value *arg2)
@@ -1663,7 +1663,7 @@ eval_op_less (struct type *expect_type, struct expression *exp,
 
 /* A helper function for BINOP_GTR.  */
 
-static struct value *
+struct value *
 eval_op_gtr (struct type *expect_type, struct expression *exp,
             enum noside noside, enum exp_opcode op,
             struct value *arg1, struct value *arg2)
@@ -1686,7 +1686,7 @@ eval_op_gtr (struct type *expect_type, struct expression *exp,
 
 /* A helper function for BINOP_GEQ.  */
 
-static struct value *
+struct value *
 eval_op_geq (struct type *expect_type, struct expression *exp,
             enum noside noside, enum exp_opcode op,
             struct value *arg1, struct value *arg2)
@@ -1709,7 +1709,7 @@ eval_op_geq (struct type *expect_type, struct expression *exp,
 
 /* A helper function for BINOP_LEQ.  */
 
-static struct value *
+struct value *
 eval_op_leq (struct type *expect_type, struct expression *exp,
             enum noside noside, enum exp_opcode op,
             struct value *arg1, struct value *arg2)
@@ -2758,7 +2758,7 @@ evaluate_subexp_standard (struct type *expect_type,
       tem = longest_to_int (exp->elts[pc + 1].longconst);
       (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
       arg1 = evaluate_subexp (nullptr, exp, pos, noside);
-      return eval_op_structop_ptr (expect_type, exp, noside, op, arg1,
+      return eval_op_structop_ptr (expect_type, exp, noside, arg1,
                                   &exp->elts[pc + 2].string);
 
     case STRUCTOP_MEMBER:
@@ -2790,7 +2790,7 @@ evaluate_subexp_standard (struct type *expect_type,
     case BINOP_CONCAT:
       arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
       arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
-      return eval_op_concat (expect_type, exp, noside, op, arg1, arg2);
+      return eval_op_concat (expect_type, exp, noside, arg1, arg2);
 
     case BINOP_ASSIGN:
       arg1 = evaluate_subexp (nullptr, exp, pos, noside);
@@ -2822,12 +2822,12 @@ evaluate_subexp_standard (struct type *expect_type,
     case BINOP_ADD:
       arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
       arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
-      return eval_op_add (expect_type, exp, noside, op, arg1, arg2);
+      return eval_op_add (expect_type, exp, noside, arg1, arg2);
 
     case BINOP_SUB:
       arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
       arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
-      return eval_op_sub (expect_type, exp, noside, op, arg1, arg2);
+      return eval_op_sub (expect_type, exp, noside, arg1, arg2);
 
     case BINOP_EXP:
     case BINOP_MUL:
@@ -3536,6 +3536,39 @@ var_msym_value_operation::evaluate_for_sizeof (struct expression *exp,
   return value_from_longest (size_type, TYPE_LENGTH (type));
 }
 
+value *
+subscript_operation::evaluate_for_sizeof (struct expression *exp,
+                                         enum noside noside)
+{
+  if (noside == EVAL_NORMAL)
+    {
+      value *val = std::get<0> (m_storage)->evaluate (nullptr, exp,
+                                                     EVAL_AVOID_SIDE_EFFECTS);
+      struct type *type = check_typedef (value_type (val));
+      if (type->code () == TYPE_CODE_ARRAY)
+       {
+         type = check_typedef (TYPE_TARGET_TYPE (type));
+         if (type->code () == TYPE_CODE_ARRAY)
+           {
+             type = type->index_type ();
+             /* Only re-evaluate the right hand side if the resulting type
+                is a variable length type.  */
+             if (type->bounds ()->flag_bound_evaluated)
+               {
+                 val = evaluate (nullptr, exp, EVAL_NORMAL);
+                 /* FIXME: This should be size_t.  */
+                 struct type *size_type
+                   = builtin_type (exp->gdbarch)->builtin_int;
+                 return value_from_longest
+                   (size_type, (LONGEST) TYPE_LENGTH (value_type (val)));
+               }
+           }
+       }
+    }
+
+  return operation::evaluate_for_sizeof (exp, noside);
+}
+
 }
 
 /* Evaluate a subexpression of EXP, at index *POS, and return a value
This page took 0.027359 seconds and 4 git commands to generate.