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