]> git.gag.com Git - fw/sdcc/blob - src/SDCCast.c
030946d2aff4ace713eb5b6f26893f7897da2c02
[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               return tree;
2391             }
2392           LRVAL (tree) = 1;
2393           TTYPE (tree) = LTYPE (tree);
2394           return tree;
2395         }
2396
2397 /*------------------------------------------------------------------*/
2398 /*----------------------------*/
2399       /*    subtraction             */
2400 /*----------------------------*/
2401
2402       if (!(IS_PTR (LTYPE (tree)) ||
2403             IS_ARRAY (LTYPE (tree)) ||
2404             IS_ARITHMETIC (LTYPE (tree))))
2405         {
2406           werror (E_PLUS_INVALID, "-");
2407           goto errorTreeReturn;
2408         }
2409
2410       if (!(IS_PTR (RTYPE (tree)) ||
2411             IS_ARRAY (RTYPE (tree)) ||
2412             IS_ARITHMETIC (RTYPE (tree))))
2413         {
2414           werror (E_PLUS_INVALID, "-");
2415           goto errorTreeReturn;
2416         }
2417
2418       if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2419           !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2420             IS_INTEGRAL (RTYPE (tree))))
2421         {
2422           werror (E_PLUS_INVALID, "-");
2423           goto errorTreeReturn;
2424         }
2425
2426       /* if they are both literal then */
2427       /* rewrite the tree */
2428       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2429         {
2430           tree->type = EX_VALUE;
2431           tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2432                                       valFromType (RETYPE (tree)));
2433           tree->right = tree->left = NULL;
2434           TETYPE (tree) = getSpec (TTYPE (tree) =
2435                                    tree->opval.val->type);
2436           return tree;
2437         }
2438
2439       /* if the left & right are equal then zero */
2440       if (isAstEqual (tree->left, tree->right))
2441         {
2442           tree->type = EX_VALUE;
2443           tree->left = tree->right = NULL;
2444           tree->opval.val = constVal ("0");
2445           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2446           return tree;
2447         }
2448
2449       /* if both of them are pointers or arrays then */
2450       /* the result is going to be an integer        */
2451       if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2452           (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2453         TETYPE (tree) = TTYPE (tree) = newIntLink ();
2454       else
2455         /* if only the left is a pointer */
2456         /* then result is a pointer      */
2457       if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2458         TETYPE (tree) = getSpec (TTYPE (tree) =
2459                                  LTYPE (tree));
2460       else
2461         TETYPE (tree) = getSpec (TTYPE (tree) =
2462                                  computeType (LTYPE (tree),
2463                                               RTYPE (tree)));
2464       LRVAL (tree) = RRVAL (tree) = 1;
2465       return tree;
2466
2467 /*------------------------------------------------------------------*/
2468 /*----------------------------*/
2469       /*    compliment              */
2470 /*----------------------------*/
2471     case '~':
2472       /* can be only integral type */
2473       if (!IS_INTEGRAL (LTYPE (tree)))
2474         {
2475           werror (E_UNARY_OP, tree->opval.op);
2476           goto errorTreeReturn;
2477         }
2478
2479       /* if left is a literal then do it */
2480       if (IS_LITERAL (LTYPE (tree)))
2481         {
2482           tree->type = EX_VALUE;
2483           tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2484           tree->left = NULL;
2485           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2486           return tree;
2487         }
2488       LRVAL (tree) = 1;
2489       COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2490       return tree;
2491
2492 /*------------------------------------------------------------------*/
2493 /*----------------------------*/
2494       /*           not              */
2495 /*----------------------------*/
2496     case '!':
2497       /* can be pointer */
2498       if (!IS_ARITHMETIC (LTYPE (tree)) &&
2499           !IS_PTR (LTYPE (tree)) &&
2500           !IS_ARRAY (LTYPE (tree)))
2501         {
2502           werror (E_UNARY_OP, tree->opval.op);
2503           goto errorTreeReturn;
2504         }
2505
2506       /* if left is a literal then do it */
2507       if (IS_LITERAL (LTYPE (tree)))
2508         {
2509           tree->type = EX_VALUE;
2510           tree->opval.val = valNot (valFromType (LETYPE (tree)));
2511           tree->left = NULL;
2512           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2513           return tree;
2514         }
2515       LRVAL (tree) = 1;
2516       TTYPE (tree) = TETYPE (tree) = newCharLink ();
2517       return tree;
2518
2519 /*------------------------------------------------------------------*/
2520 /*----------------------------*/
2521       /*           shift            */
2522 /*----------------------------*/
2523     case RRC:
2524     case RLC:
2525       TTYPE (tree) = LTYPE (tree);
2526       TETYPE (tree) = LETYPE (tree);
2527       return tree;
2528
2529     case GETHBIT:
2530       TTYPE (tree) = TETYPE (tree) = newCharLink ();
2531       return tree;
2532
2533     case LEFT_OP:
2534     case RIGHT_OP:
2535       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2536         {
2537           werror (E_SHIFT_OP_INVALID);
2538           werror (E_CONTINUE, "left & right types are ");
2539           printTypeChain (LTYPE (tree), stderr);
2540           fprintf (stderr, ",");
2541           printTypeChain (RTYPE (tree), stderr);
2542           fprintf (stderr, "\n");
2543           goto errorTreeReturn;
2544         }
2545
2546       /* if they are both literal then */
2547       /* rewrite the tree */
2548       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2549         {
2550           tree->type = EX_VALUE;
2551           tree->opval.val = valShift (valFromType (LETYPE (tree)),
2552                                       valFromType (RETYPE (tree)),
2553                                       (tree->opval.op == LEFT_OP ? 1 : 0));
2554           tree->right = tree->left = NULL;
2555           TETYPE (tree) = getSpec (TTYPE (tree) =
2556                                    tree->opval.val->type);
2557           return tree;
2558         }
2559       /* if only the right side is a literal & we are
2560          shifting more than size of the left operand then zero */
2561       if (IS_LITERAL (RTYPE (tree)) &&
2562           ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2563           (getSize (LTYPE (tree)) * 8))
2564         {
2565           werror (W_SHIFT_CHANGED,
2566                   (tree->opval.op == LEFT_OP ? "left" : "right"));
2567           tree->type = EX_VALUE;
2568           tree->left = tree->right = NULL;
2569           tree->opval.val = constVal ("0");
2570           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2571           return tree;
2572         }
2573       LRVAL (tree) = RRVAL (tree) = 1;
2574       if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2575         {
2576           COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2577         }
2578       else
2579         {
2580           COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2581         }
2582       return tree;
2583
2584 /*------------------------------------------------------------------*/
2585 /*----------------------------*/
2586       /*         casting            */
2587 /*----------------------------*/
2588     case CAST:                  /* change the type   */
2589       /* cannot cast to an aggregate type */
2590       if (IS_AGGREGATE (LTYPE (tree)))
2591         {
2592           werror (E_CAST_ILLEGAL);
2593           goto errorTreeReturn;
2594         }
2595
2596       /* if the right is a literal replace the tree */
2597       if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree)))
2598         {
2599           tree->type = EX_VALUE;
2600           tree->opval.val =
2601             valCastLiteral (LTYPE (tree),
2602                             floatFromVal (valFromType (RETYPE (tree))));
2603           tree->left = NULL;
2604           tree->right = NULL;
2605           TTYPE (tree) = tree->opval.val->type;
2606           tree->values.literalFromCast = 1;
2607         }
2608       else
2609         {
2610           TTYPE (tree) = LTYPE (tree);
2611           LRVAL (tree) = 1;
2612         }
2613
2614       TETYPE (tree) = getSpec (TTYPE (tree));
2615
2616       return tree;
2617
2618 /*------------------------------------------------------------------*/
2619 /*----------------------------*/
2620       /*       logical &&, ||       */
2621 /*----------------------------*/
2622     case AND_OP:
2623     case OR_OP:
2624       /* each must me arithmetic type or be a pointer */
2625       if (!IS_PTR (LTYPE (tree)) &&
2626           !IS_ARRAY (LTYPE (tree)) &&
2627           !IS_INTEGRAL (LTYPE (tree)))
2628         {
2629           werror (E_COMPARE_OP);
2630           goto errorTreeReturn;
2631         }
2632
2633       if (!IS_PTR (RTYPE (tree)) &&
2634           !IS_ARRAY (RTYPE (tree)) &&
2635           !IS_INTEGRAL (RTYPE (tree)))
2636         {
2637           werror (E_COMPARE_OP);
2638           goto errorTreeReturn;
2639         }
2640       /* if they are both literal then */
2641       /* rewrite the tree */
2642       if (IS_LITERAL (RTYPE (tree)) &&
2643           IS_LITERAL (LTYPE (tree)))
2644         {
2645           tree->type = EX_VALUE;
2646           tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2647                                            valFromType (RETYPE (tree)),
2648                                            tree->opval.op);
2649           tree->right = tree->left = NULL;
2650           TETYPE (tree) = getSpec (TTYPE (tree) =
2651                                    tree->opval.val->type);
2652           return tree;
2653         }
2654       LRVAL (tree) = RRVAL (tree) = 1;
2655       TTYPE (tree) = TETYPE (tree) = newCharLink ();
2656       return tree;
2657
2658 /*------------------------------------------------------------------*/
2659 /*----------------------------*/
2660       /*     comparison operators   */
2661 /*----------------------------*/
2662     case '>':
2663     case '<':
2664     case LE_OP:
2665     case GE_OP:
2666     case EQ_OP:
2667     case NE_OP:
2668       {
2669         ast *lt = optimizeCompare (tree);
2670
2671         if (tree != lt)
2672           return lt;
2673       }
2674
2675       /* if they are pointers they must be castable */
2676       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2677         {
2678           if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2679             {
2680               werror (E_COMPARE_OP);
2681               fprintf (stderr, "comparing type ");
2682               printTypeChain (LTYPE (tree), stderr);
2683               fprintf (stderr, "to type ");
2684               printTypeChain (RTYPE (tree), stderr);
2685               fprintf (stderr, "\n");
2686               goto errorTreeReturn;
2687             }
2688         }
2689       /* else they should be promotable to one another */
2690       else
2691         {
2692           if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2693                 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2694
2695             if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2696               {
2697                 werror (E_COMPARE_OP);
2698                 fprintf (stderr, "comparing type ");
2699                 printTypeChain (LTYPE (tree), stderr);
2700                 fprintf (stderr, "to type ");
2701                 printTypeChain (RTYPE (tree), stderr);
2702                 fprintf (stderr, "\n");
2703                 goto errorTreeReturn;
2704               }
2705         }
2706
2707       /* if they are both literal then */
2708       /* rewrite the tree */
2709       if (IS_LITERAL (RTYPE (tree)) &&
2710           IS_LITERAL (LTYPE (tree)))
2711         {
2712           tree->type = EX_VALUE;
2713           tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2714                                         valFromType (RETYPE (tree)),
2715                                         tree->opval.op);
2716           tree->right = tree->left = NULL;
2717           TETYPE (tree) = getSpec (TTYPE (tree) =
2718                                    tree->opval.val->type);
2719           return tree;
2720         }
2721       LRVAL (tree) = RRVAL (tree) = 1;
2722       TTYPE (tree) = TETYPE (tree) = newCharLink ();
2723       return tree;
2724
2725 /*------------------------------------------------------------------*/
2726 /*----------------------------*/
2727       /*             sizeof         */
2728 /*----------------------------*/
2729     case SIZEOF:                /* evaluate wihout code generation */
2730       /* change the type to a integer */
2731       tree->type = EX_VALUE;
2732       sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2733       tree->opval.val = constVal (buffer);
2734       tree->right = tree->left = NULL;
2735       TETYPE (tree) = getSpec (TTYPE (tree) =
2736                                tree->opval.val->type);
2737       return tree;
2738
2739 /*------------------------------------------------------------------*/
2740 /*----------------------------*/
2741       /* conditional operator  '?'  */
2742 /*----------------------------*/
2743     case '?':
2744       /* the type is one on the left */
2745       TTYPE (tree) = LTYPE (tree);
2746       TETYPE (tree) = getSpec (TTYPE (tree));
2747       return tree;
2748
2749     case ':':
2750       /* if they don't match we have a problem */
2751       if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2752         {
2753           werror (E_TYPE_MISMATCH, "conditional operator", " ");
2754           goto errorTreeReturn;
2755         }
2756
2757       TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2758       TETYPE (tree) = getSpec (TTYPE (tree));
2759       return tree;
2760
2761
2762 /*------------------------------------------------------------------*/
2763 /*----------------------------*/
2764       /*    assignment operators    */
2765 /*----------------------------*/
2766     case MUL_ASSIGN:
2767     case DIV_ASSIGN:
2768       /* for these it must be both must be integral */
2769       if (!IS_ARITHMETIC (LTYPE (tree)) ||
2770           !IS_ARITHMETIC (RTYPE (tree)))
2771         {
2772           werror (E_OPS_INTEGRAL);
2773           goto errorTreeReturn;
2774         }
2775       RRVAL (tree) = 1;
2776       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2777
2778       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2779         werror (E_CODE_WRITE, " ");
2780
2781       if (LRVAL (tree))
2782         {
2783           werror (E_LVALUE_REQUIRED, "*= or /=");
2784           goto errorTreeReturn;
2785         }
2786       LLVAL (tree) = 1;
2787
2788       propAsgType (tree);
2789
2790       return tree;
2791
2792     case AND_ASSIGN:
2793     case OR_ASSIGN:
2794     case XOR_ASSIGN:
2795     case RIGHT_ASSIGN:
2796     case LEFT_ASSIGN:
2797       /* for these it must be both must be integral */
2798       if (!IS_INTEGRAL (LTYPE (tree)) ||
2799           !IS_INTEGRAL (RTYPE (tree)))
2800         {
2801           werror (E_OPS_INTEGRAL);
2802           goto errorTreeReturn;
2803         }
2804       RRVAL (tree) = 1;
2805       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2806
2807       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2808         werror (E_CODE_WRITE, " ");
2809
2810       if (LRVAL (tree))
2811         {
2812           werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2813           goto errorTreeReturn;
2814         }
2815       LLVAL (tree) = 1;
2816
2817       propAsgType (tree);
2818
2819       return tree;
2820
2821 /*------------------------------------------------------------------*/
2822 /*----------------------------*/
2823       /*    -= operator             */
2824 /*----------------------------*/
2825     case SUB_ASSIGN:
2826       if (!(IS_PTR (LTYPE (tree)) ||
2827             IS_ARITHMETIC (LTYPE (tree))))
2828         {
2829           werror (E_PLUS_INVALID, "-=");
2830           goto errorTreeReturn;
2831         }
2832
2833       if (!(IS_PTR (RTYPE (tree)) ||
2834             IS_ARITHMETIC (RTYPE (tree))))
2835         {
2836           werror (E_PLUS_INVALID, "-=");
2837           goto errorTreeReturn;
2838         }
2839       RRVAL (tree) = 1;
2840       TETYPE (tree) = getSpec (TTYPE (tree) =
2841                                computeType (LTYPE (tree),
2842                                             RTYPE (tree)));
2843
2844       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2845         werror (E_CODE_WRITE, " ");
2846
2847       if (LRVAL (tree))
2848         {
2849           werror (E_LVALUE_REQUIRED, "-=");
2850           goto errorTreeReturn;
2851         }
2852       LLVAL (tree) = 1;
2853
2854       propAsgType (tree);
2855
2856       return tree;
2857
2858 /*------------------------------------------------------------------*/
2859 /*----------------------------*/
2860       /*          += operator       */
2861 /*----------------------------*/
2862     case ADD_ASSIGN:
2863       /* this is not a unary operation */
2864       /* if both pointers then problem */
2865       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2866         {
2867           werror (E_PTR_PLUS_PTR);
2868           goto errorTreeReturn;
2869         }
2870
2871       if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
2872         {
2873           werror (E_PLUS_INVALID, "+=");
2874           goto errorTreeReturn;
2875         }
2876
2877       if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
2878         {
2879           werror (E_PLUS_INVALID, "+=");
2880           goto errorTreeReturn;
2881         }
2882       RRVAL (tree) = 1;
2883       TETYPE (tree) = getSpec (TTYPE (tree) =
2884                                computeType (LTYPE (tree),
2885                                             RTYPE (tree)));
2886
2887       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2888         werror (E_CODE_WRITE, " ");
2889
2890       if (LRVAL (tree))
2891         {
2892           werror (E_LVALUE_REQUIRED, "+=");
2893           goto errorTreeReturn;
2894         }
2895
2896       tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
2897       tree->opval.op = '=';
2898
2899       propAsgType (tree);
2900
2901       return tree;
2902
2903 /*------------------------------------------------------------------*/
2904 /*----------------------------*/
2905       /*      straight assignemnt   */
2906 /*----------------------------*/
2907     case '=':
2908       /* cannot be an aggregate */
2909       if (IS_AGGREGATE (LTYPE (tree)))
2910         {
2911           werror (E_AGGR_ASSIGN);
2912           goto errorTreeReturn;
2913         }
2914
2915       /* they should either match or be castable */
2916       if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2917         {
2918           werror (E_TYPE_MISMATCH, "assignment", " ");
2919           fprintf (stderr, "type --> '");
2920           printTypeChain (RTYPE (tree), stderr);
2921           fprintf (stderr, "' ");
2922           fprintf (stderr, "assigned to type --> '");
2923           printTypeChain (LTYPE (tree), stderr);
2924           fprintf (stderr, "'\n");
2925           goto errorTreeReturn;
2926         }
2927
2928       /* if the left side of the tree is of type void
2929          then report error */
2930       if (IS_VOID (LTYPE (tree)))
2931         {
2932           werror (E_CAST_ZERO);
2933           fprintf (stderr, "type --> '");
2934           printTypeChain (RTYPE (tree), stderr);
2935           fprintf (stderr, "' ");
2936           fprintf (stderr, "assigned to type --> '");
2937           printTypeChain (LTYPE (tree), stderr);
2938           fprintf (stderr, "'\n");
2939         }
2940
2941       /* extra checks for pointer types */
2942       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)) &&
2943           !IS_GENPTR (LTYPE (tree)))
2944         {
2945           if (DCL_TYPE (LTYPE (tree)) != DCL_TYPE (RTYPE (tree)))
2946             werror (W_PTR_ASSIGN);
2947         }
2948
2949       TETYPE (tree) = getSpec (TTYPE (tree) =
2950                                LTYPE (tree));
2951       RRVAL (tree) = 1;
2952       LLVAL (tree) = 1;
2953       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2954         werror (E_CODE_WRITE, " ");
2955
2956       if (LRVAL (tree))
2957         {
2958           werror (E_LVALUE_REQUIRED, "=");
2959           goto errorTreeReturn;
2960         }
2961
2962       propAsgType (tree);
2963
2964       return tree;
2965
2966 /*------------------------------------------------------------------*/
2967 /*----------------------------*/
2968       /*      comma operator        */
2969 /*----------------------------*/
2970     case ',':
2971       TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
2972       return tree;
2973
2974 /*------------------------------------------------------------------*/
2975 /*----------------------------*/
2976       /*       function call        */
2977 /*----------------------------*/
2978     case CALL:
2979       parmNumber = 1;
2980
2981       if (processParms (tree->left,
2982                         tree->left->args,
2983                         tree->right, &parmNumber, TRUE))
2984         goto errorTreeReturn;
2985
2986       if (options.stackAuto || IS_RENT (LETYPE (tree)))
2987         {
2988           tree->left->args = reverseVal (tree->left->args);
2989           reverseParms (tree->right);
2990         }
2991
2992       tree->args = tree->left->args;
2993       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
2994       return tree;
2995
2996 /*------------------------------------------------------------------*/
2997 /*----------------------------*/
2998       /*     return statement       */
2999 /*----------------------------*/
3000     case RETURN:
3001       if (!tree->right)
3002         goto voidcheck;
3003
3004       if (checkType (currFunc->type->next, RTYPE (tree)) == 0)
3005         {
3006           werror (E_RETURN_MISMATCH);
3007           goto errorTreeReturn;
3008         }
3009
3010       if (IS_VOID (currFunc->type->next)
3011           && tree->right &&
3012           !IS_VOID (RTYPE (tree)))
3013         {
3014           werror (E_FUNC_VOID);
3015           goto errorTreeReturn;
3016         }
3017
3018       /* if there is going to be a casing required then add it */
3019       if (checkType (currFunc->type->next, RTYPE (tree)) < 0)
3020         {
3021 #if 0 && defined DEMAND_INTEGER_PROMOTION
3022           if (IS_INTEGRAL (currFunc->type->next))
3023             {
3024               pushTypeCastToLeaves (currFunc->type->next, tree->right, &(tree->right));
3025             }
3026           else
3027 #endif
3028             {
3029               tree->right =
3030                 decorateType (newNode (CAST,
3031                          newAst_LINK (copyLinkChain (currFunc->type->next)),
3032                                        tree->right));
3033             }
3034         }
3035
3036       RRVAL (tree) = 1;
3037       return tree;
3038
3039     voidcheck:
3040
3041       if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3042         {
3043           werror (E_VOID_FUNC, currFunc->name);
3044           goto errorTreeReturn;
3045         }
3046
3047       TTYPE (tree) = TETYPE (tree) = NULL;
3048       return tree;
3049
3050 /*------------------------------------------------------------------*/
3051 /*----------------------------*/
3052       /*     switch statement       */
3053 /*----------------------------*/
3054     case SWITCH:
3055       /* the switch value must be an integer */
3056       if (!IS_INTEGRAL (LTYPE (tree)))
3057         {
3058           werror (E_SWITCH_NON_INTEGER);
3059           goto errorTreeReturn;
3060         }
3061       LRVAL (tree) = 1;
3062       TTYPE (tree) = TETYPE (tree) = NULL;
3063       return tree;
3064
3065 /*------------------------------------------------------------------*/
3066 /*----------------------------*/
3067       /* ifx Statement              */
3068 /*----------------------------*/
3069     case IFX:
3070       tree->left = backPatchLabels (tree->left,
3071                                     tree->trueLabel,
3072                                     tree->falseLabel);
3073       TTYPE (tree) = TETYPE (tree) = NULL;
3074       return tree;
3075
3076 /*------------------------------------------------------------------*/
3077 /*----------------------------*/
3078       /* for Statement              */
3079 /*----------------------------*/
3080     case FOR:
3081
3082       decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3083       decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3084       decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3085
3086       /* if the for loop is reversible then
3087          reverse it otherwise do what we normally
3088          do */
3089       {
3090         symbol *sym;
3091         ast *init, *end;
3092
3093         if (isLoopReversible (tree, &sym, &init, &end))
3094           return reverseLoop (tree, sym, init, end);
3095         else
3096           return decorateType (createFor (AST_FOR (tree, trueLabel),
3097                                           AST_FOR (tree, continueLabel),
3098                                           AST_FOR (tree, falseLabel),
3099                                           AST_FOR (tree, condLabel),
3100                                           AST_FOR (tree, initExpr),
3101                                           AST_FOR (tree, condExpr),
3102                                           AST_FOR (tree, loopExpr),
3103                                           tree->left));
3104       }
3105     default:
3106       TTYPE (tree) = TETYPE (tree) = NULL;
3107       return tree;
3108     }
3109
3110   /* some error found this tree will be killed */
3111 errorTreeReturn:
3112   TTYPE (tree) = TETYPE (tree) = newCharLink ();
3113   tree->opval.op = NULLOP;
3114   tree->isError = 1;
3115
3116   return tree;
3117 }
3118
3119 /*-----------------------------------------------------------------*/
3120 /* sizeofOp - processes size of operation                          */
3121 /*-----------------------------------------------------------------*/
3122 value *
3123 sizeofOp (sym_link * type)
3124 {
3125   char buff[10];
3126
3127   /* get the size and convert it to character  */
3128   sprintf (buff, "%d", getSize (type));
3129
3130   /* now convert into value  */
3131   return constVal (buff);
3132 }
3133
3134
3135 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3136 #define IS_OR(ex)  (ex->type == EX_OP && ex->opval.op == OR_OP )
3137 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3138 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3139 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3140 #define IS_LT(ex)  (ex->type == EX_OP && ex->opval.op == '<' )
3141 #define IS_GT(ex)  (ex->type == EX_OP && ex->opval.op == '>')
3142
3143 /*-----------------------------------------------------------------*/
3144 /* backPatchLabels - change and or not operators to flow control    */
3145 /*-----------------------------------------------------------------*/
3146 ast *
3147 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3148 {
3149
3150   if (!tree)
3151     return NULL;
3152
3153   if (!(IS_ANDORNOT (tree)))
3154     return tree;
3155
3156   /* if this an and */
3157   if (IS_AND (tree))
3158     {
3159       static int localLbl = 0;
3160       symbol *localLabel;
3161
3162       sprintf (buffer, "_and_%d", localLbl++);
3163       localLabel = newSymbol (buffer, NestLevel);
3164
3165       tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3166
3167       /* if left is already a IFX then just change the if true label in that */
3168       if (!IS_IFX (tree->left))
3169         tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3170
3171       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3172       /* right is a IFX then just join */
3173       if (IS_IFX (tree->right))
3174         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3175
3176       tree->right = createLabel (localLabel, tree->right);
3177       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3178
3179       return newNode (NULLOP, tree->left, tree->right);
3180     }
3181
3182   /* if this is an or operation */
3183   if (IS_OR (tree))
3184     {
3185       static int localLbl = 0;
3186       symbol *localLabel;
3187
3188       sprintf (buffer, "_or_%d", localLbl++);
3189       localLabel = newSymbol (buffer, NestLevel);
3190
3191       tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3192
3193       /* if left is already a IFX then just change the if true label in that */
3194       if (!IS_IFX (tree->left))
3195         tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3196
3197       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3198       /* right is a IFX then just join */
3199       if (IS_IFX (tree->right))
3200         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3201
3202       tree->right = createLabel (localLabel, tree->right);
3203       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3204
3205       return newNode (NULLOP, tree->left, tree->right);
3206     }
3207
3208   /* change not */
3209   if (IS_NOT (tree))
3210     {
3211       int wasnot = IS_NOT (tree->left);
3212       tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3213
3214       /* if the left is already a IFX */
3215       if (!IS_IFX (tree->left))
3216         tree->left = newNode (IFX, tree->left, NULL);
3217
3218       if (wasnot)
3219         {
3220           tree->left->trueLabel = trueLabel;
3221           tree->left->falseLabel = falseLabel;
3222         }
3223       else
3224         {
3225           tree->left->trueLabel = falseLabel;
3226           tree->left->falseLabel = trueLabel;
3227         }
3228       return tree->left;
3229     }
3230
3231   if (IS_IFX (tree))
3232     {
3233       tree->trueLabel = trueLabel;
3234       tree->falseLabel = falseLabel;
3235     }
3236
3237   return tree;
3238 }
3239
3240
3241 /*-----------------------------------------------------------------*/
3242 /* createBlock - create expression tree for block                  */
3243 /*-----------------------------------------------------------------*/
3244 ast *
3245 createBlock (symbol * decl, ast * body)
3246 {
3247   ast *ex;
3248
3249   /* if the block has nothing */
3250   if (!body)
3251     return NULL;
3252
3253   ex = newNode (BLOCK, NULL, body);
3254   ex->values.sym = decl;
3255
3256   ex->right = ex->right;
3257   ex->level++;
3258   ex->lineno = 0;
3259   return ex;
3260 }
3261
3262 /*-----------------------------------------------------------------*/
3263 /* createLabel - creates the expression tree for labels            */
3264 /*-----------------------------------------------------------------*/
3265 ast *
3266 createLabel (symbol * label, ast * stmnt)
3267 {
3268   symbol *csym;
3269   char name[SDCC_NAME_MAX + 1];
3270   ast *rValue;
3271
3272   /* must create fresh symbol if the symbol name  */
3273   /* exists in the symbol table, since there can  */
3274   /* be a variable with the same name as the labl */
3275   if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3276       (csym->level == label->level))
3277     label = newSymbol (label->name, label->level);
3278
3279   /* change the name before putting it in add _ */
3280   sprintf (name, "%s", label->name);
3281
3282   /* put the label in the LabelSymbol table    */
3283   /* but first check if a label of the same    */
3284   /* name exists                               */
3285   if ((csym = findSym (LabelTab, NULL, name)))
3286     werror (E_DUPLICATE_LABEL, label->name);
3287   else
3288     addSym (LabelTab, label, name, label->level, 0);
3289
3290   label->islbl = 1;
3291   label->key = labelKey++;
3292   rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3293   rValue->lineno = 0;
3294
3295   return rValue;
3296 }
3297
3298 /*-----------------------------------------------------------------*/
3299 /* createCase - generates the parsetree for a case statement       */
3300 /*-----------------------------------------------------------------*/
3301 ast *
3302 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3303 {
3304   char caseLbl[SDCC_NAME_MAX + 1];
3305   ast *rexpr;
3306   value *val;
3307
3308   /* if the switch statement does not exist */
3309   /* then case is out of context            */
3310   if (!swStat)
3311     {
3312       werror (E_CASE_CONTEXT);
3313       return NULL;
3314     }
3315
3316   caseVal = decorateType (resolveSymbols (caseVal));
3317   /* if not a constant then error  */
3318   if (!IS_LITERAL (caseVal->ftype))
3319     {
3320       werror (E_CASE_CONSTANT);
3321       return NULL;
3322     }
3323
3324   /* if not a integer than error */
3325   if (!IS_INTEGRAL (caseVal->ftype))
3326     {
3327       werror (E_CASE_NON_INTEGER);
3328       return NULL;
3329     }
3330
3331   /* find the end of the switch values chain   */
3332   if (!(val = swStat->values.switchVals.swVals))
3333     swStat->values.switchVals.swVals = caseVal->opval.val;
3334   else
3335     {
3336       /* also order the cases according to value */
3337       value *pval = NULL;
3338       int cVal = (int) floatFromVal (caseVal->opval.val);
3339       while (val && (int) floatFromVal (val) < cVal)
3340         {
3341           pval = val;
3342           val = val->next;
3343         }
3344
3345       /* if we reached the end then */
3346       if (!val)
3347         {
3348           pval->next = caseVal->opval.val;
3349         }
3350       else
3351         {
3352           /* we found a value greater than */
3353           /* the current value we must add this */
3354           /* before the value */
3355           caseVal->opval.val->next = val;
3356
3357           /* if this was the first in chain */
3358           if (swStat->values.switchVals.swVals == val)
3359             swStat->values.switchVals.swVals =
3360               caseVal->opval.val;
3361           else
3362             pval->next = caseVal->opval.val;
3363         }
3364
3365     }
3366
3367   /* create the case label   */
3368   sprintf (caseLbl, "_case_%d_%d",
3369            swStat->values.switchVals.swNum,
3370            (int) floatFromVal (caseVal->opval.val));
3371
3372   rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3373   rexpr->lineno = 0;
3374   return rexpr;
3375 }
3376
3377 /*-----------------------------------------------------------------*/
3378 /* createDefault - creates the parse tree for the default statement */
3379 /*-----------------------------------------------------------------*/
3380 ast *
3381 createDefault (ast * swStat, ast * stmnt)
3382 {
3383   char defLbl[SDCC_NAME_MAX + 1];
3384
3385   /* if the switch statement does not exist */
3386   /* then case is out of context            */
3387   if (!swStat)
3388     {
3389       werror (E_CASE_CONTEXT);
3390       return NULL;
3391     }
3392
3393   /* turn on the default flag   */
3394   swStat->values.switchVals.swDefault = 1;
3395
3396   /* create the label  */
3397   sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3398   return createLabel (newSymbol (defLbl, 0), stmnt);
3399 }
3400
3401 /*-----------------------------------------------------------------*/
3402 /* createIf - creates the parsetree for the if statement           */
3403 /*-----------------------------------------------------------------*/
3404 ast *
3405 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3406 {
3407   static int Lblnum = 0;
3408   ast *ifTree;
3409   symbol *ifTrue, *ifFalse, *ifEnd;
3410
3411   /* if neither exists */
3412   if (!elseBody && !ifBody)
3413     return condAst;
3414
3415   /* create the labels */
3416   sprintf (buffer, "_iffalse_%d", Lblnum);
3417   ifFalse = newSymbol (buffer, NestLevel);
3418   /* if no else body then end == false */
3419   if (!elseBody)
3420     ifEnd = ifFalse;
3421   else
3422     {
3423       sprintf (buffer, "_ifend_%d", Lblnum);
3424       ifEnd = newSymbol (buffer, NestLevel);
3425     }
3426
3427   sprintf (buffer, "_iftrue_%d", Lblnum);
3428   ifTrue = newSymbol (buffer, NestLevel);
3429
3430   Lblnum++;
3431
3432   /* attach the ifTrue label to the top of it body */
3433   ifBody = createLabel (ifTrue, ifBody);
3434   /* attach a goto end to the ifBody if else is present */
3435   if (elseBody)
3436     {
3437       ifBody = newNode (NULLOP, ifBody,
3438                         newNode (GOTO,
3439                                  newAst_VALUE (symbolVal (ifEnd)),
3440                                  NULL));
3441       /* put the elseLabel on the else body */
3442       elseBody = createLabel (ifFalse, elseBody);
3443       /* out the end at the end of the body */
3444       elseBody = newNode (NULLOP,
3445                           elseBody,
3446                           createLabel (ifEnd, NULL));
3447     }
3448   else
3449     {
3450       ifBody = newNode (NULLOP, ifBody,
3451                         createLabel (ifFalse, NULL));
3452     }
3453   condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3454   if (IS_IFX (condAst))
3455     ifTree = condAst;
3456   else
3457     ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3458
3459   return newNode (NULLOP, ifTree,
3460                   newNode (NULLOP, ifBody, elseBody));
3461
3462 }
3463
3464 /*-----------------------------------------------------------------*/
3465 /* createDo - creates parse tree for do                            */
3466 /*        _dobody_n:                                               */
3467 /*            statements                                           */
3468 /*        _docontinue_n:                                           */
3469 /*            condition_expression +-> trueLabel -> _dobody_n      */
3470 /*                                 |                               */
3471 /*                                 +-> falseLabel-> _dobreak_n     */
3472 /*        _dobreak_n:                                              */
3473 /*-----------------------------------------------------------------*/
3474 ast *
3475 createDo (symbol * trueLabel, symbol * continueLabel,
3476           symbol * falseLabel, ast * condAst, ast * doBody)
3477 {
3478   ast *doTree;
3479
3480
3481   /* if the body does not exist then it is simple */
3482   if (!doBody)
3483     {
3484       condAst = backPatchLabels (condAst, continueLabel, NULL);
3485       doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3486                 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3487       doTree->trueLabel = continueLabel;
3488       doTree->falseLabel = NULL;
3489       return doTree;
3490     }
3491
3492   /* otherwise we have a body */
3493   condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3494
3495   /* attach the body label to the top */
3496   doBody = createLabel (trueLabel, doBody);
3497   /* attach the continue label to end of body */
3498   doBody = newNode (NULLOP, doBody,
3499                     createLabel (continueLabel, NULL));
3500
3501   /* now put the break label at the end */
3502   if (IS_IFX (condAst))
3503     doTree = condAst;
3504   else
3505     doTree = newIfxNode (condAst, trueLabel, falseLabel);
3506
3507   doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3508
3509   /* putting it together */
3510   return newNode (NULLOP, doBody, doTree);
3511 }
3512
3513 /*-----------------------------------------------------------------*/
3514 /* createFor - creates parse tree for 'for' statement              */
3515 /*        initExpr                                                 */
3516 /*   _forcond_n:                                                   */
3517 /*        condExpr  +-> trueLabel -> _forbody_n                    */
3518 /*                  |                                              */
3519 /*                  +-> falseLabel-> _forbreak_n                   */
3520 /*   _forbody_n:                                                   */
3521 /*        statements                                               */
3522 /*   _forcontinue_n:                                               */
3523 /*        loopExpr                                                 */
3524 /*        goto _forcond_n ;                                        */
3525 /*   _forbreak_n:                                                  */
3526 /*-----------------------------------------------------------------*/
3527 ast *
3528 createFor (symbol * trueLabel, symbol * continueLabel,
3529            symbol * falseLabel, symbol * condLabel,
3530            ast * initExpr, ast * condExpr, ast * loopExpr,
3531            ast * forBody)
3532 {
3533   ast *forTree;
3534
3535   /* if loopexpression not present then we can generate it */
3536   /* the same way as a while */
3537   if (!loopExpr)
3538     return newNode (NULLOP, initExpr,
3539                     createWhile (trueLabel, continueLabel,
3540                                  falseLabel, condExpr, forBody));
3541   /* vanilla for statement */
3542   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3543
3544   if (condExpr && !IS_IFX (condExpr))
3545     condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3546
3547
3548   /* attach condition label to condition */
3549   condExpr = createLabel (condLabel, condExpr);
3550
3551   /* attach body label to body */
3552   forBody = createLabel (trueLabel, forBody);
3553
3554   /* attach continue to forLoop expression & attach */
3555   /* goto the forcond @ and of loopExpression       */
3556   loopExpr = createLabel (continueLabel,
3557                           newNode (NULLOP,
3558                                    loopExpr,
3559                                    newNode (GOTO,
3560                                        newAst_VALUE (symbolVal (condLabel)),
3561                                             NULL)));
3562   /* now start putting them together */
3563   forTree = newNode (NULLOP, initExpr, condExpr);
3564   forTree = newNode (NULLOP, forTree, forBody);
3565   forTree = newNode (NULLOP, forTree, loopExpr);
3566   /* finally add the break label */
3567   forTree = newNode (NULLOP, forTree,
3568                      createLabel (falseLabel, NULL));
3569   return forTree;
3570 }
3571
3572 /*-----------------------------------------------------------------*/
3573 /* createWhile - creates parse tree for while statement            */
3574 /*               the while statement will be created as follows    */
3575 /*                                                                 */
3576 /*      _while_continue_n:                                         */
3577 /*            condition_expression +-> trueLabel -> _while_boby_n  */
3578 /*                                 |                               */
3579 /*                                 +-> falseLabel -> _while_break_n */
3580 /*      _while_body_n:                                             */
3581 /*            statements                                           */
3582 /*            goto _while_continue_n                               */
3583 /*      _while_break_n:                                            */
3584 /*-----------------------------------------------------------------*/
3585 ast *
3586 createWhile (symbol * trueLabel, symbol * continueLabel,
3587              symbol * falseLabel, ast * condExpr, ast * whileBody)
3588 {
3589   ast *whileTree;
3590
3591   /* put the continue label */
3592   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3593   condExpr = createLabel (continueLabel, condExpr);
3594   condExpr->lineno = 0;
3595
3596   /* put the body label in front of the body */
3597   whileBody = createLabel (trueLabel, whileBody);
3598   whileBody->lineno = 0;
3599   /* put a jump to continue at the end of the body */
3600   /* and put break label at the end of the body */
3601   whileBody = newNode (NULLOP,
3602                        whileBody,
3603                        newNode (GOTO,
3604                                 newAst_VALUE (symbolVal (continueLabel)),
3605                                 createLabel (falseLabel, NULL)));
3606
3607   /* put it all together */
3608   if (IS_IFX (condExpr))
3609     whileTree = condExpr;
3610   else
3611     {
3612       whileTree = newNode (IFX, condExpr, NULL);
3613       /* put the true & false labels in place */
3614       whileTree->trueLabel = trueLabel;
3615       whileTree->falseLabel = falseLabel;
3616     }
3617
3618   return newNode (NULLOP, whileTree, whileBody);
3619 }
3620
3621 /*-----------------------------------------------------------------*/
3622 /* optimizeGetHbit - get highest order bit of the expression       */
3623 /*-----------------------------------------------------------------*/
3624 ast *
3625 optimizeGetHbit (ast * tree)
3626 {
3627   int i, j;
3628   /* if this is not a bit and */
3629   if (!IS_BITAND (tree))
3630     return tree;
3631
3632   /* will look for tree of the form
3633      ( expr >> ((sizeof expr) -1) ) & 1 */
3634   if (!IS_AST_LIT_VALUE (tree->right))
3635     return tree;
3636
3637   if (AST_LIT_VALUE (tree->right) != 1)
3638     return tree;
3639
3640   if (!IS_RIGHT_OP (tree->left))
3641     return tree;
3642
3643   if (!IS_AST_LIT_VALUE (tree->left->right))
3644     return tree;
3645
3646   if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3647       (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3648     return tree;
3649
3650   return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3651
3652 }
3653
3654 /*-----------------------------------------------------------------*/
3655 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry     */
3656 /*-----------------------------------------------------------------*/
3657 ast *
3658 optimizeRRCRLC (ast * root)
3659 {
3660   /* will look for trees of the form
3661      (?expr << 1) | (?expr >> 7) or
3662      (?expr >> 7) | (?expr << 1) will make that
3663      into a RLC : operation ..
3664      Will also look for
3665      (?expr >> 1) | (?expr << 7) or
3666      (?expr << 7) | (?expr >> 1) will make that
3667      into a RRC operation
3668      note : by 7 I mean (number of bits required to hold the
3669      variable -1 ) */
3670   /* if the root operations is not a | operation the not */
3671   if (!IS_BITOR (root))
3672     return root;
3673
3674   /* I have to think of a better way to match patterns this sucks */
3675   /* that aside let start looking for the first case : I use a the
3676      negative check a lot to improve the efficiency */
3677   /* (?expr << 1) | (?expr >> 7) */
3678   if (IS_LEFT_OP (root->left) &&
3679       IS_RIGHT_OP (root->right))
3680     {
3681
3682       if (!SPEC_USIGN (TETYPE (root->left->left)))
3683         return root;
3684
3685       if (!IS_AST_LIT_VALUE (root->left->right) ||
3686           !IS_AST_LIT_VALUE (root->right->right))
3687         goto tryNext0;
3688
3689       /* make sure it is the same expression */
3690       if (!isAstEqual (root->left->left,
3691                        root->right->left))
3692         goto tryNext0;
3693
3694       if (AST_LIT_VALUE (root->left->right) != 1)
3695         goto tryNext0;
3696
3697       if (AST_LIT_VALUE (root->right->right) !=
3698           (getSize (TTYPE (root->left->left)) * 8 - 1))
3699         goto tryNext0;
3700
3701       /* whew got the first case : create the AST */
3702       return newNode (RLC, root->left->left, NULL);
3703     }
3704
3705 tryNext0:
3706   /* check for second case */
3707   /* (?expr >> 7) | (?expr << 1) */
3708   if (IS_LEFT_OP (root->right) &&
3709       IS_RIGHT_OP (root->left))
3710     {
3711
3712       if (!SPEC_USIGN (TETYPE (root->left->left)))
3713         return root;
3714
3715       if (!IS_AST_LIT_VALUE (root->left->right) ||
3716           !IS_AST_LIT_VALUE (root->right->right))
3717         goto tryNext1;
3718
3719       /* make sure it is the same symbol */
3720       if (!isAstEqual (root->left->left,
3721                        root->right->left))
3722         goto tryNext1;
3723
3724       if (AST_LIT_VALUE (root->right->right) != 1)
3725         goto tryNext1;
3726
3727       if (AST_LIT_VALUE (root->left->right) !=
3728           (getSize (TTYPE (root->left->left)) * 8 - 1))
3729         goto tryNext1;
3730
3731       /* whew got the first case : create the AST */
3732       return newNode (RLC, root->left->left, NULL);
3733
3734     }
3735
3736 tryNext1:
3737   /* third case for RRC */
3738   /*  (?symbol >> 1) | (?symbol << 7) */
3739   if (IS_LEFT_OP (root->right) &&
3740       IS_RIGHT_OP (root->left))
3741     {
3742
3743       if (!SPEC_USIGN (TETYPE (root->left->left)))
3744         return root;
3745
3746       if (!IS_AST_LIT_VALUE (root->left->right) ||
3747           !IS_AST_LIT_VALUE (root->right->right))
3748         goto tryNext2;
3749
3750       /* make sure it is the same symbol */
3751       if (!isAstEqual (root->left->left,
3752                        root->right->left))
3753         goto tryNext2;
3754
3755       if (AST_LIT_VALUE (root->left->right) != 1)
3756         goto tryNext2;
3757
3758       if (AST_LIT_VALUE (root->right->right) !=
3759           (getSize (TTYPE (root->left->left)) * 8 - 1))
3760         goto tryNext2;
3761
3762       /* whew got the first case : create the AST */
3763       return newNode (RRC, root->left->left, NULL);
3764
3765     }
3766 tryNext2:
3767   /* fourth and last case for now */
3768   /* (?symbol << 7) | (?symbol >> 1) */
3769   if (IS_RIGHT_OP (root->right) &&
3770       IS_LEFT_OP (root->left))
3771     {
3772
3773       if (!SPEC_USIGN (TETYPE (root->left->left)))
3774         return root;
3775
3776       if (!IS_AST_LIT_VALUE (root->left->right) ||
3777           !IS_AST_LIT_VALUE (root->right->right))
3778         return root;
3779
3780       /* make sure it is the same symbol */
3781       if (!isAstEqual (root->left->left,
3782                        root->right->left))
3783         return root;
3784
3785       if (AST_LIT_VALUE (root->right->right) != 1)
3786         return root;
3787
3788       if (AST_LIT_VALUE (root->left->right) !=
3789           (getSize (TTYPE (root->left->left)) * 8 - 1))
3790         return root;
3791
3792       /* whew got the first case : create the AST */
3793       return newNode (RRC, root->left->left, NULL);
3794
3795     }
3796
3797   /* not found return root */
3798   return root;
3799 }
3800
3801 /*-----------------------------------------------------------------*/
3802 /* optimizeCompare - otimizes compares for bit variables     */
3803 /*-----------------------------------------------------------------*/
3804 ast *
3805 optimizeCompare (ast * root)
3806 {
3807   ast *optExpr = NULL;
3808   value *vleft;
3809   value *vright;
3810   unsigned int litValue;
3811
3812   /* if nothing then return nothing */
3813   if (!root)
3814     return NULL;
3815
3816   /* if not a compare op then do leaves */
3817   if (!IS_COMPARE_OP (root))
3818     {
3819       root->left = optimizeCompare (root->left);
3820       root->right = optimizeCompare (root->right);
3821       return root;
3822     }
3823
3824   /* if left & right are the same then depending
3825      of the operation do */
3826   if (isAstEqual (root->left, root->right))
3827     {
3828       switch (root->opval.op)
3829         {
3830         case '>':
3831         case '<':
3832         case NE_OP:
3833           optExpr = newAst_VALUE (constVal ("0"));
3834           break;
3835         case GE_OP:
3836         case LE_OP:
3837         case EQ_OP:
3838           optExpr = newAst_VALUE (constVal ("1"));
3839           break;
3840         }
3841
3842       return decorateType (optExpr);
3843     }
3844
3845   vleft = (root->left->type == EX_VALUE ?
3846            root->left->opval.val : NULL);
3847
3848   vright = (root->right->type == EX_VALUE ?
3849             root->right->opval.val : NULL);
3850
3851   /* if left is a BITVAR in BITSPACE */
3852   /* and right is a LITERAL then opt- */
3853   /* imize else do nothing       */
3854   if (vleft && vright &&
3855       IS_BITVAR (vleft->etype) &&
3856       IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
3857       IS_LITERAL (vright->etype))
3858     {
3859
3860       /* if right side > 1 then comparison may never succeed */
3861       if ((litValue = (int) floatFromVal (vright)) > 1)
3862         {
3863           werror (W_BAD_COMPARE);
3864           goto noOptimize;
3865         }
3866
3867       if (litValue)
3868         {
3869           switch (root->opval.op)
3870             {
3871             case '>':           /* bit value greater than 1 cannot be */
3872               werror (W_BAD_COMPARE);
3873               goto noOptimize;
3874               break;
3875
3876             case '<':           /* bit value < 1 means 0 */
3877             case NE_OP:
3878               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3879               break;
3880
3881             case LE_OP: /* bit value <= 1 means no check */
3882               optExpr = newAst_VALUE (vright);
3883               break;
3884
3885             case GE_OP: /* bit value >= 1 means only check for = */
3886             case EQ_OP:
3887               optExpr = newAst_VALUE (vleft);
3888               break;
3889             }
3890         }
3891       else
3892         {                       /* literal is zero */
3893           switch (root->opval.op)
3894             {
3895             case '<':           /* bit value < 0 cannot be */
3896               werror (W_BAD_COMPARE);
3897               goto noOptimize;
3898               break;
3899
3900             case '>':           /* bit value > 0 means 1 */
3901             case NE_OP:
3902               optExpr = newAst_VALUE (vleft);
3903               break;
3904
3905             case LE_OP: /* bit value <= 0 means no check */
3906             case GE_OP: /* bit value >= 0 means no check */
3907               werror (W_BAD_COMPARE);
3908               goto noOptimize;
3909               break;
3910
3911             case EQ_OP: /* bit == 0 means ! of bit */
3912               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3913               break;
3914             }
3915         }
3916       return decorateType (resolveSymbols (optExpr));
3917     }                           /* end-of-if of BITVAR */
3918
3919 noOptimize:
3920   return root;
3921 }
3922 /*-----------------------------------------------------------------*/
3923 /* addSymToBlock : adds the symbol to the first block we find      */
3924 /*-----------------------------------------------------------------*/
3925 void 
3926 addSymToBlock (symbol * sym, ast * tree)
3927 {
3928   /* reached end of tree or a leaf */
3929   if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
3930     return;
3931
3932   /* found a block */
3933   if (IS_AST_OP (tree) &&
3934       tree->opval.op == BLOCK)
3935     {
3936
3937       symbol *lsym = copySymbol (sym);
3938
3939       lsym->next = AST_VALUES (tree, sym);
3940       AST_VALUES (tree, sym) = lsym;
3941       return;
3942     }
3943
3944   addSymToBlock (sym, tree->left);
3945   addSymToBlock (sym, tree->right);
3946 }
3947
3948 /*-----------------------------------------------------------------*/
3949 /* processRegParms - do processing for register parameters         */
3950 /*-----------------------------------------------------------------*/
3951 static void 
3952 processRegParms (value * args, ast * body)
3953 {
3954   while (args)
3955     {
3956       if (IS_REGPARM (args->etype))
3957         addSymToBlock (args->sym, body);
3958       args = args->next;
3959     }
3960 }
3961
3962 /*-----------------------------------------------------------------*/
3963 /* resetParmKey - resets the operandkeys for the symbols           */
3964 /*-----------------------------------------------------------------*/
3965 DEFSETFUNC (resetParmKey)
3966 {
3967   symbol *sym = item;
3968
3969   sym->key = 0;
3970   sym->defs = NULL;
3971   sym->uses = NULL;
3972   sym->remat = 0;
3973   return 1;
3974 }
3975
3976 /*-----------------------------------------------------------------*/
3977 /* createFunction - This is the key node that calls the iCode for  */
3978 /*                  generating the code for a function. Note code  */
3979 /*                  is generated function by function, later when  */
3980 /*                  add inter-procedural analysis this will change */
3981 /*-----------------------------------------------------------------*/
3982 ast *
3983 createFunction (symbol * name, ast * body)
3984 {
3985   ast *ex;
3986   symbol *csym;
3987   int stack = 0;
3988   sym_link *fetype;
3989   iCode *piCode = NULL;
3990
3991   /* if check function return 0 then some problem */
3992   if (checkFunction (name) == 0)
3993     return NULL;
3994
3995   /* create a dummy block if none exists */
3996   if (!body)
3997     body = newNode (BLOCK, NULL, NULL);
3998
3999   noLineno++;
4000
4001   /* check if the function name already in the symbol table */
4002   if ((csym = findSym (SymbolTab, NULL, name->name)))
4003     {
4004       name = csym;
4005       /* special case for compiler defined functions
4006          we need to add the name to the publics list : this
4007          actually means we are now compiling the compiler
4008          support routine */
4009       if (name->cdef)
4010         {
4011           addSet (&publics, name);
4012         }
4013     }
4014   else
4015     {
4016       addSymChain (name);
4017       allocVariables (name);
4018     }
4019   name->lastLine = yylineno;
4020   currFunc = name;
4021   processFuncArgs (currFunc, 0);
4022
4023   /* set the stack pointer */
4024   /* PENDING: check this for the mcs51 */
4025   stackPtr = -port->stack.direction * port->stack.call_overhead;
4026   if (IS_ISR (name->etype))
4027     stackPtr -= port->stack.direction * port->stack.isr_overhead;
4028   if (IS_RENT (name->etype) || options.stackAuto)
4029     stackPtr -= port->stack.direction * port->stack.reent_overhead;
4030
4031   xstackPtr = -port->stack.direction * port->stack.call_overhead;
4032
4033   fetype = getSpec (name->type);        /* get the specifier for the function */
4034   /* if this is a reentrant function then */
4035   if (IS_RENT (fetype))
4036     reentrant++;
4037
4038   allocParms (name->args);      /* allocate the parameters */
4039
4040   /* do processing for parameters that are passed in registers */
4041   processRegParms (name->args, body);
4042
4043   /* set the stack pointer */
4044   stackPtr = 0;
4045   xstackPtr = -1;
4046
4047   /* allocate & autoinit the block variables */
4048   processBlockVars (body, &stack, ALLOCATE);
4049
4050   /* save the stack information */
4051   if (options.useXstack)
4052     name->xstack = SPEC_STAK (fetype) = stack;
4053   else
4054     name->stack = SPEC_STAK (fetype) = stack;
4055
4056   /* name needs to be mangled */
4057   sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4058
4059   body = resolveSymbols (body); /* resolve the symbols */
4060   body = decorateType (body);   /* propagateType & do semantic checks */
4061
4062   ex = newAst_VALUE (symbolVal (name));         /* create name       */
4063   ex = newNode (FUNCTION, ex, body);
4064   ex->values.args = name->args;
4065
4066   if (fatalError)
4067     {
4068       werror (E_FUNC_NO_CODE, name->name);
4069       goto skipall;
4070     }
4071
4072   /* create the node & generate intermediate code */
4073   codeOutFile = code->oFile;
4074   piCode = iCodeFromAst (ex);
4075
4076   if (fatalError)
4077     {
4078       werror (E_FUNC_NO_CODE, name->name);
4079       goto skipall;
4080     }
4081
4082   eBBlockFromiCode (piCode);
4083
4084   /* if there are any statics then do them */
4085   if (staticAutos)
4086     {
4087       codeOutFile = statsg->oFile;
4088       eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4089       staticAutos = NULL;
4090     }
4091
4092 skipall:
4093
4094   /* dealloc the block variables */
4095   processBlockVars (body, &stack, DEALLOCATE);
4096   /* deallocate paramaters */
4097   deallocParms (name->args);
4098
4099   if (IS_RENT (fetype))
4100     reentrant--;
4101
4102   /* we are done freeup memory & cleanup */
4103   noLineno--;
4104   labelKey = 1;
4105   name->key = 0;
4106   name->fbody = 1;
4107   addSet (&operKeyReset, name);
4108   applyToSet (operKeyReset, resetParmKey);
4109
4110   if (options.debug && !options.nodebug)
4111     cdbStructBlock (1, cdbFile);
4112
4113   cleanUpLevel (LabelTab, 0);
4114   cleanUpBlock (StructTab, 1);
4115   cleanUpBlock (TypedefTab, 1);
4116
4117   xstack->syms = NULL;
4118   istack->syms = NULL;
4119   return NULL;
4120 }