- /* 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 && strcmp (field_name, label) == 0)
- {
- 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 (strcmp(TYPE_FIELD_NAME (substruct_type,
- subfieldno),
- label) == 0)
- {
- 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++;
- /* Skip static fields. */
- while (fieldno < TYPE_NFIELDS (struct_type)
- && field_is_static (&TYPE_FIELD (struct_type,
- fieldno)))
- 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"));
- }
- }
+ fieldno++;
+ /* Skip static fields. */
+ while (fieldno < TYPE_NFIELDS (struct_type)
+ && field_is_static (&TYPE_FIELD (struct_type,
+ fieldno)))
+ 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 (struct_type, fieldno);
+ 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)));