gdb: use gdb_bfd_count_sections in macho_symfile_offsets
[deliverable/binutils-gdb.git] / gdb / eval.c
index 056daa051602e581c9fe886989852855f6a558ab..5c348c34e6656870a1fa36d9863521df39423483 100644 (file)
 #include <ctype.h>
 #include "expop.h"
 #include "c-exp.h"
+#include "inferior.h"
 
-/* Prototypes for local functions.  */
-
-static struct value *evaluate_subexp_for_sizeof (struct expression *, int *,
-                                                enum noside);
-
-static struct value *evaluate_subexp_for_address (struct expression *,
-                                                 int *, enum noside);
-
-static value *evaluate_subexp_for_cast (expression *exp, int *pos,
-                                       enum noside noside,
-                                       struct type *type);
-
-static struct value *evaluate_struct_tuple (struct value *,
-                                           struct expression *, int *,
-                                           enum noside, int);
-
-struct value *
-evaluate_subexp (struct type *expect_type, struct expression *exp,
-                int *pos, enum noside noside)
-{
-  return ((*exp->language_defn->expression_ops ()->evaluate_exp)
-         (expect_type, exp, pos, noside));
-}
 \f
 /* Parse the string EXP as a C expression, evaluate it,
    and return the result as a number.  */
@@ -115,13 +93,12 @@ struct value *
 expression::evaluate (struct type *expect_type, enum noside noside)
 {
   gdb::optional<enable_thread_stack_temporaries> stack_temporaries;
-  if (target_has_execution ()
+  if (target_has_execution () && inferior_ptid != null_ptid
       && language_defn->la_language == language_cplus
       && !thread_stack_temporaries_enabled_p (inferior_thread ()))
     stack_temporaries.emplace (inferior_thread ());
 
-  int pos = 0;
-  struct value *retval = evaluate_subexp (expect_type, this, &pos, noside);
+  struct value *retval = op->evaluate (expect_type, this, noside);
 
   if (stack_temporaries.has_value ()
       && value_in_thread_stack_temporaries (retval, inferior_thread ()))
@@ -147,15 +124,6 @@ evaluate_type (struct expression *exp)
   return exp->evaluate (nullptr, EVAL_AVOID_SIDE_EFFECTS);
 }
 
-/* Evaluate a subexpression, avoiding all memory references and
-   getting a value whose type alone is correct.  */
-
-struct value *
-evaluate_subexpression_type (struct expression *exp, int subexp)
-{
-  return evaluate_subexp (nullptr, exp, &subexp, EVAL_AVOID_SIDE_EFFECTS);
-}
-
 /* Find the current value of a watchpoint on EXP.  Return the value in
    *VALP and *RESULTP and the chain of intermediate and final values
    in *VAL_CHAIN.  RESULTP and VAL_CHAIN may be NULL if the caller does
@@ -179,8 +147,9 @@ evaluate_subexpression_type (struct expression *exp, int subexp)
    values will be left on the value chain.  */
 
 void
-fetch_subexp_value (struct expression *exp, int *pc, struct value **valp,
-                   struct value **resultp,
+fetch_subexp_value (struct expression *exp,
+                   expr::operation *op,
+                   struct value **valp, struct value **resultp,
                    std::vector<value_ref_ptr> *val_chain,
                    bool preserve_errors)
 {
@@ -198,7 +167,7 @@ fetch_subexp_value (struct expression *exp, int *pc, struct value **valp,
 
   try
     {
-      result = evaluate_subexp (nullptr, exp, pc, EVAL_NORMAL);
+      result = op->evaluate (nullptr, exp, EVAL_NORMAL);
     }
   catch (const gdb_exception &ex)
     {
@@ -251,91 +220,6 @@ fetch_subexp_value (struct expression *exp, int *pc, struct value **valp,
     }
 }
 
-/* Extract a field operation from an expression.  If the subexpression
-   of EXP starting at *SUBEXP is not a structure dereference
-   operation, return NULL.  Otherwise, return the name of the
-   dereferenced field, and advance *SUBEXP to point to the
-   subexpression of the left-hand-side of the dereference.  This is
-   used when completing field names.  */
-
-const char *
-extract_field_op (struct expression *exp, int *subexp)
-{
-  int tem;
-  char *result;
-
-  if (exp->elts[*subexp].opcode != STRUCTOP_STRUCT
-      && exp->elts[*subexp].opcode != STRUCTOP_PTR)
-    return NULL;
-  tem = longest_to_int (exp->elts[*subexp + 1].longconst);
-  result = &exp->elts[*subexp + 2].string;
-  (*subexp) += 1 + 3 + BYTES_TO_EXP_ELEM (tem + 1);
-  return result;
-}
-
-/* This function evaluates brace-initializers (in C/C++) for
-   structure types.  */
-
-static struct value *
-evaluate_struct_tuple (struct value *struct_val,
-                      struct expression *exp,
-                      int *pos, enum noside noside, int nargs)
-{
-  struct type *struct_type = check_typedef (value_type (struct_val));
-  struct type *field_type;
-  int fieldno = -1;
-
-  while (--nargs >= 0)
-    {
-      struct value *val = NULL;
-      int bitpos, bitsize;
-      bfd_byte *addr;
-
-      fieldno++;
-      /* Skip static fields.  */
-      while (fieldno < struct_type->num_fields ()
-            && field_is_static (&struct_type->field (fieldno)))
-       fieldno++;
-      if (fieldno >= struct_type->num_fields ())
-       error (_("too many initializers"));
-      field_type = struct_type->field (fieldno).type ();
-      if (field_type->code () == TYPE_CODE_UNION
-         && TYPE_FIELD_NAME (struct_type, fieldno)[0] == '0')
-       error (_("don't know which variant you want to set"));
-
-      /* Here, struct_type is the type of the inner struct,
-        while substruct_type is the type of the inner struct.
-        These are the same for normal structures, but a variant struct
-        contains anonymous union fields that contain substruct fields.
-        The value fieldno is the index of the top-level (normal or
-        anonymous union) field in struct_field, while the value
-        subfieldno is the index of the actual real (named inner) field
-        in substruct_type.  */
-
-      field_type = struct_type->field (fieldno).type ();
-      if (val == 0)
-       val = evaluate_subexp (field_type, exp, pos, noside);
-
-      /* Now actually set the field in struct_val.  */
-
-      /* Assign val to field fieldno.  */
-      if (value_type (val) != field_type)
-       val = value_cast (field_type, val);
-
-      bitsize = TYPE_FIELD_BITSIZE (struct_type, fieldno);
-      bitpos = TYPE_FIELD_BITPOS (struct_type, fieldno);
-      addr = value_contents_writeable (struct_val) + bitpos / 8;
-      if (bitsize)
-       modify_field (struct_type, addr,
-                     value_as_long (val), bitpos % 8, bitsize);
-      else
-       memcpy (addr, value_contents (val),
-               TYPE_LENGTH (value_type (val)));
-
-    }
-  return struct_val;
-}
-
 /* Promote value ARG1 as appropriate before performing a unary operation
    on this argument.
    If the result is not appropriate for any particular language then it
@@ -636,6 +520,24 @@ fake_method::~fake_method ()
   xfree (m_type.fields ());
 }
 
+namespace expr
+{
+
+value *
+type_instance_operation::evaluate (struct type *expect_type,
+                                  struct expression *exp,
+                                  enum noside noside)
+{
+  type_instance_flags flags = std::get<0> (m_storage);
+  std::vector<type *> &types = std::get<1> (m_storage);
+
+  fake_method fake_expect_type (flags, types.size (), types.data ());
+  return std::get<2> (m_storage)->evaluate (fake_expect_type.type (),
+                                           exp, noside);
+}
+
+}
+
 /* Helper for evaluating an OP_VAR_VALUE.  */
 
 value *
@@ -668,6 +570,23 @@ evaluate_var_value (enum noside noside, const block *blk, symbol *var)
   return ret;
 }
 
+namespace expr
+
+{
+
+value *
+var_value_operation::evaluate (struct type *expect_type,
+                              struct expression *exp,
+                              enum noside noside)
+{
+  symbol *var = std::get<0> (m_storage).symbol;
+  if (SYMBOL_TYPE (var)->code () == TYPE_CODE_ERROR)
+    error_unknown_type (var->print_name ());
+  return evaluate_var_value (noside, std::get<0> (m_storage).block, var);
+}
+
+} /* namespace expr */
+
 /* Helper for evaluating an OP_VAR_MSYM_VALUE.  */
 
 value *
@@ -683,14 +602,6 @@ evaluate_var_msym_value (enum noside noside,
     return value_at_lazy (the_type, address);
 }
 
-/* Helper for returning a value when handling EVAL_SKIP.  */
-
-value *
-eval_skip_value (expression *exp)
-{
-  return value_from_longest (builtin_type (exp->gdbarch)->builtin_int, 1);
-}
-
 /* See expression.h.  */
 
 value *
@@ -764,412 +675,301 @@ evaluate_subexp_do_call (expression *exp, enum noside noside,
     }
 }
 
-/* Helper for evaluating an OP_FUNCALL.  */
-
-static value *
-evaluate_funcall (type *expect_type, expression *exp, int *pos,
-                 enum noside noside)
+namespace expr
 {
-  int tem;
-  int pc2 = 0;
-  value *arg1 = NULL;
-  value *arg2 = NULL;
-  int save_pos1;
-  symbol *function = NULL;
-  char *function_name = NULL;
-  const char *var_func_name = NULL;
 
-  int pc = (*pos);
-  (*pos) += 2;
+value *
+operation::evaluate_funcall (struct type *expect_type,
+                            struct expression *exp,
+                            enum noside noside,
+                            const char *function_name,
+                            const std::vector<operation_up> &args)
+{
+  std::vector<value *> vals (args.size ());
 
-  exp_opcode op = exp->elts[*pos].opcode;
-  int nargs = longest_to_int (exp->elts[pc].longconst);
-  /* Allocate arg vector, including space for the function to be
-     called in argvec[0], a potential `this', and a terminating
-     NULL.  */
-  value **argvec = (value **) alloca (sizeof (value *) * (nargs + 3));
-  if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR)
+  value *callee = evaluate_with_coercion (exp, noside);
+  struct type *type = value_type (callee);
+  if (type->code () == TYPE_CODE_PTR)
+    type = TYPE_TARGET_TYPE (type);
+  for (int i = 0; i < args.size (); ++i)
     {
-      /* First, evaluate the structure into arg2.  */
-      pc2 = (*pos)++;
-
-      if (op == STRUCTOP_MEMBER)
-       {
-         arg2 = evaluate_subexp_for_address (exp, pos, noside);
-       }
+      if (i < type->num_fields ())
+       vals[i] = args[i]->evaluate (type->field (i).type (), exp, noside);
       else
-       {
-         arg2 = evaluate_subexp (nullptr, exp, pos, noside);
-       }
+       vals[i] = args[i]->evaluate_with_coercion (exp, noside);
+    }
 
-      /* If the function is a virtual function, then the aggregate
-        value (providing the structure) plays its part by providing
-        the vtable.  Otherwise, it is just along for the ride: call
-        the function directly.  */
+  return evaluate_subexp_do_call (exp, noside, callee, vals,
+                                 function_name, expect_type);
+}
 
-      arg1 = evaluate_subexp (nullptr, exp, pos, noside);
+value *
+var_value_operation::evaluate_funcall (struct type *expect_type,
+                                      struct expression *exp,
+                                      enum noside noside,
+                                      const std::vector<operation_up> &args)
+{
+  if (!overload_resolution
+      || exp->language_defn->la_language != language_cplus)
+    return operation::evaluate_funcall (expect_type, exp, noside, args);
 
-      type *a1_type = check_typedef (value_type (arg1));
-      if (noside == EVAL_SKIP)
-       tem = 1;  /* Set it to the right arg index so that all
-                    arguments can also be skipped.  */
-      else if (a1_type->code () == TYPE_CODE_METHODPTR)
-       {
-         if (noside == EVAL_AVOID_SIDE_EFFECTS)
-           arg1 = value_zero (TYPE_TARGET_TYPE (a1_type), not_lval);
-         else
-           arg1 = cplus_method_ptr_to_value (&arg2, arg1);
+  std::vector<value *> argvec (args.size ());
+  for (int i = 0; i < args.size (); ++i)
+    argvec[i] = args[i]->evaluate_with_coercion (exp, noside);
 
-         /* Now, say which argument to start evaluating from.  */
-         nargs++;
-         tem = 2;
-         argvec[1] = arg2;
-       }
-      else if (a1_type->code () == TYPE_CODE_MEMBERPTR)
-       {
-         struct type *type_ptr
-           = lookup_pointer_type (TYPE_SELF_TYPE (a1_type));
-         struct type *target_type_ptr
-           = lookup_pointer_type (TYPE_TARGET_TYPE (a1_type));
+  struct symbol *symp;
+  find_overload_match (argvec, NULL, NON_METHOD,
+                      NULL, std::get<0> (m_storage).symbol,
+                      NULL, &symp, NULL, 0, noside);
 
-         /* Now, convert these values to an address.  */
-         arg2 = value_cast (type_ptr, arg2);
+  if (SYMBOL_TYPE (symp)->code () == TYPE_CODE_ERROR)
+    error_unknown_type (symp->print_name ());
+  value *callee = evaluate_var_value (noside, std::get<0> (m_storage).block,
+                                     symp);
 
-         long mem_offset = value_as_long (arg1);
+  return evaluate_subexp_do_call (exp, noside, callee, argvec,
+                                 nullptr, expect_type);
+}
 
-         arg1 = value_from_pointer (target_type_ptr,
-                                    value_as_long (arg2) + mem_offset);
-         arg1 = value_ind (arg1);
-         tem = 1;
-       }
-      else
-       error (_("Non-pointer-to-member value used in pointer-to-member "
-                "construct"));
+value *
+scope_operation::evaluate_funcall (struct type *expect_type,
+                                  struct expression *exp,
+                                  enum noside noside,
+                                  const std::vector<operation_up> &args)
+{
+  if (!overload_resolution
+      || exp->language_defn->la_language != language_cplus)
+    return operation::evaluate_funcall (expect_type, exp, noside, args);
+
+  /* Unpack it locally so we can properly handle overload
+     resolution.  */
+  const std::string &name = std::get<1> (m_storage);
+  struct type *type = std::get<0> (m_storage);
+
+  symbol *function = NULL;
+  const char *function_name = NULL;
+  std::vector<value *> argvec (1 + args.size ());
+  if (type->code () == TYPE_CODE_NAMESPACE)
+    {
+      function = cp_lookup_symbol_namespace (type->name (),
+                                            name.c_str (),
+                                            get_selected_block (0),
+                                            VAR_DOMAIN).symbol;
+      if (function == NULL)
+       error (_("No symbol \"%s\" in namespace \"%s\"."),
+              name.c_str (), type->name ());
     }
-  else if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR)
+  else
     {
-      /* Hair for method invocations.  */
-      int tem2;
-
-      nargs++;
-      /* First, evaluate the structure into arg2.  */
-      pc2 = (*pos)++;
-      tem2 = longest_to_int (exp->elts[pc2 + 1].longconst);
-      *pos += 3 + BYTES_TO_EXP_ELEM (tem2 + 1);
+      gdb_assert (type->code () == TYPE_CODE_STRUCT
+                 || type->code () == TYPE_CODE_UNION);
+      function_name = name.c_str ();
 
-      if (op == STRUCTOP_STRUCT)
-       {
-         /* If v is a variable in a register, and the user types
-            v.method (), this will produce an error, because v has no
-            address.
-
-            A possible way around this would be to allocate a copy of
-            the variable on the stack, copy in the contents, call the
-            function, and copy out the contents.  I.e. convert this
-            from call by reference to call by copy-return (or
-            whatever it's called).  However, this does not work
-            because it is not the same: the method being called could
-            stash a copy of the address, and then future uses through
-            that address (after the method returns) would be expected
-            to use the variable itself, not some copy of it.  */
-         arg2 = evaluate_subexp_for_address (exp, pos, noside);
-       }
-      else
-       {
-         arg2 = evaluate_subexp (nullptr, exp, pos, noside);
+      /* We need a properly typed value for method lookup.  */
+      argvec[0] = value_zero (type, lval_memory);
+    }
 
-         /* Check to see if the operator '->' has been overloaded.
-            If the operator has been overloaded replace arg2 with the
-            value returned by the custom operator and continue
-            evaluation.  */
-         while (unop_user_defined_p (op, arg2))
-           {
-             struct value *value = NULL;
-             try
-               {
-                 value = value_x_unop (arg2, op, noside);
-               }
+  for (int i = 0; i < args.size (); ++i)
+    argvec[i + 1] = args[i]->evaluate_with_coercion (exp, noside);
+  gdb::array_view<value *> arg_view = argvec;
 
-             catch (const gdb_exception_error &except)
-               {
-                 if (except.error == NOT_FOUND_ERROR)
-                   break;
-                 else
-                   throw;
-               }
+  value *callee = nullptr;
+  if (function_name != nullptr)
+    {
+      int static_memfuncp;
 
-               arg2 = value;
-           }
-       }
-      /* Now, say which argument to start evaluating from.  */
-      tem = 2;
-    }
-  else if (op == OP_SCOPE
-          && overload_resolution
-          && (exp->language_defn->la_language == language_cplus))
-    {
-      /* Unpack it locally so we can properly handle overload
-        resolution.  */
-      char *name;
-      int local_tem;
-
-      pc2 = (*pos)++;
-      local_tem = longest_to_int (exp->elts[pc2 + 2].longconst);
-      (*pos) += 4 + BYTES_TO_EXP_ELEM (local_tem + 1);
-      struct type *type = exp->elts[pc2 + 1].type;
-      name = &exp->elts[pc2 + 3].string;
-
-      function = NULL;
-      function_name = NULL;
-      if (type->code () == TYPE_CODE_NAMESPACE)
+      find_overload_match (arg_view, function_name, METHOD,
+                          &argvec[0], nullptr, &callee, nullptr,
+                          &static_memfuncp, 0, noside);
+      if (!static_memfuncp)
        {
-         function = cp_lookup_symbol_namespace (type->name (),
-                                                name,
-                                                get_selected_block (0),
-                                                VAR_DOMAIN).symbol;
-         if (function == NULL)
-           error (_("No symbol \"%s\" in namespace \"%s\"."),
-                  name, type->name ());
-
-         tem = 1;
-         /* arg2 is left as NULL on purpose.  */
-       }
-      else
-       {
-         gdb_assert (type->code () == TYPE_CODE_STRUCT
-                     || type->code () == TYPE_CODE_UNION);
-         function_name = name;
-
-         /* We need a properly typed value for method lookup.  For
-            static methods arg2 is otherwise unused.  */
-         arg2 = value_zero (type, lval_memory);
-         ++nargs;
-         tem = 2;
+         /* For the time being, we don't handle this.  */
+         error (_("Call to overloaded function %s requires "
+                  "`this' pointer"),
+                function_name);
        }
+
+      arg_view = arg_view.slice (1);
     }
-  else if (op == OP_ADL_FUNC)
+  else
     {
-      /* Save the function position and move pos so that the arguments
-        can be evaluated.  */
-      int func_name_len;
+      symbol *symp;
+      arg_view = arg_view.slice (1);
+      find_overload_match (arg_view, nullptr,
+                          NON_METHOD, nullptr, function,
+                          nullptr, &symp, nullptr, 1, noside);
+      callee = value_of_variable (symp, get_selected_block (0));
+    }
 
-      save_pos1 = *pos;
-      tem = 1;
+  return evaluate_subexp_do_call (exp, noside, callee, arg_view,
+                                 nullptr, expect_type);
+}
 
-      func_name_len = longest_to_int (exp->elts[save_pos1 + 3].longconst);
-      (*pos) += 6 + BYTES_TO_EXP_ELEM (func_name_len + 1);
-    }
+value *
+structop_member_base::evaluate_funcall (struct type *expect_type,
+                                       struct expression *exp,
+                                       enum noside noside,
+                                       const std::vector<operation_up> &args)
+{
+  /* First, evaluate the structure into lhs.  */
+  value *lhs;
+  if (opcode () == STRUCTOP_MEMBER)
+    lhs = std::get<0> (m_storage)->evaluate_for_address (exp, noside);
   else
-    {
-      /* Non-method function call.  */
-      save_pos1 = *pos;
-      tem = 1;
+    lhs = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
 
-      /* If this is a C++ function wait until overload resolution.  */
-      if (op == OP_VAR_VALUE
-         && overload_resolution
-         && (exp->language_defn->la_language == language_cplus))
-       {
-         (*pos) += 4; /* Skip the evaluation of the symbol.  */
-         argvec[0] = NULL;
-       }
+  std::vector<value *> vals (args.size () + 1);
+  gdb::array_view<value *> val_view = vals;
+  /* If the function is a virtual function, then the aggregate
+     value (providing the structure) plays its part by providing
+     the vtable.  Otherwise, it is just along for the ride: call
+     the function directly.  */
+  value *rhs = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
+  value *callee;
+
+  type *a1_type = check_typedef (value_type (rhs));
+  if (a1_type->code () == TYPE_CODE_METHODPTR)
+    {
+      if (noside == EVAL_AVOID_SIDE_EFFECTS)
+       callee = value_zero (TYPE_TARGET_TYPE (a1_type), not_lval);
       else
-       {
-         if (op == OP_VAR_MSYM_VALUE)
-           {
-             minimal_symbol *msym = exp->elts[*pos + 2].msymbol;
-             var_func_name = msym->print_name ();
-           }
-         else if (op == OP_VAR_VALUE)
-           {
-             symbol *sym = exp->elts[*pos + 2].symbol;
-             var_func_name = sym->print_name ();
-           }
+       callee = cplus_method_ptr_to_value (&lhs, rhs);
 
-         argvec[0] = evaluate_subexp_with_coercion (exp, pos, noside);
-         type *type = value_type (argvec[0]);
-         if (type && type->code () == TYPE_CODE_PTR)
-           type = TYPE_TARGET_TYPE (type);
-         if (type && type->code () == TYPE_CODE_FUNC)
-           {
-             for (; tem <= nargs && tem <= type->num_fields (); tem++)
-               {
-                 argvec[tem] = evaluate_subexp (type->field (tem - 1).type (),
-                                                exp, pos, noside);
-               }
-           }
-       }
+      vals[0] = lhs;
     }
-
-  /* Evaluate arguments (if not already done, e.g., namespace::func()
-     and overload-resolution is off).  */
-  for (; tem <= nargs; tem++)
+  else if (a1_type->code () == TYPE_CODE_MEMBERPTR)
     {
-      /* Ensure that array expressions are coerced into pointer
-        objects.  */
-      argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside);
-    }
-
-  /* Signal end of arglist.  */
-  argvec[tem] = 0;
+      struct type *type_ptr
+       = lookup_pointer_type (TYPE_SELF_TYPE (a1_type));
+      struct type *target_type_ptr
+       = lookup_pointer_type (TYPE_TARGET_TYPE (a1_type));
 
-  if (noside == EVAL_SKIP)
-    return eval_skip_value (exp);
+      /* Now, convert this value to an address.  */
+      lhs = value_cast (type_ptr, lhs);
 
-  if (op == OP_ADL_FUNC)
-    {
-      struct symbol *symp;
-      char *func_name;
-      int  name_len;
-      int string_pc = save_pos1 + 3;
-
-      /* Extract the function name.  */
-      name_len = longest_to_int (exp->elts[string_pc].longconst);
-      func_name = (char *) alloca (name_len + 1);
-      strcpy (func_name, &exp->elts[string_pc + 1].string);
+      long mem_offset = value_as_long (rhs);
 
-      find_overload_match (gdb::make_array_view (&argvec[1], nargs),
-                          func_name,
-                          NON_METHOD, /* not method */
-                          NULL, NULL, /* pass NULL symbol since
-                                         symbol is unknown */
-                          NULL, &symp, NULL, 0, noside);
+      callee = value_from_pointer (target_type_ptr,
+                                  value_as_long (lhs) + mem_offset);
+      callee = value_ind (callee);
 
-      /* Now fix the expression being evaluated.  */
-      exp->elts[save_pos1 + 2].symbol = symp;
-      argvec[0] = evaluate_subexp_with_coercion (exp, &save_pos1, noside);
+      val_view = val_view.slice (1);
     }
+  else
+    error (_("Non-pointer-to-member value used in pointer-to-member "
+            "construct"));
 
-  if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR
-      || (op == OP_SCOPE && function_name != NULL))
-    {
-      int static_memfuncp;
-      char *tstr;
+  for (int i = 0; i < args.size (); ++i)
+    vals[i + 1] = args[i]->evaluate_with_coercion (exp, noside);
 
-      /* Method invocation: stuff "this" as first parameter.  If the
-        method turns out to be static we undo this below.  */
-      argvec[1] = arg2;
+  return evaluate_subexp_do_call (exp, noside, callee, val_view,
+                                 nullptr, expect_type);
 
-      if (op != OP_SCOPE)
-       {
-         /* Name of method from expression.  */
-         tstr = &exp->elts[pc2 + 2].string;
-       }
-      else
-       tstr = function_name;
+}
 
-      if (overload_resolution && (exp->language_defn->la_language
-                                 == language_cplus))
+value *
+structop_base_operation::evaluate_funcall
+     (struct type *expect_type, struct expression *exp, enum noside noside,
+      const std::vector<operation_up> &args)
+{
+  /* Allocate space for the function call arguments, Including space for a
+     `this' pointer at the start.  */
+  std::vector<value *> vals (args.size () + 1);
+  /* First, evaluate the structure into vals[0].  */
+  enum exp_opcode op = opcode ();
+  if (op == STRUCTOP_STRUCT)
+    {
+      /* If v is a variable in a register, and the user types
+        v.method (), this will produce an error, because v has no
+        address.
+
+        A possible way around this would be to allocate a copy of
+        the variable on the stack, copy in the contents, call the
+        function, and copy out the contents.  I.e. convert this
+        from call by reference to call by copy-return (or
+        whatever it's called).  However, this does not work
+        because it is not the same: the method being called could
+        stash a copy of the address, and then future uses through
+        that address (after the method returns) would be expected
+        to use the variable itself, not some copy of it.  */
+      vals[0] = std::get<0> (m_storage)->evaluate_for_address (exp, noside);
+    }
+  else
+    {
+      vals[0] = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
+      /* Check to see if the operator '->' has been overloaded.
+        If the operator has been overloaded replace vals[0] with the
+        value returned by the custom operator and continue
+        evaluation.  */
+      while (unop_user_defined_p (op, vals[0]))
        {
-         /* Language is C++, do some overload resolution before
-            evaluation.  */
-         struct value *valp = NULL;
-
-         (void) find_overload_match (gdb::make_array_view (&argvec[1], nargs),
-                                     tstr,
-                                     METHOD, /* method */
-                                     &arg2,  /* the object */
-                                     NULL, &valp, NULL,
-                                     &static_memfuncp, 0, noside);
-
-         if (op == OP_SCOPE && !static_memfuncp)
+         struct value *value = nullptr;
+         try
            {
-             /* For the time being, we don't handle this.  */
-             error (_("Call to overloaded function %s requires "
-                      "`this' pointer"),
-                    function_name);
+             value = value_x_unop (vals[0], op, noside);
+           }
+         catch (const gdb_exception_error &except)
+           {
+             if (except.error == NOT_FOUND_ERROR)
+               break;
+             else
+               throw;
            }
-         argvec[1] = arg2;     /* the ``this'' pointer */
-         argvec[0] = valp;     /* Use the method found after overload
-                                  resolution.  */
-       }
-      else
-       /* Non-C++ case -- or no overload resolution.  */
-       {
-         struct value *temp = arg2;
-
-         argvec[0] = value_struct_elt (&temp, argvec + 1, tstr,
-                                       &static_memfuncp,
-                                       op == STRUCTOP_STRUCT
-                                       ? "structure" : "structure pointer");
-         /* value_struct_elt updates temp with the correct value of
-            the ``this'' pointer if necessary, so modify argvec[1] to
-            reflect any ``this'' changes.  */
-         arg2
-           = value_from_longest (lookup_pointer_type(value_type (temp)),
-                                 value_address (temp)
-                                 + value_embedded_offset (temp));
-         argvec[1] = arg2;     /* the ``this'' pointer */
-       }
 
-      /* Take out `this' if needed.  */
-      if (static_memfuncp)
-       {
-         argvec[1] = argvec[0];
-         nargs--;
-         argvec++;
+         vals[0] = value;
        }
     }
-  else if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR)
-    {
-      /* Pointer to member.  argvec[1] is already set up.  */
-      argvec[0] = arg1;
-    }
-  else if (op == OP_VAR_VALUE || (op == OP_SCOPE && function != NULL))
-    {
-      /* Non-member function being called.  */
-      /* fn: This can only be done for C++ functions.  A C-style
-        function in a C++ program, for instance, does not have the
-        fields that are expected here.  */
-
-      if (overload_resolution && (exp->language_defn->la_language
-                                 == language_cplus))
-       {
-         /* Language is C++, do some overload resolution before
-            evaluation.  */
-         struct symbol *symp;
-         int no_adl = 0;
 
-         /* If a scope has been specified disable ADL.  */
-         if (op == OP_SCOPE)
-           no_adl = 1;
+  /* Evaluate the arguments.  The '+ 1' here is to allow for the `this'
+     pointer we placed into vals[0].  */
+  for (int i = 0; i < args.size (); ++i)
+    vals[i + 1] = args[i]->evaluate_with_coercion (exp, noside);
 
-         if (op == OP_VAR_VALUE)
-           function = exp->elts[save_pos1+2].symbol;
+  /* The array view includes the `this' pointer.  */
+  gdb::array_view<value *> arg_view (vals);
 
-         (void) find_overload_match (gdb::make_array_view (&argvec[1], nargs),
-                                     NULL,        /* no need for name */
-                                     NON_METHOD,  /* not method */
-                                     NULL, function, /* the function */
-                                     NULL, &symp, NULL, no_adl, noside);
-
-         if (op == OP_VAR_VALUE)
-           {
-             /* Now fix the expression being evaluated.  */
-             exp->elts[save_pos1+2].symbol = symp;
-             argvec[0] = evaluate_subexp_with_coercion (exp, &save_pos1,
-                                                        noside);
-           }
-         else
-           argvec[0] = value_of_variable (symp, get_selected_block (0));
-       }
-      else
-       {
-         /* Not C++, or no overload resolution allowed.  */
-         /* Nothing to be done; argvec already correctly set up.  */
-       }
+  int static_memfuncp;
+  value *callee;
+  const char *tstr = std::get<1> (m_storage).c_str ();
+  if (overload_resolution
+      && exp->language_defn->la_language == language_cplus)
+    {
+      /* Language is C++, do some overload resolution before
+        evaluation.  */
+      value *val0 = vals[0];
+      find_overload_match (arg_view, tstr, METHOD,
+                          &val0, nullptr, &callee, nullptr,
+                          &static_memfuncp, 0, noside);
+      vals[0] = val0;
     }
   else
+    /* Non-C++ case -- or no overload resolution.  */
     {
-      /* It is probably a C-style function.  */
-      /* Nothing to be done; argvec already correctly set up.  */
+      struct value *temp = vals[0];
+
+      callee = value_struct_elt (&temp, arg_view, tstr,
+                                &static_memfuncp,
+                                op == STRUCTOP_STRUCT
+                                ? "structure" : "structure pointer");
+      /* value_struct_elt updates temp with the correct value of the
+        ``this'' pointer if necessary, so modify it to reflect any
+        ``this'' changes.  */
+      vals[0] = value_from_longest (lookup_pointer_type (value_type (temp)),
+                                   value_address (temp)
+                                   + value_embedded_offset (temp));
     }
 
-  return evaluate_subexp_do_call (exp, noside, argvec[0],
-                                 gdb::make_array_view (argvec + 1, nargs),
-                                 var_func_name, expect_type);
+  /* Take out `this' if needed.  */
+  if (static_memfuncp)
+    arg_view = arg_view.slice (1);
+
+  return evaluate_subexp_do_call (exp, noside, callee, arg_view,
+                                 nullptr, expect_type);
 }
 
+
+} /* namespace expr */
+
 /* Return true if type is integral or reference to integral */
 
 static bool
@@ -1191,8 +991,6 @@ eval_op_scope (struct type *expect_type, struct expression *exp,
               enum noside noside,
               struct type *type, const char *string)
 {
-  if (noside == EVAL_SKIP)
-    return eval_skip_value (exp);
   struct value *arg1 = value_aggregate_elt (type, string, expect_type,
                                            0, noside);
   if (arg1 == NULL)
@@ -1206,8 +1004,6 @@ struct value *
 eval_op_var_entry_value (struct type *expect_type, struct expression *exp,
                         enum noside noside, symbol *sym)
 {
-  if (noside == EVAL_SKIP)
-    return eval_skip_value (exp);
   if (noside == EVAL_AVOID_SIDE_EFFECTS)
     return value_zero (SYMBOL_TYPE (sym), not_lval);
 
@@ -1225,14 +1021,15 @@ eval_op_var_entry_value (struct type *expect_type, struct expression *exp,
 struct value *
 eval_op_var_msym_value (struct type *expect_type, struct expression *exp,
                        enum noside noside, bool outermost_p,
-                       minimal_symbol *msymbol, struct objfile *objfile)
+                       bound_minimal_symbol msymbol)
 {
-  value *val = evaluate_var_msym_value (noside, objfile, msymbol);
+  value *val = evaluate_var_msym_value (noside, msymbol.objfile,
+                                       msymbol.minsym);
 
   struct type *type = value_type (val);
   if (type->code () == TYPE_CODE_ERROR
       && (noside != EVAL_AVOID_SIDE_EFFECTS || !outermost_p))
-    error_unknown_type (msymbol->print_name ());
+    error_unknown_type (msymbol.minsym->print_name ());
   return val;
 }
 
@@ -1243,8 +1040,6 @@ eval_op_func_static_var (struct type *expect_type, struct expression *exp,
                         enum noside noside,
                         value *func, const char *var)
 {
-  if (noside == EVAL_SKIP)
-    return eval_skip_value (exp);
   CORE_ADDR addr = value_address (func);
   const block *blk = block_for_pc (addr);
   struct block_symbol sym = lookup_symbol (var, blk, VAR_DOMAIN, NULL);
@@ -1289,8 +1084,6 @@ struct value *
 eval_op_string (struct type *expect_type, struct expression *exp,
                enum noside noside, int len, const char *string)
 {
-  if (noside == EVAL_SKIP)
-    return eval_skip_value (exp);
   struct type *type = language_string_char_type (exp->language_defn,
                                                 exp->gdbarch);
   return value_string (string, len, type);
@@ -1303,9 +1096,6 @@ eval_op_objc_selector (struct type *expect_type, struct expression *exp,
                       enum noside noside,
                       const char *sel)
 {
-  if (noside == EVAL_SKIP)
-    return eval_skip_value (exp);
-
   struct type *selector_type = builtin_type (exp->gdbarch)->builtin_data_ptr;
   return value_from_longest (selector_type,
                             lookup_child_selector (exp->gdbarch, sel));
@@ -1317,8 +1107,6 @@ struct value *
 eval_op_concat (struct type *expect_type, struct expression *exp,
                enum noside noside, struct value *arg1, struct value *arg2)
 {
-  if (noside == EVAL_SKIP)
-    return eval_skip_value (exp);
   if (binop_user_defined_p (BINOP_CONCAT, arg1, arg2))
     return value_x_binop (arg1, arg2, BINOP_CONCAT, OP_NULL, noside);
   else
@@ -1332,8 +1120,6 @@ eval_op_ternop (struct type *expect_type, struct expression *exp,
                enum noside noside,
                struct value *array, struct value *low, struct value *upper)
 {
-  if (noside == EVAL_SKIP)
-    return eval_skip_value (exp);
   int lowbound = value_as_long (low);
   int upperbound = value_as_long (upper);
   return value_slice (array, lowbound, upperbound - lowbound + 1);
@@ -1346,9 +1132,7 @@ eval_op_structop_struct (struct type *expect_type, struct expression *exp,
                         enum noside noside,
                         struct value *arg1, const char *string)
 {
-  if (noside == EVAL_SKIP)
-    return eval_skip_value (exp);
-  struct value *arg3 = value_struct_elt (&arg1, NULL, string,
+  struct value *arg3 = value_struct_elt (&arg1, {}, string,
                                         NULL, "structure");
   if (noside == EVAL_AVOID_SIDE_EFFECTS)
     arg3 = value_zero (value_type (arg3), VALUE_LVAL (arg3));
@@ -1362,9 +1146,6 @@ eval_op_structop_ptr (struct type *expect_type, struct expression *exp,
                      enum noside noside,
                      struct value *arg1, const char *string)
 {
-  if (noside == EVAL_SKIP)
-    return eval_skip_value (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 (STRUCTOP_PTR, arg1))
@@ -1407,7 +1188,7 @@ eval_op_structop_ptr (struct type *expect_type, struct expression *exp,
       }
   }
 
-  struct value *arg3 = value_struct_elt (&arg1, NULL, string,
+  struct value *arg3 = value_struct_elt (&arg1, {}, string,
                                         NULL, "structure pointer");
   if (noside == EVAL_AVOID_SIDE_EFFECTS)
     arg3 = value_zero (value_type (arg3), VALUE_LVAL (arg3));
@@ -1423,9 +1204,6 @@ eval_op_member (struct type *expect_type, struct expression *exp,
 {
   long mem_offset;
 
-  if (noside == EVAL_SKIP)
-    return eval_skip_value (exp);
-
   struct value *arg3;
   struct type *type = check_typedef (value_type (arg2));
   switch (type->code ())
@@ -1464,8 +1242,6 @@ eval_op_add (struct type *expect_type, struct expression *exp,
             enum noside noside,
             struct value *arg1, struct value *arg2)
 {
-  if (noside == EVAL_SKIP)
-    return eval_skip_value (exp);
   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))
@@ -1488,8 +1264,6 @@ eval_op_sub (struct type *expect_type, struct expression *exp,
             enum noside noside,
             struct value *arg1, struct value *arg2)
 {
-  if (noside == EVAL_SKIP)
-    return eval_skip_value (exp);
   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))
@@ -1516,8 +1290,6 @@ eval_op_binary (struct type *expect_type, struct expression *exp,
                enum noside noside, enum exp_opcode op,
                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);
   else
@@ -1563,8 +1335,6 @@ eval_op_subscript (struct type *expect_type, struct expression *exp,
                   enum noside noside, enum exp_opcode op,
                   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);
   else
@@ -1594,13 +1364,11 @@ 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)
 {
-  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);
@@ -1617,13 +1385,11 @@ 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)
 {
-  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);
@@ -1640,13 +1406,11 @@ 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)
 {
-  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);
@@ -1663,13 +1427,11 @@ 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)
 {
-  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);
@@ -1686,13 +1448,11 @@ 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)
 {
-  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);
@@ -1709,13 +1469,11 @@ 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)
 {
-  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);
@@ -1732,13 +1490,11 @@ eval_op_leq (struct type *expect_type, struct expression *exp,
 
 /* A helper function for BINOP_REPEAT.  */
 
-static struct value *
+struct value *
 eval_op_repeat (struct type *expect_type, struct expression *exp,
-               enum noside noside,
+               enum noside noside, enum exp_opcode op,
                struct value *arg1, struct value *arg2)
 {
-  if (noside == EVAL_SKIP)
-    return eval_skip_value (exp);
   struct type *type = check_typedef (value_type (arg2));
   if (type->code () != TYPE_CODE_INT
       && type->code () != TYPE_CODE_ENUM)
@@ -1754,13 +1510,11 @@ eval_op_repeat (struct type *expect_type, struct expression *exp,
 
 /* A helper function for UNOP_PLUS.  */
 
-static struct value *
+struct value *
 eval_op_plus (struct type *expect_type, struct expression *exp,
              enum noside noside, enum exp_opcode op,
              struct value *arg1)
 {
-  if (noside == EVAL_SKIP)
-    return eval_skip_value (exp);
   if (unop_user_defined_p (op, arg1))
     return value_x_unop (arg1, op, noside);
   else
@@ -1772,13 +1526,11 @@ eval_op_plus (struct type *expect_type, struct expression *exp,
 
 /* A helper function for UNOP_NEG.  */
 
-static struct value *
+struct value *
 eval_op_neg (struct type *expect_type, struct expression *exp,
             enum noside noside, enum exp_opcode op,
             struct value *arg1)
 {
-  if (noside == EVAL_SKIP)
-    return eval_skip_value (exp);
   if (unop_user_defined_p (op, arg1))
     return value_x_unop (arg1, op, noside);
   else
@@ -1790,13 +1542,11 @@ eval_op_neg (struct type *expect_type, struct expression *exp,
 
 /* A helper function for UNOP_COMPLEMENT.  */
 
-static struct value *
+struct value *
 eval_op_complement (struct type *expect_type, struct expression *exp,
                    enum noside noside, enum exp_opcode op,
                    struct value *arg1)
 {
-  if (noside == EVAL_SKIP)
-    return eval_skip_value (exp);
   if (unop_user_defined_p (UNOP_COMPLEMENT, arg1))
     return value_x_unop (arg1, UNOP_COMPLEMENT, noside);
   else
@@ -1808,13 +1558,11 @@ eval_op_complement (struct type *expect_type, struct expression *exp,
 
 /* A helper function for UNOP_LOGICAL_NOT.  */
 
-static struct value *
+struct value *
 eval_op_lognot (struct type *expect_type, struct expression *exp,
                enum noside noside, enum exp_opcode op,
                struct value *arg1)
 {
-  if (noside == EVAL_SKIP)
-    return eval_skip_value (exp);
   if (unop_user_defined_p (op, arg1))
     return value_x_unop (arg1, op, noside);
   else
@@ -1827,9 +1575,9 @@ eval_op_lognot (struct type *expect_type, struct expression *exp,
 
 /* A helper function for UNOP_IND.  */
 
-static struct value *
+struct value *
 eval_op_ind (struct type *expect_type, struct expression *exp,
-            enum noside noside, enum exp_opcode op,
+            enum noside noside,
             struct value *arg1)
 {
   struct type *type = check_typedef (value_type (arg1));
@@ -1837,10 +1585,8 @@ eval_op_ind (struct type *expect_type, struct expression *exp,
       || type->code () == TYPE_CODE_MEMBERPTR)
     error (_("Attempt to dereference pointer "
             "to member without an object"));
-  if (noside == EVAL_SKIP)
-    return eval_skip_value (exp);
-  if (unop_user_defined_p (op, arg1))
-    return value_x_unop (arg1, op, noside);
+  if (unop_user_defined_p (UNOP_IND, arg1))
+    return value_x_unop (arg1, UNOP_IND, noside);
   else if (noside == EVAL_AVOID_SIDE_EFFECTS)
     {
       type = check_typedef (value_type (arg1));
@@ -1881,7 +1627,7 @@ eval_op_ind (struct type *expect_type, struct expression *exp,
 
 /* A helper function for UNOP_ALIGNOF.  */
 
-static struct value *
+struct value *
 eval_op_alignof (struct type *expect_type, struct expression *exp,
                 enum noside noside,
                 struct value *arg1)
@@ -1897,13 +1643,11 @@ eval_op_alignof (struct type *expect_type, struct expression *exp,
 
 /* A helper function for UNOP_MEMVAL.  */
 
-static struct value *
+struct value *
 eval_op_memval (struct type *expect_type, struct expression *exp,
                enum noside noside,
                struct value *arg1, struct type *type)
 {
-  if (noside == EVAL_SKIP)
-    return eval_skip_value (exp);
   if (noside == EVAL_AVOID_SIDE_EFFECTS)
     return value_zero (type, lval_memory);
   else
@@ -1912,12 +1656,12 @@ eval_op_memval (struct type *expect_type, struct expression *exp,
 
 /* A helper function for UNOP_PREINCREMENT.  */
 
-static struct value *
+struct value *
 eval_op_preinc (struct type *expect_type, struct expression *exp,
                enum noside noside, enum exp_opcode op,
                struct value *arg1)
 {
-  if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
+  if (noside == EVAL_AVOID_SIDE_EFFECTS)
     return arg1;
   else if (unop_user_defined_p (op, arg1))
     {
@@ -1943,12 +1687,12 @@ eval_op_preinc (struct type *expect_type, struct expression *exp,
 
 /* A helper function for UNOP_PREDECREMENT.  */
 
-static struct value *
+struct value *
 eval_op_predec (struct type *expect_type, struct expression *exp,
                enum noside noside, enum exp_opcode op,
                struct value *arg1)
 {
-  if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
+  if (noside == EVAL_AVOID_SIDE_EFFECTS)
     return arg1;
   else if (unop_user_defined_p (op, arg1))
     {
@@ -1974,12 +1718,12 @@ eval_op_predec (struct type *expect_type, struct expression *exp,
 
 /* A helper function for UNOP_POSTINCREMENT.  */
 
-static struct value *
+struct value *
 eval_op_postinc (struct type *expect_type, struct expression *exp,
                 enum noside noside, enum exp_opcode op,
                 struct value *arg1)
 {
-  if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
+  if (noside == EVAL_AVOID_SIDE_EFFECTS)
     return arg1;
   else if (unop_user_defined_p (op, arg1))
     {
@@ -2008,12 +1752,12 @@ eval_op_postinc (struct type *expect_type, struct expression *exp,
 
 /* A helper function for UNOP_POSTDECREMENT.  */
 
-static struct value *
+struct value *
 eval_op_postdec (struct type *expect_type, struct expression *exp,
                 enum noside noside, enum exp_opcode op,
                 struct value *arg1)
 {
-  if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
+  if (noside == EVAL_AVOID_SIDE_EFFECTS)
     return arg1;
   else if (unop_user_defined_p (op, arg1))
     {
@@ -2042,13 +1786,11 @@ eval_op_postdec (struct type *expect_type, struct expression *exp,
 
 /* A helper function for OP_TYPE.  */
 
-static struct value *
+struct value *
 eval_op_type (struct type *expect_type, struct expression *exp,
              enum noside noside, struct type *type)
 {
-  if (noside == EVAL_SKIP)
-    return eval_skip_value (exp);
-  else if (noside == EVAL_AVOID_SIDE_EFFECTS)
+  if (noside == EVAL_AVOID_SIDE_EFFECTS)
     return allocate_value (type);
   else
     error (_("Attempt to use a type name as an expression"));
@@ -2056,12 +1798,12 @@ eval_op_type (struct type *expect_type, struct expression *exp,
 
 /* A helper function for BINOP_ASSIGN_MODIFY.  */
 
-static struct value *
+struct value *
 eval_binop_assign_modify (struct type *expect_type, struct expression *exp,
                          enum noside noside, enum exp_opcode op,
                          struct value *arg1, struct value *arg2)
 {
-  if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
+  if (noside == EVAL_AVOID_SIDE_EFFECTS)
     return arg1;
   if (binop_user_defined_p (op, arg1, arg2))
     return value_x_binop (arg1, arg2, BINOP_ASSIGN_MODIFY, op, noside);
@@ -2230,8 +1972,8 @@ eval_op_objc_msgcall (struct type *expect_type, struct expression *exp,
 
       /* The address might point to a function descriptor;
         resolve it to the actual code address instead.  */
-      addr = gdbarch_convert_from_func_ptr_addr (exp->gdbarch, addr,
-                                                current_top_target ());
+      addr = gdbarch_convert_from_func_ptr_addr
+       (exp->gdbarch, addr, current_inferior ()->top_target ());
 
       /* Is it a high_level symbol?  */
       sym = find_pc_function (addr);
@@ -2311,8 +2053,6 @@ eval_op_objc_msgcall (struct type *expect_type, struct expression *exp,
        called_method = msg_send;
     }
 
-  if (noside == EVAL_SKIP)
-    return eval_skip_value (exp);
 
   if (noside == EVAL_AVOID_SIDE_EFFECTS)
     {
@@ -2368,8 +2108,6 @@ eval_multi_subscript (struct type *expect_type, struct expression *exp,
                      enum noside noside, value *arg1,
                      gdb::array_view<value *> args)
 {
-  if (noside == EVAL_SKIP)
-    return arg1;
   for (value *arg2 : args)
     {
       if (binop_user_defined_p (MULTI_SUBSCRIPT, arg1, arg2))
@@ -2401,738 +2139,338 @@ eval_multi_subscript (struct type *expect_type, struct expression *exp,
   return (arg1);
 }
 
-struct value *
-evaluate_subexp_standard (struct type *expect_type,
-                         struct expression *exp, int *pos,
-                         enum noside noside)
-{
-  enum exp_opcode op;
-  int tem, tem2, tem3;
-  int pc, oldpos;
-  struct value *arg1 = NULL;
-  struct value *arg2 = NULL;
-  struct type *type;
-  int nargs;
-  struct value **argvec;
-  int ix;
-  struct type **arg_types;
-
-  pc = (*pos)++;
-  op = exp->elts[pc].opcode;
-
-  switch (op)
-    {
-    case OP_SCOPE:
-      tem = longest_to_int (exp->elts[pc + 2].longconst);
-      (*pos) += 4 + BYTES_TO_EXP_ELEM (tem + 1);
-      return eval_op_scope (expect_type, exp, noside,
-                           exp->elts[pc + 1].type,
-                           &exp->elts[pc + 3].string);
-
-    case OP_LONG:
-      (*pos) += 3;
-      return value_from_longest (exp->elts[pc + 1].type,
-                                exp->elts[pc + 2].longconst);
-
-    case OP_FLOAT:
-      (*pos) += 3;
-      return value_from_contents (exp->elts[pc + 1].type,
-                                 exp->elts[pc + 2].floatconst);
-
-    case OP_ADL_FUNC:
-    case OP_VAR_VALUE:
-      {
-       (*pos) += 3;
-       symbol *var = exp->elts[pc + 2].symbol;
-       if (SYMBOL_TYPE (var)->code () == TYPE_CODE_ERROR)
-         error_unknown_type (var->print_name ());
-       if (noside != EVAL_SKIP)
-           return evaluate_var_value (noside, exp->elts[pc + 1].block, var);
-       else
-         {
-           /* Return a dummy value of the correct type when skipping, so
-              that parent functions know what is to be skipped.  */
-           return allocate_value (SYMBOL_TYPE (var));
-         }
-      }
-
-    case OP_VAR_MSYM_VALUE:
-      {
-       (*pos) += 3;
-
-       minimal_symbol *msymbol = exp->elts[pc + 2].msymbol;
-       return eval_op_var_msym_value (expect_type, exp, noside,
-                                      pc == 0, msymbol,
-                                      exp->elts[pc + 1].objfile);
-      }
-
-    case OP_VAR_ENTRY_VALUE:
-      (*pos) += 2;
-
-      {
-       struct symbol *sym = exp->elts[pc + 1].symbol;
-
-       return eval_op_var_entry_value (expect_type, exp, noside, sym);
-      }
-
-    case OP_FUNC_STATIC_VAR:
-      tem = longest_to_int (exp->elts[pc + 1].longconst);
-      (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
-      if (noside == EVAL_SKIP)
-       return eval_skip_value (exp);
-
-      {
-       value *func = evaluate_subexp_standard (NULL, exp, pos, noside);
+namespace expr
+{
 
-       return eval_op_func_static_var (expect_type, exp, noside, func,
-                                       &exp->elts[pc + 2].string);
-      }
+value *
+objc_msgcall_operation::evaluate (struct type *expect_type,
+                                 struct expression *exp,
+                                 enum noside noside)
+{
+  enum noside sub_no_side = EVAL_NORMAL;
+  struct type *selector_type = builtin_type (exp->gdbarch)->builtin_data_ptr;
 
-    case OP_LAST:
-      (*pos) += 2;
-      return
-       access_value_history (longest_to_int (exp->elts[pc + 1].longconst));
+  if (noside == EVAL_AVOID_SIDE_EFFECTS)
+    sub_no_side = EVAL_NORMAL;
+  else
+    sub_no_side = noside;
+  value *target
+    = std::get<1> (m_storage)->evaluate (selector_type, exp, sub_no_side);
 
-    case OP_REGISTER:
-      {
-       const char *name = &exp->elts[pc + 2].string;
+  if (value_as_long (target) == 0)
+    sub_no_side = EVAL_AVOID_SIDE_EFFECTS;
+  else
+    sub_no_side = noside;
+  std::vector<operation_up> &args = std::get<2> (m_storage);
+  value **argvec = XALLOCAVEC (struct value *, args.size () + 3);
+  argvec[0] = nullptr;
+  argvec[1] = nullptr;
+  for (int i = 0; i < args.size (); ++i)
+    argvec[i + 2] = args[i]->evaluate_with_coercion (exp, sub_no_side);
+  argvec[args.size () + 2] = nullptr;
 
-       (*pos) += 3 + BYTES_TO_EXP_ELEM (exp->elts[pc + 1].longconst + 1);
-       return eval_op_register (expect_type, exp, noside, name);
-      }
-    case OP_BOOL:
-      (*pos) += 2;
-      type = language_bool_type (exp->language_defn, exp->gdbarch);
-      return value_from_longest (type, exp->elts[pc + 1].longconst);
-
-    case OP_INTERNALVAR:
-      (*pos) += 2;
-      return value_of_internalvar (exp->gdbarch,
-                                  exp->elts[pc + 1].internalvar);
-
-    case OP_STRING:
-      tem = longest_to_int (exp->elts[pc + 1].longconst);
-      (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
-      return eval_op_string (expect_type, exp, noside, tem,
-                            &exp->elts[pc + 2].string);
-
-    case OP_OBJC_NSSTRING:             /* Objective C Foundation Class
-                                          NSString constant.  */
-      tem = longest_to_int (exp->elts[pc + 1].longconst);
-      (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
-      if (noside == EVAL_SKIP)
-       return eval_skip_value (exp);
-      return value_nsstring (exp->gdbarch, &exp->elts[pc + 2].string, tem + 1);
-
-    case OP_ARRAY:
-      (*pos) += 3;
-      tem2 = longest_to_int (exp->elts[pc + 1].longconst);
-      tem3 = longest_to_int (exp->elts[pc + 2].longconst);
-      nargs = tem3 - tem2 + 1;
-      type = expect_type ? check_typedef (expect_type) : nullptr;
-
-      if (expect_type != nullptr && noside != EVAL_SKIP
-         && type->code () == TYPE_CODE_STRUCT)
-       {
-         struct value *rec = allocate_value (expect_type);
+  return eval_op_objc_msgcall (expect_type, exp, noside, std::
+                              get<0> (m_storage), target,
+                              gdb::make_array_view (argvec,
+                                                    args.size () + 3));
+}
 
-         memset (value_contents_raw (rec), '\0', TYPE_LENGTH (type));
-         return evaluate_struct_tuple (rec, exp, pos, noside, nargs);
-       }
+value *
+multi_subscript_operation::evaluate (struct type *expect_type,
+                                    struct expression *exp,
+                                    enum noside noside)
+{
+  value *arg1 = std::get<0> (m_storage)->evaluate_with_coercion (exp, noside);
+  std::vector<operation_up> &values = std::get<1> (m_storage);
+  value **argvec = XALLOCAVEC (struct value *, values.size ());
+  for (int ix = 0; ix < values.size (); ++ix)
+    argvec[ix] = values[ix]->evaluate_with_coercion (exp, noside);
+  return eval_multi_subscript (expect_type, exp, noside, arg1,
+                              gdb::make_array_view (argvec, values.size ()));
+}
 
-      if (expect_type != nullptr && noside != EVAL_SKIP
-         && type->code () == TYPE_CODE_ARRAY)
-       {
-         struct type *range_type = type->index_type ();
-         struct type *element_type = TYPE_TARGET_TYPE (type);
-         struct value *array = allocate_value (expect_type);
-         int element_size = TYPE_LENGTH (check_typedef (element_type));
-         LONGEST low_bound, high_bound, index;
+value *
+logical_and_operation::evaluate (struct type *expect_type,
+                                struct expression *exp,
+                                enum noside noside)
+{
+  value *arg1 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
 
-         if (!get_discrete_bounds (range_type, &low_bound, &high_bound))
-           {
-             low_bound = 0;
-             high_bound = (TYPE_LENGTH (type) / element_size) - 1;
-           }
-         index = low_bound;
-         memset (value_contents_raw (array), 0, TYPE_LENGTH (expect_type));
-         for (tem = nargs; --nargs >= 0;)
-           {
-             struct value *element;
-
-             element = evaluate_subexp (element_type, exp, pos, noside);
-             if (value_type (element) != element_type)
-               element = value_cast (element_type, element);
-             if (index > high_bound)
-               /* To avoid memory corruption.  */
-               error (_("Too many array elements"));
-             memcpy (value_contents_raw (array)
-                     + (index - low_bound) * element_size,
-                     value_contents (element),
-                     element_size);
-             index++;
-           }
-         return array;
-       }
+  value *arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp,
+                                                  EVAL_AVOID_SIDE_EFFECTS);
 
-      if (expect_type != nullptr && noside != EVAL_SKIP
-         && type->code () == TYPE_CODE_SET)
+  if (binop_user_defined_p (BINOP_LOGICAL_AND, arg1, arg2))
+    {
+      arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
+      return value_x_binop (arg1, arg2, BINOP_LOGICAL_AND, OP_NULL, noside);
+    }
+  else
+    {
+      int tem = value_logical_not (arg1);
+      if (!tem)
        {
-         struct value *set = allocate_value (expect_type);
-         gdb_byte *valaddr = value_contents_raw (set);
-         struct type *element_type = type->index_type ();
-         struct type *check_type = element_type;
-         LONGEST low_bound, high_bound;
-
-         /* Get targettype of elementtype.  */
-         while (check_type->code () == TYPE_CODE_RANGE
-                || check_type->code () == TYPE_CODE_TYPEDEF)
-           check_type = TYPE_TARGET_TYPE (check_type);
-
-         if (!get_discrete_bounds (element_type, &low_bound, &high_bound))
-           error (_("(power)set type with unknown size"));
-         memset (valaddr, '\0', TYPE_LENGTH (type));
-         for (tem = 0; tem < nargs; tem++)
-           {
-             LONGEST range_low, range_high;
-             struct type *range_low_type, *range_high_type;
-             struct value *elem_val;
-
-             elem_val = evaluate_subexp (element_type, exp, pos, noside);
-             range_low_type = range_high_type = value_type (elem_val);
-             range_low = range_high = value_as_long (elem_val);
-
-             /* Check types of elements to avoid mixture of elements from
-                different types. Also check if type of element is "compatible"
-                with element type of powerset.  */
-             if (range_low_type->code () == TYPE_CODE_RANGE)
-               range_low_type = TYPE_TARGET_TYPE (range_low_type);
-             if (range_high_type->code () == TYPE_CODE_RANGE)
-               range_high_type = TYPE_TARGET_TYPE (range_high_type);
-             if ((range_low_type->code () != range_high_type->code ())
-                 || (range_low_type->code () == TYPE_CODE_ENUM
-                     && (range_low_type != range_high_type)))
-               /* different element modes.  */
-               error (_("POWERSET tuple elements of different mode"));
-             if ((check_type->code () != range_low_type->code ())
-                 || (check_type->code () == TYPE_CODE_ENUM
-                     && range_low_type != check_type))
-               error (_("incompatible POWERSET tuple elements"));
-             if (range_low > range_high)
-               {
-                 warning (_("empty POWERSET tuple range"));
-                 continue;
-               }
-             if (range_low < low_bound || range_high > high_bound)
-               error (_("POWERSET tuple element out of range"));
-             range_low -= low_bound;
-             range_high -= low_bound;
-             for (; range_low <= range_high; range_low++)
-               {
-                 int bit_index = (unsigned) range_low % TARGET_CHAR_BIT;
-
-                 if (gdbarch_byte_order (exp->gdbarch) == BFD_ENDIAN_BIG)
-                   bit_index = TARGET_CHAR_BIT - 1 - bit_index;
-                 valaddr[(unsigned) range_low / TARGET_CHAR_BIT]
-                   |= 1 << bit_index;
-               }
-           }
-         return set;
+         arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
+         tem = value_logical_not (arg2);
        }
+      struct type *type = language_bool_type (exp->language_defn,
+                                             exp->gdbarch);
+      return value_from_longest (type, !tem);
+    }
+}
 
-      argvec = XALLOCAVEC (struct value *, nargs);
-      for (tem = 0; tem < nargs; tem++)
-       {
-         /* Ensure that array expressions are coerced into pointer
-            objects.  */
-         argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside);
-       }
-      if (noside == EVAL_SKIP)
-       return eval_skip_value (exp);
-      return value_array (tem2, tem3, argvec);
+value *
+logical_or_operation::evaluate (struct type *expect_type,
+                               struct expression *exp,
+                               enum noside noside)
+{
+  value *arg1 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
 
-    case TERNOP_SLICE:
-      {
-       struct value *array = evaluate_subexp (nullptr, exp, pos, noside);
-       struct value *low = evaluate_subexp (nullptr, exp, pos, noside);
-       struct value *upper = evaluate_subexp (nullptr, exp, pos, noside);
-       return eval_op_ternop (expect_type, exp, noside, array, low, upper);
-      }
+  value *arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp,
+                                                  EVAL_AVOID_SIDE_EFFECTS);
 
-    case TERNOP_COND:
-      /* Skip third and second args to evaluate the first one.  */
-      arg1 = evaluate_subexp (nullptr, exp, pos, noside);
-      if (value_logical_not (arg1))
-       {
-         evaluate_subexp (nullptr, exp, pos, EVAL_SKIP);
-         return evaluate_subexp (nullptr, exp, pos, noside);
-       }
-      else
+  if (binop_user_defined_p (BINOP_LOGICAL_OR, arg1, arg2))
+    {
+      arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
+      return value_x_binop (arg1, arg2, BINOP_LOGICAL_OR, OP_NULL, noside);
+    }
+  else
+    {
+      int tem = value_logical_not (arg1);
+      if (tem)
        {
-         arg2 = evaluate_subexp (nullptr, exp, pos, noside);
-         evaluate_subexp (nullptr, exp, pos, EVAL_SKIP);
-         return arg2;
+         arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
+         tem = value_logical_not (arg2);
        }
 
-    case OP_OBJC_SELECTOR:
-      {                                /* Objective C @selector operator.  */
-       char *sel = &exp->elts[pc + 2].string;
-       int len = longest_to_int (exp->elts[pc + 1].longconst);
-
-       (*pos) += 3 + BYTES_TO_EXP_ELEM (len + 1);
-       if (sel[len] != 0)
-         sel[len] = 0;         /* Make sure it's terminated.  */
-
-       return eval_op_objc_selector (expect_type, exp, noside, sel);
-      }
-
-    case OP_OBJC_MSGCALL:
-      {                                /* Objective C message (method) call.  */
-       CORE_ADDR selector = 0;
-
-       enum noside sub_no_side = EVAL_NORMAL;
+      struct type *type = language_bool_type (exp->language_defn,
+                                             exp->gdbarch);
+      return value_from_longest (type, !tem);
+    }
+}
 
-       struct value *target = NULL;
+value *
+adl_func_operation::evaluate (struct type *expect_type,
+                             struct expression *exp,
+                             enum noside noside)
+{
+  std::vector<operation_up> &arg_ops = std::get<2> (m_storage);
+  std::vector<value *> args (arg_ops.size ());
+  for (int i = 0; i < arg_ops.size (); ++i)
+    args[i] = arg_ops[i]->evaluate_with_coercion (exp, noside);
 
-       struct type *selector_type = NULL;
+  struct symbol *symp;
+  find_overload_match (args, std::get<0> (m_storage).c_str (),
+                      NON_METHOD,
+                      nullptr, nullptr,
+                      nullptr, &symp, nullptr, 0, noside);
+  if (SYMBOL_TYPE (symp)->code () == TYPE_CODE_ERROR)
+    error_unknown_type (symp->print_name ());
+  value *callee = evaluate_var_value (noside, std::get<1> (m_storage), symp);
+  return evaluate_subexp_do_call (exp, noside, callee, args,
+                                 nullptr, expect_type);
 
-       selector = exp->elts[pc + 1].longconst;
-       nargs = exp->elts[pc + 2].longconst;
-       argvec = XALLOCAVEC (struct value *, nargs + 3);
+}
 
-       (*pos) += 3;
+/* This function evaluates brace-initializers (in C/C++) for
+   structure types.  */
 
-       selector_type = builtin_type (exp->gdbarch)->builtin_data_ptr;
+struct value *
+array_operation::evaluate_struct_tuple (struct value *struct_val,
+                                       struct expression *exp,
+                                       enum noside noside, int nargs)
+{
+  const std::vector<operation_up> &in_args = std::get<2> (m_storage);
+  struct type *struct_type = check_typedef (value_type (struct_val));
+  struct type *field_type;
+  int fieldno = -1;
 
-       if (noside == EVAL_AVOID_SIDE_EFFECTS)
-         sub_no_side = EVAL_NORMAL;
-       else
-         sub_no_side = noside;
+  int idx = 0;
+  while (--nargs >= 0)
+    {
+      struct value *val = NULL;
+      int bitpos, bitsize;
+      bfd_byte *addr;
 
-       target = evaluate_subexp (selector_type, exp, pos, sub_no_side);
+      fieldno++;
+      /* Skip static fields.  */
+      while (fieldno < struct_type->num_fields ()
+            && field_is_static (&struct_type->field (fieldno)))
+       fieldno++;
+      if (fieldno >= struct_type->num_fields ())
+       error (_("too many initializers"));
+      field_type = struct_type->field (fieldno).type ();
+      if (field_type->code () == TYPE_CODE_UNION
+         && TYPE_FIELD_NAME (struct_type, fieldno)[0] == '0')
+       error (_("don't know which variant you want to set"));
 
-       if (value_as_long (target) == 0)
-         sub_no_side = EVAL_SKIP;
-       else
-         sub_no_side = noside;
+      /* Here, struct_type is the type of the inner struct,
+        while substruct_type is the type of the inner struct.
+        These are the same for normal structures, but a variant struct
+        contains anonymous union fields that contain substruct fields.
+        The value fieldno is the index of the top-level (normal or
+        anonymous union) field in struct_field, while the value
+        subfieldno is the index of the actual real (named inner) field
+        in substruct_type.  */
 
-       /* Now depending on whether we found a symbol for the method,
-          we will either call the runtime dispatcher or the method
-          directly.  */
+      field_type = struct_type->field (fieldno).type ();
+      if (val == 0)
+       val = in_args[idx++]->evaluate (field_type, exp, noside);
 
-       argvec[0] = nullptr;
-       argvec[1] = nullptr;
-       /* User-supplied arguments.  */
-       for (tem = 0; tem < nargs; tem++)
-         argvec[tem + 2] = evaluate_subexp_with_coercion (exp, pos,
-                                                          sub_no_side);
-       argvec[tem + 3] = 0;
+      /* Now actually set the field in struct_val.  */
 
-       auto call_args = gdb::make_array_view (argvec, nargs + 3);
+      /* Assign val to field fieldno.  */
+      if (value_type (val) != field_type)
+       val = value_cast (field_type, val);
 
-       return eval_op_objc_msgcall (expect_type, exp, noside, selector,
-                                    target, call_args);
-      }
-      break;
-
-    case OP_FUNCALL:
-      return evaluate_funcall (expect_type, exp, pos, noside);
-
-    case OP_COMPLEX:
-      /* We have a complex number, There should be 2 floating 
-        point numbers that compose it.  */
-      (*pos) += 2;
-      arg1 = evaluate_subexp (nullptr, exp, pos, noside);
-      arg2 = evaluate_subexp (nullptr, exp, pos, noside);
-
-      return value_literal_complex (arg1, arg2, exp->elts[pc + 1].type);
-
-    case STRUCTOP_STRUCT:
-      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_struct (expect_type, exp, noside, arg1,
-                                     &exp->elts[pc + 2].string);
-
-    case STRUCTOP_PTR:
-      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, arg1,
-                                  &exp->elts[pc + 2].string);
-
-    case STRUCTOP_MEMBER:
-    case STRUCTOP_MPTR:
-      if (op == STRUCTOP_MEMBER)
-       arg1 = evaluate_subexp_for_address (exp, pos, noside);
+      bitsize = TYPE_FIELD_BITSIZE (struct_type, fieldno);
+      bitpos = TYPE_FIELD_BITPOS (struct_type, fieldno);
+      addr = value_contents_writeable (struct_val) + bitpos / 8;
+      if (bitsize)
+       modify_field (struct_type, addr,
+                     value_as_long (val), bitpos % 8, bitsize);
       else
-       arg1 = evaluate_subexp (nullptr, exp, pos, noside);
+       memcpy (addr, value_contents (val),
+               TYPE_LENGTH (value_type (val)));
 
-      arg2 = evaluate_subexp (nullptr, exp, pos, noside);
+    }
+  return struct_val;
+}
 
-      return eval_op_member (expect_type, exp, noside, arg1, arg2);
+value *
+array_operation::evaluate (struct type *expect_type,
+                          struct expression *exp,
+                          enum noside noside)
+{
+  int tem;
+  int tem2 = std::get<0> (m_storage);
+  int tem3 = std::get<1> (m_storage);
+  const std::vector<operation_up> &in_args = std::get<2> (m_storage);
+  int nargs = tem3 - tem2 + 1;
+  struct type *type = expect_type ? check_typedef (expect_type) : nullptr;
 
-    case TYPE_INSTANCE:
-      {
-       type_instance_flags flags
-         = (type_instance_flag_value) longest_to_int (exp->elts[pc + 1].longconst);
-       nargs = longest_to_int (exp->elts[pc + 2].longconst);
-       arg_types = (struct type **) alloca (nargs * sizeof (struct type *));
-       for (ix = 0; ix < nargs; ++ix)
-         arg_types[ix] = exp->elts[pc + 2 + ix + 1].type;
-
-       fake_method fake_expect_type (flags, nargs, arg_types);
-       *(pos) += 4 + nargs;
-       return evaluate_subexp_standard (fake_expect_type.type (), exp, pos,
-                                        noside);
-      }
+  if (expect_type != nullptr
+      && type->code () == TYPE_CODE_STRUCT)
+    {
+      struct value *rec = allocate_value (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, arg1, arg2);
-
-    case BINOP_ASSIGN:
-      arg1 = evaluate_subexp (nullptr, exp, pos, noside);
-      /* Special-case assignments where the left-hand-side is a
-        convenience variable -- in these, don't bother setting an
-        expected type.  This avoids a weird case where re-assigning a
-        string or array to an internal variable could error with "Too
-        many array elements".  */
-      arg2 = evaluate_subexp (VALUE_LVAL (arg1) == lval_internalvar
-                               ? nullptr
-                               : value_type (arg1),
-                             exp, pos, noside);
-
-      if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
-       return arg1;
-      if (binop_user_defined_p (op, arg1, arg2))
-       return value_x_binop (arg1, arg2, op, OP_NULL, noside);
-      else
-       return value_assign (arg1, arg2);
-
-    case BINOP_ASSIGN_MODIFY:
-      (*pos) += 2;
-      arg1 = evaluate_subexp (nullptr, exp, pos, noside);
-      arg2 = evaluate_subexp (value_type (arg1), exp, pos, noside);
-      op = exp->elts[pc + 1].opcode;
-      return eval_binop_assign_modify (expect_type, exp, noside, op,
-                                      arg1, arg2);
-
-    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, 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, arg1, arg2);
-
-    case BINOP_EXP:
-    case BINOP_MUL:
-    case BINOP_DIV:
-    case BINOP_INTDIV:
-    case BINOP_REM:
-    case BINOP_MOD:
-    case BINOP_LSH:
-    case BINOP_RSH:
-    case BINOP_BITWISE_AND:
-    case BINOP_BITWISE_IOR:
-    case BINOP_BITWISE_XOR:
-      arg1 = evaluate_subexp (nullptr, exp, pos, noside);
-      arg2 = evaluate_subexp (nullptr, exp, pos, noside);
-      return eval_op_binary (expect_type, exp, noside, op, arg1, arg2);
-
-    case BINOP_SUBSCRIPT:
-      arg1 = evaluate_subexp (nullptr, exp, pos, noside);
-      arg2 = evaluate_subexp (nullptr, exp, pos, noside);
-      return eval_op_subscript (expect_type, exp, noside, op, arg1, arg2);
-
-    case MULTI_SUBSCRIPT:
-      (*pos) += 2;
-      nargs = longest_to_int (exp->elts[pc + 1].longconst);
-      arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
-      argvec = XALLOCAVEC (struct value *, nargs);
-      for (ix = 0; ix < nargs; ++ix)
-       argvec[ix] = evaluate_subexp_with_coercion (exp, pos, noside);
-      return eval_multi_subscript (expect_type, exp, noside, arg1,
-                                  gdb::make_array_view (argvec, nargs));
-
-    case BINOP_LOGICAL_AND:
-      arg1 = evaluate_subexp (nullptr, exp, pos, noside);
-      if (noside == EVAL_SKIP)
-       {
-         evaluate_subexp (nullptr, exp, pos, noside);
-         return eval_skip_value (exp);
-       }
+      memset (value_contents_raw (rec), '\0', TYPE_LENGTH (type));
+      return evaluate_struct_tuple (rec, exp, noside, nargs);
+    }
 
-      oldpos = *pos;
-      arg2 = evaluate_subexp (nullptr, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
-      *pos = oldpos;
+  if (expect_type != nullptr
+      && type->code () == TYPE_CODE_ARRAY)
+    {
+      struct type *range_type = type->index_type ();
+      struct type *element_type = TYPE_TARGET_TYPE (type);
+      struct value *array = allocate_value (expect_type);
+      int element_size = TYPE_LENGTH (check_typedef (element_type));
+      LONGEST low_bound, high_bound, index;
 
-      if (binop_user_defined_p (op, arg1, arg2))
+      if (!get_discrete_bounds (range_type, &low_bound, &high_bound))
        {
-         arg2 = evaluate_subexp (nullptr, exp, pos, noside);
-         return value_x_binop (arg1, arg2, op, OP_NULL, noside);
+         low_bound = 0;
+         high_bound = (TYPE_LENGTH (type) / element_size) - 1;
        }
-      else
+      index = low_bound;
+      memset (value_contents_raw (array), 0, TYPE_LENGTH (expect_type));
+      for (tem = nargs; --nargs >= 0;)
        {
-         tem = value_logical_not (arg1);
-         arg2
-           = evaluate_subexp (nullptr, exp, pos, (tem ? EVAL_SKIP : noside));
-         type = language_bool_type (exp->language_defn, exp->gdbarch);
-         return value_from_longest (type,
-                            (LONGEST) (!tem && !value_logical_not (arg2)));
-       }
+         struct value *element;
 
-    case BINOP_LOGICAL_OR:
-      arg1 = evaluate_subexp (nullptr, exp, pos, noside);
-      if (noside == EVAL_SKIP)
-       {
-         evaluate_subexp (nullptr, exp, pos, noside);
-         return eval_skip_value (exp);
+         element = in_args[index - low_bound]->evaluate (element_type,
+                                                         exp, noside);
+         if (value_type (element) != element_type)
+           element = value_cast (element_type, element);
+         if (index > high_bound)
+           /* To avoid memory corruption.  */
+           error (_("Too many array elements"));
+         memcpy (value_contents_raw (array)
+                 + (index - low_bound) * element_size,
+                 value_contents (element),
+                 element_size);
+         index++;
        }
+      return array;
+    }
 
-      oldpos = *pos;
-      arg2 = evaluate_subexp (nullptr, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
-      *pos = oldpos;
-
-      if (binop_user_defined_p (op, arg1, arg2))
-       {
-         arg2 = evaluate_subexp (nullptr, exp, pos, noside);
-         return value_x_binop (arg1, arg2, op, OP_NULL, noside);
-       }
-      else
-       {
-         tem = value_logical_not (arg1);
-         arg2
-           = evaluate_subexp (nullptr, exp, pos, (!tem ? EVAL_SKIP : noside));
-         type = language_bool_type (exp->language_defn, exp->gdbarch);
-         return value_from_longest (type,
-                            (LONGEST) (!tem || !value_logical_not (arg2)));
-       }
+  if (expect_type != nullptr
+      && type->code () == TYPE_CODE_SET)
+    {
+      struct value *set = allocate_value (expect_type);
+      gdb_byte *valaddr = value_contents_raw (set);
+      struct type *element_type = type->index_type ();
+      struct type *check_type = element_type;
+      LONGEST low_bound, high_bound;
 
-    case BINOP_EQUAL:
-      arg1 = evaluate_subexp (nullptr, exp, pos, noside);
-      arg2 = evaluate_subexp (value_type (arg1), exp, pos, noside);
-      return eval_op_equal (expect_type, exp, noside, op, arg1, arg2);
-
-    case BINOP_NOTEQUAL:
-      arg1 = evaluate_subexp (nullptr, exp, pos, noside);
-      arg2 = evaluate_subexp (value_type (arg1), exp, pos, noside);
-      return eval_op_notequal (expect_type, exp, noside, op, arg1, arg2);
-
-    case BINOP_LESS:
-      arg1 = evaluate_subexp (nullptr, exp, pos, noside);
-      arg2 = evaluate_subexp (value_type (arg1), exp, pos, noside);
-      return eval_op_less (expect_type, exp, noside, op, arg1, arg2);
-
-    case BINOP_GTR:
-      arg1 = evaluate_subexp (nullptr, exp, pos, noside);
-      arg2 = evaluate_subexp (value_type (arg1), exp, pos, noside);
-      return eval_op_gtr (expect_type, exp, noside, op, arg1, arg2);
-
-    case BINOP_GEQ:
-      arg1 = evaluate_subexp (nullptr, exp, pos, noside);
-      arg2 = evaluate_subexp (value_type (arg1), exp, pos, noside);
-      return eval_op_geq (expect_type, exp, noside, op, arg1, arg2);
-
-    case BINOP_LEQ:
-      arg1 = evaluate_subexp (nullptr, exp, pos, noside);
-      arg2 = evaluate_subexp (value_type (arg1), exp, pos, noside);
-      return eval_op_leq (expect_type, exp, noside, op, arg1, arg2);
-
-    case BINOP_REPEAT:
-      arg1 = evaluate_subexp (nullptr, exp, pos, noside);
-      arg2 = evaluate_subexp (nullptr, exp, pos, noside);
-      return eval_op_repeat (expect_type, exp, noside, arg1, arg2);
-
-    case BINOP_COMMA:
-      evaluate_subexp (nullptr, exp, pos, noside);
-      return evaluate_subexp (nullptr, exp, pos, noside);
-
-    case UNOP_PLUS:
-      arg1 = evaluate_subexp (nullptr, exp, pos, noside);
-      return eval_op_plus (expect_type, exp, noside, op, arg1);
-      
-    case UNOP_NEG:
-      arg1 = evaluate_subexp (nullptr, exp, pos, noside);
-      return eval_op_neg (expect_type, exp, noside, op, arg1);
-
-    case UNOP_COMPLEMENT:
-      /* C++: check for and handle destructor names.  */
-
-      arg1 = evaluate_subexp (nullptr, exp, pos, noside);
-      return eval_op_complement (expect_type, exp, noside, op, arg1);
-
-    case UNOP_LOGICAL_NOT:
-      arg1 = evaluate_subexp (nullptr, exp, pos, noside);
-      return eval_op_lognot (expect_type, exp, noside, op, arg1);
-
-    case UNOP_IND:
-      if (expect_type && expect_type->code () == TYPE_CODE_PTR)
-       expect_type = TYPE_TARGET_TYPE (check_typedef (expect_type));
-      arg1 = evaluate_subexp (expect_type, exp, pos, noside);
-      return eval_op_ind (expect_type, exp, noside, op, arg1);
-
-    case UNOP_ADDR:
-      /* C++: check for and handle pointer to members.  */
-
-      if (noside == EVAL_SKIP)
-       {
-         evaluate_subexp (nullptr, exp, pos, EVAL_SKIP);
-         return eval_skip_value (exp);
-       }
-      else
-       return evaluate_subexp_for_address (exp, pos, noside);
+      /* Get targettype of elementtype.  */
+      while (check_type->code () == TYPE_CODE_RANGE
+            || check_type->code () == TYPE_CODE_TYPEDEF)
+       check_type = TYPE_TARGET_TYPE (check_type);
 
-    case UNOP_SIZEOF:
-      if (noside == EVAL_SKIP)
-       {
-         evaluate_subexp (nullptr, exp, pos, EVAL_SKIP);
-         return eval_skip_value (exp);
-       }
-      return evaluate_subexp_for_sizeof (exp, pos, noside);
-
-    case UNOP_ALIGNOF:
-      arg1 = evaluate_subexp (nullptr, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
-      return eval_op_alignof (expect_type, exp, noside, arg1);
-
-    case UNOP_CAST:
-      (*pos) += 2;
-      type = exp->elts[pc + 1].type;
-      return evaluate_subexp_for_cast (exp, pos, noside, type);
-
-    case UNOP_CAST_TYPE:
-      arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
-      type = value_type (arg1);
-      return evaluate_subexp_for_cast (exp, pos, noside, type);
-
-    case UNOP_DYNAMIC_CAST:
-      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)
-       return eval_skip_value (exp);
-      return value_dynamic_cast (type, arg1);
-
-    case UNOP_REINTERPRET_CAST:
-      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)
-       return eval_skip_value (exp);
-      return value_reinterpret_cast (type, arg1);
-
-    case UNOP_MEMVAL:
-      (*pos) += 2;
-      arg1 = evaluate_subexp (expect_type, exp, pos, noside);
-      return eval_op_memval (expect_type, exp, noside, arg1,
-                            exp->elts[pc + 1].type);
-
-    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);
-      return eval_op_memval (expect_type, exp, noside, arg1, type);
-
-    case UNOP_PREINCREMENT:
-      arg1 = evaluate_subexp (expect_type, exp, pos, noside);
-      return eval_op_preinc (expect_type, exp, noside, op, arg1);
-
-    case UNOP_PREDECREMENT:
-      arg1 = evaluate_subexp (expect_type, exp, pos, noside);
-      return eval_op_predec (expect_type, exp, noside, op, arg1);
-
-    case UNOP_POSTINCREMENT:
-      arg1 = evaluate_subexp (expect_type, exp, pos, noside);
-      return eval_op_postinc (expect_type, exp, noside, op, arg1);
-
-    case UNOP_POSTDECREMENT:
-      arg1 = evaluate_subexp (expect_type, exp, pos, noside);
-      return eval_op_postdec (expect_type, exp, noside, op, arg1);
-
-    case OP_THIS:
-      (*pos) += 1;
-      return value_of_this (exp->language_defn);
-
-    case OP_TYPE:
-      /* The value is not supposed to be used.  This is here to make it
-        easier to accommodate expressions that contain types.  */
-      (*pos) += 2;
-      return eval_op_type (expect_type, exp, noside, exp->elts[pc + 1].type);
-
-    case OP_TYPEOF:
-    case OP_DECLTYPE:
-      if (noside == EVAL_SKIP)
-       {
-         evaluate_subexp (nullptr, exp, pos, EVAL_SKIP);
-         return eval_skip_value (exp);
-       }
-      else if (noside == EVAL_AVOID_SIDE_EFFECTS)
+      if (!get_discrete_bounds (element_type, &low_bound, &high_bound))
+       error (_("(power)set type with unknown size"));
+      memset (valaddr, '\0', TYPE_LENGTH (type));
+      int idx = 0;
+      for (tem = 0; tem < nargs; tem++)
        {
-         enum exp_opcode sub_op = exp->elts[*pos].opcode;
-         struct value *result;
-
-         result = evaluate_subexp (nullptr, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
-
-         /* 'decltype' has special semantics for lvalues.  */
-         if (op == OP_DECLTYPE
-             && (sub_op == BINOP_SUBSCRIPT
-                 || sub_op == STRUCTOP_MEMBER
-                 || sub_op == STRUCTOP_MPTR
-                 || sub_op == UNOP_IND
-                 || sub_op == STRUCTOP_STRUCT
-                 || sub_op == STRUCTOP_PTR
-                 || sub_op == OP_SCOPE))
+         LONGEST range_low, range_high;
+         struct type *range_low_type, *range_high_type;
+         struct value *elem_val;
+
+         elem_val = in_args[idx++]->evaluate (element_type, exp, noside);
+         range_low_type = range_high_type = value_type (elem_val);
+         range_low = range_high = value_as_long (elem_val);
+
+         /* Check types of elements to avoid mixture of elements from
+            different types. Also check if type of element is "compatible"
+            with element type of powerset.  */
+         if (range_low_type->code () == TYPE_CODE_RANGE)
+           range_low_type = TYPE_TARGET_TYPE (range_low_type);
+         if (range_high_type->code () == TYPE_CODE_RANGE)
+           range_high_type = TYPE_TARGET_TYPE (range_high_type);
+         if ((range_low_type->code () != range_high_type->code ())
+             || (range_low_type->code () == TYPE_CODE_ENUM
+                 && (range_low_type != range_high_type)))
+           /* different element modes.  */
+           error (_("POWERSET tuple elements of different mode"));
+         if ((check_type->code () != range_low_type->code ())
+             || (check_type->code () == TYPE_CODE_ENUM
+                 && range_low_type != check_type))
+           error (_("incompatible POWERSET tuple elements"));
+         if (range_low > range_high)
            {
-             type = value_type (result);
-
-             if (!TYPE_IS_REFERENCE (type))
-               {
-                 type = lookup_lvalue_reference_type (type);
-                 result = allocate_value (type);
-               }
+             warning (_("empty POWERSET tuple range"));
+             continue;
            }
+         if (range_low < low_bound || range_high > high_bound)
+           error (_("POWERSET tuple element out of range"));
+         range_low -= low_bound;
+         range_high -= low_bound;
+         for (; range_low <= range_high; range_low++)
+           {
+             int bit_index = (unsigned) range_low % TARGET_CHAR_BIT;
 
-         return result;
+             if (gdbarch_byte_order (exp->gdbarch) == BFD_ENDIAN_BIG)
+               bit_index = TARGET_CHAR_BIT - 1 - bit_index;
+             valaddr[(unsigned) range_low / TARGET_CHAR_BIT]
+               |= 1 << bit_index;
+           }
        }
-      else
-       error (_("Attempt to use a type as an expression"));
-
-    case OP_TYPEID:
-      {
-       struct value *result;
-       enum exp_opcode sub_op = exp->elts[*pos].opcode;
-
-       if (sub_op == OP_TYPE || sub_op == OP_DECLTYPE || sub_op == OP_TYPEOF)
-         result = evaluate_subexp (nullptr, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
-       else
-         result = evaluate_subexp (nullptr, exp, pos, noside);
-
-       if (noside != EVAL_NORMAL)
-         return allocate_value (cplus_typeid_type (exp->gdbarch));
-
-       return cplus_typeid (result);
-      }
-
-    default:
-      /* Removing this case and compiling with gcc -Wall reveals that
-        a lot of cases are hitting this case.  Some of these should
-        probably be removed from expression.h; others are legitimate
-        expressions which are (apparently) not fully implemented.
-
-        If there are any cases landing here which mean a user error,
-        then they should be separate cases, with more descriptive
-        error messages.  */
+      return set;
+    }
 
-      error (_("GDB does not (yet) know how to "
-              "evaluate that kind of expression"));
+  value **argvec = XALLOCAVEC (struct value *, nargs);
+  for (tem = 0; tem < nargs; tem++)
+    {
+      /* Ensure that array expressions are coerced into pointer
+        objects.  */
+      argvec[tem] = in_args[tem]->evaluate_with_coercion (exp, noside);
     }
+  return value_array (tem2, tem3, argvec);
+}
 
-  gdb_assert_not_reached ("missed return?");
 }
+
 \f
 /* Helper for evaluate_subexp_for_address.  */
 
@@ -3157,117 +2495,6 @@ evaluate_subexp_for_address_base (struct expression *exp, enum noside noside,
   return value_addr (x);
 }
 
-/* Evaluate a subexpression of EXP, at index *POS,
-   and return the address of that subexpression.
-   Advance *POS over the subexpression.
-   If the subexpression isn't an lvalue, get an error.
-   NOSIDE may be EVAL_AVOID_SIDE_EFFECTS;
-   then only the type of the result need be correct.  */
-
-static struct value *
-evaluate_subexp_for_address (struct expression *exp, int *pos,
-                            enum noside noside)
-{
-  enum exp_opcode op;
-  int pc;
-  struct symbol *var;
-  struct value *x;
-  int tem;
-
-  pc = (*pos);
-  op = exp->elts[pc].opcode;
-
-  switch (op)
-    {
-    case UNOP_IND:
-      (*pos)++;
-      x = evaluate_subexp (nullptr, exp, pos, noside);
-
-      /* We can't optimize out "&*" if there's a user-defined operator*.  */
-      if (unop_user_defined_p (op, x))
-       {
-         x = value_x_unop (x, op, noside);
-         goto default_case_after_eval;
-       }
-
-      return coerce_array (x);
-
-    case UNOP_MEMVAL:
-      (*pos) += 3;
-      return value_cast (lookup_pointer_type (exp->elts[pc + 1].type),
-                        evaluate_subexp (nullptr, exp, pos, noside));
-
-    case UNOP_MEMVAL_TYPE:
-      {
-       struct type *type;
-
-       (*pos) += 1;
-       x = evaluate_subexp (nullptr, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
-       type = value_type (x);
-       return value_cast (lookup_pointer_type (type),
-                          evaluate_subexp (nullptr, exp, pos, noside));
-      }
-
-    case OP_VAR_VALUE:
-      var = exp->elts[pc + 2].symbol;
-
-      /* C++: The "address" of a reference should yield the address
-       * of the object pointed to.  Let value_addr() deal with it.  */
-      if (TYPE_IS_REFERENCE (SYMBOL_TYPE (var)))
-       goto default_case;
-
-      (*pos) += 4;
-      if (noside == EVAL_AVOID_SIDE_EFFECTS)
-       {
-         struct type *type =
-           lookup_pointer_type (SYMBOL_TYPE (var));
-         enum address_class sym_class = SYMBOL_CLASS (var);
-
-         if (sym_class == LOC_CONST
-             || sym_class == LOC_CONST_BYTES
-             || sym_class == LOC_REGISTER)
-           error (_("Attempt to take address of register or constant."));
-
-         return
-           value_zero (type, not_lval);
-       }
-      else
-       return address_of_variable (var, exp->elts[pc + 1].block);
-
-    case OP_VAR_MSYM_VALUE:
-      {
-       (*pos) += 4;
-
-       value *val = evaluate_var_msym_value (noside,
-                                             exp->elts[pc + 1].objfile,
-                                             exp->elts[pc + 2].msymbol);
-       if (noside == EVAL_AVOID_SIDE_EFFECTS)
-         {
-           struct type *type = lookup_pointer_type (value_type (val));
-           return value_zero (type, not_lval);
-         }
-       else
-         return value_addr (val);
-      }
-
-    case OP_SCOPE:
-      tem = longest_to_int (exp->elts[pc + 2].longconst);
-      (*pos) += 5 + BYTES_TO_EXP_ELEM (tem + 1);
-      x = value_aggregate_elt (exp->elts[pc + 1].type,
-                              &exp->elts[pc + 3].string,
-                              NULL, 1, noside);
-      if (x == NULL)
-       error (_("There is no field named %s"), &exp->elts[pc + 3].string);
-      return x;
-
-    default:
-    default_case:
-      x = evaluate_subexp (nullptr, exp, pos, noside);
-    default_case_after_eval:
-      return evaluate_subexp_for_address_base (exp, noside, x);
-    }
-}
-
 namespace expr
 {
 
@@ -3277,8 +2504,6 @@ operation::evaluate_for_cast (struct type *expect_type,
                              enum noside noside)
 {
   value *val = evaluate (expect_type, exp, noside);
-  if (noside == EVAL_SKIP)
-    return eval_skip_value (exp);
   return value_cast (expect_type, val);
 }
 
@@ -3301,13 +2526,28 @@ scope_operation::evaluate_for_address (struct expression *exp,
   return x;
 }
 
+value *
+unop_ind_base_operation::evaluate_for_address (struct expression *exp,
+                                              enum noside noside)
+{
+  value *x = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
+
+  /* We can't optimize out "&*" if there's a user-defined operator*.  */
+  if (unop_user_defined_p (UNOP_IND, x))
+    {
+      x = value_x_unop (x, UNOP_IND, noside);
+      return evaluate_subexp_for_address_base (exp, noside, x);
+    }
+
+  return coerce_array (x);
+}
+
 value *
 var_msym_value_operation::evaluate_for_address (struct expression *exp,
                                                enum noside noside)
 {
-  value *val = evaluate_var_msym_value (noside,
-                                       std::get<1> (m_storage),
-                                       std::get<0> (m_storage));
+  const bound_minimal_symbol &b = std::get<0> (m_storage);
+  value *val = evaluate_var_msym_value (noside, b.objfile, b.minsym);
   if (noside == EVAL_AVOID_SIDE_EFFECTS)
     {
       struct type *type = lookup_pointer_type (value_type (val));
@@ -3317,51 +2557,69 @@ var_msym_value_operation::evaluate_for_address (struct expression *exp,
     return value_addr (val);
 }
 
+value *
+unop_memval_operation::evaluate_for_address (struct expression *exp,
+                                            enum noside noside)
+{
+  return value_cast (lookup_pointer_type (std::get<1> (m_storage)),
+                    std::get<0> (m_storage)->evaluate (nullptr, exp, noside));
 }
 
-/* Evaluate like `evaluate_subexp' except coercing arrays to pointers.
-   When used in contexts where arrays will be coerced anyway, this is
-   equivalent to `evaluate_subexp' but much faster because it avoids
-   actually fetching array contents (perhaps obsolete now that we have
-   value_lazy()).
-
-   Note that we currently only do the coercion for C expressions, where
-   arrays are zero based and the coercion is correct.  For other languages,
-   with nonzero based arrays, coercion loses.  Use CAST_IS_CONVERSION
-   to decide if coercion is appropriate.  */
+value *
+unop_memval_type_operation::evaluate_for_address (struct expression *exp,
+                                                 enum noside noside)
+{
+  value *typeval = std::get<0> (m_storage)->evaluate (nullptr, exp,
+                                                     EVAL_AVOID_SIDE_EFFECTS);
+  struct type *type = value_type (typeval);
+  return value_cast (lookup_pointer_type (type),
+                    std::get<1> (m_storage)->evaluate (nullptr, exp, noside));
+}
 
-struct value *
-evaluate_subexp_with_coercion (struct expression *exp,
-                              int *pos, enum noside noside)
+value *
+var_value_operation::evaluate_for_address (struct expression *exp,
+                                          enum noside noside)
 {
-  enum exp_opcode op;
-  int pc;
-  struct value *val;
-  struct symbol *var;
-  struct type *type;
+  symbol *var = std::get<0> (m_storage).symbol;
 
-  pc = (*pos);
-  op = exp->elts[pc].opcode;
+  /* C++: The "address" of a reference should yield the address
+   * of the object pointed to.  Let value_addr() deal with it.  */
+  if (TYPE_IS_REFERENCE (SYMBOL_TYPE (var)))
+    return operation::evaluate_for_address (exp, noside);
 
-  switch (op)
+  if (noside == EVAL_AVOID_SIDE_EFFECTS)
     {
-    case OP_VAR_VALUE:
-      var = exp->elts[pc + 2].symbol;
-      type = check_typedef (SYMBOL_TYPE (var));
-      if (type->code () == TYPE_CODE_ARRAY
-         && !type->is_vector ()
-         && CAST_IS_CONVERSION (exp->language_defn))
-       {
-         (*pos) += 4;
-         val = address_of_variable (var, exp->elts[pc + 1].block);
-         return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
-                            val);
-       }
-      /* FALLTHROUGH */
+      struct type *type = lookup_pointer_type (SYMBOL_TYPE (var));
+      enum address_class sym_class = SYMBOL_CLASS (var);
 
-    default:
-      return evaluate_subexp (nullptr, exp, pos, noside);
+      if (sym_class == LOC_CONST
+         || sym_class == LOC_CONST_BYTES
+         || sym_class == LOC_REGISTER)
+       error (_("Attempt to take address of register or constant."));
+
+      return value_zero (type, not_lval);
     }
+  else
+    return address_of_variable (var, std::get<0> (m_storage).block);
+}
+
+value *
+var_value_operation::evaluate_with_coercion (struct expression *exp,
+                                            enum noside noside)
+{
+  struct symbol *var = std::get<0> (m_storage).symbol;
+  struct type *type = check_typedef (SYMBOL_TYPE (var));
+  if (type->code () == TYPE_CODE_ARRAY
+      && !type->is_vector ()
+      && CAST_IS_CONVERSION (exp->language_defn))
+    {
+      struct value *val = address_of_variable (var,
+                                              std::get<0> (m_storage).block);
+      return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (type)), val);
+    }
+  return evaluate (nullptr, exp, noside);
+}
+
 }
 
 /* Helper function for evaluating the size of a type.  */
@@ -3381,132 +2639,6 @@ evaluate_subexp_for_sizeof_base (struct expression *exp, struct type *type)
   return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type));
 }
 
-/* Evaluate a subexpression of EXP, at index *POS,
-   and return a value for the size of that subexpression.
-   Advance *POS over the subexpression.  If NOSIDE is EVAL_NORMAL
-   we allow side-effects on the operand if its type is a variable
-   length array.   */
-
-static struct value *
-evaluate_subexp_for_sizeof (struct expression *exp, int *pos,
-                           enum noside noside)
-{
-  /* FIXME: This should be size_t.  */
-  struct type *size_type = builtin_type (exp->gdbarch)->builtin_int;
-  enum exp_opcode op;
-  int pc;
-  struct type *type;
-  struct value *val;
-
-  pc = (*pos);
-  op = exp->elts[pc].opcode;
-
-  switch (op)
-    {
-      /* This case is handled specially
-        so that we avoid creating a value for the result type.
-        If the result type is very big, it's desirable not to
-        create a value unnecessarily.  */
-    case UNOP_IND:
-      (*pos)++;
-      val = evaluate_subexp (nullptr, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
-      type = check_typedef (value_type (val));
-      if (type->code () != TYPE_CODE_PTR
-         && !TYPE_IS_REFERENCE (type)
-         && type->code () != TYPE_CODE_ARRAY)
-       error (_("Attempt to take contents of a non-pointer value."));
-      type = TYPE_TARGET_TYPE (type);
-      if (is_dynamic_type (type))
-       type = value_type (value_ind (val));
-      return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type));
-
-    case UNOP_MEMVAL:
-      (*pos) += 3;
-      type = exp->elts[pc + 1].type;
-      break;
-
-    case UNOP_MEMVAL_TYPE:
-      (*pos) += 1;
-      val = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
-      type = value_type (val);
-      break;
-
-    case OP_VAR_VALUE:
-      type = SYMBOL_TYPE (exp->elts[pc + 2].symbol);
-      if (is_dynamic_type (type))
-       {
-         val = evaluate_subexp (nullptr, exp, pos, EVAL_NORMAL);
-         type = value_type (val);
-         if (type->code () == TYPE_CODE_ARRAY)
-           {
-             if (type_not_allocated (type) || type_not_associated (type))
-               return value_zero (size_type, not_lval);
-             else if (is_dynamic_type (type->index_type ())
-                      && type->bounds ()->high.kind () == PROP_UNDEFINED)
-               return allocate_optimized_out_value (size_type);
-           }
-       }
-      else
-       (*pos) += 4;
-      break;
-
-    case OP_VAR_MSYM_VALUE:
-      {
-       (*pos) += 4;
-
-       minimal_symbol *msymbol = exp->elts[pc + 2].msymbol;
-       value *mval = evaluate_var_msym_value (noside,
-                                              exp->elts[pc + 1].objfile,
-                                              msymbol);
-
-       type = value_type (mval);
-       if (type->code () == TYPE_CODE_ERROR)
-         error_unknown_type (msymbol->print_name ());
-
-       return value_from_longest (size_type, TYPE_LENGTH (type));
-      }
-      break;
-
-      /* Deal with the special case if NOSIDE is EVAL_NORMAL and the resulting
-        type of the subscript is a variable length array type. In this case we
-        must re-evaluate the right hand side of the subscription to allow
-        side-effects. */
-    case BINOP_SUBSCRIPT:
-      if (noside == EVAL_NORMAL)
-       {
-         int npc = (*pos) + 1;
-
-         val = evaluate_subexp (nullptr, exp, &npc, EVAL_AVOID_SIDE_EFFECTS);
-         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_subexp (nullptr, exp, pos, EVAL_NORMAL);
-                     return value_from_longest
-                       (size_type, (LONGEST) TYPE_LENGTH (value_type (val)));
-                   }
-               }
-           }
-       }
-
-      /* Fall through.  */
-
-    default:
-      val = evaluate_subexp (nullptr, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
-      type = value_type (val);
-      break;
-    }
-
-  return evaluate_subexp_for_sizeof_base (exp, type);
-}
-
 namespace expr
 {
 
@@ -3522,14 +2654,12 @@ var_msym_value_operation::evaluate_for_sizeof (struct expression *exp,
                                               enum noside noside)
 
 {
-  minimal_symbol *msymbol = std::get<0> (m_storage);
-  value *mval = evaluate_var_msym_value (noside,
-                                        std::get<1> (m_storage),
-                                        msymbol);
+  const bound_minimal_symbol &b = std::get<0> (m_storage);
+  value *mval = evaluate_var_msym_value (noside, b.objfile, b.minsym);
 
   struct type *type = value_type (mval);
   if (type->code () == TYPE_CODE_ERROR)
-    error_unknown_type (msymbol->print_name ());
+    error_unknown_type (b.minsym->print_name ());
 
   /* FIXME: This should be size_t.  */
   struct type *size_type = builtin_type (exp->gdbarch)->builtin_int;
@@ -3569,66 +2699,64 @@ subscript_operation::evaluate_for_sizeof (struct expression *exp,
   return operation::evaluate_for_sizeof (exp, noside);
 }
 
+value *
+unop_ind_base_operation::evaluate_for_sizeof (struct expression *exp,
+                                             enum noside noside)
+{
+  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_PTR
+      && !TYPE_IS_REFERENCE (type)
+      && type->code () != TYPE_CODE_ARRAY)
+    error (_("Attempt to take contents of a non-pointer value."));
+  type = TYPE_TARGET_TYPE (type);
+  if (is_dynamic_type (type))
+    type = value_type (value_ind (val));
+  /* 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 (type));
 }
 
-/* Evaluate a subexpression of EXP, at index *POS, and return a value
-   for that subexpression cast to TO_TYPE.  Advance *POS over the
-   subexpression.  */
+value *
+unop_memval_operation::evaluate_for_sizeof (struct expression *exp,
+                                           enum noside noside)
+{
+  return evaluate_subexp_for_sizeof_base (exp, std::get<1> (m_storage));
+}
 
-static value *
-evaluate_subexp_for_cast (expression *exp, int *pos,
-                         enum noside noside,
-                         struct type *to_type)
+value *
+unop_memval_type_operation::evaluate_for_sizeof (struct expression *exp,
+                                                enum noside noside)
 {
-  int pc = *pos;
+  value *typeval = std::get<0> (m_storage)->evaluate (nullptr, exp,
+                                                     EVAL_AVOID_SIDE_EFFECTS);
+  return evaluate_subexp_for_sizeof_base (exp, value_type (typeval));
+}
 
-  /* Don't let symbols be evaluated with evaluate_subexp because that
-     throws an "unknown type" error for no-debug data symbols.
-     Instead, we want the cast to reinterpret the symbol.  */
-  if (exp->elts[pc].opcode == OP_VAR_MSYM_VALUE
-      || exp->elts[pc].opcode == OP_VAR_VALUE)
+value *
+var_value_operation::evaluate_for_sizeof (struct expression *exp,
+                                         enum noside noside)
+{
+  struct type *type = SYMBOL_TYPE (std::get<0> (m_storage).symbol);
+  if (is_dynamic_type (type))
     {
-      (*pos) += 4;
-
-      value *val;
-      if (exp->elts[pc].opcode == OP_VAR_MSYM_VALUE)
-       {
-         if (noside == EVAL_AVOID_SIDE_EFFECTS)
-           return value_zero (to_type, not_lval);
-
-         val = evaluate_var_msym_value (noside,
-                                        exp->elts[pc + 1].objfile,
-                                        exp->elts[pc + 2].msymbol);
-       }
-      else
-       val = evaluate_var_value (noside,
-                                 exp->elts[pc + 1].block,
-                                 exp->elts[pc + 2].symbol);
-
-      if (noside == EVAL_SKIP)
-       return eval_skip_value (exp);
-
-      val = value_cast (to_type, val);
-
-      /* Don't allow e.g. '&(int)var_with_no_debug_info'.  */
-      if (VALUE_LVAL (val) == lval_memory)
+      value *val = evaluate (nullptr, exp, EVAL_NORMAL);
+      type = value_type (val);
+      if (type->code () == TYPE_CODE_ARRAY)
        {
-         if (value_lazy (val))
-           value_fetch_lazy (val);
-         VALUE_LVAL (val) = not_lval;
+         /* FIXME: This should be size_t.  */
+         struct type *size_type = builtin_type (exp->gdbarch)->builtin_int;
+         if (type_not_allocated (type) || type_not_associated (type))
+           return value_zero (size_type, not_lval);
+         else if (is_dynamic_type (type->index_type ())
+                  && type->bounds ()->high.kind () == PROP_UNDEFINED)
+           return allocate_optimized_out_value (size_type);
        }
-      return val;
     }
-
-  value *val = evaluate_subexp (to_type, exp, pos, noside);
-  if (noside == EVAL_SKIP)
-    return eval_skip_value (exp);
-  return value_cast (to_type, val);
+  return evaluate_subexp_for_sizeof_base (exp, type);
 }
 
-namespace expr
-{
-
 value *
 var_msym_value_operation::evaluate_for_cast (struct type *to_type,
                                             struct expression *exp,
@@ -3637,12 +2765,29 @@ var_msym_value_operation::evaluate_for_cast (struct type *to_type,
   if (noside == EVAL_AVOID_SIDE_EFFECTS)
     return value_zero (to_type, not_lval);
 
-  value *val = evaluate_var_msym_value (noside,
-                                       std::get<1> (m_storage),
-                                       std::get<0> (m_storage));
+  const bound_minimal_symbol &b = std::get<0> (m_storage);
+  value *val = evaluate_var_msym_value (noside, b.objfile, b.minsym);
+
+  val = value_cast (to_type, val);
+
+  /* Don't allow e.g. '&(int)var_with_no_debug_info'.  */
+  if (VALUE_LVAL (val) == lval_memory)
+    {
+      if (value_lazy (val))
+       value_fetch_lazy (val);
+      VALUE_LVAL (val) = not_lval;
+    }
+  return val;
+}
 
-  if (noside == EVAL_SKIP)
-    return eval_skip_value (exp);
+value *
+var_value_operation::evaluate_for_cast (struct type *to_type,
+                                       struct expression *exp,
+                                       enum noside noside)
+{
+  value *val = evaluate_var_value (noside,
+                                  std::get<0> (m_storage).block,
+                                  std::get<0> (m_storage).symbol);
 
   val = value_cast (to_type, val);
 
@@ -3671,7 +2816,9 @@ parse_and_eval_type (const char *p, int length)
   tmp[length + 2] = '0';
   tmp[length + 3] = '\0';
   expression_up expr = parse_expression (tmp);
-  if (expr->first_opcode () != UNOP_CAST)
+  expr::unop_cast_operation *op
+    = dynamic_cast<expr::unop_cast_operation *> (expr->op.get ());
+  if (op == nullptr)
     error (_("Internal error in eval_type."));
-  return expr->elts[1].type;
+  return op->get_type ();
 }
This page took 0.057607 seconds and 4 git commands to generate.