+ int pc = *pos;
+ value_ptr val = NULL;
+ int nlabels = 0;
+ int bitpos, bitsize;
+ char *addr;
+
+ /* Skip past the labels, and count them. */
+ while (get_label (exp, pos) != NULL)
+ nlabels++;
+
+ do
+ {
+ char *label = get_label (exp, &pc);
+ if (label)
+ {
+ for (fieldno = 0; fieldno < TYPE_NFIELDS (struct_type);
+ fieldno++)
+ {
+ char *field_name = TYPE_FIELD_NAME (struct_type, fieldno);
+ if (field_name != NULL && STREQ (field_name, label))
+ {
+ variantno = -1;
+ subfieldno = fieldno;
+ substruct_type = struct_type;
+ goto found;
+ }
+ }
+ for (fieldno = 0; fieldno < TYPE_NFIELDS (struct_type);
+ fieldno++)
+ {
+ char *field_name = TYPE_FIELD_NAME (struct_type, fieldno);
+ field_type = TYPE_FIELD_TYPE (struct_type, fieldno);
+ if ((field_name == 0 || *field_name == '\0')
+ && TYPE_CODE (field_type) == TYPE_CODE_UNION)
+ {
+ variantno = 0;
+ for (; variantno < TYPE_NFIELDS (field_type);
+ variantno++)
+ {
+ substruct_type
+ = TYPE_FIELD_TYPE (field_type, variantno);
+ if (TYPE_CODE (substruct_type) == TYPE_CODE_STRUCT)
+ {
+ for (subfieldno = 0;
+ subfieldno < TYPE_NFIELDS (substruct_type);
+ subfieldno++)
+ {
+ if (STREQ (TYPE_FIELD_NAME (substruct_type,
+ subfieldno),
+ label))
+ {
+ goto found;
+ }
+ }
+ }
+ }
+ }
+ }
+ error ("there is no field named %s", label);
+ found:
+ ;
+ }
+ else
+ {
+ /* Unlabelled tuple element - go to next field. */
+ if (variantno >= 0)
+ {
+ subfieldno++;
+ if (subfieldno >= TYPE_NFIELDS (substruct_type))
+ {
+ variantno = -1;
+ substruct_type = struct_type;
+ }
+ }
+ if (variantno < 0)
+ {
+ fieldno++;
+ subfieldno = fieldno;
+ if (fieldno >= TYPE_NFIELDS (struct_type))
+ error ("too many initializers");
+ field_type = TYPE_FIELD_TYPE (struct_type, fieldno);
+ if (TYPE_CODE (field_type) == 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 = TYPE_FIELD_TYPE (substruct_type, subfieldno);
+ 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 (substruct_type, subfieldno);
+ bitpos = TYPE_FIELD_BITPOS (struct_type, fieldno);
+ if (variantno >= 0)
+ bitpos += TYPE_FIELD_BITPOS (substruct_type, subfieldno);
+ addr = VALUE_CONTENTS (struct_val) + bitpos / 8;
+ if (bitsize)
+ modify_field (addr, value_as_long (val),
+ bitpos % 8, bitsize);
+ else
+ memcpy (addr, VALUE_CONTENTS (val),
+ TYPE_LENGTH (VALUE_TYPE (val)));
+ } while (--nlabels > 0);
+ }
+ return struct_val;
+}
+
+/* Recursive helper function for setting elements of array tuples for Chill.
+ The target is ARRAY (which has bounds LOW_BOUND to HIGH_BOUND);
+ the element value is ELEMENT;
+ EXP, POS and NOSIDE are as usual.
+ Evaluates index expresions and sets the specified element(s) of
+ ARRAY to ELEMENT.
+ Returns last index value. */
+
+static LONGEST
+init_array_element (array, element, exp, pos, noside, low_bound, high_bound)
+ value_ptr array, element;
+ register struct expression *exp;
+ register int *pos;
+ enum noside noside;
+{
+ LONGEST index;
+ int element_size = TYPE_LENGTH (VALUE_TYPE (element));
+ if (exp->elts[*pos].opcode == BINOP_COMMA)
+ {
+ (*pos)++;
+ init_array_element (array, element, exp, pos, noside,
+ low_bound, high_bound);
+ return init_array_element (array, element,
+ exp, pos, noside, low_bound, high_bound);
+ }
+ else if (exp->elts[*pos].opcode == BINOP_RANGE)
+ {
+ LONGEST low, high;
+ (*pos)++;
+ low = value_as_long (evaluate_subexp (NULL_TYPE, exp, pos, noside));
+ high = value_as_long (evaluate_subexp (NULL_TYPE, exp, pos, noside));
+ if (low < low_bound || high > high_bound)
+ error ("tuple range index out of range");
+ for (index = low ; index <= high; index++)