X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCglue.c;h=1d6e0ed17af9004d721e878950183cbe6545df6d;hb=ca512339e5224e3e23064654e56d490d33240787;hp=267154311972055447ceea8abc95857241d141f5;hpb=3849998dc133eed9df3d277f7efd3923cf63c127;p=fw%2Fsdcc diff --git a/src/SDCCglue.c b/src/SDCCglue.c index 26715431..1d6e0ed1 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]; @@ -48,7 +38,7 @@ set *publics = NULL; /* public variables */ set *externs = NULL; /* Varibles that are declared as extern */ /* TODO: this should be configurable (DS803C90 uses more than 6) */ -int maxInterrupts = 6; +unsigned maxInterrupts = 6; int allocInfo = 1; symbol *mainf; extern char *VersionString; @@ -80,7 +70,7 @@ DEFSETFUNC (rmTmpFiles) if (name) { unlink (name); - free (name); + Safe_free (name); } return 0; } @@ -109,10 +99,15 @@ 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)) { - unsigned long v = floatFromVal (val); + unsigned long v = (unsigned long) floatFromVal (val); v >>= (offset * 8); switch (size) { @@ -159,7 +154,9 @@ aopLiteral (value * val, int offset) static void emitRegularMap (memmap * map, bool addPublics, bool arFlag) { - symbol *sym; + symbol *sym, *symIval; + ast *ival = NULL; + memmap *segment; if (addPublics) { @@ -189,18 +186,25 @@ emitRegularMap (memmap * map, bool addPublics, bool arFlag) /* 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,29 +215,26 @@ 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 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) + if (options.debug) { fprintf (map->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype)); - + } fprintf (map->oFile, "%s\t=\t0x%04x\n", sym->rname, SPEC_ADDR (sym->etype)); @@ -241,30 +242,45 @@ emitRegularMap (memmap * map, bool addPublics, bool arFlag) else { /* allocate space */ - if ((options.debug || sym->level == 0) && !options.nodebug) + 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) getSize (sym->type) & 0xffff); + tfprintf (map->oFile, "\t!ds\n", + (unsigned int) getSize (sym->type) & 0xffff); } /* 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)) + if (IS_AGGREGATE (sym->type)) { ival = initAggregates (sym, sym->ival, NULL); - else + } else { ival = newNode ('=', newAst_VALUE (symbolVal (sym)), decorateType (resolveSymbols (list2expr (sym->ival)))); + } codeOutFile = statsg->oFile; allocInfo = 0; + + // set ival's lineno to where the symbol was defined + if (ival) ival->lineno=sym->lineDef; eBBlockFromiCode (iCodeFromAst (ival)); allocInfo = 1; + + /* if the ival is a symbol assigned to an aggregate, + (bug #458099 -> #462479) + we don't need it anymore, so delete it from its segment */ + if (IS_AST_SYM_VALUE(sym->ival->init.node) && + IS_AGGREGATE (sym->type) ) { + symIval=AST_SYMBOL(sym->ival->init.node); + segment = SPEC_OCLS (symIval->etype); + deleteSetItem (&segment->syms, symIval); + } + sym->ival = NULL; } } @@ -373,7 +389,7 @@ initPointer (initList * ilist) return val; } wrong: - werror (E_INIT_WRONG); + werror (W_INIT_WRONG); return NULL; } @@ -395,12 +411,12 @@ printChar (FILE * ofile, char *s, int plen) i = 60; while (i && *s && pplen < plen) { - if (*s < ' ' || *s == '\"') + if (*s < ' ' || *s == '\"' || *s=='\\') { *p = '\0'; if (p != buf) tfprintf (ofile, "\t!ascii\n", buf); - tfprintf (ofile, "\t!db !constbyte\n", *s); + tfprintf (ofile, "\t!db !constbyte\n", (unsigned char)*s); p = buf; } else @@ -431,7 +447,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 +458,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 +482,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,11 +507,11 @@ 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)); } /*-----------------------------------------------------------------*/ @@ -692,8 +712,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_EXESS_ARRAY_INITIALIZERS, sym->name, sym->lineDef); + } break; + } } /* if we have not been given a size */ @@ -714,7 +739,7 @@ printIvalFuncPtr (sym_link * type, initList * ilist, FILE * oFile) val = list2val (ilist); /* 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 +803,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 { @@ -814,9 +846,9 @@ printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile) } } - - if (val->sym && val->sym->isstrlit) + if (val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) { addSet (&statsg->syms, val->sym); + } return 1; } @@ -850,8 +882,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)) @@ -883,11 +915,15 @@ printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile) } else if (size == FPTRSIZE) { - tfprintf (oFile, "\t!dws\n", val->name); + if (port->use_dw_for_init) { + tfprintf (oFile, "\t!dws\n", val->name); + } else { + printPointerType (oFile, val->name); + } } 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)))); } @@ -959,42 +995,39 @@ emitStaticSeg (memmap * map, FILE * out) 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 (!TARGET_IS_MCS51 && !TARGET_IS_DS390 && sym->ival) + if (sym->ival) { fprintf (out, "%s:\n", sym->rname); noAlloc++; @@ -1025,6 +1058,7 @@ emitStaticSeg (memmap * map, FILE * out) void emitMaps () { + inInitMode++; /* no special considerations for the following data, idata & bit & xdata */ emitRegularMap (data, TRUE, TRUE); @@ -1037,6 +1071,7 @@ emitMaps () emitRegularMap (code, TRUE, FALSE); emitStaticSeg (statsg, code->oFile); + inInitMode--; } /*-----------------------------------------------------------------*/ @@ -1056,23 +1091,23 @@ flushStatics (void) void createInterruptVect (FILE * vFile) { - int i = 0; + unsigned i = 0; mainf = newSymbol ("main", 0); mainf->block = 0; /* 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; } @@ -1216,9 +1251,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) @@ -1240,7 +1274,7 @@ 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", @@ -1249,9 +1283,9 @@ emitOverlay (FILE * afile) } else { - if ((options.debug || sym->level == 0) && !options.nodebug) + 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); @@ -1273,7 +1307,7 @@ glue () addSetHead (&tmpfileSet, ovrFile); /* print the global struct definitions */ - if (options.debug && !options.nodebug) + if (options.debug) cdbStructBlock (0, cdbFile); vFile = tempfile (); @@ -1296,17 +1330,17 @@ glue () if (!options.c1mode) { - sprintf (buffer, srcFileName); - strcat (buffer, ".asm"); + 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); } @@ -1354,7 +1388,7 @@ glue () 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"); @@ -1376,7 +1410,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"); @@ -1393,7 +1427,7 @@ glue () copyFile (asmFile, xdata->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"); @@ -1416,7 +1450,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 @@ -1451,7 +1485,7 @@ glue () } 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 @@ -1473,7 +1507,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 */ @@ -1502,6 +1536,42 @@ glue () 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(). @@ -1519,7 +1589,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"); @@ -1535,11 +1605,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; -}