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