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