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