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