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