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