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