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