a better fix for "if ( -v < 3)"
[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 (DECLARATOR);
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 (DECLARATOR);
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 (DECLARATOR);
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         // 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       if (IS_PTR(LTYPE(tree))) {
2065         SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2066       }
2067       return tree;
2068
2069       /*------------------------------------------------------------------*/
2070       /*----------------------------*/
2071       /*      struct/union          */
2072       /*----------------------------*/
2073     case '.':
2074       /* if this is not a structure */
2075       if (!IS_STRUCT (LTYPE (tree)))
2076         {
2077           werror (E_STRUCT_UNION, ".");
2078           goto errorTreeReturn;
2079         }
2080       TTYPE (tree) = structElemType (LTYPE (tree),
2081                                      (tree->right->type == EX_VALUE ?
2082                                tree->right->opval.val : NULL));
2083       TETYPE (tree) = getSpec (TTYPE (tree));
2084       return tree;
2085
2086       /*------------------------------------------------------------------*/
2087       /*----------------------------*/
2088       /*    struct/union pointer    */
2089       /*----------------------------*/
2090     case PTR_OP:
2091       /* if not pointer to a structure */
2092       if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2093         {
2094           werror (E_PTR_REQD);
2095           goto errorTreeReturn;
2096         }
2097
2098       if (!IS_STRUCT (LTYPE (tree)->next))
2099         {
2100           werror (E_STRUCT_UNION, "->");
2101           goto errorTreeReturn;
2102         }
2103
2104       TTYPE (tree) = structElemType (LTYPE (tree)->next,
2105                                      (tree->right->type == EX_VALUE ?
2106                                tree->right->opval.val : NULL));
2107       TETYPE (tree) = getSpec (TTYPE (tree));
2108
2109       /* adjust the storage class */
2110       switch (DCL_TYPE(tree->left->ftype)) {
2111       case POINTER:
2112         break;
2113       case FPOINTER:
2114         SPEC_SCLS(TETYPE(tree)) = S_XDATA; 
2115         break;
2116       case CPOINTER:
2117         SPEC_SCLS(TETYPE(tree)) = S_CODE; 
2118         break;
2119       case GPOINTER:
2120         break;
2121       case PPOINTER:
2122         SPEC_SCLS(TETYPE(tree)) = S_XSTACK; 
2123         break;
2124       case IPOINTER:
2125         SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2126         break;
2127       case EEPPOINTER:
2128         SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2129         break;
2130       case UPOINTER:
2131       case ARRAY:
2132       case FUNCTION:
2133         break;
2134       }
2135
2136       return tree;
2137
2138       /*------------------------------------------------------------------*/
2139       /*----------------------------*/
2140       /*  ++/-- operation           */
2141       /*----------------------------*/
2142     case INC_OP:                /* incerement operator unary so left only */
2143     case DEC_OP:
2144       {
2145         sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2146         COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2147         if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2148           werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2149
2150         if (tree->right)
2151           RLVAL (tree) = 1;
2152         else
2153           LLVAL (tree) = 1;
2154         return tree;
2155       }
2156
2157       /*------------------------------------------------------------------*/
2158       /*----------------------------*/
2159       /*  bitwise and               */
2160       /*----------------------------*/
2161     case '&':                   /* can be unary   */
2162       /* if right is NULL then unary operation  */
2163       if (tree->right)          /* not an unary operation */
2164         {
2165
2166           if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2167             {
2168               werror (E_BITWISE_OP);
2169               werror (W_CONTINUE, "left & right types are ");
2170               printTypeChain (LTYPE (tree), stderr);
2171               fprintf (stderr, ",");
2172               printTypeChain (RTYPE (tree), stderr);
2173               fprintf (stderr, "\n");
2174               goto errorTreeReturn;
2175             }
2176
2177           /* if they are both literal */
2178           if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2179             {
2180               tree->type = EX_VALUE;
2181               tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2182                                           valFromType (RETYPE (tree)), '&');
2183
2184               tree->right = tree->left = NULL;
2185               TETYPE (tree) = tree->opval.val->etype;
2186               TTYPE (tree) = tree->opval.val->type;
2187               return tree;
2188             }
2189
2190           /* see if this is a GETHBIT operation if yes
2191              then return that */
2192           {
2193             ast *otree = optimizeGetHbit (tree);
2194
2195             if (otree != tree)
2196               return decorateType (otree);
2197           }
2198
2199           TTYPE (tree) =
2200             computeType (LTYPE (tree), RTYPE (tree));
2201           TETYPE (tree) = getSpec (TTYPE (tree));
2202
2203           LRVAL (tree) = RRVAL (tree) = 1;
2204           return tree;
2205         }
2206
2207       /*------------------------------------------------------------------*/
2208       /*----------------------------*/
2209       /*  address of                */
2210       /*----------------------------*/
2211       p = newLink (DECLARATOR);
2212       /* if bit field then error */
2213       if (IS_BITVAR (tree->left->etype))
2214         {
2215           werror (E_ILLEGAL_ADDR, "address of bit variable");
2216           goto errorTreeReturn;
2217         }
2218
2219       if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2220         {
2221           werror (E_ILLEGAL_ADDR, "address of register variable");
2222           goto errorTreeReturn;
2223         }
2224
2225       if (IS_FUNC (LTYPE (tree)))
2226         {
2227           // this ought to be ignored
2228           return (tree->left);
2229         }
2230
2231       if (IS_LITERAL(LTYPE(tree)))
2232         {
2233           werror (E_ILLEGAL_ADDR, "address of literal");
2234           goto errorTreeReturn;
2235         }
2236
2237      if (LRVAL (tree))
2238         {
2239           werror (E_LVALUE_REQUIRED, "address of");
2240           goto errorTreeReturn;
2241         }
2242       if (SPEC_SCLS (tree->left->etype) == S_CODE)
2243         {
2244           DCL_TYPE (p) = CPOINTER;
2245           DCL_PTR_CONST (p) = port->mem.code_ro;
2246         }
2247       else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2248         DCL_TYPE (p) = FPOINTER;
2249       else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2250         DCL_TYPE (p) = PPOINTER;
2251       else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2252         DCL_TYPE (p) = IPOINTER;
2253       else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2254         DCL_TYPE (p) = EEPPOINTER;
2255       else if (SPEC_OCLS(tree->left->etype))
2256           DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2257       else
2258           DCL_TYPE (p) = POINTER;
2259
2260       if (IS_AST_SYM_VALUE (tree->left))
2261         {
2262           AST_SYMBOL (tree->left)->addrtaken = 1;
2263           AST_SYMBOL (tree->left)->allocreq = 1;
2264         }
2265
2266       p->next = LTYPE (tree);
2267       TTYPE (tree) = p;
2268       TETYPE (tree) = getSpec (TTYPE (tree));
2269       DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));   
2270       DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree)); 
2271       LLVAL (tree) = 1;
2272       TLVAL (tree) = 1;
2273       return tree;
2274
2275       /*------------------------------------------------------------------*/
2276       /*----------------------------*/
2277       /*  bitwise or                */
2278       /*----------------------------*/
2279     case '|':
2280       /* if the rewrite succeeds then don't go any furthur */
2281       {
2282         ast *wtree = optimizeRRCRLC (tree);
2283         if (wtree != tree)
2284           return decorateType (wtree);
2285         // fall through
2286       }
2287       /*------------------------------------------------------------------*/
2288       /*----------------------------*/
2289       /*  bitwise xor               */
2290       /*----------------------------*/
2291     case '^':
2292       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2293         {
2294           werror (E_BITWISE_OP);
2295           werror (W_CONTINUE, "left & right types are ");
2296           printTypeChain (LTYPE (tree), stderr);
2297           fprintf (stderr, ",");
2298           printTypeChain (RTYPE (tree), stderr);
2299           fprintf (stderr, "\n");
2300           goto errorTreeReturn;
2301         }
2302
2303       /* if they are both literal then */
2304       /* rewrite the tree */
2305       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2306         {
2307           tree->type = EX_VALUE;
2308           tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2309                                         valFromType (RETYPE (tree)),
2310                                         tree->opval.op);
2311           tree->right = tree->left = NULL;
2312           TETYPE (tree) = tree->opval.val->etype;
2313           TTYPE (tree) = tree->opval.val->type;
2314           return tree;
2315         }
2316       LRVAL (tree) = RRVAL (tree) = 1;
2317       TETYPE (tree) = getSpec (TTYPE (tree) =
2318                                computeType (LTYPE (tree),
2319                                             RTYPE (tree)));
2320
2321       /*------------------------------------------------------------------*/
2322       /*----------------------------*/
2323       /*  division                  */
2324       /*----------------------------*/
2325     case '/':
2326       if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2327         {
2328           werror (E_INVALID_OP, "divide");
2329           goto errorTreeReturn;
2330         }
2331       /* if they are both literal then */
2332       /* rewrite the tree */
2333       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2334         {
2335           tree->type = EX_VALUE;
2336           tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2337                                     valFromType (RETYPE (tree)));
2338           tree->right = tree->left = NULL;
2339           TETYPE (tree) = getSpec (TTYPE (tree) =
2340                                    tree->opval.val->type);
2341           return tree;
2342         }
2343       LRVAL (tree) = RRVAL (tree) = 1;
2344       TETYPE (tree) = getSpec (TTYPE (tree) =
2345                                computeType (LTYPE (tree),
2346                                             RTYPE (tree)));
2347       return tree;
2348
2349       /*------------------------------------------------------------------*/
2350       /*----------------------------*/
2351       /*            modulus         */
2352       /*----------------------------*/
2353     case '%':
2354       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2355         {
2356           werror (E_BITWISE_OP);
2357           werror (W_CONTINUE, "left & right types are ");
2358           printTypeChain (LTYPE (tree), stderr);
2359           fprintf (stderr, ",");
2360           printTypeChain (RTYPE (tree), stderr);
2361           fprintf (stderr, "\n");
2362           goto errorTreeReturn;
2363         }
2364       /* if they are both literal then */
2365       /* rewrite the tree */
2366       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2367         {
2368           tree->type = EX_VALUE;
2369           tree->opval.val = valMod (valFromType (LETYPE (tree)),
2370                                     valFromType (RETYPE (tree)));
2371           tree->right = tree->left = NULL;
2372           TETYPE (tree) = getSpec (TTYPE (tree) =
2373                                    tree->opval.val->type);
2374           return tree;
2375         }
2376       LRVAL (tree) = RRVAL (tree) = 1;
2377       TETYPE (tree) = getSpec (TTYPE (tree) =
2378                                computeType (LTYPE (tree),
2379                                             RTYPE (tree)));
2380       return tree;
2381
2382       /*------------------------------------------------------------------*/
2383       /*----------------------------*/
2384       /*  address dereference       */
2385       /*----------------------------*/
2386     case '*':                   /* can be unary  : if right is null then unary operation */
2387       if (!tree->right)
2388         {
2389           if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2390             {
2391               werror (E_PTR_REQD);
2392               goto errorTreeReturn;
2393             }
2394
2395           if (LRVAL (tree))
2396             {
2397               werror (E_LVALUE_REQUIRED, "pointer deref");
2398               goto errorTreeReturn;
2399             }
2400           TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2401           TETYPE (tree) = getSpec (TTYPE (tree));
2402           SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2403           return tree;
2404         }
2405
2406       /*------------------------------------------------------------------*/
2407       /*----------------------------*/
2408       /*      multiplication        */
2409       /*----------------------------*/
2410       if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2411         {
2412           werror (E_INVALID_OP, "multiplication");
2413           goto errorTreeReturn;
2414         }
2415
2416       /* if they are both literal then */
2417       /* rewrite the tree */
2418       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2419         {
2420           tree->type = EX_VALUE;
2421           tree->opval.val = valMult (valFromType (LETYPE (tree)),
2422                                      valFromType (RETYPE (tree)));
2423           tree->right = tree->left = NULL;
2424           TETYPE (tree) = getSpec (TTYPE (tree) =
2425                                    tree->opval.val->type);
2426           return tree;
2427         }
2428
2429       /* if left is a literal exchange left & right */
2430       if (IS_LITERAL (LTYPE (tree)))
2431         {
2432           ast *tTree = tree->left;
2433           tree->left = tree->right;
2434           tree->right = tTree;
2435         }
2436
2437       LRVAL (tree) = RRVAL (tree) = 1;
2438       TETYPE (tree) = getSpec (TTYPE (tree) =
2439                                computeType (LTYPE (tree),
2440                                             RTYPE (tree)));
2441
2442       /* promote result to int if left & right are char
2443          this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2444       if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2445         SPEC_NOUN(TETYPE(tree)) = V_INT;
2446       }
2447
2448       return tree;
2449
2450       /*------------------------------------------------------------------*/
2451       /*----------------------------*/
2452       /*    unary '+' operator      */
2453       /*----------------------------*/
2454     case '+':
2455       /* if unary plus */
2456       if (!tree->right)
2457         {
2458           if (!IS_INTEGRAL (LTYPE (tree)))
2459             {
2460               werror (E_UNARY_OP, '+');
2461               goto errorTreeReturn;
2462             }
2463
2464           /* if left is a literal then do it */
2465           if (IS_LITERAL (LTYPE (tree)))
2466             {
2467               tree->type = EX_VALUE;
2468               tree->opval.val = valFromType (LETYPE (tree));
2469               tree->left = NULL;
2470               TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2471               return tree;
2472             }
2473           LRVAL (tree) = 1;
2474           COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2475           return tree;
2476         }
2477
2478       /*------------------------------------------------------------------*/
2479       /*----------------------------*/
2480       /*      addition              */
2481       /*----------------------------*/
2482
2483       /* this is not a unary operation */
2484       /* if both pointers then problem */
2485       if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2486           (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2487         {
2488           werror (E_PTR_PLUS_PTR);
2489           goto errorTreeReturn;
2490         }
2491
2492       if (!IS_ARITHMETIC (LTYPE (tree)) &&
2493           !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2494         {
2495           werror (E_PLUS_INVALID, "+");
2496           goto errorTreeReturn;
2497         }
2498
2499       if (!IS_ARITHMETIC (RTYPE (tree)) &&
2500           !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2501         {
2502           werror (E_PLUS_INVALID, "+");
2503           goto errorTreeReturn;
2504         }
2505       /* if they are both literal then */
2506       /* rewrite the tree */
2507       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2508         {
2509           tree->type = EX_VALUE;
2510           tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2511                                      valFromType (RETYPE (tree)));
2512           tree->right = tree->left = NULL;
2513           TETYPE (tree) = getSpec (TTYPE (tree) =
2514                                    tree->opval.val->type);
2515           return tree;
2516         }
2517
2518       /* if the right is a pointer or left is a literal
2519          xchange left & right */
2520       if (IS_ARRAY (RTYPE (tree)) ||
2521           IS_PTR (RTYPE (tree)) ||
2522           IS_LITERAL (LTYPE (tree)))
2523         {
2524           ast *tTree = tree->left;
2525           tree->left = tree->right;
2526           tree->right = tTree;
2527         }
2528
2529       LRVAL (tree) = RRVAL (tree) = 1;
2530       /* if the left is a pointer */
2531       if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
2532         TETYPE (tree) = getSpec (TTYPE (tree) =
2533                                  LTYPE (tree));
2534       else
2535         TETYPE (tree) = getSpec (TTYPE (tree) =
2536                                  computeType (LTYPE (tree),
2537                                               RTYPE (tree)));
2538       return tree;
2539
2540       /*------------------------------------------------------------------*/
2541       /*----------------------------*/
2542       /*      unary '-'             */
2543       /*----------------------------*/
2544     case '-':                   /* can be unary   */
2545       /* if right is null then unary */
2546       if (!tree->right)
2547         {
2548
2549           if (!IS_ARITHMETIC (LTYPE (tree)))
2550             {
2551               werror (E_UNARY_OP, tree->opval.op);
2552               goto errorTreeReturn;
2553             }
2554
2555           /* if left is a literal then do it */
2556           if (IS_LITERAL (LTYPE (tree)))
2557             {
2558               tree->type = EX_VALUE;
2559               tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2560               tree->left = NULL;
2561               TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2562               SPEC_USIGN(TETYPE(tree)) = 0;
2563               return tree;
2564             }
2565           LRVAL (tree) = 1;
2566           TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2567           return tree;
2568         }
2569
2570       /*------------------------------------------------------------------*/
2571       /*----------------------------*/
2572       /*    subtraction             */
2573       /*----------------------------*/
2574
2575       if (!(IS_PTR (LTYPE (tree)) ||
2576             IS_ARRAY (LTYPE (tree)) ||
2577             IS_ARITHMETIC (LTYPE (tree))))
2578         {
2579           werror (E_PLUS_INVALID, "-");
2580           goto errorTreeReturn;
2581         }
2582
2583       if (!(IS_PTR (RTYPE (tree)) ||
2584             IS_ARRAY (RTYPE (tree)) ||
2585             IS_ARITHMETIC (RTYPE (tree))))
2586         {
2587           werror (E_PLUS_INVALID, "-");
2588           goto errorTreeReturn;
2589         }
2590
2591       if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2592           !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2593             IS_INTEGRAL (RTYPE (tree))))
2594         {
2595           werror (E_PLUS_INVALID, "-");
2596           goto errorTreeReturn;
2597         }
2598
2599       /* if they are both literal then */
2600       /* rewrite the tree */
2601       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2602         {
2603           tree->type = EX_VALUE;
2604           tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2605                                       valFromType (RETYPE (tree)));
2606           tree->right = tree->left = NULL;
2607           TETYPE (tree) = getSpec (TTYPE (tree) =
2608                                    tree->opval.val->type);
2609           return tree;
2610         }
2611
2612       /* if the left & right are equal then zero */
2613       if (isAstEqual (tree->left, tree->right))
2614         {
2615           tree->type = EX_VALUE;
2616           tree->left = tree->right = NULL;
2617           tree->opval.val = constVal ("0");
2618           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2619           return tree;
2620         }
2621
2622       /* if both of them are pointers or arrays then */
2623       /* the result is going to be an integer        */
2624       if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2625           (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2626         TETYPE (tree) = TTYPE (tree) = newIntLink ();
2627       else
2628         /* if only the left is a pointer */
2629         /* then result is a pointer      */
2630       if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2631         TETYPE (tree) = getSpec (TTYPE (tree) =
2632                                  LTYPE (tree));
2633       else
2634         TETYPE (tree) = getSpec (TTYPE (tree) =
2635                                  computeType (LTYPE (tree),
2636                                               RTYPE (tree)));
2637       LRVAL (tree) = RRVAL (tree) = 1;
2638       return tree;
2639
2640       /*------------------------------------------------------------------*/
2641       /*----------------------------*/
2642       /*    compliment              */
2643       /*----------------------------*/
2644     case '~':
2645       /* can be only integral type */
2646       if (!IS_INTEGRAL (LTYPE (tree)))
2647         {
2648           werror (E_UNARY_OP, tree->opval.op);
2649           goto errorTreeReturn;
2650         }
2651
2652       /* if left is a literal then do it */
2653       if (IS_LITERAL (LTYPE (tree)))
2654         {
2655           tree->type = EX_VALUE;
2656           tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2657           tree->left = NULL;
2658           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2659           return tree;
2660         }
2661       LRVAL (tree) = 1;
2662       COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2663       return tree;
2664
2665       /*------------------------------------------------------------------*/
2666       /*----------------------------*/
2667       /*           not              */
2668       /*----------------------------*/
2669     case '!':
2670       /* can be pointer */
2671       if (!IS_ARITHMETIC (LTYPE (tree)) &&
2672           !IS_PTR (LTYPE (tree)) &&
2673           !IS_ARRAY (LTYPE (tree)))
2674         {
2675           werror (E_UNARY_OP, tree->opval.op);
2676           goto errorTreeReturn;
2677         }
2678
2679       /* if left is a literal then do it */
2680       if (IS_LITERAL (LTYPE (tree)))
2681         {
2682           tree->type = EX_VALUE;
2683           tree->opval.val = valNot (valFromType (LETYPE (tree)));
2684           tree->left = NULL;
2685           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2686           return tree;
2687         }
2688       LRVAL (tree) = 1;
2689       TTYPE (tree) = TETYPE (tree) = newCharLink ();
2690       return tree;
2691
2692       /*------------------------------------------------------------------*/
2693       /*----------------------------*/
2694       /*           shift            */
2695       /*----------------------------*/
2696     case RRC:
2697     case RLC:
2698       TTYPE (tree) = LTYPE (tree);
2699       TETYPE (tree) = LETYPE (tree);
2700       return tree;
2701
2702     case GETHBIT:
2703       TTYPE (tree) = TETYPE (tree) = newCharLink ();
2704       return tree;
2705
2706     case LEFT_OP:
2707     case RIGHT_OP:
2708       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2709         {
2710           werror (E_SHIFT_OP_INVALID);
2711           werror (W_CONTINUE, "left & right types are ");
2712           printTypeChain (LTYPE (tree), stderr);
2713           fprintf (stderr, ",");
2714           printTypeChain (RTYPE (tree), stderr);
2715           fprintf (stderr, "\n");
2716           goto errorTreeReturn;
2717         }
2718
2719       /* if they are both literal then */
2720       /* rewrite the tree */
2721       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2722         {
2723           tree->type = EX_VALUE;
2724           tree->opval.val = valShift (valFromType (LETYPE (tree)),
2725                                       valFromType (RETYPE (tree)),
2726                                       (tree->opval.op == LEFT_OP ? 1 : 0));
2727           tree->right = tree->left = NULL;
2728           TETYPE (tree) = getSpec (TTYPE (tree) =
2729                                    tree->opval.val->type);
2730           return tree;
2731         }
2732
2733       /* if only the right side is a literal & we are
2734          shifting more than size of the left operand then zero */
2735       if (IS_LITERAL (RTYPE (tree)) &&
2736           ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2737           (getSize (LTYPE (tree)) * 8))
2738         {
2739           if (tree->opval.op==LEFT_OP ||
2740               (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) {
2741             lineno=tree->lineno;
2742             werror (W_SHIFT_CHANGED,
2743                     (tree->opval.op == LEFT_OP ? "left" : "right"));
2744             tree->type = EX_VALUE;
2745             tree->left = tree->right = NULL;
2746             tree->opval.val = constVal ("0");
2747             TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2748             return tree;
2749           }
2750         }
2751       LRVAL (tree) = RRVAL (tree) = 1;
2752       if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2753         {
2754           COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2755         }
2756       else
2757         {
2758           COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2759         }
2760       return tree;
2761
2762       /*------------------------------------------------------------------*/
2763       /*----------------------------*/
2764       /*         casting            */
2765       /*----------------------------*/
2766     case CAST:                  /* change the type   */
2767       /* cannot cast to an aggregate type */
2768       if (IS_AGGREGATE (LTYPE (tree)))
2769         {
2770           werror (E_CAST_ILLEGAL);
2771           goto errorTreeReturn;
2772         }
2773       
2774       /* make sure the type is complete and sane */
2775       checkTypeSanity(LETYPE(tree), "(cast)");
2776
2777 #if 0
2778       /* if the right is a literal replace the tree */
2779       if (IS_LITERAL (RETYPE (tree))) {
2780               if (!IS_PTR (LTYPE (tree))) {
2781                       tree->type = EX_VALUE;
2782                       tree->opval.val =
2783                               valCastLiteral (LTYPE (tree),
2784                                               floatFromVal (valFromType (RETYPE (tree))));
2785                       tree->left = NULL;
2786                       tree->right = NULL;
2787                       TTYPE (tree) = tree->opval.val->type;
2788                       tree->values.literalFromCast = 1;
2789               } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) && 
2790                          ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */  {
2791                       sym_link *rest = LTYPE(tree)->next;
2792                       werror(W_LITERAL_GENERIC);                      
2793                       TTYPE(tree) = newLink(DECLARATOR);
2794                       DCL_TYPE(TTYPE(tree)) = FPOINTER;
2795                       TTYPE(tree)->next = rest;
2796                       tree->left->opval.lnk = TTYPE(tree);
2797                       LRVAL (tree) = 1;
2798               } else {
2799                       TTYPE (tree) = LTYPE (tree);
2800                       LRVAL (tree) = 1;
2801               }
2802       } else {
2803               TTYPE (tree) = LTYPE (tree);
2804               LRVAL (tree) = 1;
2805       }
2806 #else
2807 #if 0 // this is already checked, now this could be explicit
2808       /* if pointer to struct then check names */
2809       if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2810           IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2811           strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) 
2812         {
2813           werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
2814                  SPEC_STRUCT(LETYPE(tree))->tag);
2815         }
2816 #endif
2817       /* if the right is a literal replace the tree */
2818       if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2819         tree->type = EX_VALUE;
2820         tree->opval.val =
2821           valCastLiteral (LTYPE (tree),
2822                           floatFromVal (valFromType (RETYPE (tree))));
2823         tree->left = NULL;
2824         tree->right = NULL;
2825         TTYPE (tree) = tree->opval.val->type;
2826         tree->values.literalFromCast = 1;
2827       } else {
2828         TTYPE (tree) = LTYPE (tree);
2829         LRVAL (tree) = 1;
2830       }
2831 #endif      
2832       TETYPE (tree) = getSpec (TTYPE (tree));
2833
2834       return tree;
2835
2836       /*------------------------------------------------------------------*/
2837       /*----------------------------*/
2838       /*       logical &&, ||       */
2839       /*----------------------------*/
2840     case AND_OP:
2841     case OR_OP:
2842       /* each must me arithmetic type or be a pointer */
2843       if (!IS_PTR (LTYPE (tree)) &&
2844           !IS_ARRAY (LTYPE (tree)) &&
2845           !IS_INTEGRAL (LTYPE (tree)))
2846         {
2847           werror (E_COMPARE_OP);
2848           goto errorTreeReturn;
2849         }
2850
2851       if (!IS_PTR (RTYPE (tree)) &&
2852           !IS_ARRAY (RTYPE (tree)) &&
2853           !IS_INTEGRAL (RTYPE (tree)))
2854         {
2855           werror (E_COMPARE_OP);
2856           goto errorTreeReturn;
2857         }
2858       /* if they are both literal then */
2859       /* rewrite the tree */
2860       if (IS_LITERAL (RTYPE (tree)) &&
2861           IS_LITERAL (LTYPE (tree)))
2862         {
2863           tree->type = EX_VALUE;
2864           tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2865                                            valFromType (RETYPE (tree)),
2866                                            tree->opval.op);
2867           tree->right = tree->left = NULL;
2868           TETYPE (tree) = getSpec (TTYPE (tree) =
2869                                    tree->opval.val->type);
2870           return tree;
2871         }
2872       LRVAL (tree) = RRVAL (tree) = 1;
2873       TTYPE (tree) = TETYPE (tree) = newCharLink ();
2874       return tree;
2875
2876       /*------------------------------------------------------------------*/
2877       /*----------------------------*/
2878       /*     comparison operators   */
2879       /*----------------------------*/
2880     case '>':
2881     case '<':
2882     case LE_OP:
2883     case GE_OP:
2884     case EQ_OP:
2885     case NE_OP:
2886       {
2887         ast *lt = optimizeCompare (tree);
2888
2889         if (tree != lt)
2890           return lt;
2891       }
2892
2893       /* if they are pointers they must be castable */
2894       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2895         {
2896           if (tree->opval.op==EQ_OP && 
2897               !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
2898             // we cannot cast a gptr to a !gptr: switch the leaves
2899             struct ast *s=tree->left;
2900             tree->left=tree->right;
2901             tree->right=s;
2902           }
2903           if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2904             {
2905               werror (E_COMPARE_OP);
2906               fprintf (stderr, "comparring type ");
2907               printTypeChain (LTYPE (tree), stderr);
2908               fprintf (stderr, "to type ");
2909               printTypeChain (RTYPE (tree), stderr);
2910               fprintf (stderr, "\n");
2911               goto errorTreeReturn;
2912             }
2913         }
2914       /* else they should be promotable to one another */
2915       else
2916         {
2917           if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2918                 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2919
2920             if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2921               {
2922                 werror (E_COMPARE_OP);
2923                 fprintf (stderr, "comparing type ");
2924                 printTypeChain (LTYPE (tree), stderr);
2925                 fprintf (stderr, "to type ");
2926                 printTypeChain (RTYPE (tree), stderr);
2927                 fprintf (stderr, "\n");
2928                 goto errorTreeReturn;
2929               }
2930         }
2931       /* if unsigned value < 0  then always false */
2932       /* if (unsigned value) > 0 then (unsigned value) */
2933       if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree))  && 
2934           ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2935
2936           if (tree->opval.op == '<') {
2937               return tree->right;
2938           }
2939           if (tree->opval.op == '>') {
2940               return tree->left;
2941           }
2942       }
2943       /* if they are both literal then */
2944       /* rewrite the tree */
2945       if (IS_LITERAL (RTYPE (tree)) &&
2946           IS_LITERAL (LTYPE (tree)))
2947         {
2948           tree->type = EX_VALUE;
2949           tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2950                                         valFromType (RETYPE (tree)),
2951                                         tree->opval.op);
2952           tree->right = tree->left = NULL;
2953           TETYPE (tree) = getSpec (TTYPE (tree) =
2954                                    tree->opval.val->type);
2955           return tree;
2956         }
2957       LRVAL (tree) = RRVAL (tree) = 1;
2958       TTYPE (tree) = TETYPE (tree) = newCharLink ();
2959       return tree;
2960
2961       /*------------------------------------------------------------------*/
2962       /*----------------------------*/
2963       /*             sizeof         */
2964       /*----------------------------*/
2965     case SIZEOF:                /* evaluate wihout code generation */
2966       /* change the type to a integer */
2967       tree->type = EX_VALUE;
2968       SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
2969       tree->opval.val = constVal (buffer);
2970       tree->right = tree->left = NULL;
2971       TETYPE (tree) = getSpec (TTYPE (tree) =
2972                                tree->opval.val->type);
2973       return tree;
2974
2975       /*------------------------------------------------------------------*/
2976       /*----------------------------*/
2977       /*             typeof         */
2978       /*----------------------------*/
2979     case TYPEOF:
2980         /* return typeof enum value */
2981         tree->type = EX_VALUE;
2982         {
2983             int typeofv = 0;
2984             if (IS_SPEC(tree->right->ftype)) {
2985                 switch (SPEC_NOUN(tree->right->ftype)) {
2986                 case V_INT:
2987                     if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2988                     else typeofv = TYPEOF_INT;
2989                     break;
2990                 case V_FLOAT:
2991                     typeofv = TYPEOF_FLOAT;
2992                     break;
2993                 case V_CHAR:
2994                     typeofv = TYPEOF_CHAR;
2995                     break;
2996                 case V_VOID:
2997                     typeofv = TYPEOF_VOID;
2998                     break;
2999                 case V_STRUCT:
3000                     typeofv = TYPEOF_STRUCT;
3001                     break;
3002                 case V_BIT:
3003                     typeofv = TYPEOF_BIT;
3004                     break;
3005                 case V_SBIT:
3006                     typeofv = TYPEOF_SBIT;
3007                     break;
3008                 default:
3009                     break;
3010                 }
3011             } else {
3012                 switch (DCL_TYPE(tree->right->ftype)) {
3013                 case POINTER:
3014                     typeofv = TYPEOF_POINTER;
3015                     break;
3016                 case FPOINTER:
3017                     typeofv = TYPEOF_FPOINTER;
3018                     break;
3019                 case CPOINTER:
3020                     typeofv = TYPEOF_CPOINTER;
3021                     break;
3022                 case GPOINTER:
3023                     typeofv = TYPEOF_GPOINTER;
3024                     break;
3025                 case PPOINTER:
3026                     typeofv = TYPEOF_PPOINTER;
3027                     break;
3028                 case IPOINTER:
3029                     typeofv = TYPEOF_IPOINTER;
3030                     break;
3031                 case ARRAY:
3032                     typeofv = TYPEOF_ARRAY;
3033                     break;
3034                 case FUNCTION:
3035                     typeofv = TYPEOF_FUNCTION;
3036                     break;
3037                 default:
3038                     break;
3039                 }
3040             }
3041             SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3042             tree->opval.val = constVal (buffer);
3043             tree->right = tree->left = NULL;
3044             TETYPE (tree) = getSpec (TTYPE (tree) =
3045                                      tree->opval.val->type);
3046         }
3047         return tree;
3048       /*------------------------------------------------------------------*/
3049       /*----------------------------*/
3050       /* conditional operator  '?'  */
3051       /*----------------------------*/
3052     case '?':
3053       /* the type is value of the colon operator (on the right) */
3054       assert(IS_COLON_OP(tree->right));
3055       /* if already known then replace the tree : optimizer will do it
3056          but faster to do it here */
3057       if (IS_LITERAL (LTYPE(tree))) {     
3058           if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
3059               return decorateType(tree->right->left) ;
3060           } else {
3061               return decorateType(tree->right->right) ;
3062           }
3063       } else {
3064           tree->right = decorateType(tree->right);
3065           TTYPE (tree) = RTYPE(tree);
3066           TETYPE (tree) = getSpec (TTYPE (tree));
3067       }
3068       return tree;
3069
3070     case ':':
3071       /* if they don't match we have a problem */
3072       if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3073         {
3074           werror (E_TYPE_MISMATCH, "conditional operator", " ");
3075           goto errorTreeReturn;
3076         }
3077
3078       TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
3079       TETYPE (tree) = getSpec (TTYPE (tree));
3080       return tree;
3081
3082
3083 #if 0 // assignment operators are converted by the parser
3084       /*------------------------------------------------------------------*/
3085       /*----------------------------*/
3086       /*    assignment operators    */
3087       /*----------------------------*/
3088     case MUL_ASSIGN:
3089     case DIV_ASSIGN:
3090       /* for these it must be both must be integral */
3091       if (!IS_ARITHMETIC (LTYPE (tree)) ||
3092           !IS_ARITHMETIC (RTYPE (tree)))
3093         {
3094           werror (E_OPS_INTEGRAL);
3095           goto errorTreeReturn;
3096         }
3097       RRVAL (tree) = 1;
3098       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3099
3100       if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3101         werror (E_CODE_WRITE, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3102
3103       if (LRVAL (tree))
3104         {
3105           werror (E_LVALUE_REQUIRED, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3106           goto errorTreeReturn;
3107         }
3108       LLVAL (tree) = 1;
3109
3110       return tree;
3111
3112     case AND_ASSIGN:
3113     case OR_ASSIGN:
3114     case XOR_ASSIGN:
3115     case RIGHT_ASSIGN:
3116     case LEFT_ASSIGN:
3117       /* for these it must be both must be integral */
3118       if (!IS_INTEGRAL (LTYPE (tree)) ||
3119           !IS_INTEGRAL (RTYPE (tree)))
3120         {
3121           werror (E_OPS_INTEGRAL);
3122           goto errorTreeReturn;
3123         }
3124       RRVAL (tree) = 1;
3125       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3126
3127       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3128         werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3129
3130       if (LRVAL (tree))
3131         {
3132           werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3133           goto errorTreeReturn;
3134         }
3135       LLVAL (tree) = 1;
3136
3137       return tree;
3138
3139       /*------------------------------------------------------------------*/
3140       /*----------------------------*/
3141       /*    -= operator             */
3142       /*----------------------------*/
3143     case SUB_ASSIGN:
3144       if (!(IS_PTR (LTYPE (tree)) ||
3145             IS_ARITHMETIC (LTYPE (tree))))
3146         {
3147           werror (E_PLUS_INVALID, "-=");
3148           goto errorTreeReturn;
3149         }
3150
3151       if (!(IS_PTR (RTYPE (tree)) ||
3152             IS_ARITHMETIC (RTYPE (tree))))
3153         {
3154           werror (E_PLUS_INVALID, "-=");
3155           goto errorTreeReturn;
3156         }
3157       RRVAL (tree) = 1;
3158       TETYPE (tree) = getSpec (TTYPE (tree) =
3159                                computeType (LTYPE (tree),
3160                                             RTYPE (tree)));
3161
3162       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3163         werror (E_CODE_WRITE, "-=");
3164
3165       if (LRVAL (tree))
3166         {
3167           werror (E_LVALUE_REQUIRED, "-=");
3168           goto errorTreeReturn;
3169         }
3170       LLVAL (tree) = 1;
3171
3172       return tree;
3173
3174       /*------------------------------------------------------------------*/
3175       /*----------------------------*/
3176       /*          += operator       */
3177       /*----------------------------*/
3178     case ADD_ASSIGN:
3179       /* this is not a unary operation */
3180       /* if both pointers then problem */
3181       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3182         {
3183           werror (E_PTR_PLUS_PTR);
3184           goto errorTreeReturn;
3185         }
3186
3187       if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3188         {
3189           werror (E_PLUS_INVALID, "+=");
3190           goto errorTreeReturn;
3191         }
3192
3193       if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3194         {
3195           werror (E_PLUS_INVALID, "+=");
3196           goto errorTreeReturn;
3197         }
3198       RRVAL (tree) = 1;
3199       TETYPE (tree) = getSpec (TTYPE (tree) =
3200                                computeType (LTYPE (tree),
3201                                             RTYPE (tree)));
3202
3203       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3204         werror (E_CODE_WRITE, "+=");
3205
3206       if (LRVAL (tree))
3207         {
3208           werror (E_LVALUE_REQUIRED, "+=");
3209           goto errorTreeReturn;
3210         }
3211
3212       tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3213       tree->opval.op = '=';
3214
3215       return tree;
3216 #endif
3217
3218       /*------------------------------------------------------------------*/
3219       /*----------------------------*/
3220       /*      straight assignemnt   */
3221       /*----------------------------*/
3222     case '=':
3223       /* cannot be an aggregate */
3224       if (IS_AGGREGATE (LTYPE (tree)))
3225         {
3226           werror (E_AGGR_ASSIGN);
3227           goto errorTreeReturn;
3228         }
3229
3230       /* they should either match or be castable */
3231       if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3232         {
3233           werror (E_TYPE_MISMATCH, "assignment", " ");
3234           printFromToType(RTYPE(tree),LTYPE(tree));
3235           //goto errorTreeReturn;
3236         }
3237
3238       /* if the left side of the tree is of type void
3239          then report error */
3240       if (IS_VOID (LTYPE (tree)))
3241         {
3242           werror (E_CAST_ZERO);
3243           printFromToType(RTYPE(tree), LTYPE(tree));
3244         }
3245
3246       TETYPE (tree) = getSpec (TTYPE (tree) =
3247                                LTYPE (tree));
3248       RRVAL (tree) = 1;
3249       LLVAL (tree) = 1;
3250       if (!tree->initMode ) {
3251         if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3252           werror (E_CODE_WRITE, "=");
3253       }
3254       if (LRVAL (tree))
3255         {
3256           werror (E_LVALUE_REQUIRED, "=");
3257           goto errorTreeReturn;
3258         }
3259
3260       return tree;
3261
3262       /*------------------------------------------------------------------*/
3263       /*----------------------------*/
3264       /*      comma operator        */
3265       /*----------------------------*/
3266     case ',':
3267       TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3268       return tree;
3269
3270       /*------------------------------------------------------------------*/
3271       /*----------------------------*/
3272       /*       function call        */
3273       /*----------------------------*/
3274     case CALL:
3275       parmNumber = 1;
3276
3277       if (processParms (tree->left,
3278                         FUNC_ARGS(tree->left->ftype),
3279                         tree->right, &parmNumber, TRUE)) {
3280         goto errorTreeReturn;
3281       }
3282
3283       if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) && 
3284           !IFFUNC_ISBUILTIN(LTYPE(tree)))
3285         {
3286           //FUNC_ARGS(tree->left->ftype) = 
3287           //reverseVal (FUNC_ARGS(tree->left->ftype));
3288           reverseParms (tree->right);
3289         }
3290
3291       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3292       return tree;
3293
3294       /*------------------------------------------------------------------*/
3295       /*----------------------------*/
3296       /*     return statement       */
3297       /*----------------------------*/
3298     case RETURN:
3299       if (!tree->right)
3300         goto voidcheck;
3301
3302       if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3303         {
3304           werror (W_RETURN_MISMATCH);
3305           printFromToType (RTYPE(tree), currFunc->type->next);
3306           goto errorTreeReturn;
3307         }
3308
3309       if (IS_VOID (currFunc->type->next)
3310           && tree->right &&
3311           !IS_VOID (RTYPE (tree)))
3312         {
3313           werror (E_FUNC_VOID);
3314           goto errorTreeReturn;
3315         }
3316
3317       /* if there is going to be a casing required then add it */
3318       if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3319         {
3320           tree->right =
3321             decorateType (newNode (CAST,
3322                            newAst_LINK (copyLinkChain (currFunc->type->next)),
3323                                    tree->right));
3324         }
3325
3326       RRVAL (tree) = 1;
3327       return tree;
3328
3329     voidcheck:
3330
3331       if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3332         {
3333           werror (E_VOID_FUNC, currFunc->name);
3334           goto errorTreeReturn;
3335         }
3336
3337       TTYPE (tree) = TETYPE (tree) = NULL;
3338       return tree;
3339
3340       /*------------------------------------------------------------------*/
3341       /*----------------------------*/
3342       /*     switch statement       */
3343       /*----------------------------*/
3344     case SWITCH:
3345       /* the switch value must be an integer */
3346       if (!IS_INTEGRAL (LTYPE (tree)))
3347         {
3348           werror (E_SWITCH_NON_INTEGER);
3349           goto errorTreeReturn;
3350         }
3351       LRVAL (tree) = 1;
3352       TTYPE (tree) = TETYPE (tree) = NULL;
3353       return tree;
3354
3355       /*------------------------------------------------------------------*/
3356       /*----------------------------*/
3357       /* ifx Statement              */
3358       /*----------------------------*/
3359     case IFX:
3360       tree->left = backPatchLabels (tree->left,
3361                                     tree->trueLabel,
3362                                     tree->falseLabel);
3363       TTYPE (tree) = TETYPE (tree) = NULL;
3364       return tree;
3365
3366       /*------------------------------------------------------------------*/
3367       /*----------------------------*/
3368       /* for Statement              */
3369       /*----------------------------*/
3370     case FOR:
3371
3372       decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3373       decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3374       decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3375
3376       /* if the for loop is reversible then
3377          reverse it otherwise do what we normally
3378          do */
3379       {
3380         symbol *sym;
3381         ast *init, *end;
3382
3383         if (isLoopReversible (tree, &sym, &init, &end))
3384           return reverseLoop (tree, sym, init, end);
3385         else
3386           return decorateType (createFor (AST_FOR (tree, trueLabel),
3387                                           AST_FOR (tree, continueLabel),
3388                                           AST_FOR (tree, falseLabel),
3389                                           AST_FOR (tree, condLabel),
3390                                           AST_FOR (tree, initExpr),
3391                                           AST_FOR (tree, condExpr),
3392                                           AST_FOR (tree, loopExpr),
3393                                           tree->left));
3394       }
3395     default:
3396       TTYPE (tree) = TETYPE (tree) = NULL;
3397       return tree;
3398     }
3399
3400   /* some error found this tree will be killed */
3401 errorTreeReturn:
3402   TTYPE (tree) = TETYPE (tree) = newCharLink ();
3403   tree->opval.op = NULLOP;
3404   tree->isError = 1;
3405
3406   return tree;
3407 }
3408
3409 /*-----------------------------------------------------------------*/
3410 /* sizeofOp - processes size of operation                          */
3411 /*-----------------------------------------------------------------*/
3412 value *
3413 sizeofOp (sym_link * type)
3414 {
3415   char buff[10];
3416
3417   /* make sure the type is complete and sane */
3418   checkTypeSanity(type, "(sizeof)");
3419
3420   /* get the size and convert it to character  */
3421   SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
3422
3423   /* now convert into value  */
3424   return constVal (buff);
3425 }
3426
3427
3428 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3429 #define IS_OR(ex)  (ex->type == EX_OP && ex->opval.op == OR_OP )
3430 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3431 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3432 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3433 #define IS_LT(ex)  (ex->type == EX_OP && ex->opval.op == '<' )
3434 #define IS_GT(ex)  (ex->type == EX_OP && ex->opval.op == '>')
3435
3436 /*-----------------------------------------------------------------*/
3437 /* backPatchLabels - change and or not operators to flow control    */
3438 /*-----------------------------------------------------------------*/
3439 ast *
3440 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3441 {
3442
3443   if (!tree)
3444     return NULL;
3445
3446   if (!(IS_ANDORNOT (tree)))
3447     return tree;
3448
3449   /* if this an and */
3450   if (IS_AND (tree))
3451     {
3452       static int localLbl = 0;
3453       symbol *localLabel;
3454
3455       SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
3456       localLabel = newSymbol (buffer, NestLevel);
3457
3458       tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3459
3460       /* if left is already a IFX then just change the if true label in that */
3461       if (!IS_IFX (tree->left))
3462         tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3463
3464       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3465       /* right is a IFX then just join */
3466       if (IS_IFX (tree->right))
3467         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3468
3469       tree->right = createLabel (localLabel, tree->right);
3470       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3471
3472       return newNode (NULLOP, tree->left, tree->right);
3473     }
3474
3475   /* if this is an or operation */
3476   if (IS_OR (tree))
3477     {
3478       static int localLbl = 0;
3479       symbol *localLabel;
3480
3481       SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
3482       localLabel = newSymbol (buffer, NestLevel);
3483
3484       tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3485
3486       /* if left is already a IFX then just change the if true label in that */
3487       if (!IS_IFX (tree->left))
3488         tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3489
3490       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3491       /* right is a IFX then just join */
3492       if (IS_IFX (tree->right))
3493         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3494
3495       tree->right = createLabel (localLabel, tree->right);
3496       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3497
3498       return newNode (NULLOP, tree->left, tree->right);
3499     }
3500
3501   /* change not */
3502   if (IS_NOT (tree))
3503     {
3504       int wasnot = IS_NOT (tree->left);
3505       tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3506
3507       /* if the left is already a IFX */
3508       if (!IS_IFX (tree->left))
3509         tree->left = newNode (IFX, tree->left, NULL);
3510
3511       if (wasnot)
3512         {
3513           tree->left->trueLabel = trueLabel;
3514           tree->left->falseLabel = falseLabel;
3515         }
3516       else
3517         {
3518           tree->left->trueLabel = falseLabel;
3519           tree->left->falseLabel = trueLabel;
3520         }
3521       return tree->left;
3522     }
3523
3524   if (IS_IFX (tree))
3525     {
3526       tree->trueLabel = trueLabel;
3527       tree->falseLabel = falseLabel;
3528     }
3529
3530   return tree;
3531 }
3532
3533
3534 /*-----------------------------------------------------------------*/
3535 /* createBlock - create expression tree for block                  */
3536 /*-----------------------------------------------------------------*/
3537 ast *
3538 createBlock (symbol * decl, ast * body)
3539 {
3540   ast *ex;
3541
3542   /* if the block has nothing */
3543   if (!body && !decl)
3544     return NULL;
3545
3546   ex = newNode (BLOCK, NULL, body);
3547   ex->values.sym = decl;
3548   
3549   ex->right = ex->right;
3550   ex->level++;
3551   ex->lineno = 0;
3552   return ex;
3553 }
3554
3555 /*-----------------------------------------------------------------*/
3556 /* createLabel - creates the expression tree for labels            */
3557 /*-----------------------------------------------------------------*/
3558 ast *
3559 createLabel (symbol * label, ast * stmnt)
3560 {
3561   symbol *csym;
3562   char name[SDCC_NAME_MAX + 1];
3563   ast *rValue;
3564
3565   /* must create fresh symbol if the symbol name  */
3566   /* exists in the symbol table, since there can  */
3567   /* be a variable with the same name as the labl */
3568   if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3569       (csym->level == label->level))
3570     label = newSymbol (label->name, label->level);
3571
3572   /* change the name before putting it in add _ */
3573   SNPRINTF(name, sizeof(name), "%s", label->name);
3574
3575   /* put the label in the LabelSymbol table    */
3576   /* but first check if a label of the same    */
3577   /* name exists                               */
3578   if ((csym = findSym (LabelTab, NULL, name)))
3579     werror (E_DUPLICATE_LABEL, label->name);
3580   else
3581     addSym (LabelTab, label, name, label->level, 0, 0);
3582
3583   label->islbl = 1;
3584   label->key = labelKey++;
3585   rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3586   rValue->lineno = 0;
3587
3588   return rValue;
3589 }
3590
3591 /*-----------------------------------------------------------------*/
3592 /* createCase - generates the parsetree for a case statement       */
3593 /*-----------------------------------------------------------------*/
3594 ast *
3595 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3596 {
3597   char caseLbl[SDCC_NAME_MAX + 1];
3598   ast *rexpr;
3599   value *val;
3600
3601   /* if the switch statement does not exist */
3602   /* then case is out of context            */
3603   if (!swStat)
3604     {
3605       werror (E_CASE_CONTEXT);
3606       return NULL;
3607     }
3608
3609   caseVal = decorateType (resolveSymbols (caseVal));
3610   /* if not a constant then error  */
3611   if (!IS_LITERAL (caseVal->ftype))
3612     {
3613       werror (E_CASE_CONSTANT);
3614       return NULL;
3615     }
3616
3617   /* if not a integer than error */
3618   if (!IS_INTEGRAL (caseVal->ftype))
3619     {
3620       werror (E_CASE_NON_INTEGER);
3621       return NULL;
3622     }
3623
3624   /* find the end of the switch values chain   */
3625   if (!(val = swStat->values.switchVals.swVals))
3626     swStat->values.switchVals.swVals = caseVal->opval.val;
3627   else
3628     {
3629       /* also order the cases according to value */
3630       value *pval = NULL;
3631       int cVal = (int) floatFromVal (caseVal->opval.val);
3632       while (val && (int) floatFromVal (val) < cVal)
3633         {
3634           pval = val;
3635           val = val->next;
3636         }
3637
3638       /* if we reached the end then */
3639       if (!val)
3640         {
3641           pval->next = caseVal->opval.val;
3642         }
3643       else
3644         {
3645           /* we found a value greater than */
3646           /* the current value we must add this */
3647           /* before the value */
3648           caseVal->opval.val->next = val;
3649
3650           /* if this was the first in chain */
3651           if (swStat->values.switchVals.swVals == val)
3652             swStat->values.switchVals.swVals =
3653               caseVal->opval.val;
3654           else
3655             pval->next = caseVal->opval.val;
3656         }
3657
3658     }
3659
3660   /* create the case label   */
3661   SNPRINTF(caseLbl, sizeof(caseLbl), 
3662            "_case_%d_%d",
3663            swStat->values.switchVals.swNum,
3664            (int) floatFromVal (caseVal->opval.val));
3665
3666   rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3667   rexpr->lineno = 0;
3668   return rexpr;
3669 }
3670
3671 /*-----------------------------------------------------------------*/
3672 /* createDefault - creates the parse tree for the default statement */
3673 /*-----------------------------------------------------------------*/
3674 ast *
3675 createDefault (ast * swStat, ast * stmnt)
3676 {
3677   char defLbl[SDCC_NAME_MAX + 1];
3678
3679   /* if the switch statement does not exist */
3680   /* then case is out of context            */
3681   if (!swStat)
3682     {
3683       werror (E_CASE_CONTEXT);
3684       return NULL;
3685     }
3686
3687   /* turn on the default flag   */
3688   swStat->values.switchVals.swDefault = 1;
3689
3690   /* create the label  */
3691   SNPRINTF (defLbl, sizeof(defLbl),
3692             "_default_%d", swStat->values.switchVals.swNum);
3693   return createLabel (newSymbol (defLbl, 0), stmnt);
3694 }
3695
3696 /*-----------------------------------------------------------------*/
3697 /* createIf - creates the parsetree for the if statement           */
3698 /*-----------------------------------------------------------------*/
3699 ast *
3700 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3701 {
3702   static int Lblnum = 0;
3703   ast *ifTree;
3704   symbol *ifTrue, *ifFalse, *ifEnd;
3705
3706   /* if neither exists */
3707   if (!elseBody && !ifBody) {
3708     // if there are no side effects (i++, j() etc)
3709     if (!hasSEFcalls(condAst)) {
3710       return condAst;
3711     }
3712   }
3713
3714   /* create the labels */
3715   SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
3716   ifFalse = newSymbol (buffer, NestLevel);
3717   /* if no else body then end == false */
3718   if (!elseBody)
3719     ifEnd = ifFalse;
3720   else
3721     {
3722       SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
3723       ifEnd = newSymbol (buffer, NestLevel);
3724     }
3725
3726   SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
3727   ifTrue = newSymbol (buffer, NestLevel);
3728
3729   Lblnum++;
3730
3731   /* attach the ifTrue label to the top of it body */
3732   ifBody = createLabel (ifTrue, ifBody);
3733   /* attach a goto end to the ifBody if else is present */
3734   if (elseBody)
3735     {
3736       ifBody = newNode (NULLOP, ifBody,
3737                         newNode (GOTO,
3738                                  newAst_VALUE (symbolVal (ifEnd)),
3739                                  NULL));
3740       /* put the elseLabel on the else body */
3741       elseBody = createLabel (ifFalse, elseBody);
3742       /* out the end at the end of the body */
3743       elseBody = newNode (NULLOP,
3744                           elseBody,
3745                           createLabel (ifEnd, NULL));
3746     }
3747   else
3748     {
3749       ifBody = newNode (NULLOP, ifBody,
3750                         createLabel (ifFalse, NULL));
3751     }
3752   condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3753   if (IS_IFX (condAst))
3754     ifTree = condAst;
3755   else
3756     ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3757
3758   return newNode (NULLOP, ifTree,
3759                   newNode (NULLOP, ifBody, elseBody));
3760
3761 }
3762
3763 /*-----------------------------------------------------------------*/
3764 /* createDo - creates parse tree for do                            */
3765 /*        _dobody_n:                                               */
3766 /*            statements                                           */
3767 /*        _docontinue_n:                                           */
3768 /*            condition_expression +-> trueLabel -> _dobody_n      */
3769 /*                                 |                               */
3770 /*                                 +-> falseLabel-> _dobreak_n     */
3771 /*        _dobreak_n:                                              */
3772 /*-----------------------------------------------------------------*/
3773 ast *
3774 createDo (symbol * trueLabel, symbol * continueLabel,
3775           symbol * falseLabel, ast * condAst, ast * doBody)
3776 {
3777   ast *doTree;
3778
3779
3780   /* if the body does not exist then it is simple */
3781   if (!doBody)
3782     {
3783       condAst = backPatchLabels (condAst, continueLabel, NULL);
3784       doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3785                 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3786       doTree->trueLabel = continueLabel;
3787       doTree->falseLabel = NULL;
3788       return doTree;
3789     }
3790
3791   /* otherwise we have a body */
3792   condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3793
3794   /* attach the body label to the top */
3795   doBody = createLabel (trueLabel, doBody);
3796   /* attach the continue label to end of body */
3797   doBody = newNode (NULLOP, doBody,
3798                     createLabel (continueLabel, NULL));
3799
3800   /* now put the break label at the end */
3801   if (IS_IFX (condAst))
3802     doTree = condAst;
3803   else
3804     doTree = newIfxNode (condAst, trueLabel, falseLabel);
3805
3806   doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3807
3808   /* putting it together */
3809   return newNode (NULLOP, doBody, doTree);
3810 }
3811
3812 /*-----------------------------------------------------------------*/
3813 /* createFor - creates parse tree for 'for' statement              */
3814 /*        initExpr                                                 */
3815 /*   _forcond_n:                                                   */
3816 /*        condExpr  +-> trueLabel -> _forbody_n                    */
3817 /*                  |                                              */
3818 /*                  +-> falseLabel-> _forbreak_n                   */
3819 /*   _forbody_n:                                                   */
3820 /*        statements                                               */
3821 /*   _forcontinue_n:                                               */
3822 /*        loopExpr                                                 */
3823 /*        goto _forcond_n ;                                        */
3824 /*   _forbreak_n:                                                  */
3825 /*-----------------------------------------------------------------*/
3826 ast *
3827 createFor (symbol * trueLabel, symbol * continueLabel,
3828            symbol * falseLabel, symbol * condLabel,
3829            ast * initExpr, ast * condExpr, ast * loopExpr,
3830            ast * forBody)
3831 {
3832   ast *forTree;
3833
3834   /* if loopexpression not present then we can generate it */
3835   /* the same way as a while */
3836   if (!loopExpr)
3837     return newNode (NULLOP, initExpr,
3838                     createWhile (trueLabel, continueLabel,
3839                                  falseLabel, condExpr, forBody));
3840   /* vanilla for statement */
3841   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3842
3843   if (condExpr && !IS_IFX (condExpr))
3844     condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3845
3846
3847   /* attach condition label to condition */
3848   condExpr = createLabel (condLabel, condExpr);
3849
3850   /* attach body label to body */
3851   forBody = createLabel (trueLabel, forBody);
3852
3853   /* attach continue to forLoop expression & attach */
3854   /* goto the forcond @ and of loopExpression       */
3855   loopExpr = createLabel (continueLabel,
3856                           newNode (NULLOP,
3857                                    loopExpr,
3858                                    newNode (GOTO,
3859                                        newAst_VALUE (symbolVal (condLabel)),
3860                                             NULL)));
3861   /* now start putting them together */
3862   forTree = newNode (NULLOP, initExpr, condExpr);
3863   forTree = newNode (NULLOP, forTree, forBody);
3864   forTree = newNode (NULLOP, forTree, loopExpr);
3865   /* finally add the break label */
3866   forTree = newNode (NULLOP, forTree,
3867                      createLabel (falseLabel, NULL));
3868   return forTree;
3869 }
3870
3871 /*-----------------------------------------------------------------*/
3872 /* createWhile - creates parse tree for while statement            */
3873 /*               the while statement will be created as follows    */
3874 /*                                                                 */
3875 /*      _while_continue_n:                                         */
3876 /*            condition_expression +-> trueLabel -> _while_boby_n  */
3877 /*                                 |                               */
3878 /*                                 +-> falseLabel -> _while_break_n */
3879 /*      _while_body_n:                                             */
3880 /*            statements                                           */
3881 /*            goto _while_continue_n                               */
3882 /*      _while_break_n:                                            */
3883 /*-----------------------------------------------------------------*/
3884 ast *
3885 createWhile (symbol * trueLabel, symbol * continueLabel,
3886              symbol * falseLabel, ast * condExpr, ast * whileBody)
3887 {
3888   ast *whileTree;
3889
3890   /* put the continue label */
3891   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3892   condExpr = createLabel (continueLabel, condExpr);
3893   condExpr->lineno = 0;
3894
3895   /* put the body label in front of the body */
3896   whileBody = createLabel (trueLabel, whileBody);
3897   whileBody->lineno = 0;
3898   /* put a jump to continue at the end of the body */
3899   /* and put break label at the end of the body */
3900   whileBody = newNode (NULLOP,
3901                        whileBody,
3902                        newNode (GOTO,
3903                                 newAst_VALUE (symbolVal (continueLabel)),
3904                                 createLabel (falseLabel, NULL)));
3905
3906   /* put it all together */
3907   if (IS_IFX (condExpr))
3908     whileTree = condExpr;
3909   else
3910     {
3911       whileTree = newNode (IFX, condExpr, NULL);
3912       /* put the true & false labels in place */
3913       whileTree->trueLabel = trueLabel;
3914       whileTree->falseLabel = falseLabel;
3915     }
3916
3917   return newNode (NULLOP, whileTree, whileBody);
3918 }
3919
3920 /*-----------------------------------------------------------------*/
3921 /* optimizeGetHbit - get highest order bit of the expression       */
3922 /*-----------------------------------------------------------------*/
3923 ast *
3924 optimizeGetHbit (ast * tree)
3925 {
3926   int i, j;
3927   /* if this is not a bit and */
3928   if (!IS_BITAND (tree))
3929     return tree;
3930
3931   /* will look for tree of the form
3932      ( expr >> ((sizeof expr) -1) ) & 1 */
3933   if (!IS_AST_LIT_VALUE (tree->right))
3934     return tree;
3935
3936   if (AST_LIT_VALUE (tree->right) != 1)
3937     return tree;
3938
3939   if (!IS_RIGHT_OP (tree->left))
3940     return tree;
3941
3942   if (!IS_AST_LIT_VALUE (tree->left->right))
3943     return tree;
3944
3945   if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3946       (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3947     return tree;
3948
3949   return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3950
3951 }
3952
3953 /*-----------------------------------------------------------------*/
3954 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry     */
3955 /*-----------------------------------------------------------------*/
3956 ast *
3957 optimizeRRCRLC (ast * root)
3958 {
3959   /* will look for trees of the form
3960      (?expr << 1) | (?expr >> 7) or
3961      (?expr >> 7) | (?expr << 1) will make that
3962      into a RLC : operation ..
3963      Will also look for
3964      (?expr >> 1) | (?expr << 7) or
3965      (?expr << 7) | (?expr >> 1) will make that
3966      into a RRC operation
3967      note : by 7 I mean (number of bits required to hold the
3968      variable -1 ) */
3969   /* if the root operations is not a | operation the not */
3970   if (!IS_BITOR (root))
3971     return root;
3972
3973   /* I have to think of a better way to match patterns this sucks */
3974   /* that aside let start looking for the first case : I use a the
3975      negative check a lot to improve the efficiency */
3976   /* (?expr << 1) | (?expr >> 7) */
3977   if (IS_LEFT_OP (root->left) &&
3978       IS_RIGHT_OP (root->right))
3979     {
3980
3981       if (!SPEC_USIGN (TETYPE (root->left->left)))
3982         return root;
3983
3984       if (!IS_AST_LIT_VALUE (root->left->right) ||
3985           !IS_AST_LIT_VALUE (root->right->right))
3986         goto tryNext0;
3987
3988       /* make sure it is the same expression */
3989       if (!isAstEqual (root->left->left,
3990                        root->right->left))
3991         goto tryNext0;
3992
3993       if (AST_LIT_VALUE (root->left->right) != 1)
3994         goto tryNext0;
3995
3996       if (AST_LIT_VALUE (root->right->right) !=
3997           (getSize (TTYPE (root->left->left)) * 8 - 1))
3998         goto tryNext0;
3999
4000       /* whew got the first case : create the AST */
4001       return newNode (RLC, root->left->left, NULL);
4002     }
4003
4004 tryNext0:
4005   /* check for second case */
4006   /* (?expr >> 7) | (?expr << 1) */
4007   if (IS_LEFT_OP (root->right) &&
4008       IS_RIGHT_OP (root->left))
4009     {
4010
4011       if (!SPEC_USIGN (TETYPE (root->left->left)))
4012         return root;
4013
4014       if (!IS_AST_LIT_VALUE (root->left->right) ||
4015           !IS_AST_LIT_VALUE (root->right->right))
4016         goto tryNext1;
4017
4018       /* make sure it is the same symbol */
4019       if (!isAstEqual (root->left->left,
4020                        root->right->left))
4021         goto tryNext1;
4022
4023       if (AST_LIT_VALUE (root->right->right) != 1)
4024         goto tryNext1;
4025
4026       if (AST_LIT_VALUE (root->left->right) !=
4027           (getSize (TTYPE (root->left->left)) * 8 - 1))
4028         goto tryNext1;
4029
4030       /* whew got the first case : create the AST */
4031       return newNode (RLC, root->left->left, NULL);
4032
4033     }
4034
4035 tryNext1:
4036   /* third case for RRC */
4037   /*  (?symbol >> 1) | (?symbol << 7) */
4038   if (IS_LEFT_OP (root->right) &&
4039       IS_RIGHT_OP (root->left))
4040     {
4041
4042       if (!SPEC_USIGN (TETYPE (root->left->left)))
4043         return root;
4044
4045       if (!IS_AST_LIT_VALUE (root->left->right) ||
4046           !IS_AST_LIT_VALUE (root->right->right))
4047         goto tryNext2;
4048
4049       /* make sure it is the same symbol */
4050       if (!isAstEqual (root->left->left,
4051                        root->right->left))
4052         goto tryNext2;
4053
4054       if (AST_LIT_VALUE (root->left->right) != 1)
4055         goto tryNext2;
4056
4057       if (AST_LIT_VALUE (root->right->right) !=
4058           (getSize (TTYPE (root->left->left)) * 8 - 1))
4059         goto tryNext2;
4060
4061       /* whew got the first case : create the AST */
4062       return newNode (RRC, root->left->left, NULL);
4063
4064     }
4065 tryNext2:
4066   /* fourth and last case for now */
4067   /* (?symbol << 7) | (?symbol >> 1) */
4068   if (IS_RIGHT_OP (root->right) &&
4069       IS_LEFT_OP (root->left))
4070     {
4071
4072       if (!SPEC_USIGN (TETYPE (root->left->left)))
4073         return root;
4074
4075       if (!IS_AST_LIT_VALUE (root->left->right) ||
4076           !IS_AST_LIT_VALUE (root->right->right))
4077         return root;
4078
4079       /* make sure it is the same symbol */
4080       if (!isAstEqual (root->left->left,
4081                        root->right->left))
4082         return root;
4083
4084       if (AST_LIT_VALUE (root->right->right) != 1)
4085         return root;
4086
4087       if (AST_LIT_VALUE (root->left->right) !=
4088           (getSize (TTYPE (root->left->left)) * 8 - 1))
4089         return root;
4090
4091       /* whew got the first case : create the AST */
4092       return newNode (RRC, root->left->left, NULL);
4093
4094     }
4095
4096   /* not found return root */
4097   return root;
4098 }
4099
4100 /*-----------------------------------------------------------------*/
4101 /* optimizeCompare - otimizes compares for bit variables     */
4102 /*-----------------------------------------------------------------*/
4103 static ast *
4104 optimizeCompare (ast * root)
4105 {
4106   ast *optExpr = NULL;
4107   value *vleft;
4108   value *vright;
4109   unsigned int litValue;
4110
4111   /* if nothing then return nothing */
4112   if (!root)
4113     return NULL;
4114
4115   /* if not a compare op then do leaves */
4116   if (!IS_COMPARE_OP (root))
4117     {
4118       root->left = optimizeCompare (root->left);
4119       root->right = optimizeCompare (root->right);
4120       return root;
4121     }
4122
4123   /* if left & right are the same then depending
4124      of the operation do */
4125   if (isAstEqual (root->left, root->right))
4126     {
4127       switch (root->opval.op)
4128         {
4129         case '>':
4130         case '<':
4131         case NE_OP:
4132           optExpr = newAst_VALUE (constVal ("0"));
4133           break;
4134         case GE_OP:
4135         case LE_OP:
4136         case EQ_OP:
4137           optExpr = newAst_VALUE (constVal ("1"));
4138           break;
4139         }
4140
4141       return decorateType (optExpr);
4142     }
4143
4144   vleft = (root->left->type == EX_VALUE ?
4145            root->left->opval.val : NULL);
4146
4147   vright = (root->right->type == EX_VALUE ?
4148             root->right->opval.val : NULL);
4149
4150   /* if left is a BITVAR in BITSPACE */
4151   /* and right is a LITERAL then opt- */
4152   /* imize else do nothing       */
4153   if (vleft && vright &&
4154       IS_BITVAR (vleft->etype) &&
4155       IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4156       IS_LITERAL (vright->etype))
4157     {
4158
4159       /* if right side > 1 then comparison may never succeed */
4160       if ((litValue = (int) floatFromVal (vright)) > 1)
4161         {
4162           werror (W_BAD_COMPARE);
4163           goto noOptimize;
4164         }
4165
4166       if (litValue)
4167         {
4168           switch (root->opval.op)
4169             {
4170             case '>':           /* bit value greater than 1 cannot be */
4171               werror (W_BAD_COMPARE);
4172               goto noOptimize;
4173               break;
4174
4175             case '<':           /* bit value < 1 means 0 */
4176             case NE_OP:
4177               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4178               break;
4179
4180             case LE_OP: /* bit value <= 1 means no check */
4181               optExpr = newAst_VALUE (vright);
4182               break;
4183
4184             case GE_OP: /* bit value >= 1 means only check for = */
4185             case EQ_OP:
4186               optExpr = newAst_VALUE (vleft);
4187               break;
4188             }
4189         }
4190       else
4191         {                       /* literal is zero */
4192           switch (root->opval.op)
4193             {
4194             case '<':           /* bit value < 0 cannot be */
4195               werror (W_BAD_COMPARE);
4196               goto noOptimize;
4197               break;
4198
4199             case '>':           /* bit value > 0 means 1 */
4200             case NE_OP:
4201               optExpr = newAst_VALUE (vleft);
4202               break;
4203
4204             case LE_OP: /* bit value <= 0 means no check */
4205             case GE_OP: /* bit value >= 0 means no check */
4206               werror (W_BAD_COMPARE);
4207               goto noOptimize;
4208               break;
4209
4210             case EQ_OP: /* bit == 0 means ! of bit */
4211               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4212               break;
4213             }
4214         }
4215       return decorateType (resolveSymbols (optExpr));
4216     }                           /* end-of-if of BITVAR */
4217
4218 noOptimize:
4219   return root;
4220 }
4221 /*-----------------------------------------------------------------*/
4222 /* addSymToBlock : adds the symbol to the first block we find      */
4223 /*-----------------------------------------------------------------*/
4224 void 
4225 addSymToBlock (symbol * sym, ast * tree)
4226 {
4227   /* reached end of tree or a leaf */
4228   if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4229     return;
4230
4231   /* found a block */
4232   if (IS_AST_OP (tree) &&
4233       tree->opval.op == BLOCK)
4234     {
4235
4236       symbol *lsym = copySymbol (sym);
4237
4238       lsym->next = AST_VALUES (tree, sym);
4239       AST_VALUES (tree, sym) = lsym;
4240       return;
4241     }
4242
4243   addSymToBlock (sym, tree->left);
4244   addSymToBlock (sym, tree->right);
4245 }
4246
4247 /*-----------------------------------------------------------------*/
4248 /* processRegParms - do processing for register parameters         */
4249 /*-----------------------------------------------------------------*/
4250 static void 
4251 processRegParms (value * args, ast * body)
4252 {
4253   while (args)
4254     {
4255       if (IS_REGPARM (args->etype))
4256         addSymToBlock (args->sym, body);
4257       args = args->next;
4258     }
4259 }
4260
4261 /*-----------------------------------------------------------------*/
4262 /* resetParmKey - resets the operandkeys for the symbols           */
4263 /*-----------------------------------------------------------------*/
4264 DEFSETFUNC (resetParmKey)
4265 {
4266   symbol *sym = item;
4267
4268   sym->key = 0;
4269   sym->defs = NULL;
4270   sym->uses = NULL;
4271   sym->remat = 0;
4272   return 1;
4273 }
4274
4275 /*-----------------------------------------------------------------*/
4276 /* createFunction - This is the key node that calls the iCode for  */
4277 /*                  generating the code for a function. Note code  */
4278 /*                  is generated function by function, later when  */
4279 /*                  add inter-procedural analysis this will change */
4280 /*-----------------------------------------------------------------*/
4281 ast *
4282 createFunction (symbol * name, ast * body)
4283 {
4284   ast *ex;
4285   symbol *csym;
4286   int stack = 0;
4287   sym_link *fetype;
4288   iCode *piCode = NULL;
4289
4290   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4291     fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4292
4293   /* if check function return 0 then some problem */
4294   if (checkFunction (name, NULL) == 0)
4295     return NULL;
4296
4297   /* create a dummy block if none exists */
4298   if (!body)
4299     body = newNode (BLOCK, NULL, NULL);
4300
4301   noLineno++;
4302
4303   /* check if the function name already in the symbol table */
4304   if ((csym = findSym (SymbolTab, NULL, name->name)))
4305     {
4306       name = csym;
4307       /* special case for compiler defined functions
4308          we need to add the name to the publics list : this
4309          actually means we are now compiling the compiler
4310          support routine */
4311       if (name->cdef)
4312         {
4313           addSet (&publics, name);
4314         }
4315     }
4316   else
4317     {
4318       addSymChain (name);
4319       allocVariables (name);
4320     }
4321   name->lastLine = yylineno;
4322   currFunc = name;
4323
4324   /* set the stack pointer */
4325   /* PENDING: check this for the mcs51 */
4326   stackPtr = -port->stack.direction * port->stack.call_overhead;
4327   if (IFFUNC_ISISR (name->type))
4328     stackPtr -= port->stack.direction * port->stack.isr_overhead;
4329   if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4330     stackPtr -= port->stack.direction * port->stack.reent_overhead;
4331
4332   xstackPtr = -port->stack.direction * port->stack.call_overhead;
4333
4334   fetype = getSpec (name->type);        /* get the specifier for the function */
4335   /* if this is a reentrant function then */
4336   if (IFFUNC_ISREENT (name->type))
4337     reentrant++;
4338
4339   allocParms (FUNC_ARGS(name->type));   /* allocate the parameters */
4340
4341   /* do processing for parameters that are passed in registers */
4342   processRegParms (FUNC_ARGS(name->type), body);
4343
4344   /* set the stack pointer */
4345   stackPtr = 0;
4346   xstackPtr = -1;
4347
4348   /* allocate & autoinit the block variables */
4349   processBlockVars (body, &stack, ALLOCATE);
4350
4351   /* save the stack information */
4352   if (options.useXstack)
4353     name->xstack = SPEC_STAK (fetype) = stack;
4354   else
4355     name->stack = SPEC_STAK (fetype) = stack;
4356
4357   /* name needs to be mangled */
4358   SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
4359
4360   body = resolveSymbols (body); /* resolve the symbols */
4361   body = decorateType (body);   /* propagateType & do semantic checks */
4362
4363   ex = newAst_VALUE (symbolVal (name)); /* create name */
4364   ex = newNode (FUNCTION, ex, body);
4365   ex->values.args = FUNC_ARGS(name->type);
4366   ex->decorated=1;
4367   if (options.dump_tree) PA(ex);
4368   if (fatalError)
4369     {
4370       werror (E_FUNC_NO_CODE, name->name);
4371       goto skipall;
4372     }
4373
4374   /* create the node & generate intermediate code */
4375   GcurMemmap = code;
4376   codeOutFile = code->oFile;
4377   piCode = iCodeFromAst (ex);
4378
4379   if (fatalError)
4380     {
4381       werror (E_FUNC_NO_CODE, name->name);
4382       goto skipall;
4383     }
4384
4385   eBBlockFromiCode (piCode);
4386
4387   /* if there are any statics then do them */
4388   if (staticAutos)
4389     {
4390       GcurMemmap = statsg;
4391       codeOutFile = statsg->oFile;
4392       eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4393       staticAutos = NULL;
4394     }
4395
4396 skipall:
4397
4398   /* dealloc the block variables */
4399   processBlockVars (body, &stack, DEALLOCATE);
4400   outputDebugStackSymbols();
4401   /* deallocate paramaters */
4402   deallocParms (FUNC_ARGS(name->type));
4403
4404   if (IFFUNC_ISREENT (name->type))
4405     reentrant--;
4406
4407   /* we are done freeup memory & cleanup */
4408   noLineno--;
4409   if (port->reset_labelKey) labelKey = 1;
4410   name->key = 0;
4411   FUNC_HASBODY(name->type) = 1;
4412   addSet (&operKeyReset, name);
4413   applyToSet (operKeyReset, resetParmKey);
4414
4415   if (options.debug)    
4416     cdbStructBlock(1);
4417
4418   cleanUpLevel (LabelTab, 0);
4419   cleanUpBlock (StructTab, 1);
4420   cleanUpBlock (TypedefTab, 1);
4421
4422   xstack->syms = NULL;
4423   istack->syms = NULL;
4424   return NULL;
4425 }
4426
4427
4428 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
4429 /*-----------------------------------------------------------------*/
4430 /* ast_print : prints the ast (for debugging purposes)             */
4431 /*-----------------------------------------------------------------*/
4432
4433 void ast_print (ast * tree, FILE *outfile, int indent)
4434 {
4435         
4436         if (!tree) return ;
4437
4438         /* can print only decorated trees */
4439         if (!tree->decorated) return;
4440
4441         /* if any child is an error | this one is an error do nothing */
4442         if (tree->isError ||
4443             (tree->left && tree->left->isError) ||
4444             (tree->right && tree->right->isError)) {
4445                 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4446         }
4447
4448         
4449         /* print the line          */
4450         /* if not block & function */
4451         if (tree->type == EX_OP &&
4452             (tree->opval.op != FUNCTION &&
4453              tree->opval.op != BLOCK &&
4454              tree->opval.op != NULLOP)) {
4455         }
4456         
4457         if (tree->opval.op == FUNCTION) {
4458                 int arg=0;
4459                 value *args=FUNC_ARGS(tree->left->opval.val->type);
4460                 fprintf(outfile,"FUNCTION (%s=%p) type (", 
4461                         tree->left->opval.val->name, tree);
4462                 printTypeChain (tree->ftype,outfile);
4463                 fprintf(outfile,") args (");
4464                 do {
4465                   if (arg) {
4466                     fprintf (outfile, ", ");
4467                   }
4468                   printTypeChain (args ? args->type : NULL, outfile);
4469                   arg++;
4470                   args= args ? args->next : NULL;
4471                 } while (args);
4472                 fprintf(outfile,")\n");
4473                 ast_print(tree->left,outfile,indent);
4474                 ast_print(tree->right,outfile,indent);
4475                 return ;
4476         }
4477         if (tree->opval.op == BLOCK) {
4478                 symbol *decls = tree->values.sym;
4479                 INDENT(indent,outfile);
4480                 fprintf(outfile,"{\n");
4481                 while (decls) {
4482                         INDENT(indent+2,outfile);
4483                         fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4484                                 decls->name, decls);
4485                         printTypeChain(decls->type,outfile);
4486                         fprintf(outfile,")\n");
4487                         
4488                         decls = decls->next;                    
4489                 }
4490                 ast_print(tree->right,outfile,indent+2);
4491                 INDENT(indent,outfile);
4492                 fprintf(outfile,"}\n");
4493                 return;
4494         }
4495         if (tree->opval.op == NULLOP) {
4496                 ast_print(tree->left,outfile,indent);
4497                 ast_print(tree->right,outfile,indent);
4498                 return ;
4499         }
4500         INDENT(indent,outfile);
4501
4502         /*------------------------------------------------------------------*/
4503         /*----------------------------*/
4504         /*   leaf has been reached    */
4505         /*----------------------------*/
4506         /* if this is of type value */
4507         /* just get the type        */
4508         if (tree->type == EX_VALUE) {
4509
4510                 if (IS_LITERAL (tree->opval.val->etype)) {                      
4511                         fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4512                                 (int) floatFromVal(tree->opval.val),
4513                                 (int) floatFromVal(tree->opval.val),
4514                                 floatFromVal(tree->opval.val));
4515                 } else if (tree->opval.val->sym) {
4516                         /* if the undefined flag is set then give error message */
4517                         if (tree->opval.val->sym->undefined) {
4518                                 fprintf(outfile,"UNDEFINED SYMBOL ");
4519                         } else {
4520                                 fprintf(outfile,"SYMBOL ");
4521                         }
4522                         fprintf(outfile,"(%s=%p)",
4523                                 tree->opval.val->sym->name,tree);
4524                 }
4525                 if (tree->ftype) {
4526                         fprintf(outfile," type (");
4527                         printTypeChain(tree->ftype,outfile);
4528                         fprintf(outfile,")\n");
4529                 } else {
4530                         fprintf(outfile,"\n");
4531                 }
4532                 return ;
4533         }
4534
4535         /* if type link for the case of cast */
4536         if (tree->type == EX_LINK) {
4537                 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4538                 printTypeChain(tree->opval.lnk,outfile);
4539                 fprintf(outfile,")\n");
4540                 return ;
4541         }
4542
4543
4544         /* depending on type of operator do */
4545         
4546         switch (tree->opval.op) {
4547                 /*------------------------------------------------------------------*/
4548                 /*----------------------------*/
4549                 /*        array node          */
4550                 /*----------------------------*/
4551         case '[':
4552                 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4553                 printTypeChain(tree->ftype,outfile);
4554                 fprintf(outfile,")\n");
4555                 ast_print(tree->left,outfile,indent+2);
4556                 ast_print(tree->right,outfile,indent+2);
4557                 return;
4558
4559                 /*------------------------------------------------------------------*/
4560                 /*----------------------------*/
4561                 /*      struct/union          */
4562                 /*----------------------------*/
4563         case '.':
4564                 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4565                 printTypeChain(tree->ftype,outfile);
4566                 fprintf(outfile,")\n");
4567                 ast_print(tree->left,outfile,indent+2);
4568                 ast_print(tree->right,outfile,indent+2);
4569                 return ;
4570
4571                 /*------------------------------------------------------------------*/
4572                 /*----------------------------*/
4573                 /*    struct/union pointer    */
4574                 /*----------------------------*/
4575         case PTR_OP:
4576                 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4577                 printTypeChain(tree->ftype,outfile);
4578                 fprintf(outfile,")\n");
4579                 ast_print(tree->left,outfile,indent+2);
4580                 ast_print(tree->right,outfile,indent+2);
4581                 return ;
4582
4583                 /*------------------------------------------------------------------*/
4584                 /*----------------------------*/
4585                 /*  ++/-- operation           */
4586                 /*----------------------------*/
4587         case INC_OP:            /* incerement operator unary so left only */
4588                 fprintf(outfile,"INC_OP (%p) type (",tree);
4589                 printTypeChain(tree->ftype,outfile);
4590                 fprintf(outfile,")\n");
4591                 ast_print(tree->left,outfile,indent+2);
4592                 return ;
4593
4594         case DEC_OP:
4595                 fprintf(outfile,"DEC_OP (%p) type (",tree);
4596                 printTypeChain(tree->ftype,outfile);
4597                 fprintf(outfile,")\n");
4598                 ast_print(tree->left,outfile,indent+2);
4599                 return ;
4600
4601                 /*------------------------------------------------------------------*/
4602                 /*----------------------------*/
4603                 /*  bitwise and               */
4604                 /*----------------------------*/
4605         case '&':                       
4606                 if (tree->right) {
4607                         fprintf(outfile,"& (%p) type (",tree);
4608                         printTypeChain(tree->ftype,outfile);
4609                         fprintf(outfile,")\n");
4610                         ast_print(tree->left,outfile,indent+2);
4611                         ast_print(tree->right,outfile,indent+2);
4612                 } else {
4613                         fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4614                         printTypeChain(tree->ftype,outfile);
4615                         fprintf(outfile,")\n");
4616                         ast_print(tree->left,outfile,indent+2);
4617                         ast_print(tree->right,outfile,indent+2);
4618                 }
4619                 return ;
4620                 /*----------------------------*/
4621                 /*  bitwise or                */
4622                 /*----------------------------*/
4623         case '|':
4624                 fprintf(outfile,"OR (%p) type (",tree);
4625                 printTypeChain(tree->ftype,outfile);
4626                 fprintf(outfile,")\n");
4627                 ast_print(tree->left,outfile,indent+2);
4628                 ast_print(tree->right,outfile,indent+2);
4629                 return ;
4630                 /*------------------------------------------------------------------*/
4631                 /*----------------------------*/
4632                 /*  bitwise xor               */
4633                 /*----------------------------*/
4634         case '^':
4635                 fprintf(outfile,"XOR (%p) type (",tree);
4636                 printTypeChain(tree->ftype,outfile);
4637                 fprintf(outfile,")\n");
4638                 ast_print(tree->left,outfile,indent+2);
4639                 ast_print(tree->right,outfile,indent+2);
4640                 return ;
4641                 
4642                 /*------------------------------------------------------------------*/
4643                 /*----------------------------*/
4644                 /*  division                  */
4645                 /*----------------------------*/
4646         case '/':
4647                 fprintf(outfile,"DIV (%p) type (",tree);
4648                 printTypeChain(tree->ftype,outfile);
4649                 fprintf(outfile,")\n");
4650                 ast_print(tree->left,outfile,indent+2);
4651                 ast_print(tree->right,outfile,indent+2);
4652                 return ;
4653                 /*------------------------------------------------------------------*/
4654                 /*----------------------------*/
4655                 /*            modulus         */
4656                 /*----------------------------*/
4657         case '%':
4658                 fprintf(outfile,"MOD (%p) type (",tree);
4659                 printTypeChain(tree->ftype,outfile);
4660                 fprintf(outfile,")\n");
4661                 ast_print(tree->left,outfile,indent+2);
4662                 ast_print(tree->right,outfile,indent+2);
4663                 return ;
4664
4665                 /*------------------------------------------------------------------*/
4666                 /*----------------------------*/
4667                 /*  address dereference       */
4668                 /*----------------------------*/
4669         case '*':                       /* can be unary  : if right is null then unary operation */
4670                 if (!tree->right) {
4671                         fprintf(outfile,"DEREF (%p) type (",tree);
4672                         printTypeChain(tree->ftype,outfile);
4673                         fprintf(outfile,")\n");
4674                         ast_print(tree->left,outfile,indent+2);
4675                         return ;
4676                 }                       
4677                 /*------------------------------------------------------------------*/
4678                 /*----------------------------*/
4679                 /*      multiplication        */
4680                 /*----------------------------*/                
4681                 fprintf(outfile,"MULT (%p) type (",tree);
4682                 printTypeChain(tree->ftype,outfile);
4683                 fprintf(outfile,")\n");
4684                 ast_print(tree->left,outfile,indent+2);
4685                 ast_print(tree->right,outfile,indent+2);
4686                 return ;
4687
4688
4689                 /*------------------------------------------------------------------*/
4690                 /*----------------------------*/
4691                 /*    unary '+' operator      */
4692                 /*----------------------------*/
4693         case '+':
4694                 /* if unary plus */
4695                 if (!tree->right) {
4696                         fprintf(outfile,"UPLUS (%p) type (",tree);
4697                         printTypeChain(tree->ftype,outfile);
4698                         fprintf(outfile,")\n");
4699                         ast_print(tree->left,outfile,indent+2);
4700                 } else {
4701                         /*------------------------------------------------------------------*/
4702                         /*----------------------------*/
4703                         /*      addition              */
4704                         /*----------------------------*/
4705                         fprintf(outfile,"ADD (%p) type (",tree);
4706                         printTypeChain(tree->ftype,outfile);
4707                         fprintf(outfile,")\n");
4708                         ast_print(tree->left,outfile,indent+2);
4709                         ast_print(tree->right,outfile,indent+2);
4710                 }
4711                 return;
4712                 /*------------------------------------------------------------------*/
4713                 /*----------------------------*/
4714                 /*      unary '-'             */
4715                 /*----------------------------*/
4716         case '-':                       /* can be unary   */
4717                 if (!tree->right) {
4718                         fprintf(outfile,"UMINUS (%p) type (",tree);
4719                         printTypeChain(tree->ftype,outfile);
4720                         fprintf(outfile,")\n");
4721                         ast_print(tree->left,outfile,indent+2);
4722                 } else {
4723                         /*------------------------------------------------------------------*/
4724                         /*----------------------------*/
4725                         /*      subtraction           */
4726                         /*----------------------------*/
4727                         fprintf(outfile,"SUB (%p) type (",tree);
4728                         printTypeChain(tree->ftype,outfile);
4729                         fprintf(outfile,")\n");
4730                         ast_print(tree->left,outfile,indent+2);
4731                         ast_print(tree->right,outfile,indent+2);
4732                 }
4733                 return;
4734                 /*------------------------------------------------------------------*/
4735                 /*----------------------------*/
4736                 /*    compliment              */
4737                 /*----------------------------*/
4738         case '~':
4739                 fprintf(outfile,"COMPL (%p) type (",tree);
4740                 printTypeChain(tree->ftype,outfile);
4741                 fprintf(outfile,")\n");
4742                 ast_print(tree->left,outfile,indent+2);
4743                 return ;
4744                 /*------------------------------------------------------------------*/
4745                 /*----------------------------*/
4746                 /*           not              */
4747                 /*----------------------------*/
4748         case '!':
4749                 fprintf(outfile,"NOT (%p) type (",tree);
4750                 printTypeChain(tree->ftype,outfile);
4751                 fprintf(outfile,")\n");
4752                 ast_print(tree->left,outfile,indent+2);
4753                 return ;
4754                 /*------------------------------------------------------------------*/
4755                 /*----------------------------*/
4756                 /*           shift            */
4757                 /*----------------------------*/
4758         case RRC:
4759                 fprintf(outfile,"RRC (%p) type (",tree);
4760                 printTypeChain(tree->ftype,outfile);
4761                 fprintf(outfile,")\n");
4762                 ast_print(tree->left,outfile,indent+2);
4763                 return ;
4764
4765         case RLC:
4766                 fprintf(outfile,"RLC (%p) type (",tree);
4767                 printTypeChain(tree->ftype,outfile);
4768                 fprintf(outfile,")\n");
4769                 ast_print(tree->left,outfile,indent+2);
4770                 return ;
4771         case GETHBIT:
4772                 fprintf(outfile,"GETHBIT (%p) type (",tree);
4773                 printTypeChain(tree->ftype,outfile);
4774                 fprintf(outfile,")\n");
4775                 ast_print(tree->left,outfile,indent+2);
4776                 return ;
4777         case LEFT_OP:
4778                 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4779                 printTypeChain(tree->ftype,outfile);
4780                 fprintf(outfile,")\n");
4781                 ast_print(tree->left,outfile,indent+2);
4782                 ast_print(tree->right,outfile,indent+2);
4783                 return ;
4784         case RIGHT_OP:
4785                 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4786                 printTypeChain(tree->ftype,outfile);
4787                 fprintf(outfile,")\n");
4788                 ast_print(tree->left,outfile,indent+2);
4789                 ast_print(tree->right,outfile,indent+2);
4790                 return ;
4791                 /*------------------------------------------------------------------*/
4792                 /*----------------------------*/
4793                 /*         casting            */
4794                 /*----------------------------*/
4795         case CAST:                      /* change the type   */
4796                 fprintf(outfile,"CAST (%p) from type (",tree);
4797                 printTypeChain(tree->right->ftype,outfile);
4798                 fprintf(outfile,") to type (");
4799                 printTypeChain(tree->ftype,outfile);
4800                 fprintf(outfile,")\n");
4801                 ast_print(tree->right,outfile,indent+2);
4802                 return ;
4803                 
4804         case AND_OP:
4805                 fprintf(outfile,"ANDAND (%p) type (",tree);
4806                 printTypeChain(tree->ftype,outfile);
4807                 fprintf(outfile,")\n");
4808                 ast_print(tree->left,outfile,indent+2);
4809                 ast_print(tree->right,outfile,indent+2);
4810                 return ;
4811         case OR_OP:
4812                 fprintf(outfile,"OROR (%p) type (",tree);
4813                 printTypeChain(tree->ftype,outfile);
4814                 fprintf(outfile,")\n");
4815                 ast_print(tree->left,outfile,indent+2);
4816                 ast_print(tree->right,outfile,indent+2);
4817                 return ;
4818                 
4819                 /*------------------------------------------------------------------*/
4820                 /*----------------------------*/
4821                 /*     comparison operators   */
4822                 /*----------------------------*/
4823         case '>':
4824                 fprintf(outfile,"GT(>) (%p) type (",tree);
4825                 printTypeChain(tree->ftype,outfile);
4826                 fprintf(outfile,")\n");
4827                 ast_print(tree->left,outfile,indent+2);
4828                 ast_print(tree->right,outfile,indent+2);
4829                 return ;
4830         case '<':
4831                 fprintf(outfile,"LT(<) (%p) type (",tree);
4832                 printTypeChain(tree->ftype,outfile);
4833                 fprintf(outfile,")\n");
4834                 ast_print(tree->left,outfile,indent+2);
4835                 ast_print(tree->right,outfile,indent+2);
4836                 return ;
4837         case LE_OP:
4838                 fprintf(outfile,"LE(<=) (%p) type (",tree);
4839                 printTypeChain(tree->ftype,outfile);
4840                 fprintf(outfile,")\n");
4841                 ast_print(tree->left,outfile,indent+2);
4842                 ast_print(tree->right,outfile,indent+2);
4843                 return ;
4844         case GE_OP:
4845                 fprintf(outfile,"GE(>=) (%p) type (",tree);
4846                 printTypeChain(tree->ftype,outfile);
4847                 fprintf(outfile,")\n");
4848                 ast_print(tree->left,outfile,indent+2);
4849                 ast_print(tree->right,outfile,indent+2);
4850                 return ;
4851         case EQ_OP:
4852                 fprintf(outfile,"EQ(==) (%p) type (",tree);
4853                 printTypeChain(tree->ftype,outfile);
4854                 fprintf(outfile,")\n");
4855                 ast_print(tree->left,outfile,indent+2);
4856                 ast_print(tree->right,outfile,indent+2);
4857                 return ;
4858         case NE_OP:
4859                 fprintf(outfile,"NE(!=) (%p) type (",tree);
4860                 printTypeChain(tree->ftype,outfile);
4861                 fprintf(outfile,")\n");
4862                 ast_print(tree->left,outfile,indent+2);
4863                 ast_print(tree->right,outfile,indent+2);
4864                 /*------------------------------------------------------------------*/
4865                 /*----------------------------*/
4866                 /*             sizeof         */
4867                 /*----------------------------*/
4868         case SIZEOF:            /* evaluate wihout code generation */
4869                 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4870                 return ;
4871
4872                 /*------------------------------------------------------------------*/
4873                 /*----------------------------*/
4874                 /* conditional operator  '?'  */
4875                 /*----------------------------*/
4876         case '?':
4877                 fprintf(outfile,"QUEST(?) (%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         case ':':
4885                 fprintf(outfile,"COLON(:) (%p) type (",tree);
4886                 printTypeChain(tree->ftype,outfile);
4887                 fprintf(outfile,")\n");
4888                 ast_print(tree->left,outfile,indent+2);
4889                 ast_print(tree->right,outfile,indent+2);
4890                 return ;
4891                 
4892                 /*------------------------------------------------------------------*/
4893                 /*----------------------------*/
4894                 /*    assignment operators    */
4895                 /*----------------------------*/
4896         case MUL_ASSIGN:
4897                 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4898                 printTypeChain(tree->ftype,outfile);
4899                 fprintf(outfile,")\n");
4900                 ast_print(tree->left,outfile,indent+2);
4901                 ast_print(tree->right,outfile,indent+2);
4902                 return;
4903         case DIV_ASSIGN:
4904                 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4905                 printTypeChain(tree->ftype,outfile);
4906                 fprintf(outfile,")\n");
4907                 ast_print(tree->left,outfile,indent+2);
4908                 ast_print(tree->right,outfile,indent+2);
4909                 return;
4910         case AND_ASSIGN:
4911                 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4912                 printTypeChain(tree->ftype,outfile);
4913                 fprintf(outfile,")\n");
4914                 ast_print(tree->left,outfile,indent+2);
4915                 ast_print(tree->right,outfile,indent+2);
4916                 return;
4917         case OR_ASSIGN:
4918                 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
4919                 printTypeChain(tree->ftype,outfile);
4920                 fprintf(outfile,")\n");
4921                 ast_print(tree->left,outfile,indent+2);
4922                 ast_print(tree->right,outfile,indent+2);
4923                 return;
4924         case XOR_ASSIGN:
4925                 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
4926                 printTypeChain(tree->ftype,outfile);
4927                 fprintf(outfile,")\n");
4928                 ast_print(tree->left,outfile,indent+2);
4929                 ast_print(tree->right,outfile,indent+2);
4930                 return;
4931         case RIGHT_ASSIGN:
4932                 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4933                 printTypeChain(tree->ftype,outfile);
4934                 fprintf(outfile,")\n");
4935                 ast_print(tree->left,outfile,indent+2);
4936                 ast_print(tree->right,outfile,indent+2);
4937                 return;
4938         case LEFT_ASSIGN:
4939                 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
4940                 printTypeChain(tree->ftype,outfile);
4941                 fprintf(outfile,")\n");
4942                 ast_print(tree->left,outfile,indent+2);
4943                 ast_print(tree->right,outfile,indent+2);
4944                 return;
4945                 /*------------------------------------------------------------------*/
4946                 /*----------------------------*/
4947                 /*    -= operator             */
4948                 /*----------------------------*/
4949         case SUB_ASSIGN:
4950                 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4951                 printTypeChain(tree->ftype,outfile);
4952                 fprintf(outfile,")\n");
4953                 ast_print(tree->left,outfile,indent+2);
4954                 ast_print(tree->right,outfile,indent+2);
4955                 return;
4956                 /*------------------------------------------------------------------*/
4957                 /*----------------------------*/
4958                 /*          += operator       */
4959                 /*----------------------------*/
4960         case ADD_ASSIGN:
4961                 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4962                 printTypeChain(tree->ftype,outfile);
4963                 fprintf(outfile,")\n");
4964                 ast_print(tree->left,outfile,indent+2);
4965                 ast_print(tree->right,outfile,indent+2);
4966                 return;
4967                 /*------------------------------------------------------------------*/
4968                 /*----------------------------*/
4969                 /*      straight assignemnt   */
4970                 /*----------------------------*/
4971         case '=':
4972                 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4973                 printTypeChain(tree->ftype,outfile);
4974                 fprintf(outfile,")\n");
4975                 ast_print(tree->left,outfile,indent+2);
4976                 ast_print(tree->right,outfile,indent+2);
4977                 return;     
4978                 /*------------------------------------------------------------------*/
4979                 /*----------------------------*/
4980                 /*      comma operator        */
4981                 /*----------------------------*/
4982         case ',':
4983                 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4984                 printTypeChain(tree->ftype,outfile);
4985                 fprintf(outfile,")\n");
4986                 ast_print(tree->left,outfile,indent+2);
4987                 ast_print(tree->right,outfile,indent+2);
4988                 return;
4989                 /*------------------------------------------------------------------*/
4990                 /*----------------------------*/
4991                 /*       function call        */
4992                 /*----------------------------*/
4993         case CALL:
4994         case PCALL:
4995                 fprintf(outfile,"CALL (%p) type (",tree);
4996                 printTypeChain(tree->ftype,outfile);
4997                 fprintf(outfile,")\n");
4998                 ast_print(tree->left,outfile,indent+2);
4999                 ast_print(tree->right,outfile,indent+2);
5000                 return;
5001         case PARAM:
5002                 fprintf(outfile,"PARMS\n");
5003                 ast_print(tree->left,outfile,indent+2);
5004                 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5005                         ast_print(tree->right,outfile,indent+2);
5006                 }
5007                 return ;
5008                 /*------------------------------------------------------------------*/
5009                 /*----------------------------*/
5010                 /*     return statement       */
5011                 /*----------------------------*/
5012         case RETURN:
5013                 fprintf(outfile,"RETURN (%p) type (",tree);
5014                 if (tree->right) {
5015                     printTypeChain(tree->right->ftype,outfile);
5016                 }
5017                 fprintf(outfile,")\n");
5018                 ast_print(tree->right,outfile,indent+2);
5019                 return ;
5020                 /*------------------------------------------------------------------*/
5021                 /*----------------------------*/
5022                 /*     label statement        */
5023                 /*----------------------------*/
5024         case LABEL :
5025                 fprintf(outfile,"LABEL (%p)\n",tree);
5026                 ast_print(tree->left,outfile,indent+2);
5027                 ast_print(tree->right,outfile,indent);
5028                 return;
5029                 /*------------------------------------------------------------------*/
5030                 /*----------------------------*/
5031                 /*     switch statement       */
5032                 /*----------------------------*/
5033         case SWITCH:
5034                 {
5035                         value *val;
5036                         fprintf(outfile,"SWITCH (%p) ",tree);
5037                         ast_print(tree->left,outfile,0);
5038                         for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5039                                 INDENT(indent+2,outfile);
5040                                 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5041                                         (int) floatFromVal(val),
5042                                         tree->values.switchVals.swNum,
5043                                         (int) floatFromVal(val));
5044                         }
5045                         ast_print(tree->right,outfile,indent);
5046                 }
5047                 return ;
5048                 /*------------------------------------------------------------------*/
5049                 /*----------------------------*/
5050                 /* ifx Statement              */
5051                 /*----------------------------*/
5052         case IFX:
5053                 fprintf(outfile,"IF (%p) \n",tree);
5054                 ast_print(tree->left,outfile,indent+2);
5055                 if (tree->trueLabel) {
5056                         INDENT(indent+2,outfile);
5057                         fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5058                 }
5059                 if (tree->falseLabel) {
5060                         INDENT(indent+2,outfile);
5061                         fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5062                 }
5063                 ast_print(tree->right,outfile,indent+2);
5064                 return ;
5065                 /*----------------------------*/
5066                 /* goto Statement              */
5067                 /*----------------------------*/
5068         case GOTO:
5069                 fprintf(outfile,"GOTO (%p) \n",tree);
5070                 ast_print(tree->left,outfile,indent+2);
5071                 fprintf(outfile,"\n");
5072                 return ;
5073                 /*------------------------------------------------------------------*/
5074                 /*----------------------------*/
5075                 /* for Statement              */
5076                 /*----------------------------*/
5077         case FOR:
5078                 fprintf(outfile,"FOR (%p) \n",tree);
5079                 if (AST_FOR( tree, initExpr)) {
5080                         INDENT(indent+2,outfile);
5081                         fprintf(outfile,"INIT EXPR ");
5082                         ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5083                 }
5084                 if (AST_FOR( tree, condExpr)) {
5085                         INDENT(indent+2,outfile);
5086                         fprintf(outfile,"COND EXPR ");
5087                         ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5088                 }
5089                 if (AST_FOR( tree, loopExpr)) {
5090                         INDENT(indent+2,outfile);
5091                         fprintf(outfile,"LOOP EXPR ");
5092                         ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5093                 }
5094                 fprintf(outfile,"FOR LOOP BODY \n");
5095                 ast_print(tree->left,outfile,indent+2);
5096                 return ;
5097         default:
5098             return ;
5099         }
5100 }
5101
5102 void PA(ast *t)
5103 {
5104         ast_print(t,stdout,0);
5105 }