+ tem = longest_to_int (exp->elts[pc + 1].longconst);
+ (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ return value_string (&exp->elts[pc + 2].string, tem);
+
+ case OP_BITSTRING:
+ tem = longest_to_int (exp->elts[pc + 1].longconst);
+ (*pos)
+ += 3 + BYTES_TO_EXP_ELEM ((tem + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ return value_bitstring (&exp->elts[pc + 2].string, tem);
+ break;
+
+ 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) : NULL_TYPE;
+
+ if (expect_type != NULL_TYPE && noside != EVAL_SKIP
+ && TYPE_CODE (type) == TYPE_CODE_STRUCT)
+ {
+ value_ptr rec = allocate_value (expect_type);
+ memset (VALUE_CONTENTS_RAW (rec), '\0', TYPE_LENGTH (type));
+ return evaluate_struct_tuple (rec, exp, pos, noside, nargs);
+ }
+
+ if (expect_type != NULL_TYPE && noside != EVAL_SKIP
+ && TYPE_CODE (type) == TYPE_CODE_ARRAY)
+ {
+ struct type *range_type = TYPE_FIELD_TYPE (type, 0);
+ struct type *element_type = TYPE_TARGET_TYPE (type);
+ value_ptr array = allocate_value (expect_type);
+ int element_size = TYPE_LENGTH (check_typedef (element_type));
+ LONGEST low_bound, high_bound, index;
+ if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
+ {
+ 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;)
+ {
+ value_ptr element;
+ int index_pc = 0;
+ if (exp->elts[*pos].opcode == BINOP_RANGE)
+ {
+ index_pc = ++(*pos);
+ evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP);
+ }
+ element = evaluate_subexp (element_type, exp, pos, noside);
+ if (VALUE_TYPE (element) != element_type)
+ element = value_cast (element_type, element);
+ if (index_pc)
+ {
+ int continue_pc = *pos;
+ *pos = index_pc;
+ index = init_array_element (array, element, exp, pos, noside,
+ low_bound, high_bound);
+ *pos = continue_pc;
+ }
+ else
+ {
+ 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;
+ }
+
+ if (expect_type != NULL_TYPE && noside != EVAL_SKIP
+ && TYPE_CODE (type) == TYPE_CODE_SET)
+ {
+ value_ptr set = allocate_value (expect_type);
+ char *valaddr = VALUE_CONTENTS_RAW (set);
+ struct type *element_type = TYPE_INDEX_TYPE (type);
+ struct type *check_type = element_type;
+ LONGEST low_bound, high_bound;
+
+ /* get targettype of elementtype */
+ while (TYPE_CODE (check_type) == TYPE_CODE_RANGE ||
+ TYPE_CODE (check_type) == TYPE_CODE_TYPEDEF)
+ check_type = TYPE_TARGET_TYPE (check_type);
+
+ if (get_discrete_bounds (element_type, &low_bound, &high_bound) < 0)
+ 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;
+ value_ptr elem_val;
+ if (exp->elts[*pos].opcode == BINOP_RANGE)
+ {
+ (*pos)++;
+ elem_val = evaluate_subexp (element_type, exp, pos, noside);
+ range_low_type = VALUE_TYPE (elem_val);
+ range_low = value_as_long (elem_val);
+ elem_val = evaluate_subexp (element_type, exp, pos, noside);
+ range_high_type = VALUE_TYPE (elem_val);
+ range_high = value_as_long (elem_val);
+ }
+ else
+ {
+ 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 (TYPE_CODE (range_low_type) == TYPE_CODE_RANGE)
+ range_low_type = TYPE_TARGET_TYPE (range_low_type);
+ if (TYPE_CODE (range_high_type) == TYPE_CODE_RANGE)
+ range_high_type = TYPE_TARGET_TYPE (range_high_type);
+ if ((TYPE_CODE (range_low_type) != TYPE_CODE (range_high_type)) ||
+ (TYPE_CODE (range_low_type) == TYPE_CODE_ENUM &&
+ (range_low_type != range_high_type)))
+ /* different element modes */
+ error ("POWERSET tuple elements of different mode");
+ if ((TYPE_CODE (check_type) != TYPE_CODE (range_low_type)) ||
+ (TYPE_CODE (check_type) == 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 (BITS_BIG_ENDIAN)
+ bit_index = TARGET_CHAR_BIT - 1 - bit_index;
+ valaddr[(unsigned) range_low / TARGET_CHAR_BIT]
+ |= 1 << bit_index;
+ }
+ }
+ return set;
+ }
+
+ argvec = (value_ptr *) alloca (sizeof (value_ptr) * 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);
+ }