fixed bug #514865
[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           werror (E_ILLEGAL_ADDR, "address of function");
2152           goto errorTreeReturn;
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         tree->left = 
2662           decorateType (newNode (CAST,
2663                                  newAst_LINK(copyLinkChain(LTYPE(tree))),
2664                                  tree->left));
2665         SPEC_NOUN(tree->left->left->ftype)=V_INT;
2666       }
2667       /* if only the right side is a literal & we are
2668          shifting more than size of the left operand then zero */
2669       if (IS_LITERAL (RTYPE (tree)) &&
2670           ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2671           (getSize (LTYPE (tree)) * 8))
2672         {
2673           werror (W_SHIFT_CHANGED,
2674                   (tree->opval.op == LEFT_OP ? "left" : "right"));
2675           tree->type = EX_VALUE;
2676           tree->left = tree->right = NULL;
2677           tree->opval.val = constVal ("0");
2678           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2679           return tree;
2680         }
2681       LRVAL (tree) = RRVAL (tree) = 1;
2682       if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2683         {
2684           COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2685         }
2686       else
2687         {
2688           COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2689         }
2690       return tree;
2691
2692       /*------------------------------------------------------------------*/
2693       /*----------------------------*/
2694       /*         casting            */
2695       /*----------------------------*/
2696     case CAST:                  /* change the type   */
2697       /* cannot cast to an aggregate type */
2698       if (IS_AGGREGATE (LTYPE (tree)))
2699         {
2700           werror (E_CAST_ILLEGAL);
2701           goto errorTreeReturn;
2702         }
2703       
2704       /* make sure the type is complete and sane */
2705       checkTypeSanity(LETYPE(tree), "(cast)");
2706
2707 #if 0
2708       /* if the right is a literal replace the tree */
2709       if (IS_LITERAL (RETYPE (tree))) {
2710               if (!IS_PTR (LTYPE (tree))) {
2711                       tree->type = EX_VALUE;
2712                       tree->opval.val =
2713                               valCastLiteral (LTYPE (tree),
2714                                               floatFromVal (valFromType (RETYPE (tree))));
2715                       tree->left = NULL;
2716                       tree->right = NULL;
2717                       TTYPE (tree) = tree->opval.val->type;
2718                       tree->values.literalFromCast = 1;
2719               } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) && 
2720                          ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */  {
2721                       sym_link *rest = LTYPE(tree)->next;
2722                       werror(W_LITERAL_GENERIC);                      
2723                       TTYPE(tree) = newLink();
2724                       DCL_TYPE(TTYPE(tree)) = FPOINTER;
2725                       TTYPE(tree)->next = rest;
2726                       tree->left->opval.lnk = TTYPE(tree);
2727                       LRVAL (tree) = 1;
2728               } else {
2729                       TTYPE (tree) = LTYPE (tree);
2730                       LRVAL (tree) = 1;
2731               }
2732       } else {
2733               TTYPE (tree) = LTYPE (tree);
2734               LRVAL (tree) = 1;
2735       }
2736 #else
2737       /* if pointer to struct then check names */
2738       if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2739           IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2740           strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) {
2741               werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag);
2742       }
2743       /* if the right is a literal replace the tree */
2744       if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2745         tree->type = EX_VALUE;
2746         tree->opval.val =
2747           valCastLiteral (LTYPE (tree),
2748                           floatFromVal (valFromType (RETYPE (tree))));
2749         tree->left = NULL;
2750         tree->right = NULL;
2751         TTYPE (tree) = tree->opval.val->type;
2752         tree->values.literalFromCast = 1;
2753       } else {
2754         TTYPE (tree) = LTYPE (tree);
2755         LRVAL (tree) = 1;
2756       }
2757 #endif      
2758       TETYPE (tree) = getSpec (TTYPE (tree));
2759
2760       return tree;
2761
2762       /*------------------------------------------------------------------*/
2763       /*----------------------------*/
2764       /*       logical &&, ||       */
2765       /*----------------------------*/
2766     case AND_OP:
2767     case OR_OP:
2768       /* each must me arithmetic type or be a pointer */
2769       if (!IS_PTR (LTYPE (tree)) &&
2770           !IS_ARRAY (LTYPE (tree)) &&
2771           !IS_INTEGRAL (LTYPE (tree)))
2772         {
2773           werror (E_COMPARE_OP);
2774           goto errorTreeReturn;
2775         }
2776
2777       if (!IS_PTR (RTYPE (tree)) &&
2778           !IS_ARRAY (RTYPE (tree)) &&
2779           !IS_INTEGRAL (RTYPE (tree)))
2780         {
2781           werror (E_COMPARE_OP);
2782           goto errorTreeReturn;
2783         }
2784       /* if they are both literal then */
2785       /* rewrite the tree */
2786       if (IS_LITERAL (RTYPE (tree)) &&
2787           IS_LITERAL (LTYPE (tree)))
2788         {
2789           tree->type = EX_VALUE;
2790           tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2791                                            valFromType (RETYPE (tree)),
2792                                            tree->opval.op);
2793           tree->right = tree->left = NULL;
2794           TETYPE (tree) = getSpec (TTYPE (tree) =
2795                                    tree->opval.val->type);
2796           return tree;
2797         }
2798       LRVAL (tree) = RRVAL (tree) = 1;
2799       TTYPE (tree) = TETYPE (tree) = newCharLink ();
2800       return tree;
2801
2802       /*------------------------------------------------------------------*/
2803       /*----------------------------*/
2804       /*     comparison operators   */
2805       /*----------------------------*/
2806     case '>':
2807     case '<':
2808     case LE_OP:
2809     case GE_OP:
2810     case EQ_OP:
2811     case NE_OP:
2812       {
2813         ast *lt = optimizeCompare (tree);
2814
2815         if (tree != lt)
2816           return lt;
2817       }
2818
2819       /* if they are pointers they must be castable */
2820       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2821         {
2822           if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2823             {
2824               werror (E_COMPARE_OP);
2825               fprintf (stderr, "comparing type ");
2826               printTypeChain (LTYPE (tree), stderr);
2827               fprintf (stderr, "to type ");
2828               printTypeChain (RTYPE (tree), stderr);
2829               fprintf (stderr, "\n");
2830               goto errorTreeReturn;
2831             }
2832         }
2833       /* else they should be promotable to one another */
2834       else
2835         {
2836           if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2837                 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2838
2839             if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2840               {
2841                 werror (E_COMPARE_OP);
2842                 fprintf (stderr, "comparing type ");
2843                 printTypeChain (LTYPE (tree), stderr);
2844                 fprintf (stderr, "to type ");
2845                 printTypeChain (RTYPE (tree), stderr);
2846                 fprintf (stderr, "\n");
2847                 goto errorTreeReturn;
2848               }
2849         }
2850       /* if unsigned value < 0  then always false */
2851       /* if (unsigned value) > 0 then (unsigned value) */
2852       if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) && 
2853           ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2854
2855           if (tree->opval.op == '<') {
2856               return tree->right;
2857           }
2858           if (tree->opval.op == '>') {
2859               return tree->left;
2860           }
2861       }
2862       /* if they are both literal then */
2863       /* rewrite the tree */
2864       if (IS_LITERAL (RTYPE (tree)) &&
2865           IS_LITERAL (LTYPE (tree)))
2866         {
2867           tree->type = EX_VALUE;
2868           tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2869                                         valFromType (RETYPE (tree)),
2870                                         tree->opval.op);
2871           tree->right = tree->left = NULL;
2872           TETYPE (tree) = getSpec (TTYPE (tree) =
2873                                    tree->opval.val->type);
2874           return tree;
2875         }
2876       LRVAL (tree) = RRVAL (tree) = 1;
2877       TTYPE (tree) = TETYPE (tree) = newCharLink ();
2878       return tree;
2879
2880       /*------------------------------------------------------------------*/
2881       /*----------------------------*/
2882       /*             sizeof         */
2883       /*----------------------------*/
2884     case SIZEOF:                /* evaluate wihout code generation */
2885       /* change the type to a integer */
2886       tree->type = EX_VALUE;
2887       sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2888       tree->opval.val = constVal (buffer);
2889       tree->right = tree->left = NULL;
2890       TETYPE (tree) = getSpec (TTYPE (tree) =
2891                                tree->opval.val->type);
2892       return tree;
2893
2894       /*------------------------------------------------------------------*/
2895       /*----------------------------*/
2896       /*             typeof         */
2897       /*----------------------------*/
2898     case TYPEOF:
2899         /* return typeof enum value */
2900         tree->type = EX_VALUE;
2901         {
2902             int typeofv = 0;
2903             if (IS_SPEC(tree->right->ftype)) {
2904                 switch (SPEC_NOUN(tree->right->ftype)) {
2905                 case V_INT:
2906                     if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2907                     else typeofv = TYPEOF_INT;
2908                     break;
2909                 case V_FLOAT:
2910                     typeofv = TYPEOF_FLOAT;
2911                     break;
2912                 case V_CHAR:
2913                     typeofv = TYPEOF_CHAR;
2914                     break;
2915                 case V_VOID:
2916                     typeofv = TYPEOF_VOID;
2917                     break;
2918                 case V_STRUCT:
2919                     typeofv = TYPEOF_STRUCT;
2920                     break;
2921                 case V_BIT:
2922                     typeofv = TYPEOF_BIT;
2923                     break;
2924                 case V_SBIT:
2925                     typeofv = TYPEOF_SBIT;
2926                     break;
2927                 default:
2928                     break;
2929                 }
2930             } else {
2931                 switch (DCL_TYPE(tree->right->ftype)) {
2932                 case POINTER:
2933                     typeofv = TYPEOF_POINTER;
2934                     break;
2935                 case FPOINTER:
2936                     typeofv = TYPEOF_FPOINTER;
2937                     break;
2938                 case CPOINTER:
2939                     typeofv = TYPEOF_CPOINTER;
2940                     break;
2941                 case GPOINTER:
2942                     typeofv = TYPEOF_GPOINTER;
2943                     break;
2944                 case PPOINTER:
2945                     typeofv = TYPEOF_PPOINTER;
2946                     break;
2947                 case IPOINTER:
2948                     typeofv = TYPEOF_IPOINTER;
2949                     break;
2950                 case ARRAY:
2951                     typeofv = TYPEOF_ARRAY;
2952                     break;
2953                 case FUNCTION:
2954                     typeofv = TYPEOF_FUNCTION;
2955                     break;
2956                 default:
2957                     break;
2958                 }
2959             }
2960             sprintf (buffer, "%d", typeofv);
2961             tree->opval.val = constVal (buffer);
2962             tree->right = tree->left = NULL;
2963             TETYPE (tree) = getSpec (TTYPE (tree) =
2964                                      tree->opval.val->type);
2965         }
2966         return tree;
2967       /*------------------------------------------------------------------*/
2968       /*----------------------------*/
2969       /* conditional operator  '?'  */
2970       /*----------------------------*/
2971     case '?':
2972       /* the type is value of the colon operator (on the right) */
2973       assert(IS_COLON_OP(tree->right));
2974       /* if already known then replace the tree : optimizer will do it
2975          but faster to do it here */
2976       if (IS_LITERAL (LTYPE(tree))) {     
2977           if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2978               return decorateType(tree->right->left) ;
2979           } else {
2980               return decorateType(tree->right->right) ;
2981           }
2982       } else {
2983           tree->right = decorateType(tree->right);
2984           TTYPE (tree) = RTYPE(tree);
2985           TETYPE (tree) = getSpec (TTYPE (tree));
2986       }
2987       return tree;
2988
2989     case ':':
2990       /* if they don't match we have a problem */
2991       if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2992         {
2993           werror (E_TYPE_MISMATCH, "conditional operator", " ");
2994           goto errorTreeReturn;
2995         }
2996
2997       TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2998       TETYPE (tree) = getSpec (TTYPE (tree));
2999       return tree;
3000
3001
3002 #if 0 // assignment operators are converted by the parser
3003       /*------------------------------------------------------------------*/
3004       /*----------------------------*/
3005       /*    assignment operators    */
3006       /*----------------------------*/
3007     case MUL_ASSIGN:
3008     case DIV_ASSIGN:
3009       /* for these it must be both must be integral */
3010       if (!IS_ARITHMETIC (LTYPE (tree)) ||
3011           !IS_ARITHMETIC (RTYPE (tree)))
3012         {
3013           werror (E_OPS_INTEGRAL);
3014           goto errorTreeReturn;
3015         }
3016       RRVAL (tree) = 1;
3017       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3018
3019       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3020         werror (E_CODE_WRITE, " ");
3021
3022       if (LRVAL (tree))
3023         {
3024           werror (E_LVALUE_REQUIRED, "*= or /=");
3025           goto errorTreeReturn;
3026         }
3027       LLVAL (tree) = 1;
3028
3029       return tree;
3030
3031     case AND_ASSIGN:
3032     case OR_ASSIGN:
3033     case XOR_ASSIGN:
3034     case RIGHT_ASSIGN:
3035     case LEFT_ASSIGN:
3036       /* for these it must be both must be integral */
3037       if (!IS_INTEGRAL (LTYPE (tree)) ||
3038           !IS_INTEGRAL (RTYPE (tree)))
3039         {
3040           werror (E_OPS_INTEGRAL);
3041           goto errorTreeReturn;
3042         }
3043       RRVAL (tree) = 1;
3044       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3045
3046       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3047         werror (E_CODE_WRITE, " ");
3048
3049       if (LRVAL (tree))
3050         {
3051           werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3052           goto errorTreeReturn;
3053         }
3054       LLVAL (tree) = 1;
3055
3056       return tree;
3057
3058       /*------------------------------------------------------------------*/
3059       /*----------------------------*/
3060       /*    -= operator             */
3061       /*----------------------------*/
3062     case SUB_ASSIGN:
3063       if (!(IS_PTR (LTYPE (tree)) ||
3064             IS_ARITHMETIC (LTYPE (tree))))
3065         {
3066           werror (E_PLUS_INVALID, "-=");
3067           goto errorTreeReturn;
3068         }
3069
3070       if (!(IS_PTR (RTYPE (tree)) ||
3071             IS_ARITHMETIC (RTYPE (tree))))
3072         {
3073           werror (E_PLUS_INVALID, "-=");
3074           goto errorTreeReturn;
3075         }
3076       RRVAL (tree) = 1;
3077       TETYPE (tree) = getSpec (TTYPE (tree) =
3078                                computeType (LTYPE (tree),
3079                                             RTYPE (tree)));
3080
3081       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3082         werror (E_CODE_WRITE, " ");
3083
3084       if (LRVAL (tree))
3085         {
3086           werror (E_LVALUE_REQUIRED, "-=");
3087           goto errorTreeReturn;
3088         }
3089       LLVAL (tree) = 1;
3090
3091       return tree;
3092
3093       /*------------------------------------------------------------------*/
3094       /*----------------------------*/
3095       /*          += operator       */
3096       /*----------------------------*/
3097     case ADD_ASSIGN:
3098       /* this is not a unary operation */
3099       /* if both pointers then problem */
3100       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3101         {
3102           werror (E_PTR_PLUS_PTR);
3103           goto errorTreeReturn;
3104         }
3105
3106       if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3107         {
3108           werror (E_PLUS_INVALID, "+=");
3109           goto errorTreeReturn;
3110         }
3111
3112       if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3113         {
3114           werror (E_PLUS_INVALID, "+=");
3115           goto errorTreeReturn;
3116         }
3117       RRVAL (tree) = 1;
3118       TETYPE (tree) = getSpec (TTYPE (tree) =
3119                                computeType (LTYPE (tree),
3120                                             RTYPE (tree)));
3121
3122       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3123         werror (E_CODE_WRITE, " ");
3124
3125       if (LRVAL (tree))
3126         {
3127           werror (E_LVALUE_REQUIRED, "+=");
3128           goto errorTreeReturn;
3129         }
3130
3131       tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3132       tree->opval.op = '=';
3133
3134       return tree;
3135 #endif
3136
3137       /*------------------------------------------------------------------*/
3138       /*----------------------------*/
3139       /*      straight assignemnt   */
3140       /*----------------------------*/
3141     case '=':
3142       /* cannot be an aggregate */
3143       if (IS_AGGREGATE (LTYPE (tree)))
3144         {
3145           werror (E_AGGR_ASSIGN);
3146           goto errorTreeReturn;
3147         }
3148
3149       /* they should either match or be castable */
3150       if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3151         {
3152           werror (E_TYPE_MISMATCH, "assignment", " ");
3153           printFromToType(RTYPE(tree),LTYPE(tree));
3154           //goto errorTreeReturn;
3155         }
3156
3157       /* if the left side of the tree is of type void
3158          then report error */
3159       if (IS_VOID (LTYPE (tree)))
3160         {
3161           werror (E_CAST_ZERO);
3162           printFromToType(RTYPE(tree), LTYPE(tree));
3163         }
3164
3165       TETYPE (tree) = getSpec (TTYPE (tree) =
3166                                LTYPE (tree));
3167       RRVAL (tree) = 1;
3168       LLVAL (tree) = 1;
3169       if (!tree->initMode ) {
3170         if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3171           werror (E_CODE_WRITE, " ");
3172       }
3173       if (LRVAL (tree))
3174         {
3175           werror (E_LVALUE_REQUIRED, "=");
3176           goto errorTreeReturn;
3177         }
3178
3179       return tree;
3180
3181       /*------------------------------------------------------------------*/
3182       /*----------------------------*/
3183       /*      comma operator        */
3184       /*----------------------------*/
3185     case ',':
3186       TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3187       return tree;
3188
3189       /*------------------------------------------------------------------*/
3190       /*----------------------------*/
3191       /*       function call        */
3192       /*----------------------------*/
3193     case CALL:
3194       parmNumber = 1;
3195
3196       if (processParms (tree->left,
3197                         FUNC_ARGS(tree->left->ftype),
3198                         tree->right, &parmNumber, TRUE)) {
3199         goto errorTreeReturn;
3200       }
3201
3202       if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) && 
3203           !IFFUNC_ISBUILTIN(LTYPE(tree)))
3204         {
3205           //FUNC_ARGS(tree->left->ftype) = 
3206           //reverseVal (FUNC_ARGS(tree->left->ftype));
3207           reverseParms (tree->right);
3208         }
3209
3210       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3211       return tree;
3212
3213       /*------------------------------------------------------------------*/
3214       /*----------------------------*/
3215       /*     return statement       */
3216       /*----------------------------*/
3217     case RETURN:
3218       if (!tree->right)
3219         goto voidcheck;
3220
3221       if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3222         {
3223           werror (W_RETURN_MISMATCH);
3224           printFromToType (RTYPE(tree), currFunc->type->next);
3225           goto errorTreeReturn;
3226         }
3227
3228       if (IS_VOID (currFunc->type->next)
3229           && tree->right &&
3230           !IS_VOID (RTYPE (tree)))
3231         {
3232           werror (E_FUNC_VOID);
3233           goto errorTreeReturn;
3234         }
3235
3236       /* if there is going to be a casing required then add it */
3237       if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3238         {
3239           tree->right =
3240             decorateType (newNode (CAST,
3241                            newAst_LINK (copyLinkChain (currFunc->type->next)),
3242                                    tree->right));
3243         }
3244
3245       RRVAL (tree) = 1;
3246       return tree;
3247
3248     voidcheck:
3249
3250       if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3251         {
3252           werror (E_VOID_FUNC, currFunc->name);
3253           goto errorTreeReturn;
3254         }
3255
3256       TTYPE (tree) = TETYPE (tree) = NULL;
3257       return tree;
3258
3259       /*------------------------------------------------------------------*/
3260       /*----------------------------*/
3261       /*     switch statement       */
3262       /*----------------------------*/
3263     case SWITCH:
3264       /* the switch value must be an integer */
3265       if (!IS_INTEGRAL (LTYPE (tree)))
3266         {
3267           werror (E_SWITCH_NON_INTEGER);
3268           goto errorTreeReturn;
3269         }
3270       LRVAL (tree) = 1;
3271       TTYPE (tree) = TETYPE (tree) = NULL;
3272       return tree;
3273
3274       /*------------------------------------------------------------------*/
3275       /*----------------------------*/
3276       /* ifx Statement              */
3277       /*----------------------------*/
3278     case IFX:
3279       tree->left = backPatchLabels (tree->left,
3280                                     tree->trueLabel,
3281                                     tree->falseLabel);
3282       TTYPE (tree) = TETYPE (tree) = NULL;
3283       return tree;
3284
3285       /*------------------------------------------------------------------*/
3286       /*----------------------------*/
3287       /* for Statement              */
3288       /*----------------------------*/
3289     case FOR:
3290
3291       decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3292       decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3293       decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3294
3295       /* if the for loop is reversible then
3296          reverse it otherwise do what we normally
3297          do */
3298       {
3299         symbol *sym;
3300         ast *init, *end;
3301
3302         if (isLoopReversible (tree, &sym, &init, &end))
3303           return reverseLoop (tree, sym, init, end);
3304         else
3305           return decorateType (createFor (AST_FOR (tree, trueLabel),
3306                                           AST_FOR (tree, continueLabel),
3307                                           AST_FOR (tree, falseLabel),
3308                                           AST_FOR (tree, condLabel),
3309                                           AST_FOR (tree, initExpr),
3310                                           AST_FOR (tree, condExpr),
3311                                           AST_FOR (tree, loopExpr),
3312                                           tree->left));
3313       }
3314     default:
3315       TTYPE (tree) = TETYPE (tree) = NULL;
3316       return tree;
3317     }
3318
3319   /* some error found this tree will be killed */
3320 errorTreeReturn:
3321   TTYPE (tree) = TETYPE (tree) = newCharLink ();
3322   tree->opval.op = NULLOP;
3323   tree->isError = 1;
3324
3325   return tree;
3326 }
3327
3328 /*-----------------------------------------------------------------*/
3329 /* sizeofOp - processes size of operation                          */
3330 /*-----------------------------------------------------------------*/
3331 value *
3332 sizeofOp (sym_link * type)
3333 {
3334   char buff[10];
3335
3336   /* make sure the type is complete and sane */
3337   checkTypeSanity(type, "(sizeof)");
3338
3339   /* get the size and convert it to character  */
3340   sprintf (buff, "%d", getSize (type));
3341
3342   /* now convert into value  */
3343   return constVal (buff);
3344 }
3345
3346
3347 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3348 #define IS_OR(ex)  (ex->type == EX_OP && ex->opval.op == OR_OP )
3349 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3350 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3351 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3352 #define IS_LT(ex)  (ex->type == EX_OP && ex->opval.op == '<' )
3353 #define IS_GT(ex)  (ex->type == EX_OP && ex->opval.op == '>')
3354
3355 /*-----------------------------------------------------------------*/
3356 /* backPatchLabels - change and or not operators to flow control    */
3357 /*-----------------------------------------------------------------*/
3358 ast *
3359 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3360 {
3361
3362   if (!tree)
3363     return NULL;
3364
3365   if (!(IS_ANDORNOT (tree)))
3366     return tree;
3367
3368   /* if this an and */
3369   if (IS_AND (tree))
3370     {
3371       static int localLbl = 0;
3372       symbol *localLabel;
3373
3374       sprintf (buffer, "_and_%d", localLbl++);
3375       localLabel = newSymbol (buffer, NestLevel);
3376
3377       tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3378
3379       /* if left is already a IFX then just change the if true label in that */
3380       if (!IS_IFX (tree->left))
3381         tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3382
3383       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3384       /* right is a IFX then just join */
3385       if (IS_IFX (tree->right))
3386         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3387
3388       tree->right = createLabel (localLabel, tree->right);
3389       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3390
3391       return newNode (NULLOP, tree->left, tree->right);
3392     }
3393
3394   /* if this is an or operation */
3395   if (IS_OR (tree))
3396     {
3397       static int localLbl = 0;
3398       symbol *localLabel;
3399
3400       sprintf (buffer, "_or_%d", localLbl++);
3401       localLabel = newSymbol (buffer, NestLevel);
3402
3403       tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3404
3405       /* if left is already a IFX then just change the if true label in that */
3406       if (!IS_IFX (tree->left))
3407         tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3408
3409       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3410       /* right is a IFX then just join */
3411       if (IS_IFX (tree->right))
3412         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3413
3414       tree->right = createLabel (localLabel, tree->right);
3415       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3416
3417       return newNode (NULLOP, tree->left, tree->right);
3418     }
3419
3420   /* change not */
3421   if (IS_NOT (tree))
3422     {
3423       int wasnot = IS_NOT (tree->left);
3424       tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3425
3426       /* if the left is already a IFX */
3427       if (!IS_IFX (tree->left))
3428         tree->left = newNode (IFX, tree->left, NULL);
3429
3430       if (wasnot)
3431         {
3432           tree->left->trueLabel = trueLabel;
3433           tree->left->falseLabel = falseLabel;
3434         }
3435       else
3436         {
3437           tree->left->trueLabel = falseLabel;
3438           tree->left->falseLabel = trueLabel;
3439         }
3440       return tree->left;
3441     }
3442
3443   if (IS_IFX (tree))
3444     {
3445       tree->trueLabel = trueLabel;
3446       tree->falseLabel = falseLabel;
3447     }
3448
3449   return tree;
3450 }
3451
3452
3453 /*-----------------------------------------------------------------*/
3454 /* createBlock - create expression tree for block                  */
3455 /*-----------------------------------------------------------------*/
3456 ast *
3457 createBlock (symbol * decl, ast * body)
3458 {
3459   ast *ex;
3460
3461   /* if the block has nothing */
3462   if (!body)
3463     return NULL;
3464
3465   ex = newNode (BLOCK, NULL, body);
3466   ex->values.sym = decl;
3467
3468   ex->right = ex->right;
3469   ex->level++;
3470   ex->lineno = 0;
3471   return ex;
3472 }
3473
3474 /*-----------------------------------------------------------------*/
3475 /* createLabel - creates the expression tree for labels            */
3476 /*-----------------------------------------------------------------*/
3477 ast *
3478 createLabel (symbol * label, ast * stmnt)
3479 {
3480   symbol *csym;
3481   char name[SDCC_NAME_MAX + 1];
3482   ast *rValue;
3483
3484   /* must create fresh symbol if the symbol name  */
3485   /* exists in the symbol table, since there can  */
3486   /* be a variable with the same name as the labl */
3487   if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3488       (csym->level == label->level))
3489     label = newSymbol (label->name, label->level);
3490
3491   /* change the name before putting it in add _ */
3492   sprintf (name, "%s", label->name);
3493
3494   /* put the label in the LabelSymbol table    */
3495   /* but first check if a label of the same    */
3496   /* name exists                               */
3497   if ((csym = findSym (LabelTab, NULL, name)))
3498     werror (E_DUPLICATE_LABEL, label->name);
3499   else
3500     addSym (LabelTab, label, name, label->level, 0, 0);
3501
3502   label->islbl = 1;
3503   label->key = labelKey++;
3504   rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3505   rValue->lineno = 0;
3506
3507   return rValue;
3508 }
3509
3510 /*-----------------------------------------------------------------*/
3511 /* createCase - generates the parsetree for a case statement       */
3512 /*-----------------------------------------------------------------*/
3513 ast *
3514 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3515 {
3516   char caseLbl[SDCC_NAME_MAX + 1];
3517   ast *rexpr;
3518   value *val;
3519
3520   /* if the switch statement does not exist */
3521   /* then case is out of context            */
3522   if (!swStat)
3523     {
3524       werror (E_CASE_CONTEXT);
3525       return NULL;
3526     }
3527
3528   caseVal = decorateType (resolveSymbols (caseVal));
3529   /* if not a constant then error  */
3530   if (!IS_LITERAL (caseVal->ftype))
3531     {
3532       werror (E_CASE_CONSTANT);
3533       return NULL;
3534     }
3535
3536   /* if not a integer than error */
3537   if (!IS_INTEGRAL (caseVal->ftype))
3538     {
3539       werror (E_CASE_NON_INTEGER);
3540       return NULL;
3541     }
3542
3543   /* find the end of the switch values chain   */
3544   if (!(val = swStat->values.switchVals.swVals))
3545     swStat->values.switchVals.swVals = caseVal->opval.val;
3546   else
3547     {
3548       /* also order the cases according to value */
3549       value *pval = NULL;
3550       int cVal = (int) floatFromVal (caseVal->opval.val);
3551       while (val && (int) floatFromVal (val) < cVal)
3552         {
3553           pval = val;
3554           val = val->next;
3555         }
3556
3557       /* if we reached the end then */
3558       if (!val)
3559         {
3560           pval->next = caseVal->opval.val;
3561         }
3562       else
3563         {
3564           /* we found a value greater than */
3565           /* the current value we must add this */
3566           /* before the value */
3567           caseVal->opval.val->next = val;
3568
3569           /* if this was the first in chain */
3570           if (swStat->values.switchVals.swVals == val)
3571             swStat->values.switchVals.swVals =
3572               caseVal->opval.val;
3573           else
3574             pval->next = caseVal->opval.val;
3575         }
3576
3577     }
3578
3579   /* create the case label   */
3580   sprintf (caseLbl, "_case_%d_%d",
3581            swStat->values.switchVals.swNum,
3582            (int) floatFromVal (caseVal->opval.val));
3583
3584   rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3585   rexpr->lineno = 0;
3586   return rexpr;
3587 }
3588
3589 /*-----------------------------------------------------------------*/
3590 /* createDefault - creates the parse tree for the default statement */
3591 /*-----------------------------------------------------------------*/
3592 ast *
3593 createDefault (ast * swStat, ast * stmnt)
3594 {
3595   char defLbl[SDCC_NAME_MAX + 1];
3596
3597   /* if the switch statement does not exist */
3598   /* then case is out of context            */
3599   if (!swStat)
3600     {
3601       werror (E_CASE_CONTEXT);
3602       return NULL;
3603     }
3604
3605   /* turn on the default flag   */
3606   swStat->values.switchVals.swDefault = 1;
3607
3608   /* create the label  */
3609   sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3610   return createLabel (newSymbol (defLbl, 0), stmnt);
3611 }
3612
3613 /*-----------------------------------------------------------------*/
3614 /* createIf - creates the parsetree for the if statement           */
3615 /*-----------------------------------------------------------------*/
3616 ast *
3617 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3618 {
3619   static int Lblnum = 0;
3620   ast *ifTree;
3621   symbol *ifTrue, *ifFalse, *ifEnd;
3622
3623   /* if neither exists */
3624   if (!elseBody && !ifBody) {
3625     // if there are no side effects (i++, j() etc)
3626     if (!hasSEFcalls(condAst)) {
3627       return condAst;
3628     }
3629   }
3630
3631   /* create the labels */
3632   sprintf (buffer, "_iffalse_%d", Lblnum);
3633   ifFalse = newSymbol (buffer, NestLevel);
3634   /* if no else body then end == false */
3635   if (!elseBody)
3636     ifEnd = ifFalse;
3637   else
3638     {
3639       sprintf (buffer, "_ifend_%d", Lblnum);
3640       ifEnd = newSymbol (buffer, NestLevel);
3641     }
3642
3643   sprintf (buffer, "_iftrue_%d", Lblnum);
3644   ifTrue = newSymbol (buffer, NestLevel);
3645
3646   Lblnum++;
3647
3648   /* attach the ifTrue label to the top of it body */
3649   ifBody = createLabel (ifTrue, ifBody);
3650   /* attach a goto end to the ifBody if else is present */
3651   if (elseBody)
3652     {
3653       ifBody = newNode (NULLOP, ifBody,
3654                         newNode (GOTO,
3655                                  newAst_VALUE (symbolVal (ifEnd)),
3656                                  NULL));
3657       /* put the elseLabel on the else body */
3658       elseBody = createLabel (ifFalse, elseBody);
3659       /* out the end at the end of the body */
3660       elseBody = newNode (NULLOP,
3661                           elseBody,
3662                           createLabel (ifEnd, NULL));
3663     }
3664   else
3665     {
3666       ifBody = newNode (NULLOP, ifBody,
3667                         createLabel (ifFalse, NULL));
3668     }
3669   condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3670   if (IS_IFX (condAst))
3671     ifTree = condAst;
3672   else
3673     ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3674
3675   return newNode (NULLOP, ifTree,
3676                   newNode (NULLOP, ifBody, elseBody));
3677
3678 }
3679
3680 /*-----------------------------------------------------------------*/
3681 /* createDo - creates parse tree for do                            */
3682 /*        _dobody_n:                                               */
3683 /*            statements                                           */
3684 /*        _docontinue_n:                                           */
3685 /*            condition_expression +-> trueLabel -> _dobody_n      */
3686 /*                                 |                               */
3687 /*                                 +-> falseLabel-> _dobreak_n     */
3688 /*        _dobreak_n:                                              */
3689 /*-----------------------------------------------------------------*/
3690 ast *
3691 createDo (symbol * trueLabel, symbol * continueLabel,
3692           symbol * falseLabel, ast * condAst, ast * doBody)
3693 {
3694   ast *doTree;
3695
3696
3697   /* if the body does not exist then it is simple */
3698   if (!doBody)
3699     {
3700       condAst = backPatchLabels (condAst, continueLabel, NULL);
3701       doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3702                 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3703       doTree->trueLabel = continueLabel;
3704       doTree->falseLabel = NULL;
3705       return doTree;
3706     }
3707
3708   /* otherwise we have a body */
3709   condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3710
3711   /* attach the body label to the top */
3712   doBody = createLabel (trueLabel, doBody);
3713   /* attach the continue label to end of body */
3714   doBody = newNode (NULLOP, doBody,
3715                     createLabel (continueLabel, NULL));
3716
3717   /* now put the break label at the end */
3718   if (IS_IFX (condAst))
3719     doTree = condAst;
3720   else
3721     doTree = newIfxNode (condAst, trueLabel, falseLabel);
3722
3723   doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3724
3725   /* putting it together */
3726   return newNode (NULLOP, doBody, doTree);
3727 }
3728
3729 /*-----------------------------------------------------------------*/
3730 /* createFor - creates parse tree for 'for' statement              */
3731 /*        initExpr                                                 */
3732 /*   _forcond_n:                                                   */
3733 /*        condExpr  +-> trueLabel -> _forbody_n                    */
3734 /*                  |                                              */
3735 /*                  +-> falseLabel-> _forbreak_n                   */
3736 /*   _forbody_n:                                                   */
3737 /*        statements                                               */
3738 /*   _forcontinue_n:                                               */
3739 /*        loopExpr                                                 */
3740 /*        goto _forcond_n ;                                        */
3741 /*   _forbreak_n:                                                  */
3742 /*-----------------------------------------------------------------*/
3743 ast *
3744 createFor (symbol * trueLabel, symbol * continueLabel,
3745            symbol * falseLabel, symbol * condLabel,
3746            ast * initExpr, ast * condExpr, ast * loopExpr,
3747            ast * forBody)
3748 {
3749   ast *forTree;
3750
3751   /* if loopexpression not present then we can generate it */
3752   /* the same way as a while */
3753   if (!loopExpr)
3754     return newNode (NULLOP, initExpr,
3755                     createWhile (trueLabel, continueLabel,
3756                                  falseLabel, condExpr, forBody));
3757   /* vanilla for statement */
3758   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3759
3760   if (condExpr && !IS_IFX (condExpr))
3761     condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3762
3763
3764   /* attach condition label to condition */
3765   condExpr = createLabel (condLabel, condExpr);
3766
3767   /* attach body label to body */
3768   forBody = createLabel (trueLabel, forBody);
3769
3770   /* attach continue to forLoop expression & attach */
3771   /* goto the forcond @ and of loopExpression       */
3772   loopExpr = createLabel (continueLabel,
3773                           newNode (NULLOP,
3774                                    loopExpr,
3775                                    newNode (GOTO,
3776                                        newAst_VALUE (symbolVal (condLabel)),
3777                                             NULL)));
3778   /* now start putting them together */
3779   forTree = newNode (NULLOP, initExpr, condExpr);
3780   forTree = newNode (NULLOP, forTree, forBody);
3781   forTree = newNode (NULLOP, forTree, loopExpr);
3782   /* finally add the break label */
3783   forTree = newNode (NULLOP, forTree,
3784                      createLabel (falseLabel, NULL));
3785   return forTree;
3786 }
3787
3788 /*-----------------------------------------------------------------*/
3789 /* createWhile - creates parse tree for while statement            */
3790 /*               the while statement will be created as follows    */
3791 /*                                                                 */
3792 /*      _while_continue_n:                                         */
3793 /*            condition_expression +-> trueLabel -> _while_boby_n  */
3794 /*                                 |                               */
3795 /*                                 +-> falseLabel -> _while_break_n */
3796 /*      _while_body_n:                                             */
3797 /*            statements                                           */
3798 /*            goto _while_continue_n                               */
3799 /*      _while_break_n:                                            */
3800 /*-----------------------------------------------------------------*/
3801 ast *
3802 createWhile (symbol * trueLabel, symbol * continueLabel,
3803              symbol * falseLabel, ast * condExpr, ast * whileBody)
3804 {
3805   ast *whileTree;
3806
3807   /* put the continue label */
3808   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3809   condExpr = createLabel (continueLabel, condExpr);
3810   condExpr->lineno = 0;
3811
3812   /* put the body label in front of the body */
3813   whileBody = createLabel (trueLabel, whileBody);
3814   whileBody->lineno = 0;
3815   /* put a jump to continue at the end of the body */
3816   /* and put break label at the end of the body */
3817   whileBody = newNode (NULLOP,
3818                        whileBody,
3819                        newNode (GOTO,
3820                                 newAst_VALUE (symbolVal (continueLabel)),
3821                                 createLabel (falseLabel, NULL)));
3822
3823   /* put it all together */
3824   if (IS_IFX (condExpr))
3825     whileTree = condExpr;
3826   else
3827     {
3828       whileTree = newNode (IFX, condExpr, NULL);
3829       /* put the true & false labels in place */
3830       whileTree->trueLabel = trueLabel;
3831       whileTree->falseLabel = falseLabel;
3832     }
3833
3834   return newNode (NULLOP, whileTree, whileBody);
3835 }
3836
3837 /*-----------------------------------------------------------------*/
3838 /* optimizeGetHbit - get highest order bit of the expression       */
3839 /*-----------------------------------------------------------------*/
3840 ast *
3841 optimizeGetHbit (ast * tree)
3842 {
3843   int i, j;
3844   /* if this is not a bit and */
3845   if (!IS_BITAND (tree))
3846     return tree;
3847
3848   /* will look for tree of the form
3849      ( expr >> ((sizeof expr) -1) ) & 1 */
3850   if (!IS_AST_LIT_VALUE (tree->right))
3851     return tree;
3852
3853   if (AST_LIT_VALUE (tree->right) != 1)
3854     return tree;
3855
3856   if (!IS_RIGHT_OP (tree->left))
3857     return tree;
3858
3859   if (!IS_AST_LIT_VALUE (tree->left->right))
3860     return tree;
3861
3862   if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3863       (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3864     return tree;
3865
3866   return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3867
3868 }
3869
3870 /*-----------------------------------------------------------------*/
3871 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry     */
3872 /*-----------------------------------------------------------------*/
3873 ast *
3874 optimizeRRCRLC (ast * root)
3875 {
3876   /* will look for trees of the form
3877      (?expr << 1) | (?expr >> 7) or
3878      (?expr >> 7) | (?expr << 1) will make that
3879      into a RLC : operation ..
3880      Will also look for
3881      (?expr >> 1) | (?expr << 7) or
3882      (?expr << 7) | (?expr >> 1) will make that
3883      into a RRC operation
3884      note : by 7 I mean (number of bits required to hold the
3885      variable -1 ) */
3886   /* if the root operations is not a | operation the not */
3887   if (!IS_BITOR (root))
3888     return root;
3889
3890   /* I have to think of a better way to match patterns this sucks */
3891   /* that aside let start looking for the first case : I use a the
3892      negative check a lot to improve the efficiency */
3893   /* (?expr << 1) | (?expr >> 7) */
3894   if (IS_LEFT_OP (root->left) &&
3895       IS_RIGHT_OP (root->right))
3896     {
3897
3898       if (!SPEC_USIGN (TETYPE (root->left->left)))
3899         return root;
3900
3901       if (!IS_AST_LIT_VALUE (root->left->right) ||
3902           !IS_AST_LIT_VALUE (root->right->right))
3903         goto tryNext0;
3904
3905       /* make sure it is the same expression */
3906       if (!isAstEqual (root->left->left,
3907                        root->right->left))
3908         goto tryNext0;
3909
3910       if (AST_LIT_VALUE (root->left->right) != 1)
3911         goto tryNext0;
3912
3913       if (AST_LIT_VALUE (root->right->right) !=
3914           (getSize (TTYPE (root->left->left)) * 8 - 1))
3915         goto tryNext0;
3916
3917       /* whew got the first case : create the AST */
3918       return newNode (RLC, root->left->left, NULL);
3919     }
3920
3921 tryNext0:
3922   /* check for second case */
3923   /* (?expr >> 7) | (?expr << 1) */
3924   if (IS_LEFT_OP (root->right) &&
3925       IS_RIGHT_OP (root->left))
3926     {
3927
3928       if (!SPEC_USIGN (TETYPE (root->left->left)))
3929         return root;
3930
3931       if (!IS_AST_LIT_VALUE (root->left->right) ||
3932           !IS_AST_LIT_VALUE (root->right->right))
3933         goto tryNext1;
3934
3935       /* make sure it is the same symbol */
3936       if (!isAstEqual (root->left->left,
3937                        root->right->left))
3938         goto tryNext1;
3939
3940       if (AST_LIT_VALUE (root->right->right) != 1)
3941         goto tryNext1;
3942
3943       if (AST_LIT_VALUE (root->left->right) !=
3944           (getSize (TTYPE (root->left->left)) * 8 - 1))
3945         goto tryNext1;
3946
3947       /* whew got the first case : create the AST */
3948       return newNode (RLC, root->left->left, NULL);
3949
3950     }
3951
3952 tryNext1:
3953   /* third case for RRC */
3954   /*  (?symbol >> 1) | (?symbol << 7) */
3955   if (IS_LEFT_OP (root->right) &&
3956       IS_RIGHT_OP (root->left))
3957     {
3958
3959       if (!SPEC_USIGN (TETYPE (root->left->left)))
3960         return root;
3961
3962       if (!IS_AST_LIT_VALUE (root->left->right) ||
3963           !IS_AST_LIT_VALUE (root->right->right))
3964         goto tryNext2;
3965
3966       /* make sure it is the same symbol */
3967       if (!isAstEqual (root->left->left,
3968                        root->right->left))
3969         goto tryNext2;
3970
3971       if (AST_LIT_VALUE (root->left->right) != 1)
3972         goto tryNext2;
3973
3974       if (AST_LIT_VALUE (root->right->right) !=
3975           (getSize (TTYPE (root->left->left)) * 8 - 1))
3976         goto tryNext2;
3977
3978       /* whew got the first case : create the AST */
3979       return newNode (RRC, root->left->left, NULL);
3980
3981     }
3982 tryNext2:
3983   /* fourth and last case for now */
3984   /* (?symbol << 7) | (?symbol >> 1) */
3985   if (IS_RIGHT_OP (root->right) &&
3986       IS_LEFT_OP (root->left))
3987     {
3988
3989       if (!SPEC_USIGN (TETYPE (root->left->left)))
3990         return root;
3991
3992       if (!IS_AST_LIT_VALUE (root->left->right) ||
3993           !IS_AST_LIT_VALUE (root->right->right))
3994         return root;
3995
3996       /* make sure it is the same symbol */
3997       if (!isAstEqual (root->left->left,
3998                        root->right->left))
3999         return root;
4000
4001       if (AST_LIT_VALUE (root->right->right) != 1)
4002         return root;
4003
4004       if (AST_LIT_VALUE (root->left->right) !=
4005           (getSize (TTYPE (root->left->left)) * 8 - 1))
4006         return root;
4007
4008       /* whew got the first case : create the AST */
4009       return newNode (RRC, root->left->left, NULL);
4010
4011     }
4012
4013   /* not found return root */
4014   return root;
4015 }
4016
4017 /*-----------------------------------------------------------------*/
4018 /* optimizeCompare - otimizes compares for bit variables     */
4019 /*-----------------------------------------------------------------*/
4020 static ast *
4021 optimizeCompare (ast * root)
4022 {
4023   ast *optExpr = NULL;
4024   value *vleft;
4025   value *vright;
4026   unsigned int litValue;
4027
4028   /* if nothing then return nothing */
4029   if (!root)
4030     return NULL;
4031
4032   /* if not a compare op then do leaves */
4033   if (!IS_COMPARE_OP (root))
4034     {
4035       root->left = optimizeCompare (root->left);
4036       root->right = optimizeCompare (root->right);
4037       return root;
4038     }
4039
4040   /* if left & right are the same then depending
4041      of the operation do */
4042   if (isAstEqual (root->left, root->right))
4043     {
4044       switch (root->opval.op)
4045         {
4046         case '>':
4047         case '<':
4048         case NE_OP:
4049           optExpr = newAst_VALUE (constVal ("0"));
4050           break;
4051         case GE_OP:
4052         case LE_OP:
4053         case EQ_OP:
4054           optExpr = newAst_VALUE (constVal ("1"));
4055           break;
4056         }
4057
4058       return decorateType (optExpr);
4059     }
4060
4061   vleft = (root->left->type == EX_VALUE ?
4062            root->left->opval.val : NULL);
4063
4064   vright = (root->right->type == EX_VALUE ?
4065             root->right->opval.val : NULL);
4066
4067   /* if left is a BITVAR in BITSPACE */
4068   /* and right is a LITERAL then opt- */
4069   /* imize else do nothing       */
4070   if (vleft && vright &&
4071       IS_BITVAR (vleft->etype) &&
4072       IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4073       IS_LITERAL (vright->etype))
4074     {
4075
4076       /* if right side > 1 then comparison may never succeed */
4077       if ((litValue = (int) floatFromVal (vright)) > 1)
4078         {
4079           werror (W_BAD_COMPARE);
4080           goto noOptimize;
4081         }
4082
4083       if (litValue)
4084         {
4085           switch (root->opval.op)
4086             {
4087             case '>':           /* bit value greater than 1 cannot be */
4088               werror (W_BAD_COMPARE);
4089               goto noOptimize;
4090               break;
4091
4092             case '<':           /* bit value < 1 means 0 */
4093             case NE_OP:
4094               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4095               break;
4096
4097             case LE_OP: /* bit value <= 1 means no check */
4098               optExpr = newAst_VALUE (vright);
4099               break;
4100
4101             case GE_OP: /* bit value >= 1 means only check for = */
4102             case EQ_OP:
4103               optExpr = newAst_VALUE (vleft);
4104               break;
4105             }
4106         }
4107       else
4108         {                       /* literal is zero */
4109           switch (root->opval.op)
4110             {
4111             case '<':           /* bit value < 0 cannot be */
4112               werror (W_BAD_COMPARE);
4113               goto noOptimize;
4114               break;
4115
4116             case '>':           /* bit value > 0 means 1 */
4117             case NE_OP:
4118               optExpr = newAst_VALUE (vleft);
4119               break;
4120
4121             case LE_OP: /* bit value <= 0 means no check */
4122             case GE_OP: /* bit value >= 0 means no check */
4123               werror (W_BAD_COMPARE);
4124               goto noOptimize;
4125               break;
4126
4127             case EQ_OP: /* bit == 0 means ! of bit */
4128               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4129               break;
4130             }
4131         }
4132       return decorateType (resolveSymbols (optExpr));
4133     }                           /* end-of-if of BITVAR */
4134
4135 noOptimize:
4136   return root;
4137 }
4138 /*-----------------------------------------------------------------*/
4139 /* addSymToBlock : adds the symbol to the first block we find      */
4140 /*-----------------------------------------------------------------*/
4141 void 
4142 addSymToBlock (symbol * sym, ast * tree)
4143 {
4144   /* reached end of tree or a leaf */
4145   if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4146     return;
4147
4148   /* found a block */
4149   if (IS_AST_OP (tree) &&
4150       tree->opval.op == BLOCK)
4151     {
4152
4153       symbol *lsym = copySymbol (sym);
4154
4155       lsym->next = AST_VALUES (tree, sym);
4156       AST_VALUES (tree, sym) = lsym;
4157       return;
4158     }
4159
4160   addSymToBlock (sym, tree->left);
4161   addSymToBlock (sym, tree->right);
4162 }
4163
4164 /*-----------------------------------------------------------------*/
4165 /* processRegParms - do processing for register parameters         */
4166 /*-----------------------------------------------------------------*/
4167 static void 
4168 processRegParms (value * args, ast * body)
4169 {
4170   while (args)
4171     {
4172       if (IS_REGPARM (args->etype))
4173         addSymToBlock (args->sym, body);
4174       args = args->next;
4175     }
4176 }
4177
4178 /*-----------------------------------------------------------------*/
4179 /* resetParmKey - resets the operandkeys for the symbols           */
4180 /*-----------------------------------------------------------------*/
4181 DEFSETFUNC (resetParmKey)
4182 {
4183   symbol *sym = item;
4184
4185   sym->key = 0;
4186   sym->defs = NULL;
4187   sym->uses = NULL;
4188   sym->remat = 0;
4189   return 1;
4190 }
4191
4192 /*-----------------------------------------------------------------*/
4193 /* createFunction - This is the key node that calls the iCode for  */
4194 /*                  generating the code for a function. Note code  */
4195 /*                  is generated function by function, later when  */
4196 /*                  add inter-procedural analysis this will change */
4197 /*-----------------------------------------------------------------*/
4198 ast *
4199 createFunction (symbol * name, ast * body)
4200 {
4201   ast *ex;
4202   symbol *csym;
4203   int stack = 0;
4204   sym_link *fetype;
4205   iCode *piCode = NULL;
4206
4207   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4208     fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4209
4210   /* if check function return 0 then some problem */
4211   if (checkFunction (name, NULL) == 0)
4212     return NULL;
4213
4214   /* create a dummy block if none exists */
4215   if (!body)
4216     body = newNode (BLOCK, NULL, NULL);
4217
4218   noLineno++;
4219
4220   /* check if the function name already in the symbol table */
4221   if ((csym = findSym (SymbolTab, NULL, name->name)))
4222     {
4223       name = csym;
4224       /* special case for compiler defined functions
4225          we need to add the name to the publics list : this
4226          actually means we are now compiling the compiler
4227          support routine */
4228       if (name->cdef)
4229         {
4230           addSet (&publics, name);
4231         }
4232     }
4233   else
4234     {
4235       addSymChain (name);
4236       allocVariables (name);
4237     }
4238   name->lastLine = yylineno;
4239   currFunc = name;
4240
4241   /* set the stack pointer */
4242   /* PENDING: check this for the mcs51 */
4243   stackPtr = -port->stack.direction * port->stack.call_overhead;
4244   if (IFFUNC_ISISR (name->type))
4245     stackPtr -= port->stack.direction * port->stack.isr_overhead;
4246   if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4247     stackPtr -= port->stack.direction * port->stack.reent_overhead;
4248
4249   xstackPtr = -port->stack.direction * port->stack.call_overhead;
4250
4251   fetype = getSpec (name->type);        /* get the specifier for the function */
4252   /* if this is a reentrant function then */
4253   if (IFFUNC_ISREENT (name->type))
4254     reentrant++;
4255
4256   allocParms (FUNC_ARGS(name->type));   /* allocate the parameters */
4257
4258   /* do processing for parameters that are passed in registers */
4259   processRegParms (FUNC_ARGS(name->type), body);
4260
4261   /* set the stack pointer */
4262   stackPtr = 0;
4263   xstackPtr = -1;
4264
4265   /* allocate & autoinit the block variables */
4266   processBlockVars (body, &stack, ALLOCATE);
4267
4268   /* save the stack information */
4269   if (options.useXstack)
4270     name->xstack = SPEC_STAK (fetype) = stack;
4271   else
4272     name->stack = SPEC_STAK (fetype) = stack;
4273
4274   /* name needs to be mangled */
4275   sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4276
4277   body = resolveSymbols (body); /* resolve the symbols */
4278   body = decorateType (body);   /* propagateType & do semantic checks */
4279
4280   ex = newAst_VALUE (symbolVal (name)); /* create name */
4281   ex = newNode (FUNCTION, ex, body);
4282   ex->values.args = FUNC_ARGS(name->type);
4283   ex->decorated=1;
4284   if (options.dump_tree) PA(ex);
4285   if (fatalError)
4286     {
4287       werror (E_FUNC_NO_CODE, name->name);
4288       goto skipall;
4289     }
4290
4291   /* create the node & generate intermediate code */
4292   GcurMemmap = code;
4293   codeOutFile = code->oFile;
4294   piCode = iCodeFromAst (ex);
4295
4296   if (fatalError)
4297     {
4298       werror (E_FUNC_NO_CODE, name->name);
4299       goto skipall;
4300     }
4301
4302   eBBlockFromiCode (piCode);
4303
4304   /* if there are any statics then do them */
4305   if (staticAutos)
4306     {
4307       GcurMemmap = statsg;
4308       codeOutFile = statsg->oFile;
4309       eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4310       staticAutos = NULL;
4311     }
4312
4313 skipall:
4314
4315   /* dealloc the block variables */
4316   processBlockVars (body, &stack, DEALLOCATE);
4317   /* deallocate paramaters */
4318   deallocParms (FUNC_ARGS(name->type));
4319
4320   if (IFFUNC_ISREENT (name->type))
4321     reentrant--;
4322
4323   /* we are done freeup memory & cleanup */
4324   noLineno--;
4325   if (port->reset_labelKey) labelKey = 1;
4326   name->key = 0;
4327   FUNC_HASBODY(name->type) = 1;
4328   addSet (&operKeyReset, name);
4329   applyToSet (operKeyReset, resetParmKey);
4330
4331   if (options.debug)
4332     cdbStructBlock (1, cdbFile);
4333
4334   cleanUpLevel (LabelTab, 0);
4335   cleanUpBlock (StructTab, 1);
4336   cleanUpBlock (TypedefTab, 1);
4337
4338   xstack->syms = NULL;
4339   istack->syms = NULL;
4340   return NULL;
4341 }
4342
4343
4344 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4345 /*-----------------------------------------------------------------*/
4346 /* ast_print : prints the ast (for debugging purposes)             */
4347 /*-----------------------------------------------------------------*/
4348
4349 void ast_print (ast * tree, FILE *outfile, int indent)
4350 {
4351         
4352         if (!tree) return ;
4353
4354         /* can print only decorated trees */
4355         if (!tree->decorated) return;
4356
4357         /* if any child is an error | this one is an error do nothing */
4358         if (tree->isError ||
4359             (tree->left && tree->left->isError) ||
4360             (tree->right && tree->right->isError)) {
4361                 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4362         }
4363
4364         
4365         /* print the line          */
4366         /* if not block & function */
4367         if (tree->type == EX_OP &&
4368             (tree->opval.op != FUNCTION &&
4369              tree->opval.op != BLOCK &&
4370              tree->opval.op != NULLOP)) {
4371         }
4372         
4373         if (tree->opval.op == FUNCTION) {
4374                 int arg=0;
4375                 value *args=FUNC_ARGS(tree->left->opval.val->type);
4376                 fprintf(outfile,"FUNCTION (%s=%p) type (", 
4377                         tree->left->opval.val->name, tree);
4378                 printTypeChain (tree->ftype,outfile);
4379                 fprintf(outfile,") args (");
4380                 do {
4381                   if (arg) {
4382                     fprintf (outfile, ", ");
4383                   }
4384                   printTypeChain (args ? args->type : NULL, outfile);
4385                   arg++;
4386                   args= args ? args->next : NULL;
4387                 } while (args);
4388                 fprintf(outfile,")\n");
4389                 ast_print(tree->left,outfile,indent);
4390                 ast_print(tree->right,outfile,indent);
4391                 return ;
4392         }
4393         if (tree->opval.op == BLOCK) {
4394                 symbol *decls = tree->values.sym;
4395                 INDENT(indent,outfile);
4396                 fprintf(outfile,"{\n");
4397                 while (decls) {
4398                         INDENT(indent+2,outfile);
4399                         fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4400                                 decls->name, decls);
4401                         printTypeChain(decls->type,outfile);
4402                         fprintf(outfile,")\n");
4403                         
4404                         decls = decls->next;                    
4405                 }
4406                 ast_print(tree->right,outfile,indent+2);
4407                 INDENT(indent,outfile);
4408                 fprintf(outfile,"}\n");
4409                 return;
4410         }
4411         if (tree->opval.op == NULLOP) {
4412                 fprintf(outfile,"\n");
4413                 ast_print(tree->left,outfile,indent);
4414                 fprintf(outfile,"\n");
4415                 ast_print(tree->right,outfile,indent);
4416                 return ;
4417         }
4418         INDENT(indent,outfile);
4419
4420         /*------------------------------------------------------------------*/
4421         /*----------------------------*/
4422         /*   leaf has been reached    */
4423         /*----------------------------*/
4424         /* if this is of type value */
4425         /* just get the type        */
4426         if (tree->type == EX_VALUE) {
4427
4428                 if (IS_LITERAL (tree->opval.val->etype)) {                      
4429                         fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4430                                 (int) floatFromVal(tree->opval.val),
4431                                 (int) floatFromVal(tree->opval.val),
4432                                 floatFromVal(tree->opval.val));
4433                 } else if (tree->opval.val->sym) {
4434                         /* if the undefined flag is set then give error message */
4435                         if (tree->opval.val->sym->undefined) {
4436                                 fprintf(outfile,"UNDEFINED SYMBOL ");
4437                         } else {
4438                                 fprintf(outfile,"SYMBOL ");
4439                         }
4440                         fprintf(outfile,"(%s=%p)",
4441                                 tree->opval.val->sym->name,tree);
4442                 }
4443                 if (tree->ftype) {
4444                         fprintf(outfile," type (");
4445                         printTypeChain(tree->ftype,outfile);
4446                         fprintf(outfile,")\n");
4447                 } else {
4448                         fprintf(outfile,"\n");
4449                 }
4450                 return ;
4451         }
4452
4453         /* if type link for the case of cast */
4454         if (tree->type == EX_LINK) {
4455                 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4456                 printTypeChain(tree->opval.lnk,outfile);
4457                 fprintf(outfile,")\n");
4458                 return ;
4459         }
4460
4461
4462         /* depending on type of operator do */
4463         
4464         switch (tree->opval.op) {
4465                 /*------------------------------------------------------------------*/
4466                 /*----------------------------*/
4467                 /*        array node          */
4468                 /*----------------------------*/
4469         case '[':
4470                 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4471                 printTypeChain(tree->ftype,outfile);
4472                 fprintf(outfile,")\n");
4473                 ast_print(tree->left,outfile,indent+2);
4474                 ast_print(tree->right,outfile,indent+2);
4475                 return;
4476
4477                 /*------------------------------------------------------------------*/
4478                 /*----------------------------*/
4479                 /*      struct/union          */
4480                 /*----------------------------*/
4481         case '.':
4482                 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4483                 printTypeChain(tree->ftype,outfile);
4484                 fprintf(outfile,")\n");
4485                 ast_print(tree->left,outfile,indent+2);
4486                 ast_print(tree->right,outfile,indent+2);
4487                 return ;
4488
4489                 /*------------------------------------------------------------------*/
4490                 /*----------------------------*/
4491                 /*    struct/union pointer    */
4492                 /*----------------------------*/
4493         case PTR_OP:
4494                 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4495                 printTypeChain(tree->ftype,outfile);
4496                 fprintf(outfile,")\n");
4497                 ast_print(tree->left,outfile,indent+2);
4498                 ast_print(tree->right,outfile,indent+2);
4499                 return ;
4500
4501                 /*------------------------------------------------------------------*/
4502                 /*----------------------------*/
4503                 /*  ++/-- operation           */
4504                 /*----------------------------*/
4505         case INC_OP:            /* incerement operator unary so left only */
4506                 fprintf(outfile,"INC_OP (%p) type (",tree);
4507                 printTypeChain(tree->ftype,outfile);
4508                 fprintf(outfile,")\n");
4509                 ast_print(tree->left,outfile,indent+2);
4510                 return ;
4511
4512         case DEC_OP:
4513                 fprintf(outfile,"DEC_OP (%p) type (",tree);
4514                 printTypeChain(tree->ftype,outfile);
4515                 fprintf(outfile,")\n");
4516                 ast_print(tree->left,outfile,indent+2);
4517                 return ;
4518
4519                 /*------------------------------------------------------------------*/
4520                 /*----------------------------*/
4521                 /*  bitwise and               */
4522                 /*----------------------------*/
4523         case '&':                       
4524                 if (tree->right) {
4525                         fprintf(outfile,"& (%p) type (",tree);
4526                         printTypeChain(tree->ftype,outfile);
4527                         fprintf(outfile,")\n");
4528                         ast_print(tree->left,outfile,indent+2);
4529                         ast_print(tree->right,outfile,indent+2);
4530                 } else {
4531                         fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4532                         printTypeChain(tree->ftype,outfile);
4533                         fprintf(outfile,")\n");
4534                         ast_print(tree->left,outfile,indent+2);
4535                         ast_print(tree->right,outfile,indent+2);
4536                 }
4537                 return ;
4538                 /*----------------------------*/
4539                 /*  bitwise or                */
4540                 /*----------------------------*/
4541         case '|':
4542                 fprintf(outfile,"OR (%p) type (",tree);
4543                 printTypeChain(tree->ftype,outfile);
4544                 fprintf(outfile,")\n");
4545                 ast_print(tree->left,outfile,indent+2);
4546                 ast_print(tree->right,outfile,indent+2);
4547                 return ;
4548                 /*------------------------------------------------------------------*/
4549                 /*----------------------------*/
4550                 /*  bitwise xor               */
4551                 /*----------------------------*/
4552         case '^':
4553                 fprintf(outfile,"XOR (%p) type (",tree);
4554                 printTypeChain(tree->ftype,outfile);
4555                 fprintf(outfile,")\n");
4556                 ast_print(tree->left,outfile,indent+2);
4557                 ast_print(tree->right,outfile,indent+2);
4558                 return ;
4559                 
4560                 /*------------------------------------------------------------------*/
4561                 /*----------------------------*/
4562                 /*  division                  */
4563                 /*----------------------------*/
4564         case '/':
4565                 fprintf(outfile,"DIV (%p) type (",tree);
4566                 printTypeChain(tree->ftype,outfile);
4567                 fprintf(outfile,")\n");
4568                 ast_print(tree->left,outfile,indent+2);
4569                 ast_print(tree->right,outfile,indent+2);
4570                 return ;
4571                 /*------------------------------------------------------------------*/
4572                 /*----------------------------*/
4573                 /*            modulus         */
4574                 /*----------------------------*/
4575         case '%':
4576                 fprintf(outfile,"MOD (%p) type (",tree);
4577                 printTypeChain(tree->ftype,outfile);
4578                 fprintf(outfile,")\n");
4579                 ast_print(tree->left,outfile,indent+2);
4580                 ast_print(tree->right,outfile,indent+2);
4581                 return ;
4582
4583                 /*------------------------------------------------------------------*/
4584                 /*----------------------------*/
4585                 /*  address dereference       */
4586                 /*----------------------------*/
4587         case '*':                       /* can be unary  : if right is null then unary operation */
4588                 if (!tree->right) {
4589                         fprintf(outfile,"DEREF (%p) type (",tree);
4590                         printTypeChain(tree->ftype,outfile);
4591                         fprintf(outfile,")\n");
4592                         ast_print(tree->left,outfile,indent+2);
4593                         return ;
4594                 }                       
4595                 /*------------------------------------------------------------------*/
4596                 /*----------------------------*/
4597                 /*      multiplication        */
4598                 /*----------------------------*/                
4599                 fprintf(outfile,"MULT (%p) type (",tree);
4600                 printTypeChain(tree->ftype,outfile);
4601                 fprintf(outfile,")\n");
4602                 ast_print(tree->left,outfile,indent+2);
4603                 ast_print(tree->right,outfile,indent+2);
4604                 return ;
4605
4606
4607                 /*------------------------------------------------------------------*/
4608                 /*----------------------------*/
4609                 /*    unary '+' operator      */
4610                 /*----------------------------*/
4611         case '+':
4612                 /* if unary plus */
4613                 if (!tree->right) {
4614                         fprintf(outfile,"UPLUS (%p) type (",tree);
4615                         printTypeChain(tree->ftype,outfile);
4616                         fprintf(outfile,")\n");
4617                         ast_print(tree->left,outfile,indent+2);
4618                 } else {
4619                         /*------------------------------------------------------------------*/
4620                         /*----------------------------*/
4621                         /*      addition              */
4622                         /*----------------------------*/
4623                         fprintf(outfile,"ADD (%p) type (",tree);
4624                         printTypeChain(tree->ftype,outfile);
4625                         fprintf(outfile,")\n");
4626                         ast_print(tree->left,outfile,indent+2);
4627                         ast_print(tree->right,outfile,indent+2);
4628                 }
4629                 return;
4630                 /*------------------------------------------------------------------*/
4631                 /*----------------------------*/
4632                 /*      unary '-'             */
4633                 /*----------------------------*/
4634         case '-':                       /* can be unary   */
4635                 if (!tree->right) {
4636                         fprintf(outfile,"UMINUS (%p) type (",tree);
4637                         printTypeChain(tree->ftype,outfile);
4638                         fprintf(outfile,")\n");
4639                         ast_print(tree->left,outfile,indent+2);
4640                 } else {
4641                         /*------------------------------------------------------------------*/
4642                         /*----------------------------*/
4643                         /*      subtraction           */
4644                         /*----------------------------*/
4645                         fprintf(outfile,"SUB (%p) type (",tree);
4646                         printTypeChain(tree->ftype,outfile);
4647                         fprintf(outfile,")\n");
4648                         ast_print(tree->left,outfile,indent+2);
4649                         ast_print(tree->right,outfile,indent+2);
4650                 }
4651                 return;
4652                 /*------------------------------------------------------------------*/
4653                 /*----------------------------*/
4654                 /*    compliment              */
4655                 /*----------------------------*/
4656         case '~':
4657                 fprintf(outfile,"COMPL (%p) type (",tree);
4658                 printTypeChain(tree->ftype,outfile);
4659                 fprintf(outfile,")\n");
4660                 ast_print(tree->left,outfile,indent+2);
4661                 return ;
4662                 /*------------------------------------------------------------------*/
4663                 /*----------------------------*/
4664                 /*           not              */
4665                 /*----------------------------*/
4666         case '!':
4667                 fprintf(outfile,"NOT (%p) type (",tree);
4668                 printTypeChain(tree->ftype,outfile);
4669                 fprintf(outfile,")\n");
4670                 ast_print(tree->left,outfile,indent+2);
4671                 return ;
4672                 /*------------------------------------------------------------------*/
4673                 /*----------------------------*/
4674                 /*           shift            */
4675                 /*----------------------------*/
4676         case RRC:
4677                 fprintf(outfile,"RRC (%p) type (",tree);
4678                 printTypeChain(tree->ftype,outfile);
4679                 fprintf(outfile,")\n");
4680                 ast_print(tree->left,outfile,indent+2);
4681                 return ;
4682
4683         case RLC:
4684                 fprintf(outfile,"RLC (%p) type (",tree);
4685                 printTypeChain(tree->ftype,outfile);
4686                 fprintf(outfile,")\n");
4687                 ast_print(tree->left,outfile,indent+2);
4688                 return ;
4689         case GETHBIT:
4690                 fprintf(outfile,"GETHBIT (%p) type (",tree);
4691                 printTypeChain(tree->ftype,outfile);
4692                 fprintf(outfile,")\n");
4693                 ast_print(tree->left,outfile,indent+2);
4694                 return ;
4695         case LEFT_OP:
4696                 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4697                 printTypeChain(tree->ftype,outfile);
4698                 fprintf(outfile,")\n");
4699                 ast_print(tree->left,outfile,indent+2);
4700                 ast_print(tree->right,outfile,indent+2);
4701                 return ;
4702         case RIGHT_OP:
4703                 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4704                 printTypeChain(tree->ftype,outfile);
4705                 fprintf(outfile,")\n");
4706                 ast_print(tree->left,outfile,indent+2);
4707                 ast_print(tree->right,outfile,indent+2);
4708                 return ;
4709                 /*------------------------------------------------------------------*/
4710                 /*----------------------------*/
4711                 /*         casting            */
4712                 /*----------------------------*/
4713         case CAST:                      /* change the type   */
4714                 fprintf(outfile,"CAST (%p) from type (",tree);
4715                 printTypeChain(tree->right->ftype,outfile);
4716                 fprintf(outfile,") to type (");
4717                 printTypeChain(tree->ftype,outfile);
4718                 fprintf(outfile,")\n");
4719                 ast_print(tree->right,outfile,indent+2);
4720                 return ;
4721                 
4722         case AND_OP:
4723                 fprintf(outfile,"ANDAND (%p) type (",tree);
4724                 printTypeChain(tree->ftype,outfile);
4725                 fprintf(outfile,")\n");
4726                 ast_print(tree->left,outfile,indent+2);
4727                 ast_print(tree->right,outfile,indent+2);
4728                 return ;
4729         case OR_OP:
4730                 fprintf(outfile,"OROR (%p) type (",tree);
4731                 printTypeChain(tree->ftype,outfile);
4732                 fprintf(outfile,")\n");
4733                 ast_print(tree->left,outfile,indent+2);
4734                 ast_print(tree->right,outfile,indent+2);
4735                 return ;
4736                 
4737                 /*------------------------------------------------------------------*/
4738                 /*----------------------------*/
4739                 /*     comparison operators   */
4740                 /*----------------------------*/
4741         case '>':
4742                 fprintf(outfile,"GT(>) (%p) type (",tree);
4743                 printTypeChain(tree->ftype,outfile);
4744                 fprintf(outfile,")\n");
4745                 ast_print(tree->left,outfile,indent+2);
4746                 ast_print(tree->right,outfile,indent+2);
4747                 return ;
4748         case '<':
4749                 fprintf(outfile,"LT(<) (%p) type (",tree);
4750                 printTypeChain(tree->ftype,outfile);
4751                 fprintf(outfile,")\n");
4752                 ast_print(tree->left,outfile,indent+2);
4753                 ast_print(tree->right,outfile,indent+2);
4754                 return ;
4755         case LE_OP:
4756                 fprintf(outfile,"LE(<=) (%p) type (",tree);
4757                 printTypeChain(tree->ftype,outfile);
4758                 fprintf(outfile,")\n");
4759                 ast_print(tree->left,outfile,indent+2);
4760                 ast_print(tree->right,outfile,indent+2);
4761                 return ;
4762         case GE_OP:
4763                 fprintf(outfile,"GE(>=) (%p) type (",tree);
4764                 printTypeChain(tree->ftype,outfile);
4765                 fprintf(outfile,")\n");
4766                 ast_print(tree->left,outfile,indent+2);
4767                 ast_print(tree->right,outfile,indent+2);
4768                 return ;
4769         case EQ_OP:
4770                 fprintf(outfile,"EQ(==) (%p) type (",tree);
4771                 printTypeChain(tree->ftype,outfile);
4772                 fprintf(outfile,")\n");
4773                 ast_print(tree->left,outfile,indent+2);
4774                 ast_print(tree->right,outfile,indent+2);
4775                 return ;
4776         case NE_OP:
4777                 fprintf(outfile,"NE(!=) (%p) type (",tree);
4778                 printTypeChain(tree->ftype,outfile);
4779                 fprintf(outfile,")\n");
4780                 ast_print(tree->left,outfile,indent+2);
4781                 ast_print(tree->right,outfile,indent+2);
4782                 /*------------------------------------------------------------------*/
4783                 /*----------------------------*/
4784                 /*             sizeof         */
4785                 /*----------------------------*/
4786         case SIZEOF:            /* evaluate wihout code generation */
4787                 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4788                 return ;
4789
4790                 /*------------------------------------------------------------------*/
4791                 /*----------------------------*/
4792                 /* conditional operator  '?'  */
4793                 /*----------------------------*/
4794         case '?':
4795                 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4796                 printTypeChain(tree->ftype,outfile);
4797                 fprintf(outfile,")\n");
4798                 ast_print(tree->left,outfile,indent+2);
4799                 ast_print(tree->right,outfile,indent+2);
4800                 return;
4801
4802         case ':':
4803                 fprintf(outfile,"COLON(:) (%p) type (",tree);
4804                 printTypeChain(tree->ftype,outfile);
4805                 fprintf(outfile,")\n");
4806                 ast_print(tree->left,outfile,indent+2);
4807                 ast_print(tree->right,outfile,indent+2);
4808                 return ;
4809                 
4810                 /*------------------------------------------------------------------*/
4811                 /*----------------------------*/
4812                 /*    assignment operators    */
4813                 /*----------------------------*/
4814         case MUL_ASSIGN:
4815                 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4816                 printTypeChain(tree->ftype,outfile);
4817                 fprintf(outfile,")\n");
4818                 ast_print(tree->left,outfile,indent+2);
4819                 ast_print(tree->right,outfile,indent+2);
4820                 return;
4821         case DIV_ASSIGN:
4822                 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4823                 printTypeChain(tree->ftype,outfile);
4824                 fprintf(outfile,")\n");
4825                 ast_print(tree->left,outfile,indent+2);
4826                 ast_print(tree->right,outfile,indent+2);
4827                 return;
4828         case AND_ASSIGN:
4829                 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4830                 printTypeChain(tree->ftype,outfile);
4831                 fprintf(outfile,")\n");
4832                 ast_print(tree->left,outfile,indent+2);
4833                 ast_print(tree->right,outfile,indent+2);
4834                 return;
4835         case OR_ASSIGN:
4836                 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4837                 printTypeChain(tree->ftype,outfile);
4838                 fprintf(outfile,")\n");
4839                 ast_print(tree->left,outfile,indent+2);
4840                 ast_print(tree->right,outfile,indent+2);
4841                 return;
4842         case XOR_ASSIGN:
4843                 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4844                 printTypeChain(tree->ftype,outfile);
4845                 fprintf(outfile,")\n");
4846                 ast_print(tree->left,outfile,indent+2);
4847                 ast_print(tree->right,outfile,indent+2);
4848                 return;
4849         case RIGHT_ASSIGN:
4850                 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4851                 printTypeChain(tree->ftype,outfile);
4852                 fprintf(outfile,")\n");
4853                 ast_print(tree->left,outfile,indent+2);
4854                 ast_print(tree->right,outfile,indent+2);
4855                 return;
4856         case LEFT_ASSIGN:
4857                 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4858                 printTypeChain(tree->ftype,outfile);
4859                 fprintf(outfile,")\n");
4860                 ast_print(tree->left,outfile,indent+2);
4861                 ast_print(tree->right,outfile,indent+2);
4862                 return;
4863                 /*------------------------------------------------------------------*/
4864                 /*----------------------------*/
4865                 /*    -= operator             */
4866                 /*----------------------------*/
4867         case SUB_ASSIGN:
4868                 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4869                 printTypeChain(tree->ftype,outfile);
4870                 fprintf(outfile,")\n");
4871                 ast_print(tree->left,outfile,indent+2);
4872                 ast_print(tree->right,outfile,indent+2);
4873                 return;
4874                 /*------------------------------------------------------------------*/
4875                 /*----------------------------*/
4876                 /*          += operator       */
4877                 /*----------------------------*/
4878         case ADD_ASSIGN:
4879                 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4880                 printTypeChain(tree->ftype,outfile);
4881                 fprintf(outfile,")\n");
4882                 ast_print(tree->left,outfile,indent+2);
4883                 ast_print(tree->right,outfile,indent+2);
4884                 return;
4885                 /*------------------------------------------------------------------*/
4886                 /*----------------------------*/
4887                 /*      straight assignemnt   */
4888                 /*----------------------------*/
4889         case '=':
4890                 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4891                 printTypeChain(tree->ftype,outfile);
4892                 fprintf(outfile,")\n");
4893                 ast_print(tree->left,outfile,indent+2);
4894                 ast_print(tree->right,outfile,indent+2);
4895                 return;     
4896                 /*------------------------------------------------------------------*/
4897                 /*----------------------------*/
4898                 /*      comma operator        */
4899                 /*----------------------------*/
4900         case ',':
4901                 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4902                 printTypeChain(tree->ftype,outfile);
4903                 fprintf(outfile,")\n");
4904                 ast_print(tree->left,outfile,indent+2);
4905                 ast_print(tree->right,outfile,indent+2);
4906                 return;
4907                 /*------------------------------------------------------------------*/
4908                 /*----------------------------*/
4909                 /*       function call        */
4910                 /*----------------------------*/
4911         case CALL:
4912         case PCALL:
4913                 fprintf(outfile,"CALL (%p) type (",tree);
4914                 printTypeChain(tree->ftype,outfile);
4915                 fprintf(outfile,")\n");
4916                 ast_print(tree->left,outfile,indent+2);
4917                 ast_print(tree->right,outfile,indent+2);
4918                 return;
4919         case PARAM:
4920                 fprintf(outfile,"PARMS\n");
4921                 ast_print(tree->left,outfile,indent+2);
4922                 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4923                         ast_print(tree->right,outfile,indent+2);
4924                 }
4925                 return ;
4926                 /*------------------------------------------------------------------*/
4927                 /*----------------------------*/
4928                 /*     return statement       */
4929                 /*----------------------------*/
4930         case RETURN:
4931                 fprintf(outfile,"RETURN (%p) type (",tree);
4932                 if (tree->right) {
4933                     printTypeChain(tree->right->ftype,outfile);
4934                 }
4935                 fprintf(outfile,")\n");
4936                 ast_print(tree->right,outfile,indent+2);
4937                 return ;
4938                 /*------------------------------------------------------------------*/
4939                 /*----------------------------*/
4940                 /*     label statement        */
4941                 /*----------------------------*/
4942         case LABEL :
4943                 fprintf(outfile,"LABEL (%p)\n",tree);
4944                 ast_print(tree->left,outfile,indent+2);
4945                 ast_print(tree->right,outfile,indent);
4946                 return;
4947                 /*------------------------------------------------------------------*/
4948                 /*----------------------------*/
4949                 /*     switch statement       */
4950                 /*----------------------------*/
4951         case SWITCH:
4952                 {
4953                         value *val;
4954                         fprintf(outfile,"SWITCH (%p) ",tree);
4955                         ast_print(tree->left,outfile,0);
4956                         for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4957                                 INDENT(indent+2,outfile);
4958                                 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4959                                         (int) floatFromVal(val),
4960                                         tree->values.switchVals.swNum,
4961                                         (int) floatFromVal(val));
4962                         }
4963                         ast_print(tree->right,outfile,indent);
4964                 }
4965                 return ;
4966                 /*------------------------------------------------------------------*/
4967                 /*----------------------------*/
4968                 /* ifx Statement              */
4969                 /*----------------------------*/
4970         case IFX:
4971                 fprintf(outfile,"IF (%p) \n",tree);
4972                 ast_print(tree->left,outfile,indent+2);
4973                 if (tree->trueLabel) {
4974                         INDENT(indent,outfile);
4975                         fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4976                 }
4977                 if (tree->falseLabel) {
4978                         INDENT(indent,outfile);
4979                         fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4980                 }
4981                 ast_print(tree->right,outfile,indent+2);
4982                 return ;
4983                 /*------------------------------------------------------------------*/
4984                 /*----------------------------*/
4985                 /* for Statement              */
4986                 /*----------------------------*/
4987         case FOR:
4988                 fprintf(outfile,"FOR (%p) \n",tree);
4989                 if (AST_FOR( tree, initExpr)) {
4990                         INDENT(indent+2,outfile);
4991                         fprintf(outfile,"INIT EXPR ");
4992                         ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
4993                 }
4994                 if (AST_FOR( tree, condExpr)) {
4995                         INDENT(indent+2,outfile);
4996                         fprintf(outfile,"COND EXPR ");
4997                         ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
4998                 }
4999                 if (AST_FOR( tree, loopExpr)) {
5000                         INDENT(indent+2,outfile);
5001                         fprintf(outfile,"LOOP EXPR ");
5002                         ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5003                 }
5004                 fprintf(outfile,"FOR LOOP BODY \n");
5005                 ast_print(tree->left,outfile,indent+2);
5006                 return ;
5007         default:
5008             return ;
5009         }
5010 }
5011
5012 void PA(ast *t)
5013 {
5014         ast_print(t,stdout,0);
5015 }