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