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