948d57de2a296a7587caa6b05abde022e0e0400c
[fw/sdcc] / src / SDCCast.c
1 /*-------------------------------------------------------------------------
2   SDCCast.c - source file for parser support & all ast related routines
3
4              Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
5
6    This program is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by the
8    Free Software Foundation; either version 2, or (at your option) any
9    later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20    In other words, you are welcome to use, share and improve this program.
21    You are forbidden to forbid anyone else to use, share and improve
22    what you give them.   Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
24
25 #include "common.h"
26 #include "newalloc.h"
27
28 int currLineno = 0;
29 set *astList = NULL;
30 set *operKeyReset = NULL;
31 ast *staticAutos = NULL;
32 int labelKey = 1;
33
34 #define LRVAL(x) x->left->rvalue
35 #define RRVAL(x) x->right->rvalue
36 #define TRVAL(x) x->rvalue
37 #define LLVAL(x) x->left->lvalue
38 #define RLVAL(x) x->right->lvalue
39 #define TLVAL(x) x->lvalue
40 #define RTYPE(x) x->right->ftype
41 #define RETYPE(x) x->right->etype
42 #define LTYPE(x) x->left->ftype
43 #define LETYPE(x) x->left->etype
44 #define TTYPE(x) x->ftype
45 #define TETYPE(x) x->etype
46 #define ALLOCATE 1
47 #define DEALLOCATE 2
48
49 char buffer[1024];
50 int noLineno = 0;
51 int noAlloc = 0;
52 symbol *currFunc;
53 ast *createIval (ast *, sym_link *, initList *, ast *);
54 ast *createIvalCharPtr (ast *, sym_link *, ast *);
55 ast *optimizeRRCRLC (ast *);
56 ast *optimizeGetHbit (ast *);
57 ast *backPatchLabels (ast *, symbol *, symbol *);
58 int inInitMode = 0;
59 memmap *GcurMemmap=NULL;  /* points to the memmap that's currently active */
60 FILE *codeOutFile;
61 int 
62 ptt (ast * tree)
63 {
64   printTypeChain (tree->ftype, stdout);
65   return 0;
66 }
67
68
69 /*-----------------------------------------------------------------*/
70 /* newAst - creates a fresh node for an expression tree           */
71 /*-----------------------------------------------------------------*/
72 #if 0
73 ast *
74 newAst (int type, void *op)
75 {
76   ast *ex;
77   static int oldLineno = 0;
78
79   Safe_calloc (1, ex, sizeof (ast));
80
81   ex->type = type;
82   ex->lineno = (noLineno ? oldLineno : yylineno);
83   ex->filename = currFname;
84   ex->level = NestLevel;
85   ex->block = currBlockno;
86   ex->initMode = inInitMode;
87
88   /* depending on the type */
89   switch (type)
90     {
91     case EX_VALUE:
92       ex->opval.val = (value *) op;
93       break;
94     case EX_OP:
95       ex->opval.op = (long) op;
96       break;
97     case EX_LINK:
98       ex->opval.lnk = (sym_link *) op;
99       break;
100     case EX_STMNT:
101       ex->opval.stmnt = (unsigned) op;
102     }
103
104   return ex;
105 }
106 #endif
107
108 static ast *
109 newAst_ (unsigned type)
110 {
111   ast *ex;
112   static int oldLineno = 0;
113
114   ex = Safe_calloc (1, sizeof (ast));
115
116   ex->type = type;
117   ex->lineno = (noLineno ? oldLineno : yylineno);
118   ex->filename = currFname;
119   ex->level = NestLevel;
120   ex->block = currBlockno;
121   ex->initMode = inInitMode;
122   return ex;
123 }
124
125 ast *
126 newAst_VALUE (value * val)
127 {
128   ast *ex = newAst_ (EX_VALUE);
129   ex->opval.val = val;
130   return ex;
131 }
132
133 ast *
134 newAst_OP (unsigned op)
135 {
136   ast *ex = newAst_ (EX_OP);
137   ex->opval.op = op;
138   return ex;
139 }
140
141 ast *
142 newAst_LINK (sym_link * val)
143 {
144   ast *ex = newAst_ (EX_LINK);
145   ex->opval.lnk = val;
146   return ex;
147 }
148
149 ast *
150 newAst_STMNT (unsigned val)
151 {
152   ast *ex = newAst_ (EX_STMNT);
153   ex->opval.stmnt = val;
154   return ex;
155 }
156
157 /*-----------------------------------------------------------------*/
158 /* newNode - creates a new node                                    */
159 /*-----------------------------------------------------------------*/
160 ast *
161 newNode (long op, ast * left, ast * right)
162 {
163   ast *ex;
164
165   ex = newAst_OP (op);
166   ex->left = left;
167   ex->right = right;
168
169   return ex;
170 }
171
172 /*-----------------------------------------------------------------*/
173 /* newIfxNode - creates a new Ifx Node                             */
174 /*-----------------------------------------------------------------*/
175 ast *
176 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
177 {
178   ast *ifxNode;
179
180   /* if this is a literal then we already know the result */
181   if (condAst->etype && IS_LITERAL (condAst->etype))
182     {
183
184       /* then depending on the expression value */
185       if (floatFromVal (condAst->opval.val))
186         ifxNode = newNode (GOTO,
187                            newAst_VALUE (symbolVal (trueLabel)),
188                            NULL);
189       else
190         ifxNode = newNode (GOTO,
191                            newAst_VALUE (symbolVal (falseLabel)),
192                            NULL);
193     }
194   else
195     {
196       ifxNode = newNode (IFX, condAst, NULL);
197       ifxNode->trueLabel = trueLabel;
198       ifxNode->falseLabel = falseLabel;
199     }
200
201   return ifxNode;
202 }
203
204 /*-----------------------------------------------------------------*/
205 /* copyAstValues - copies value portion of ast if needed     */
206 /*-----------------------------------------------------------------*/
207 void 
208 copyAstValues (ast * dest, ast * src)
209 {
210   switch (src->opval.op)
211     {
212     case BLOCK:
213       dest->values.sym = copySymbolChain (src->values.sym);
214       break;
215
216     case SWITCH:
217       dest->values.switchVals.swVals =
218         copyValue (src->values.switchVals.swVals);
219       dest->values.switchVals.swDefault =
220         src->values.switchVals.swDefault;
221       dest->values.switchVals.swNum =
222         src->values.switchVals.swNum;
223       break;
224
225     case INLINEASM:
226       dest->values.inlineasm = Safe_calloc (1, strlen (src->values.inlineasm) + 1);
227       strcpy (dest->values.inlineasm, src->values.inlineasm);
228
229     case FOR:
230       AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
231       AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
232       AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
233       AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
234       AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
235       AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
236       AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
237     }
238
239 }
240
241 /*-----------------------------------------------------------------*/
242 /* copyAst - makes a copy of a given astession                     */
243 /*-----------------------------------------------------------------*/
244 ast *
245 copyAst (ast * src)
246 {
247   ast *dest;
248
249   if (!src)
250     return NULL;
251
252   dest = Safe_calloc (1, sizeof (ast));
253
254   dest->type = src->type;
255   dest->lineno = src->lineno;
256   dest->level = src->level;
257   dest->funcName = src->funcName;
258   dest->argSym = src->argSym;
259
260   /* if this is a leaf */
261   /* if value */
262   if (src->type == EX_VALUE)
263     {
264       dest->opval.val = copyValue (src->opval.val);
265       goto exit;
266     }
267
268   /* if link */
269   if (src->type == EX_LINK)
270     {
271       dest->opval.lnk = copyLinkChain (src->opval.lnk);
272       goto exit;
273     }
274
275   dest->opval.op = src->opval.op;
276
277   /* if this is a node that has special values */
278   copyAstValues (dest, src);
279
280   if (src->ftype)
281     dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
282
283   dest->trueLabel = copySymbol (src->trueLabel);
284   dest->falseLabel = copySymbol (src->falseLabel);
285   dest->left = copyAst (src->left);
286   dest->right = copyAst (src->right);
287 exit:
288   return dest;
289
290 }
291
292 /*-----------------------------------------------------------------*/
293 /* hasSEFcalls - returns TRUE if tree has a function call          */
294 /*-----------------------------------------------------------------*/
295 bool 
296 hasSEFcalls (ast * tree)
297 {
298   if (!tree)
299     return FALSE;
300
301   if (tree->type == EX_OP &&
302       (tree->opval.op == CALL ||
303        tree->opval.op == PCALL ||
304        tree->opval.op == '=' ||
305        tree->opval.op == INC_OP ||
306        tree->opval.op == DEC_OP))
307     return TRUE;
308
309   return (hasSEFcalls (tree->left) |
310           hasSEFcalls (tree->right));
311 }
312
313 /*-----------------------------------------------------------------*/
314 /* isAstEqual - compares two asts & returns 1 if they are equal    */
315 /*-----------------------------------------------------------------*/
316 int 
317 isAstEqual (ast * t1, ast * t2)
318 {
319   if (!t1 && !t2)
320     return 1;
321
322   if (!t1 || !t2)
323     return 0;
324
325   /* match type */
326   if (t1->type != t2->type)
327     return 0;
328
329   switch (t1->type)
330     {
331     case EX_OP:
332       if (t1->opval.op != t2->opval.op)
333         return 0;
334       return (isAstEqual (t1->left, t2->left) &&
335               isAstEqual (t1->right, t2->right));
336       break;
337
338     case EX_VALUE:
339       if (t1->opval.val->sym)
340         {
341           if (!t2->opval.val->sym)
342             return 0;
343           else
344             return isSymbolEqual (t1->opval.val->sym,
345                                   t2->opval.val->sym);
346         }
347       else
348         {
349           if (t2->opval.val->sym)
350             return 0;
351           else
352             return (floatFromVal (t1->opval.val) ==
353                     floatFromVal (t2->opval.val));
354         }
355       break;
356
357       /* only compare these two types */
358     default:
359       return 0;
360     }
361
362   return 0;
363 }
364
365 /*-----------------------------------------------------------------*/
366 /* resolveSymbols - resolve symbols from the symbol table          */
367 /*-----------------------------------------------------------------*/
368 ast *
369 resolveSymbols (ast * tree)
370 {
371   /* walk the entire tree and check for values */
372   /* with symbols if we find one then replace  */
373   /* symbol with that from the symbol table    */
374
375   if (tree == NULL)
376     return tree;
377
378   /* print the line          */
379   /* if not block & function */
380   if (tree->type == EX_OP &&
381       (tree->opval.op != FUNCTION &&
382        tree->opval.op != BLOCK &&
383        tree->opval.op != NULLOP))
384     {
385       filename = tree->filename;
386       lineno = tree->lineno;
387     }
388
389   /* make sure we resolve the true & false labels for ifx */
390   if (tree->type == EX_OP && tree->opval.op == IFX)
391     {
392       symbol *csym;
393
394       if (tree->trueLabel)
395         {
396           if ((csym = findSym (LabelTab, tree->trueLabel,
397                                tree->trueLabel->name)))
398             tree->trueLabel = csym;
399           else
400             werror (E_LABEL_UNDEF, tree->trueLabel->name);
401         }
402
403       if (tree->falseLabel)
404         {
405           if ((csym = findSym (LabelTab,
406                                tree->falseLabel,
407                                tree->falseLabel->name)))
408             tree->falseLabel = csym;
409           else
410             werror (E_LABEL_UNDEF, tree->falseLabel->name);
411         }
412
413     }
414
415   /* if this is a label resolve it from the labelTab */
416   if (IS_AST_VALUE (tree) &&
417       tree->opval.val->sym &&
418       tree->opval.val->sym->islbl)
419     {
420
421       symbol *csym = findSym (LabelTab, tree->opval.val->sym,
422                               tree->opval.val->sym->name);
423
424       if (!csym)
425         werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
426       else
427         tree->opval.val->sym = csym;
428
429       goto resolveChildren;
430     }
431
432   /* do only for leafs */
433   if (IS_AST_VALUE (tree) &&
434       tree->opval.val->sym &&
435       !tree->opval.val->sym->implicit)
436     {
437
438       symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
439
440       /* if found in the symbol table & they r not the same */
441       if (csym && tree->opval.val->sym != csym)
442         {
443           tree->opval.val->sym = csym;
444           tree->opval.val->type = csym->type;
445           tree->opval.val->etype = csym->etype;
446         }
447
448       /* if not found in the symbol table */
449       /* mark it as undefined assume it is */
450       /* an integer in data space         */
451       if (!csym && !tree->opval.val->sym->implicit)
452         {
453
454           /* if this is a function name then */
455           /* mark it as returning an int     */
456           if (tree->funcName)
457             {
458               tree->opval.val->sym->type = newLink ();
459               DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
460               tree->opval.val->sym->type->next =
461                 tree->opval.val->sym->etype = newIntLink ();
462               tree->opval.val->etype = tree->opval.val->etype;
463               tree->opval.val->type = tree->opval.val->sym->type;
464               werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
465             }
466           else
467             {
468               tree->opval.val->sym->undefined = 1;
469               tree->opval.val->type =
470                 tree->opval.val->etype = newIntLink ();
471               tree->opval.val->sym->type =
472                 tree->opval.val->sym->etype = newIntLink ();
473             }
474         }
475     }
476
477 resolveChildren:
478   resolveSymbols (tree->left);
479   resolveSymbols (tree->right);
480
481   return tree;
482 }
483
484 /*-----------------------------------------------------------------*/
485 /* setAstLineno - walks a ast tree & sets the line number          */
486 /*-----------------------------------------------------------------*/
487 int 
488 setAstLineno (ast * tree, int lineno)
489 {
490   if (!tree)
491     return 0;
492
493   tree->lineno = lineno;
494   setAstLineno (tree->left, lineno);
495   setAstLineno (tree->right, lineno);
496   return 0;
497 }
498
499 #if 0
500 /* this functions seems to be superfluous?! kmh */
501
502 /*-----------------------------------------------------------------*/
503 /* resolveFromTable - will return the symbal table value           */
504 /*-----------------------------------------------------------------*/
505 value *
506 resolveFromTable (value * val)
507 {
508   symbol *csym;
509
510   if (!val->sym)
511     return val;
512
513   csym = findSymWithLevel (SymbolTab, val->sym);
514
515   /* if found in the symbol table & they r not the same */
516   if (csym && val->sym != csym &&
517       csym->level == val->sym->level &&
518       csym->_isparm &&
519       !csym->ismyparm)
520     {
521
522       val->sym = csym;
523       val->type = csym->type;
524       val->etype = csym->etype;
525     }
526
527   return val;
528 }
529 #endif
530
531 /*-----------------------------------------------------------------*/
532 /* funcOfType :- function of type with name                        */
533 /*-----------------------------------------------------------------*/
534 symbol *
535 funcOfType (char *name, sym_link * type, sym_link * argType,
536             int nArgs, int rent)
537 {
538   symbol *sym;
539   int argStack = 0;
540   /* create the symbol */
541   sym = newSymbol (name, 0);
542
543   /* if arguments required */
544   if (nArgs)
545     {
546
547       value *args;
548       args = sym->args = newValue ();
549
550       while (nArgs--)
551         {
552           argStack += getSize (type);
553           args->type = copyLinkChain (argType);
554           args->etype = getSpec (args->type);
555           if (!nArgs)
556             break;
557           args = args->next = newValue ();
558         }
559     }
560
561   /* setup return value */
562   sym->type = newLink ();
563   DCL_TYPE (sym->type) = FUNCTION;
564   sym->type->next = copyLinkChain (type);
565   sym->etype = getSpec (sym->type);
566   SPEC_RENT (sym->etype) = rent;
567
568   /* save it */
569   addSymChain (sym);
570   sym->cdef = 1;
571   sym->argStack = (rent ? argStack : 0);
572   allocVariables (sym);
573   return sym;
574
575 }
576
577 /*-----------------------------------------------------------------*/
578 /* reverseParms - will reverse a parameter tree                    */
579 /*-----------------------------------------------------------------*/
580 void 
581 reverseParms (ast * ptree)
582 {
583   ast *ttree;
584   if (!ptree)
585     return;
586
587   /* top down if we find a nonParm tree then quit */
588   if (ptree->type == EX_OP && ptree->opval.op == PARAM)
589     {
590       ttree = ptree->left;
591       ptree->left = ptree->right;
592       ptree->right = ttree;
593       reverseParms (ptree->left);
594       reverseParms (ptree->right);
595     }
596
597   return;
598 }
599
600 /*-----------------------------------------------------------------*/
601 /* processParms  - makes sure the parameters are okay and do some  */
602 /*                 processing with them                            */
603 /*-----------------------------------------------------------------*/
604 int 
605 processParms (ast * func,
606               value * defParm,
607               ast * actParm,
608               int *parmNumber,
609               bool rightmost)
610 {
611   sym_link *fetype = func->etype;
612
613   /* if none of them exist */
614   if (!defParm && !actParm)
615     return 0;
616
617   /* if the function is being called via a pointer &   */
618   /* it has not been defined a reentrant then we cannot */
619   /* have parameters                                   */
620   if (func->type != EX_VALUE && !IS_RENT (fetype) && !options.stackAuto)
621     {
622       werror (E_NONRENT_ARGS);
623       return 1;
624     }
625
626   /* if defined parameters ended but actual parameters */
627   /* exist and this is not defined as a variable arg   */
628   /* also check if statckAuto option is specified      */
629   if ((!defParm) && actParm && (!func->hasVargs) &&
630       !options.stackAuto && !IS_RENT (fetype))
631     {
632       werror (E_TOO_MANY_PARMS);
633       return 1;
634     }
635
636   /* if defined parameters present but no actual parameters */
637   if (defParm && !actParm)
638     {
639       werror (E_TOO_FEW_PARMS);
640       return 1;
641     }
642
643   /* If this is a varargs function... */
644   if (!defParm && actParm && func->hasVargs)
645     {
646       ast *newType = NULL;
647
648       if (IS_CAST_OP (actParm)
649           || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
650         {
651           /* Parameter was explicitly typecast; don't touch it. */
652           return 0;
653         }
654
655       /* If it's a small integer, upcast to int. */
656       if (IS_INTEGRAL (actParm->ftype)
657           && getSize (actParm->ftype) < (unsigned) INTSIZE)
658         {
659           newType = newAst_LINK (INTTYPE);
660         }
661
662       if (IS_PTR (actParm->ftype) && !IS_GENPTR (actParm->ftype))
663         {
664           newType = newAst_LINK (copyLinkChain (actParm->ftype));
665           DCL_TYPE (newType->opval.lnk) = GPOINTER;
666         }
667
668       if (IS_AGGREGATE (actParm->ftype))
669         {
670           newType = newAst_LINK (copyLinkChain (actParm->ftype));
671           DCL_TYPE (newType->opval.lnk) = GPOINTER;
672         }
673
674       if (newType)
675         {
676           /* cast required; change this op to a cast. */
677           ast *parmCopy = resolveSymbols (copyAst (actParm));
678
679           actParm->type = EX_OP;
680           actParm->opval.op = CAST;
681           actParm->left = newType;
682           actParm->right = parmCopy;
683           decorateType (actParm);
684         }
685       else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
686         {
687           return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
688           processParms (func, NULL, actParm->right, parmNumber, rightmost));
689         }
690       return 0;
691     }
692
693   /* if defined parameters ended but actual has not & */
694   /* stackAuto                */
695   if (!defParm && actParm &&
696       (options.stackAuto || IS_RENT (fetype)))
697     return 0;
698
699   resolveSymbols (actParm);
700   /* if this is a PARAM node then match left & right */
701   if (actParm->type == EX_OP && actParm->opval.op == PARAM)
702     {
703       return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
704               processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
705     }
706   else
707     {
708       /* If we have found a value node by following only right-hand links,
709        * then we know that there are no more values after us.
710        *
711        * Therefore, if there are more defined parameters, the caller didn't
712        * supply enough.
713        */
714       if (rightmost && defParm->next)
715         {
716           werror (E_TOO_FEW_PARMS);
717           return 1;
718         }
719     }
720
721   /* the parameter type must be at least castable */
722   if (checkType (defParm->type, actParm->ftype) == 0)
723     {
724       werror (E_TYPE_MISMATCH_PARM, *parmNumber);
725       werror (E_CONTINUE, "defined type ");
726       printTypeChain (defParm->type, stderr);
727       fprintf (stderr, "\n");
728       werror (E_CONTINUE, "actual type ");
729       printTypeChain (actParm->ftype, stderr);
730       fprintf (stderr, "\n");
731     }
732
733   /* if the parameter is castable then add the cast */
734   if (checkType (defParm->type, actParm->ftype) < 0)
735     {
736       ast *pTree = resolveSymbols (copyAst (actParm));
737
738       /* now change the current one to a cast */
739       actParm->type = EX_OP;
740       actParm->opval.op = CAST;
741       actParm->left = newAst_LINK (defParm->type);
742       actParm->right = pTree;
743       actParm->etype = defParm->etype;
744       actParm->ftype = defParm->type;
745     }
746
747 /*    actParm->argSym = resolveFromTable(defParm)->sym ; */
748
749   actParm->argSym = defParm->sym;
750   /* make a copy and change the regparm type to the defined parm */
751   actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
752   SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
753   (*parmNumber)++;
754   return 0;
755 }
756 /*-----------------------------------------------------------------*/
757 /* createIvalType - generates ival for basic types                 */
758 /*-----------------------------------------------------------------*/
759 ast *
760 createIvalType (ast * sym, sym_link * type, initList * ilist)
761 {
762   ast *iExpr;
763
764   /* if initList is deep */
765   if (ilist->type == INIT_DEEP)
766     ilist = ilist->init.deep;
767
768   iExpr = decorateType (resolveSymbols (list2expr (ilist)));
769   return decorateType (newNode ('=', sym, iExpr));
770 }
771
772 /*-----------------------------------------------------------------*/
773 /* createIvalStruct - generates initial value for structures       */
774 /*-----------------------------------------------------------------*/
775 ast *
776 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
777 {
778   ast *rast = NULL;
779   symbol *sflds;
780   initList *iloop;
781
782   sflds = SPEC_STRUCT (type)->fields;
783   if (ilist->type != INIT_DEEP)
784     {
785       werror (E_INIT_STRUCT, "");
786       return NULL;
787     }
788
789   iloop = ilist->init.deep;
790
791   for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
792     {
793       ast *lAst;
794
795       /* if we have come to end */
796       if (!iloop)
797         break;
798       sflds->implicit = 1;
799       lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
800       lAst = decorateType (resolveSymbols (lAst));
801       rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
802     }
803   return rast;
804 }
805
806
807 /*-----------------------------------------------------------------*/
808 /* createIvalArray - generates code for array initialization       */
809 /*-----------------------------------------------------------------*/
810 ast *
811 createIvalArray (ast * sym, sym_link * type, initList * ilist)
812 {
813   ast *rast = NULL;
814   initList *iloop;
815   int lcnt = 0, size = 0;
816
817   /* take care of the special   case  */
818   /* array of characters can be init  */
819   /* by a string                      */
820   if (IS_CHAR (type->next))
821     if ((rast = createIvalCharPtr (sym,
822                                    type,
823                         decorateType (resolveSymbols (list2expr (ilist))))))
824
825       return decorateType (resolveSymbols (rast));
826
827   /* not the special case             */
828   if (ilist->type != INIT_DEEP)
829     {
830       werror (E_INIT_STRUCT, "");
831       return NULL;
832     }
833
834   iloop = ilist->init.deep;
835   lcnt = DCL_ELEM (type);
836
837   for (;;)
838     {
839       ast *aSym;
840       size++;
841
842       aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size - 1))));
843       aSym = decorateType (resolveSymbols (aSym));
844       rast = createIval (aSym, type->next, iloop, rast);
845       iloop = (iloop ? iloop->next : NULL);
846       if (!iloop)
847         break;
848       /* if not array limits given & we */
849       /* are out of initialisers then   */
850       if (!DCL_ELEM (type) && !iloop)
851         break;
852
853       /* no of elements given and we    */
854       /* have generated for all of them */
855       if (!--lcnt)
856         break;
857     }
858
859   /* if we have not been given a size  */
860   if (!DCL_ELEM (type))
861     DCL_ELEM (type) = size;
862
863   return decorateType (resolveSymbols (rast));
864 }
865
866
867 /*-----------------------------------------------------------------*/
868 /* createIvalCharPtr - generates initial values for char pointers  */
869 /*-----------------------------------------------------------------*/
870 ast *
871 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
872 {
873   ast *rast = NULL;
874
875   /* if this is a pointer & right is a literal array then */
876   /* just assignment will do                              */
877   if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
878                          SPEC_SCLS (iexpr->etype) == S_CODE)
879                         && IS_ARRAY (iexpr->ftype)))
880     return newNode ('=', sym, iexpr);
881
882   /* left side is an array so we have to assign each */
883   /* element                                         */
884   if ((IS_LITERAL (iexpr->etype) ||
885        SPEC_SCLS (iexpr->etype) == S_CODE)
886       && IS_ARRAY (iexpr->ftype))
887     {
888
889       /* for each character generate an assignment */
890       /* to the array element */
891       char *s = SPEC_CVAL (iexpr->etype).v_char;
892       int i = 0;
893
894       while (*s)
895         {
896           rast = newNode (NULLOP,
897                           rast,
898                           newNode ('=',
899                                    newNode ('[', sym,
900                                    newAst_VALUE (valueFromLit ((float) i))),
901                                    newAst_VALUE (valueFromLit (*s))));
902           i++;
903           s++;
904         }
905       rast = newNode (NULLOP,
906                       rast,
907                       newNode ('=',
908                                newNode ('[', sym,
909                                    newAst_VALUE (valueFromLit ((float) i))),
910                                newAst_VALUE (valueFromLit (*s))));
911       return decorateType (resolveSymbols (rast));
912     }
913
914   return NULL;
915 }
916
917 /*-----------------------------------------------------------------*/
918 /* createIvalPtr - generates initial value for pointers            */
919 /*-----------------------------------------------------------------*/
920 ast *
921 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
922 {
923   ast *rast;
924   ast *iexpr;
925
926   /* if deep then   */
927   if (ilist->type == INIT_DEEP)
928     ilist = ilist->init.deep;
929
930   iexpr = decorateType (resolveSymbols (list2expr (ilist)));
931
932   /* if character pointer */
933   if (IS_CHAR (type->next))
934     if ((rast = createIvalCharPtr (sym, type, iexpr)))
935       return rast;
936
937   return newNode ('=', sym, iexpr);
938 }
939
940 /*-----------------------------------------------------------------*/
941 /* createIval - generates code for initial value                   */
942 /*-----------------------------------------------------------------*/
943 ast *
944 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
945 {
946   ast *rast = NULL;
947
948   if (!ilist)
949     return NULL;
950
951   /* if structure then    */
952   if (IS_STRUCT (type))
953     rast = createIvalStruct (sym, type, ilist);
954   else
955     /* if this is a pointer */
956   if (IS_PTR (type))
957     rast = createIvalPtr (sym, type, ilist);
958   else
959     /* if this is an array   */
960   if (IS_ARRAY (type))
961     rast = createIvalArray (sym, type, ilist);
962   else
963     /* if type is SPECIFIER */
964   if (IS_SPEC (type))
965     rast = createIvalType (sym, type, ilist);
966   if (wid)
967     return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
968   else
969     return decorateType (resolveSymbols (rast));
970 }
971
972 /*-----------------------------------------------------------------*/
973 /* initAggregates - initialises aggregate variables with initv     */
974 /*-----------------------------------------------------------------*/
975 ast *
976 initAggregates (symbol * sym, initList * ival, ast * wid)
977 {
978   return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
979 }
980
981 /*-----------------------------------------------------------------*/
982 /* gatherAutoInit - creates assignment expressions for initial     */
983 /*    values                 */
984 /*-----------------------------------------------------------------*/
985 ast *
986 gatherAutoInit (symbol * autoChain)
987 {
988   ast *init = NULL;
989   ast *work;
990   symbol *sym;
991
992   inInitMode = 1;
993   for (sym = autoChain; sym; sym = sym->next)
994     {
995
996       /* resolve the symbols in the ival */
997       if (sym->ival)
998         resolveIvalSym (sym->ival);
999
1000       /* if this is a static variable & has an */
1001       /* initial value the code needs to be lifted */
1002       /* here to the main portion since they can be */
1003       /* initialised only once at the start    */
1004       if (IS_STATIC (sym->etype) && sym->ival &&
1005           SPEC_SCLS (sym->etype) != S_CODE)
1006         {
1007           symbol *newSym;
1008
1009           /* insert the symbol into the symbol table */
1010           /* with level = 0 & name = rname       */
1011           newSym = copySymbol (sym);
1012           addSym (SymbolTab, newSym, newSym->name, 0, 0);
1013
1014           /* now lift the code to main */
1015           if (IS_AGGREGATE (sym->type))
1016             work = initAggregates (sym, sym->ival, NULL);
1017           else
1018             work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1019                             list2expr (sym->ival));
1020
1021           setAstLineno (work, sym->lineDef);
1022
1023           sym->ival = NULL;
1024           if (staticAutos)
1025             staticAutos = newNode (NULLOP, staticAutos, work);
1026           else
1027             staticAutos = work;
1028
1029           continue;
1030         }
1031
1032       /* if there is an initial value */
1033       if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1034         {
1035           if (IS_AGGREGATE (sym->type))
1036             work = initAggregates (sym, sym->ival, NULL);
1037           else
1038             work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1039                             list2expr (sym->ival));
1040
1041           setAstLineno (work, sym->lineDef);
1042           sym->ival = NULL;
1043           if (init)
1044             init = newNode (NULLOP, init, work);
1045           else
1046             init = work;
1047         }
1048     }
1049   inInitMode = 0;
1050   return init;
1051 }
1052
1053 /*-----------------------------------------------------------------*/
1054 /* stringToSymbol - creates a symbol from a literal string         */
1055 /*-----------------------------------------------------------------*/
1056 static value *
1057 stringToSymbol (value * val)
1058 {
1059   char name[SDCC_NAME_MAX + 1];
1060   static int charLbl = 0;
1061   symbol *sym;
1062
1063   sprintf (name, "_str_%d", charLbl++);
1064   sym = newSymbol (name, 0);    /* make it @ level 0 */
1065   strcpy (sym->rname, name);
1066
1067   /* copy the type from the value passed */
1068   sym->type = copyLinkChain (val->type);
1069   sym->etype = getSpec (sym->type);
1070   /* change to storage class & output class */
1071   SPEC_SCLS (sym->etype) = S_CODE;
1072   SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1073   SPEC_STAT (sym->etype) = 1;
1074   /* make the level & block = 0 */
1075   sym->block = sym->level = 0;
1076   sym->isstrlit = 1;
1077   /* create an ival */
1078   sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1079   if (noAlloc == 0)
1080     {
1081       /* allocate it */
1082       addSymChain (sym);
1083       allocVariables (sym);
1084     }
1085   sym->ival = NULL;
1086   return symbolVal (sym);
1087
1088 }
1089
1090 /*-----------------------------------------------------------------*/
1091 /* processBlockVars - will go thru the ast looking for block if    */
1092 /*                    a block is found then will allocate the syms */
1093 /*                    will also gather the auto inits present      */
1094 /*-----------------------------------------------------------------*/
1095 ast *
1096 processBlockVars (ast * tree, int *stack, int action)
1097 {
1098   if (!tree)
1099     return NULL;
1100
1101   /* if this is a block */
1102   if (tree->type == EX_OP && tree->opval.op == BLOCK)
1103     {
1104       ast *autoInit;
1105
1106       if (action == ALLOCATE)
1107         {
1108           autoInit = gatherAutoInit (tree->values.sym);
1109           *stack += allocVariables (tree->values.sym);
1110
1111           /* if there are auto inits then do them */
1112           if (autoInit)
1113             tree->left = newNode (NULLOP, autoInit, tree->left);
1114         }
1115       else                      /* action is deallocate */
1116         deallocLocal (tree->values.sym);
1117     }
1118
1119   processBlockVars (tree->left, stack, action);
1120   processBlockVars (tree->right, stack, action);
1121   return tree;
1122 }
1123
1124 /*-----------------------------------------------------------------*/
1125 /* constExprValue - returns the value of a constant expression     */
1126 /*-----------------------------------------------------------------*/
1127 value *
1128 constExprValue (ast * cexpr, int check)
1129 {
1130   cexpr = decorateType (resolveSymbols (cexpr));
1131
1132   /* if this is not a constant then */
1133   if (!IS_LITERAL (cexpr->ftype))
1134     {
1135       /* then check if this is a literal array
1136          in code segment */
1137       if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1138           SPEC_CVAL (cexpr->etype).v_char &&
1139           IS_ARRAY (cexpr->ftype))
1140         {
1141           value *val = valFromType (cexpr->ftype);
1142           SPEC_SCLS (val->etype) = S_LITERAL;
1143           val->sym = cexpr->opval.val->sym;
1144           val->sym->type = copyLinkChain (cexpr->ftype);
1145           val->sym->etype = getSpec (val->sym->type);
1146           strcpy (val->name, cexpr->opval.val->sym->rname);
1147           return val;
1148         }
1149
1150       /* if we are casting a literal value then */
1151       if (IS_AST_OP (cexpr) &&
1152           cexpr->opval.op == CAST &&
1153           IS_LITERAL (cexpr->left->ftype))
1154         return valCastLiteral (cexpr->ftype,
1155                                floatFromVal (cexpr->left->opval.val));
1156
1157       if (IS_AST_VALUE (cexpr))
1158         return cexpr->opval.val;
1159
1160       if (check)
1161         werror (E_CONST_EXPECTED, "found expression");
1162
1163       return NULL;
1164     }
1165
1166   /* return the value */
1167   return cexpr->opval.val;
1168
1169 }
1170
1171 /*-----------------------------------------------------------------*/
1172 /* isLabelInAst - will return true if a given label is found       */
1173 /*-----------------------------------------------------------------*/
1174 bool 
1175 isLabelInAst (symbol * label, ast * tree)
1176 {
1177   if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1178     return FALSE;
1179
1180   if (IS_AST_OP (tree) &&
1181       tree->opval.op == LABEL &&
1182       isSymbolEqual (AST_SYMBOL (tree->left), label))
1183     return TRUE;
1184
1185   return isLabelInAst (label, tree->right) &&
1186     isLabelInAst (label, tree->left);
1187
1188 }
1189
1190 /*-----------------------------------------------------------------*/
1191 /* isLoopCountable - return true if the loop count can be determi- */
1192 /* -ned at compile time .                                          */
1193 /*-----------------------------------------------------------------*/
1194 bool 
1195 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1196                  symbol ** sym, ast ** init, ast ** end)
1197 {
1198
1199   /* the loop is considered countable if the following
1200      conditions are true :-
1201
1202      a) initExpr :- <sym> = <const>
1203      b) condExpr :- <sym> < <const1>
1204      c) loopExpr :- <sym> ++
1205    */
1206
1207   /* first check the initExpr */
1208   if (IS_AST_OP (initExpr) &&
1209       initExpr->opval.op == '=' &&      /* is assignment */
1210       IS_AST_SYM_VALUE (initExpr->left))
1211     {                           /* left is a symbol */
1212
1213       *sym = AST_SYMBOL (initExpr->left);
1214       *init = initExpr->right;
1215     }
1216   else
1217     return FALSE;
1218
1219   /* for now the symbol has to be of
1220      integral type */
1221   if (!IS_INTEGRAL ((*sym)->type))
1222     return FALSE;
1223
1224   /* now check condExpr */
1225   if (IS_AST_OP (condExpr))
1226     {
1227
1228       switch (condExpr->opval.op)
1229         {
1230         case '<':
1231           if (IS_AST_SYM_VALUE (condExpr->left) &&
1232               isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1233               IS_AST_LIT_VALUE (condExpr->right))
1234             {
1235               *end = condExpr->right;
1236               break;
1237             }
1238           return FALSE;
1239
1240         case '!':
1241           if (IS_AST_OP (condExpr->left) &&
1242               condExpr->left->opval.op == '>' &&
1243               IS_AST_LIT_VALUE (condExpr->left->right) &&
1244               IS_AST_SYM_VALUE (condExpr->left->left) &&
1245               isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1246             {
1247
1248               *end = newNode ('+', condExpr->left->right,
1249                               newAst_VALUE (constVal ("1")));
1250               break;
1251             }
1252           return FALSE;
1253
1254         default:
1255           return FALSE;
1256         }
1257
1258     }
1259
1260   /* check loop expression is of the form <sym>++ */
1261   if (!IS_AST_OP (loopExpr))
1262     return FALSE;
1263
1264   /* check if <sym> ++ */
1265   if (loopExpr->opval.op == INC_OP)
1266     {
1267
1268       if (loopExpr->left)
1269         {
1270           /* pre */
1271           if (IS_AST_SYM_VALUE (loopExpr->left) &&
1272               isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1273             return TRUE;
1274
1275         }
1276       else
1277         {
1278           /* post */
1279           if (IS_AST_SYM_VALUE (loopExpr->right) &&
1280               isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1281             return TRUE;
1282         }
1283
1284     }
1285   else
1286     {
1287       /* check for += */
1288       if (loopExpr->opval.op == ADD_ASSIGN)
1289         {
1290
1291           if (IS_AST_SYM_VALUE (loopExpr->left) &&
1292               isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1293               IS_AST_LIT_VALUE (loopExpr->right) &&
1294               (int) AST_LIT_VALUE (loopExpr->right) != 1)
1295             return TRUE;
1296         }
1297     }
1298
1299   return FALSE;
1300 }
1301
1302 /*-----------------------------------------------------------------*/
1303 /* astHasVolatile - returns true if ast contains any volatile      */
1304 /*-----------------------------------------------------------------*/
1305 bool 
1306 astHasVolatile (ast * tree)
1307 {
1308   if (!tree)
1309     return FALSE;
1310
1311   if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1312     return TRUE;
1313
1314   if (IS_AST_OP (tree))
1315     return astHasVolatile (tree->left) ||
1316       astHasVolatile (tree->right);
1317   else
1318     return FALSE;
1319 }
1320
1321 /*-----------------------------------------------------------------*/
1322 /* astHasPointer - return true if the ast contains any ptr variable */
1323 /*-----------------------------------------------------------------*/
1324 bool 
1325 astHasPointer (ast * tree)
1326 {
1327   if (!tree)
1328     return FALSE;
1329
1330   if (IS_AST_LINK (tree))
1331     return TRUE;
1332
1333   /* if we hit an array expression then check
1334      only the left side */
1335   if (IS_AST_OP (tree) && tree->opval.op == '[')
1336     return astHasPointer (tree->left);
1337
1338   if (IS_AST_VALUE (tree))
1339     return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1340
1341   return astHasPointer (tree->left) ||
1342     astHasPointer (tree->right);
1343
1344 }
1345
1346 /*-----------------------------------------------------------------*/
1347 /* astHasSymbol - return true if the ast has the given symbol      */
1348 /*-----------------------------------------------------------------*/
1349 bool 
1350 astHasSymbol (ast * tree, symbol * sym)
1351 {
1352   if (!tree || IS_AST_LINK (tree))
1353     return FALSE;
1354
1355   if (IS_AST_VALUE (tree))
1356     {
1357       if (IS_AST_SYM_VALUE (tree))
1358         return isSymbolEqual (AST_SYMBOL (tree), sym);
1359       else
1360         return FALSE;
1361     }
1362
1363   return astHasSymbol (tree->left, sym) ||
1364     astHasSymbol (tree->right, sym);
1365 }
1366
1367 /*-----------------------------------------------------------------*/
1368 /* isConformingBody - the loop body has to conform to a set of rules */
1369 /* for the loop to be considered reversible read on for rules      */
1370 /*-----------------------------------------------------------------*/
1371 bool 
1372 isConformingBody (ast * pbody, symbol * sym, ast * body)
1373 {
1374
1375   /* we are going to do a pre-order traversal of the
1376      tree && check for the following conditions. (essentially
1377      a set of very shallow tests )
1378      a) the sym passed does not participate in
1379      any arithmetic operation
1380      b) There are no function calls
1381      c) all jumps are within the body
1382      d) address of loop control variable not taken
1383      e) if an assignment has a pointer on the
1384      left hand side make sure right does not have
1385      loop control variable */
1386
1387   /* if we reach the end or a leaf then true */
1388   if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1389     return TRUE;
1390
1391
1392   /* if anything else is "volatile" */
1393   if (IS_VOLATILE (TETYPE (pbody)))
1394     return FALSE;
1395
1396   /* we will walk the body in a pre-order traversal for
1397      efficiency sake */
1398   switch (pbody->opval.op)
1399     {
1400 /*------------------------------------------------------------------*/
1401     case '[':
1402       return isConformingBody (pbody->right, sym, body);
1403
1404 /*------------------------------------------------------------------*/
1405     case PTR_OP:
1406     case '.':
1407       return TRUE;
1408
1409 /*------------------------------------------------------------------*/
1410     case INC_OP:                /* incerement operator unary so left only */
1411     case DEC_OP:
1412
1413       /* sure we are not sym is not modified */
1414       if (pbody->left &&
1415           IS_AST_SYM_VALUE (pbody->left) &&
1416           isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1417         return FALSE;
1418
1419       if (pbody->right &&
1420           IS_AST_SYM_VALUE (pbody->right) &&
1421           isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1422         return FALSE;
1423
1424       return TRUE;
1425
1426 /*------------------------------------------------------------------*/
1427
1428     case '*':                   /* can be unary  : if right is null then unary operation */
1429     case '+':
1430     case '-':
1431     case '&':
1432
1433       /* if right is NULL then unary operation  */
1434 /*------------------------------------------------------------------*/
1435 /*----------------------------*/
1436       /*  address of                */
1437 /*----------------------------*/
1438       if (!pbody->right)
1439         {
1440           if (IS_AST_SYM_VALUE (pbody->left) &&
1441               isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1442             return FALSE;
1443           else
1444             return isConformingBody (pbody->left, sym, body);
1445         }
1446       else
1447         {
1448           if (astHasSymbol (pbody->left, sym) ||
1449               astHasSymbol (pbody->right, sym))
1450             return FALSE;
1451         }
1452
1453
1454 /*------------------------------------------------------------------*/
1455     case '|':
1456     case '^':
1457     case '/':
1458     case '%':
1459     case LEFT_OP:
1460     case RIGHT_OP:
1461
1462       if (IS_AST_SYM_VALUE (pbody->left) &&
1463           isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1464         return FALSE;
1465
1466       if (IS_AST_SYM_VALUE (pbody->right) &&
1467           isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1468         return FALSE;
1469
1470       return isConformingBody (pbody->left, sym, body) &&
1471         isConformingBody (pbody->right, sym, body);
1472
1473     case '~':
1474     case '!':
1475     case RRC:
1476     case RLC:
1477     case GETHBIT:
1478       if (IS_AST_SYM_VALUE (pbody->left) &&
1479           isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1480         return FALSE;
1481       return isConformingBody (pbody->left, sym, body);
1482
1483 /*------------------------------------------------------------------*/
1484
1485     case AND_OP:
1486     case OR_OP:
1487     case '>':
1488     case '<':
1489     case LE_OP:
1490     case GE_OP:
1491     case EQ_OP:
1492     case NE_OP:
1493     case '?':
1494     case ':':
1495     case SIZEOF:                /* evaluate wihout code generation */
1496
1497       return isConformingBody (pbody->left, sym, body) &&
1498         isConformingBody (pbody->right, sym, body);
1499
1500 /*------------------------------------------------------------------*/
1501     case '=':
1502
1503       /* if left has a pointer & right has loop
1504          control variable then we cannot */
1505       if (astHasPointer (pbody->left) &&
1506           astHasSymbol (pbody->right, sym))
1507         return FALSE;
1508       if (astHasVolatile (pbody->left))
1509         return FALSE;
1510
1511       if (IS_AST_SYM_VALUE (pbody->left) &&
1512           isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1513         return FALSE;
1514
1515       if (astHasVolatile (pbody->left))
1516         return FALSE;
1517
1518       return isConformingBody (pbody->left, sym, body) &&
1519         isConformingBody (pbody->right, sym, body);
1520
1521     case MUL_ASSIGN:
1522     case DIV_ASSIGN:
1523     case AND_ASSIGN:
1524     case OR_ASSIGN:
1525     case XOR_ASSIGN:
1526     case RIGHT_ASSIGN:
1527     case LEFT_ASSIGN:
1528     case SUB_ASSIGN:
1529     case ADD_ASSIGN:
1530       assert ("Parser should not have generated this\n");
1531
1532 /*------------------------------------------------------------------*/
1533 /*----------------------------*/
1534       /*      comma operator        */
1535 /*----------------------------*/
1536     case ',':
1537       return isConformingBody (pbody->left, sym, body) &&
1538         isConformingBody (pbody->right, sym, body);
1539
1540 /*------------------------------------------------------------------*/
1541 /*----------------------------*/
1542       /*       function call        */
1543 /*----------------------------*/
1544     case CALL:
1545       return FALSE;
1546
1547 /*------------------------------------------------------------------*/
1548 /*----------------------------*/
1549       /*     return statement       */
1550 /*----------------------------*/
1551     case RETURN:
1552       return FALSE;
1553
1554     case GOTO:
1555       if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1556         return TRUE;
1557       else
1558         return FALSE;
1559     case SWITCH:
1560       if (astHasSymbol (pbody->left, sym))
1561         return FALSE;
1562
1563     default:
1564       break;
1565     }
1566
1567   return isConformingBody (pbody->left, sym, body) &&
1568     isConformingBody (pbody->right, sym, body);
1569
1570
1571
1572 }
1573
1574 /*-----------------------------------------------------------------*/
1575 /* isLoopReversible - takes a for loop as input && returns true    */
1576 /* if the for loop is reversible. If yes will set the value of     */
1577 /* the loop control var & init value & termination value           */
1578 /*-----------------------------------------------------------------*/
1579 bool 
1580 isLoopReversible (ast * loop, symbol ** loopCntrl,
1581                   ast ** init, ast ** end)
1582 {
1583   /* if option says don't do it then don't */
1584   if (optimize.noLoopReverse)
1585     return 0;
1586   /* there are several tests to determine this */
1587
1588   /* for loop has to be of the form
1589      for ( <sym> = <const1> ;
1590      [<sym> < <const2>]  ;
1591      [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1592      forBody */
1593   if (!isLoopCountable (AST_FOR (loop, initExpr),
1594                         AST_FOR (loop, condExpr),
1595                         AST_FOR (loop, loopExpr),
1596                         loopCntrl, init, end))
1597     return 0;
1598
1599   /* now do some serious checking on the body of the loop
1600    */
1601
1602   return isConformingBody (loop->left, *loopCntrl, loop->left);
1603
1604 }
1605
1606 /*-----------------------------------------------------------------*/
1607 /* replLoopSym - replace the loop sym by loop sym -1               */
1608 /*-----------------------------------------------------------------*/
1609 static void 
1610 replLoopSym (ast * body, symbol * sym)
1611 {
1612   /* reached end */
1613   if (!body || IS_AST_LINK (body))
1614     return;
1615
1616   if (IS_AST_SYM_VALUE (body))
1617     {
1618
1619       if (isSymbolEqual (AST_SYMBOL (body), sym))
1620         {
1621
1622           body->type = EX_OP;
1623           body->opval.op = '-';
1624           body->left = newAst_VALUE (symbolVal (sym));
1625           body->right = newAst_VALUE (constVal ("1"));
1626
1627         }
1628
1629       return;
1630
1631     }
1632
1633   replLoopSym (body->left, sym);
1634   replLoopSym (body->right, sym);
1635
1636 }
1637
1638 /*-----------------------------------------------------------------*/
1639 /* reverseLoop - do the actual loop reversal                       */
1640 /*-----------------------------------------------------------------*/
1641 ast *
1642 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1643 {
1644   ast *rloop;
1645
1646   /* create the following tree
1647      <sym> = loopCount ;
1648      for_continue:
1649      forbody
1650      <sym> -= 1;
1651      if (sym) goto for_continue ;
1652      <sym> = end */
1653
1654   /* put it together piece by piece */
1655   rloop = newNode (NULLOP,
1656                    createIf (newAst_VALUE (symbolVal (sym)),
1657                              newNode (GOTO,
1658                    newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1659                                       NULL), NULL),
1660                    newNode ('=',
1661                             newAst_VALUE (symbolVal (sym)),
1662                             end));
1663
1664   replLoopSym (loop->left, sym);
1665
1666   rloop = newNode (NULLOP,
1667                    newNode ('=',
1668                             newAst_VALUE (symbolVal (sym)),
1669                             newNode ('-', end, init)),
1670                    createLabel (AST_FOR (loop, continueLabel),
1671                                 newNode (NULLOP,
1672                                          loop->left,
1673                                          newNode (NULLOP,
1674                                                   newNode (SUB_ASSIGN,
1675                                              newAst_VALUE (symbolVal (sym)),
1676                                              newAst_VALUE (constVal ("1"))),
1677                                                   rloop))));
1678
1679   return decorateType (rloop);
1680
1681 }
1682
1683 #define DEMAND_INTEGER_PROMOTION
1684
1685 #ifdef DEMAND_INTEGER_PROMOTION
1686
1687 /*-----------------------------------------------------------------*/
1688 /* walk a tree looking for the leaves. Add a typecast to the given */
1689 /* type to each value leaf node.           */
1690 /*-----------------------------------------------------------------*/
1691 void 
1692 pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
1693 {
1694   if (!node || IS_CALLOP(node))
1695     {
1696       /* WTF? We should never get here. */
1697       return;
1698     }
1699
1700   if (!node->left && !node->right)
1701     {
1702       /* We're at a leaf; if it's a value, apply the typecast */
1703       if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
1704         {
1705           *parentPtr = decorateType (newNode (CAST,
1706                                          newAst_LINK (copyLinkChain (type)),
1707                                               node));
1708         }
1709     }
1710   else
1711     {
1712       if (node->left)
1713         {
1714           pushTypeCastToLeaves (type, node->left, &(node->left));
1715         }
1716       if (node->right)
1717         {
1718           pushTypeCastToLeaves (type, node->right, &(node->right));
1719         }
1720     }
1721 }
1722
1723 #endif
1724
1725 /*-----------------------------------------------------------------*/
1726 /* Given an assignment operation in a tree, determine if the LHS   */
1727 /* (the result) has a different (integer) type than the RHS.     */
1728 /* If so, walk the RHS and add a typecast to the type of the LHS   */
1729 /* to all leaf nodes.              */
1730 /*-----------------------------------------------------------------*/
1731 void 
1732 propAsgType (ast * tree)
1733 {
1734 #ifdef DEMAND_INTEGER_PROMOTION
1735   if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
1736     {
1737       /* Nothing to do here... */
1738       return;
1739     }
1740
1741   if (getSize (LTYPE (tree)) > getSize (RTYPE (tree)))
1742     {
1743       pushTypeCastToLeaves (LTYPE (tree), tree->right, &(tree->right));
1744     }
1745 #else
1746   (void) tree;
1747 #endif
1748 }
1749
1750 /*-----------------------------------------------------------------*/
1751 /* decorateType - compute type for this tree also does type cheking */
1752 /*          this is done bottom up, since type have to flow upwards */
1753 /*          it also does constant folding, and paramater checking  */
1754 /*-----------------------------------------------------------------*/
1755 ast *
1756 decorateType (ast * tree)
1757 {
1758   int parmNumber;
1759   sym_link *p;
1760
1761   if (!tree)
1762     return tree;
1763
1764   /* if already has type then do nothing */
1765   if (tree->decorated)
1766     return tree;
1767
1768   tree->decorated = 1;
1769
1770   /* print the line          */
1771   /* if not block & function */
1772   if (tree->type == EX_OP &&
1773       (tree->opval.op != FUNCTION &&
1774        tree->opval.op != BLOCK &&
1775        tree->opval.op != NULLOP))
1776     {
1777       filename = tree->filename;
1778       lineno = tree->lineno;
1779     }
1780
1781   /* if any child is an error | this one is an error do nothing */
1782   if (tree->isError ||
1783       (tree->left && tree->left->isError) ||
1784       (tree->right && tree->right->isError))
1785     return tree;
1786
1787 /*------------------------------------------------------------------*/
1788 /*----------------------------*/
1789   /*   leaf has been reached    */
1790 /*----------------------------*/
1791   /* if this is of type value */
1792   /* just get the type        */
1793   if (tree->type == EX_VALUE)
1794     {
1795
1796       if (IS_LITERAL (tree->opval.val->etype))
1797         {
1798
1799           /* if this is a character array then declare it */
1800           if (IS_ARRAY (tree->opval.val->type))
1801             tree->opval.val = stringToSymbol (tree->opval.val);
1802
1803           /* otherwise just copy the type information */
1804           COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1805           if (funcInChain (tree->opval.val->type))
1806             {
1807               tree->hasVargs = tree->opval.val->sym->hasVargs;
1808               tree->args = copyValueChain (tree->opval.val->sym->args);
1809             }
1810           return tree;
1811         }
1812
1813       if (tree->opval.val->sym)
1814         {
1815           /* if the undefined flag is set then give error message */
1816           if (tree->opval.val->sym->undefined)
1817             {
1818               werror (E_ID_UNDEF, tree->opval.val->sym->name);
1819               /* assume int */
1820               TTYPE (tree) = TETYPE (tree) =
1821                 tree->opval.val->type = tree->opval.val->sym->type =
1822                 tree->opval.val->etype = tree->opval.val->sym->etype =
1823                 copyLinkChain (INTTYPE);
1824             }
1825           else
1826             {
1827
1828               /* if impilicit i.e. struct/union member then no type */
1829               if (tree->opval.val->sym->implicit)
1830                 TTYPE (tree) = TETYPE (tree) = NULL;
1831
1832               else
1833                 {
1834
1835                   /* else copy the type */
1836                   COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1837
1838                   /* and mark it as referenced */
1839                   tree->opval.val->sym->isref = 1;
1840                   /* if this is of type function or function pointer */
1841                   if (funcInChain (tree->opval.val->type))
1842                     {
1843                       tree->hasVargs = tree->opval.val->sym->hasVargs;
1844                       tree->args = copyValueChain (tree->opval.val->sym->args);
1845
1846                     }
1847                 }
1848             }
1849         }
1850
1851       return tree;
1852     }
1853
1854   /* if type link for the case of cast */
1855   if (tree->type == EX_LINK)
1856     {
1857       COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1858       return tree;
1859     }
1860
1861   {
1862     ast *dtl, *dtr;
1863
1864     dtl = decorateType (tree->left);
1865     dtr = decorateType (tree->right);
1866
1867     /* this is to take care of situations
1868        when the tree gets rewritten */
1869     if (dtl != tree->left)
1870       tree->left = dtl;
1871     if (dtr != tree->right)
1872       tree->right = dtr;
1873   }
1874
1875   /* depending on type of operator do */
1876
1877   switch (tree->opval.op)
1878     {
1879 /*------------------------------------------------------------------*/
1880 /*----------------------------*/
1881       /*        array node          */
1882 /*----------------------------*/
1883     case '[':
1884
1885       /* determine which is the array & which the index */
1886       if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1887         {
1888
1889           ast *tempTree = tree->left;
1890           tree->left = tree->right;
1891           tree->right = tempTree;
1892         }
1893
1894       /* first check if this is a array or a pointer */
1895       if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1896         {
1897           werror (E_NEED_ARRAY_PTR, "[]");
1898           goto errorTreeReturn;
1899         }
1900
1901       /* check if the type of the idx */
1902       if (!IS_INTEGRAL (RTYPE (tree)))
1903         {
1904           werror (E_IDX_NOT_INT);
1905           goto errorTreeReturn;
1906         }
1907
1908       /* if the left is an rvalue then error */
1909       if (LRVAL (tree))
1910         {
1911           werror (E_LVALUE_REQUIRED, "array access");
1912           goto errorTreeReturn;
1913         }
1914       RRVAL (tree) = 1;
1915       COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1916       if (IS_PTR(LTYPE(tree))) {
1917               SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1918       }
1919       return tree;
1920
1921 /*------------------------------------------------------------------*/
1922 /*----------------------------*/
1923       /*      struct/union          */
1924 /*----------------------------*/
1925     case '.':
1926       /* if this is not a structure */
1927       if (!IS_STRUCT (LTYPE (tree)))
1928         {
1929           werror (E_STRUCT_UNION, ".");
1930           goto errorTreeReturn;
1931         }
1932       TTYPE (tree) = structElemType (LTYPE (tree),
1933                                      (tree->right->type == EX_VALUE ?
1934                                tree->right->opval.val : NULL), &tree->args);
1935       TETYPE (tree) = getSpec (TTYPE (tree));
1936       return tree;
1937
1938 /*------------------------------------------------------------------*/
1939 /*----------------------------*/
1940       /*    struct/union pointer    */
1941 /*----------------------------*/
1942     case PTR_OP:
1943       /* if not pointer to a structure */
1944       if (!IS_PTR (LTYPE (tree)))
1945         {
1946           werror (E_PTR_REQD);
1947           goto errorTreeReturn;
1948         }
1949
1950       if (!IS_STRUCT (LTYPE (tree)->next))
1951         {
1952           werror (E_STRUCT_UNION, "->");
1953           goto errorTreeReturn;
1954         }
1955
1956       TTYPE (tree) = structElemType (LTYPE (tree)->next,
1957                                      (tree->right->type == EX_VALUE ?
1958                                tree->right->opval.val : NULL), &tree->args);
1959       TETYPE (tree) = getSpec (TTYPE (tree));
1960       return tree;
1961
1962 /*------------------------------------------------------------------*/
1963 /*----------------------------*/
1964       /*  ++/-- operation           */
1965 /*----------------------------*/
1966     case INC_OP:                /* incerement operator unary so left only */
1967     case DEC_OP:
1968       {
1969         sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
1970         COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
1971         if (!tree->initMode && IS_CONSTANT (TETYPE (tree)))
1972           werror (E_CODE_WRITE, "++/--");
1973
1974         if (tree->right)
1975           RLVAL (tree) = 1;
1976         else
1977           LLVAL (tree) = 1;
1978         return tree;
1979       }
1980
1981 /*------------------------------------------------------------------*/
1982 /*----------------------------*/
1983       /*  bitwise and               */
1984 /*----------------------------*/
1985     case '&':                   /* can be unary   */
1986       /* if right is NULL then unary operation  */
1987       if (tree->right)          /* not an unary operation */
1988         {
1989
1990           if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
1991             {
1992               werror (E_BITWISE_OP);
1993               werror (E_CONTINUE, "left & right types are ");
1994               printTypeChain (LTYPE (tree), stderr);
1995               fprintf (stderr, ",");
1996               printTypeChain (RTYPE (tree), stderr);
1997               fprintf (stderr, "\n");
1998               goto errorTreeReturn;
1999             }
2000
2001           /* if they are both literal */
2002           if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2003             {
2004               tree->type = EX_VALUE;
2005               tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2006                                           valFromType (RETYPE (tree)), '&');
2007
2008               tree->right = tree->left = NULL;
2009               TETYPE (tree) = tree->opval.val->etype;
2010               TTYPE (tree) = tree->opval.val->type;
2011               return tree;
2012             }
2013
2014           /* see if this is a GETHBIT operation if yes
2015              then return that */
2016           {
2017             ast *otree = optimizeGetHbit (tree);
2018
2019             if (otree != tree)
2020               return decorateType (otree);
2021           }
2022
2023           /* if right or left is literal then result of that type */
2024           if (IS_LITERAL (RTYPE (tree)))
2025             {
2026
2027               TTYPE (tree) = copyLinkChain (RTYPE (tree));
2028               TETYPE (tree) = getSpec (TTYPE (tree));
2029               SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2030             }
2031           else
2032             {
2033               if (IS_LITERAL (LTYPE (tree)))
2034                 {
2035                   TTYPE (tree) = copyLinkChain (LTYPE (tree));
2036                   TETYPE (tree) = getSpec (TTYPE (tree));
2037                   SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2038
2039                 }
2040               else
2041                 {
2042                   TTYPE (tree) =
2043                     computeType (LTYPE (tree), RTYPE (tree));
2044                   TETYPE (tree) = getSpec (TTYPE (tree));
2045                 }
2046             }
2047           LRVAL (tree) = RRVAL (tree) = 1;
2048           return tree;
2049         }
2050
2051 /*------------------------------------------------------------------*/
2052 /*----------------------------*/
2053       /*  address of                */
2054 /*----------------------------*/
2055       p = newLink ();
2056       p->class = DECLARATOR;
2057       /* if bit field then error */
2058       if (IS_BITVAR (tree->left->etype))
2059         {
2060           werror (E_ILLEGAL_ADDR, "addrress of bit variable");
2061           goto errorTreeReturn;
2062         }
2063
2064       if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2065         {
2066           werror (E_ILLEGAL_ADDR, "address of register variable");
2067           goto errorTreeReturn;
2068         }
2069
2070       if (IS_FUNC (LTYPE (tree)))
2071         {
2072           werror (E_ILLEGAL_ADDR, "address of function");
2073           goto errorTreeReturn;
2074         }
2075
2076       if (LRVAL (tree))
2077         {
2078           werror (E_LVALUE_REQUIRED, "address of");
2079           goto errorTreeReturn;
2080         }
2081       if (SPEC_SCLS (tree->left->etype) == S_CODE)
2082         {
2083           DCL_TYPE (p) = CPOINTER;
2084           DCL_PTR_CONST (p) = port->mem.code_ro;
2085         }
2086       else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2087         DCL_TYPE (p) = FPOINTER;
2088       else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2089         DCL_TYPE (p) = PPOINTER;
2090       else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2091         DCL_TYPE (p) = IPOINTER;
2092       else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2093         DCL_TYPE (p) = EEPPOINTER;
2094       else
2095         DCL_TYPE (p) = POINTER;
2096
2097       if (IS_AST_SYM_VALUE (tree->left))
2098         {
2099           AST_SYMBOL (tree->left)->addrtaken = 1;
2100           AST_SYMBOL (tree->left)->allocreq = 1;
2101         }
2102
2103       p->next = LTYPE (tree);
2104       TTYPE (tree) = p;
2105       TETYPE (tree) = getSpec (TTYPE (tree));
2106       DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2107       DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2108       LLVAL (tree) = 1;
2109       TLVAL (tree) = 1;
2110       return tree;
2111
2112 /*------------------------------------------------------------------*/
2113 /*----------------------------*/
2114       /*  bitwise or                */
2115 /*----------------------------*/
2116     case '|':
2117       /* if the rewrite succeeds then don't go any furthur */
2118       {
2119         ast *wtree = optimizeRRCRLC (tree);
2120         if (wtree != tree)
2121           return decorateType (wtree);
2122       }
2123 /*------------------------------------------------------------------*/
2124 /*----------------------------*/
2125       /*  bitwise xor               */
2126 /*----------------------------*/
2127     case '^':
2128       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2129         {
2130           werror (E_BITWISE_OP);
2131           werror (E_CONTINUE, "left & right types are ");
2132           printTypeChain (LTYPE (tree), stderr);
2133           fprintf (stderr, ",");
2134           printTypeChain (RTYPE (tree), stderr);
2135           fprintf (stderr, "\n");
2136           goto errorTreeReturn;
2137         }
2138
2139       /* if they are both literal then */
2140       /* rewrite the tree */
2141       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2142         {
2143           tree->type = EX_VALUE;
2144           tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2145                                         valFromType (RETYPE (tree)),
2146                                         tree->opval.op);
2147           tree->right = tree->left = NULL;
2148           TETYPE (tree) = tree->opval.val->etype;
2149           TTYPE (tree) = tree->opval.val->type;
2150           return tree;
2151         }
2152       LRVAL (tree) = RRVAL (tree) = 1;
2153       TETYPE (tree) = getSpec (TTYPE (tree) =
2154                                computeType (LTYPE (tree),
2155                                             RTYPE (tree)));
2156
2157 /*------------------------------------------------------------------*/
2158 /*----------------------------*/
2159       /*  division                  */
2160 /*----------------------------*/
2161     case '/':
2162       if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2163         {
2164           werror (E_INVALID_OP, "divide");
2165           goto errorTreeReturn;
2166         }
2167       /* if they are both literal then */
2168       /* rewrite the tree */
2169       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2170         {
2171           tree->type = EX_VALUE;
2172           tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2173                                     valFromType (RETYPE (tree)));
2174           tree->right = tree->left = NULL;
2175           TETYPE (tree) = getSpec (TTYPE (tree) =
2176                                    tree->opval.val->type);
2177           return tree;
2178         }
2179       LRVAL (tree) = RRVAL (tree) = 1;
2180       TETYPE (tree) = getSpec (TTYPE (tree) =
2181                                computeType (LTYPE (tree),
2182                                             RTYPE (tree)));
2183       return tree;
2184
2185 /*------------------------------------------------------------------*/
2186 /*----------------------------*/
2187       /*            modulus         */
2188 /*----------------------------*/
2189     case '%':
2190       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2191         {
2192           werror (E_BITWISE_OP);
2193           werror (E_CONTINUE, "left & right types are ");
2194           printTypeChain (LTYPE (tree), stderr);
2195           fprintf (stderr, ",");
2196           printTypeChain (RTYPE (tree), stderr);
2197           fprintf (stderr, "\n");
2198           goto errorTreeReturn;
2199         }
2200       /* if they are both literal then */
2201       /* rewrite the tree */
2202       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2203         {
2204           tree->type = EX_VALUE;
2205           tree->opval.val = valMod (valFromType (LETYPE (tree)),
2206                                     valFromType (RETYPE (tree)));
2207           tree->right = tree->left = NULL;
2208           TETYPE (tree) = getSpec (TTYPE (tree) =
2209                                    tree->opval.val->type);
2210           return tree;
2211         }
2212       LRVAL (tree) = RRVAL (tree) = 1;
2213       TETYPE (tree) = getSpec (TTYPE (tree) =
2214                                computeType (LTYPE (tree),
2215                                             RTYPE (tree)));
2216       return tree;
2217
2218 /*------------------------------------------------------------------*/
2219 /*----------------------------*/
2220 /*  address dereference       */
2221 /*----------------------------*/
2222     case '*':                   /* can be unary  : if right is null then unary operation */
2223       if (!tree->right)
2224         {
2225           if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2226             {
2227               werror (E_PTR_REQD);
2228               goto errorTreeReturn;
2229             }
2230
2231           if (LRVAL (tree))
2232             {
2233               werror (E_LVALUE_REQUIRED, "pointer deref");
2234               goto errorTreeReturn;
2235             }
2236           TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2237                                         LTYPE (tree)->next : NULL);
2238           TETYPE (tree) = getSpec (TTYPE (tree));
2239           tree->args = tree->left->args;
2240           tree->hasVargs = tree->left->hasVargs;
2241           SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2242           return tree;
2243         }
2244
2245 /*------------------------------------------------------------------*/
2246 /*----------------------------*/
2247       /*      multiplication        */
2248 /*----------------------------*/
2249       if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2250         {
2251           werror (E_INVALID_OP, "multiplication");
2252           goto errorTreeReturn;
2253         }
2254
2255       /* if they are both literal then */
2256       /* rewrite the tree */
2257       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2258         {
2259           tree->type = EX_VALUE;
2260           tree->opval.val = valMult (valFromType (LETYPE (tree)),
2261                                      valFromType (RETYPE (tree)));
2262           tree->right = tree->left = NULL;
2263           TETYPE (tree) = getSpec (TTYPE (tree) =
2264                                    tree->opval.val->type);
2265           return tree;
2266         }
2267
2268       /* if left is a literal exchange left & right */
2269       if (IS_LITERAL (LTYPE (tree)))
2270         {
2271           ast *tTree = tree->left;
2272           tree->left = tree->right;
2273           tree->right = tTree;
2274         }
2275
2276       LRVAL (tree) = RRVAL (tree) = 1;
2277       /* promote result to int if left & right are char / short 
2278          this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2279       if ((IS_CHAR(LETYPE(tree)) || IS_SHORT(LETYPE(tree))) && 
2280            (IS_CHAR(RETYPE(tree)) || IS_SHORT(RETYPE(tree)))) {
2281               TETYPE (tree) = getSpec (TTYPE (tree) =
2282                                        computeType (LTYPE (tree),
2283                                                     RTYPE (tree)));
2284               SPEC_NOUN(TETYPE(tree)) = V_INT;
2285               SPEC_SHORT(TETYPE(tree))=0;
2286       } else {
2287               TETYPE (tree) = getSpec (TTYPE (tree) =
2288                                        computeType (LTYPE (tree),
2289                                                     RTYPE (tree)));
2290       }
2291       return tree;
2292
2293 /*------------------------------------------------------------------*/
2294 /*----------------------------*/
2295       /*    unary '+' operator      */
2296 /*----------------------------*/
2297     case '+':
2298       /* if unary plus */
2299       if (!tree->right)
2300         {
2301           if (!IS_INTEGRAL (LTYPE (tree)))
2302             {
2303               werror (E_UNARY_OP, '+');
2304               goto errorTreeReturn;
2305             }
2306
2307           /* if left is a literal then do it */
2308           if (IS_LITERAL (LTYPE (tree)))
2309             {
2310               tree->type = EX_VALUE;
2311               tree->opval.val = valFromType (LETYPE (tree));
2312               tree->left = NULL;
2313               TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2314               return tree;
2315             }
2316           LRVAL (tree) = 1;
2317           COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2318           return tree;
2319         }
2320
2321 /*------------------------------------------------------------------*/
2322 /*----------------------------*/
2323       /*      addition              */
2324 /*----------------------------*/
2325
2326       /* this is not a unary operation */
2327       /* if both pointers then problem */
2328       if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2329           (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2330         {
2331           werror (E_PTR_PLUS_PTR);
2332           goto errorTreeReturn;
2333         }
2334
2335       if (!IS_ARITHMETIC (LTYPE (tree)) &&
2336           !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2337         {
2338           werror (E_PLUS_INVALID, "+");
2339           goto errorTreeReturn;
2340         }
2341
2342       if (!IS_ARITHMETIC (RTYPE (tree)) &&
2343           !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2344         {
2345           werror (E_PLUS_INVALID, "+");
2346           goto errorTreeReturn;
2347         }
2348       /* if they are both literal then */
2349       /* rewrite the tree */
2350       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2351         {
2352           tree->type = EX_VALUE;
2353           tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2354                                      valFromType (RETYPE (tree)));
2355           tree->right = tree->left = NULL;
2356           TETYPE (tree) = getSpec (TTYPE (tree) =
2357                                    tree->opval.val->type);
2358           return tree;
2359         }
2360
2361       /* if the right is a pointer or left is a literal
2362          xchange left & right */
2363       if (IS_ARRAY (RTYPE (tree)) ||
2364           IS_PTR (RTYPE (tree)) ||
2365           IS_LITERAL (LTYPE (tree)))
2366         {
2367           ast *tTree = tree->left;
2368           tree->left = tree->right;
2369           tree->right = tTree;
2370         }
2371
2372       LRVAL (tree) = RRVAL (tree) = 1;
2373       /* if the left is a pointer */
2374       if (IS_PTR (LTYPE (tree)))
2375         TETYPE (tree) = getSpec (TTYPE (tree) =
2376                                  LTYPE (tree));
2377       else
2378         TETYPE (tree) = getSpec (TTYPE (tree) =
2379                                  computeType (LTYPE (tree),
2380                                               RTYPE (tree)));
2381       return tree;
2382
2383 /*------------------------------------------------------------------*/
2384 /*----------------------------*/
2385       /*      unary '-'             */
2386 /*----------------------------*/
2387     case '-':                   /* can be unary   */
2388       /* if right is null then unary */
2389       if (!tree->right)
2390         {
2391
2392           if (!IS_ARITHMETIC (LTYPE (tree)))
2393             {
2394               werror (E_UNARY_OP, tree->opval.op);
2395               goto errorTreeReturn;
2396             }
2397
2398           /* if left is a literal then do it */
2399           if (IS_LITERAL (LTYPE (tree)))
2400             {
2401               tree->type = EX_VALUE;
2402               tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2403               tree->left = NULL;
2404               TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2405               SPEC_USIGN(TETYPE(tree)) = 0;
2406               return tree;
2407             }
2408           LRVAL (tree) = 1;
2409           TTYPE (tree) = LTYPE (tree);
2410           return tree;
2411         }
2412
2413 /*------------------------------------------------------------------*/
2414 /*----------------------------*/
2415       /*    subtraction             */
2416 /*----------------------------*/
2417
2418       if (!(IS_PTR (LTYPE (tree)) ||
2419             IS_ARRAY (LTYPE (tree)) ||
2420             IS_ARITHMETIC (LTYPE (tree))))
2421         {
2422           werror (E_PLUS_INVALID, "-");
2423           goto errorTreeReturn;
2424         }
2425
2426       if (!(IS_PTR (RTYPE (tree)) ||
2427             IS_ARRAY (RTYPE (tree)) ||
2428             IS_ARITHMETIC (RTYPE (tree))))
2429         {
2430           werror (E_PLUS_INVALID, "-");
2431           goto errorTreeReturn;
2432         }
2433
2434       if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2435           !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2436             IS_INTEGRAL (RTYPE (tree))))
2437         {
2438           werror (E_PLUS_INVALID, "-");
2439           goto errorTreeReturn;
2440         }
2441
2442       /* if they are both literal then */
2443       /* rewrite the tree */
2444       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2445         {
2446           tree->type = EX_VALUE;
2447           tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2448                                       valFromType (RETYPE (tree)));
2449           tree->right = tree->left = NULL;
2450           TETYPE (tree) = getSpec (TTYPE (tree) =
2451                                    tree->opval.val->type);
2452           return tree;
2453         }
2454
2455       /* if the left & right are equal then zero */
2456       if (isAstEqual (tree->left, tree->right))
2457         {
2458           tree->type = EX_VALUE;
2459           tree->left = tree->right = NULL;
2460           tree->opval.val = constVal ("0");
2461           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2462           return tree;
2463         }
2464
2465       /* if both of them are pointers or arrays then */
2466       /* the result is going to be an integer        */
2467       if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2468           (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2469         TETYPE (tree) = TTYPE (tree) = newIntLink ();
2470       else
2471         /* if only the left is a pointer */
2472         /* then result is a pointer      */
2473       if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2474         TETYPE (tree) = getSpec (TTYPE (tree) =
2475                                  LTYPE (tree));
2476       else
2477         TETYPE (tree) = getSpec (TTYPE (tree) =
2478                                  computeType (LTYPE (tree),
2479                                               RTYPE (tree)));
2480       LRVAL (tree) = RRVAL (tree) = 1;
2481       return tree;
2482
2483 /*------------------------------------------------------------------*/
2484 /*----------------------------*/
2485       /*    compliment              */
2486 /*----------------------------*/
2487     case '~':
2488       /* can be only integral type */
2489       if (!IS_INTEGRAL (LTYPE (tree)))
2490         {
2491           werror (E_UNARY_OP, tree->opval.op);
2492           goto errorTreeReturn;
2493         }
2494
2495       /* if left is a literal then do it */
2496       if (IS_LITERAL (LTYPE (tree)))
2497         {
2498           tree->type = EX_VALUE;
2499           tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2500           tree->left = NULL;
2501           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2502           return tree;
2503         }
2504       LRVAL (tree) = 1;
2505       COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2506       return tree;
2507
2508 /*------------------------------------------------------------------*/
2509 /*----------------------------*/
2510       /*           not              */
2511 /*----------------------------*/
2512     case '!':
2513       /* can be pointer */
2514       if (!IS_ARITHMETIC (LTYPE (tree)) &&
2515           !IS_PTR (LTYPE (tree)) &&
2516           !IS_ARRAY (LTYPE (tree)))
2517         {
2518           werror (E_UNARY_OP, tree->opval.op);
2519           goto errorTreeReturn;
2520         }
2521
2522       /* if left is a literal then do it */
2523       if (IS_LITERAL (LTYPE (tree)))
2524         {
2525           tree->type = EX_VALUE;
2526           tree->opval.val = valNot (valFromType (LETYPE (tree)));
2527           tree->left = NULL;
2528           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2529           return tree;
2530         }
2531       LRVAL (tree) = 1;
2532       TTYPE (tree) = TETYPE (tree) = newCharLink ();
2533       return tree;
2534
2535 /*------------------------------------------------------------------*/
2536 /*----------------------------*/
2537       /*           shift            */
2538 /*----------------------------*/
2539     case RRC:
2540     case RLC:
2541       TTYPE (tree) = LTYPE (tree);
2542       TETYPE (tree) = LETYPE (tree);
2543       return tree;
2544
2545     case GETHBIT:
2546       TTYPE (tree) = TETYPE (tree) = newCharLink ();
2547       return tree;
2548
2549     case LEFT_OP:
2550     case RIGHT_OP:
2551       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2552         {
2553           werror (E_SHIFT_OP_INVALID);
2554           werror (E_CONTINUE, "left & right types are ");
2555           printTypeChain (LTYPE (tree), stderr);
2556           fprintf (stderr, ",");
2557           printTypeChain (RTYPE (tree), stderr);
2558           fprintf (stderr, "\n");
2559           goto errorTreeReturn;
2560         }
2561
2562       /* if they are both literal then */
2563       /* rewrite the tree */
2564       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2565         {
2566           tree->type = EX_VALUE;
2567           tree->opval.val = valShift (valFromType (LETYPE (tree)),
2568                                       valFromType (RETYPE (tree)),
2569                                       (tree->opval.op == LEFT_OP ? 1 : 0));
2570           tree->right = tree->left = NULL;
2571           TETYPE (tree) = getSpec (TTYPE (tree) =
2572                                    tree->opval.val->type);
2573           return tree;
2574         }
2575       /* if only the right side is a literal & we are
2576          shifting more than size of the left operand then zero */
2577       if (IS_LITERAL (RTYPE (tree)) &&
2578           ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2579           (getSize (LTYPE (tree)) * 8))
2580         {
2581           werror (W_SHIFT_CHANGED,
2582                   (tree->opval.op == LEFT_OP ? "left" : "right"));
2583           tree->type = EX_VALUE;
2584           tree->left = tree->right = NULL;
2585           tree->opval.val = constVal ("0");
2586           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2587           return tree;
2588         }
2589       LRVAL (tree) = RRVAL (tree) = 1;
2590       if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2591         {
2592           COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2593         }
2594       else
2595         {
2596           COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2597         }
2598       return tree;
2599
2600 /*------------------------------------------------------------------*/
2601 /*----------------------------*/
2602       /*         casting            */
2603 /*----------------------------*/
2604     case CAST:                  /* change the type   */
2605       /* cannot cast to an aggregate type */
2606       if (IS_AGGREGATE (LTYPE (tree)))
2607         {
2608           werror (E_CAST_ILLEGAL);
2609           goto errorTreeReturn;
2610         }
2611
2612       /* if the right is a literal replace the tree */
2613       if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree)))
2614         {
2615           tree->type = EX_VALUE;
2616           tree->opval.val =
2617             valCastLiteral (LTYPE (tree),
2618                             floatFromVal (valFromType (RETYPE (tree))));
2619           tree->left = NULL;
2620           tree->right = NULL;
2621           TTYPE (tree) = tree->opval.val->type;
2622           tree->values.literalFromCast = 1;
2623         }
2624       else
2625         {
2626           TTYPE (tree) = LTYPE (tree);
2627           LRVAL (tree) = 1;
2628         }
2629
2630       TETYPE (tree) = getSpec (TTYPE (tree));
2631
2632       return tree;
2633
2634 /*------------------------------------------------------------------*/
2635 /*----------------------------*/
2636       /*       logical &&, ||       */
2637 /*----------------------------*/
2638     case AND_OP:
2639     case OR_OP:
2640       /* each must me arithmetic type or be a pointer */
2641       if (!IS_PTR (LTYPE (tree)) &&
2642           !IS_ARRAY (LTYPE (tree)) &&
2643           !IS_INTEGRAL (LTYPE (tree)))
2644         {
2645           werror (E_COMPARE_OP);
2646           goto errorTreeReturn;
2647         }
2648
2649       if (!IS_PTR (RTYPE (tree)) &&
2650           !IS_ARRAY (RTYPE (tree)) &&
2651           !IS_INTEGRAL (RTYPE (tree)))
2652         {
2653           werror (E_COMPARE_OP);
2654           goto errorTreeReturn;
2655         }
2656       /* if they are both literal then */
2657       /* rewrite the tree */
2658       if (IS_LITERAL (RTYPE (tree)) &&
2659           IS_LITERAL (LTYPE (tree)))
2660         {
2661           tree->type = EX_VALUE;
2662           tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2663                                            valFromType (RETYPE (tree)),
2664                                            tree->opval.op);
2665           tree->right = tree->left = NULL;
2666           TETYPE (tree) = getSpec (TTYPE (tree) =
2667                                    tree->opval.val->type);
2668           return tree;
2669         }
2670       LRVAL (tree) = RRVAL (tree) = 1;
2671       TTYPE (tree) = TETYPE (tree) = newCharLink ();
2672       return tree;
2673
2674 /*------------------------------------------------------------------*/
2675 /*----------------------------*/
2676       /*     comparison operators   */
2677 /*----------------------------*/
2678     case '>':
2679     case '<':
2680     case LE_OP:
2681     case GE_OP:
2682     case EQ_OP:
2683     case NE_OP:
2684       {
2685         ast *lt = optimizeCompare (tree);
2686
2687         if (tree != lt)
2688           return lt;
2689       }
2690
2691       /* if they are pointers they must be castable */
2692       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2693         {
2694           if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2695             {
2696               werror (E_COMPARE_OP);
2697               fprintf (stderr, "comparing type ");
2698               printTypeChain (LTYPE (tree), stderr);
2699               fprintf (stderr, "to type ");
2700               printTypeChain (RTYPE (tree), stderr);
2701               fprintf (stderr, "\n");
2702               goto errorTreeReturn;
2703             }
2704         }
2705       /* else they should be promotable to one another */
2706       else
2707         {
2708           if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2709                 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2710
2711             if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2712               {
2713                 werror (E_COMPARE_OP);
2714                 fprintf (stderr, "comparing type ");
2715                 printTypeChain (LTYPE (tree), stderr);
2716                 fprintf (stderr, "to type ");
2717                 printTypeChain (RTYPE (tree), stderr);
2718                 fprintf (stderr, "\n");
2719                 goto errorTreeReturn;
2720               }
2721         }
2722
2723       /* if they are both literal then */
2724       /* rewrite the tree */
2725       if (IS_LITERAL (RTYPE (tree)) &&
2726           IS_LITERAL (LTYPE (tree)))
2727         {
2728           tree->type = EX_VALUE;
2729           tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2730                                         valFromType (RETYPE (tree)),
2731                                         tree->opval.op);
2732           tree->right = tree->left = NULL;
2733           TETYPE (tree) = getSpec (TTYPE (tree) =
2734                                    tree->opval.val->type);
2735           return tree;
2736         }
2737       LRVAL (tree) = RRVAL (tree) = 1;
2738       TTYPE (tree) = TETYPE (tree) = newCharLink ();
2739       return tree;
2740
2741 /*------------------------------------------------------------------*/
2742 /*----------------------------*/
2743       /*             sizeof         */
2744 /*----------------------------*/
2745     case SIZEOF:                /* evaluate wihout code generation */
2746       /* change the type to a integer */
2747       tree->type = EX_VALUE;
2748       sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2749       tree->opval.val = constVal (buffer);
2750       tree->right = tree->left = NULL;
2751       TETYPE (tree) = getSpec (TTYPE (tree) =
2752                                tree->opval.val->type);
2753       return tree;
2754
2755 /*------------------------------------------------------------------*/
2756 /*----------------------------*/
2757       /* conditional operator  '?'  */
2758 /*----------------------------*/
2759     case '?':
2760       /* the type is one on the left */
2761       TTYPE (tree) = LTYPE (tree);
2762       TETYPE (tree) = getSpec (TTYPE (tree));
2763       return tree;
2764
2765     case ':':
2766       /* if they don't match we have a problem */
2767       if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2768         {
2769           werror (E_TYPE_MISMATCH, "conditional operator", " ");
2770           goto errorTreeReturn;
2771         }
2772
2773       TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2774       TETYPE (tree) = getSpec (TTYPE (tree));
2775       return tree;
2776
2777
2778 /*------------------------------------------------------------------*/
2779 /*----------------------------*/
2780       /*    assignment operators    */
2781 /*----------------------------*/
2782     case MUL_ASSIGN:
2783     case DIV_ASSIGN:
2784       /* for these it must be both must be integral */
2785       if (!IS_ARITHMETIC (LTYPE (tree)) ||
2786           !IS_ARITHMETIC (RTYPE (tree)))
2787         {
2788           werror (E_OPS_INTEGRAL);
2789           goto errorTreeReturn;
2790         }
2791       RRVAL (tree) = 1;
2792       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2793
2794       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2795         werror (E_CODE_WRITE, " ");
2796
2797       if (LRVAL (tree))
2798         {
2799           werror (E_LVALUE_REQUIRED, "*= or /=");
2800           goto errorTreeReturn;
2801         }
2802       LLVAL (tree) = 1;
2803
2804       propAsgType (tree);
2805
2806       return tree;
2807
2808     case AND_ASSIGN:
2809     case OR_ASSIGN:
2810     case XOR_ASSIGN:
2811     case RIGHT_ASSIGN:
2812     case LEFT_ASSIGN:
2813       /* for these it must be both must be integral */
2814       if (!IS_INTEGRAL (LTYPE (tree)) ||
2815           !IS_INTEGRAL (RTYPE (tree)))
2816         {
2817           werror (E_OPS_INTEGRAL);
2818           goto errorTreeReturn;
2819         }
2820       RRVAL (tree) = 1;
2821       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2822
2823       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2824         werror (E_CODE_WRITE, " ");
2825
2826       if (LRVAL (tree))
2827         {
2828           werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2829           goto errorTreeReturn;
2830         }
2831       LLVAL (tree) = 1;
2832
2833       propAsgType (tree);
2834
2835       return tree;
2836
2837 /*------------------------------------------------------------------*/
2838 /*----------------------------*/
2839       /*    -= operator             */
2840 /*----------------------------*/
2841     case SUB_ASSIGN:
2842       if (!(IS_PTR (LTYPE (tree)) ||
2843             IS_ARITHMETIC (LTYPE (tree))))
2844         {
2845           werror (E_PLUS_INVALID, "-=");
2846           goto errorTreeReturn;
2847         }
2848
2849       if (!(IS_PTR (RTYPE (tree)) ||
2850             IS_ARITHMETIC (RTYPE (tree))))
2851         {
2852           werror (E_PLUS_INVALID, "-=");
2853           goto errorTreeReturn;
2854         }
2855       RRVAL (tree) = 1;
2856       TETYPE (tree) = getSpec (TTYPE (tree) =
2857                                computeType (LTYPE (tree),
2858                                             RTYPE (tree)));
2859
2860       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2861         werror (E_CODE_WRITE, " ");
2862
2863       if (LRVAL (tree))
2864         {
2865           werror (E_LVALUE_REQUIRED, "-=");
2866           goto errorTreeReturn;
2867         }
2868       LLVAL (tree) = 1;
2869
2870       propAsgType (tree);
2871
2872       return tree;
2873
2874 /*------------------------------------------------------------------*/
2875 /*----------------------------*/
2876       /*          += operator       */
2877 /*----------------------------*/
2878     case ADD_ASSIGN:
2879       /* this is not a unary operation */
2880       /* if both pointers then problem */
2881       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2882         {
2883           werror (E_PTR_PLUS_PTR);
2884           goto errorTreeReturn;
2885         }
2886
2887       if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
2888         {
2889           werror (E_PLUS_INVALID, "+=");
2890           goto errorTreeReturn;
2891         }
2892
2893       if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
2894         {
2895           werror (E_PLUS_INVALID, "+=");
2896           goto errorTreeReturn;
2897         }
2898       RRVAL (tree) = 1;
2899       TETYPE (tree) = getSpec (TTYPE (tree) =
2900                                computeType (LTYPE (tree),
2901                                             RTYPE (tree)));
2902
2903       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2904         werror (E_CODE_WRITE, " ");
2905
2906       if (LRVAL (tree))
2907         {
2908           werror (E_LVALUE_REQUIRED, "+=");
2909           goto errorTreeReturn;
2910         }
2911
2912       tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
2913       tree->opval.op = '=';
2914
2915       propAsgType (tree);
2916
2917       return tree;
2918
2919 /*------------------------------------------------------------------*/
2920 /*----------------------------*/
2921       /*      straight assignemnt   */
2922 /*----------------------------*/
2923     case '=':
2924       /* cannot be an aggregate */
2925       if (IS_AGGREGATE (LTYPE (tree)))
2926         {
2927           werror (E_AGGR_ASSIGN);
2928           goto errorTreeReturn;
2929         }
2930
2931       /* they should either match or be castable */
2932       if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2933         {
2934           werror (E_TYPE_MISMATCH, "assignment", " ");
2935           fprintf (stderr, "type --> '");
2936           printTypeChain (RTYPE (tree), stderr);
2937           fprintf (stderr, "' ");
2938           fprintf (stderr, "assigned to type --> '");
2939           printTypeChain (LTYPE (tree), stderr);
2940           fprintf (stderr, "'\n");
2941           goto errorTreeReturn;
2942         }
2943
2944       /* if the left side of the tree is of type void
2945          then report error */
2946       if (IS_VOID (LTYPE (tree)))
2947         {
2948           werror (E_CAST_ZERO);
2949           fprintf (stderr, "type --> '");
2950           printTypeChain (RTYPE (tree), stderr);
2951           fprintf (stderr, "' ");
2952           fprintf (stderr, "assigned to type --> '");
2953           printTypeChain (LTYPE (tree), stderr);
2954           fprintf (stderr, "'\n");
2955         }
2956
2957       /* extra checks for pointer types */
2958       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)) &&
2959           !IS_GENPTR (LTYPE (tree)))
2960         {
2961           if (DCL_TYPE (LTYPE (tree)) != DCL_TYPE (RTYPE (tree)))
2962             werror (W_PTR_ASSIGN);
2963         }
2964
2965       TETYPE (tree) = getSpec (TTYPE (tree) =
2966                                LTYPE (tree));
2967       RRVAL (tree) = 1;
2968       LLVAL (tree) = 1;
2969       if (!tree->initMode ) {
2970               if (IS_CONSTANT (LETYPE (tree))) {
2971                       werror (E_CODE_WRITE, " ");
2972               } 
2973       }
2974       if (LRVAL (tree))
2975         {
2976           werror (E_LVALUE_REQUIRED, "=");
2977           goto errorTreeReturn;
2978         }
2979
2980       propAsgType (tree);
2981
2982       return tree;
2983
2984 /*------------------------------------------------------------------*/
2985 /*----------------------------*/
2986       /*      comma operator        */
2987 /*----------------------------*/
2988     case ',':
2989       TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
2990       return tree;
2991
2992 /*------------------------------------------------------------------*/
2993 /*----------------------------*/
2994       /*       function call        */
2995 /*----------------------------*/
2996     case CALL:
2997       parmNumber = 1;
2998
2999       if (processParms (tree->left,
3000                         tree->left->args,
3001                         tree->right, &parmNumber, TRUE))
3002         goto errorTreeReturn;
3003
3004       if (options.stackAuto || IS_RENT (LETYPE (tree)))
3005         {
3006           tree->left->args = reverseVal (tree->left->args);
3007           reverseParms (tree->right);
3008         }
3009
3010       tree->args = tree->left->args;
3011       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3012       return tree;
3013
3014 /*------------------------------------------------------------------*/
3015 /*----------------------------*/
3016       /*     return statement       */
3017 /*----------------------------*/
3018     case RETURN:
3019       if (!tree->right)
3020         goto voidcheck;
3021
3022       if (checkType (currFunc->type->next, RTYPE (tree)) == 0)
3023         {
3024           werror (E_RETURN_MISMATCH);
3025           goto errorTreeReturn;
3026         }
3027
3028       if (IS_VOID (currFunc->type->next)
3029           && tree->right &&
3030           !IS_VOID (RTYPE (tree)))
3031         {
3032           werror (E_FUNC_VOID);
3033           goto errorTreeReturn;
3034         }
3035
3036       /* if there is going to be a casing required then add it */
3037       if (checkType (currFunc->type->next, RTYPE (tree)) < 0)
3038         {
3039 #if 0 && defined DEMAND_INTEGER_PROMOTION
3040           if (IS_INTEGRAL (currFunc->type->next))
3041             {
3042               pushTypeCastToLeaves (currFunc->type->next, tree->right, &(tree->right));
3043             }
3044           else
3045 #endif
3046             {
3047               tree->right =
3048                 decorateType (newNode (CAST,
3049                          newAst_LINK (copyLinkChain (currFunc->type->next)),
3050                                        tree->right));
3051             }
3052         }
3053
3054       RRVAL (tree) = 1;
3055       return tree;
3056
3057     voidcheck:
3058
3059       if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3060         {
3061           werror (E_VOID_FUNC, currFunc->name);
3062           goto errorTreeReturn;
3063         }
3064
3065       TTYPE (tree) = TETYPE (tree) = NULL;
3066       return tree;
3067
3068 /*------------------------------------------------------------------*/
3069 /*----------------------------*/
3070       /*     switch statement       */
3071 /*----------------------------*/
3072     case SWITCH:
3073       /* the switch value must be an integer */
3074       if (!IS_INTEGRAL (LTYPE (tree)))
3075         {
3076           werror (E_SWITCH_NON_INTEGER);
3077           goto errorTreeReturn;
3078         }
3079       LRVAL (tree) = 1;
3080       TTYPE (tree) = TETYPE (tree) = NULL;
3081       return tree;
3082
3083 /*------------------------------------------------------------------*/
3084 /*----------------------------*/
3085       /* ifx Statement              */
3086 /*----------------------------*/
3087     case IFX:
3088       tree->left = backPatchLabels (tree->left,
3089                                     tree->trueLabel,
3090                                     tree->falseLabel);
3091       TTYPE (tree) = TETYPE (tree) = NULL;
3092       return tree;
3093
3094 /*------------------------------------------------------------------*/
3095 /*----------------------------*/
3096       /* for Statement              */
3097 /*----------------------------*/
3098     case FOR:
3099
3100       decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3101       decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3102       decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3103
3104       /* if the for loop is reversible then
3105          reverse it otherwise do what we normally
3106          do */
3107       {
3108         symbol *sym;
3109         ast *init, *end;
3110
3111         if (isLoopReversible (tree, &sym, &init, &end))
3112           return reverseLoop (tree, sym, init, end);
3113         else
3114           return decorateType (createFor (AST_FOR (tree, trueLabel),
3115                                           AST_FOR (tree, continueLabel),
3116                                           AST_FOR (tree, falseLabel),
3117                                           AST_FOR (tree, condLabel),
3118                                           AST_FOR (tree, initExpr),
3119                                           AST_FOR (tree, condExpr),
3120                                           AST_FOR (tree, loopExpr),
3121                                           tree->left));
3122       }
3123     default:
3124       TTYPE (tree) = TETYPE (tree) = NULL;
3125       return tree;
3126     }
3127
3128   /* some error found this tree will be killed */
3129 errorTreeReturn:
3130   TTYPE (tree) = TETYPE (tree) = newCharLink ();
3131   tree->opval.op = NULLOP;
3132   tree->isError = 1;
3133
3134   return tree;
3135 }
3136
3137 /*-----------------------------------------------------------------*/
3138 /* sizeofOp - processes size of operation                          */
3139 /*-----------------------------------------------------------------*/
3140 value *
3141 sizeofOp (sym_link * type)
3142 {
3143   char buff[10];
3144
3145   /* get the size and convert it to character  */
3146   sprintf (buff, "%d", getSize (type));
3147
3148   /* now convert into value  */
3149   return constVal (buff);
3150 }
3151
3152
3153 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3154 #define IS_OR(ex)  (ex->type == EX_OP && ex->opval.op == OR_OP )
3155 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3156 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3157 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3158 #define IS_LT(ex)  (ex->type == EX_OP && ex->opval.op == '<' )
3159 #define IS_GT(ex)  (ex->type == EX_OP && ex->opval.op == '>')
3160
3161 /*-----------------------------------------------------------------*/
3162 /* backPatchLabels - change and or not operators to flow control    */
3163 /*-----------------------------------------------------------------*/
3164 ast *
3165 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3166 {
3167
3168   if (!tree)
3169     return NULL;
3170
3171   if (!(IS_ANDORNOT (tree)))
3172     return tree;
3173
3174   /* if this an and */
3175   if (IS_AND (tree))
3176     {
3177       static int localLbl = 0;
3178       symbol *localLabel;
3179
3180       sprintf (buffer, "_and_%d", localLbl++);
3181       localLabel = newSymbol (buffer, NestLevel);
3182
3183       tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3184
3185       /* if left is already a IFX then just change the if true label in that */
3186       if (!IS_IFX (tree->left))
3187         tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3188
3189       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3190       /* right is a IFX then just join */
3191       if (IS_IFX (tree->right))
3192         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3193
3194       tree->right = createLabel (localLabel, tree->right);
3195       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3196
3197       return newNode (NULLOP, tree->left, tree->right);
3198     }
3199
3200   /* if this is an or operation */
3201   if (IS_OR (tree))
3202     {
3203       static int localLbl = 0;
3204       symbol *localLabel;
3205
3206       sprintf (buffer, "_or_%d", localLbl++);
3207       localLabel = newSymbol (buffer, NestLevel);
3208
3209       tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3210
3211       /* if left is already a IFX then just change the if true label in that */
3212       if (!IS_IFX (tree->left))
3213         tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3214
3215       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3216       /* right is a IFX then just join */
3217       if (IS_IFX (tree->right))
3218         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3219
3220       tree->right = createLabel (localLabel, tree->right);
3221       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3222
3223       return newNode (NULLOP, tree->left, tree->right);
3224     }
3225
3226   /* change not */
3227   if (IS_NOT (tree))
3228     {
3229       int wasnot = IS_NOT (tree->left);
3230       tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3231
3232       /* if the left is already a IFX */
3233       if (!IS_IFX (tree->left))
3234         tree->left = newNode (IFX, tree->left, NULL);
3235
3236       if (wasnot)
3237         {
3238           tree->left->trueLabel = trueLabel;
3239           tree->left->falseLabel = falseLabel;
3240         }
3241       else
3242         {
3243           tree->left->trueLabel = falseLabel;
3244           tree->left->falseLabel = trueLabel;
3245         }
3246       return tree->left;
3247     }
3248
3249   if (IS_IFX (tree))
3250     {
3251       tree->trueLabel = trueLabel;
3252       tree->falseLabel = falseLabel;
3253     }
3254
3255   return tree;
3256 }
3257
3258
3259 /*-----------------------------------------------------------------*/
3260 /* createBlock - create expression tree for block                  */
3261 /*-----------------------------------------------------------------*/
3262 ast *
3263 createBlock (symbol * decl, ast * body)
3264 {
3265   ast *ex;
3266
3267   /* if the block has nothing */
3268   if (!body)
3269     return NULL;
3270
3271   ex = newNode (BLOCK, NULL, body);
3272   ex->values.sym = decl;
3273
3274   ex->right = ex->right;
3275   ex->level++;
3276   ex->lineno = 0;
3277   return ex;
3278 }
3279
3280 /*-----------------------------------------------------------------*/
3281 /* createLabel - creates the expression tree for labels            */
3282 /*-----------------------------------------------------------------*/
3283 ast *
3284 createLabel (symbol * label, ast * stmnt)
3285 {
3286   symbol *csym;
3287   char name[SDCC_NAME_MAX + 1];
3288   ast *rValue;
3289
3290   /* must create fresh symbol if the symbol name  */
3291   /* exists in the symbol table, since there can  */
3292   /* be a variable with the same name as the labl */
3293   if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3294       (csym->level == label->level))
3295     label = newSymbol (label->name, label->level);
3296
3297   /* change the name before putting it in add _ */
3298   sprintf (name, "%s", label->name);
3299
3300   /* put the label in the LabelSymbol table    */
3301   /* but first check if a label of the same    */
3302   /* name exists                               */
3303   if ((csym = findSym (LabelTab, NULL, name)))
3304     werror (E_DUPLICATE_LABEL, label->name);
3305   else
3306     addSym (LabelTab, label, name, label->level, 0);
3307
3308   label->islbl = 1;
3309   label->key = labelKey++;
3310   rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3311   rValue->lineno = 0;
3312
3313   return rValue;
3314 }
3315
3316 /*-----------------------------------------------------------------*/
3317 /* createCase - generates the parsetree for a case statement       */
3318 /*-----------------------------------------------------------------*/
3319 ast *
3320 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3321 {
3322   char caseLbl[SDCC_NAME_MAX + 1];
3323   ast *rexpr;
3324   value *val;
3325
3326   /* if the switch statement does not exist */
3327   /* then case is out of context            */
3328   if (!swStat)
3329     {
3330       werror (E_CASE_CONTEXT);
3331       return NULL;
3332     }
3333
3334   caseVal = decorateType (resolveSymbols (caseVal));
3335   /* if not a constant then error  */
3336   if (!IS_LITERAL (caseVal->ftype))
3337     {
3338       werror (E_CASE_CONSTANT);
3339       return NULL;
3340     }
3341
3342   /* if not a integer than error */
3343   if (!IS_INTEGRAL (caseVal->ftype))
3344     {
3345       werror (E_CASE_NON_INTEGER);
3346       return NULL;
3347     }
3348
3349   /* find the end of the switch values chain   */
3350   if (!(val = swStat->values.switchVals.swVals))
3351     swStat->values.switchVals.swVals = caseVal->opval.val;
3352   else
3353     {
3354       /* also order the cases according to value */
3355       value *pval = NULL;
3356       int cVal = (int) floatFromVal (caseVal->opval.val);
3357       while (val && (int) floatFromVal (val) < cVal)
3358         {
3359           pval = val;
3360           val = val->next;
3361         }
3362
3363       /* if we reached the end then */
3364       if (!val)
3365         {
3366           pval->next = caseVal->opval.val;
3367         }
3368       else
3369         {
3370           /* we found a value greater than */
3371           /* the current value we must add this */
3372           /* before the value */
3373           caseVal->opval.val->next = val;
3374
3375           /* if this was the first in chain */
3376           if (swStat->values.switchVals.swVals == val)
3377             swStat->values.switchVals.swVals =
3378               caseVal->opval.val;
3379           else
3380             pval->next = caseVal->opval.val;
3381         }
3382
3383     }
3384
3385   /* create the case label   */
3386   sprintf (caseLbl, "_case_%d_%d",
3387            swStat->values.switchVals.swNum,
3388            (int) floatFromVal (caseVal->opval.val));
3389
3390   rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3391   rexpr->lineno = 0;
3392   return rexpr;
3393 }
3394
3395 /*-----------------------------------------------------------------*/
3396 /* createDefault - creates the parse tree for the default statement */
3397 /*-----------------------------------------------------------------*/
3398 ast *
3399 createDefault (ast * swStat, ast * stmnt)
3400 {
3401   char defLbl[SDCC_NAME_MAX + 1];
3402
3403   /* if the switch statement does not exist */
3404   /* then case is out of context            */
3405   if (!swStat)
3406     {
3407       werror (E_CASE_CONTEXT);
3408       return NULL;
3409     }
3410
3411   /* turn on the default flag   */
3412   swStat->values.switchVals.swDefault = 1;
3413
3414   /* create the label  */
3415   sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3416   return createLabel (newSymbol (defLbl, 0), stmnt);
3417 }
3418
3419 /*-----------------------------------------------------------------*/
3420 /* createIf - creates the parsetree for the if statement           */
3421 /*-----------------------------------------------------------------*/
3422 ast *
3423 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3424 {
3425   static int Lblnum = 0;
3426   ast *ifTree;
3427   symbol *ifTrue, *ifFalse, *ifEnd;
3428
3429   /* if neither exists */
3430   if (!elseBody && !ifBody)
3431     return condAst;
3432
3433   /* create the labels */
3434   sprintf (buffer, "_iffalse_%d", Lblnum);
3435   ifFalse = newSymbol (buffer, NestLevel);
3436   /* if no else body then end == false */
3437   if (!elseBody)
3438     ifEnd = ifFalse;
3439   else
3440     {
3441       sprintf (buffer, "_ifend_%d", Lblnum);
3442       ifEnd = newSymbol (buffer, NestLevel);
3443     }
3444
3445   sprintf (buffer, "_iftrue_%d", Lblnum);
3446   ifTrue = newSymbol (buffer, NestLevel);
3447
3448   Lblnum++;
3449
3450   /* attach the ifTrue label to the top of it body */
3451   ifBody = createLabel (ifTrue, ifBody);
3452   /* attach a goto end to the ifBody if else is present */
3453   if (elseBody)
3454     {
3455       ifBody = newNode (NULLOP, ifBody,
3456                         newNode (GOTO,
3457                                  newAst_VALUE (symbolVal (ifEnd)),
3458                                  NULL));
3459       /* put the elseLabel on the else body */
3460       elseBody = createLabel (ifFalse, elseBody);
3461       /* out the end at the end of the body */
3462       elseBody = newNode (NULLOP,
3463                           elseBody,
3464                           createLabel (ifEnd, NULL));
3465     }
3466   else
3467     {
3468       ifBody = newNode (NULLOP, ifBody,
3469                         createLabel (ifFalse, NULL));
3470     }
3471   condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3472   if (IS_IFX (condAst))
3473     ifTree = condAst;
3474   else
3475     ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3476
3477   return newNode (NULLOP, ifTree,
3478                   newNode (NULLOP, ifBody, elseBody));
3479
3480 }
3481
3482 /*-----------------------------------------------------------------*/
3483 /* createDo - creates parse tree for do                            */
3484 /*        _dobody_n:                                               */
3485 /*            statements                                           */
3486 /*        _docontinue_n:                                           */
3487 /*            condition_expression +-> trueLabel -> _dobody_n      */
3488 /*                                 |                               */
3489 /*                                 +-> falseLabel-> _dobreak_n     */
3490 /*        _dobreak_n:                                              */
3491 /*-----------------------------------------------------------------*/
3492 ast *
3493 createDo (symbol * trueLabel, symbol * continueLabel,
3494           symbol * falseLabel, ast * condAst, ast * doBody)
3495 {
3496   ast *doTree;
3497
3498
3499   /* if the body does not exist then it is simple */
3500   if (!doBody)
3501     {
3502       condAst = backPatchLabels (condAst, continueLabel, NULL);
3503       doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3504                 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3505       doTree->trueLabel = continueLabel;
3506       doTree->falseLabel = NULL;
3507       return doTree;
3508     }
3509
3510   /* otherwise we have a body */
3511   condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3512
3513   /* attach the body label to the top */
3514   doBody = createLabel (trueLabel, doBody);
3515   /* attach the continue label to end of body */
3516   doBody = newNode (NULLOP, doBody,
3517                     createLabel (continueLabel, NULL));
3518
3519   /* now put the break label at the end */
3520   if (IS_IFX (condAst))
3521     doTree = condAst;
3522   else
3523     doTree = newIfxNode (condAst, trueLabel, falseLabel);
3524
3525   doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3526
3527   /* putting it together */
3528   return newNode (NULLOP, doBody, doTree);
3529 }
3530
3531 /*-----------------------------------------------------------------*/
3532 /* createFor - creates parse tree for 'for' statement              */
3533 /*        initExpr                                                 */
3534 /*   _forcond_n:                                                   */
3535 /*        condExpr  +-> trueLabel -> _forbody_n                    */
3536 /*                  |                                              */
3537 /*                  +-> falseLabel-> _forbreak_n                   */
3538 /*   _forbody_n:                                                   */
3539 /*        statements                                               */
3540 /*   _forcontinue_n:                                               */
3541 /*        loopExpr                                                 */
3542 /*        goto _forcond_n ;                                        */
3543 /*   _forbreak_n:                                                  */
3544 /*-----------------------------------------------------------------*/
3545 ast *
3546 createFor (symbol * trueLabel, symbol * continueLabel,
3547            symbol * falseLabel, symbol * condLabel,
3548            ast * initExpr, ast * condExpr, ast * loopExpr,
3549            ast * forBody)
3550 {
3551   ast *forTree;
3552
3553   /* if loopexpression not present then we can generate it */
3554   /* the same way as a while */
3555   if (!loopExpr)
3556     return newNode (NULLOP, initExpr,
3557                     createWhile (trueLabel, continueLabel,
3558                                  falseLabel, condExpr, forBody));
3559   /* vanilla for statement */
3560   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3561
3562   if (condExpr && !IS_IFX (condExpr))
3563     condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3564
3565
3566   /* attach condition label to condition */
3567   condExpr = createLabel (condLabel, condExpr);
3568
3569   /* attach body label to body */
3570   forBody = createLabel (trueLabel, forBody);
3571
3572   /* attach continue to forLoop expression & attach */
3573   /* goto the forcond @ and of loopExpression       */
3574   loopExpr = createLabel (continueLabel,
3575                           newNode (NULLOP,
3576                                    loopExpr,
3577                                    newNode (GOTO,
3578                                        newAst_VALUE (symbolVal (condLabel)),
3579                                             NULL)));
3580   /* now start putting them together */
3581   forTree = newNode (NULLOP, initExpr, condExpr);
3582   forTree = newNode (NULLOP, forTree, forBody);
3583   forTree = newNode (NULLOP, forTree, loopExpr);
3584   /* finally add the break label */
3585   forTree = newNode (NULLOP, forTree,
3586                      createLabel (falseLabel, NULL));
3587   return forTree;
3588 }
3589
3590 /*-----------------------------------------------------------------*/
3591 /* createWhile - creates parse tree for while statement            */
3592 /*               the while statement will be created as follows    */
3593 /*                                                                 */
3594 /*      _while_continue_n:                                         */
3595 /*            condition_expression +-> trueLabel -> _while_boby_n  */
3596 /*                                 |                               */
3597 /*                                 +-> falseLabel -> _while_break_n */
3598 /*      _while_body_n:                                             */
3599 /*            statements                                           */
3600 /*            goto _while_continue_n                               */
3601 /*      _while_break_n:                                            */
3602 /*-----------------------------------------------------------------*/
3603 ast *
3604 createWhile (symbol * trueLabel, symbol * continueLabel,
3605              symbol * falseLabel, ast * condExpr, ast * whileBody)
3606 {
3607   ast *whileTree;
3608
3609   /* put the continue label */
3610   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3611   condExpr = createLabel (continueLabel, condExpr);
3612   condExpr->lineno = 0;
3613
3614   /* put the body label in front of the body */
3615   whileBody = createLabel (trueLabel, whileBody);
3616   whileBody->lineno = 0;
3617   /* put a jump to continue at the end of the body */
3618   /* and put break label at the end of the body */
3619   whileBody = newNode (NULLOP,
3620                        whileBody,
3621                        newNode (GOTO,
3622                                 newAst_VALUE (symbolVal (continueLabel)),
3623                                 createLabel (falseLabel, NULL)));
3624
3625   /* put it all together */
3626   if (IS_IFX (condExpr))
3627     whileTree = condExpr;
3628   else
3629     {
3630       whileTree = newNode (IFX, condExpr, NULL);
3631       /* put the true & false labels in place */
3632       whileTree->trueLabel = trueLabel;
3633       whileTree->falseLabel = falseLabel;
3634     }
3635
3636   return newNode (NULLOP, whileTree, whileBody);
3637 }
3638
3639 /*-----------------------------------------------------------------*/
3640 /* optimizeGetHbit - get highest order bit of the expression       */
3641 /*-----------------------------------------------------------------*/
3642 ast *
3643 optimizeGetHbit (ast * tree)
3644 {
3645   int i, j;
3646   /* if this is not a bit and */
3647   if (!IS_BITAND (tree))
3648     return tree;
3649
3650   /* will look for tree of the form
3651      ( expr >> ((sizeof expr) -1) ) & 1 */
3652   if (!IS_AST_LIT_VALUE (tree->right))
3653     return tree;
3654
3655   if (AST_LIT_VALUE (tree->right) != 1)
3656     return tree;
3657
3658   if (!IS_RIGHT_OP (tree->left))
3659     return tree;
3660
3661   if (!IS_AST_LIT_VALUE (tree->left->right))
3662     return tree;
3663
3664   if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3665       (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3666     return tree;
3667
3668   return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3669
3670 }
3671
3672 /*-----------------------------------------------------------------*/
3673 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry     */
3674 /*-----------------------------------------------------------------*/
3675 ast *
3676 optimizeRRCRLC (ast * root)
3677 {
3678   /* will look for trees of the form
3679      (?expr << 1) | (?expr >> 7) or
3680      (?expr >> 7) | (?expr << 1) will make that
3681      into a RLC : operation ..
3682      Will also look for
3683      (?expr >> 1) | (?expr << 7) or
3684      (?expr << 7) | (?expr >> 1) will make that
3685      into a RRC operation
3686      note : by 7 I mean (number of bits required to hold the
3687      variable -1 ) */
3688   /* if the root operations is not a | operation the not */
3689   if (!IS_BITOR (root))
3690     return root;
3691
3692   /* I have to think of a better way to match patterns this sucks */
3693   /* that aside let start looking for the first case : I use a the
3694      negative check a lot to improve the efficiency */
3695   /* (?expr << 1) | (?expr >> 7) */
3696   if (IS_LEFT_OP (root->left) &&
3697       IS_RIGHT_OP (root->right))
3698     {
3699
3700       if (!SPEC_USIGN (TETYPE (root->left->left)))
3701         return root;
3702
3703       if (!IS_AST_LIT_VALUE (root->left->right) ||
3704           !IS_AST_LIT_VALUE (root->right->right))
3705         goto tryNext0;
3706
3707       /* make sure it is the same expression */
3708       if (!isAstEqual (root->left->left,
3709                        root->right->left))
3710         goto tryNext0;
3711
3712       if (AST_LIT_VALUE (root->left->right) != 1)
3713         goto tryNext0;
3714
3715       if (AST_LIT_VALUE (root->right->right) !=
3716           (getSize (TTYPE (root->left->left)) * 8 - 1))
3717         goto tryNext0;
3718
3719       /* whew got the first case : create the AST */
3720       return newNode (RLC, root->left->left, NULL);
3721     }
3722
3723 tryNext0:
3724   /* check for second case */
3725   /* (?expr >> 7) | (?expr << 1) */
3726   if (IS_LEFT_OP (root->right) &&
3727       IS_RIGHT_OP (root->left))
3728     {
3729
3730       if (!SPEC_USIGN (TETYPE (root->left->left)))
3731         return root;
3732
3733       if (!IS_AST_LIT_VALUE (root->left->right) ||
3734           !IS_AST_LIT_VALUE (root->right->right))
3735         goto tryNext1;
3736
3737       /* make sure it is the same symbol */
3738       if (!isAstEqual (root->left->left,
3739                        root->right->left))
3740         goto tryNext1;
3741
3742       if (AST_LIT_VALUE (root->right->right) != 1)
3743         goto tryNext1;
3744
3745       if (AST_LIT_VALUE (root->left->right) !=
3746           (getSize (TTYPE (root->left->left)) * 8 - 1))
3747         goto tryNext1;
3748
3749       /* whew got the first case : create the AST */
3750       return newNode (RLC, root->left->left, NULL);
3751
3752     }
3753
3754 tryNext1:
3755   /* third case for RRC */
3756   /*  (?symbol >> 1) | (?symbol << 7) */
3757   if (IS_LEFT_OP (root->right) &&
3758       IS_RIGHT_OP (root->left))
3759     {
3760
3761       if (!SPEC_USIGN (TETYPE (root->left->left)))
3762         return root;
3763
3764       if (!IS_AST_LIT_VALUE (root->left->right) ||
3765           !IS_AST_LIT_VALUE (root->right->right))
3766         goto tryNext2;
3767
3768       /* make sure it is the same symbol */
3769       if (!isAstEqual (root->left->left,
3770                        root->right->left))
3771         goto tryNext2;
3772
3773       if (AST_LIT_VALUE (root->left->right) != 1)
3774         goto tryNext2;
3775
3776       if (AST_LIT_VALUE (root->right->right) !=
3777           (getSize (TTYPE (root->left->left)) * 8 - 1))
3778         goto tryNext2;
3779
3780       /* whew got the first case : create the AST */
3781       return newNode (RRC, root->left->left, NULL);
3782
3783     }
3784 tryNext2:
3785   /* fourth and last case for now */
3786   /* (?symbol << 7) | (?symbol >> 1) */
3787   if (IS_RIGHT_OP (root->right) &&
3788       IS_LEFT_OP (root->left))
3789     {
3790
3791       if (!SPEC_USIGN (TETYPE (root->left->left)))
3792         return root;
3793
3794       if (!IS_AST_LIT_VALUE (root->left->right) ||
3795           !IS_AST_LIT_VALUE (root->right->right))
3796         return root;
3797
3798       /* make sure it is the same symbol */
3799       if (!isAstEqual (root->left->left,
3800                        root->right->left))
3801         return root;
3802
3803       if (AST_LIT_VALUE (root->right->right) != 1)
3804         return root;
3805
3806       if (AST_LIT_VALUE (root->left->right) !=
3807           (getSize (TTYPE (root->left->left)) * 8 - 1))
3808         return root;
3809
3810       /* whew got the first case : create the AST */
3811       return newNode (RRC, root->left->left, NULL);
3812
3813     }
3814
3815   /* not found return root */
3816   return root;
3817 }
3818
3819 /*-----------------------------------------------------------------*/
3820 /* optimizeCompare - otimizes compares for bit variables     */
3821 /*-----------------------------------------------------------------*/
3822 ast *
3823 optimizeCompare (ast * root)
3824 {
3825   ast *optExpr = NULL;
3826   value *vleft;
3827   value *vright;
3828   unsigned int litValue;
3829
3830   /* if nothing then return nothing */
3831   if (!root)
3832     return NULL;
3833
3834   /* if not a compare op then do leaves */
3835   if (!IS_COMPARE_OP (root))
3836     {
3837       root->left = optimizeCompare (root->left);
3838       root->right = optimizeCompare (root->right);
3839       return root;
3840     }
3841
3842   /* if left & right are the same then depending
3843      of the operation do */
3844   if (isAstEqual (root->left, root->right))
3845     {
3846       switch (root->opval.op)
3847         {
3848         case '>':
3849         case '<':
3850         case NE_OP:
3851           optExpr = newAst_VALUE (constVal ("0"));
3852           break;
3853         case GE_OP:
3854         case LE_OP:
3855         case EQ_OP:
3856           optExpr = newAst_VALUE (constVal ("1"));
3857           break;
3858         }
3859
3860       return decorateType (optExpr);
3861     }
3862
3863   vleft = (root->left->type == EX_VALUE ?
3864            root->left->opval.val : NULL);
3865
3866   vright = (root->right->type == EX_VALUE ?
3867             root->right->opval.val : NULL);
3868
3869   /* if left is a BITVAR in BITSPACE */
3870   /* and right is a LITERAL then opt- */
3871   /* imize else do nothing       */
3872   if (vleft && vright &&
3873       IS_BITVAR (vleft->etype) &&
3874       IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
3875       IS_LITERAL (vright->etype))
3876     {
3877
3878       /* if right side > 1 then comparison may never succeed */
3879       if ((litValue = (int) floatFromVal (vright)) > 1)
3880         {
3881           werror (W_BAD_COMPARE);
3882           goto noOptimize;
3883         }
3884
3885       if (litValue)
3886         {
3887           switch (root->opval.op)
3888             {
3889             case '>':           /* bit value greater than 1 cannot be */
3890               werror (W_BAD_COMPARE);
3891               goto noOptimize;
3892               break;
3893
3894             case '<':           /* bit value < 1 means 0 */
3895             case NE_OP:
3896               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3897               break;
3898
3899             case LE_OP: /* bit value <= 1 means no check */
3900               optExpr = newAst_VALUE (vright);
3901               break;
3902
3903             case GE_OP: /* bit value >= 1 means only check for = */
3904             case EQ_OP:
3905               optExpr = newAst_VALUE (vleft);
3906               break;
3907             }
3908         }
3909       else
3910         {                       /* literal is zero */
3911           switch (root->opval.op)
3912             {
3913             case '<':           /* bit value < 0 cannot be */
3914               werror (W_BAD_COMPARE);
3915               goto noOptimize;
3916               break;
3917
3918             case '>':           /* bit value > 0 means 1 */
3919             case NE_OP:
3920               optExpr = newAst_VALUE (vleft);
3921               break;
3922
3923             case LE_OP: /* bit value <= 0 means no check */
3924             case GE_OP: /* bit value >= 0 means no check */
3925               werror (W_BAD_COMPARE);
3926               goto noOptimize;
3927               break;
3928
3929             case EQ_OP: /* bit == 0 means ! of bit */
3930               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3931               break;
3932             }
3933         }
3934       return decorateType (resolveSymbols (optExpr));
3935     }                           /* end-of-if of BITVAR */
3936
3937 noOptimize:
3938   return root;
3939 }
3940 /*-----------------------------------------------------------------*/
3941 /* addSymToBlock : adds the symbol to the first block we find      */
3942 /*-----------------------------------------------------------------*/
3943 void 
3944 addSymToBlock (symbol * sym, ast * tree)
3945 {
3946   /* reached end of tree or a leaf */
3947   if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
3948     return;
3949
3950   /* found a block */
3951   if (IS_AST_OP (tree) &&
3952       tree->opval.op == BLOCK)
3953     {
3954
3955       symbol *lsym = copySymbol (sym);
3956
3957       lsym->next = AST_VALUES (tree, sym);
3958       AST_VALUES (tree, sym) = lsym;
3959       return;
3960     }
3961
3962   addSymToBlock (sym, tree->left);
3963   addSymToBlock (sym, tree->right);
3964 }
3965
3966 /*-----------------------------------------------------------------*/
3967 /* processRegParms - do processing for register parameters         */
3968 /*-----------------------------------------------------------------*/
3969 static void 
3970 processRegParms (value * args, ast * body)
3971 {
3972   while (args)
3973     {
3974       if (IS_REGPARM (args->etype))
3975         addSymToBlock (args->sym, body);
3976       args = args->next;
3977     }
3978 }
3979
3980 /*-----------------------------------------------------------------*/
3981 /* resetParmKey - resets the operandkeys for the symbols           */
3982 /*-----------------------------------------------------------------*/
3983 DEFSETFUNC (resetParmKey)
3984 {
3985   symbol *sym = item;
3986
3987   sym->key = 0;
3988   sym->defs = NULL;
3989   sym->uses = NULL;
3990   sym->remat = 0;
3991   return 1;
3992 }
3993
3994 /*-----------------------------------------------------------------*/
3995 /* createFunction - This is the key node that calls the iCode for  */
3996 /*                  generating the code for a function. Note code  */
3997 /*                  is generated function by function, later when  */
3998 /*                  add inter-procedural analysis this will change */
3999 /*-----------------------------------------------------------------*/
4000 ast *
4001 createFunction (symbol * name, ast * body)
4002 {
4003   ast *ex;
4004   symbol *csym;
4005   int stack = 0;
4006   sym_link *fetype;
4007   iCode *piCode = NULL;
4008
4009   /* if check function return 0 then some problem */
4010   if (checkFunction (name) == 0)
4011     return NULL;
4012
4013   /* create a dummy block if none exists */
4014   if (!body)
4015     body = newNode (BLOCK, NULL, NULL);
4016
4017   noLineno++;
4018
4019   /* check if the function name already in the symbol table */
4020   if ((csym = findSym (SymbolTab, NULL, name->name)))
4021     {
4022       name = csym;
4023       /* special case for compiler defined functions
4024          we need to add the name to the publics list : this
4025          actually means we are now compiling the compiler
4026          support routine */
4027       if (name->cdef)
4028         {
4029           addSet (&publics, name);
4030         }
4031     }
4032   else
4033     {
4034       addSymChain (name);
4035       allocVariables (name);
4036     }
4037   name->lastLine = yylineno;
4038   currFunc = name;
4039   processFuncArgs (currFunc, 0);
4040
4041   /* set the stack pointer */
4042   /* PENDING: check this for the mcs51 */
4043   stackPtr = -port->stack.direction * port->stack.call_overhead;
4044   if (IS_ISR (name->etype))
4045     stackPtr -= port->stack.direction * port->stack.isr_overhead;
4046   if (IS_RENT (name->etype) || options.stackAuto)
4047     stackPtr -= port->stack.direction * port->stack.reent_overhead;
4048
4049   xstackPtr = -port->stack.direction * port->stack.call_overhead;
4050
4051   fetype = getSpec (name->type);        /* get the specifier for the function */
4052   /* if this is a reentrant function then */
4053   if (IS_RENT (fetype))
4054     reentrant++;
4055
4056   allocParms (name->args);      /* allocate the parameters */
4057
4058   /* do processing for parameters that are passed in registers */
4059   processRegParms (name->args, body);
4060
4061   /* set the stack pointer */
4062   stackPtr = 0;
4063   xstackPtr = -1;
4064
4065   /* allocate & autoinit the block variables */
4066   processBlockVars (body, &stack, ALLOCATE);
4067
4068   /* save the stack information */
4069   if (options.useXstack)
4070     name->xstack = SPEC_STAK (fetype) = stack;
4071   else
4072     name->stack = SPEC_STAK (fetype) = stack;
4073
4074   /* name needs to be mangled */
4075   sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4076
4077   body = resolveSymbols (body); /* resolve the symbols */
4078   body = decorateType (body);   /* propagateType & do semantic checks */
4079
4080   ex = newAst_VALUE (symbolVal (name));         /* create name       */
4081   ex = newNode (FUNCTION, ex, body);
4082   ex->values.args = name->args;
4083
4084   if (fatalError)
4085     {
4086       werror (E_FUNC_NO_CODE, name->name);
4087       goto skipall;
4088     }
4089
4090   /* create the node & generate intermediate code */
4091   GcurMemmap = code;
4092   codeOutFile = code->oFile;
4093   piCode = iCodeFromAst (ex);
4094
4095   if (fatalError)
4096     {
4097       werror (E_FUNC_NO_CODE, name->name);
4098       goto skipall;
4099     }
4100
4101   eBBlockFromiCode (piCode);
4102
4103   /* if there are any statics then do them */
4104   if (staticAutos)
4105     {
4106       GcurMemmap = statsg;
4107       codeOutFile = statsg->oFile;
4108       eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4109       staticAutos = NULL;
4110     }
4111
4112 skipall:
4113
4114   /* dealloc the block variables */
4115   processBlockVars (body, &stack, DEALLOCATE);
4116   /* deallocate paramaters */
4117   deallocParms (name->args);
4118
4119   if (IS_RENT (fetype))
4120     reentrant--;
4121
4122   /* we are done freeup memory & cleanup */
4123   noLineno--;
4124   labelKey = 1;
4125   name->key = 0;
4126   name->fbody = 1;
4127   addSet (&operKeyReset, name);
4128   applyToSet (operKeyReset, resetParmKey);
4129
4130   if (options.debug && !options.nodebug)
4131     cdbStructBlock (1, cdbFile);
4132
4133   cleanUpLevel (LabelTab, 0);
4134   cleanUpBlock (StructTab, 1);
4135   cleanUpBlock (TypedefTab, 1);
4136
4137   xstack->syms = NULL;
4138   istack->syms = NULL;
4139   return NULL;
4140 }