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