dfb3ad05d9550b67640489dac1eafae661aab514
[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           isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1638         return FALSE;
1639
1640       if (astHasVolatile (pbody->left))
1641         return FALSE;
1642       
1643       if (astHasDeref(pbody->right)) return FALSE;
1644
1645       return isConformingBody (pbody->left, sym, body) &&
1646         isConformingBody (pbody->right, sym, body);
1647
1648     case MUL_ASSIGN:
1649     case DIV_ASSIGN:
1650     case AND_ASSIGN:
1651     case OR_ASSIGN:
1652     case XOR_ASSIGN:
1653     case RIGHT_ASSIGN:
1654     case LEFT_ASSIGN:
1655     case SUB_ASSIGN:
1656     case ADD_ASSIGN:
1657       assert ("Parser should not have generated this\n");
1658
1659 /*------------------------------------------------------------------*/
1660 /*----------------------------*/
1661       /*      comma operator        */
1662 /*----------------------------*/
1663     case ',':
1664       return isConformingBody (pbody->left, sym, body) &&
1665         isConformingBody (pbody->right, sym, body);
1666
1667 /*------------------------------------------------------------------*/
1668 /*----------------------------*/
1669       /*       function call        */
1670 /*----------------------------*/
1671     case CALL:
1672         /* if local & not passed as paramater then ok */
1673         if (sym->level && !astHasSymbol(pbody->right,sym)) 
1674             return TRUE;
1675       return FALSE;
1676
1677 /*------------------------------------------------------------------*/
1678 /*----------------------------*/
1679       /*     return statement       */
1680 /*----------------------------*/
1681     case RETURN:
1682       return FALSE;
1683
1684     case GOTO:
1685       if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1686         return TRUE;
1687       else
1688         return FALSE;
1689     case SWITCH:
1690       if (astHasSymbol (pbody->left, sym))
1691         return FALSE;
1692
1693     default:
1694       break;
1695     }
1696
1697   return isConformingBody (pbody->left, sym, body) &&
1698     isConformingBody (pbody->right, sym, body);
1699
1700
1701
1702 }
1703
1704 /*-----------------------------------------------------------------*/
1705 /* isLoopReversible - takes a for loop as input && returns true    */
1706 /* if the for loop is reversible. If yes will set the value of     */
1707 /* the loop control var & init value & termination value           */
1708 /*-----------------------------------------------------------------*/
1709 bool 
1710 isLoopReversible (ast * loop, symbol ** loopCntrl,
1711                   ast ** init, ast ** end)
1712 {
1713   /* if option says don't do it then don't */
1714   if (optimize.noLoopReverse)
1715     return 0;
1716   /* there are several tests to determine this */
1717
1718   /* for loop has to be of the form
1719      for ( <sym> = <const1> ;
1720      [<sym> < <const2>]  ;
1721      [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1722      forBody */
1723   if (!isLoopCountable (AST_FOR (loop, initExpr),
1724                         AST_FOR (loop, condExpr),
1725                         AST_FOR (loop, loopExpr),
1726                         loopCntrl, init, end))
1727     return 0;
1728
1729   /* now do some serious checking on the body of the loop
1730    */
1731
1732   return isConformingBody (loop->left, *loopCntrl, loop->left);
1733
1734 }
1735
1736 /*-----------------------------------------------------------------*/
1737 /* replLoopSym - replace the loop sym by loop sym -1               */
1738 /*-----------------------------------------------------------------*/
1739 static void 
1740 replLoopSym (ast * body, symbol * sym)
1741 {
1742   /* reached end */
1743   if (!body || IS_AST_LINK (body))
1744     return;
1745
1746   if (IS_AST_SYM_VALUE (body))
1747     {
1748
1749       if (isSymbolEqual (AST_SYMBOL (body), sym))
1750         {
1751
1752           body->type = EX_OP;
1753           body->opval.op = '-';
1754           body->left = newAst_VALUE (symbolVal (sym));
1755           body->right = newAst_VALUE (constVal ("1"));
1756
1757         }
1758
1759       return;
1760
1761     }
1762
1763   replLoopSym (body->left, sym);
1764   replLoopSym (body->right, sym);
1765
1766 }
1767
1768 /*-----------------------------------------------------------------*/
1769 /* reverseLoop - do the actual loop reversal                       */
1770 /*-----------------------------------------------------------------*/
1771 ast *
1772 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1773 {
1774   ast *rloop;
1775
1776   /* create the following tree
1777      <sym> = loopCount ;
1778      for_continue:
1779      forbody
1780      <sym> -= 1;
1781      if (sym) goto for_continue ;
1782      <sym> = end */
1783
1784   /* put it together piece by piece */
1785   rloop = newNode (NULLOP,
1786                    createIf (newAst_VALUE (symbolVal (sym)),
1787                              newNode (GOTO,
1788                    newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1789                                       NULL), NULL),
1790                    newNode ('=',
1791                             newAst_VALUE (symbolVal (sym)),
1792                             end));
1793
1794   replLoopSym (loop->left, sym);
1795
1796   rloop = newNode (NULLOP,
1797                    newNode ('=',
1798                             newAst_VALUE (symbolVal (sym)),
1799                             newNode ('-', end, init)),
1800                    createLabel (AST_FOR (loop, continueLabel),
1801                                 newNode (NULLOP,
1802                                          loop->left,
1803                                          newNode (NULLOP,
1804                                                   newNode (SUB_ASSIGN,
1805                                              newAst_VALUE (symbolVal (sym)),
1806                                              newAst_VALUE (constVal ("1"))),
1807                                                   rloop))));
1808
1809   return decorateType (rloop);
1810
1811 }
1812
1813 /*-----------------------------------------------------------------*/
1814 /* decorateType - compute type for this tree also does type cheking */
1815 /*          this is done bottom up, since type have to flow upwards */
1816 /*          it also does constant folding, and paramater checking  */
1817 /*-----------------------------------------------------------------*/
1818 ast *
1819 decorateType (ast * tree)
1820 {
1821   int parmNumber;
1822   sym_link *p;
1823
1824   if (!tree)
1825     return tree;
1826
1827   /* if already has type then do nothing */
1828   if (tree->decorated)
1829     return tree;
1830
1831   tree->decorated = 1;
1832
1833   /* print the line          */
1834   /* if not block & function */
1835   if (tree->type == EX_OP &&
1836       (tree->opval.op != FUNCTION &&
1837        tree->opval.op != BLOCK &&
1838        tree->opval.op != NULLOP))
1839     {
1840       filename = tree->filename;
1841       lineno = tree->lineno;
1842     }
1843
1844   /* if any child is an error | this one is an error do nothing */
1845   if (tree->isError ||
1846       (tree->left && tree->left->isError) ||
1847       (tree->right && tree->right->isError))
1848     return tree;
1849
1850 /*------------------------------------------------------------------*/
1851 /*----------------------------*/
1852   /*   leaf has been reached    */
1853 /*----------------------------*/
1854   /* if this is of type value */
1855   /* just get the type        */
1856   if (tree->type == EX_VALUE)
1857     {
1858
1859       if (IS_LITERAL (tree->opval.val->etype))
1860         {
1861
1862           /* if this is a character array then declare it */
1863           if (IS_ARRAY (tree->opval.val->type))
1864             tree->opval.val = stringToSymbol (tree->opval.val);
1865
1866           /* otherwise just copy the type information */
1867           COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1868           return tree;
1869         }
1870
1871       if (tree->opval.val->sym)
1872         {
1873           /* if the undefined flag is set then give error message */
1874           if (tree->opval.val->sym->undefined)
1875             {
1876               werror (E_ID_UNDEF, tree->opval.val->sym->name);
1877               /* assume int */
1878               TTYPE (tree) = TETYPE (tree) =
1879                 tree->opval.val->type = tree->opval.val->sym->type =
1880                 tree->opval.val->etype = tree->opval.val->sym->etype =
1881                 copyLinkChain (INTTYPE);
1882             }
1883           else
1884             {
1885
1886               /* if impilicit i.e. struct/union member then no type */
1887               if (tree->opval.val->sym->implicit)
1888                 TTYPE (tree) = TETYPE (tree) = NULL;
1889
1890               else
1891                 {
1892
1893                   /* else copy the type */
1894                   COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1895
1896                   /* and mark it as referenced */
1897                   tree->opval.val->sym->isref = 1;
1898                 }
1899             }
1900         }
1901
1902       return tree;
1903     }
1904
1905   /* if type link for the case of cast */
1906   if (tree->type == EX_LINK)
1907     {
1908       COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1909       return tree;
1910     }
1911
1912   {
1913     ast *dtl, *dtr;
1914
1915     dtl = decorateType (tree->left);
1916     /* delay right side for '?' operator since conditional macro expansions might
1917        rely on this */
1918     dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
1919
1920     /* this is to take care of situations
1921        when the tree gets rewritten */
1922     if (dtl != tree->left)
1923       tree->left = dtl;
1924     if (dtr != tree->right)
1925       tree->right = dtr;
1926   }
1927
1928   /* depending on type of operator do */
1929
1930   switch (tree->opval.op)
1931     {
1932         /*------------------------------------------------------------------*/
1933         /*----------------------------*/
1934         /*        array node          */
1935         /*----------------------------*/
1936     case '[':
1937
1938       /* determine which is the array & which the index */
1939       if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1940         {
1941
1942           ast *tempTree = tree->left;
1943           tree->left = tree->right;
1944           tree->right = tempTree;
1945         }
1946
1947       /* first check if this is a array or a pointer */
1948       if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1949         {
1950           werror (E_NEED_ARRAY_PTR, "[]");
1951           goto errorTreeReturn;
1952         }
1953
1954       /* check if the type of the idx */
1955       if (!IS_INTEGRAL (RTYPE (tree)))
1956         {
1957           werror (E_IDX_NOT_INT);
1958           goto errorTreeReturn;
1959         }
1960
1961       /* if the left is an rvalue then error */
1962       if (LRVAL (tree))
1963         {
1964           werror (E_LVALUE_REQUIRED, "array access");
1965           goto errorTreeReturn;
1966         }
1967       RRVAL (tree) = 1;
1968       COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1969       if (IS_PTR(LTYPE(tree))) {
1970               SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1971       }
1972       return tree;
1973
1974       /*------------------------------------------------------------------*/
1975       /*----------------------------*/
1976       /*      struct/union          */
1977       /*----------------------------*/
1978     case '.':
1979       /* if this is not a structure */
1980       if (!IS_STRUCT (LTYPE (tree)))
1981         {
1982           werror (E_STRUCT_UNION, ".");
1983           goto errorTreeReturn;
1984         }
1985       TTYPE (tree) = structElemType (LTYPE (tree),
1986                                      (tree->right->type == EX_VALUE ?
1987                                tree->right->opval.val : NULL));
1988       TETYPE (tree) = getSpec (TTYPE (tree));
1989       return tree;
1990
1991       /*------------------------------------------------------------------*/
1992       /*----------------------------*/
1993       /*    struct/union pointer    */
1994       /*----------------------------*/
1995     case PTR_OP:
1996       /* if not pointer to a structure */
1997       if (!IS_PTR (LTYPE (tree)))
1998         {
1999           werror (E_PTR_REQD);
2000           goto errorTreeReturn;
2001         }
2002
2003       if (!IS_STRUCT (LTYPE (tree)->next))
2004         {
2005           werror (E_STRUCT_UNION, "->");
2006           goto errorTreeReturn;
2007         }
2008
2009       TTYPE (tree) = structElemType (LTYPE (tree)->next,
2010                                      (tree->right->type == EX_VALUE ?
2011                                tree->right->opval.val : NULL));
2012       TETYPE (tree) = getSpec (TTYPE (tree));
2013
2014       /* adjust the storage class */
2015       switch (DCL_TYPE(tree->left->ftype)) {
2016       case POINTER:
2017         break;
2018       case FPOINTER:
2019         SPEC_SCLS(TETYPE(tree)) = S_XDATA; 
2020         break;
2021       case CPOINTER:
2022         SPEC_SCLS(TETYPE(tree)) = S_CODE; 
2023         break;
2024       case GPOINTER:
2025         break;
2026       case PPOINTER:
2027         SPEC_SCLS(TETYPE(tree)) = S_XSTACK; 
2028         break;
2029       case IPOINTER:
2030         SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2031         break;
2032       case EEPPOINTER:
2033         SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2034         break;
2035       case UPOINTER:
2036       case ARRAY:
2037       case FUNCTION:
2038       }
2039
2040       return tree;
2041
2042       /*------------------------------------------------------------------*/
2043       /*----------------------------*/
2044       /*  ++/-- operation           */
2045       /*----------------------------*/
2046     case INC_OP:                /* incerement operator unary so left only */
2047     case DEC_OP:
2048       {
2049         sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2050         COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2051         if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2052           werror (E_CODE_WRITE, "++/--");
2053
2054         if (tree->right)
2055           RLVAL (tree) = 1;
2056         else
2057           LLVAL (tree) = 1;
2058         return tree;
2059       }
2060
2061       /*------------------------------------------------------------------*/
2062       /*----------------------------*/
2063       /*  bitwise and               */
2064       /*----------------------------*/
2065     case '&':                   /* can be unary   */
2066       /* if right is NULL then unary operation  */
2067       if (tree->right)          /* not an unary operation */
2068         {
2069
2070           if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2071             {
2072               werror (E_BITWISE_OP);
2073               werror (W_CONTINUE, "left & right types are ");
2074               printTypeChain (LTYPE (tree), stderr);
2075               fprintf (stderr, ",");
2076               printTypeChain (RTYPE (tree), stderr);
2077               fprintf (stderr, "\n");
2078               goto errorTreeReturn;
2079             }
2080
2081           /* if they are both literal */
2082           if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2083             {
2084               tree->type = EX_VALUE;
2085               tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2086                                           valFromType (RETYPE (tree)), '&');
2087
2088               tree->right = tree->left = NULL;
2089               TETYPE (tree) = tree->opval.val->etype;
2090               TTYPE (tree) = tree->opval.val->type;
2091               return tree;
2092             }
2093
2094           /* see if this is a GETHBIT operation if yes
2095              then return that */
2096           {
2097             ast *otree = optimizeGetHbit (tree);
2098
2099             if (otree != tree)
2100               return decorateType (otree);
2101           }
2102
2103           TTYPE (tree) =
2104             computeType (LTYPE (tree), RTYPE (tree));
2105           TETYPE (tree) = getSpec (TTYPE (tree));
2106
2107           LRVAL (tree) = RRVAL (tree) = 1;
2108           return tree;
2109         }
2110
2111       /*------------------------------------------------------------------*/
2112       /*----------------------------*/
2113       /*  address of                */
2114       /*----------------------------*/
2115       p = newLink ();
2116       p->class = DECLARATOR;
2117       /* if bit field then error */
2118       if (IS_BITVAR (tree->left->etype))
2119         {
2120           werror (E_ILLEGAL_ADDR, "address of bit variable");
2121           goto errorTreeReturn;
2122         }
2123
2124       if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2125         {
2126           werror (E_ILLEGAL_ADDR, "address of register variable");
2127           goto errorTreeReturn;
2128         }
2129
2130       if (IS_FUNC (LTYPE (tree)))
2131         {
2132           werror (E_ILLEGAL_ADDR, "address of function");
2133           goto errorTreeReturn;
2134         }
2135
2136       if (IS_LITERAL(LTYPE(tree)))
2137         {
2138           werror (E_ILLEGAL_ADDR, "address of literal");
2139           goto errorTreeReturn;
2140         }
2141
2142      if (LRVAL (tree))
2143         {
2144           werror (E_LVALUE_REQUIRED, "address of");
2145           goto errorTreeReturn;
2146         }
2147       if (SPEC_SCLS (tree->left->etype) == S_CODE)
2148         {
2149           DCL_TYPE (p) = CPOINTER;
2150           DCL_PTR_CONST (p) = port->mem.code_ro;
2151         }
2152       else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2153         DCL_TYPE (p) = FPOINTER;
2154       else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2155         DCL_TYPE (p) = PPOINTER;
2156       else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2157         DCL_TYPE (p) = IPOINTER;
2158       else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2159         DCL_TYPE (p) = EEPPOINTER;
2160       else if (SPEC_OCLS(tree->left->etype))
2161           DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2162       else
2163           DCL_TYPE (p) = POINTER;
2164
2165       if (IS_AST_SYM_VALUE (tree->left))
2166         {
2167           AST_SYMBOL (tree->left)->addrtaken = 1;
2168           AST_SYMBOL (tree->left)->allocreq = 1;
2169         }
2170
2171       p->next = LTYPE (tree);
2172       TTYPE (tree) = p;
2173       TETYPE (tree) = getSpec (TTYPE (tree));
2174       DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2175       DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2176       LLVAL (tree) = 1;
2177       TLVAL (tree) = 1;
2178       return tree;
2179
2180       /*------------------------------------------------------------------*/
2181       /*----------------------------*/
2182       /*  bitwise or                */
2183       /*----------------------------*/
2184     case '|':
2185       /* if the rewrite succeeds then don't go any furthur */
2186       {
2187         ast *wtree = optimizeRRCRLC (tree);
2188         if (wtree != tree)
2189           return decorateType (wtree);
2190       }
2191       /*------------------------------------------------------------------*/
2192       /*----------------------------*/
2193       /*  bitwise xor               */
2194       /*----------------------------*/
2195     case '^':
2196       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2197         {
2198           werror (E_BITWISE_OP);
2199           werror (W_CONTINUE, "left & right types are ");
2200           printTypeChain (LTYPE (tree), stderr);
2201           fprintf (stderr, ",");
2202           printTypeChain (RTYPE (tree), stderr);
2203           fprintf (stderr, "\n");
2204           goto errorTreeReturn;
2205         }
2206
2207       /* if they are both literal then */
2208       /* rewrite the tree */
2209       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2210         {
2211           tree->type = EX_VALUE;
2212           tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2213                                         valFromType (RETYPE (tree)),
2214                                         tree->opval.op);
2215           tree->right = tree->left = NULL;
2216           TETYPE (tree) = tree->opval.val->etype;
2217           TTYPE (tree) = tree->opval.val->type;
2218           return tree;
2219         }
2220       LRVAL (tree) = RRVAL (tree) = 1;
2221       TETYPE (tree) = getSpec (TTYPE (tree) =
2222                                computeType (LTYPE (tree),
2223                                             RTYPE (tree)));
2224
2225       /*------------------------------------------------------------------*/
2226       /*----------------------------*/
2227       /*  division                  */
2228       /*----------------------------*/
2229     case '/':
2230       if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2231         {
2232           werror (E_INVALID_OP, "divide");
2233           goto errorTreeReturn;
2234         }
2235       /* if they are both literal then */
2236       /* rewrite the tree */
2237       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2238         {
2239           tree->type = EX_VALUE;
2240           tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2241                                     valFromType (RETYPE (tree)));
2242           tree->right = tree->left = NULL;
2243           TETYPE (tree) = getSpec (TTYPE (tree) =
2244                                    tree->opval.val->type);
2245           return tree;
2246         }
2247       LRVAL (tree) = RRVAL (tree) = 1;
2248       TETYPE (tree) = getSpec (TTYPE (tree) =
2249                                computeType (LTYPE (tree),
2250                                             RTYPE (tree)));
2251       return tree;
2252
2253       /*------------------------------------------------------------------*/
2254       /*----------------------------*/
2255       /*            modulus         */
2256       /*----------------------------*/
2257     case '%':
2258       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2259         {
2260           werror (E_BITWISE_OP);
2261           werror (W_CONTINUE, "left & right types are ");
2262           printTypeChain (LTYPE (tree), stderr);
2263           fprintf (stderr, ",");
2264           printTypeChain (RTYPE (tree), stderr);
2265           fprintf (stderr, "\n");
2266           goto errorTreeReturn;
2267         }
2268       /* if they are both literal then */
2269       /* rewrite the tree */
2270       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2271         {
2272           tree->type = EX_VALUE;
2273           tree->opval.val = valMod (valFromType (LETYPE (tree)),
2274                                     valFromType (RETYPE (tree)));
2275           tree->right = tree->left = NULL;
2276           TETYPE (tree) = getSpec (TTYPE (tree) =
2277                                    tree->opval.val->type);
2278           return tree;
2279         }
2280       LRVAL (tree) = RRVAL (tree) = 1;
2281       TETYPE (tree) = getSpec (TTYPE (tree) =
2282                                computeType (LTYPE (tree),
2283                                             RTYPE (tree)));
2284       return tree;
2285
2286       /*------------------------------------------------------------------*/
2287       /*----------------------------*/
2288       /*  address dereference       */
2289       /*----------------------------*/
2290     case '*':                   /* can be unary  : if right is null then unary operation */
2291       if (!tree->right)
2292         {
2293           if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2294             {
2295               werror (E_PTR_REQD);
2296               goto errorTreeReturn;
2297             }
2298
2299           if (LRVAL (tree))
2300             {
2301               werror (E_LVALUE_REQUIRED, "pointer deref");
2302               goto errorTreeReturn;
2303             }
2304           TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2305                                         LTYPE (tree)->next : NULL);
2306           TETYPE (tree) = getSpec (TTYPE (tree));
2307           SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2308           return tree;
2309         }
2310
2311       /*------------------------------------------------------------------*/
2312       /*----------------------------*/
2313       /*      multiplication        */
2314       /*----------------------------*/
2315       if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2316         {
2317           werror (E_INVALID_OP, "multiplication");
2318           goto errorTreeReturn;
2319         }
2320
2321       /* if they are both literal then */
2322       /* rewrite the tree */
2323       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2324         {
2325           tree->type = EX_VALUE;
2326           tree->opval.val = valMult (valFromType (LETYPE (tree)),
2327                                      valFromType (RETYPE (tree)));
2328           tree->right = tree->left = NULL;
2329           TETYPE (tree) = getSpec (TTYPE (tree) =
2330                                    tree->opval.val->type);
2331           return tree;
2332         }
2333
2334       /* if left is a literal exchange left & right */
2335       if (IS_LITERAL (LTYPE (tree)))
2336         {
2337           ast *tTree = tree->left;
2338           tree->left = tree->right;
2339           tree->right = tTree;
2340         }
2341
2342       LRVAL (tree) = RRVAL (tree) = 1;
2343       /* promote result to int if left & right are char
2344          this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2345       if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2346         TETYPE (tree) = getSpec (TTYPE (tree) =
2347                                  computeType (LTYPE (tree),
2348                                               RTYPE (tree)));
2349         SPEC_NOUN(TETYPE(tree)) = V_INT;
2350       } else {
2351         TETYPE (tree) = getSpec (TTYPE (tree) =
2352                                  computeType (LTYPE (tree),
2353                                               RTYPE (tree)));
2354       }
2355       return tree;
2356
2357       /*------------------------------------------------------------------*/
2358       /*----------------------------*/
2359       /*    unary '+' operator      */
2360       /*----------------------------*/
2361     case '+':
2362       /* if unary plus */
2363       if (!tree->right)
2364         {
2365           if (!IS_INTEGRAL (LTYPE (tree)))
2366             {
2367               werror (E_UNARY_OP, '+');
2368               goto errorTreeReturn;
2369             }
2370
2371           /* if left is a literal then do it */
2372           if (IS_LITERAL (LTYPE (tree)))
2373             {
2374               tree->type = EX_VALUE;
2375               tree->opval.val = valFromType (LETYPE (tree));
2376               tree->left = NULL;
2377               TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2378               return tree;
2379             }
2380           LRVAL (tree) = 1;
2381           COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2382           return tree;
2383         }
2384
2385       /*------------------------------------------------------------------*/
2386       /*----------------------------*/
2387       /*      addition              */
2388       /*----------------------------*/
2389
2390       /* this is not a unary operation */
2391       /* if both pointers then problem */
2392       if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2393           (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2394         {
2395           werror (E_PTR_PLUS_PTR);
2396           goto errorTreeReturn;
2397         }
2398
2399       if (!IS_ARITHMETIC (LTYPE (tree)) &&
2400           !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2401         {
2402           werror (E_PLUS_INVALID, "+");
2403           goto errorTreeReturn;
2404         }
2405
2406       if (!IS_ARITHMETIC (RTYPE (tree)) &&
2407           !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2408         {
2409           werror (E_PLUS_INVALID, "+");
2410           goto errorTreeReturn;
2411         }
2412       /* if they are both literal then */
2413       /* rewrite the tree */
2414       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2415         {
2416           tree->type = EX_VALUE;
2417           tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2418                                      valFromType (RETYPE (tree)));
2419           tree->right = tree->left = NULL;
2420           TETYPE (tree) = getSpec (TTYPE (tree) =
2421                                    tree->opval.val->type);
2422           return tree;
2423         }
2424
2425       /* if the right is a pointer or left is a literal
2426          xchange left & right */
2427       if (IS_ARRAY (RTYPE (tree)) ||
2428           IS_PTR (RTYPE (tree)) ||
2429           IS_LITERAL (LTYPE (tree)))
2430         {
2431           ast *tTree = tree->left;
2432           tree->left = tree->right;
2433           tree->right = tTree;
2434         }
2435
2436       LRVAL (tree) = RRVAL (tree) = 1;
2437       /* if the left is a pointer */
2438       if (IS_PTR (LTYPE (tree)))
2439         TETYPE (tree) = getSpec (TTYPE (tree) =
2440                                  LTYPE (tree));
2441       else
2442         TETYPE (tree) = getSpec (TTYPE (tree) =
2443                                  computeType (LTYPE (tree),
2444                                               RTYPE (tree)));
2445       return tree;
2446
2447       /*------------------------------------------------------------------*/
2448       /*----------------------------*/
2449       /*      unary '-'             */
2450       /*----------------------------*/
2451     case '-':                   /* can be unary   */
2452       /* if right is null then unary */
2453       if (!tree->right)
2454         {
2455
2456           if (!IS_ARITHMETIC (LTYPE (tree)))
2457             {
2458               werror (E_UNARY_OP, tree->opval.op);
2459               goto errorTreeReturn;
2460             }
2461
2462           /* if left is a literal then do it */
2463           if (IS_LITERAL (LTYPE (tree)))
2464             {
2465               tree->type = EX_VALUE;
2466               tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2467               tree->left = NULL;
2468               TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2469               SPEC_USIGN(TETYPE(tree)) = 0;
2470               return tree;
2471             }
2472           LRVAL (tree) = 1;
2473           TTYPE (tree) = LTYPE (tree);
2474           return tree;
2475         }
2476
2477       /*------------------------------------------------------------------*/
2478       /*----------------------------*/
2479       /*    subtraction             */
2480       /*----------------------------*/
2481
2482       if (!(IS_PTR (LTYPE (tree)) ||
2483             IS_ARRAY (LTYPE (tree)) ||
2484             IS_ARITHMETIC (LTYPE (tree))))
2485         {
2486           werror (E_PLUS_INVALID, "-");
2487           goto errorTreeReturn;
2488         }
2489
2490       if (!(IS_PTR (RTYPE (tree)) ||
2491             IS_ARRAY (RTYPE (tree)) ||
2492             IS_ARITHMETIC (RTYPE (tree))))
2493         {
2494           werror (E_PLUS_INVALID, "-");
2495           goto errorTreeReturn;
2496         }
2497
2498       if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2499           !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2500             IS_INTEGRAL (RTYPE (tree))))
2501         {
2502           werror (E_PLUS_INVALID, "-");
2503           goto errorTreeReturn;
2504         }
2505
2506       /* if they are both literal then */
2507       /* rewrite the tree */
2508       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2509         {
2510           tree->type = EX_VALUE;
2511           tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2512                                       valFromType (RETYPE (tree)));
2513           tree->right = tree->left = NULL;
2514           TETYPE (tree) = getSpec (TTYPE (tree) =
2515                                    tree->opval.val->type);
2516           return tree;
2517         }
2518
2519       /* if the left & right are equal then zero */
2520       if (isAstEqual (tree->left, tree->right))
2521         {
2522           tree->type = EX_VALUE;
2523           tree->left = tree->right = NULL;
2524           tree->opval.val = constVal ("0");
2525           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2526           return tree;
2527         }
2528
2529       /* if both of them are pointers or arrays then */
2530       /* the result is going to be an integer        */
2531       if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2532           (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2533         TETYPE (tree) = TTYPE (tree) = newIntLink ();
2534       else
2535         /* if only the left is a pointer */
2536         /* then result is a pointer      */
2537       if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2538         TETYPE (tree) = getSpec (TTYPE (tree) =
2539                                  LTYPE (tree));
2540       else
2541         TETYPE (tree) = getSpec (TTYPE (tree) =
2542                                  computeType (LTYPE (tree),
2543                                               RTYPE (tree)));
2544       LRVAL (tree) = RRVAL (tree) = 1;
2545       return tree;
2546
2547       /*------------------------------------------------------------------*/
2548       /*----------------------------*/
2549       /*    compliment              */
2550       /*----------------------------*/
2551     case '~':
2552       /* can be only integral type */
2553       if (!IS_INTEGRAL (LTYPE (tree)))
2554         {
2555           werror (E_UNARY_OP, tree->opval.op);
2556           goto errorTreeReturn;
2557         }
2558
2559       /* if left is a literal then do it */
2560       if (IS_LITERAL (LTYPE (tree)))
2561         {
2562           tree->type = EX_VALUE;
2563           tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2564           tree->left = NULL;
2565           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2566           return tree;
2567         }
2568       LRVAL (tree) = 1;
2569       COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2570       return tree;
2571
2572       /*------------------------------------------------------------------*/
2573       /*----------------------------*/
2574       /*           not              */
2575       /*----------------------------*/
2576     case '!':
2577       /* can be pointer */
2578       if (!IS_ARITHMETIC (LTYPE (tree)) &&
2579           !IS_PTR (LTYPE (tree)) &&
2580           !IS_ARRAY (LTYPE (tree)))
2581         {
2582           werror (E_UNARY_OP, tree->opval.op);
2583           goto errorTreeReturn;
2584         }
2585
2586       /* if left is a literal then do it */
2587       if (IS_LITERAL (LTYPE (tree)))
2588         {
2589           tree->type = EX_VALUE;
2590           tree->opval.val = valNot (valFromType (LETYPE (tree)));
2591           tree->left = NULL;
2592           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2593           return tree;
2594         }
2595       LRVAL (tree) = 1;
2596       TTYPE (tree) = TETYPE (tree) = newCharLink ();
2597       return tree;
2598
2599       /*------------------------------------------------------------------*/
2600       /*----------------------------*/
2601       /*           shift            */
2602       /*----------------------------*/
2603     case RRC:
2604     case RLC:
2605       TTYPE (tree) = LTYPE (tree);
2606       TETYPE (tree) = LETYPE (tree);
2607       return tree;
2608
2609     case GETHBIT:
2610       TTYPE (tree) = TETYPE (tree) = newCharLink ();
2611       return tree;
2612
2613     case LEFT_OP:
2614     case RIGHT_OP:
2615       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2616         {
2617           werror (E_SHIFT_OP_INVALID);
2618           werror (W_CONTINUE, "left & right types are ");
2619           printTypeChain (LTYPE (tree), stderr);
2620           fprintf (stderr, ",");
2621           printTypeChain (RTYPE (tree), stderr);
2622           fprintf (stderr, "\n");
2623           goto errorTreeReturn;
2624         }
2625
2626       /* if they are both literal then */
2627       /* rewrite the tree */
2628       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2629         {
2630           tree->type = EX_VALUE;
2631           tree->opval.val = valShift (valFromType (LETYPE (tree)),
2632                                       valFromType (RETYPE (tree)),
2633                                       (tree->opval.op == LEFT_OP ? 1 : 0));
2634           tree->right = tree->left = NULL;
2635           TETYPE (tree) = getSpec (TTYPE (tree) =
2636                                    tree->opval.val->type);
2637           return tree;
2638         }
2639       /* if only the right side is a literal & we are
2640          shifting more than size of the left operand then zero */
2641       if (IS_LITERAL (RTYPE (tree)) &&
2642           ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2643           (getSize (LTYPE (tree)) * 8))
2644         {
2645           werror (W_SHIFT_CHANGED,
2646                   (tree->opval.op == LEFT_OP ? "left" : "right"));
2647           tree->type = EX_VALUE;
2648           tree->left = tree->right = NULL;
2649           tree->opval.val = constVal ("0");
2650           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2651           return tree;
2652         }
2653       LRVAL (tree) = RRVAL (tree) = 1;
2654       if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2655         {
2656           COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2657         }
2658       else
2659         {
2660           COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2661         }
2662       return tree;
2663
2664       /*------------------------------------------------------------------*/
2665       /*----------------------------*/
2666       /*         casting            */
2667       /*----------------------------*/
2668     case CAST:                  /* change the type   */
2669       /* cannot cast to an aggregate type */
2670       if (IS_AGGREGATE (LTYPE (tree)))
2671         {
2672           werror (E_CAST_ILLEGAL);
2673           goto errorTreeReturn;
2674         }
2675       
2676       /* make sure the type is complete and sane */
2677       checkTypeSanity(LETYPE(tree), "(cast)");
2678
2679 #if 0
2680       /* if the right is a literal replace the tree */
2681       if (IS_LITERAL (RETYPE (tree))) {
2682               if (!IS_PTR (LTYPE (tree))) {
2683                       tree->type = EX_VALUE;
2684                       tree->opval.val =
2685                               valCastLiteral (LTYPE (tree),
2686                                               floatFromVal (valFromType (RETYPE (tree))));
2687                       tree->left = NULL;
2688                       tree->right = NULL;
2689                       TTYPE (tree) = tree->opval.val->type;
2690                       tree->values.literalFromCast = 1;
2691               } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) && 
2692                          ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */  {
2693                       sym_link *rest = LTYPE(tree)->next;
2694                       werror(W_LITERAL_GENERIC);                      
2695                       TTYPE(tree) = newLink();
2696                       DCL_TYPE(TTYPE(tree)) = FPOINTER;
2697                       TTYPE(tree)->next = rest;
2698                       tree->left->opval.lnk = TTYPE(tree);
2699                       LRVAL (tree) = 1;
2700               } else {
2701                       TTYPE (tree) = LTYPE (tree);
2702                       LRVAL (tree) = 1;
2703               }
2704       } else {
2705               TTYPE (tree) = LTYPE (tree);
2706               LRVAL (tree) = 1;
2707       }
2708 #else
2709       /* if pointer to struct then check names */
2710       if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2711           IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2712           strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) {
2713               werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag);
2714       }
2715       /* if the right is a literal replace the tree */
2716       if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2717         tree->type = EX_VALUE;
2718         tree->opval.val =
2719           valCastLiteral (LTYPE (tree),
2720                           floatFromVal (valFromType (RETYPE (tree))));
2721         tree->left = NULL;
2722         tree->right = NULL;
2723         TTYPE (tree) = tree->opval.val->type;
2724         tree->values.literalFromCast = 1;
2725       } else {
2726         TTYPE (tree) = LTYPE (tree);
2727         LRVAL (tree) = 1;
2728       }
2729 #endif      
2730       TETYPE (tree) = getSpec (TTYPE (tree));
2731
2732       return tree;
2733
2734       /*------------------------------------------------------------------*/
2735       /*----------------------------*/
2736       /*       logical &&, ||       */
2737       /*----------------------------*/
2738     case AND_OP:
2739     case OR_OP:
2740       /* each must me arithmetic type or be a pointer */
2741       if (!IS_PTR (LTYPE (tree)) &&
2742           !IS_ARRAY (LTYPE (tree)) &&
2743           !IS_INTEGRAL (LTYPE (tree)))
2744         {
2745           werror (E_COMPARE_OP);
2746           goto errorTreeReturn;
2747         }
2748
2749       if (!IS_PTR (RTYPE (tree)) &&
2750           !IS_ARRAY (RTYPE (tree)) &&
2751           !IS_INTEGRAL (RTYPE (tree)))
2752         {
2753           werror (E_COMPARE_OP);
2754           goto errorTreeReturn;
2755         }
2756       /* if they are both literal then */
2757       /* rewrite the tree */
2758       if (IS_LITERAL (RTYPE (tree)) &&
2759           IS_LITERAL (LTYPE (tree)))
2760         {
2761           tree->type = EX_VALUE;
2762           tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2763                                            valFromType (RETYPE (tree)),
2764                                            tree->opval.op);
2765           tree->right = tree->left = NULL;
2766           TETYPE (tree) = getSpec (TTYPE (tree) =
2767                                    tree->opval.val->type);
2768           return tree;
2769         }
2770       LRVAL (tree) = RRVAL (tree) = 1;
2771       TTYPE (tree) = TETYPE (tree) = newCharLink ();
2772       return tree;
2773
2774       /*------------------------------------------------------------------*/
2775       /*----------------------------*/
2776       /*     comparison operators   */
2777       /*----------------------------*/
2778     case '>':
2779     case '<':
2780     case LE_OP:
2781     case GE_OP:
2782     case EQ_OP:
2783     case NE_OP:
2784       {
2785         ast *lt = optimizeCompare (tree);
2786
2787         if (tree != lt)
2788           return lt;
2789       }
2790
2791       /* if they are pointers they must be castable */
2792       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2793         {
2794           if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2795             {
2796               werror (E_COMPARE_OP);
2797               fprintf (stderr, "comparing type ");
2798               printTypeChain (LTYPE (tree), stderr);
2799               fprintf (stderr, "to type ");
2800               printTypeChain (RTYPE (tree), stderr);
2801               fprintf (stderr, "\n");
2802               goto errorTreeReturn;
2803             }
2804         }
2805       /* else they should be promotable to one another */
2806       else
2807         {
2808           if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2809                 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2810
2811             if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2812               {
2813                 werror (E_COMPARE_OP);
2814                 fprintf (stderr, "comparing type ");
2815                 printTypeChain (LTYPE (tree), stderr);
2816                 fprintf (stderr, "to type ");
2817                 printTypeChain (RTYPE (tree), stderr);
2818                 fprintf (stderr, "\n");
2819                 goto errorTreeReturn;
2820               }
2821         }
2822       /* if unsigned value < 0  then always false */
2823       /* if (unsigned value) > 0 then (unsigned value) */
2824       if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) && 
2825           ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2826
2827           if (tree->opval.op == '<') {
2828               return tree->right;
2829           }
2830           if (tree->opval.op == '>') {
2831               return tree->left;
2832           }
2833       }
2834       /* if they are both literal then */
2835       /* rewrite the tree */
2836       if (IS_LITERAL (RTYPE (tree)) &&
2837           IS_LITERAL (LTYPE (tree)))
2838         {
2839           tree->type = EX_VALUE;
2840           tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2841                                         valFromType (RETYPE (tree)),
2842                                         tree->opval.op);
2843           tree->right = tree->left = NULL;
2844           TETYPE (tree) = getSpec (TTYPE (tree) =
2845                                    tree->opval.val->type);
2846           return tree;
2847         }
2848       LRVAL (tree) = RRVAL (tree) = 1;
2849       TTYPE (tree) = TETYPE (tree) = newCharLink ();
2850       return tree;
2851
2852       /*------------------------------------------------------------------*/
2853       /*----------------------------*/
2854       /*             sizeof         */
2855       /*----------------------------*/
2856     case SIZEOF:                /* evaluate wihout code generation */
2857       /* change the type to a integer */
2858       tree->type = EX_VALUE;
2859       sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2860       tree->opval.val = constVal (buffer);
2861       tree->right = tree->left = NULL;
2862       TETYPE (tree) = getSpec (TTYPE (tree) =
2863                                tree->opval.val->type);
2864       return tree;
2865
2866       /*------------------------------------------------------------------*/
2867       /*----------------------------*/
2868       /*             typeof         */
2869       /*----------------------------*/
2870     case TYPEOF:
2871         /* return typeof enum value */
2872         tree->type = EX_VALUE;
2873         {
2874             int typeofv = 0;
2875             if (IS_SPEC(tree->right->ftype)) {
2876                 switch (SPEC_NOUN(tree->right->ftype)) {
2877                 case V_INT:
2878                     if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2879                     else typeofv = TYPEOF_INT;
2880                     break;
2881                 case V_FLOAT:
2882                     typeofv = TYPEOF_FLOAT;
2883                     break;
2884                 case V_CHAR:
2885                     typeofv = TYPEOF_CHAR;
2886                     break;
2887                 case V_VOID:
2888                     typeofv = TYPEOF_VOID;
2889                     break;
2890                 case V_STRUCT:
2891                     typeofv = TYPEOF_STRUCT;
2892                     break;
2893                 case V_BIT:
2894                     typeofv = TYPEOF_BIT;
2895                     break;
2896                 case V_SBIT:
2897                     typeofv = TYPEOF_SBIT;
2898                     break;
2899                 default:
2900                     break;
2901                 }
2902             } else {
2903                 switch (DCL_TYPE(tree->right->ftype)) {
2904                 case POINTER:
2905                     typeofv = TYPEOF_POINTER;
2906                     break;
2907                 case FPOINTER:
2908                     typeofv = TYPEOF_FPOINTER;
2909                     break;
2910                 case CPOINTER:
2911                     typeofv = TYPEOF_CPOINTER;
2912                     break;
2913                 case GPOINTER:
2914                     typeofv = TYPEOF_GPOINTER;
2915                     break;
2916                 case PPOINTER:
2917                     typeofv = TYPEOF_PPOINTER;
2918                     break;
2919                 case IPOINTER:
2920                     typeofv = TYPEOF_IPOINTER;
2921                     break;
2922                 case ARRAY:
2923                     typeofv = TYPEOF_ARRAY;
2924                     break;
2925                 case FUNCTION:
2926                     typeofv = TYPEOF_FUNCTION;
2927                     break;
2928                 default:
2929                     break;
2930                 }
2931             }
2932             sprintf (buffer, "%d", typeofv);
2933             tree->opval.val = constVal (buffer);
2934             tree->right = tree->left = NULL;
2935             TETYPE (tree) = getSpec (TTYPE (tree) =
2936                                      tree->opval.val->type);
2937         }
2938         return tree;
2939       /*------------------------------------------------------------------*/
2940       /*----------------------------*/
2941       /* conditional operator  '?'  */
2942       /*----------------------------*/
2943     case '?':
2944       /* the type is value of the colon operator (on the right) */
2945       assert(IS_COLON_OP(tree->right));
2946       /* if already known then replace the tree : optimizer will do it
2947          but faster to do it here */
2948       if (IS_LITERAL (LTYPE(tree))) {     
2949           if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2950               return decorateType(tree->right->left) ;
2951           } else {
2952               return decorateType(tree->right->right) ;
2953           }
2954       } else {
2955           tree->right = decorateType(tree->right);
2956           TTYPE (tree) = RTYPE(tree);
2957           TETYPE (tree) = getSpec (TTYPE (tree));
2958       }
2959       return tree;
2960
2961     case ':':
2962       /* if they don't match we have a problem */
2963       if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2964         {
2965           werror (E_TYPE_MISMATCH, "conditional operator", " ");
2966           goto errorTreeReturn;
2967         }
2968
2969       TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2970       TETYPE (tree) = getSpec (TTYPE (tree));
2971       return tree;
2972
2973
2974 #if 0 // assignment operators are converted by the parser
2975       /*------------------------------------------------------------------*/
2976       /*----------------------------*/
2977       /*    assignment operators    */
2978       /*----------------------------*/
2979     case MUL_ASSIGN:
2980     case DIV_ASSIGN:
2981       /* for these it must be both must be integral */
2982       if (!IS_ARITHMETIC (LTYPE (tree)) ||
2983           !IS_ARITHMETIC (RTYPE (tree)))
2984         {
2985           werror (E_OPS_INTEGRAL);
2986           goto errorTreeReturn;
2987         }
2988       RRVAL (tree) = 1;
2989       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2990
2991       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2992         werror (E_CODE_WRITE, " ");
2993
2994       if (LRVAL (tree))
2995         {
2996           werror (E_LVALUE_REQUIRED, "*= or /=");
2997           goto errorTreeReturn;
2998         }
2999       LLVAL (tree) = 1;
3000
3001       return tree;
3002
3003     case AND_ASSIGN:
3004     case OR_ASSIGN:
3005     case XOR_ASSIGN:
3006     case RIGHT_ASSIGN:
3007     case LEFT_ASSIGN:
3008       /* for these it must be both must be integral */
3009       if (!IS_INTEGRAL (LTYPE (tree)) ||
3010           !IS_INTEGRAL (RTYPE (tree)))
3011         {
3012           werror (E_OPS_INTEGRAL);
3013           goto errorTreeReturn;
3014         }
3015       RRVAL (tree) = 1;
3016       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3017
3018       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3019         werror (E_CODE_WRITE, " ");
3020
3021       if (LRVAL (tree))
3022         {
3023           werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3024           goto errorTreeReturn;
3025         }
3026       LLVAL (tree) = 1;
3027
3028       return tree;
3029
3030       /*------------------------------------------------------------------*/
3031       /*----------------------------*/
3032       /*    -= operator             */
3033       /*----------------------------*/
3034     case SUB_ASSIGN:
3035       if (!(IS_PTR (LTYPE (tree)) ||
3036             IS_ARITHMETIC (LTYPE (tree))))
3037         {
3038           werror (E_PLUS_INVALID, "-=");
3039           goto errorTreeReturn;
3040         }
3041
3042       if (!(IS_PTR (RTYPE (tree)) ||
3043             IS_ARITHMETIC (RTYPE (tree))))
3044         {
3045           werror (E_PLUS_INVALID, "-=");
3046           goto errorTreeReturn;
3047         }
3048       RRVAL (tree) = 1;
3049       TETYPE (tree) = getSpec (TTYPE (tree) =
3050                                computeType (LTYPE (tree),
3051                                             RTYPE (tree)));
3052
3053       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3054         werror (E_CODE_WRITE, " ");
3055
3056       if (LRVAL (tree))
3057         {
3058           werror (E_LVALUE_REQUIRED, "-=");
3059           goto errorTreeReturn;
3060         }
3061       LLVAL (tree) = 1;
3062
3063       return tree;
3064
3065       /*------------------------------------------------------------------*/
3066       /*----------------------------*/
3067       /*          += operator       */
3068       /*----------------------------*/
3069     case ADD_ASSIGN:
3070       /* this is not a unary operation */
3071       /* if both pointers then problem */
3072       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3073         {
3074           werror (E_PTR_PLUS_PTR);
3075           goto errorTreeReturn;
3076         }
3077
3078       if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3079         {
3080           werror (E_PLUS_INVALID, "+=");
3081           goto errorTreeReturn;
3082         }
3083
3084       if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3085         {
3086           werror (E_PLUS_INVALID, "+=");
3087           goto errorTreeReturn;
3088         }
3089       RRVAL (tree) = 1;
3090       TETYPE (tree) = getSpec (TTYPE (tree) =
3091                                computeType (LTYPE (tree),
3092                                             RTYPE (tree)));
3093
3094       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3095         werror (E_CODE_WRITE, " ");
3096
3097       if (LRVAL (tree))
3098         {
3099           werror (E_LVALUE_REQUIRED, "+=");
3100           goto errorTreeReturn;
3101         }
3102
3103       tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3104       tree->opval.op = '=';
3105
3106       return tree;
3107 #endif
3108
3109       /*------------------------------------------------------------------*/
3110       /*----------------------------*/
3111       /*      straight assignemnt   */
3112       /*----------------------------*/
3113     case '=':
3114       /* cannot be an aggregate */
3115       if (IS_AGGREGATE (LTYPE (tree)))
3116         {
3117           werror (E_AGGR_ASSIGN);
3118           goto errorTreeReturn;
3119         }
3120
3121       /* they should either match or be castable */
3122       if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3123         {
3124           werror (E_TYPE_MISMATCH, "assignment", " ");
3125           printFromToType(RTYPE(tree),LTYPE(tree));
3126           //goto errorTreeReturn;
3127         }
3128
3129       /* if the left side of the tree is of type void
3130          then report error */
3131       if (IS_VOID (LTYPE (tree)))
3132         {
3133           werror (E_CAST_ZERO);
3134           printFromToType(RTYPE(tree), LTYPE(tree));
3135         }
3136
3137       TETYPE (tree) = getSpec (TTYPE (tree) =
3138                                LTYPE (tree));
3139       RRVAL (tree) = 1;
3140       LLVAL (tree) = 1;
3141       if (!tree->initMode ) {
3142         if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3143           werror (E_CODE_WRITE, " ");
3144       }
3145       if (LRVAL (tree))
3146         {
3147           werror (E_LVALUE_REQUIRED, "=");
3148           goto errorTreeReturn;
3149         }
3150
3151       return tree;
3152
3153       /*------------------------------------------------------------------*/
3154       /*----------------------------*/
3155       /*      comma operator        */
3156       /*----------------------------*/
3157     case ',':
3158       TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3159       return tree;
3160
3161       /*------------------------------------------------------------------*/
3162       /*----------------------------*/
3163       /*       function call        */
3164       /*----------------------------*/
3165     case CALL:
3166       parmNumber = 1;
3167
3168       if (processParms (tree->left,
3169                         FUNC_ARGS(tree->left->ftype),
3170                         tree->right, &parmNumber, TRUE)) {
3171         goto errorTreeReturn;
3172       }
3173
3174       if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) && 
3175           !IFFUNC_ISBUILTIN(LTYPE(tree)))
3176         {
3177           //FUNC_ARGS(tree->left->ftype) = 
3178           //reverseVal (FUNC_ARGS(tree->left->ftype));
3179           reverseParms (tree->right);
3180         }
3181
3182       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3183       return tree;
3184
3185       /*------------------------------------------------------------------*/
3186       /*----------------------------*/
3187       /*     return statement       */
3188       /*----------------------------*/
3189     case RETURN:
3190       if (!tree->right)
3191         goto voidcheck;
3192
3193       if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3194         {
3195           werror (W_RETURN_MISMATCH);
3196           printFromToType (RTYPE(tree), currFunc->type->next);
3197           goto errorTreeReturn;
3198         }
3199
3200       if (IS_VOID (currFunc->type->next)
3201           && tree->right &&
3202           !IS_VOID (RTYPE (tree)))
3203         {
3204           werror (E_FUNC_VOID);
3205           goto errorTreeReturn;
3206         }
3207
3208       /* if there is going to be a casing required then add it */
3209       if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3210         {
3211           tree->right =
3212             decorateType (newNode (CAST,
3213                            newAst_LINK (copyLinkChain (currFunc->type->next)),
3214                                    tree->right));
3215         }
3216
3217       RRVAL (tree) = 1;
3218       return tree;
3219
3220     voidcheck:
3221
3222       if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3223         {
3224           werror (E_VOID_FUNC, currFunc->name);
3225           goto errorTreeReturn;
3226         }
3227
3228       TTYPE (tree) = TETYPE (tree) = NULL;
3229       return tree;
3230
3231       /*------------------------------------------------------------------*/
3232       /*----------------------------*/
3233       /*     switch statement       */
3234       /*----------------------------*/
3235     case SWITCH:
3236       /* the switch value must be an integer */
3237       if (!IS_INTEGRAL (LTYPE (tree)))
3238         {
3239           werror (E_SWITCH_NON_INTEGER);
3240           goto errorTreeReturn;
3241         }
3242       LRVAL (tree) = 1;
3243       TTYPE (tree) = TETYPE (tree) = NULL;
3244       return tree;
3245
3246       /*------------------------------------------------------------------*/
3247       /*----------------------------*/
3248       /* ifx Statement              */
3249       /*----------------------------*/
3250     case IFX:
3251       tree->left = backPatchLabels (tree->left,
3252                                     tree->trueLabel,
3253                                     tree->falseLabel);
3254       TTYPE (tree) = TETYPE (tree) = NULL;
3255       return tree;
3256
3257       /*------------------------------------------------------------------*/
3258       /*----------------------------*/
3259       /* for Statement              */
3260       /*----------------------------*/
3261     case FOR:
3262
3263       decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3264       decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3265       decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3266
3267       /* if the for loop is reversible then
3268          reverse it otherwise do what we normally
3269          do */
3270       {
3271         symbol *sym;
3272         ast *init, *end;
3273
3274         if (isLoopReversible (tree, &sym, &init, &end))
3275           return reverseLoop (tree, sym, init, end);
3276         else
3277           return decorateType (createFor (AST_FOR (tree, trueLabel),
3278                                           AST_FOR (tree, continueLabel),
3279                                           AST_FOR (tree, falseLabel),
3280                                           AST_FOR (tree, condLabel),
3281                                           AST_FOR (tree, initExpr),
3282                                           AST_FOR (tree, condExpr),
3283                                           AST_FOR (tree, loopExpr),
3284                                           tree->left));
3285       }
3286     default:
3287       TTYPE (tree) = TETYPE (tree) = NULL;
3288       return tree;
3289     }
3290
3291   /* some error found this tree will be killed */
3292 errorTreeReturn:
3293   TTYPE (tree) = TETYPE (tree) = newCharLink ();
3294   tree->opval.op = NULLOP;
3295   tree->isError = 1;
3296
3297   return tree;
3298 }
3299
3300 /*-----------------------------------------------------------------*/
3301 /* sizeofOp - processes size of operation                          */
3302 /*-----------------------------------------------------------------*/
3303 value *
3304 sizeofOp (sym_link * type)
3305 {
3306   char buff[10];
3307
3308   /* make sure the type is complete and sane */
3309   checkTypeSanity(type, "(sizeof)");
3310
3311   /* get the size and convert it to character  */
3312   sprintf (buff, "%d", getSize (type));
3313
3314   /* now convert into value  */
3315   return constVal (buff);
3316 }
3317
3318
3319 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3320 #define IS_OR(ex)  (ex->type == EX_OP && ex->opval.op == OR_OP )
3321 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3322 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3323 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3324 #define IS_LT(ex)  (ex->type == EX_OP && ex->opval.op == '<' )
3325 #define IS_GT(ex)  (ex->type == EX_OP && ex->opval.op == '>')
3326
3327 /*-----------------------------------------------------------------*/
3328 /* backPatchLabels - change and or not operators to flow control    */
3329 /*-----------------------------------------------------------------*/
3330 ast *
3331 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3332 {
3333
3334   if (!tree)
3335     return NULL;
3336
3337   if (!(IS_ANDORNOT (tree)))
3338     return tree;
3339
3340   /* if this an and */
3341   if (IS_AND (tree))
3342     {
3343       static int localLbl = 0;
3344       symbol *localLabel;
3345
3346       sprintf (buffer, "_and_%d", localLbl++);
3347       localLabel = newSymbol (buffer, NestLevel);
3348
3349       tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3350
3351       /* if left is already a IFX then just change the if true label in that */
3352       if (!IS_IFX (tree->left))
3353         tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3354
3355       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3356       /* right is a IFX then just join */
3357       if (IS_IFX (tree->right))
3358         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3359
3360       tree->right = createLabel (localLabel, tree->right);
3361       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3362
3363       return newNode (NULLOP, tree->left, tree->right);
3364     }
3365
3366   /* if this is an or operation */
3367   if (IS_OR (tree))
3368     {
3369       static int localLbl = 0;
3370       symbol *localLabel;
3371
3372       sprintf (buffer, "_or_%d", localLbl++);
3373       localLabel = newSymbol (buffer, NestLevel);
3374
3375       tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3376
3377       /* if left is already a IFX then just change the if true label in that */
3378       if (!IS_IFX (tree->left))
3379         tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3380
3381       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3382       /* right is a IFX then just join */
3383       if (IS_IFX (tree->right))
3384         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3385
3386       tree->right = createLabel (localLabel, tree->right);
3387       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3388
3389       return newNode (NULLOP, tree->left, tree->right);
3390     }
3391
3392   /* change not */
3393   if (IS_NOT (tree))
3394     {
3395       int wasnot = IS_NOT (tree->left);
3396       tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3397
3398       /* if the left is already a IFX */
3399       if (!IS_IFX (tree->left))
3400         tree->left = newNode (IFX, tree->left, NULL);
3401
3402       if (wasnot)
3403         {
3404           tree->left->trueLabel = trueLabel;
3405           tree->left->falseLabel = falseLabel;
3406         }
3407       else
3408         {
3409           tree->left->trueLabel = falseLabel;
3410           tree->left->falseLabel = trueLabel;
3411         }
3412       return tree->left;
3413     }
3414
3415   if (IS_IFX (tree))
3416     {
3417       tree->trueLabel = trueLabel;
3418       tree->falseLabel = falseLabel;
3419     }
3420
3421   return tree;
3422 }
3423
3424
3425 /*-----------------------------------------------------------------*/
3426 /* createBlock - create expression tree for block                  */
3427 /*-----------------------------------------------------------------*/
3428 ast *
3429 createBlock (symbol * decl, ast * body)
3430 {
3431   ast *ex;
3432
3433   /* if the block has nothing */
3434   if (!body)
3435     return NULL;
3436
3437   ex = newNode (BLOCK, NULL, body);
3438   ex->values.sym = decl;
3439
3440   ex->right = ex->right;
3441   ex->level++;
3442   ex->lineno = 0;
3443   return ex;
3444 }
3445
3446 /*-----------------------------------------------------------------*/
3447 /* createLabel - creates the expression tree for labels            */
3448 /*-----------------------------------------------------------------*/
3449 ast *
3450 createLabel (symbol * label, ast * stmnt)
3451 {
3452   symbol *csym;
3453   char name[SDCC_NAME_MAX + 1];
3454   ast *rValue;
3455
3456   /* must create fresh symbol if the symbol name  */
3457   /* exists in the symbol table, since there can  */
3458   /* be a variable with the same name as the labl */
3459   if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3460       (csym->level == label->level))
3461     label = newSymbol (label->name, label->level);
3462
3463   /* change the name before putting it in add _ */
3464   sprintf (name, "%s", label->name);
3465
3466   /* put the label in the LabelSymbol table    */
3467   /* but first check if a label of the same    */
3468   /* name exists                               */
3469   if ((csym = findSym (LabelTab, NULL, name)))
3470     werror (E_DUPLICATE_LABEL, label->name);
3471   else
3472     addSym (LabelTab, label, name, label->level, 0, 0);
3473
3474   label->islbl = 1;
3475   label->key = labelKey++;
3476   rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3477   rValue->lineno = 0;
3478
3479   return rValue;
3480 }
3481
3482 /*-----------------------------------------------------------------*/
3483 /* createCase - generates the parsetree for a case statement       */
3484 /*-----------------------------------------------------------------*/
3485 ast *
3486 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3487 {
3488   char caseLbl[SDCC_NAME_MAX + 1];
3489   ast *rexpr;
3490   value *val;
3491
3492   /* if the switch statement does not exist */
3493   /* then case is out of context            */
3494   if (!swStat)
3495     {
3496       werror (E_CASE_CONTEXT);
3497       return NULL;
3498     }
3499
3500   caseVal = decorateType (resolveSymbols (caseVal));
3501   /* if not a constant then error  */
3502   if (!IS_LITERAL (caseVal->ftype))
3503     {
3504       werror (E_CASE_CONSTANT);
3505       return NULL;
3506     }
3507
3508   /* if not a integer than error */
3509   if (!IS_INTEGRAL (caseVal->ftype))
3510     {
3511       werror (E_CASE_NON_INTEGER);
3512       return NULL;
3513     }
3514
3515   /* find the end of the switch values chain   */
3516   if (!(val = swStat->values.switchVals.swVals))
3517     swStat->values.switchVals.swVals = caseVal->opval.val;
3518   else
3519     {
3520       /* also order the cases according to value */
3521       value *pval = NULL;
3522       int cVal = (int) floatFromVal (caseVal->opval.val);
3523       while (val && (int) floatFromVal (val) < cVal)
3524         {
3525           pval = val;
3526           val = val->next;
3527         }
3528
3529       /* if we reached the end then */
3530       if (!val)
3531         {
3532           pval->next = caseVal->opval.val;
3533         }
3534       else
3535         {
3536           /* we found a value greater than */
3537           /* the current value we must add this */
3538           /* before the value */
3539           caseVal->opval.val->next = val;
3540
3541           /* if this was the first in chain */
3542           if (swStat->values.switchVals.swVals == val)
3543             swStat->values.switchVals.swVals =
3544               caseVal->opval.val;
3545           else
3546             pval->next = caseVal->opval.val;
3547         }
3548
3549     }
3550
3551   /* create the case label   */
3552   sprintf (caseLbl, "_case_%d_%d",
3553            swStat->values.switchVals.swNum,
3554            (int) floatFromVal (caseVal->opval.val));
3555
3556   rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3557   rexpr->lineno = 0;
3558   return rexpr;
3559 }
3560
3561 /*-----------------------------------------------------------------*/
3562 /* createDefault - creates the parse tree for the default statement */
3563 /*-----------------------------------------------------------------*/
3564 ast *
3565 createDefault (ast * swStat, ast * stmnt)
3566 {
3567   char defLbl[SDCC_NAME_MAX + 1];
3568
3569   /* if the switch statement does not exist */
3570   /* then case is out of context            */
3571   if (!swStat)
3572     {
3573       werror (E_CASE_CONTEXT);
3574       return NULL;
3575     }
3576
3577   /* turn on the default flag   */
3578   swStat->values.switchVals.swDefault = 1;
3579
3580   /* create the label  */
3581   sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3582   return createLabel (newSymbol (defLbl, 0), stmnt);
3583 }
3584
3585 /*-----------------------------------------------------------------*/
3586 /* createIf - creates the parsetree for the if statement           */
3587 /*-----------------------------------------------------------------*/
3588 ast *
3589 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3590 {
3591   static int Lblnum = 0;
3592   ast *ifTree;
3593   symbol *ifTrue, *ifFalse, *ifEnd;
3594
3595   /* if neither exists */
3596   if (!elseBody && !ifBody) {
3597     // if there are no side effects (i++, j() etc)
3598     if (!hasSEFcalls(condAst)) {
3599       return condAst;
3600     }
3601   }
3602
3603   /* create the labels */
3604   sprintf (buffer, "_iffalse_%d", Lblnum);
3605   ifFalse = newSymbol (buffer, NestLevel);
3606   /* if no else body then end == false */
3607   if (!elseBody)
3608     ifEnd = ifFalse;
3609   else
3610     {
3611       sprintf (buffer, "_ifend_%d", Lblnum);
3612       ifEnd = newSymbol (buffer, NestLevel);
3613     }
3614
3615   sprintf (buffer, "_iftrue_%d", Lblnum);
3616   ifTrue = newSymbol (buffer, NestLevel);
3617
3618   Lblnum++;
3619
3620   /* attach the ifTrue label to the top of it body */
3621   ifBody = createLabel (ifTrue, ifBody);
3622   /* attach a goto end to the ifBody if else is present */
3623   if (elseBody)
3624     {
3625       ifBody = newNode (NULLOP, ifBody,
3626                         newNode (GOTO,
3627                                  newAst_VALUE (symbolVal (ifEnd)),
3628                                  NULL));
3629       /* put the elseLabel on the else body */
3630       elseBody = createLabel (ifFalse, elseBody);
3631       /* out the end at the end of the body */
3632       elseBody = newNode (NULLOP,
3633                           elseBody,
3634                           createLabel (ifEnd, NULL));
3635     }
3636   else
3637     {
3638       ifBody = newNode (NULLOP, ifBody,
3639                         createLabel (ifFalse, NULL));
3640     }
3641   condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3642   if (IS_IFX (condAst))
3643     ifTree = condAst;
3644   else
3645     ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3646
3647   return newNode (NULLOP, ifTree,
3648                   newNode (NULLOP, ifBody, elseBody));
3649
3650 }
3651
3652 /*-----------------------------------------------------------------*/
3653 /* createDo - creates parse tree for do                            */
3654 /*        _dobody_n:                                               */
3655 /*            statements                                           */
3656 /*        _docontinue_n:                                           */
3657 /*            condition_expression +-> trueLabel -> _dobody_n      */
3658 /*                                 |                               */
3659 /*                                 +-> falseLabel-> _dobreak_n     */
3660 /*        _dobreak_n:                                              */
3661 /*-----------------------------------------------------------------*/
3662 ast *
3663 createDo (symbol * trueLabel, symbol * continueLabel,
3664           symbol * falseLabel, ast * condAst, ast * doBody)
3665 {
3666   ast *doTree;
3667
3668
3669   /* if the body does not exist then it is simple */
3670   if (!doBody)
3671     {
3672       condAst = backPatchLabels (condAst, continueLabel, NULL);
3673       doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3674                 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3675       doTree->trueLabel = continueLabel;
3676       doTree->falseLabel = NULL;
3677       return doTree;
3678     }
3679
3680   /* otherwise we have a body */
3681   condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3682
3683   /* attach the body label to the top */
3684   doBody = createLabel (trueLabel, doBody);
3685   /* attach the continue label to end of body */
3686   doBody = newNode (NULLOP, doBody,
3687                     createLabel (continueLabel, NULL));
3688
3689   /* now put the break label at the end */
3690   if (IS_IFX (condAst))
3691     doTree = condAst;
3692   else
3693     doTree = newIfxNode (condAst, trueLabel, falseLabel);
3694
3695   doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3696
3697   /* putting it together */
3698   return newNode (NULLOP, doBody, doTree);
3699 }
3700
3701 /*-----------------------------------------------------------------*/
3702 /* createFor - creates parse tree for 'for' statement              */
3703 /*        initExpr                                                 */
3704 /*   _forcond_n:                                                   */
3705 /*        condExpr  +-> trueLabel -> _forbody_n                    */
3706 /*                  |                                              */
3707 /*                  +-> falseLabel-> _forbreak_n                   */
3708 /*   _forbody_n:                                                   */
3709 /*        statements                                               */
3710 /*   _forcontinue_n:                                               */
3711 /*        loopExpr                                                 */
3712 /*        goto _forcond_n ;                                        */
3713 /*   _forbreak_n:                                                  */
3714 /*-----------------------------------------------------------------*/
3715 ast *
3716 createFor (symbol * trueLabel, symbol * continueLabel,
3717            symbol * falseLabel, symbol * condLabel,
3718            ast * initExpr, ast * condExpr, ast * loopExpr,
3719            ast * forBody)
3720 {
3721   ast *forTree;
3722
3723   /* if loopexpression not present then we can generate it */
3724   /* the same way as a while */
3725   if (!loopExpr)
3726     return newNode (NULLOP, initExpr,
3727                     createWhile (trueLabel, continueLabel,
3728                                  falseLabel, condExpr, forBody));
3729   /* vanilla for statement */
3730   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3731
3732   if (condExpr && !IS_IFX (condExpr))
3733     condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3734
3735
3736   /* attach condition label to condition */
3737   condExpr = createLabel (condLabel, condExpr);
3738
3739   /* attach body label to body */
3740   forBody = createLabel (trueLabel, forBody);
3741
3742   /* attach continue to forLoop expression & attach */
3743   /* goto the forcond @ and of loopExpression       */
3744   loopExpr = createLabel (continueLabel,
3745                           newNode (NULLOP,
3746                                    loopExpr,
3747                                    newNode (GOTO,
3748                                        newAst_VALUE (symbolVal (condLabel)),
3749                                             NULL)));
3750   /* now start putting them together */
3751   forTree = newNode (NULLOP, initExpr, condExpr);
3752   forTree = newNode (NULLOP, forTree, forBody);
3753   forTree = newNode (NULLOP, forTree, loopExpr);
3754   /* finally add the break label */
3755   forTree = newNode (NULLOP, forTree,
3756                      createLabel (falseLabel, NULL));
3757   return forTree;
3758 }
3759
3760 /*-----------------------------------------------------------------*/
3761 /* createWhile - creates parse tree for while statement            */
3762 /*               the while statement will be created as follows    */
3763 /*                                                                 */
3764 /*      _while_continue_n:                                         */
3765 /*            condition_expression +-> trueLabel -> _while_boby_n  */
3766 /*                                 |                               */
3767 /*                                 +-> falseLabel -> _while_break_n */
3768 /*      _while_body_n:                                             */
3769 /*            statements                                           */
3770 /*            goto _while_continue_n                               */
3771 /*      _while_break_n:                                            */
3772 /*-----------------------------------------------------------------*/
3773 ast *
3774 createWhile (symbol * trueLabel, symbol * continueLabel,
3775              symbol * falseLabel, ast * condExpr, ast * whileBody)
3776 {
3777   ast *whileTree;
3778
3779   /* put the continue label */
3780   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3781   condExpr = createLabel (continueLabel, condExpr);
3782   condExpr->lineno = 0;
3783
3784   /* put the body label in front of the body */
3785   whileBody = createLabel (trueLabel, whileBody);
3786   whileBody->lineno = 0;
3787   /* put a jump to continue at the end of the body */
3788   /* and put break label at the end of the body */
3789   whileBody = newNode (NULLOP,
3790                        whileBody,
3791                        newNode (GOTO,
3792                                 newAst_VALUE (symbolVal (continueLabel)),
3793                                 createLabel (falseLabel, NULL)));
3794
3795   /* put it all together */
3796   if (IS_IFX (condExpr))
3797     whileTree = condExpr;
3798   else
3799     {
3800       whileTree = newNode (IFX, condExpr, NULL);
3801       /* put the true & false labels in place */
3802       whileTree->trueLabel = trueLabel;
3803       whileTree->falseLabel = falseLabel;
3804     }
3805
3806   return newNode (NULLOP, whileTree, whileBody);
3807 }
3808
3809 /*-----------------------------------------------------------------*/
3810 /* optimizeGetHbit - get highest order bit of the expression       */
3811 /*-----------------------------------------------------------------*/
3812 ast *
3813 optimizeGetHbit (ast * tree)
3814 {
3815   int i, j;
3816   /* if this is not a bit and */
3817   if (!IS_BITAND (tree))
3818     return tree;
3819
3820   /* will look for tree of the form
3821      ( expr >> ((sizeof expr) -1) ) & 1 */
3822   if (!IS_AST_LIT_VALUE (tree->right))
3823     return tree;
3824
3825   if (AST_LIT_VALUE (tree->right) != 1)
3826     return tree;
3827
3828   if (!IS_RIGHT_OP (tree->left))
3829     return tree;
3830
3831   if (!IS_AST_LIT_VALUE (tree->left->right))
3832     return tree;
3833
3834   if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3835       (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3836     return tree;
3837
3838   return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3839
3840 }
3841
3842 /*-----------------------------------------------------------------*/
3843 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry     */
3844 /*-----------------------------------------------------------------*/
3845 ast *
3846 optimizeRRCRLC (ast * root)
3847 {
3848   /* will look for trees of the form
3849      (?expr << 1) | (?expr >> 7) or
3850      (?expr >> 7) | (?expr << 1) will make that
3851      into a RLC : operation ..
3852      Will also look for
3853      (?expr >> 1) | (?expr << 7) or
3854      (?expr << 7) | (?expr >> 1) will make that
3855      into a RRC operation
3856      note : by 7 I mean (number of bits required to hold the
3857      variable -1 ) */
3858   /* if the root operations is not a | operation the not */
3859   if (!IS_BITOR (root))
3860     return root;
3861
3862   /* I have to think of a better way to match patterns this sucks */
3863   /* that aside let start looking for the first case : I use a the
3864      negative check a lot to improve the efficiency */
3865   /* (?expr << 1) | (?expr >> 7) */
3866   if (IS_LEFT_OP (root->left) &&
3867       IS_RIGHT_OP (root->right))
3868     {
3869
3870       if (!SPEC_USIGN (TETYPE (root->left->left)))
3871         return root;
3872
3873       if (!IS_AST_LIT_VALUE (root->left->right) ||
3874           !IS_AST_LIT_VALUE (root->right->right))
3875         goto tryNext0;
3876
3877       /* make sure it is the same expression */
3878       if (!isAstEqual (root->left->left,
3879                        root->right->left))
3880         goto tryNext0;
3881
3882       if (AST_LIT_VALUE (root->left->right) != 1)
3883         goto tryNext0;
3884
3885       if (AST_LIT_VALUE (root->right->right) !=
3886           (getSize (TTYPE (root->left->left)) * 8 - 1))
3887         goto tryNext0;
3888
3889       /* whew got the first case : create the AST */
3890       return newNode (RLC, root->left->left, NULL);
3891     }
3892
3893 tryNext0:
3894   /* check for second case */
3895   /* (?expr >> 7) | (?expr << 1) */
3896   if (IS_LEFT_OP (root->right) &&
3897       IS_RIGHT_OP (root->left))
3898     {
3899
3900       if (!SPEC_USIGN (TETYPE (root->left->left)))
3901         return root;
3902
3903       if (!IS_AST_LIT_VALUE (root->left->right) ||
3904           !IS_AST_LIT_VALUE (root->right->right))
3905         goto tryNext1;
3906
3907       /* make sure it is the same symbol */
3908       if (!isAstEqual (root->left->left,
3909                        root->right->left))
3910         goto tryNext1;
3911
3912       if (AST_LIT_VALUE (root->right->right) != 1)
3913         goto tryNext1;
3914
3915       if (AST_LIT_VALUE (root->left->right) !=
3916           (getSize (TTYPE (root->left->left)) * 8 - 1))
3917         goto tryNext1;
3918
3919       /* whew got the first case : create the AST */
3920       return newNode (RLC, root->left->left, NULL);
3921
3922     }
3923
3924 tryNext1:
3925   /* third case for RRC */
3926   /*  (?symbol >> 1) | (?symbol << 7) */
3927   if (IS_LEFT_OP (root->right) &&
3928       IS_RIGHT_OP (root->left))
3929     {
3930
3931       if (!SPEC_USIGN (TETYPE (root->left->left)))
3932         return root;
3933
3934       if (!IS_AST_LIT_VALUE (root->left->right) ||
3935           !IS_AST_LIT_VALUE (root->right->right))
3936         goto tryNext2;
3937
3938       /* make sure it is the same symbol */
3939       if (!isAstEqual (root->left->left,
3940                        root->right->left))
3941         goto tryNext2;
3942
3943       if (AST_LIT_VALUE (root->left->right) != 1)
3944         goto tryNext2;
3945
3946       if (AST_LIT_VALUE (root->right->right) !=
3947           (getSize (TTYPE (root->left->left)) * 8 - 1))
3948         goto tryNext2;
3949
3950       /* whew got the first case : create the AST */
3951       return newNode (RRC, root->left->left, NULL);
3952
3953     }
3954 tryNext2:
3955   /* fourth and last case for now */
3956   /* (?symbol << 7) | (?symbol >> 1) */
3957   if (IS_RIGHT_OP (root->right) &&
3958       IS_LEFT_OP (root->left))
3959     {
3960
3961       if (!SPEC_USIGN (TETYPE (root->left->left)))
3962         return root;
3963
3964       if (!IS_AST_LIT_VALUE (root->left->right) ||
3965           !IS_AST_LIT_VALUE (root->right->right))
3966         return root;
3967
3968       /* make sure it is the same symbol */
3969       if (!isAstEqual (root->left->left,
3970                        root->right->left))
3971         return root;
3972
3973       if (AST_LIT_VALUE (root->right->right) != 1)
3974         return root;
3975
3976       if (AST_LIT_VALUE (root->left->right) !=
3977           (getSize (TTYPE (root->left->left)) * 8 - 1))
3978         return root;
3979
3980       /* whew got the first case : create the AST */
3981       return newNode (RRC, root->left->left, NULL);
3982
3983     }
3984
3985   /* not found return root */
3986   return root;
3987 }
3988
3989 /*-----------------------------------------------------------------*/
3990 /* optimizeCompare - otimizes compares for bit variables     */
3991 /*-----------------------------------------------------------------*/
3992 static ast *
3993 optimizeCompare (ast * root)
3994 {
3995   ast *optExpr = NULL;
3996   value *vleft;
3997   value *vright;
3998   unsigned int litValue;
3999
4000   /* if nothing then return nothing */
4001   if (!root)
4002     return NULL;
4003
4004   /* if not a compare op then do leaves */
4005   if (!IS_COMPARE_OP (root))
4006     {
4007       root->left = optimizeCompare (root->left);
4008       root->right = optimizeCompare (root->right);
4009       return root;
4010     }
4011
4012   /* if left & right are the same then depending
4013      of the operation do */
4014   if (isAstEqual (root->left, root->right))
4015     {
4016       switch (root->opval.op)
4017         {
4018         case '>':
4019         case '<':
4020         case NE_OP:
4021           optExpr = newAst_VALUE (constVal ("0"));
4022           break;
4023         case GE_OP:
4024         case LE_OP:
4025         case EQ_OP:
4026           optExpr = newAst_VALUE (constVal ("1"));
4027           break;
4028         }
4029
4030       return decorateType (optExpr);
4031     }
4032
4033   vleft = (root->left->type == EX_VALUE ?
4034            root->left->opval.val : NULL);
4035
4036   vright = (root->right->type == EX_VALUE ?
4037             root->right->opval.val : NULL);
4038
4039   /* if left is a BITVAR in BITSPACE */
4040   /* and right is a LITERAL then opt- */
4041   /* imize else do nothing       */
4042   if (vleft && vright &&
4043       IS_BITVAR (vleft->etype) &&
4044       IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4045       IS_LITERAL (vright->etype))
4046     {
4047
4048       /* if right side > 1 then comparison may never succeed */
4049       if ((litValue = (int) floatFromVal (vright)) > 1)
4050         {
4051           werror (W_BAD_COMPARE);
4052           goto noOptimize;
4053         }
4054
4055       if (litValue)
4056         {
4057           switch (root->opval.op)
4058             {
4059             case '>':           /* bit value greater than 1 cannot be */
4060               werror (W_BAD_COMPARE);
4061               goto noOptimize;
4062               break;
4063
4064             case '<':           /* bit value < 1 means 0 */
4065             case NE_OP:
4066               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4067               break;
4068
4069             case LE_OP: /* bit value <= 1 means no check */
4070               optExpr = newAst_VALUE (vright);
4071               break;
4072
4073             case GE_OP: /* bit value >= 1 means only check for = */
4074             case EQ_OP:
4075               optExpr = newAst_VALUE (vleft);
4076               break;
4077             }
4078         }
4079       else
4080         {                       /* literal is zero */
4081           switch (root->opval.op)
4082             {
4083             case '<':           /* bit value < 0 cannot be */
4084               werror (W_BAD_COMPARE);
4085               goto noOptimize;
4086               break;
4087
4088             case '>':           /* bit value > 0 means 1 */
4089             case NE_OP:
4090               optExpr = newAst_VALUE (vleft);
4091               break;
4092
4093             case LE_OP: /* bit value <= 0 means no check */
4094             case GE_OP: /* bit value >= 0 means no check */
4095               werror (W_BAD_COMPARE);
4096               goto noOptimize;
4097               break;
4098
4099             case EQ_OP: /* bit == 0 means ! of bit */
4100               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4101               break;
4102             }
4103         }
4104       return decorateType (resolveSymbols (optExpr));
4105     }                           /* end-of-if of BITVAR */
4106
4107 noOptimize:
4108   return root;
4109 }
4110 /*-----------------------------------------------------------------*/
4111 /* addSymToBlock : adds the symbol to the first block we find      */
4112 /*-----------------------------------------------------------------*/
4113 void 
4114 addSymToBlock (symbol * sym, ast * tree)
4115 {
4116   /* reached end of tree or a leaf */
4117   if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4118     return;
4119
4120   /* found a block */
4121   if (IS_AST_OP (tree) &&
4122       tree->opval.op == BLOCK)
4123     {
4124
4125       symbol *lsym = copySymbol (sym);
4126
4127       lsym->next = AST_VALUES (tree, sym);
4128       AST_VALUES (tree, sym) = lsym;
4129       return;
4130     }
4131
4132   addSymToBlock (sym, tree->left);
4133   addSymToBlock (sym, tree->right);
4134 }
4135
4136 /*-----------------------------------------------------------------*/
4137 /* processRegParms - do processing for register parameters         */
4138 /*-----------------------------------------------------------------*/
4139 static void 
4140 processRegParms (value * args, ast * body)
4141 {
4142   while (args)
4143     {
4144       if (IS_REGPARM (args->etype))
4145         addSymToBlock (args->sym, body);
4146       args = args->next;
4147     }
4148 }
4149
4150 /*-----------------------------------------------------------------*/
4151 /* resetParmKey - resets the operandkeys for the symbols           */
4152 /*-----------------------------------------------------------------*/
4153 DEFSETFUNC (resetParmKey)
4154 {
4155   symbol *sym = item;
4156
4157   sym->key = 0;
4158   sym->defs = NULL;
4159   sym->uses = NULL;
4160   sym->remat = 0;
4161   return 1;
4162 }
4163
4164 /*-----------------------------------------------------------------*/
4165 /* createFunction - This is the key node that calls the iCode for  */
4166 /*                  generating the code for a function. Note code  */
4167 /*                  is generated function by function, later when  */
4168 /*                  add inter-procedural analysis this will change */
4169 /*-----------------------------------------------------------------*/
4170 ast *
4171 createFunction (symbol * name, ast * body)
4172 {
4173   ast *ex;
4174   symbol *csym;
4175   int stack = 0;
4176   sym_link *fetype;
4177   iCode *piCode = NULL;
4178
4179   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4180     fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4181
4182   /* if check function return 0 then some problem */
4183   if (checkFunction (name, NULL) == 0)
4184     return NULL;
4185
4186   /* create a dummy block if none exists */
4187   if (!body)
4188     body = newNode (BLOCK, NULL, NULL);
4189
4190   noLineno++;
4191
4192   /* check if the function name already in the symbol table */
4193   if ((csym = findSym (SymbolTab, NULL, name->name)))
4194     {
4195       name = csym;
4196       /* special case for compiler defined functions
4197          we need to add the name to the publics list : this
4198          actually means we are now compiling the compiler
4199          support routine */
4200       if (name->cdef)
4201         {
4202           addSet (&publics, name);
4203         }
4204     }
4205   else
4206     {
4207       addSymChain (name);
4208       allocVariables (name);
4209     }
4210   name->lastLine = yylineno;
4211   currFunc = name;
4212
4213   /* set the stack pointer */
4214   /* PENDING: check this for the mcs51 */
4215   stackPtr = -port->stack.direction * port->stack.call_overhead;
4216   if (IFFUNC_ISISR (name->type))
4217     stackPtr -= port->stack.direction * port->stack.isr_overhead;
4218   if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4219     stackPtr -= port->stack.direction * port->stack.reent_overhead;
4220
4221   xstackPtr = -port->stack.direction * port->stack.call_overhead;
4222
4223   fetype = getSpec (name->type);        /* get the specifier for the function */
4224   /* if this is a reentrant function then */
4225   if (IFFUNC_ISREENT (name->type))
4226     reentrant++;
4227
4228   allocParms (FUNC_ARGS(name->type));   /* allocate the parameters */
4229
4230   /* do processing for parameters that are passed in registers */
4231   processRegParms (FUNC_ARGS(name->type), body);
4232
4233   /* set the stack pointer */
4234   stackPtr = 0;
4235   xstackPtr = -1;
4236
4237   /* allocate & autoinit the block variables */
4238   processBlockVars (body, &stack, ALLOCATE);
4239
4240   /* save the stack information */
4241   if (options.useXstack)
4242     name->xstack = SPEC_STAK (fetype) = stack;
4243   else
4244     name->stack = SPEC_STAK (fetype) = stack;
4245
4246   /* name needs to be mangled */
4247   sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4248
4249   body = resolveSymbols (body); /* resolve the symbols */
4250   body = decorateType (body);   /* propagateType & do semantic checks */
4251
4252   ex = newAst_VALUE (symbolVal (name)); /* create name */
4253   ex = newNode (FUNCTION, ex, body);
4254   ex->values.args = FUNC_ARGS(name->type);
4255   ex->decorated=1;
4256   if (options.dump_tree) PA(ex);
4257   if (fatalError)
4258     {
4259       werror (E_FUNC_NO_CODE, name->name);
4260       goto skipall;
4261     }
4262
4263   /* create the node & generate intermediate code */
4264   GcurMemmap = code;
4265   codeOutFile = code->oFile;
4266   piCode = iCodeFromAst (ex);
4267
4268   if (fatalError)
4269     {
4270       werror (E_FUNC_NO_CODE, name->name);
4271       goto skipall;
4272     }
4273
4274   eBBlockFromiCode (piCode);
4275
4276   /* if there are any statics then do them */
4277   if (staticAutos)
4278     {
4279       GcurMemmap = statsg;
4280       codeOutFile = statsg->oFile;
4281       eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4282       staticAutos = NULL;
4283     }
4284
4285 skipall:
4286
4287   /* dealloc the block variables */
4288   processBlockVars (body, &stack, DEALLOCATE);
4289   /* deallocate paramaters */
4290   deallocParms (FUNC_ARGS(name->type));
4291
4292   if (IFFUNC_ISREENT (name->type))
4293     reentrant--;
4294
4295   /* we are done freeup memory & cleanup */
4296   noLineno--;
4297   if (port->reset_labelKey) labelKey = 1;
4298   name->key = 0;
4299   FUNC_HASBODY(name->type) = 1;
4300   addSet (&operKeyReset, name);
4301   applyToSet (operKeyReset, resetParmKey);
4302
4303   if (options.debug)
4304     cdbStructBlock (1, cdbFile);
4305
4306   cleanUpLevel (LabelTab, 0);
4307   cleanUpBlock (StructTab, 1);
4308   cleanUpBlock (TypedefTab, 1);
4309
4310   xstack->syms = NULL;
4311   istack->syms = NULL;
4312   return NULL;
4313 }
4314
4315
4316 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4317 /*-----------------------------------------------------------------*/
4318 /* ast_print : prints the ast (for debugging purposes)             */
4319 /*-----------------------------------------------------------------*/
4320
4321 void ast_print (ast * tree, FILE *outfile, int indent)
4322 {
4323         
4324         if (!tree) return ;
4325
4326         /* can print only decorated trees */
4327         if (!tree->decorated) return;
4328
4329         /* if any child is an error | this one is an error do nothing */
4330         if (tree->isError ||
4331             (tree->left && tree->left->isError) ||
4332             (tree->right && tree->right->isError)) {
4333                 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4334         }
4335
4336         
4337         /* print the line          */
4338         /* if not block & function */
4339         if (tree->type == EX_OP &&
4340             (tree->opval.op != FUNCTION &&
4341              tree->opval.op != BLOCK &&
4342              tree->opval.op != NULLOP)) {
4343         }
4344         
4345         if (tree->opval.op == FUNCTION) {
4346                 int arg=0;
4347                 value *args=FUNC_ARGS(tree->left->opval.val->type);
4348                 fprintf(outfile,"FUNCTION (%s=%p) type (", 
4349                         tree->left->opval.val->name, tree);
4350                 printTypeChain (tree->ftype,outfile);
4351                 fprintf(outfile,") args (");
4352                 do {
4353                   if (arg) {
4354                     fprintf (outfile, ", ");
4355                   }
4356                   printTypeChain (args ? args->type : NULL, outfile);
4357                   arg++;
4358                   args= args ? args->next : NULL;
4359                 } while (args);
4360                 fprintf(outfile,")\n");
4361                 ast_print(tree->left,outfile,indent);
4362                 ast_print(tree->right,outfile,indent);
4363                 return ;
4364         }
4365         if (tree->opval.op == BLOCK) {
4366                 symbol *decls = tree->values.sym;
4367                 INDENT(indent,outfile);
4368                 fprintf(outfile,"{\n");
4369                 while (decls) {
4370                         INDENT(indent+2,outfile);
4371                         fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4372                                 decls->name, decls);
4373                         printTypeChain(decls->type,outfile);
4374                         fprintf(outfile,")\n");
4375                         
4376                         decls = decls->next;                    
4377                 }
4378                 ast_print(tree->right,outfile,indent+2);
4379                 INDENT(indent,outfile);
4380                 fprintf(outfile,"}\n");
4381                 return;
4382         }
4383         if (tree->opval.op == NULLOP) {
4384                 fprintf(outfile,"\n");
4385                 ast_print(tree->left,outfile,indent);
4386                 fprintf(outfile,"\n");
4387                 ast_print(tree->right,outfile,indent);
4388                 return ;
4389         }
4390         INDENT(indent,outfile);
4391
4392         /*------------------------------------------------------------------*/
4393         /*----------------------------*/
4394         /*   leaf has been reached    */
4395         /*----------------------------*/
4396         /* if this is of type value */
4397         /* just get the type        */
4398         if (tree->type == EX_VALUE) {
4399
4400                 if (IS_LITERAL (tree->opval.val->etype)) {                      
4401                         fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4402                                 (int) floatFromVal(tree->opval.val),
4403                                 (int) floatFromVal(tree->opval.val),
4404                                 floatFromVal(tree->opval.val));
4405                 } else if (tree->opval.val->sym) {
4406                         /* if the undefined flag is set then give error message */
4407                         if (tree->opval.val->sym->undefined) {
4408                                 fprintf(outfile,"UNDEFINED SYMBOL ");
4409                         } else {
4410                                 fprintf(outfile,"SYMBOL ");
4411                         }
4412                         fprintf(outfile,"(%s=%p)",
4413                                 tree->opval.val->sym->name,tree);
4414                 }
4415                 if (tree->ftype) {
4416                         fprintf(outfile," type (");
4417                         printTypeChain(tree->ftype,outfile);
4418                         fprintf(outfile,")\n");
4419                 } else {
4420                         fprintf(outfile,"\n");
4421                 }
4422                 return ;
4423         }
4424
4425         /* if type link for the case of cast */
4426         if (tree->type == EX_LINK) {
4427                 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4428                 printTypeChain(tree->opval.lnk,outfile);
4429                 fprintf(outfile,")\n");
4430                 return ;
4431         }
4432
4433
4434         /* depending on type of operator do */
4435         
4436         switch (tree->opval.op) {
4437                 /*------------------------------------------------------------------*/
4438                 /*----------------------------*/
4439                 /*        array node          */
4440                 /*----------------------------*/
4441         case '[':
4442                 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4443                 printTypeChain(tree->ftype,outfile);
4444                 fprintf(outfile,")\n");
4445                 ast_print(tree->left,outfile,indent+2);
4446                 ast_print(tree->right,outfile,indent+2);
4447                 return;
4448
4449                 /*------------------------------------------------------------------*/
4450                 /*----------------------------*/
4451                 /*      struct/union          */
4452                 /*----------------------------*/
4453         case '.':
4454                 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4455                 printTypeChain(tree->ftype,outfile);
4456                 fprintf(outfile,")\n");
4457                 ast_print(tree->left,outfile,indent+2);
4458                 ast_print(tree->right,outfile,indent+2);
4459                 return ;
4460
4461                 /*------------------------------------------------------------------*/
4462                 /*----------------------------*/
4463                 /*    struct/union pointer    */
4464                 /*----------------------------*/
4465         case PTR_OP:
4466                 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4467                 printTypeChain(tree->ftype,outfile);
4468                 fprintf(outfile,")\n");
4469                 ast_print(tree->left,outfile,indent+2);
4470                 ast_print(tree->right,outfile,indent+2);
4471                 return ;
4472
4473                 /*------------------------------------------------------------------*/
4474                 /*----------------------------*/
4475                 /*  ++/-- operation           */
4476                 /*----------------------------*/
4477         case INC_OP:            /* incerement operator unary so left only */
4478                 fprintf(outfile,"INC_OP (%p) type (",tree);
4479                 printTypeChain(tree->ftype,outfile);
4480                 fprintf(outfile,")\n");
4481                 ast_print(tree->left,outfile,indent+2);
4482                 return ;
4483
4484         case DEC_OP:
4485                 fprintf(outfile,"DEC_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                 /*------------------------------------------------------------------*/
4492                 /*----------------------------*/
4493                 /*  bitwise and               */
4494                 /*----------------------------*/
4495         case '&':                       
4496                 if (tree->right) {
4497                         fprintf(outfile,"& (%p) type (",tree);
4498                         printTypeChain(tree->ftype,outfile);
4499                         fprintf(outfile,")\n");
4500                         ast_print(tree->left,outfile,indent+2);
4501                         ast_print(tree->right,outfile,indent+2);
4502                 } else {
4503                         fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4504                         printTypeChain(tree->ftype,outfile);
4505                         fprintf(outfile,")\n");
4506                         ast_print(tree->left,outfile,indent+2);
4507                         ast_print(tree->right,outfile,indent+2);
4508                 }
4509                 return ;
4510                 /*----------------------------*/
4511                 /*  bitwise or                */
4512                 /*----------------------------*/
4513         case '|':
4514                 fprintf(outfile,"OR (%p) type (",tree);
4515                 printTypeChain(tree->ftype,outfile);
4516                 fprintf(outfile,")\n");
4517                 ast_print(tree->left,outfile,indent+2);
4518                 ast_print(tree->right,outfile,indent+2);
4519                 return ;
4520                 /*------------------------------------------------------------------*/
4521                 /*----------------------------*/
4522                 /*  bitwise xor               */
4523                 /*----------------------------*/
4524         case '^':
4525                 fprintf(outfile,"XOR (%p) type (",tree);
4526                 printTypeChain(tree->ftype,outfile);
4527                 fprintf(outfile,")\n");
4528                 ast_print(tree->left,outfile,indent+2);
4529                 ast_print(tree->right,outfile,indent+2);
4530                 return ;
4531                 
4532                 /*------------------------------------------------------------------*/
4533                 /*----------------------------*/
4534                 /*  division                  */
4535                 /*----------------------------*/
4536         case '/':
4537                 fprintf(outfile,"DIV (%p) type (",tree);
4538                 printTypeChain(tree->ftype,outfile);
4539                 fprintf(outfile,")\n");
4540                 ast_print(tree->left,outfile,indent+2);
4541                 ast_print(tree->right,outfile,indent+2);
4542                 return ;
4543                 /*------------------------------------------------------------------*/
4544                 /*----------------------------*/
4545                 /*            modulus         */
4546                 /*----------------------------*/
4547         case '%':
4548                 fprintf(outfile,"MOD (%p) type (",tree);
4549                 printTypeChain(tree->ftype,outfile);
4550                 fprintf(outfile,")\n");
4551                 ast_print(tree->left,outfile,indent+2);
4552                 ast_print(tree->right,outfile,indent+2);
4553                 return ;
4554
4555                 /*------------------------------------------------------------------*/
4556                 /*----------------------------*/
4557                 /*  address dereference       */
4558                 /*----------------------------*/
4559         case '*':                       /* can be unary  : if right is null then unary operation */
4560                 if (!tree->right) {
4561                         fprintf(outfile,"DEREF (%p) type (",tree);
4562                         printTypeChain(tree->ftype,outfile);
4563                         fprintf(outfile,")\n");
4564                         ast_print(tree->left,outfile,indent+2);
4565                         return ;
4566                 }                       
4567                 /*------------------------------------------------------------------*/
4568                 /*----------------------------*/
4569                 /*      multiplication        */
4570                 /*----------------------------*/                
4571                 fprintf(outfile,"MULT (%p) type (",tree);
4572                 printTypeChain(tree->ftype,outfile);
4573                 fprintf(outfile,")\n");
4574                 ast_print(tree->left,outfile,indent+2);
4575                 ast_print(tree->right,outfile,indent+2);
4576                 return ;
4577
4578
4579                 /*------------------------------------------------------------------*/
4580                 /*----------------------------*/
4581                 /*    unary '+' operator      */
4582                 /*----------------------------*/
4583         case '+':
4584                 /* if unary plus */
4585                 if (!tree->right) {
4586                         fprintf(outfile,"UPLUS (%p) type (",tree);
4587                         printTypeChain(tree->ftype,outfile);
4588                         fprintf(outfile,")\n");
4589                         ast_print(tree->left,outfile,indent+2);
4590                 } else {
4591                         /*------------------------------------------------------------------*/
4592                         /*----------------------------*/
4593                         /*      addition              */
4594                         /*----------------------------*/
4595                         fprintf(outfile,"ADD (%p) type (",tree);
4596                         printTypeChain(tree->ftype,outfile);
4597                         fprintf(outfile,")\n");
4598                         ast_print(tree->left,outfile,indent+2);
4599                         ast_print(tree->right,outfile,indent+2);
4600                 }
4601                 return;
4602                 /*------------------------------------------------------------------*/
4603                 /*----------------------------*/
4604                 /*      unary '-'             */
4605                 /*----------------------------*/
4606         case '-':                       /* can be unary   */
4607                 if (!tree->right) {
4608                         fprintf(outfile,"UMINUS (%p) type (",tree);
4609                         printTypeChain(tree->ftype,outfile);
4610                         fprintf(outfile,")\n");
4611                         ast_print(tree->left,outfile,indent+2);
4612                 } else {
4613                         /*------------------------------------------------------------------*/
4614                         /*----------------------------*/
4615                         /*      subtraction           */
4616                         /*----------------------------*/
4617                         fprintf(outfile,"SUB (%p) type (",tree);
4618                         printTypeChain(tree->ftype,outfile);
4619                         fprintf(outfile,")\n");
4620                         ast_print(tree->left,outfile,indent+2);
4621                         ast_print(tree->right,outfile,indent+2);
4622                 }
4623                 return;
4624                 /*------------------------------------------------------------------*/
4625                 /*----------------------------*/
4626                 /*    compliment              */
4627                 /*----------------------------*/
4628         case '~':
4629                 fprintf(outfile,"COMPL (%p) type (",tree);
4630                 printTypeChain(tree->ftype,outfile);
4631                 fprintf(outfile,")\n");
4632                 ast_print(tree->left,outfile,indent+2);
4633                 return ;
4634                 /*------------------------------------------------------------------*/
4635                 /*----------------------------*/
4636                 /*           not              */
4637                 /*----------------------------*/
4638         case '!':
4639                 fprintf(outfile,"NOT (%p) type (",tree);
4640                 printTypeChain(tree->ftype,outfile);
4641                 fprintf(outfile,")\n");
4642                 ast_print(tree->left,outfile,indent+2);
4643                 return ;
4644                 /*------------------------------------------------------------------*/
4645                 /*----------------------------*/
4646                 /*           shift            */
4647                 /*----------------------------*/
4648         case RRC:
4649                 fprintf(outfile,"RRC (%p) type (",tree);
4650                 printTypeChain(tree->ftype,outfile);
4651                 fprintf(outfile,")\n");
4652                 ast_print(tree->left,outfile,indent+2);
4653                 return ;
4654
4655         case RLC:
4656                 fprintf(outfile,"RLC (%p) type (",tree);
4657                 printTypeChain(tree->ftype,outfile);
4658                 fprintf(outfile,")\n");
4659                 ast_print(tree->left,outfile,indent+2);
4660                 return ;
4661         case GETHBIT:
4662                 fprintf(outfile,"GETHBIT (%p) type (",tree);
4663                 printTypeChain(tree->ftype,outfile);
4664                 fprintf(outfile,")\n");
4665                 ast_print(tree->left,outfile,indent+2);
4666                 return ;
4667         case LEFT_OP:
4668                 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4669                 printTypeChain(tree->ftype,outfile);
4670                 fprintf(outfile,")\n");
4671                 ast_print(tree->left,outfile,indent+2);
4672                 ast_print(tree->right,outfile,indent+2);
4673                 return ;
4674         case RIGHT_OP:
4675                 fprintf(outfile,"RIGHT_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                 /*------------------------------------------------------------------*/
4682                 /*----------------------------*/
4683                 /*         casting            */
4684                 /*----------------------------*/
4685         case CAST:                      /* change the type   */
4686                 fprintf(outfile,"CAST (%p) from type (",tree);
4687                 printTypeChain(tree->right->ftype,outfile);
4688                 fprintf(outfile,") to type (");
4689                 printTypeChain(tree->ftype,outfile);
4690                 fprintf(outfile,")\n");
4691                 ast_print(tree->right,outfile,indent+2);
4692                 return ;
4693                 
4694         case AND_OP:
4695                 fprintf(outfile,"ANDAND (%p) type (",tree);
4696                 printTypeChain(tree->ftype,outfile);
4697                 fprintf(outfile,")\n");
4698                 ast_print(tree->left,outfile,indent+2);
4699                 ast_print(tree->right,outfile,indent+2);
4700                 return ;
4701         case OR_OP:
4702                 fprintf(outfile,"OROR (%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                 
4709                 /*------------------------------------------------------------------*/
4710                 /*----------------------------*/
4711                 /*     comparison operators   */
4712                 /*----------------------------*/
4713         case '>':
4714                 fprintf(outfile,"GT(>) (%p) type (",tree);
4715                 printTypeChain(tree->ftype,outfile);
4716                 fprintf(outfile,")\n");
4717                 ast_print(tree->left,outfile,indent+2);
4718                 ast_print(tree->right,outfile,indent+2);
4719                 return ;
4720         case '<':
4721                 fprintf(outfile,"LT(<) (%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 LE_OP:
4728                 fprintf(outfile,"LE(<=) (%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 GE_OP:
4735                 fprintf(outfile,"GE(>=) (%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 EQ_OP:
4742                 fprintf(outfile,"EQ(==) (%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 NE_OP:
4749                 fprintf(outfile,"NE(!=) (%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                 /*------------------------------------------------------------------*/
4755                 /*----------------------------*/
4756                 /*             sizeof         */
4757                 /*----------------------------*/
4758         case SIZEOF:            /* evaluate wihout code generation */
4759                 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4760                 return ;
4761
4762                 /*------------------------------------------------------------------*/
4763                 /*----------------------------*/
4764                 /* conditional operator  '?'  */
4765                 /*----------------------------*/
4766         case '?':
4767                 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4768                 printTypeChain(tree->ftype,outfile);
4769                 fprintf(outfile,")\n");
4770                 ast_print(tree->left,outfile,indent+2);
4771                 ast_print(tree->right,outfile,indent+2);
4772                 return;
4773
4774         case ':':
4775                 fprintf(outfile,"COLON(:) (%p) type (",tree);
4776                 printTypeChain(tree->ftype,outfile);
4777                 fprintf(outfile,")\n");
4778                 ast_print(tree->left,outfile,indent+2);
4779                 ast_print(tree->right,outfile,indent+2);
4780                 return ;
4781                 
4782                 /*------------------------------------------------------------------*/
4783                 /*----------------------------*/
4784                 /*    assignment operators    */
4785                 /*----------------------------*/
4786         case MUL_ASSIGN:
4787                 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4788                 printTypeChain(tree->ftype,outfile);
4789                 fprintf(outfile,")\n");
4790                 ast_print(tree->left,outfile,indent+2);
4791                 ast_print(tree->right,outfile,indent+2);
4792                 return;
4793         case DIV_ASSIGN:
4794                 fprintf(outfile,"DIVASS(/=) (%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 AND_ASSIGN:
4801                 fprintf(outfile,"ANDASS(&=) (%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 OR_ASSIGN:
4808                 fprintf(outfile,"ORASS(*=) (%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 XOR_ASSIGN:
4815                 fprintf(outfile,"XORASS(*=) (%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 RIGHT_ASSIGN:
4822                 fprintf(outfile,"RSHFTASS(>>=) (%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 LEFT_ASSIGN:
4829                 fprintf(outfile,"LSHFTASS(*=) (%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                 /*------------------------------------------------------------------*/
4836                 /*----------------------------*/
4837                 /*    -= operator             */
4838                 /*----------------------------*/
4839         case SUB_ASSIGN:
4840                 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4841                 printTypeChain(tree->ftype,outfile);
4842                 fprintf(outfile,")\n");
4843                 ast_print(tree->left,outfile,indent+2);
4844                 ast_print(tree->right,outfile,indent+2);
4845                 return;
4846                 /*------------------------------------------------------------------*/
4847                 /*----------------------------*/
4848                 /*          += operator       */
4849                 /*----------------------------*/
4850         case ADD_ASSIGN:
4851                 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4852                 printTypeChain(tree->ftype,outfile);
4853                 fprintf(outfile,")\n");
4854                 ast_print(tree->left,outfile,indent+2);
4855                 ast_print(tree->right,outfile,indent+2);
4856                 return;
4857                 /*------------------------------------------------------------------*/
4858                 /*----------------------------*/
4859                 /*      straight assignemnt   */
4860                 /*----------------------------*/
4861         case '=':
4862                 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4863                 printTypeChain(tree->ftype,outfile);
4864                 fprintf(outfile,")\n");
4865                 ast_print(tree->left,outfile,indent+2);
4866                 ast_print(tree->right,outfile,indent+2);
4867                 return;     
4868                 /*------------------------------------------------------------------*/
4869                 /*----------------------------*/
4870                 /*      comma operator        */
4871                 /*----------------------------*/
4872         case ',':
4873                 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4874                 printTypeChain(tree->ftype,outfile);
4875                 fprintf(outfile,")\n");
4876                 ast_print(tree->left,outfile,indent+2);
4877                 ast_print(tree->right,outfile,indent+2);
4878                 return;
4879                 /*------------------------------------------------------------------*/
4880                 /*----------------------------*/
4881                 /*       function call        */
4882                 /*----------------------------*/
4883         case CALL:
4884         case PCALL:
4885                 fprintf(outfile,"CALL (%p) type (",tree);
4886                 printTypeChain(tree->ftype,outfile);
4887                 fprintf(outfile,")\n");
4888                 ast_print(tree->left,outfile,indent+2);
4889                 ast_print(tree->right,outfile,indent+2);
4890                 return;
4891         case PARAM:
4892                 fprintf(outfile,"PARMS\n");
4893                 ast_print(tree->left,outfile,indent+2);
4894                 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4895                         ast_print(tree->right,outfile,indent+2);
4896                 }
4897                 return ;
4898                 /*------------------------------------------------------------------*/
4899                 /*----------------------------*/
4900                 /*     return statement       */
4901                 /*----------------------------*/
4902         case RETURN:
4903                 fprintf(outfile,"RETURN (%p) type (",tree);
4904                 if (tree->right) {
4905                     printTypeChain(tree->right->ftype,outfile);
4906                 }
4907                 fprintf(outfile,")\n");
4908                 ast_print(tree->right,outfile,indent+2);
4909                 return ;
4910                 /*------------------------------------------------------------------*/
4911                 /*----------------------------*/
4912                 /*     label statement        */
4913                 /*----------------------------*/
4914         case LABEL :
4915                 fprintf(outfile,"LABEL (%p)\n",tree);
4916                 ast_print(tree->left,outfile,indent+2);
4917                 ast_print(tree->right,outfile,indent);
4918                 return;
4919                 /*------------------------------------------------------------------*/
4920                 /*----------------------------*/
4921                 /*     switch statement       */
4922                 /*----------------------------*/
4923         case SWITCH:
4924                 {
4925                         value *val;
4926                         fprintf(outfile,"SWITCH (%p) ",tree);
4927                         ast_print(tree->left,outfile,0);
4928                         for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4929                                 INDENT(indent+2,outfile);
4930                                 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4931                                         (int) floatFromVal(val),
4932                                         tree->values.switchVals.swNum,
4933                                         (int) floatFromVal(val));
4934                         }
4935                         ast_print(tree->right,outfile,indent);
4936                 }
4937                 return ;
4938                 /*------------------------------------------------------------------*/
4939                 /*----------------------------*/
4940                 /* ifx Statement              */
4941                 /*----------------------------*/
4942         case IFX:
4943                 fprintf(outfile,"IF (%p) \n",tree);
4944                 ast_print(tree->left,outfile,indent+2);
4945                 if (tree->trueLabel) {
4946                         INDENT(indent,outfile);
4947                         fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4948                 }
4949                 if (tree->falseLabel) {
4950                         INDENT(indent,outfile);
4951                         fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4952                 }
4953                 ast_print(tree->right,outfile,indent+2);
4954                 return ;
4955                 /*------------------------------------------------------------------*/
4956                 /*----------------------------*/
4957                 /* for Statement              */
4958                 /*----------------------------*/
4959         case FOR:
4960                 fprintf(outfile,"FOR (%p) \n",tree);
4961                 if (AST_FOR( tree, initExpr)) {
4962                         INDENT(indent+2,outfile);
4963                         fprintf(outfile,"INIT EXPR ");
4964                         ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
4965                 }
4966                 if (AST_FOR( tree, condExpr)) {
4967                         INDENT(indent+2,outfile);
4968                         fprintf(outfile,"COND EXPR ");
4969                         ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
4970                 }
4971                 if (AST_FOR( tree, loopExpr)) {
4972                         INDENT(indent+2,outfile);
4973                         fprintf(outfile,"LOOP EXPR ");
4974                         ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
4975                 }
4976                 fprintf(outfile,"FOR LOOP BODY \n");
4977                 ast_print(tree->left,outfile,indent+2);
4978                 return ;
4979         default:
4980             return ;
4981         }
4982 }
4983
4984 void PA(ast *t)
4985 {
4986         ast_print(t,stdout,0);
4987 }