+#endif
+
+ return;
+}
+
+/*-----------------------------------------------------------------*/
+/* pic16_printIvalBitFields - generate initializer for bitfields */
+/*-----------------------------------------------------------------*/
+static void
+pic16_printIvalBitFields (symbol **sym, initList **ilist, char ptype, void *p)
+{
+ symbol *lsym = *sym;
+ initList *lilist = *ilist;
+ unsigned long ival = 0;
+ int size = 0;
+ unsigned long i;
+
+
+#if DEBUG_PRINTIVAL
+ fprintf(stderr, "%s\n",__FUNCTION__);
+#endif
+
+
+ while (lsym)
+ {
+ if (0 == SPEC_BLEN (lsym->etype))
+ {
+ /* bit-field structure member with a width of 0 */
+ lsym = lsym->next;
+ break;
+ }
+ else if (!SPEC_BUNNAMED (lsym->etype))
+ {
+ /* not an unnamed bit-field structure member */
+ value *val = list2val (lilist);
+ int bit_length = SPEC_BLEN (lsym->etype);
+
+ if (size)
+ {
+ if (bit_length > 8)
+ size += (bit_length + 7) / 8;
+ }
+ else
+ size = (bit_length + 7) / 8;
+
+ ival |= (ulFromVal (val) & ((1ul << bit_length) - 1ul)) << SPEC_BSTR (lsym->etype);
+ lilist = (lilist ? lilist->next : NULL);
+ }
+ lsym = lsym->next;
+ }
+
+ for (i = 0; i < size; i++)
+ pic16_emitDB (BYTE_IN_LONG (ival, i), ptype, p);
+
+ *sym = lsym;
+ *ilist = lilist;
+}
+
+
+/*-----------------------------------------------------------------*/
+/* printIvalStruct - generates initial value for structures */
+/*-----------------------------------------------------------------*/
+static void
+pic16_printIvalStruct (symbol * sym, sym_link * type,
+ initList * ilist, char ptype, void *p)
+{
+ symbol *sflds;
+ initList *iloop = NULL;
+
+
+#if DEBUG_PRINTIVAL
+ fprintf(stderr, "%s\n",__FUNCTION__);
+#endif
+
+ sflds = SPEC_STRUCT (type)->fields;
+
+ if (ilist)
+ {
+ if (ilist->type != INIT_DEEP)
+ {
+ werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
+ return;
+ }
+
+ iloop = ilist->init.deep;
+ }
+
+ while (sflds)
+ {
+// fprintf(stderr, "%s:%d sflds: %p\tiloop = %p\n", __FILE__, __LINE__, sflds, iloop);
+ if (IS_BITFIELD (sflds->type))
+ {
+ pic16_printIvalBitFields (&sflds, &iloop, ptype, p);
+ }
+ else
+ {
+ pic16_printIval (sym, sflds->type, iloop, ptype, p);
+ sflds = sflds->next;
+ iloop = iloop ? iloop->next : NULL;
+ }
+ }
+ if (iloop)
+ werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
+}
+
+/*-----------------------------------------------------------------*/
+/* printIvalUnion - generates initial value for unions */
+/*-----------------------------------------------------------------*/
+static void
+pic16_printIvalUnion (symbol * sym, sym_link * type,
+ initList * ilist, char ptype, void *p)
+{
+ //symbol *sflds;
+ initList *iloop = NULL;
+ int size;
+ symbol *sflds = NULL;
+
+#if DEBUG_PRINTIVAL
+ fprintf(stderr, "%s\n",__FUNCTION__);
+#endif
+
+ assert (type);
+
+ sflds = SPEC_STRUCT (type)->fields;
+
+ if (ilist) {
+ if (ilist->type != INIT_DEEP) {
+ werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
+ return;
+ }
+
+ iloop = ilist->init.deep;
+ }
+
+ size = SPEC_STRUCT(type)->size;
+ sflds = SPEC_STRUCT(type)->fields;
+ pic16_printIval (sym, sflds->type, iloop, ptype, p);
+
+ /* if the first field is not the longest, fill with 0s */
+ while (size > getSize (sflds->type)) {
+ pic16_emitDB(0, ptype, p);
+ size--;
+ } // while
+}
+
+static int
+pic16_isUnion( symbol *sym, sym_link *type )
+{
+ if (type && SPEC_STRUCT(type)->type == UNION) return 1;
+ return 0;
+}
+
+/*--------------------------------------------------------------------------*/
+/* pic16_printIvalCharPtr - generates initial values for character pointers */
+/*--------------------------------------------------------------------------*/
+static int
+pic16_printIvalCharPtr (symbol * sym, sym_link * type, value * val, char ptype, void *p)
+{
+ int size = 0;
+ int i;
+
+ /* PENDING: this is _very_ mcs51 specific, including a magic
+ number...
+ It's also endin specific.
+
+ VR - Attempting to port this function to pic16 port - 8-Jun-2004
+ */
+
+
+#if DEBUG_PRINTIVAL
+ fprintf(stderr, "%s\n",__FUNCTION__);
+#endif
+
+ size = getSize (type);
+
+ if (val->name && strlen (val->name))
+ {
+ if (size == 1) /* This appears to be Z80 specific?? */
+ {
+ pic16_emitDS(val->name, ptype, p);
+ }
+ else if (size == 2)
+ {
+ pic16_printPointerType (val->name, ptype, p);
+ }
+ else if (size == 3)
+ {
+ int type;
+ type = PTR_TYPE (SPEC_OCLS (val->etype));
+ if (val->sym && val->sym->isstrlit) {
+ // this is a literal string
+ type = CPOINTER;
+ }
+ pic16_printGPointerType(val->name, type, ptype, p);
+ }
+ else
+ {
+ fprintf (stderr, "*** internal error: unknown size in "
+ "printIvalCharPtr.\n");
+ assert(0);
+ }
+ }
+ else
+ {
+ // these are literals assigned to pointers
+ for (i = 0; i < size; i++)
+ {
+ pic16_emitDB(pic16aopLiteral(val, i), ptype, p);
+ } // for
+ }
+
+ if (val->sym && val->sym->isstrlit) { // && !isinSet(statsg->syms, val->sym)) {
+ if(ptype == 'p' && !isinSet(statsg->syms, val->sym))addSet (&statsg->syms, val->sym);
+ else if(ptype == 'f' /*&& !isinSet(rel_idataSymSet, val->sym)*/)addSet(&rel_idataSymSet, val->sym);
+ }
+
+ return 1;
+}
+
+/*-----------------------------------------------------------------------*/
+/* pic16_printIvalFuncPtr - generate initial value for function pointers */
+/*-----------------------------------------------------------------------*/
+static void
+pic16_printIvalFuncPtr (sym_link * type, initList * ilist, char ptype, void *p)
+{
+ value *val;
+ int dLvl = 0;
+
+
+#if DEBUG_PRINTIVAL
+ fprintf(stderr, "%s\n",__FUNCTION__);
+#endif
+
+ if (ilist)
+ val = list2val (ilist);
+ else
+ val = valCastLiteral(type, 0.0);
+
+ if (!val) {
+ // an error has been thrown already
+ val = constCharVal (0);
+ }
+
+ if (IS_LITERAL(val->etype)) {
+ if (0 && compareType(type, val->etype) == 0) {
+ werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
+ printFromToType (val->type, type);
+ }
+ pic16_printIvalCharPtr (NULL, type, val, ptype, p);
+ return;
+ }
+
+ /* check the types */
+ if ((dLvl = compareType (val->type, type->next)) <= 0)
+ {
+ pic16_emitDB(0x00, ptype, p);
+ return;
+ }
+
+ /* now generate the name */
+ if (!val->sym) {
+ pic16_printGPointerType (val->name, CPOINTER /*DCL_TYPE(val->type)*/, ptype, p);
+ } else {
+ pic16_printGPointerType (val->sym->rname, CPOINTER /*DCL_TYPE(val->type)*/, ptype, p);
+
+ if(IS_FUNC(val->sym->type) && !val->sym->used && !IS_STATIC(val->sym->etype)) {
+
+ if(!checkSym(publics, val->sym))
+ if(checkAddSym(&externs, val->sym) && (ptype == 'f')) {
+ /* this has not been declared as extern
+ * so declare it as a 'late extern' just after the symbol */
+ fprintf((FILE *)p, ";\tdeclare symbol as extern\n");
+ fprintf((FILE *)p, "\textern\t%s\n", val->sym->rname);
+ fprintf((FILE *)p, ";\tcontinue variable declaration\n");
+ }
+ }
+ }