X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCglue.c;h=9861c9855feb2a0eb3095f334d35cd047fe227fa;hb=7c0f63b9c6907ac31c81ae7036481519f7e63ff6;hp=b95d90dbc65cf2075b051442c634da0535b3a870;hpb=2fc4945671c819e3a9c8d12f42e04b62e796e03f;p=fw%2Fsdcc diff --git a/src/SDCCglue.c b/src/SDCCglue.c index b95d90db..9861c985 100644 --- a/src/SDCCglue.c +++ b/src/SDCCglue.c @@ -28,17 +28,7 @@ #include "newalloc.h" #if !defined(__BORLANDC__) && !defined(_MSC_VER) -#if 0 /* This should no longer be necessary. */ -// This is a bit messy because we define link ourself -#define link NoLiNk #include -#undef link -#else - -#include -#endif -#else -// No unistd.h in Borland C++ #endif symbol *interrupts[256]; @@ -80,7 +70,7 @@ DEFSETFUNC (rmTmpFiles) if (name) { unlink (name); - free (name); + Safe_free (name); } return 0; } @@ -109,6 +99,11 @@ aopLiteralLong (value * val, int offset, int size) } fl; + if (!val) { + // assuming we have been warned before + val=constVal("0"); + } + /* if it is a float then it gets tricky */ /* otherwise it is fairly simple */ if (!IS_FLOAT (val->type)) { @@ -160,6 +155,10 @@ static void emitRegularMap (memmap * map, bool addPublics, bool arFlag) { symbol *sym; + ast *ival = NULL; + + if (!map) + return; if (addPublics) { @@ -173,34 +172,41 @@ emitRegularMap (memmap * map, bool addPublics, bool arFlag) else tfprintf (map->oFile, "\t!area\n", map->sname); } - - /* print the area name */ + for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) { + symbol *newSym=NULL; /* if extern then add it into the extern list */ if (IS_EXTERN (sym->etype)) { - addSetHead (&externs, sym); + addSetHead (&externs, sym); continue; } /* if allocation required check is needed then check if the symbol really requires allocation only for local variables */ + if (arFlag && !IS_AGGREGATE (sym->type) && !(sym->_isparm && !IS_REGPARM (sym->etype)) && !sym->allocreq && sym->level) continue; + /* for bitvar locals and parameters */ + if (!arFlag && !sym->allocreq && sym->level + && !SPEC_ABSA (sym->etype)) { + continue; + } + /* if global variable & not static or extern and addPublics allowed then add it to the public set */ if ((sym->level == 0 || (sym->_isparm && !IS_REGPARM (sym->etype))) && addPublics && !IS_STATIC (sym->etype) && - (sym->used || sym->fbody)) + (IS_FUNC(sym->type) ? (sym->used || IFFUNC_HASBODY(sym->type)) : 1)) { addSetHead (&publics, sym); } @@ -211,62 +217,99 @@ emitRegularMap (memmap * map, bool addPublics, bool arFlag) continue; /* print extra debug info if required */ - if ((options.debug || sym->level == 0) && !options.nodebug) - { - - cdbSymbol (sym, cdbFile, FALSE, FALSE); - - if (!sym->level) /* global */ - if (IS_STATIC (sym->etype)) - fprintf (map->oFile, "F%s$", moduleName); /* scope is file */ - else - fprintf (map->oFile, "G$"); /* scope is global */ + if (options.debug) { + cdbSymbol (sym, cdbFile, FALSE, FALSE); + if (!sym->level) /* global */ + if (IS_STATIC (sym->etype)) + fprintf (map->oFile, "F%s$", moduleName); /* scope is file */ else - /* symbol is local */ - fprintf (map->oFile, "L%s$", (sym->localof ? sym->localof->name : "-null-")); - fprintf (map->oFile, "%s$%d$%d", sym->name, sym->level, sym->block); - } + fprintf (map->oFile, "G$"); /* scope is global */ + else + /* symbol is local */ + fprintf (map->oFile, "L%s$", (sym->localof ? sym->localof->name : "-null-")); + fprintf (map->oFile, "%s$%d$%d", sym->name, sym->level, sym->block); + } + + /* if it has an initial value then do it only if + it is a global variable */ + if (sym->ival && sym->level == 0) { + if (SPEC_OCLS(sym->etype)==xidata) { + // create a new "XINIT (CODE)" symbol, that will be emitted later + newSym=copySymbol (sym); + SPEC_OCLS(newSym->etype)=xinit; + sprintf (newSym->name, "__xinit_%s", sym->name); + sprintf (newSym->rname,"__xinit_%s", sym->rname); + SPEC_CONST(newSym->etype)=1; + SPEC_STAT(newSym->etype)=1; + resolveIvalSym(newSym->ival); + + // add it to the "XINIT (CODE)" segment + addSet(&xinit->syms, newSym); + sym->ival=NULL; + } else { + if (IS_AGGREGATE (sym->type)) { + ival = initAggregates (sym, sym->ival, NULL); + } else { + if (getNelements(sym->type, sym->ival)>1) { + werror (W_EXCESS_INITIALIZERS, "scalar", + sym->name, sym->lineDef); + } + ival = newNode ('=', newAst_VALUE (symbolVal (sym)), + decorateType (resolveSymbols (list2expr (sym->ival)))); + } + codeOutFile = statsg->oFile; + + if (ival) { + // set ival's lineno to where the symbol was defined + setAstLineno (ival, lineno=sym->lineDef); + // check if this is not a constant expression + if (!constExprTree(ival)) { + werror (E_CONST_EXPECTED, "found expression"); + // but try to do it anyway + } + allocInfo = 0; + eBBlockFromiCode (iCodeFromAst (ival)); + allocInfo = 1; + } + } + sym->ival = NULL; + } /* if is has an absolute address then generate an equate for this no need to allocate space */ if (SPEC_ABSA (sym->etype)) { - if ((options.debug || sym->level == 0) && !options.nodebug) + char *equ="="; + if (options.debug) { fprintf (map->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype)); - - fprintf (map->oFile, "%s\t=\t0x%04x\n", - sym->rname, + } + if (TARGET_IS_XA51) { + if (map==sfr) { + equ="sfr"; + } else if (map==bit || map==sfrbit) { + equ="bit"; + } + } + fprintf (map->oFile, "%s\t%s\t0x%04x\n", + sym->rname, equ, SPEC_ADDR (sym->etype)); } - else - { - /* allocate space */ - if ((options.debug || sym->level == 0) && !options.nodebug) - fprintf (map->oFile, "==.\n"); - if (IS_STATIC (sym->etype)) - tfprintf (map->oFile, "!slabeldef\n", sym->rname); - else - tfprintf (map->oFile, "!labeldef\n", sym->rname); - tfprintf (map->oFile, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff); + else { + int size = getSize (sym->type); + if (size==0) { + werror(E_UNKNOWN_SIZE,sym->name); } - - /* if it has an initial value then do it only if - it is a global variable */ - if (sym->ival && sym->level == 0) - { - ast *ival = NULL; - - if (IS_AGGREGATE (sym->type)) - ival = initAggregates (sym, sym->ival, NULL); - else - ival = newNode ('=', newAst_VALUE (symbolVal (sym)), - decorateType (resolveSymbols (list2expr (sym->ival)))); - codeOutFile = statsg->oFile; - allocInfo = 0; - eBBlockFromiCode (iCodeFromAst (ival)); - allocInfo = 1; - sym->ival = NULL; + /* allocate space */ + if (options.debug) { + fprintf (map->oFile, "==.\n"); } + if (IS_STATIC (sym->etype)) + tfprintf (map->oFile, "!slabeldef\n", sym->rname); + else + tfprintf (map->oFile, "!labeldef\n", sym->rname); + tfprintf (map->oFile, "\t!ds\n", + (unsigned int) size & 0xffff); + } } } @@ -274,7 +317,7 @@ emitRegularMap (memmap * map, bool addPublics, bool arFlag) /* initPointer - pointer initialization code massaging */ /*-----------------------------------------------------------------*/ value * -initPointer (initList * ilist) +initPointer (initList * ilist, sym_link *toType) { value *val; ast *expr = list2expr (ilist); @@ -286,6 +329,17 @@ initPointer (initList * ilist) if ((val = constExprValue (expr, FALSE))) return val; + /* (char *)&a */ + if (IS_AST_OP(expr) && expr->opval.op==CAST && + IS_AST_OP(expr->right) && expr->right->opval.op=='&') { + if (compareType(toType, expr->left->ftype)!=1) { + werror (W_INIT_WRONG); + printFromToType(expr->left->ftype, toType); + } + // skip the cast ??? + expr=expr->right; + } + /* no then we have to do these cludgy checks */ /* pointers can be initialized with address of a variable or address of an array element */ @@ -329,10 +383,10 @@ initPointer (initList * ilist) (&some_struct)->element */ if (IS_AST_OP (expr->left) && expr->left->opval.op == PTR_OP && - IS_ADDRESS_OF_OP (expr->left->left)) - return valForStructElem (expr->left->left->left, - expr->left->right); - + IS_ADDRESS_OF_OP (expr->left->left)) { + return valForStructElem (expr->left->left->left, + expr->left->right); + } } /* case 3. (((char *) &a) +/- constant) */ if (IS_AST_OP (expr) && @@ -373,7 +427,7 @@ initPointer (initList * ilist) return val; } wrong: - werror (E_INIT_WRONG); + werror (W_INIT_WRONG); return NULL; } @@ -431,7 +485,7 @@ printChar (FILE * ofile, char *s, int plen) /* return the generic pointer high byte for a given pointer type. */ /*-----------------------------------------------------------------*/ int -pointerTypeToGPByte (const int p_type) +pointerTypeToGPByte (const int p_type, const char *iname, const char *oname) { switch (p_type) { @@ -442,6 +496,9 @@ pointerTypeToGPByte (const int p_type) /* hack - if we get a generic pointer, we just assume * it's an FPOINTER (i.e. in XDATA space). */ + werror (E_CANNOT_USE_GENERIC_POINTER, iname, oname); + exit (1); + // fall through case FPOINTER: return 1; case CPOINTER: @@ -463,7 +520,8 @@ pointerTypeToGPByte (const int p_type) void _printPointerType (FILE * oFile, const char *name) { - if (TARGET_IS_DS390) + /* if (TARGET_IS_DS390) */ + if (options.model == MODEL_FLAT24) { fprintf (oFile, "\t.byte %s,(%s >> 8),(%s >> 16)", name, name, name); } @@ -487,18 +545,18 @@ printPointerType (FILE * oFile, const char *name) /* printGPointerType - generates ival for generic pointer type */ /*-----------------------------------------------------------------*/ void -printGPointerType (FILE * oFile, const char *name, +printGPointerType (FILE * oFile, const char *iname, const char *oname, const unsigned int type) { - _printPointerType (oFile, name); - fprintf (oFile, ",#0x%02x\n", pointerTypeToGPByte (type)); + _printPointerType (oFile, iname); + fprintf (oFile, ",#0x%02x\n", pointerTypeToGPByte (type, iname, oname)); } /*-----------------------------------------------------------------*/ /* printIvalType - generates ival for int/char */ /*-----------------------------------------------------------------*/ void -printIvalType (sym_link * type, initList * ilist, FILE * oFile) +printIvalType (symbol *sym, sym_link * type, initList * ilist, FILE * oFile) { value *val; @@ -506,7 +564,19 @@ printIvalType (sym_link * type, initList * ilist, FILE * oFile) if (ilist->type == INIT_DEEP) ilist = ilist->init.deep; - val = list2val (ilist); + if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) { + werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef); + } + + if (!(val = list2val (ilist))) { + // assuming a warning has been thrown + val=constVal("0"); + } + + if (val->type != type) { + val = valCastLiteral(type, floatFromVal(val)); + } + switch (getSize (type)) { case 1: if (!val) @@ -608,9 +678,12 @@ printIvalStruct (symbol * sym, sym_link * type, if (IS_BITFIELD(sflds->type)) { printIvalBitFields(&sflds,&iloop,oFile); } else { - printIval (sflds, sflds->type, iloop, oFile); + printIval (sym, sflds->type, iloop, oFile); } } + if (iloop) { + werror (W_EXCESS_INITIALIZERS, "struct", sym->name, sym->lineDef); + } return; } @@ -662,12 +735,16 @@ printIvalArray (symbol * sym, sym_link * type, initList * ilist, /* take care of the special case */ /* array of characters can be init */ /* by a string */ - if (IS_CHAR (type->next)) + if (IS_CHAR (type->next)) { + if (!IS_LITERAL(list2val(ilist)->etype)) { + werror (W_INIT_WRONG); + return; + } if (printIvalChar (type, (ilist->type == INIT_DEEP ? ilist->init.deep : ilist), oFile, SPEC_CVAL (sym->etype).v_char)) return; - + } /* not the special case */ if (ilist->type != INIT_DEEP) { @@ -692,8 +769,13 @@ printIvalArray (symbol * sym, sym_link * type, initList * ilist, /* no of elements given and we */ /* have generated for all of them */ - if (!--lcnt) + if (!--lcnt) { + /* if initializers left */ + if (iloop) { + werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef); + } break; + } } /* if we have not been given a size */ @@ -713,8 +795,23 @@ printIvalFuncPtr (sym_link * type, initList * ilist, FILE * oFile) int dLvl = 0; val = list2val (ilist); + + if (!val) { + // an error has been thrown allready + val=constVal("0"); + } + + if (IS_LITERAL(val->etype)) { + if (compareType(type,val->etype)==0) { + werror (E_INCOMPAT_TYPES); + printFromToType (val->type, type); + } + printIvalCharPtr (NULL, type, val, oFile); + return; + } + /* check the types */ - if ((dLvl = checkType (val->type, type->next)) <= 0) + if ((dLvl = compareType (val->type, type->next)) <= 0) { tfprintf (oFile, "\t!dw !constword\n", 0); return; @@ -778,10 +875,17 @@ printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile) } else if (size == GPTRSIZE) { - /* PENDING: 0x02 or 0x%02x, CDATA? */ - printGPointerType (oFile, val->name, - (IS_PTR (val->type) ? DCL_TYPE (val->type) : - PTR_TYPE (SPEC_OCLS (val->etype)))); + int type; + if (IS_PTR (val->type)) { + type = DCL_TYPE (val->type); + } else { + type = PTR_TYPE (SPEC_OCLS (val->etype)); + } + if (val->sym && val->sym->isstrlit) { + // this is a literal string + type=CPOINTER; + } + printGPointerType (oFile, val->name, sym->name, type); } else { @@ -791,7 +895,7 @@ printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile) } else { - /* What is this case? Are these pointers? */ + // these are literals assigned to pointers switch (size) { case 1: @@ -805,9 +909,25 @@ printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile) aopLiteral (val, 0), aopLiteral (val, 1)); break; case 3: - /* PENDING: 0x02 or 0x%02x, CDATA? */ - fprintf (oFile, "\t.byte %s,%s,#0x02\n", - aopLiteral (val, 0), aopLiteral (val, 1)); + if (IS_GENPTR(type) && floatFromVal(val)!=0) { + // non-zero mcs51 generic pointer + werror (E_LITERAL_GENERIC); + } + fprintf (oFile, "\t.byte %s,%s,%s\n", + aopLiteral (val, 0), + aopLiteral (val, 1), + aopLiteral (val, 2)); + break; + case 4: + if (IS_GENPTR(type) && floatFromVal(val)!=0) { + // non-zero ds390 generic pointer + werror (E_LITERAL_GENERIC); + } + fprintf (oFile, "\t.byte %s,%s,%s,%s\n", + aopLiteral (val, 0), + aopLiteral (val, 1), + aopLiteral (val, 2), + aopLiteral (val, 3)); break; default: assert (0); @@ -841,7 +961,7 @@ printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile) return; } - if (!(val = initPointer (ilist))) + if (!(val = initPointer (ilist, type))) return; /* if character pointer */ @@ -850,8 +970,8 @@ printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile) return; /* check the type */ - if (checkType (type, val->type) == 0) - werror (E_INIT_WRONG); + if (compareType (type, val->type) == 0) + werror (W_INIT_WRONG); /* if val is literal */ if (IS_LITERAL (val->etype)) @@ -891,7 +1011,7 @@ printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile) } else if (size == GPTRSIZE) { - printGPointerType (oFile, val->name, + printGPointerType (oFile, val->name, sym->name, (IS_PTR (val->type) ? DCL_TYPE (val->type) : PTR_TYPE (SPEC_OCLS (val->etype)))); } @@ -931,7 +1051,7 @@ printIval (symbol * sym, sym_link * type, initList * ilist, FILE * oFile) /* if type is SPECIFIER */ if (IS_SPEC (type)) { - printIvalType (type, ilist, oFile); + printIvalType (sym, type, ilist, oFile); return; } } @@ -944,9 +1064,7 @@ emitStaticSeg (memmap * map, FILE * out) { symbol *sym; - /* fprintf(map->oFile,"\t.area\t%s\n",map->sname); */ - if (!out) - out = code->oFile; + /* fprintf(out, "\t.area\t%s\n", map->sname); */ /* for all variables in this segment do */ for (sym = setFirstItem (map->syms); sym; @@ -960,43 +1078,42 @@ emitStaticSeg (memmap * map, FILE * out) /* if it is not static add it to the public table */ if (!IS_STATIC (sym->etype)) - addSetHead (&publics, sym); + { + addSetHead (&publics, sym); + } /* print extra debug info if required */ - if ((options.debug || sym->level == 0) && !options.nodebug) - { - - cdbSymbol (sym, cdbFile, FALSE, FALSE); - - if (!sym->level) - { /* global */ - if (IS_STATIC (sym->etype)) - fprintf (out, "F%s$", moduleName); /* scope is file */ - else - fprintf (out, "G$"); /* scope is global */ - } - else - /* symbol is local */ - fprintf (out, "L%s$", - (sym->localof ? sym->localof->name : "-null-")); - fprintf (out, "%s$%d$%d", sym->name, sym->level, sym->block); - } - + if (options.debug) { + cdbSymbol (sym, cdbFile, FALSE, FALSE); + if (!sym->level) + { /* global */ + if (IS_STATIC (sym->etype)) + fprintf (out, "F%s$", moduleName); /* scope is file */ + else + fprintf (out, "G$"); /* scope is global */ + } + else + /* symbol is local */ + fprintf (out, "L%s$", + (sym->localof ? sym->localof->name : "-null-")); + fprintf (out, "%s$%d$%d", sym->name, sym->level, sym->block); + } + /* if it has an absolute address */ if (SPEC_ABSA (sym->etype)) { - if ((options.debug || sym->level == 0) && !options.nodebug) + if (options.debug) fprintf (out, " == 0x%04x\n", SPEC_ADDR (sym->etype)); - + fprintf (out, "%s\t=\t0x%04x\n", sym->rname, SPEC_ADDR (sym->etype)); } else { - if ((options.debug || sym->level == 0) && !options.nodebug) + if (options.debug) fprintf (out, " == .\n"); - + /* if it has an initial value */ if (sym->ival) { @@ -1006,18 +1123,22 @@ emitStaticSeg (memmap * map, FILE * out) printIval (sym, sym->type, sym->ival, out); noAlloc--; } - else - { + else { /* allocate space */ + int size = getSize (sym->type); + + if (size==0) { + werror(E_UNKNOWN_SIZE,sym->name); + } fprintf (out, "%s:\n", sym->rname); /* special case for character strings */ if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) && SPEC_CVAL (sym->etype).v_char) - printChar (out, - SPEC_CVAL (sym->etype).v_char, - strlen (SPEC_CVAL (sym->etype).v_char) + 1); + printChar (out, + SPEC_CVAL (sym->etype).v_char, + strlen (SPEC_CVAL (sym->etype).v_char) + 1); else - tfprintf (out, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff); + tfprintf (out, "\t!ds\n", (unsigned int) size & 0xffff); } } } @@ -1029,18 +1150,27 @@ emitStaticSeg (memmap * map, FILE * out) void emitMaps () { + inInitMode++; /* no special considerations for the following data, idata & bit & xdata */ emitRegularMap (data, TRUE, TRUE); emitRegularMap (idata, TRUE, TRUE); emitRegularMap (bit, TRUE, FALSE); emitRegularMap (xdata, TRUE, TRUE); + if (port->genXINIT) { + emitRegularMap (xidata, TRUE, TRUE); + } emitRegularMap (sfr, FALSE, FALSE); emitRegularMap (sfrbit, FALSE, FALSE); emitRegularMap (home, TRUE, FALSE); emitRegularMap (code, TRUE, FALSE); emitStaticSeg (statsg, code->oFile); + if (port->genXINIT) { + tfprintf (code->oFile, "\t!area\n", xinit->sname); + emitStaticSeg (xinit, code->oFile); + } + inInitMode--; } /*-----------------------------------------------------------------*/ @@ -1067,16 +1197,16 @@ createInterruptVect (FILE * vFile) /* only if the main function exists */ if (!(mainf = findSymWithLevel (SymbolTab, mainf))) { - if (!options.cc_only) + if (!options.cc_only && !noAssemble) werror (E_NO_MAIN); return; } /* if the main is only a prototype ie. no body then do nothing */ - if (!mainf->fbody) + if (!IFFUNC_HASBODY(mainf->type)) { /* if ! compile only then main function should be present */ - if (!options.cc_only) + if (!options.cc_only && !noAssemble) werror (E_NO_MAIN); return; } @@ -1088,7 +1218,6 @@ createInterruptVect (FILE * vFile) if (!port->genIVT || !(port->genIVT (vFile, interrupts, maxInterrupts))) { /* "generic" interrupt table header (if port doesn't specify one). - * Look suspiciously like 8051 code to me... */ @@ -1160,7 +1289,7 @@ printExterns (FILE * afile) for (sym = setFirstItem (externs); sym; sym = setNextItem (externs)) - tfprintf (afile, "\t!global\n", sym->rname); + tfprintf (afile, "\t!extern\n", sym->rname); } /*-----------------------------------------------------------------*/ @@ -1183,11 +1312,6 @@ emitOverlay (FILE * afile) if (elementsInSet (ovrset)) { - /* this dummy area is used to fool the assembler - otherwise the assembler will append each of these - declarations into one chunk and will not overlay - sad but true */ - fprintf (afile, "\t.area _DUMMY\n"); /* output the area informtion */ fprintf (afile, "\t.area\t%s\n", port->mem.overlay_name); /* MOF */ } @@ -1195,8 +1319,7 @@ emitOverlay (FILE * afile) for (sym = setFirstItem (ovrset); sym; sym = setNextItem (ovrset)) { - - /* if extern then add it to the publics tabledo nothing */ + /* if extern then it is in the publics table: do nothing */ if (IS_EXTERN (sym->etype)) continue; @@ -1212,7 +1335,9 @@ emitOverlay (FILE * afile) and addPublics allowed then add it to the public set */ if ((sym->_isparm && !IS_REGPARM (sym->etype)) && !IS_STATIC (sym->etype)) - addSetHead (&publics, sym); + { + addSetHead (&publics, sym); + } /* if extern then do nothing or is a function then do nothing */ @@ -1220,9 +1345,8 @@ emitOverlay (FILE * afile) continue; /* print extra debug info if required */ - if ((options.debug || sym->level == 0) && !options.nodebug) + if (options.debug) { - cdbSymbol (sym, cdbFile, FALSE, FALSE); if (!sym->level) @@ -1244,23 +1368,27 @@ emitOverlay (FILE * afile) if (SPEC_ABSA (sym->etype)) { - if ((options.debug || sym->level == 0) && !options.nodebug) + if (options.debug) fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype)); fprintf (afile, "%s\t=\t0x%04x\n", sym->rname, SPEC_ADDR (sym->etype)); } - else - { - if ((options.debug || sym->level == 0) && !options.nodebug) - fprintf (afile, "==.\n"); - + else { + int size = getSize(sym->type); + + if (size==0) { + werror(E_UNKNOWN_SIZE,sym->name); + } + if (options.debug) + fprintf (afile, "==.\n"); + /* allocate space */ tfprintf (afile, "!labeldef\n", sym->rname); tfprintf (afile, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff); - } - + } + } } } @@ -1277,7 +1405,7 @@ glue () addSetHead (&tmpfileSet, ovrFile); /* print the global struct definitions */ - if (options.debug && !options.nodebug) + if (options.debug) cdbStructBlock (0, cdbFile); vFile = tempfile (); @@ -1300,17 +1428,17 @@ glue () if (!options.c1mode) { - sprintf (buffer, srcFileName); - strcat (buffer, port->assembler.file_ext); + sprintf (scratchFileName, srcFileName); + strcat (scratchFileName, port->assembler.file_ext); } else { - strcpy (buffer, options.out_name); + strcpy (scratchFileName, options.out_name); } - if (!(asmFile = fopen (buffer, "w"))) + if (!(asmFile = fopen (scratchFileName, "w"))) { - werror (E_FILE_OPEN_ERR, buffer); + werror (E_FILE_OPEN_ERR, scratchFileName); exit (1); } @@ -1352,13 +1480,15 @@ glue () /* create the overlay segments */ - fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "; overlayable items in internal ram \n"); - fprintf (asmFile, "%s", iComments2); - copyFile (asmFile, ovrFile); + if (overlay) { + fprintf (asmFile, "%s", iComments2); + fprintf (asmFile, "; overlayable items in internal ram \n"); + fprintf (asmFile, "%s", iComments2); + copyFile (asmFile, ovrFile); + } /* create the stack segment MOF */ - if (mainf && mainf->fbody) + if (mainf && IFFUNC_HASBODY(mainf->type)) { fprintf (asmFile, "%s", iComments2); fprintf (asmFile, "; Stack segment in internal ram \n"); @@ -1368,10 +1498,12 @@ glue () } /* create the idata segment */ - fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "; indirectly addressable internal ram data\n"); - fprintf (asmFile, "%s", iComments2); - copyFile (asmFile, idata->oFile); + if (idata) { + fprintf (asmFile, "%s", iComments2); + fprintf (asmFile, "; indirectly addressable internal ram data\n"); + fprintf (asmFile, "%s", iComments2); + copyFile (asmFile, idata->oFile); + } /* copy the bit segment */ fprintf (asmFile, "%s", iComments2); @@ -1380,7 +1512,7 @@ glue () copyFile (asmFile, bit->oFile); /* if external stack then reserve space of it */ - if (mainf && mainf->fbody && options.useXstack) + if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack) { fprintf (asmFile, "%s", iComments2); fprintf (asmFile, "; external stack \n"); @@ -1396,8 +1528,14 @@ glue () fprintf (asmFile, "%s", iComments2); copyFile (asmFile, xdata->oFile); + /* copy xternal initialized ram data */ + fprintf (asmFile, "%s", iComments2); + fprintf (asmFile, "; external initialized ram data\n"); + fprintf (asmFile, "%s", iComments2); + copyFile (asmFile, xidata->oFile); + /* copy the interrupt vector table */ - if (mainf && mainf->fbody) + if (mainf && IFFUNC_HASBODY(mainf->type)) { fprintf (asmFile, "%s", iComments2); fprintf (asmFile, "; interrupt vector \n"); @@ -1420,7 +1558,7 @@ glue () tfprintf (asmFile, "\t!area\n", port->mem.post_static_name); tfprintf (asmFile, "\t!area\n", port->mem.static_name); - if (mainf && mainf->fbody) + if (mainf && IFFUNC_HASBODY(mainf->type)) { fprintf (asmFile, "__sdcc_gsinit_startup:\n"); /* if external stack is specified then the @@ -1438,7 +1576,7 @@ glue () /* initialise the stack pointer */ /* if the user specified a value then use it */ if (options.stack_loc) - fprintf (asmFile, "\tmov\tsp,#%d\n", options.stack_loc); + fprintf (asmFile, "\tmov\tsp,#%d\n", options.stack_loc & 0xff); else /* no: we have to compute it */ if (!options.stackOnData && maxRegBank <= 3) @@ -1452,10 +1590,15 @@ glue () fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n"); fprintf (asmFile, "__sdcc_init_data:\n"); + // if the port can copy the XINIT segment to XISEG + if (port->genXINIT) { + port->genXINIT(asmFile); + } + } copyFile (asmFile, statsg->oFile); - if (port->general.glue_up_main && mainf && mainf->fbody) + if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) { /* This code is generated in the post-static area. * This area is guaranteed to follow the static area @@ -1477,7 +1620,7 @@ glue () fprintf (asmFile, "; code\n"); fprintf (asmFile, "%s", iComments2); tfprintf (asmFile, "\t!areacode\n", CODE_NAME); - if (mainf && mainf->fbody) + if (mainf && IFFUNC_HASBODY(mainf->type)) { /* entry point @ start of CSEG */ @@ -1501,11 +1644,50 @@ glue () } copyFile (asmFile, code->oFile); + if (port->genAssemblerEnd) { + port->genAssemblerEnd(asmFile); + } fclose (asmFile); applyToSet (tmpfileSet, closeTmpFiles); applyToSet (tmpfileNameSet, rmTmpFiles); } +#if defined (__MINGW32__) || defined (__CYGWIN__) || defined (_MSC_VER) +void +rm_tmpfiles (void) +{ + applyToSet (tmpfileSet, closeTmpFiles); + applyToSet (tmpfileNameSet, rmTmpFiles); +} +#endif + +/** Creates a temporary file name a'la tmpnam which avoids the bugs + in cygwin wrt c:\tmp. + Scans, in order: TMP, TEMP, TMPDIR, else uses tmpfile(). +*/ +char * +tempfilename (void) +{ +#if !defined(_MSC_VER) + const char *tmpdir = NULL; + if (getenv ("TMP")) + tmpdir = getenv ("TMP"); + else if (getenv ("TEMP")) + tmpdir = getenv ("TEMP"); + else if (getenv ("TMPDIR")) + tmpdir = getenv ("TMPDIR"); + if (tmpdir) + { + char *name = tempnam (tmpdir, "sdcc"); + if (name) + { + return name; + } + } +#endif + return tmpnam (NULL); +} + /** Creates a temporary file a'la tmpfile which avoids the bugs in cygwin wrt c:\tmp. Scans, in order: TMP, TEMP, TMPDIR, else uses tmpfile(). @@ -1523,7 +1705,7 @@ tempfile (void) tmpdir = getenv ("TMPDIR"); if (tmpdir) { - char *name = tempnam (tmpdir, "sdcc"); + char *name = Safe_strdup( tempnam (tmpdir, "sdcc")); if (name) { FILE *fp = fopen (name, "w+b"); @@ -1539,11 +1721,3 @@ tempfile (void) return tmpfile (); } -char * -gc_strdup (const char *s) -{ - char *ret; - ret = Safe_calloc (1, strlen (s) + 1); - strcpy (ret, s); - return ret; -}