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