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