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