Added simple assertions to help bug tracking
[fw/sdcc] / src / SDCCglue.c
index b95d90dbc65cf2075b051442c634da0535b3a870..f378ab1af21b51a0091d0704ed3e2228fe7fc3fa 100644 (file)
 #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 <unistd.h>
-#undef link
-#else
-
 #include <unistd.h>
 #endif
-#else
-// No unistd.h in Borland C++
-#endif
 
 symbol *interrupts[256];
 
@@ -160,6 +150,7 @@ static void
 emitRegularMap (memmap * map, bool addPublics, bool arFlag)
 {
   symbol *sym;
+  ast *ival = NULL;
 
   if (addPublics)
     {
@@ -211,29 +202,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,20 +229,21 @@ 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))
            ival = initAggregates (sym, sym->ival, NULL);
@@ -263,6 +252,10 @@ emitRegularMap (memmap * map, bool addPublics, bool arFlag)
                     decorateType (resolveSymbols (list2expr (sym->ival))));
          codeOutFile = statsg->oFile;
          allocInfo = 0;
+
+         // set ival's lineno to where the symbol was defined
+         ival->lineno=sym->lineDef;
+
          eBBlockFromiCode (iCodeFromAst (ival));
          allocInfo = 1;
          sym->ival = NULL;
@@ -431,7 +424,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 +435,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:
@@ -487,11 +483,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 +688,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 +715,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 +779,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
        {
@@ -850,7 +858,7 @@ printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
       return;
 
   /* check the type      */
-  if (checkType (type, val->type) == 0)
+  if (compareType (type, val->type) == 0)
     werror (E_INIT_WRONG);
 
   /* if val is literal */
@@ -891,7 +899,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))));
     }
@@ -963,40 +971,37 @@ 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 (sym->ival)
            {
@@ -1029,6 +1034,7 @@ emitStaticSeg (memmap * map, FILE * out)
 void 
 emitMaps ()
 {
+  inInitMode++;
   /* no special considerations for the following
      data, idata & bit & xdata */
   emitRegularMap (data, TRUE, TRUE);
@@ -1041,6 +1047,7 @@ emitMaps ()
   emitRegularMap (code, TRUE, FALSE);
 
   emitStaticSeg (statsg, code->oFile);
+  inInitMode--;
 }
 
 /*-----------------------------------------------------------------*/
@@ -1067,7 +1074,7 @@ 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;
     }
@@ -1076,7 +1083,7 @@ createInterruptVect (FILE * vFile)
   if (!mainf->fbody)
     {
       /* if ! compile only then main function should be present */
-      if (!options.cc_only)
+      if (!options.cc_only && !noAssemble)
        werror (E_NO_MAIN);
       return;
     }
@@ -1220,9 +1227,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,7 +1250,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",
@@ -1253,9 +1259,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);
@@ -1277,7 +1283,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 +1306,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);
     }
 
@@ -1506,6 +1512,15 @@ 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 a'la tmpfile which avoids the bugs
     in cygwin wrt c:\tmp.
     Scans, in order: TMP, TEMP, TMPDIR, else uses tmpfile().