+ if (IS_PTR(my_type)) {
+ DEBUGprintf ("(pointer, %d byte) %p\n", size, list ? (void *)(long)list2int(list) : NULL);
+ emitIvals(oBuf, topsym, list, 0, size);
+ return;
+ }
+
+ if (IS_ARRAY(my_type) && topsym && topsym->isstrlit) {
+ str = (unsigned char *)SPEC_CVAL(topsym->etype).v_char;
+ emitIvalLabel(oBuf, topsym);
+ do {
+ dbuf_printf (oBuf, "\tretlw 0x%02x ; '%c'\n", str[0], (str[0] >= 0x20 && str[0] < 128) ? str[0] : '.');
+ } while (*(str++));
+ return;
+ }
+
+ if (IS_ARRAY(my_type) && list && list->type == INIT_NODE) {
+ fprintf (stderr, "Unhandled initialized symbol: %s\n", topsym->name);
+ assert ( !"Initialized char-arrays are not yet supported, assign at runtime instead." );
+ return;
+ }
+
+ if (IS_ARRAY(my_type)) {
+ DEBUGprintf ("(array, %d items, %d byte) below\n", DCL_ELEM(my_type), size);
+ assert (!list || list->type == INIT_DEEP);
+ if (list) list = list->init.deep;
+ for (i = 0; i < DCL_ELEM(my_type); i++) {
+ emitInitVal(oBuf, topsym, my_type->next, list);
+ topsym = NULL;
+ if (list) list = list->next;
+ } // for i
+ return;
+ }
+
+ if (IS_FLOAT(my_type)) {
+ // float, 32 bit
+ DEBUGprintf ("(float, %d byte) %lf\n", size, list ? list2int(list) : 0.0);
+ emitIvals(oBuf, topsym, list, 0, size);
+ return;
+ }
+
+ if (IS_CHAR(my_type) || IS_INT(my_type) || IS_LONG(my_type)) {
+ // integral type, 8, 16, or 32 bit
+ DEBUGprintf ("(integral, %d byte) 0x%lx/%ld\n", size, list ? (long)list2int(list) : 0, list ? (long)list2int(list) : 0);
+ emitIvals(oBuf, topsym, list, 0, size);
+ return;
+
+ } else if (IS_STRUCT(my_type) && SPEC_STRUCT(my_type)->type == STRUCT) {
+ // struct
+ DEBUGprintf ("(struct, %d byte) handled below\n", size);
+ assert (!list || (list->type == INIT_DEEP));
+
+ // iterate over struct members and initList
+ if (list) list = list->init.deep;
+ sym = SPEC_STRUCT(my_type)->fields;
+ while (sym) {
+ long bitfield = 0;
+ int len = 0;
+ if (IS_BITFIELD(sym->type)) {
+ while (sym && IS_BITFIELD(sym->type)) {
+ assert (!list || ((list->type == INIT_NODE)
+ && IS_AST_LIT_VALUE(list->init.node)));
+ lit = (long) (list ? list2int(list) : 0);
+ DEBUGprintf ( "(bitfield member) %02lx (%d bit, starting at %d, bitfield %02lx)\n",
+ lit, SPEC_BLEN(getSpec(sym->type)),
+ SPEC_BSTR(getSpec(sym->type)), bitfield);
+ bitfield |= (lit & ((1ul << SPEC_BLEN(getSpec(sym->type))) - 1)) << SPEC_BSTR(getSpec(sym->type));
+ len += SPEC_BLEN(getSpec(sym->type));
+
+ sym = sym->next;
+ if (list) list = list->next;
+ } // while
+ assert (len < sizeof (long) * 8); // did we overflow our initializer?!?
+ len = (len + 7) & ~0x07; // round up to full bytes
+ emitIvals(oBuf, topsym, NULL, bitfield, len / 8);
+ topsym = NULL;
+ } // if
+
+ if (sym) {
+ emitInitVal(oBuf, topsym, sym->type, list);
+ topsym = NULL;
+ sym = sym->next;
+ if (list) list = list->next;
+ } // if
+ } // while
+ if (list) {
+ assert ( !"Excess initializers." );
+ } // if
+ return;
+
+ } else if (IS_STRUCT(my_type) && SPEC_STRUCT(my_type)->type == UNION) {
+ // union
+ DEBUGprintf ("(union, %d byte) handled below\n", size);
+ assert (list && list->type == INIT_DEEP);
+
+ // iterate over union members and initList, try to map number and type of fields and initializers
+ my_type = matchIvalToUnion(list, my_type, size);
+ if (my_type) {
+ emitInitVal(oBuf, topsym, my_type, list->init.deep);
+ topsym = NULL;
+ size -= getSize(my_type);
+ if (size > 0) {
+ // pad with (leading) zeros
+ emitIvals(oBuf, NULL, NULL, 0, size);
+ }
+ return;
+ } // if
+
+ assert ( !"No UNION member matches the initializer structure.");
+ } else if (IS_BITFIELD(my_type)) {
+ assert ( !"bitfields should only occur in structs..." );
+
+ } else {
+ printf ("SPEC_NOUN: %d\n", SPEC_NOUN(my_type));
+ assert( !"Unhandled initialized type.");
+ }
+}
+
+/*
+ * Emit a set of symbols.
+ * type - 0: have symbol tell whether it is local, extern or global
+ * 1: assume all symbols in set to be global
+ * 2: assume all symbols in set to be extern
+ */
+static void
+emitSymbolSet(set *s, int type)