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