* device/lib/z80/printf.c: Changed emitter to volatile to work
[fw/sdcc] / src / SDCCast.c
index 7092d9ea1e545fbed7f76b1fafdf701b4ef40126..61c5655bf6be7dfee42c8ba9522d618a664c23b9 100644 (file)
@@ -367,6 +367,7 @@ resolveSymbols (ast * tree)
   if (tree == NULL)
     return tree;
 
+#if 0
   /* print the line          */
   /* if not block & function */
   if (tree->type == EX_OP &&
@@ -377,6 +378,7 @@ resolveSymbols (ast * tree)
       filename = tree->filename;
       lineno = tree->lineno;
     }
+#endif
 
   /* make sure we resolve the true & false labels for ifx */
   if (tree->type == EX_OP && tree->opval.op == IFX)
@@ -477,8 +479,7 @@ resolveChildren:
 /*-----------------------------------------------------------------*/
 /* setAstLineno - walks a ast tree & sets the line number          */
 /*-----------------------------------------------------------------*/
-int 
-setAstLineno (ast * tree, int lineno)
+int setAstLineno (ast * tree, int lineno)
 {
   if (!tree)
     return 0;
@@ -505,7 +506,7 @@ funcOfType (char *name, sym_link * type, sym_link * argType,
   DCL_TYPE (sym->type) = FUNCTION;
   sym->type->next = copyLinkChain (type);
   sym->etype = getSpec (sym->type);
-  FUNC_ISREENT(sym->type) = rent;
+  FUNC_ISREENT(sym->type) = rent ? 1 : 0;
 
   /* if arguments required */
   if (nArgs)
@@ -753,6 +754,7 @@ processParms (ast * func,
   /* make a copy and change the regparm type to the defined parm */
   actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
   SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
+  SPEC_ARGREG  (actParm->etype) = SPEC_ARGREG (defParm->etype);
   (*parmNumber)++;
   return 0;
 }
@@ -950,6 +952,13 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
                               newNode ('[', sym,
                                   newAst_VALUE (valueFromLit ((float) i))),
                               newAst_VALUE (valueFromLit (*s))));
+
+      // now we don't need iexpr's symbol anymore
+      {
+       symbol *sym=AST_SYMBOL(iexpr);
+       memmap *segment=SPEC_OCLS(sym->etype);
+       deleteSetItem(&segment->syms, sym);
+      }
       return decorateType (resolveSymbols (rast));
     }
 
@@ -1078,6 +1087,16 @@ gatherAutoInit (symbol * autoChain)
       /* if there is an initial value */
       if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
        {
+         initList *ilist=sym->ival;
+         
+         while (ilist->type == INIT_DEEP) {
+           ilist = ilist->init.deep;
+         }
+
+         /* update lineno for error msg */
+         lineno=sym->lineDef;
+         setAstLineno (ilist->init.node, lineno);
+         
          if (IS_AGGREGATE (sym->type)) {
            work = initAggregates (sym, sym->ival, NULL);
          } else {
@@ -1088,8 +1107,10 @@ gatherAutoInit (symbol * autoChain)
            work = newNode ('=', newAst_VALUE (symbolVal (sym)),
                            list2expr (sym->ival));
          }
-
+         
+         // just to be sure
          setAstLineno (work, sym->lineDef);
+
          sym->ival = NULL;
          if (init)
            init = newNode (NULLOP, init, work);
@@ -1512,8 +1533,7 @@ isConformingBody (ast * pbody, symbol * sym, ast * body)
   /* if we reach the end or a leaf then true */
   if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
     return TRUE;
-
-
+  
   /* if anything else is "volatile" */
   if (IS_VOLATILE (TETYPE (pbody)))
     return FALSE;
@@ -1524,6 +1544,10 @@ isConformingBody (ast * pbody, symbol * sym, ast * body)
     {
 /*------------------------------------------------------------------*/
     case '[':
+      // if the loopvar is used as an index
+      if (astHasSymbol(pbody->right, sym)) {
+       return FALSE;
+      }
       return isConformingBody (pbody->right, sym, body);
 
 /*------------------------------------------------------------------*/
@@ -1792,14 +1816,15 @@ reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
   rloop = newNode (NULLOP,
                   createIf (newAst_VALUE (symbolVal (sym)),
                             newNode (GOTO,
-                  newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
+                                     newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
                                      NULL), NULL),
                   newNode ('=',
                            newAst_VALUE (symbolVal (sym)),
                            end));
-
+  
   replLoopSym (loop->left, sym);
-
+  setAstLineno (rloop, init->lineno);
+  
   rloop = newNode (NULLOP,
                   newNode ('=',
                            newAst_VALUE (symbolVal (sym)),
@@ -1809,12 +1834,13 @@ reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
                                         loop->left,
                                         newNode (NULLOP,
                                                  newNode (SUB_ASSIGN,
-                                            newAst_VALUE (symbolVal (sym)),
-                                            newAst_VALUE (constVal ("1"))),
+                                                          newAst_VALUE (symbolVal (sym)),
+                                                          newAst_VALUE (constVal ("1"))),
                                                  rloop))));
-
+  
+  rloop->lineno=init->lineno;
   return decorateType (rloop);
-
+  
 }
 
 /*-----------------------------------------------------------------*/
@@ -1837,6 +1863,7 @@ decorateType (ast * tree)
 
   tree->decorated = 1;
 
+#if 0
   /* print the line          */
   /* if not block & function */
   if (tree->type == EX_OP &&
@@ -1847,6 +1874,7 @@ decorateType (ast * tree)
       filename = tree->filename;
       lineno = tree->lineno;
     }
+#endif
 
   /* if any child is an error | this one is an error do nothing */
   if (tree->isError ||
@@ -1930,6 +1958,22 @@ decorateType (ast * tree)
       tree->left = dtl;
     if (dtr != tree->right)
       tree->right = dtr;
+
+    /* special case for left shift operation : cast up right->left if type of left
+       has greater size than right */
+    if (tree->left && tree->right && tree->right->opval.op == LEFT_OP) {
+       int lsize = getSize(LTYPE(tree));
+       int rsize = getSize(RTYPE(tree));
+
+       if (lsize > rsize) {
+           tree->right->decorated = 0;
+           tree->right->left = newNode( CAST, (lsize == 2 ? 
+                                              newAst_LINK(newIntLink()) : 
+                                              newAst_LINK(newLongLink())),
+                                       tree->right->left);
+           tree->right = decorateType(tree->right);
+       }
+    }
   }
 
   /* depending on type of operator do */
@@ -2136,8 +2180,8 @@ decorateType (ast * tree)
 
       if (IS_FUNC (LTYPE (tree)))
        {
-         werror (E_ILLEGAL_ADDR, "address of function");
-         goto errorTreeReturn;
+         // this ought to be ignored
+         return (tree->left);
        }
 
       if (IS_LITERAL(LTYPE(tree)))
@@ -2442,7 +2486,7 @@ decorateType (ast * tree)
 
       LRVAL (tree) = RRVAL (tree) = 1;
       /* if the left is a pointer */
-      if (IS_PTR (LTYPE (tree)))
+      if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
        TETYPE (tree) = getSpec (TTYPE (tree) =
                                 LTYPE (tree));
       else
@@ -2643,19 +2687,46 @@ decorateType (ast * tree)
                                   tree->opval.val->type);
          return tree;
        }
+#if 0
+      /* a left shift must be done with at least 16bits */
+      if ((tree->opval.op==LEFT_OP) && (getSize(LTYPE(tree))<2)) {
+       // insert a cast
+       if (IS_AST_SYM_VALUE(tree->left) || IS_AST_OP(tree->left)) {
+         tree->left = 
+           decorateType (newNode (CAST,
+                                  newAst_LINK(copyLinkChain(LTYPE(tree))),
+                                  tree->left));
+         SPEC_NOUN(tree->left->left->ftype)=V_INT;
+       } else {
+         // must be a literal, we can do it right away
+         SPEC_NOUN(tree->left->opval.val->type)=V_INT;
+       }
+      }
+#endif
       /* if only the right side is a literal & we are
          shifting more than size of the left operand then zero */
       if (IS_LITERAL (RTYPE (tree)) &&
          ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
          (getSize (LTYPE (tree)) * 8))
        {
-         werror (W_SHIFT_CHANGED,
-                 (tree->opval.op == LEFT_OP ? "left" : "right"));
-         tree->type = EX_VALUE;
-         tree->left = tree->right = NULL;
-         tree->opval.val = constVal ("0");
-         TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
-         return tree;
+           /* if left shift then cast up */
+           if (tree->opval.op==LEFT_OP) {
+               int size = getSize(LTYPE(tree));
+               tree->left = 
+                   decorateType (newNode (CAST,
+                                          (size == 1 ? newAst_LINK(newIntLink()) : 
+                                           (size == 2 ? newAst_LINK(newLongLink()) : 
+                                            newAst_LINK(newIntLink()))),
+                                          tree->left));
+           } else {
+               werror (W_SHIFT_CHANGED,
+                       (tree->opval.op == LEFT_OP ? "left" : "right"));
+               tree->type = EX_VALUE;
+               tree->left = tree->right = NULL;
+               tree->opval.val = constVal ("0");
+               TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
+               return tree;
+           }
        }
       LRVAL (tree) = RRVAL (tree) = 1;
       if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
@@ -2713,12 +2784,16 @@ decorateType (ast * tree)
              LRVAL (tree) = 1;
       }
 #else
+#if 0 // this is already checked, now this could be explicit
       /* if pointer to struct then check names */
       if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
          IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
-         strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) {
-             werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag);
-      }
+         strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) 
+       {
+         werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
+                SPEC_STRUCT(LETYPE(tree))->tag);
+       }
+#endif
       /* if the right is a literal replace the tree */
       if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
        tree->type = EX_VALUE;