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