* src/SDCCast.c (decorateType): fixed bug #1105626
[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   else
1537     return FALSE;
1538
1539   /* check loop expression is of the form <sym>++ */
1540   if (!IS_AST_OP (loopExpr))
1541     return FALSE;
1542
1543   /* check if <sym> ++ */
1544   if (loopExpr->opval.op == INC_OP)
1545     {
1546
1547       if (loopExpr->left)
1548         {
1549           /* pre */
1550           if (IS_AST_SYM_VALUE (loopExpr->left) &&
1551               isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1552             return TRUE;
1553
1554         }
1555       else
1556         {
1557           /* post */
1558           if (IS_AST_SYM_VALUE (loopExpr->right) &&
1559               isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1560             return TRUE;
1561         }
1562
1563     }
1564   else
1565     {
1566       /* check for += */
1567       if (loopExpr->opval.op == ADD_ASSIGN)
1568         {
1569
1570           if (IS_AST_SYM_VALUE (loopExpr->left) &&
1571               isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1572               IS_AST_LIT_VALUE (loopExpr->right) &&
1573               (int) AST_LIT_VALUE (loopExpr->right) != 1)
1574             return TRUE;
1575         }
1576     }
1577
1578   return FALSE;
1579 }
1580
1581 /*-----------------------------------------------------------------*/
1582 /* astHasVolatile - returns true if ast contains any volatile      */
1583 /*-----------------------------------------------------------------*/
1584 bool 
1585 astHasVolatile (ast * tree)
1586 {
1587   if (!tree)
1588     return FALSE;
1589
1590   if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1591     return TRUE;
1592
1593   if (IS_AST_OP (tree))
1594     return astHasVolatile (tree->left) ||
1595       astHasVolatile (tree->right);
1596   else
1597     return FALSE;
1598 }
1599
1600 /*-----------------------------------------------------------------*/
1601 /* astHasPointer - return true if the ast contains any ptr variable */
1602 /*-----------------------------------------------------------------*/
1603 bool 
1604 astHasPointer (ast * tree)
1605 {
1606   if (!tree)
1607     return FALSE;
1608
1609   if (IS_AST_LINK (tree))
1610     return TRUE;
1611
1612   /* if we hit an array expression then check
1613      only the left side */
1614   if (IS_AST_OP (tree) && tree->opval.op == '[')
1615     return astHasPointer (tree->left);
1616
1617   if (IS_AST_VALUE (tree))
1618     return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1619
1620   return astHasPointer (tree->left) ||
1621     astHasPointer (tree->right);
1622
1623 }
1624
1625 /*-----------------------------------------------------------------*/
1626 /* astHasSymbol - return true if the ast has the given symbol      */
1627 /*-----------------------------------------------------------------*/
1628 bool 
1629 astHasSymbol (ast * tree, symbol * sym)
1630 {
1631   if (!tree || IS_AST_LINK (tree))
1632     return FALSE;
1633
1634   if (IS_AST_VALUE (tree))
1635     {
1636       if (IS_AST_SYM_VALUE (tree))
1637         return isSymbolEqual (AST_SYMBOL (tree), sym);
1638       else
1639         return FALSE;
1640     }
1641
1642   return astHasSymbol (tree->left, sym) ||
1643     astHasSymbol (tree->right, sym);
1644 }
1645
1646 /*-----------------------------------------------------------------*/
1647 /* astHasDeref - return true if the ast has an indirect access     */
1648 /*-----------------------------------------------------------------*/
1649 static bool 
1650 astHasDeref (ast * tree)
1651 {
1652   if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1653     return FALSE;
1654
1655   if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1656   
1657   return astHasDeref (tree->left) || astHasDeref (tree->right);
1658 }
1659
1660 /*-----------------------------------------------------------------*/
1661 /* isConformingBody - the loop body has to conform to a set of rules */
1662 /* for the loop to be considered reversible read on for rules      */
1663 /*-----------------------------------------------------------------*/
1664 bool 
1665 isConformingBody (ast * pbody, symbol * sym, ast * body)
1666 {
1667
1668   /* we are going to do a pre-order traversal of the
1669      tree && check for the following conditions. (essentially
1670      a set of very shallow tests )
1671      a) the sym passed does not participate in
1672      any arithmetic operation
1673      b) There are no function calls
1674      c) all jumps are within the body
1675      d) address of loop control variable not taken
1676      e) if an assignment has a pointer on the
1677      left hand side make sure right does not have
1678      loop control variable */
1679
1680   /* if we reach the end or a leaf then true */
1681   if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1682     return TRUE;
1683   
1684   /* if anything else is "volatile" */
1685   if (IS_VOLATILE (TETYPE (pbody)))
1686     return FALSE;
1687
1688   /* we will walk the body in a pre-order traversal for
1689      efficiency sake */
1690   switch (pbody->opval.op)
1691     {
1692 /*------------------------------------------------------------------*/
1693     case '[':
1694       // if the loopvar is used as an index
1695       /* array op is commutative -- must check both left & right */
1696       if (astHasSymbol(pbody->right, sym) || astHasSymbol(pbody->left, sym)) {
1697         return FALSE;
1698       }
1699       return isConformingBody (pbody->right, sym, body)
1700               && isConformingBody (pbody->left, sym, body);
1701
1702 /*------------------------------------------------------------------*/
1703     case PTR_OP:
1704     case '.':
1705       return TRUE;
1706
1707 /*------------------------------------------------------------------*/
1708     case INC_OP:
1709     case DEC_OP:
1710
1711       /* sure we are not sym is not modified */
1712       if (pbody->left &&
1713           IS_AST_SYM_VALUE (pbody->left) &&
1714           isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1715         return FALSE;
1716
1717       if (pbody->right &&
1718           IS_AST_SYM_VALUE (pbody->right) &&
1719           isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1720         return FALSE;
1721
1722       return TRUE;
1723
1724 /*------------------------------------------------------------------*/
1725
1726     case '*':                   /* can be unary  : if right is null then unary operation */
1727     case '+':
1728     case '-':
1729     case '&':
1730
1731       /* if right is NULL then unary operation  */
1732 /*------------------------------------------------------------------*/
1733 /*----------------------------*/
1734       /*  address of                */
1735 /*----------------------------*/
1736       if (!pbody->right)
1737         {
1738           if (IS_AST_SYM_VALUE (pbody->left) &&
1739               isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1740             return FALSE;
1741           else
1742             return isConformingBody (pbody->left, sym, body);
1743         }
1744       else
1745         {
1746           if (astHasSymbol (pbody->left, sym) ||
1747               astHasSymbol (pbody->right, sym))
1748             return FALSE;
1749         }
1750
1751
1752 /*------------------------------------------------------------------*/
1753     case '|':
1754     case '^':
1755     case '/':
1756     case '%':
1757     case LEFT_OP:
1758     case RIGHT_OP:
1759
1760       if (IS_AST_SYM_VALUE (pbody->left) &&
1761           isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1762         return FALSE;
1763
1764       if (IS_AST_SYM_VALUE (pbody->right) &&
1765           isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1766         return FALSE;
1767
1768       return isConformingBody (pbody->left, sym, body) &&
1769         isConformingBody (pbody->right, sym, body);
1770
1771     case '~':
1772     case '!':
1773     case RRC:
1774     case RLC:
1775     case GETHBIT:
1776     case SWAP:
1777       if (IS_AST_SYM_VALUE (pbody->left) &&
1778           isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1779         return FALSE;
1780       return isConformingBody (pbody->left, sym, body);
1781
1782 /*------------------------------------------------------------------*/
1783
1784     case AND_OP:
1785     case OR_OP:
1786     case '>':
1787     case '<':
1788     case LE_OP:
1789     case GE_OP:
1790     case EQ_OP:
1791     case NE_OP:
1792     case '?':
1793     case ':':
1794     case SIZEOF:                /* evaluate wihout code generation */
1795
1796       if (IS_AST_SYM_VALUE (pbody->left) &&
1797           isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1798         return FALSE;
1799
1800       if (IS_AST_SYM_VALUE (pbody->right) &&
1801           isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1802         return FALSE;
1803
1804       return isConformingBody (pbody->left, sym, body) &&
1805         isConformingBody (pbody->right, sym, body);
1806
1807 /*------------------------------------------------------------------*/
1808     case '=':
1809
1810       /* if left has a pointer & right has loop
1811          control variable then we cannot */
1812       if (astHasPointer (pbody->left) &&
1813           astHasSymbol (pbody->right, sym))
1814         return FALSE;
1815       if (astHasVolatile (pbody->left))
1816         return FALSE;
1817
1818       if (IS_AST_SYM_VALUE (pbody->left)) {
1819         // if the loopvar has an assignment
1820         if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1821           return FALSE;
1822         // if the loopvar is used in another (maybe conditional) block
1823         if (astHasSymbol (pbody->right, sym) &&
1824             (pbody->level >= body->level)) {
1825           return FALSE;
1826         }
1827       }
1828
1829       if (astHasVolatile (pbody->left))
1830         return FALSE;
1831
1832       if (astHasDeref(pbody->right)) return FALSE;
1833
1834       return isConformingBody (pbody->left, sym, body) &&
1835         isConformingBody (pbody->right, sym, body);
1836
1837     case MUL_ASSIGN:
1838     case DIV_ASSIGN:
1839     case AND_ASSIGN:
1840     case OR_ASSIGN:
1841     case XOR_ASSIGN:
1842     case RIGHT_ASSIGN:
1843     case LEFT_ASSIGN:
1844     case SUB_ASSIGN:
1845     case ADD_ASSIGN:
1846       assert ("Parser should not have generated this\n");
1847
1848 /*------------------------------------------------------------------*/
1849 /*----------------------------*/
1850       /*      comma operator        */
1851 /*----------------------------*/
1852     case ',':
1853       return isConformingBody (pbody->left, sym, body) &&
1854         isConformingBody (pbody->right, sym, body);
1855
1856 /*------------------------------------------------------------------*/
1857 /*----------------------------*/
1858       /*       function call        */
1859 /*----------------------------*/
1860     case CALL:
1861         /* if local & not passed as paramater then ok */
1862         if (sym->level && !astHasSymbol(pbody->right,sym)) 
1863             return TRUE;
1864       return FALSE;
1865
1866 /*------------------------------------------------------------------*/
1867 /*----------------------------*/
1868       /*     return statement       */
1869 /*----------------------------*/
1870     case RETURN:
1871       return FALSE;
1872
1873     case GOTO:
1874       if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1875         return TRUE;
1876       else
1877         return FALSE;
1878     case SWITCH:
1879       if (astHasSymbol (pbody->left, sym))
1880         return FALSE;
1881
1882     default:
1883       break;
1884     }
1885
1886   return isConformingBody (pbody->left, sym, body) &&
1887     isConformingBody (pbody->right, sym, body);
1888
1889
1890
1891 }
1892
1893 /*-----------------------------------------------------------------*/
1894 /* isLoopReversible - takes a for loop as input && returns true    */
1895 /* if the for loop is reversible. If yes will set the value of     */
1896 /* the loop control var & init value & termination value           */
1897 /*-----------------------------------------------------------------*/
1898 bool
1899 isLoopReversible (ast * loop, symbol ** loopCntrl,
1900                   ast ** init, ast ** end)
1901 {
1902   /* if option says don't do it then don't */
1903   if (optimize.noLoopReverse)
1904     return 0;
1905   /* there are several tests to determine this */
1906
1907   /* for loop has to be of the form
1908      for ( <sym> = <const1> ;
1909      [<sym> < <const2>]  ;
1910      [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1911      forBody */
1912   if (!isLoopCountable (AST_FOR (loop, initExpr),
1913                         AST_FOR (loop, condExpr),
1914                         AST_FOR (loop, loopExpr),
1915                         loopCntrl, init, end))
1916     return 0;
1917
1918   /* now do some serious checking on the body of the loop
1919    */
1920
1921   return isConformingBody (loop->left, *loopCntrl, loop->left);
1922
1923 }
1924
1925 /*-----------------------------------------------------------------*/
1926 /* replLoopSym - replace the loop sym by loop sym -1               */
1927 /*-----------------------------------------------------------------*/
1928 static void 
1929 replLoopSym (ast * body, symbol * sym)
1930 {
1931   /* reached end */
1932   if (!body || IS_AST_LINK (body))
1933     return;
1934
1935   if (IS_AST_SYM_VALUE (body))
1936     {
1937
1938       if (isSymbolEqual (AST_SYMBOL (body), sym))
1939         {
1940
1941           body->type = EX_OP;
1942           body->opval.op = '-';
1943           body->left = newAst_VALUE (symbolVal (sym));
1944           body->right = newAst_VALUE (constVal ("1"));
1945
1946         }
1947
1948       return;
1949
1950     }
1951
1952   replLoopSym (body->left, sym);
1953   replLoopSym (body->right, sym);
1954
1955 }
1956
1957 /*-----------------------------------------------------------------*/
1958 /* reverseLoop - do the actual loop reversal                       */
1959 /*-----------------------------------------------------------------*/
1960 ast *
1961 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1962 {
1963   ast *rloop;
1964
1965   /* create the following tree
1966      <sym> = loopCount ;
1967      for_continue:
1968      forbody
1969      <sym> -= 1;
1970      if (sym) goto for_continue ;
1971      <sym> = end */
1972
1973   /* put it together piece by piece */
1974   rloop = newNode (NULLOP,
1975                    createIf (newAst_VALUE (symbolVal (sym)),
1976                              newNode (GOTO,
1977                                       newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1978                                       NULL), NULL),
1979                    newNode ('=',
1980                             newAst_VALUE (symbolVal (sym)),
1981                             end));
1982
1983   replLoopSym (loop->left, sym);
1984   setAstLineno (rloop, init->lineno);
1985
1986   rloop = newNode (NULLOP,
1987                    newNode ('=',
1988                             newAst_VALUE (symbolVal (sym)),
1989                             newNode ('-', end, init)),
1990                    createLabel (AST_FOR (loop, continueLabel),
1991                                 newNode (NULLOP,
1992                                          loop->left,
1993                                          newNode (NULLOP,
1994                                                   newNode (SUB_ASSIGN,
1995                                                            newAst_VALUE (symbolVal (sym)),
1996                                                            newAst_VALUE (constVal ("1"))),
1997                                                   rloop))));
1998
1999   rloop->lineno=init->lineno;
2000   return decorateType (rloop, RESULT_TYPE_NONE);
2001
2002 }
2003
2004 /*-----------------------------------------------------------------*/
2005 /* searchLitOp - search tree (*ops only) for an ast with literal */
2006 /*-----------------------------------------------------------------*/
2007 static ast *
2008 searchLitOp (ast *tree, ast **parent, const unsigned char *ops)
2009 {
2010   ast *ret;
2011
2012   if (tree && optimize.global_cse)
2013     {
2014       /* is there a literal operand? */
2015       if (tree->right &&
2016           IS_AST_OP(tree->right) &&
2017           tree->right->right &&
2018           (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
2019         {
2020           if (IS_LITERAL (RTYPE (tree->right)) !=
2021               IS_LITERAL (LTYPE (tree->right)))
2022             {
2023               tree->right->decorated = 0;
2024               tree->decorated = 0;
2025               *parent = tree;
2026               return tree->right;
2027             }
2028           ret = searchLitOp (tree->right, parent, ops);
2029           if (ret)
2030             return ret;
2031         }
2032       if (tree->left &&
2033           IS_AST_OP(tree->left) &&
2034           tree->left->right &&
2035           (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
2036         {
2037           if (IS_LITERAL (RTYPE (tree->left)) !=
2038               IS_LITERAL (LTYPE (tree->left)))
2039             {
2040               tree->left->decorated = 0;
2041               tree->decorated = 0;
2042               *parent = tree;
2043               return tree->left;
2044             }
2045           ret = searchLitOp (tree->left, parent, ops);
2046           if (ret)
2047             return ret;
2048         }
2049     }
2050   return NULL;
2051 }
2052
2053 /*-----------------------------------------------------------------*/
2054 /* getResultFromType                                               */
2055 /*-----------------------------------------------------------------*/
2056 RESULT_TYPE
2057 getResultTypeFromType (sym_link *type)
2058 {
2059   /* type = getSpec (type); */
2060   if (IS_BIT (type))
2061     return RESULT_TYPE_BIT;
2062   if (IS_BITFIELD (type))
2063     {
2064       int blen = SPEC_BLEN (type);
2065       
2066       if (blen <= 1)
2067         return RESULT_TYPE_BIT;
2068       if (blen <= 8)
2069         return RESULT_TYPE_CHAR;
2070       return RESULT_TYPE_INT;
2071     }
2072   if (IS_CHAR (type))
2073     return RESULT_TYPE_CHAR;
2074   if (   IS_INT (type)
2075       && !IS_LONG (type))
2076     return RESULT_TYPE_INT;
2077   return RESULT_TYPE_OTHER;
2078 }
2079
2080 /*-----------------------------------------------------------------*/
2081 /* addCast - adds casts to a type specified by RESULT_TYPE         */
2082 /*-----------------------------------------------------------------*/
2083 static ast *
2084 addCast (ast *tree, RESULT_TYPE resultType, bool upcast)
2085 {
2086   sym_link *newLink;
2087   bool upCasted = FALSE;
2088   
2089   switch (resultType)
2090     {
2091       case RESULT_TYPE_NONE:
2092         /* char: promote to int */
2093         if (!upcast ||
2094             getSize (tree->etype) >= INTSIZE)
2095           return tree;
2096         newLink = newIntLink();
2097         upCasted = TRUE;
2098         break;
2099       case RESULT_TYPE_CHAR:
2100         if (IS_CHAR (tree->etype) ||
2101             IS_FLOAT(tree->etype))
2102           return tree;
2103         newLink = newCharLink();
2104         break;
2105       case RESULT_TYPE_INT:
2106 #if 0
2107         if (getSize (tree->etype) > INTSIZE)
2108           {
2109             /* warn ("Loosing significant digits"); */
2110             return;
2111           }
2112 #endif
2113         /* char: promote to int */
2114         if (!upcast ||
2115             getSize (tree->etype) >= INTSIZE)
2116           return tree;
2117         newLink = newIntLink();
2118         upCasted = TRUE;
2119         break;
2120       case RESULT_TYPE_OTHER:
2121         if (!upcast)
2122           return tree;
2123         /* return type is long, float: promote char to int */
2124         if (getSize (tree->etype) >= INTSIZE)
2125           return tree;
2126         newLink = newIntLink();
2127         upCasted = TRUE;
2128         break;
2129       default:
2130         return tree;
2131     }
2132   tree->decorated = 0;
2133   tree = newNode (CAST, newAst_LINK (newLink), tree);
2134   tree->lineno = tree->right->lineno;
2135   /* keep unsigned type during cast to smaller type,
2136      but not when promoting from char to int */
2137   if (!upCasted)
2138     SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2139   return decorateType (tree, resultType);
2140 }
2141
2142 /*-----------------------------------------------------------------*/
2143 /* resultTypePropagate - decides if resultType can be propagated   */
2144 /*-----------------------------------------------------------------*/
2145 static RESULT_TYPE
2146 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2147 {
2148   switch (tree->opval.op)
2149     {
2150       case '=':
2151       case '?':
2152       case ':':
2153       case '|':
2154       case '^':
2155       case '~':
2156       case '*':
2157       case '+':
2158       case '-':
2159       case LABEL:
2160         return resultType;
2161       case '&':
2162         if (!tree->right)
2163           /* can be unary */
2164           return RESULT_TYPE_NONE;
2165         else
2166           return resultType;
2167       case IFX:
2168         return RESULT_TYPE_IFX;
2169       default:
2170         return RESULT_TYPE_NONE;
2171     }
2172 }
2173
2174 /*-----------------------------------------------------------------*/
2175 /* getLeftResultType - gets type from left branch for propagation  */
2176 /*-----------------------------------------------------------------*/
2177 static RESULT_TYPE
2178 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2179 {
2180   switch (tree->opval.op)
2181     {
2182       case '=':
2183       case CAST:
2184         if (IS_PTR (LTYPE (tree)))
2185           return RESULT_TYPE_NONE;
2186         else
2187           return getResultTypeFromType (LETYPE (tree));
2188       case RETURN:
2189         if (IS_PTR (currFunc->type->next))
2190           return RESULT_TYPE_NONE;
2191         else
2192           return getResultTypeFromType (currFunc->type->next);
2193       case '[':
2194         if (!IS_ARRAY (LTYPE (tree)))
2195           return resultType;
2196         if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256)
2197           return RESULT_TYPE_CHAR;
2198         return resultType;
2199       default:
2200         return resultType;
2201     }
2202 }
2203
2204 /*--------------------------------------------------------------------*/
2205 /* decorateType - compute type for this tree, also does type checking.*/
2206 /* This is done bottom up, since type has to flow upwards.            */
2207 /* resultType flows top-down and forces e.g. char-arithmetik, if the  */
2208 /* result is a char and the operand(s) are int's.                     */
2209 /* It also does constant folding, and parameter checking.             */
2210 /*--------------------------------------------------------------------*/
2211 ast *
2212 decorateType (ast * tree, RESULT_TYPE resultType)
2213 {
2214   int parmNumber;
2215   sym_link *p;
2216   RESULT_TYPE resultTypeProp;
2217
2218   if (!tree)
2219     return tree;
2220
2221   /* if already has type then do nothing */
2222   if (tree->decorated)
2223     return tree;
2224
2225   tree->decorated = 1;
2226
2227 #if 0
2228   /* print the line          */
2229   /* if not block & function */
2230   if (tree->type == EX_OP &&
2231       (tree->opval.op != FUNCTION &&
2232        tree->opval.op != BLOCK &&
2233        tree->opval.op != NULLOP))
2234     {
2235       filename = tree->filename;
2236       lineno = tree->lineno;
2237     }
2238 #endif
2239
2240   /* if any child is an error | this one is an error do nothing */
2241   if (tree->isError ||
2242       (tree->left && tree->left->isError) ||
2243       (tree->right && tree->right->isError))
2244     return tree;
2245
2246 /*------------------------------------------------------------------*/
2247 /*----------------------------*/
2248 /*   leaf has been reached    */
2249 /*----------------------------*/
2250   lineno=tree->lineno;
2251   /* if this is of type value */
2252   /* just get the type        */
2253   if (tree->type == EX_VALUE)
2254     {
2255
2256       if (IS_LITERAL (tree->opval.val->etype))
2257         {
2258
2259           /* if this is a character array then declare it */
2260           if (IS_ARRAY (tree->opval.val->type))
2261             tree->opval.val = stringToSymbol (tree->opval.val);
2262
2263           /* otherwise just copy the type information */
2264           COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2265           return tree;
2266         }
2267
2268       if (tree->opval.val->sym)
2269         {
2270           /* if the undefined flag is set then give error message */
2271           if (tree->opval.val->sym->undefined)
2272             {
2273               werror (E_ID_UNDEF, tree->opval.val->sym->name);
2274               /* assume int */
2275               TTYPE (tree) = TETYPE (tree) =
2276                 tree->opval.val->type = tree->opval.val->sym->type =
2277                 tree->opval.val->etype = tree->opval.val->sym->etype =
2278                 copyLinkChain (INTTYPE);
2279             }
2280           else
2281             {
2282
2283               /* if impilicit i.e. struct/union member then no type */
2284               if (tree->opval.val->sym->implicit)
2285                 TTYPE (tree) = TETYPE (tree) = NULL;
2286
2287               else
2288                 {
2289
2290                   /* else copy the type */
2291                   COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2292
2293                   /* and mark it as referenced */
2294                   tree->opval.val->sym->isref = 1;
2295                 }
2296             }
2297         }
2298
2299       return tree;
2300     }
2301
2302   /* if type link for the case of cast */
2303   if (tree->type == EX_LINK)
2304     {
2305       COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2306       return tree;
2307     }
2308
2309   {
2310     ast *dtl, *dtr;
2311
2312     #if 0
2313     if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2314       {
2315         if (tree->left && tree->left->type == EX_OPERAND
2316             && (tree->left->opval.op == INC_OP
2317                 || tree->left->opval.op == DEC_OP)
2318             && tree->left->left)
2319           {
2320             tree->left->right = tree->left->left;
2321             tree->left->left = NULL;
2322           }
2323         if (tree->right && tree->right->type == EX_OPERAND
2324             && (tree->right->opval.op == INC_OP
2325                 || tree->right->opval.op == DEC_OP)
2326             && tree->right->left)
2327           {
2328             tree->right->right = tree->right->left;
2329             tree->right->left = NULL;
2330           }
2331       }
2332     #endif
2333
2334     /* Before decorating the left branch we've to decide in dependence
2335        upon tree->opval.op, if resultType can be propagated */
2336     resultTypeProp = resultTypePropagate (tree, resultType);
2337
2338     if (tree->opval.op == '?')
2339       dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2340     else
2341       dtl = decorateType (tree->left, resultTypeProp);
2342
2343     /* if an array node, we may need to swap branches */
2344     if (tree->opval.op == '[')
2345       {
2346         /* determine which is the array & which the index */
2347         if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2348             IS_INTEGRAL (LTYPE (tree)))
2349           {
2350             ast *tempTree = tree->left;
2351             tree->left = tree->right;
2352             tree->right = tempTree;
2353           }
2354       }
2355
2356     /* After decorating the left branch there's type information available
2357        in tree->left->?type. If the op is e.g. '=' we extract the type
2358        information from there and propagate it to the right branch. */
2359     resultTypeProp = getLeftResultType (tree, resultTypeProp);
2360     
2361     switch (tree->opval.op)
2362       {
2363         case '?':
2364           /* delay right side for '?' operator since conditional macro
2365              expansions might rely on this */
2366           dtr = tree->right;
2367           break;
2368         case CALL: 
2369           /* decorate right side for CALL (parameter list) in processParms();
2370              there is resultType available */
2371           dtr = tree->right;
2372           break;
2373         default:     
2374           dtr = decorateType (tree->right, resultTypeProp);
2375           break;
2376       }
2377
2378     /* this is to take care of situations
2379        when the tree gets rewritten */
2380     if (dtl != tree->left)
2381       tree->left = dtl;
2382     if (dtr != tree->right)
2383       tree->right = dtr;
2384     if ((dtl && dtl->isError) || (dtr && dtr->isError))
2385       return tree;
2386   }
2387
2388   /* depending on type of operator do */
2389
2390   switch (tree->opval.op)
2391     {
2392         /*------------------------------------------------------------------*/
2393         /*----------------------------*/
2394         /*        array node          */
2395         /*----------------------------*/
2396     case '[':
2397
2398       /* first check if this is a array or a pointer */
2399       if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2400         {
2401           werror (E_NEED_ARRAY_PTR, "[]");
2402           goto errorTreeReturn;
2403         }
2404
2405       /* check if the type of the idx */
2406       if (!IS_INTEGRAL (RTYPE (tree)))
2407         {
2408           werror (E_IDX_NOT_INT);
2409           goto errorTreeReturn;
2410         }
2411
2412       /* if the left is an rvalue then error */
2413       if (LRVAL (tree))
2414         {
2415           werror (E_LVALUE_REQUIRED, "array access");
2416           goto errorTreeReturn;
2417         }
2418
2419       if (IS_LITERAL (RTYPE (tree)))
2420         {
2421           int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2422           int arraySize = DCL_ELEM (LTYPE (tree));
2423           if (arraySize && arrayIndex >= arraySize)
2424             {
2425               werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2426             }
2427         }
2428
2429       RRVAL (tree) = 1;
2430       COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2431       return tree;
2432
2433       /*------------------------------------------------------------------*/
2434       /*----------------------------*/
2435       /*      struct/union          */
2436       /*----------------------------*/
2437     case '.':
2438       /* if this is not a structure */
2439       if (!IS_STRUCT (LTYPE (tree)))
2440         {
2441           werror (E_STRUCT_UNION, ".");
2442           goto errorTreeReturn;
2443         }
2444       TTYPE (tree) = structElemType (LTYPE (tree),
2445                                      (tree->right->type == EX_VALUE ?
2446                                tree->right->opval.val : NULL));
2447       TETYPE (tree) = getSpec (TTYPE (tree));
2448       return tree;
2449
2450       /*------------------------------------------------------------------*/
2451       /*----------------------------*/
2452       /*    struct/union pointer    */
2453       /*----------------------------*/
2454     case PTR_OP:
2455       /* if not pointer to a structure */
2456       if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2457         {
2458           werror (E_PTR_REQD);
2459           goto errorTreeReturn;
2460         }
2461
2462       if (!IS_STRUCT (LTYPE (tree)->next))
2463         {
2464           werror (E_STRUCT_UNION, "->");
2465           goto errorTreeReturn;
2466         }
2467
2468       TTYPE (tree) = structElemType (LTYPE (tree)->next,
2469                                      (tree->right->type == EX_VALUE ?
2470                                tree->right->opval.val : NULL));
2471       TETYPE (tree) = getSpec (TTYPE (tree));
2472
2473       /* adjust the storage class */
2474       switch (DCL_TYPE(tree->left->ftype)) {
2475       case POINTER:
2476         SPEC_SCLS(TETYPE(tree)) = S_DATA; 
2477         break;
2478       case FPOINTER:
2479         SPEC_SCLS(TETYPE(tree)) = S_XDATA; 
2480         break;
2481       case CPOINTER:
2482         SPEC_SCLS(TETYPE(tree)) = S_CODE; 
2483         break;
2484       case GPOINTER:
2485         SPEC_SCLS (TETYPE (tree)) = 0;
2486         break;
2487       case PPOINTER:
2488         SPEC_SCLS(TETYPE(tree)) = S_XSTACK; 
2489         break;
2490       case IPOINTER:
2491         SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2492         break;
2493       case EEPPOINTER:
2494         SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2495         break;
2496       case UPOINTER:
2497         SPEC_SCLS (TETYPE (tree)) = 0;
2498         break;
2499       case ARRAY:
2500       case FUNCTION:
2501         break;
2502       }
2503       
2504       /* This breaks with extern declarations, bitfields, and perhaps other */
2505       /* cases (gcse). Let's leave this optimization disabled for now and   */
2506       /* ponder if there's a safe way to do this. -- EEP                    */
2507       #if 0
2508       if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2509           && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2510         {
2511             /* If defined    struct type at addr var
2512                then rewrite  (&struct var)->member
2513                as            temp
2514                and define    membertype at (addr+offsetof(struct var,member)) temp
2515             */
2516             symbol *sym;
2517             symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2518                                                 AST_SYMBOL(tree->right));
2519
2520             sym = newSymbol(genSymName (0), 0);
2521             sym->type = TTYPE (tree);
2522             sym->etype = getSpec(sym->type);
2523             sym->lineDef = tree->lineno;
2524             sym->cdef = 1;
2525             sym->isref = 1;
2526             SPEC_STAT (sym->etype) = 1;
2527             SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2528                                      + element->offset;
2529             SPEC_ABSA(sym->etype) = 1;
2530             addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2531             allocGlobal (sym);
2532             
2533             AST_VALUE (tree) = symbolVal(sym);
2534             TLVAL (tree) = 1;
2535             TRVAL (tree) = 0;
2536             tree->type = EX_VALUE;
2537             tree->left = NULL;
2538             tree->right = NULL;
2539         }
2540       #endif
2541       
2542       return tree;
2543
2544       /*------------------------------------------------------------------*/
2545       /*----------------------------*/
2546       /*  ++/-- operation           */
2547       /*----------------------------*/
2548     case INC_OP:
2549     case DEC_OP:
2550       {
2551         sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2552         COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2553         if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2554           werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2555
2556         if (tree->right)
2557           RLVAL (tree) = 1;
2558         else
2559           LLVAL (tree) = 1;
2560         return tree;
2561       }
2562
2563       /*------------------------------------------------------------------*/
2564       /*----------------------------*/
2565       /*  bitwise and               */
2566       /*----------------------------*/
2567     case '&':                   /* can be unary   */
2568       /* if right is NULL then unary operation  */
2569       if (tree->right)          /* not an unary operation */
2570         {
2571
2572           if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2573             {
2574               werror (E_BITWISE_OP);
2575               werror (W_CONTINUE, "left & right types are ");
2576               printTypeChain (LTYPE (tree), stderr);
2577               fprintf (stderr, ",");
2578               printTypeChain (RTYPE (tree), stderr);
2579               fprintf (stderr, "\n");
2580               goto errorTreeReturn;
2581             }
2582
2583           /* if they are both literal */
2584           if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2585             {
2586               tree->type = EX_VALUE;
2587               tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2588                                           valFromType (RETYPE (tree)), '&');
2589
2590               tree->right = tree->left = NULL;
2591               TETYPE (tree) = tree->opval.val->etype;
2592               TTYPE (tree) = tree->opval.val->type;
2593               return tree;
2594             }
2595
2596           /* see if this is a GETHBIT operation if yes
2597              then return that */
2598           {
2599             ast *otree = optimizeGetHbit (tree);
2600
2601             if (otree != tree)
2602               return decorateType (otree, RESULT_TYPE_NONE);
2603           }
2604
2605           /* if left is a literal exchange left & right */
2606           if (IS_LITERAL (LTYPE (tree)))
2607             {
2608               ast *tTree = tree->left;
2609               tree->left = tree->right;
2610               tree->right = tTree;
2611             }
2612
2613           /* if right is a literal and */
2614           /* we can find a 2nd literal in an and-tree then */
2615           /* rearrange the tree */
2616           if (IS_LITERAL (RTYPE (tree)))
2617             {
2618               ast *parent;
2619               ast *litTree = searchLitOp (tree, &parent, "&");
2620               if (litTree)
2621                 {
2622                   DEBUG_CF("&")
2623                   ast *tTree = litTree->left;
2624                   litTree->left = tree->right;
2625                   tree->right = tTree;
2626                   /* both operands in litTree are literal now */
2627                   decorateType (parent, resultType);
2628                 }
2629             }
2630
2631           LRVAL (tree) = RRVAL (tree) = 1;
2632           
2633           TTYPE (tree) = computeType (LTYPE (tree),
2634                                       RTYPE (tree),
2635                                       resultType,
2636                                       tree->opval.op);
2637           TETYPE (tree) = getSpec (TTYPE (tree));
2638
2639           return tree;
2640         }
2641
2642       /*------------------------------------------------------------------*/
2643       /*----------------------------*/
2644       /*  address of                */
2645       /*----------------------------*/
2646       p = newLink (DECLARATOR);
2647       /* if bit field then error */
2648       if (IS_BITVAR (tree->left->etype))
2649         {
2650           werror (E_ILLEGAL_ADDR, "address of bit variable");
2651           goto errorTreeReturn;
2652         }
2653
2654       if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2655         {
2656           werror (E_ILLEGAL_ADDR, "address of register variable");
2657           goto errorTreeReturn;
2658         }
2659
2660       if (IS_FUNC (LTYPE (tree)))
2661         {
2662           // this ought to be ignored
2663           return (tree->left);
2664         }
2665
2666       if (IS_LITERAL(LTYPE(tree)))
2667         {
2668           werror (E_ILLEGAL_ADDR, "address of literal");
2669           goto errorTreeReturn;
2670         }
2671
2672      if (LRVAL (tree))
2673         {
2674           werror (E_LVALUE_REQUIRED, "address of");
2675           goto errorTreeReturn;
2676         }
2677       if (!LETYPE (tree))
2678         DCL_TYPE (p) = POINTER;
2679       else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2680         DCL_TYPE (p) = CPOINTER;
2681       else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2682         DCL_TYPE (p) = FPOINTER;
2683       else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2684         DCL_TYPE (p) = PPOINTER;
2685       else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2686         DCL_TYPE (p) = IPOINTER;
2687       else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2688         DCL_TYPE (p) = EEPPOINTER;
2689       else if (SPEC_OCLS(tree->left->etype))
2690           DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2691       else
2692           DCL_TYPE (p) = POINTER;
2693
2694       if (IS_AST_SYM_VALUE (tree->left))
2695         {
2696           AST_SYMBOL (tree->left)->addrtaken = 1;
2697           AST_SYMBOL (tree->left)->allocreq = 1;
2698         }
2699
2700       p->next = LTYPE (tree);
2701       TTYPE (tree) = p;
2702       TETYPE (tree) = getSpec (TTYPE (tree));
2703       LLVAL (tree) = 1;
2704       TLVAL (tree) = 1;
2705
2706       #if 0
2707       if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2708           && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2709         {
2710           symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2711                                       AST_SYMBOL(tree->left->right));
2712           AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2713                                     valueFromLit(element->offset));
2714           tree->left = NULL;
2715           tree->right = NULL;
2716           tree->type = EX_VALUE;
2717           tree->values.literalFromCast = 1;
2718         }
2719       #endif
2720
2721       return tree;
2722
2723       /*------------------------------------------------------------------*/
2724       /*----------------------------*/
2725       /*  bitwise or                */
2726       /*----------------------------*/
2727     case '|':
2728       /* if the rewrite succeeds then don't go any furthur */
2729       {
2730         ast *wtree = optimizeRRCRLC (tree);
2731         if (wtree != tree)
2732           return decorateType (wtree, RESULT_TYPE_NONE);
2733         
2734         wtree = optimizeSWAP (tree);
2735         if (wtree != tree)
2736           return decorateType (wtree, RESULT_TYPE_NONE);
2737       }
2738
2739       /* if left is a literal exchange left & right */
2740       if (IS_LITERAL (LTYPE (tree)))
2741         {
2742           ast *tTree = tree->left;
2743           tree->left = tree->right;
2744           tree->right = tTree;
2745         }
2746
2747       /* if right is a literal and */
2748       /* we can find a 2nd literal in an or-tree then */
2749       /* rearrange the tree */
2750       if (IS_LITERAL (RTYPE (tree)))
2751         {
2752           ast *parent;
2753           ast *litTree = searchLitOp (tree, &parent, "|");
2754           if (litTree)
2755             {
2756               DEBUG_CF("|")
2757               ast *tTree = litTree->left;
2758               litTree->left = tree->right;
2759               tree->right = tTree;
2760               /* both operands in tTree are literal now */
2761               decorateType (parent, resultType);
2762             }
2763         }
2764       /* fall through */
2765
2766       /*------------------------------------------------------------------*/
2767       /*----------------------------*/
2768       /*  bitwise xor               */
2769       /*----------------------------*/
2770     case '^':
2771       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2772         {
2773           werror (E_BITWISE_OP);
2774           werror (W_CONTINUE, "left & right types are ");
2775           printTypeChain (LTYPE (tree), stderr);
2776           fprintf (stderr, ",");
2777           printTypeChain (RTYPE (tree), stderr);
2778           fprintf (stderr, "\n");
2779           goto errorTreeReturn;
2780         }
2781
2782       /* if they are both literal then rewrite the tree */
2783       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2784         {
2785           tree->type = EX_VALUE;
2786           tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2787                                         valFromType (RETYPE (tree)),
2788                                         tree->opval.op);
2789           tree->right = tree->left = NULL;
2790           TETYPE (tree) = tree->opval.val->etype;
2791           TTYPE (tree) = tree->opval.val->type;
2792           return tree;
2793         }
2794
2795       /* if left is a literal exchange left & right */
2796       if (IS_LITERAL (LTYPE (tree)))
2797         {
2798           ast *tTree = tree->left;
2799           tree->left = tree->right;
2800           tree->right = tTree;
2801         }
2802
2803       /* if right is a literal and */
2804       /* we can find a 2nd literal in a xor-tree then */
2805       /* rearrange the tree */
2806       if (IS_LITERAL (RTYPE (tree)) &&
2807           tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2808         {
2809           ast *parent;
2810           ast *litTree = searchLitOp (tree, &parent, "^");
2811           if (litTree)
2812             {
2813               DEBUG_CF("^")
2814               ast *tTree = litTree->left;
2815               litTree->left = tree->right;
2816               tree->right = tTree;
2817               /* both operands in litTree are literal now */
2818               decorateType (parent, resultType);
2819             }
2820         }
2821
2822       LRVAL (tree) = RRVAL (tree) = 1;
2823
2824       TTYPE (tree) = computeType (LTYPE (tree),
2825                                   RTYPE (tree),
2826                                   resultType,
2827                                   tree->opval.op);
2828       TETYPE (tree) = getSpec (TTYPE (tree));
2829
2830       return tree;
2831
2832       /*------------------------------------------------------------------*/
2833       /*----------------------------*/
2834       /*  division                  */
2835       /*----------------------------*/
2836     case '/':
2837       if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2838         {
2839           werror (E_INVALID_OP, "divide");
2840           goto errorTreeReturn;
2841         }
2842       /* if they are both literal then */
2843       /* rewrite the tree */
2844       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2845         {
2846           tree->type = EX_VALUE;
2847           tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2848                                     valFromType (RETYPE (tree)));
2849           tree->right = tree->left = NULL;
2850           TETYPE (tree) = getSpec (TTYPE (tree) =
2851                                    tree->opval.val->type);
2852           return tree;
2853         }
2854
2855       LRVAL (tree) = RRVAL (tree) = 1;
2856
2857       TETYPE (tree) = getSpec (TTYPE (tree) =
2858                                computeType (LTYPE (tree),
2859                                             RTYPE (tree),
2860                                             resultType,
2861                                             tree->opval.op));
2862
2863       /* if right is a literal and */
2864       /* left is also a division by a literal then */
2865       /* rearrange the tree */
2866       if (IS_LITERAL (RTYPE (tree))
2867           /* avoid infinite loop */
2868           && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2869         {
2870           ast *parent;
2871           ast *litTree = searchLitOp (tree, &parent, "/");
2872           if (litTree)
2873             {
2874               if (IS_LITERAL (RTYPE (litTree)))
2875                 {
2876                   /* foo_div */
2877                   DEBUG_CF("div r")
2878                   litTree->right = newNode ('*',
2879                                             litTree->right,
2880                                             copyAst (tree->right));
2881                   litTree->right->lineno = tree->lineno;
2882
2883                   tree->right->opval.val = constVal ("1");
2884                   decorateType (parent, resultType);
2885                 }
2886               else
2887                 {
2888                   /* litTree->left is literal: no gcse possible.
2889                      We can't call decorateType(parent, RESULT_TYPE_NONE), because
2890                      this would cause an infinit loop. */
2891                   parent->decorated = 1;
2892                   decorateType (litTree, resultType);
2893                 }
2894             }
2895         }
2896
2897       return tree;
2898
2899       /*------------------------------------------------------------------*/
2900       /*----------------------------*/
2901       /*            modulus         */
2902       /*----------------------------*/
2903     case '%':
2904       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2905         {
2906           werror (E_BITWISE_OP);
2907           werror (W_CONTINUE, "left & right types are ");
2908           printTypeChain (LTYPE (tree), stderr);
2909           fprintf (stderr, ",");
2910           printTypeChain (RTYPE (tree), stderr);
2911           fprintf (stderr, "\n");
2912           goto errorTreeReturn;
2913         }
2914       /* if they are both literal then */
2915       /* rewrite the tree */
2916       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2917         {
2918           tree->type = EX_VALUE;
2919           tree->opval.val = valMod (valFromType (LETYPE (tree)),
2920                                     valFromType (RETYPE (tree)));
2921           tree->right = tree->left = NULL;
2922           TETYPE (tree) = getSpec (TTYPE (tree) =
2923                                    tree->opval.val->type);
2924           return tree;
2925         }
2926       LRVAL (tree) = RRVAL (tree) = 1;
2927       TETYPE (tree) = getSpec (TTYPE (tree) =
2928                                computeType (LTYPE (tree),
2929                                             RTYPE (tree),
2930                                             resultType,
2931                                             tree->opval.op));
2932       return tree;
2933
2934       /*------------------------------------------------------------------*/
2935       /*----------------------------*/
2936       /*  address dereference       */
2937       /*----------------------------*/
2938     case '*':                   /* can be unary  : if right is null then unary operation */
2939       if (!tree->right)
2940         {
2941           if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2942             {
2943               werror (E_PTR_REQD);
2944               goto errorTreeReturn;
2945             }
2946
2947           if (LRVAL (tree))
2948             {
2949               werror (E_LVALUE_REQUIRED, "pointer deref");
2950               goto errorTreeReturn;
2951             }
2952           if (IS_ADDRESS_OF_OP(tree->left))
2953             {
2954               /* replace *&obj with obj */
2955               return tree->left->left;
2956             }
2957           TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2958           TETYPE (tree) = getSpec (TTYPE (tree));
2959           /* adjust the storage class */
2960           switch (DCL_TYPE(tree->left->ftype)) {
2961             case POINTER:
2962               SPEC_SCLS(TETYPE(tree)) = S_DATA;
2963               break;
2964             case FPOINTER:
2965               SPEC_SCLS(TETYPE(tree)) = S_XDATA; 
2966               break;
2967             case CPOINTER:
2968               SPEC_SCLS(TETYPE(tree)) = S_CODE; 
2969               break;
2970             case GPOINTER:
2971               SPEC_SCLS (TETYPE (tree)) = 0;
2972               break;
2973             case PPOINTER:
2974               SPEC_SCLS(TETYPE(tree)) = S_XSTACK; 
2975               break;
2976             case IPOINTER:
2977               SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2978               break;
2979             case EEPPOINTER:
2980               SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2981               break;
2982             case UPOINTER:
2983               SPEC_SCLS (TETYPE (tree)) = 0;
2984               break;
2985             case ARRAY:
2986             case FUNCTION:
2987               break;
2988           }
2989           return tree;
2990         }
2991
2992       /*------------------------------------------------------------------*/
2993       /*----------------------------*/
2994       /*      multiplication        */
2995       /*----------------------------*/
2996       if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2997         {
2998           werror (E_INVALID_OP, "multiplication");
2999           goto errorTreeReturn;
3000         }
3001
3002       /* if they are both literal then */
3003       /* rewrite the tree */
3004       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3005         {
3006           tree->type = EX_VALUE;
3007           tree->opval.val = valMult (valFromType (LETYPE (tree)),
3008                                      valFromType (RETYPE (tree)));
3009           tree->right = tree->left = NULL;
3010           TETYPE (tree) = getSpec (TTYPE (tree) =
3011                                    tree->opval.val->type);
3012           return tree;
3013         }
3014
3015       /* if left is a literal exchange left & right */
3016       if (IS_LITERAL (LTYPE (tree)))
3017         {
3018           ast *tTree = tree->left;
3019           tree->left = tree->right;
3020           tree->right = tTree;
3021         }
3022
3023       /* if right is a literal and */
3024       /* we can find a 2nd literal in a mul-tree then */
3025       /* rearrange the tree */
3026       if (IS_LITERAL (RTYPE (tree)))
3027         {
3028           ast *parent;
3029           ast *litTree = searchLitOp (tree, &parent, "*");
3030           if (litTree)
3031             {
3032               DEBUG_CF("mul")
3033               ast *tTree = litTree->left;
3034               litTree->left = tree->right;
3035               tree->right = tTree;
3036               /* both operands in litTree are literal now */
3037               decorateType (parent, resultType);
3038             }
3039         }
3040
3041       LRVAL (tree) = RRVAL (tree) = 1;
3042       tree->left  = addCast (tree->left,  resultType, FALSE);
3043       tree->right = addCast (tree->right, resultType, FALSE);
3044       TETYPE (tree) = getSpec (TTYPE (tree) =
3045                                    computeType (LTYPE (tree),
3046                                                 RTYPE (tree),
3047                                                 resultType,
3048                                                 tree->opval.op));
3049
3050       return tree;
3051
3052       /*------------------------------------------------------------------*/
3053       /*----------------------------*/
3054       /*    unary '+' operator      */
3055       /*----------------------------*/
3056     case '+':
3057       /* if unary plus */
3058       if (!tree->right)
3059         {
3060           if (!IS_ARITHMETIC (LTYPE (tree)))
3061             {
3062               werror (E_UNARY_OP, '+');
3063               goto errorTreeReturn;
3064             }
3065
3066           /* if left is a literal then do it */
3067           if (IS_LITERAL (LTYPE (tree)))
3068             {
3069               tree->type = EX_VALUE;
3070               tree->opval.val = valFromType (LETYPE (tree));
3071               tree->left = NULL;
3072               TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3073               return tree;
3074             }
3075           LRVAL (tree) = 1;
3076           COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3077           return tree;
3078         }
3079
3080       /*------------------------------------------------------------------*/
3081       /*----------------------------*/
3082       /*      addition              */
3083       /*----------------------------*/
3084
3085       /* this is not a unary operation */
3086       /* if both pointers then problem */
3087       if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3088           (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3089         {
3090           werror (E_PTR_PLUS_PTR);
3091           goto errorTreeReturn;
3092         }
3093
3094       if (!IS_ARITHMETIC (LTYPE (tree)) &&
3095           !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3096         {
3097           werror (E_PLUS_INVALID, "+");
3098           goto errorTreeReturn;
3099         }
3100
3101       if (!IS_ARITHMETIC (RTYPE (tree)) &&
3102           !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3103         {
3104           werror (E_PLUS_INVALID, "+");
3105           goto errorTreeReturn;
3106         }
3107       /* if they are both literal then */
3108       /* rewrite the tree */
3109       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3110         {
3111           tree->type = EX_VALUE;
3112           tree->left  = addCast (tree->left,  resultType, TRUE);
3113           tree->right = addCast (tree->right, resultType, TRUE);
3114           tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3115                                      valFromType (RETYPE (tree)));
3116           tree->right = tree->left = NULL;
3117           TETYPE (tree) = getSpec (TTYPE (tree) =
3118                                    tree->opval.val->type);
3119           return tree;
3120         }
3121
3122       /* if the right is a pointer or left is a literal
3123          xchange left & right */
3124       if (IS_ARRAY (RTYPE (tree)) ||
3125           IS_PTR (RTYPE (tree)) ||
3126           IS_LITERAL (LTYPE (tree)))
3127         {
3128           ast *tTree = tree->left;
3129           tree->left = tree->right;
3130           tree->right = tTree;
3131         }
3132
3133       /* if right is a literal and */
3134       /* left is also an addition/subtraction with a literal then */
3135       /* rearrange the tree */
3136       if (IS_LITERAL (RTYPE (tree)))
3137         {
3138           ast *litTree, *parent;
3139           litTree = searchLitOp (tree, &parent, "+-");
3140           if (litTree)
3141             {
3142               if (litTree->opval.op == '+')
3143                 {
3144                   /* foo_aa */
3145                   DEBUG_CF("+ 1 AA")
3146                   ast *tTree = litTree->left;
3147                   litTree->left = tree->right;
3148                   tree->right = tree->left;
3149                   tree->left = tTree;
3150                 }
3151               else if (litTree->opval.op == '-')
3152                 {
3153                   if (IS_LITERAL (RTYPE (litTree)))
3154                     {
3155                       DEBUG_CF("+ 2 ASR")
3156                       /* foo_asr */
3157                       ast *tTree = litTree->left;
3158                       litTree->left = tree->right;
3159                       tree->right = tTree;
3160                     }
3161                   else
3162                     {
3163                       DEBUG_CF("+ 3 ASL")
3164                       /* foo_asl */
3165                       ast *tTree = litTree->right;
3166                       litTree->right = tree->right;
3167                       tree->right = tTree;
3168                       litTree->opval.op = '+';
3169                       tree->opval.op = '-';
3170                     }
3171                 }
3172               decorateType (parent, resultType);
3173             }
3174         }
3175
3176       LRVAL (tree) = RRVAL (tree) = 1;
3177       /* if the left is a pointer */
3178       if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3179         TETYPE (tree) = getSpec (TTYPE (tree) =
3180                                  LTYPE (tree));
3181       else
3182         {
3183           tree->left  = addCast (tree->left,  resultType, TRUE);
3184           tree->right = addCast (tree->right, resultType, TRUE);
3185           TETYPE (tree) = getSpec (TTYPE (tree) =
3186                                      computeType (LTYPE (tree),
3187                                                   RTYPE (tree),
3188                                                   resultType,
3189                                                   tree->opval.op));
3190         }
3191         
3192       return tree;
3193
3194       /*------------------------------------------------------------------*/
3195       /*----------------------------*/
3196       /*      unary '-'             */
3197       /*----------------------------*/
3198     case '-':                   /* can be unary   */
3199       /* if right is null then unary */
3200       if (!tree->right)
3201         {
3202
3203           if (!IS_ARITHMETIC (LTYPE (tree)))
3204             {
3205               werror (E_UNARY_OP, tree->opval.op);
3206               goto errorTreeReturn;
3207             }
3208
3209           /* if left is a literal then do it */
3210           if (IS_LITERAL (LTYPE (tree)))
3211             {
3212               tree->type = EX_VALUE;
3213               tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3214               tree->left = NULL;
3215               TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3216               SPEC_USIGN(TETYPE(tree)) = 0;
3217               return tree;
3218             }
3219           LRVAL (tree) = 1;
3220           TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3221           return tree;
3222         }
3223
3224       /*------------------------------------------------------------------*/
3225       /*----------------------------*/
3226       /*    subtraction             */
3227       /*----------------------------*/
3228
3229       if (!(IS_PTR (LTYPE (tree)) ||
3230             IS_ARRAY (LTYPE (tree)) ||
3231             IS_ARITHMETIC (LTYPE (tree))))
3232         {
3233           werror (E_PLUS_INVALID, "-");
3234           goto errorTreeReturn;
3235         }
3236
3237       if (!(IS_PTR (RTYPE (tree)) ||
3238             IS_ARRAY (RTYPE (tree)) ||
3239             IS_ARITHMETIC (RTYPE (tree))))
3240         {
3241           werror (E_PLUS_INVALID, "-");
3242           goto errorTreeReturn;
3243         }
3244
3245       if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3246           !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3247             IS_INTEGRAL (RTYPE (tree))))
3248         {
3249           werror (E_PLUS_INVALID, "-");
3250           goto errorTreeReturn;
3251         }
3252
3253       /* if they are both literal then */
3254       /* rewrite the tree */
3255       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3256         {
3257           tree->type = EX_VALUE;
3258           tree->left  = addCast (tree->left,  resultType, TRUE);
3259           tree->right = addCast (tree->right, resultType, TRUE);
3260           tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3261                                       valFromType (RETYPE (tree)));
3262           tree->right = tree->left = NULL;
3263           TETYPE (tree) = getSpec (TTYPE (tree) =
3264                                    tree->opval.val->type);
3265           return tree;
3266         }
3267
3268       /* if the left & right are equal then zero */
3269       if (isAstEqual (tree->left, tree->right))
3270         {
3271           tree->type = EX_VALUE;
3272           tree->left = tree->right = NULL;
3273           tree->opval.val = constVal ("0");
3274           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3275           return tree;
3276         }
3277
3278       /* if both of them are pointers or arrays then */
3279       /* the result is going to be an integer        */
3280       if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3281           (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3282         TETYPE (tree) = TTYPE (tree) = newIntLink ();
3283       else
3284         /* if only the left is a pointer */
3285         /* then result is a pointer      */
3286       if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3287         TETYPE (tree) = getSpec (TTYPE (tree) =
3288                                  LTYPE (tree));
3289       else
3290         {
3291           tree->left  = addCast (tree->left,  resultType, TRUE);
3292           tree->right = addCast (tree->right, resultType, TRUE);
3293
3294           TETYPE (tree) = getSpec (TTYPE (tree) =
3295                                      computeType (LTYPE (tree),
3296                                                   RTYPE (tree),
3297                                                   resultType,
3298                                                   tree->opval.op));
3299         }
3300
3301       LRVAL (tree) = RRVAL (tree) = 1;
3302
3303       /* if right is a literal and */
3304       /* left is also an addition/subtraction with a literal then */
3305       /* rearrange the tree */
3306       if (IS_LITERAL (RTYPE (tree))
3307           /* avoid infinite loop */
3308           && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3309         {
3310           ast *litTree, *litParent;
3311           litTree = searchLitOp (tree, &litParent, "+-");
3312           if (litTree)
3313             {
3314               if (litTree->opval.op == '+')
3315                 {
3316                   /* foo_sa */
3317                   DEBUG_CF("- 1 SA")
3318                   ast *tTree = litTree->left;
3319                   litTree->left = litTree->right;
3320                   litTree->right = tree->right;
3321                   tree->right = tTree;
3322                   tree->opval.op = '+';
3323                   litTree->opval.op = '-';
3324                 }
3325               else if (litTree->opval.op == '-')
3326                 {
3327                   if (IS_LITERAL (RTYPE (litTree)))
3328                     {
3329                       /* foo_ssr */
3330                       DEBUG_CF("- 2 SSR")
3331                       ast *tTree = litTree->left;
3332                       litTree->left = tree->right;
3333                       tree->right = litParent->left;
3334                       litParent->left = tTree;
3335                       litTree->opval.op = '+';
3336                       
3337                       tree->decorated = 0;
3338                       decorateType (tree, resultType);
3339                     }
3340                   else
3341                     {
3342                       /* foo_ssl */
3343                       DEBUG_CF("- 3 SSL")
3344                       ast *tTree = litTree->right;
3345                       litTree->right = tree->right;
3346                       tree->right = tTree;
3347                     }
3348                 }
3349               decorateType (litParent, resultType);
3350             }
3351         }
3352       return tree;
3353
3354       /*------------------------------------------------------------------*/
3355       /*----------------------------*/
3356       /*    complement              */
3357       /*----------------------------*/
3358     case '~':
3359       /* can be only integral type */
3360       if (!IS_INTEGRAL (LTYPE (tree)))
3361         {
3362           werror (E_UNARY_OP, tree->opval.op);
3363           goto errorTreeReturn;
3364         }
3365
3366       /* if left is a literal then do it */
3367       if (IS_LITERAL (LTYPE (tree)))
3368         {
3369           tree->type = EX_VALUE;
3370           tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3371           tree->left = NULL;
3372           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3373           return addCast (tree, resultType, TRUE);
3374         }
3375       tree->left = addCast (tree->left, resultType, TRUE);
3376       LRVAL (tree) = 1;
3377       COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3378       return tree;
3379
3380       /*------------------------------------------------------------------*/
3381       /*----------------------------*/
3382       /*           not              */
3383       /*----------------------------*/
3384     case '!':
3385       /* can be pointer */
3386       if (!IS_ARITHMETIC (LTYPE (tree)) &&
3387           !IS_PTR (LTYPE (tree)) &&
3388           !IS_ARRAY (LTYPE (tree)))
3389         {
3390           werror (E_UNARY_OP, tree->opval.op);
3391           goto errorTreeReturn;
3392         }
3393
3394       /* if left is a literal then do it */
3395       if (IS_LITERAL (LTYPE (tree)))
3396         {
3397           tree->type = EX_VALUE;
3398           tree->opval.val = valNot (valFromType (LETYPE (tree)));
3399           tree->left = NULL;
3400           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3401           return tree;
3402         }
3403       LRVAL (tree) = 1;
3404       TTYPE (tree) = TETYPE (tree) = newCharLink ();
3405       return tree;
3406
3407       /*------------------------------------------------------------------*/
3408       /*----------------------------*/
3409       /*           shift            */
3410       /*----------------------------*/
3411     case RRC:
3412     case RLC:
3413     case SWAP:
3414       TTYPE (tree) = LTYPE (tree);
3415       TETYPE (tree) = LETYPE (tree);
3416       return tree;
3417
3418     case GETHBIT:
3419       TTYPE (tree) = TETYPE (tree) = newCharLink ();
3420       return tree;
3421
3422     case LEFT_OP:
3423     case RIGHT_OP:
3424       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3425         {
3426           werror (E_SHIFT_OP_INVALID);
3427           werror (W_CONTINUE, "left & right types are ");
3428           printTypeChain (LTYPE (tree), stderr);
3429           fprintf (stderr, ",");
3430           printTypeChain (RTYPE (tree), stderr);
3431           fprintf (stderr, "\n");
3432           goto errorTreeReturn;
3433         }
3434
3435       /* make smaller type only if it's a LEFT_OP */
3436       if (tree->opval.op == LEFT_OP)
3437         tree->left = addCast (tree->left, resultType, TRUE);
3438       
3439       /* if they are both literal then */
3440       /* rewrite the tree */
3441       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3442         {
3443           tree->type = EX_VALUE;
3444           tree->opval.val = valShift (valFromType (LETYPE (tree)),
3445                                       valFromType (RETYPE (tree)),
3446                                       (tree->opval.op == LEFT_OP ? 1 : 0));
3447           tree->right = tree->left = NULL;
3448           TETYPE (tree) = getSpec (TTYPE (tree) =
3449                                    tree->opval.val->type);
3450           return tree;
3451         }
3452
3453       LRVAL (tree) = RRVAL (tree) = 1;
3454       if (tree->opval.op == LEFT_OP)
3455         {
3456           TETYPE (tree) = getSpec (TTYPE (tree) =
3457                                        computeType (LTYPE (tree),
3458                                                     NULL,
3459                                                     resultType,
3460                                                     tree->opval.op));
3461         }
3462       else /* RIGHT_OP */
3463         {
3464           /* no promotion necessary */
3465           TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3466           if (IS_LITERAL (TTYPE (tree)))
3467             SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3468         }
3469
3470       /* if only the right side is a literal & we are
3471          shifting more than size of the left operand then zero */
3472       if (IS_LITERAL (RTYPE (tree)) &&
3473           ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3474           (getSize (TETYPE (tree)) * 8))
3475         {
3476           if (tree->opval.op==LEFT_OP ||
3477               (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3478             {
3479               lineno=tree->lineno;
3480               werror (W_SHIFT_CHANGED,
3481                       (tree->opval.op == LEFT_OP ? "left" : "right"));
3482               tree->type = EX_VALUE;
3483               tree->left = tree->right = NULL;
3484               tree->opval.val = constVal ("0");
3485               TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3486               return tree;
3487             }
3488         }
3489
3490       return tree;
3491
3492       /*------------------------------------------------------------------*/
3493       /*----------------------------*/
3494       /*         casting            */
3495       /*----------------------------*/
3496     case CAST:                  /* change the type   */
3497       /* cannot cast to an aggregate type */
3498       if (IS_AGGREGATE (LTYPE (tree)))
3499         {
3500           werror (E_CAST_ILLEGAL);
3501           goto errorTreeReturn;
3502         }
3503
3504       /* make sure the type is complete and sane */
3505       changePointer(LTYPE(tree));
3506       checkTypeSanity(LETYPE(tree), "(cast)");
3507
3508       /* If code memory is read only, then pointers to code memory */
3509       /* implicitly point to constants -- make this explicit       */
3510       {
3511         sym_link *t = LTYPE(tree);
3512         while (t && t->next)
3513           {
3514             if (IS_CODEPTR(t) && port->mem.code_ro)
3515               {
3516                 if (IS_SPEC(t->next))
3517                   SPEC_CONST (t->next) = 1;
3518                 else
3519                   DCL_PTR_CONST (t->next) = 1;
3520               }
3521             t = t->next;
3522           }
3523       }
3524
3525 #if 0
3526       /* if the right is a literal replace the tree */
3527       if (IS_LITERAL (RETYPE (tree))) {
3528               if (!IS_PTR (LTYPE (tree))) {
3529                       tree->type = EX_VALUE;
3530                       tree->opval.val =
3531                               valCastLiteral (LTYPE (tree),
3532                                               floatFromVal (valFromType (RETYPE (tree))));
3533                       tree->left = NULL;
3534                       tree->right = NULL;
3535                       TTYPE (tree) = tree->opval.val->type;
3536                       tree->values.literalFromCast = 1;
3537               } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3538                          ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */  {
3539                       sym_link *rest = LTYPE(tree)->next;
3540                       werror(W_LITERAL_GENERIC);
3541                       TTYPE(tree) = newLink(DECLARATOR);
3542                       DCL_TYPE(TTYPE(tree)) = FPOINTER;
3543                       TTYPE(tree)->next = rest;
3544                       tree->left->opval.lnk = TTYPE(tree);
3545                       LRVAL (tree) = 1;
3546               } else {
3547                       TTYPE (tree) = LTYPE (tree);
3548                       LRVAL (tree) = 1;
3549               }
3550       } else {
3551               TTYPE (tree) = LTYPE (tree);
3552               LRVAL (tree) = 1;
3553       }
3554 #else
3555 #if 0 // this is already checked, now this could be explicit
3556       /* if pointer to struct then check names */
3557       if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3558           IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3559           strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3560         {
3561           werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3562                  SPEC_STRUCT(LETYPE(tree))->tag);
3563         }
3564 #endif
3565       if (IS_ADDRESS_OF_OP(tree->right)
3566           && IS_AST_SYM_VALUE (tree->right->left)
3567           && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3568         
3569         symbol * sym = AST_SYMBOL (tree->right->left);
3570         unsigned int gptype = 0;
3571         unsigned int addr = SPEC_ADDR (sym->etype);
3572
3573         if (IS_GENPTR (LTYPE (tree)) && GPTRSIZE > FPTRSIZE)
3574           {
3575             switch (SPEC_SCLS (sym->etype))
3576               {
3577               case S_CODE:
3578                 gptype = GPTYPE_CODE;
3579                 break;
3580               case S_XDATA:
3581                 gptype = GPTYPE_FAR;
3582                 break;
3583               case S_DATA:
3584                 gptype = GPTYPE_NEAR;
3585                 break;
3586               case S_IDATA:
3587                 gptype = GPTYPE_IDATA;
3588                 break;
3589               case S_PDATA:
3590                 gptype = GPTYPE_XSTACK;
3591                 break;
3592               default:
3593                 gptype = 0;
3594               }
3595             addr |= gptype << (8*(GPTRSIZE - 1));
3596           }
3597         
3598         tree->type = EX_VALUE;
3599         tree->opval.val =
3600           valCastLiteral (LTYPE (tree), addr);
3601         TTYPE (tree) = tree->opval.val->type;
3602         TETYPE (tree) = getSpec (TTYPE (tree));
3603         tree->left = NULL;
3604         tree->right = NULL;
3605         tree->values.literalFromCast = 1;
3606         return tree;
3607       }
3608
3609       /* handle offsetof macro:            */
3610       /* #define offsetof(TYPE, MEMBER) \  */
3611       /* ((unsigned) &((TYPE *)0)->MEMBER) */
3612       if (IS_ADDRESS_OF_OP(tree->right)
3613           && IS_AST_OP (tree->right->left)
3614           && tree->right->left->opval.op == PTR_OP
3615           && IS_AST_OP (tree->right->left->left)
3616           && tree->right->left->left->opval.op == CAST
3617           && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3618
3619         symbol *element = getStructElement (
3620           SPEC_STRUCT (LETYPE(tree->right->left)),
3621           AST_SYMBOL(tree->right->left->right)
3622         );
3623
3624         if (element) {
3625           tree->type = EX_VALUE;
3626           tree->opval.val = valCastLiteral (
3627             LTYPE (tree),
3628             element->offset
3629             + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3630           );
3631
3632           TTYPE (tree) = tree->opval.val->type;
3633           TETYPE (tree) = getSpec (TTYPE (tree));
3634           tree->left = NULL;
3635           tree->right = NULL;
3636           return tree;
3637         }
3638       }
3639
3640       /* if the right is a literal replace the tree */
3641       if (IS_LITERAL (RETYPE (tree))) {
3642         #if 0
3643         if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3644           /* rewrite      (type *)litaddr
3645              as           &temp
3646              and define   type at litaddr temp
3647              (but only if type's storage class is not generic)
3648           */
3649           ast *newTree = newNode ('&', NULL, NULL);
3650           symbol *sym;
3651
3652           TTYPE (newTree) = LTYPE (tree);
3653           TETYPE (newTree) = getSpec(LTYPE (tree));
3654
3655           /* define a global symbol at the casted address*/
3656           sym = newSymbol(genSymName (0), 0);
3657           sym->type = LTYPE (tree)->next;
3658           if (!sym->type)
3659             sym->type = newLink (V_VOID);
3660           sym->etype = getSpec(sym->type);
3661           SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3662           sym->lineDef = tree->lineno;
3663           sym->cdef = 1;
3664           sym->isref = 1;
3665           SPEC_STAT (sym->etype) = 1;
3666           SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3667           SPEC_ABSA(sym->etype) = 1;
3668           addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3669           allocGlobal (sym);
3670
3671           newTree->left = newAst_VALUE(symbolVal(sym));
3672           newTree->left->lineno = tree->lineno;
3673           LTYPE (newTree) = sym->type;
3674           LETYPE (newTree) = sym->etype;
3675           LLVAL (newTree) = 1;
3676           LRVAL (newTree) = 0;
3677           TLVAL (newTree) = 1;
3678           return newTree;
3679         }
3680         #endif
3681         if (!IS_PTR (LTYPE (tree))) {
3682           tree->type = EX_VALUE;
3683           tree->opval.val =
3684           valCastLiteral (LTYPE (tree),
3685                           floatFromVal (valFromType (RTYPE (tree))));
3686           TTYPE (tree) = tree->opval.val->type;
3687           tree->left = NULL;
3688           tree->right = NULL;
3689           tree->values.literalFromCast = 1;
3690           TETYPE (tree) = getSpec (TTYPE (tree));
3691           return tree;
3692         }
3693       }
3694       TTYPE (tree) = LTYPE (tree);
3695       LRVAL (tree) = 1;
3696
3697 #endif
3698       TETYPE (tree) = getSpec (TTYPE (tree));
3699
3700       return tree;
3701
3702       /*------------------------------------------------------------------*/
3703       /*----------------------------*/
3704       /*       logical &&, ||       */
3705       /*----------------------------*/
3706     case AND_OP:
3707     case OR_OP:
3708       /* each must be arithmetic type or be a pointer */
3709       if (!IS_PTR (LTYPE (tree)) &&
3710           !IS_ARRAY (LTYPE (tree)) &&
3711           !IS_INTEGRAL (LTYPE (tree)))
3712         {
3713           werror (E_COMPARE_OP);
3714           goto errorTreeReturn;
3715         }
3716
3717       if (!IS_PTR (RTYPE (tree)) &&
3718           !IS_ARRAY (RTYPE (tree)) &&
3719           !IS_INTEGRAL (RTYPE (tree)))
3720         {
3721           werror (E_COMPARE_OP);
3722           goto errorTreeReturn;
3723         }
3724       /* if they are both literal then */
3725       /* rewrite the tree */
3726       if (IS_LITERAL (RTYPE (tree)) &&
3727           IS_LITERAL (LTYPE (tree)))
3728         {
3729           tree->type = EX_VALUE;
3730           tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3731                                            valFromType (RTYPE (tree)),
3732                                            tree->opval.op);
3733           tree->right = tree->left = NULL;
3734           TETYPE (tree) = getSpec (TTYPE (tree) =
3735                                    tree->opval.val->type);
3736           return tree;
3737         }
3738       LRVAL (tree) = RRVAL (tree) = 1;
3739       TTYPE (tree) = TETYPE (tree) = newCharLink ();
3740       return tree;
3741
3742       /*------------------------------------------------------------------*/
3743       /*----------------------------*/
3744       /*     comparison operators   */
3745       /*----------------------------*/
3746     case '>':
3747     case '<':
3748     case LE_OP:
3749     case GE_OP:
3750     case EQ_OP:
3751     case NE_OP:
3752       {
3753         ast *lt = optimizeCompare (tree);
3754
3755         if (tree != lt)
3756           return lt;
3757       }
3758
3759       /* if they are pointers they must be castable */
3760       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3761         {
3762           if (tree->opval.op==EQ_OP &&
3763               !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3764             // we cannot cast a gptr to a !gptr: switch the leaves
3765             struct ast *s=tree->left;
3766             tree->left=tree->right;
3767             tree->right=s;
3768           }
3769           if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3770             {
3771               werror (E_COMPARE_OP);
3772               fprintf (stderr, "comparing type ");
3773               printTypeChain (LTYPE (tree), stderr);
3774               fprintf (stderr, "to type ");
3775               printTypeChain (RTYPE (tree), stderr);
3776               fprintf (stderr, "\n");
3777               goto errorTreeReturn;
3778             }
3779         }
3780       /* else they should be promotable to one another */
3781       else
3782         {
3783           if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3784                 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3785
3786             if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3787               {
3788                 werror (E_COMPARE_OP);
3789                 fprintf (stderr, "comparing type ");
3790                 printTypeChain (LTYPE (tree), stderr);
3791                 fprintf (stderr, "to type ");
3792                 printTypeChain (RTYPE (tree), stderr);
3793                 fprintf (stderr, "\n");
3794                 goto errorTreeReturn;
3795               }
3796         }
3797       /* if unsigned value < 0  then always false */
3798       /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3799       if (SPEC_USIGN(LETYPE(tree)) &&
3800           !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3801           IS_LITERAL(RTYPE(tree))  &&
3802           ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3803         {
3804           if (tree->opval.op == '<')
3805             {
3806               return tree->right;
3807             }
3808           if (tree->opval.op == '>')
3809             {
3810               if (resultType == RESULT_TYPE_IFX)
3811                 {
3812                   /* the parent is an ifx: */
3813                   /* if (unsigned value) */
3814                   return tree->left;
3815                 }
3816               
3817               /* (unsigned value) ? 1 : 0 */
3818               tree->opval.op = '?';
3819               tree->right = newNode (':',
3820                                      newAst_VALUE (constVal ("1")),
3821                                      tree->right); /* val 0 */
3822               tree->right->lineno = tree->lineno;
3823               tree->right->left->lineno = tree->lineno;
3824               decorateType (tree->right, RESULT_TYPE_NONE);
3825             }
3826         }
3827       /* if they are both literal then */
3828       /* rewrite the tree */
3829       if (IS_LITERAL (RTYPE (tree)) &&
3830           IS_LITERAL (LTYPE (tree)))
3831         {
3832           tree->type = EX_VALUE;
3833           tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3834                                         valFromType (RETYPE (tree)),
3835                                         tree->opval.op);
3836           tree->right = tree->left = NULL;
3837           TETYPE (tree) = getSpec (TTYPE (tree) =
3838                                    tree->opval.val->type);
3839           return tree;
3840         }
3841       LRVAL (tree) = RRVAL (tree) = 1;
3842       TTYPE (tree) = TETYPE (tree) = newCharLink ();
3843       return tree;
3844
3845       /*------------------------------------------------------------------*/
3846       /*----------------------------*/
3847       /*             sizeof         */
3848       /*----------------------------*/
3849     case SIZEOF:                /* evaluate wihout code generation */
3850       /* change the type to a integer */
3851       {
3852         int size = getSize (tree->right->ftype);
3853         SNPRINTF(buffer, sizeof(buffer), "%d", size);
3854         if (!size && !IS_VOID(tree->right->ftype))
3855           werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
3856       }
3857       tree->type = EX_VALUE;
3858       tree->opval.val = constVal (buffer);
3859       tree->right = tree->left = NULL;
3860       TETYPE (tree) = getSpec (TTYPE (tree) =
3861                                tree->opval.val->type);
3862       return tree;
3863
3864       /*------------------------------------------------------------------*/
3865       /*----------------------------*/
3866       /*             typeof         */
3867       /*----------------------------*/
3868     case TYPEOF:
3869         /* return typeof enum value */
3870         tree->type = EX_VALUE;
3871         {
3872             int typeofv = 0;
3873             if (IS_SPEC(tree->right->ftype)) {
3874                 switch (SPEC_NOUN(tree->right->ftype)) {
3875                 case V_INT:
3876                     if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3877                     else typeofv = TYPEOF_INT;
3878                     break;
3879                 case V_FLOAT:
3880                     typeofv = TYPEOF_FLOAT;
3881                     break;
3882                 case V_CHAR:
3883                     typeofv = TYPEOF_CHAR;
3884                     break;
3885                 case V_VOID:
3886                     typeofv = TYPEOF_VOID;
3887                     break;
3888                 case V_STRUCT:
3889                     typeofv = TYPEOF_STRUCT;
3890                     break;
3891                 case V_BITFIELD:
3892                     typeofv = TYPEOF_BITFIELD;
3893                     break;
3894                 case V_BIT:
3895                     typeofv = TYPEOF_BIT;
3896                     break;
3897                 case V_SBIT:
3898                     typeofv = TYPEOF_SBIT;
3899                     break;
3900                 default:
3901                     break;
3902                 }
3903             } else {
3904                 switch (DCL_TYPE(tree->right->ftype)) {
3905                 case POINTER:
3906                     typeofv = TYPEOF_POINTER;
3907                     break;
3908                 case FPOINTER:
3909                     typeofv = TYPEOF_FPOINTER;
3910                     break;
3911                 case CPOINTER:
3912                     typeofv = TYPEOF_CPOINTER;
3913                     break;
3914                 case GPOINTER:
3915                     typeofv = TYPEOF_GPOINTER;
3916                     break;
3917                 case PPOINTER:
3918                     typeofv = TYPEOF_PPOINTER;
3919                     break;
3920                 case IPOINTER:
3921                     typeofv = TYPEOF_IPOINTER;
3922                     break;
3923                 case ARRAY:
3924                     typeofv = TYPEOF_ARRAY;
3925                     break;
3926                 case FUNCTION:
3927                     typeofv = TYPEOF_FUNCTION;
3928                     break;
3929                 default:
3930                     break;
3931                 }
3932             }
3933             SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3934             tree->opval.val = constVal (buffer);
3935             tree->right = tree->left = NULL;
3936             TETYPE (tree) = getSpec (TTYPE (tree) =
3937                                      tree->opval.val->type);
3938         }
3939         return tree;
3940       /*------------------------------------------------------------------*/
3941       /*----------------------------*/
3942       /* conditional operator  '?'  */
3943       /*----------------------------*/
3944     case '?':
3945       /* the type is value of the colon operator (on the right) */
3946       assert (IS_COLON_OP (tree->right));
3947       /* if already known then replace the tree : optimizer will do it
3948          but faster to do it here */
3949       if (IS_LITERAL (LTYPE (tree)))
3950         {
3951           if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
3952             return decorateType (tree->right->left, resultTypeProp);
3953           else
3954             return decorateType (tree->right->right, resultTypeProp);
3955         }
3956       else
3957         {
3958           tree->right = decorateType (tree->right, resultTypeProp);
3959           TTYPE (tree) = RTYPE (tree);
3960           TETYPE (tree) = getSpec (TTYPE (tree));
3961         }
3962       return tree;
3963
3964     case ':':
3965       /* if they don't match we have a problem */
3966       if ((compareType (LTYPE (tree), RTYPE (tree)) == 0) &&
3967           (compareType (RTYPE (tree), LTYPE (tree)) == 0))
3968         {
3969           werror (E_TYPE_MISMATCH, "conditional operator", " ");
3970           goto errorTreeReturn;
3971         }
3972
3973       TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
3974                                   resultType, tree->opval.op);
3975       TETYPE (tree) = getSpec (TTYPE (tree));
3976       return tree;
3977
3978
3979 #if 0 // assignment operators are converted by the parser
3980       /*------------------------------------------------------------------*/
3981       /*----------------------------*/
3982       /*    assignment operators    */
3983       /*----------------------------*/
3984     case MUL_ASSIGN:
3985     case DIV_ASSIGN:
3986       /* for these it must be both must be integral */
3987       if (!IS_ARITHMETIC (LTYPE (tree)) ||
3988           !IS_ARITHMETIC (RTYPE (tree)))
3989         {
3990           werror (E_OPS_INTEGRAL);
3991           goto errorTreeReturn;
3992         }
3993       RRVAL (tree) = 1;
3994       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3995
3996       if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3997         werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3998
3999       if (LRVAL (tree))
4000         {
4001           werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4002           goto errorTreeReturn;
4003         }
4004       LLVAL (tree) = 1;
4005
4006       return tree;
4007
4008     case AND_ASSIGN:
4009     case OR_ASSIGN:
4010     case XOR_ASSIGN:
4011     case RIGHT_ASSIGN:
4012     case LEFT_ASSIGN:
4013       /* for these it must be both must be integral */
4014       if (!IS_INTEGRAL (LTYPE (tree)) ||
4015           !IS_INTEGRAL (RTYPE (tree)))
4016         {
4017           werror (E_OPS_INTEGRAL);
4018           goto errorTreeReturn;
4019         }
4020       RRVAL (tree) = 1;
4021       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4022
4023       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4024         werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
4025
4026       if (LRVAL (tree))
4027         {
4028           werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
4029           goto errorTreeReturn;
4030         }
4031       LLVAL (tree) = 1;
4032
4033       return tree;
4034
4035       /*------------------------------------------------------------------*/
4036       /*----------------------------*/
4037       /*    -= operator             */
4038       /*----------------------------*/
4039     case SUB_ASSIGN:
4040       if (!(IS_PTR (LTYPE (tree)) ||
4041             IS_ARITHMETIC (LTYPE (tree))))
4042         {
4043           werror (E_PLUS_INVALID, "-=");
4044           goto errorTreeReturn;
4045         }
4046
4047       if (!(IS_PTR (RTYPE (tree)) ||
4048             IS_ARITHMETIC (RTYPE (tree))))
4049         {
4050           werror (E_PLUS_INVALID, "-=");
4051           goto errorTreeReturn;
4052         }
4053       RRVAL (tree) = 1;
4054       TETYPE (tree) = getSpec (TTYPE (tree) =
4055                                computeType (LTYPE (tree),
4056                                             RTYPE (tree),
4057                                             RESULT_TYPE_NOPROM,
4058                                             tree->opval.op));
4059
4060       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4061         werror (E_CODE_WRITE, "-=");
4062
4063       if (LRVAL (tree))
4064         {
4065           werror (E_LVALUE_REQUIRED, "-=");
4066           goto errorTreeReturn;
4067         }
4068       LLVAL (tree) = 1;
4069
4070       return tree;
4071
4072       /*------------------------------------------------------------------*/
4073       /*----------------------------*/
4074       /*          += operator       */
4075       /*----------------------------*/
4076     case ADD_ASSIGN:
4077       /* this is not a unary operation */
4078       /* if both pointers then problem */
4079       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4080         {
4081           werror (E_PTR_PLUS_PTR);
4082           goto errorTreeReturn;
4083         }
4084
4085       if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4086         {
4087           werror (E_PLUS_INVALID, "+=");
4088           goto errorTreeReturn;
4089         }
4090
4091       if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4092         {
4093           werror (E_PLUS_INVALID, "+=");
4094           goto errorTreeReturn;
4095         }
4096       RRVAL (tree) = 1;
4097       TETYPE (tree) = getSpec (TTYPE (tree) =
4098                                computeType (LTYPE (tree),
4099                                             RTYPE (tree),
4100                                             RESULT_TYPE_NOPROM,
4101                                             tree->opval.op));
4102
4103       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4104         werror (E_CODE_WRITE, "+=");
4105
4106       if (LRVAL (tree))
4107         {
4108           werror (E_LVALUE_REQUIRED, "+=");
4109           goto errorTreeReturn;
4110         }
4111
4112       tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE);
4113       tree->opval.op = '=';
4114
4115       return tree;
4116 #endif
4117
4118       /*------------------------------------------------------------------*/
4119       /*----------------------------*/
4120       /*      straight assignemnt   */
4121       /*----------------------------*/
4122     case '=':
4123       /* cannot be an aggregate */
4124       if (IS_AGGREGATE (LTYPE (tree)))
4125         {
4126           werror (E_AGGR_ASSIGN);
4127           goto errorTreeReturn;
4128         }
4129
4130       /* they should either match or be castable */
4131       if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4132         {
4133           werror (E_TYPE_MISMATCH, "assignment", " ");
4134           printFromToType(RTYPE(tree),LTYPE(tree));
4135         }
4136
4137       /* if the left side of the tree is of type void
4138          then report error */
4139       if (IS_VOID (LTYPE (tree)))
4140         {
4141           werror (E_CAST_ZERO);
4142           printFromToType(RTYPE(tree), LTYPE(tree));
4143         }
4144
4145       TETYPE (tree) = getSpec (TTYPE (tree) =
4146                                LTYPE (tree));
4147       RRVAL (tree) = 1;
4148       LLVAL (tree) = 1;
4149       if (!tree->initMode ) {
4150         if (IS_CONSTANT(LTYPE(tree)))
4151           werror (E_CODE_WRITE, "=");
4152       }
4153       if (LRVAL (tree))
4154         {
4155           werror (E_LVALUE_REQUIRED, "=");
4156           goto errorTreeReturn;
4157         }
4158
4159       return tree;
4160
4161       /*------------------------------------------------------------------*/
4162       /*----------------------------*/
4163       /*      comma operator        */
4164       /*----------------------------*/
4165     case ',':
4166       TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4167       return tree;
4168
4169       /*------------------------------------------------------------------*/
4170       /*----------------------------*/
4171       /*       function call        */
4172       /*----------------------------*/
4173     case CALL:
4174       
4175       /* undo any explicit pointer derefernce; PCALL will handle it instead */
4176       if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4177         {
4178           if (tree->left->opval.op == '*' && !tree->left->right)
4179             tree->left = tree->left->left;
4180         }
4181
4182       /* require a function or pointer to function */
4183       if (!IS_FUNC (LTYPE (tree))
4184           && !(IS_CODEPTR (LTYPE (tree)) && IS_FUNC (LTYPE (tree)->next)))
4185         {
4186           werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4187           goto errorTreeReturn;
4188         }
4189
4190       /* if there are parms, make sure that
4191          parms are decorate / process / reverse only once */
4192       if (!tree->right ||
4193           !tree->right->decorated)
4194         {
4195           sym_link *functype;      
4196           parmNumber = 1;
4197
4198           if (IS_CODEPTR(LTYPE(tree)))
4199             functype = LTYPE (tree)->next;
4200           else
4201             functype = LTYPE (tree);
4202
4203           if (processParms (tree->left, FUNC_ARGS(functype),
4204                             &tree->right, &parmNumber, TRUE))
4205             {
4206               goto errorTreeReturn;
4207             }
4208         
4209           if ((options.stackAuto || IFFUNC_ISREENT (functype)) && 
4210              !IFFUNC_ISBUILTIN(functype))
4211             {
4212               reverseParms (tree->right);
4213             }
4214
4215            TTYPE (tree) = functype->next;
4216            TETYPE (tree) = getSpec (TTYPE (tree));
4217         }
4218       return tree;
4219
4220       /*------------------------------------------------------------------*/
4221       /*----------------------------*/
4222       /*     return statement       */
4223       /*----------------------------*/
4224     case RETURN:
4225       if (!tree->right)
4226         goto voidcheck;
4227
4228       if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4229         {
4230           werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4231           printFromToType (RTYPE(tree), currFunc->type->next);
4232           goto errorTreeReturn;
4233         }
4234
4235       if (IS_VOID (currFunc->type->next)
4236           && tree->right &&
4237           !IS_VOID (RTYPE (tree)))
4238         {
4239           werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4240           goto errorTreeReturn;
4241         }
4242
4243       /* if there is going to be a casting required then add it */
4244       if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4245         {
4246           tree->right =
4247             decorateType (newNode (CAST,
4248                           newAst_LINK (copyLinkChain (currFunc->type->next)),
4249                                         tree->right),
4250                           RESULT_TYPE_NONE);
4251         }
4252
4253       RRVAL (tree) = 1;
4254       return tree;
4255
4256     voidcheck:
4257
4258       if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4259         {
4260           werror (W_VOID_FUNC, currFunc->name);
4261           goto errorTreeReturn;
4262         }
4263
4264       TTYPE (tree) = TETYPE (tree) = NULL;
4265       return tree;
4266
4267       /*------------------------------------------------------------------*/
4268       /*----------------------------*/
4269       /*     switch statement       */
4270       /*----------------------------*/
4271     case SWITCH:
4272       /* the switch value must be an integer */
4273       if (!IS_INTEGRAL (LTYPE (tree)))
4274         {
4275           werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4276           goto errorTreeReturn;
4277         }
4278       LRVAL (tree) = 1;
4279       TTYPE (tree) = TETYPE (tree) = NULL;
4280       return tree;
4281
4282       /*------------------------------------------------------------------*/
4283       /*----------------------------*/
4284       /* ifx Statement              */
4285       /*----------------------------*/
4286     case IFX:
4287       tree->left = backPatchLabels (tree->left,
4288                                     tree->trueLabel,
4289                                     tree->falseLabel);
4290       TTYPE (tree) = TETYPE (tree) = NULL;
4291       return tree;
4292
4293       /*------------------------------------------------------------------*/
4294       /*----------------------------*/
4295       /* for Statement              */
4296       /*----------------------------*/
4297     case FOR:
4298
4299       decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE);
4300       decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE);
4301       decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE);
4302
4303       /* if the for loop is reversible then
4304          reverse it otherwise do what we normally
4305          do */
4306       {
4307         symbol *sym;
4308         ast *init, *end;
4309
4310         if (isLoopReversible (tree, &sym, &init, &end))
4311           return reverseLoop (tree, sym, init, end);
4312         else
4313           return decorateType (createFor (AST_FOR (tree, trueLabel),
4314                                           AST_FOR (tree, continueLabel),
4315                                           AST_FOR (tree, falseLabel),
4316                                           AST_FOR (tree, condLabel),
4317                                           AST_FOR (tree, initExpr),
4318                                           AST_FOR (tree, condExpr),
4319                                           AST_FOR (tree, loopExpr),
4320                                           tree->left), RESULT_TYPE_NONE);
4321       }
4322     case PARAM:
4323       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4324               "node PARAM shouldn't be processed here");
4325               /* but in processParams() */
4326       return tree;
4327     default:
4328       TTYPE (tree) = TETYPE (tree) = NULL;
4329       return tree;
4330     }
4331
4332   /* some error found this tree will be killed */
4333 errorTreeReturn:
4334   TTYPE (tree) = TETYPE (tree) = newCharLink ();
4335   tree->opval.op = NULLOP;
4336   tree->isError = 1;
4337
4338   return tree;
4339 }
4340
4341 /*-----------------------------------------------------------------*/
4342 /* sizeofOp - processes size of operation                          */
4343 /*-----------------------------------------------------------------*/
4344 value *
4345 sizeofOp (sym_link * type)
4346 {
4347   char buff[10];
4348   int size;
4349
4350   /* make sure the type is complete and sane */
4351   checkTypeSanity(type, "(sizeof)");
4352
4353   /* get the size and convert it to character  */
4354   SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4355   if (!size && !IS_VOID(type))
4356     werror (E_SIZEOF_INCOMPLETE_TYPE);
4357
4358   /* now convert into value  */
4359   return constVal (buff);
4360 }
4361
4362
4363 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4364 #define IS_OR(ex)  (ex->type == EX_OP && ex->opval.op == OR_OP )
4365 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4366 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4367 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4368 #define IS_LT(ex)  (ex->type == EX_OP && ex->opval.op == '<' )
4369 #define IS_GT(ex)  (ex->type == EX_OP && ex->opval.op == '>')
4370
4371 /*-----------------------------------------------------------------*/
4372 /* backPatchLabels - change and or not operators to flow control    */
4373 /*-----------------------------------------------------------------*/
4374 ast *
4375 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4376 {
4377
4378   if (!tree)
4379     return NULL;
4380
4381   if (!(IS_ANDORNOT (tree)))
4382     return tree;
4383
4384   /* if this an and */
4385   if (IS_AND (tree))
4386     {
4387       static int localLbl = 0;
4388       symbol *localLabel;
4389
4390       SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4391       localLabel = newSymbol (buffer, NestLevel);
4392
4393       tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4394
4395       /* if left is already a IFX then just change the if true label in that */
4396       if (!IS_IFX (tree->left))
4397         tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4398
4399       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4400       /* right is a IFX then just join */
4401       if (IS_IFX (tree->right))
4402         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4403
4404       tree->right = createLabel (localLabel, tree->right);
4405       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4406
4407       return newNode (NULLOP, tree->left, tree->right);
4408     }
4409
4410   /* if this is an or operation */
4411   if (IS_OR (tree))
4412     {
4413       static int localLbl = 0;
4414       symbol *localLabel;
4415
4416       SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4417       localLabel = newSymbol (buffer, NestLevel);
4418
4419       tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4420
4421       /* if left is already a IFX then just change the if true label in that */
4422       if (!IS_IFX (tree->left))
4423         tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4424
4425       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4426       /* right is a IFX then just join */
4427       if (IS_IFX (tree->right))
4428         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4429
4430       tree->right = createLabel (localLabel, tree->right);
4431       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4432
4433       return newNode (NULLOP, tree->left, tree->right);
4434     }
4435
4436   /* change not */
4437   if (IS_NOT (tree))
4438     {
4439       int wasnot = IS_NOT (tree->left);
4440       tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4441
4442       /* if the left is already a IFX */
4443       if (!IS_IFX (tree->left))
4444         tree->left = newNode (IFX, tree->left, NULL);
4445
4446       if (wasnot)
4447         {
4448           tree->left->trueLabel = trueLabel;
4449           tree->left->falseLabel = falseLabel;
4450         }
4451       else
4452         {
4453           tree->left->trueLabel = falseLabel;
4454           tree->left->falseLabel = trueLabel;
4455         }
4456       return tree->left;
4457     }
4458
4459   if (IS_IFX (tree))
4460     {
4461       tree->trueLabel = trueLabel;
4462       tree->falseLabel = falseLabel;
4463     }
4464
4465   return tree;
4466 }
4467
4468
4469 /*-----------------------------------------------------------------*/
4470 /* createBlock - create expression tree for block                  */
4471 /*-----------------------------------------------------------------*/
4472 ast *
4473 createBlock (symbol * decl, ast * body)
4474 {
4475   ast *ex;
4476
4477   /* if the block has nothing */
4478   if (!body && !decl)
4479     return NULL;
4480
4481   ex = newNode (BLOCK, NULL, body);
4482   ex->values.sym = decl;
4483   
4484   ex->level++;
4485   ex->lineno = 0;
4486   return ex;
4487 }
4488
4489 /*-----------------------------------------------------------------*/
4490 /* createLabel - creates the expression tree for labels            */
4491 /*-----------------------------------------------------------------*/
4492 ast *
4493 createLabel (symbol * label, ast * stmnt)
4494 {
4495   symbol *csym;
4496   char name[SDCC_NAME_MAX + 1];
4497   ast *rValue;
4498
4499   /* must create fresh symbol if the symbol name  */
4500   /* exists in the symbol table, since there can  */
4501   /* be a variable with the same name as the labl */
4502   if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4503       (csym->level == label->level))
4504     label = newSymbol (label->name, label->level);
4505
4506   /* change the name before putting it in add _ */
4507   SNPRINTF(name, sizeof(name), "%s", label->name);
4508
4509   /* put the label in the LabelSymbol table    */
4510   /* but first check if a label of the same    */
4511   /* name exists                               */
4512   if ((csym = findSym (LabelTab, NULL, name)))
4513     werror (E_DUPLICATE_LABEL, label->name);
4514   else
4515     addSym (LabelTab, label, name, label->level, 0, 0);
4516
4517   label->isitmp = 1;
4518   label->islbl = 1;
4519   label->key = labelKey++;
4520   rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4521   rValue->lineno = 0;
4522
4523   return rValue;
4524 }
4525
4526 /*-----------------------------------------------------------------*/
4527 /* createCase - generates the parsetree for a case statement       */
4528 /*-----------------------------------------------------------------*/
4529 ast *
4530 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4531 {
4532   char caseLbl[SDCC_NAME_MAX + 1];
4533   ast *rexpr;
4534   value *val;
4535
4536   /* if the switch statement does not exist */
4537   /* then case is out of context            */
4538   if (!swStat)
4539     {
4540       werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4541       return NULL;
4542     }
4543
4544   caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE);
4545   /* if not a constant then error  */
4546   if (!IS_LITERAL (caseVal->ftype))
4547     {
4548       werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4549       return NULL;
4550     }
4551
4552   /* if not a integer than error */
4553   if (!IS_INTEGRAL (caseVal->ftype))
4554     {
4555       werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4556       return NULL;
4557     }
4558
4559   /* find the end of the switch values chain   */
4560   if (!(val = swStat->values.switchVals.swVals))
4561     swStat->values.switchVals.swVals = caseVal->opval.val;
4562   else
4563     {
4564       /* also order the cases according to value */
4565       value *pval = NULL;
4566       int cVal = (int) floatFromVal (caseVal->opval.val);
4567       while (val && (int) floatFromVal (val) < cVal)
4568         {
4569           pval = val;
4570           val = val->next;
4571         }
4572
4573       /* if we reached the end then */
4574       if (!val)
4575         {
4576           pval->next = caseVal->opval.val;
4577         }
4578       else if ((int) floatFromVal (val) == cVal)
4579         {
4580           werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4581                     "case");
4582           return NULL;
4583         }
4584       else
4585         {
4586           /* we found a value greater than */
4587           /* the current value we must add this */
4588           /* before the value */
4589           caseVal->opval.val->next = val;
4590
4591           /* if this was the first in chain */
4592           if (swStat->values.switchVals.swVals == val)
4593             swStat->values.switchVals.swVals =
4594               caseVal->opval.val;
4595           else
4596             pval->next = caseVal->opval.val;
4597         }
4598
4599     }
4600
4601   /* create the case label   */
4602   SNPRINTF(caseLbl, sizeof(caseLbl), 
4603            "_case_%d_%d",
4604            swStat->values.switchVals.swNum,
4605            (int) floatFromVal (caseVal->opval.val));
4606
4607   rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4608   rexpr->lineno = 0;
4609   return rexpr;
4610 }
4611
4612 /*-----------------------------------------------------------------*/
4613 /* createDefault - creates the parse tree for the default statement */
4614 /*-----------------------------------------------------------------*/
4615 ast *
4616 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4617 {
4618   char defLbl[SDCC_NAME_MAX + 1];
4619
4620   /* if the switch statement does not exist */
4621   /* then case is out of context            */
4622   if (!swStat)
4623     {
4624       werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4625       return NULL;
4626     }
4627
4628   if (swStat->values.switchVals.swDefault)
4629     {
4630       werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4631                 "default");
4632       return NULL;
4633     }
4634
4635   /* turn on the default flag   */
4636   swStat->values.switchVals.swDefault = 1;
4637
4638   /* create the label  */
4639   SNPRINTF (defLbl, sizeof(defLbl),
4640             "_default_%d", swStat->values.switchVals.swNum);
4641   return createLabel (newSymbol (defLbl, 0), stmnt);
4642 }
4643
4644 /*-----------------------------------------------------------------*/
4645 /* createIf - creates the parsetree for the if statement           */
4646 /*-----------------------------------------------------------------*/
4647 ast *
4648 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4649 {
4650   static int Lblnum = 0;
4651   ast *ifTree;
4652   symbol *ifTrue, *ifFalse, *ifEnd;
4653
4654   /* if neither exists */
4655   if (!elseBody && !ifBody) {
4656     // if there are no side effects (i++, j() etc)
4657     if (!hasSEFcalls(condAst)) {
4658       return condAst;
4659     }
4660   }
4661
4662   /* create the labels */
4663   SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4664   ifFalse = newSymbol (buffer, NestLevel);
4665   /* if no else body then end == false */
4666   if (!elseBody)
4667     ifEnd = ifFalse;
4668   else
4669     {
4670       SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4671       ifEnd = newSymbol (buffer, NestLevel);
4672     }
4673
4674   SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4675   ifTrue = newSymbol (buffer, NestLevel);
4676
4677   Lblnum++;
4678
4679   /* attach the ifTrue label to the top of it body */
4680   ifBody = createLabel (ifTrue, ifBody);
4681   /* attach a goto end to the ifBody if else is present */
4682   if (elseBody)
4683     {
4684       ifBody = newNode (NULLOP, ifBody,
4685                         newNode (GOTO,
4686                                  newAst_VALUE (symbolVal (ifEnd)),
4687                                  NULL));
4688       /* put the elseLabel on the else body */
4689       elseBody = createLabel (ifFalse, elseBody);
4690       /* out the end at the end of the body */
4691       elseBody = newNode (NULLOP,
4692                           elseBody,
4693                           createLabel (ifEnd, NULL));
4694     }
4695   else
4696     {
4697       ifBody = newNode (NULLOP, ifBody,
4698                         createLabel (ifFalse, NULL));
4699     }
4700   condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4701   if (IS_IFX (condAst))
4702     ifTree = condAst;
4703   else
4704     ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4705
4706   return newNode (NULLOP, ifTree,
4707                   newNode (NULLOP, ifBody, elseBody));
4708
4709 }
4710
4711 /*-----------------------------------------------------------------*/
4712 /* createDo - creates parse tree for do                            */
4713 /*        _dobody_n:                                               */
4714 /*            statements                                           */
4715 /*        _docontinue_n:                                           */
4716 /*            condition_expression +-> trueLabel -> _dobody_n      */
4717 /*                                 |                               */
4718 /*                                 +-> falseLabel-> _dobreak_n     */
4719 /*        _dobreak_n:                                              */
4720 /*-----------------------------------------------------------------*/
4721 ast *
4722 createDo (symbol * trueLabel, symbol * continueLabel,
4723           symbol * falseLabel, ast * condAst, ast * doBody)
4724 {
4725   ast *doTree;
4726
4727
4728   /* if the body does not exist then it is simple */
4729   if (!doBody)
4730     {
4731       condAst = backPatchLabels (condAst, continueLabel, NULL);
4732       doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4733                 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4734       doTree->trueLabel = continueLabel;
4735       doTree->falseLabel = NULL;
4736       return doTree;
4737     }
4738
4739   /* otherwise we have a body */
4740   condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4741
4742   /* attach the body label to the top */
4743   doBody = createLabel (trueLabel, doBody);
4744   /* attach the continue label to end of body */
4745   doBody = newNode (NULLOP, doBody,
4746                     createLabel (continueLabel, NULL));
4747
4748   /* now put the break label at the end */
4749   if (IS_IFX (condAst))
4750     doTree = condAst;
4751   else
4752     doTree = newIfxNode (condAst, trueLabel, falseLabel);
4753
4754   doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4755
4756   /* putting it together */
4757   return newNode (NULLOP, doBody, doTree);
4758 }
4759
4760 /*-----------------------------------------------------------------*/
4761 /* createFor - creates parse tree for 'for' statement              */
4762 /*        initExpr                                                 */
4763 /*   _forcond_n:                                                   */
4764 /*        condExpr  +-> trueLabel -> _forbody_n                    */
4765 /*                  |                                              */
4766 /*                  +-> falseLabel-> _forbreak_n                   */
4767 /*   _forbody_n:                                                   */
4768 /*        statements                                               */
4769 /*   _forcontinue_n:                                               */
4770 /*        loopExpr                                                 */
4771 /*        goto _forcond_n ;                                        */
4772 /*   _forbreak_n:                                                  */
4773 /*-----------------------------------------------------------------*/
4774 ast *
4775 createFor (symbol * trueLabel, symbol * continueLabel,
4776            symbol * falseLabel, symbol * condLabel,
4777            ast * initExpr, ast * condExpr, ast * loopExpr,
4778            ast * forBody)
4779 {
4780   ast *forTree;
4781
4782   /* if loopexpression not present then we can generate it */
4783   /* the same way as a while */
4784   if (!loopExpr)
4785     return newNode (NULLOP, initExpr,
4786                     createWhile (trueLabel, continueLabel,
4787                                  falseLabel, condExpr, forBody));
4788   /* vanilla for statement */
4789   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4790
4791   if (condExpr && !IS_IFX (condExpr))
4792     condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4793
4794
4795   /* attach condition label to condition */
4796   condExpr = createLabel (condLabel, condExpr);
4797
4798   /* attach body label to body */
4799   forBody = createLabel (trueLabel, forBody);
4800
4801   /* attach continue to forLoop expression & attach */
4802   /* goto the forcond @ and of loopExpression       */
4803   loopExpr = createLabel (continueLabel,
4804                           newNode (NULLOP,
4805                                    loopExpr,
4806                                    newNode (GOTO,
4807                                        newAst_VALUE (symbolVal (condLabel)),
4808                                             NULL)));
4809   /* now start putting them together */
4810   forTree = newNode (NULLOP, initExpr, condExpr);
4811   forTree = newNode (NULLOP, forTree, forBody);
4812   forTree = newNode (NULLOP, forTree, loopExpr);
4813   /* finally add the break label */
4814   forTree = newNode (NULLOP, forTree,
4815                      createLabel (falseLabel, NULL));
4816   return forTree;
4817 }
4818
4819 /*-----------------------------------------------------------------*/
4820 /* createWhile - creates parse tree for while statement            */
4821 /*               the while statement will be created as follows    */
4822 /*                                                                 */
4823 /*      _while_continue_n:                                         */
4824 /*            condition_expression +-> trueLabel -> _while_boby_n  */
4825 /*                                 |                               */
4826 /*                                 +-> falseLabel -> _while_break_n */
4827 /*      _while_body_n:                                             */
4828 /*            statements                                           */
4829 /*            goto _while_continue_n                               */
4830 /*      _while_break_n:                                            */
4831 /*-----------------------------------------------------------------*/
4832 ast *
4833 createWhile (symbol * trueLabel, symbol * continueLabel,
4834              symbol * falseLabel, ast * condExpr, ast * whileBody)
4835 {
4836   ast *whileTree;
4837
4838   /* put the continue label */
4839   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4840   condExpr = createLabel (continueLabel, condExpr);
4841   condExpr->lineno = 0;
4842
4843   /* put the body label in front of the body */
4844   whileBody = createLabel (trueLabel, whileBody);
4845   whileBody->lineno = 0;
4846   /* put a jump to continue at the end of the body */
4847   /* and put break label at the end of the body */
4848   whileBody = newNode (NULLOP,
4849                        whileBody,
4850                        newNode (GOTO,
4851                                 newAst_VALUE (symbolVal (continueLabel)),
4852                                 createLabel (falseLabel, NULL)));
4853
4854   /* put it all together */
4855   if (IS_IFX (condExpr))
4856     whileTree = condExpr;
4857   else
4858     {
4859       whileTree = newNode (IFX, condExpr, NULL);
4860       /* put the true & false labels in place */
4861       whileTree->trueLabel = trueLabel;
4862       whileTree->falseLabel = falseLabel;
4863     }
4864
4865   return newNode (NULLOP, whileTree, whileBody);
4866 }
4867
4868 /*-----------------------------------------------------------------*/
4869 /* optimizeGetHbit - get highest order bit of the expression       */
4870 /*-----------------------------------------------------------------*/
4871 ast *
4872 optimizeGetHbit (ast * tree)
4873 {
4874   int i, j;
4875   /* if this is not a bit and */
4876   if (!IS_BITAND (tree))
4877     return tree;
4878
4879   /* will look for tree of the form
4880      ( expr >> ((sizeof expr) -1) ) & 1 */
4881   if (!IS_AST_LIT_VALUE (tree->right))
4882     return tree;
4883
4884   if (AST_LIT_VALUE (tree->right) != 1)
4885     return tree;
4886
4887   if (!IS_RIGHT_OP (tree->left))
4888     return tree;
4889
4890   if (!IS_AST_LIT_VALUE (tree->left->right))
4891     return tree;
4892
4893   if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4894       (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4895     return tree;
4896       
4897   /* make sure the port supports GETHBIT */
4898   if (port->hasExtBitOp
4899       && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4900     return tree;
4901
4902   return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_TYPE_NONE);
4903
4904 }
4905
4906 /*-----------------------------------------------------------------*/
4907 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry     */
4908 /*-----------------------------------------------------------------*/
4909 ast *
4910 optimizeRRCRLC (ast * root)
4911 {
4912   /* will look for trees of the form
4913      (?expr << 1) | (?expr >> 7) or
4914      (?expr >> 7) | (?expr << 1) will make that
4915      into a RLC : operation ..
4916      Will also look for
4917      (?expr >> 1) | (?expr << 7) or
4918      (?expr << 7) | (?expr >> 1) will make that
4919      into a RRC operation
4920      note : by 7 I mean (number of bits required to hold the
4921      variable -1 ) */
4922   /* if the root operations is not a | operation the not */
4923   if (!IS_BITOR (root))
4924     return root;
4925
4926   /* I have to think of a better way to match patterns this sucks */
4927   /* that aside let start looking for the first case : I use a the
4928      negative check a lot to improve the efficiency */
4929   /* (?expr << 1) | (?expr >> 7) */
4930   if (IS_LEFT_OP (root->left) &&
4931       IS_RIGHT_OP (root->right))
4932     {
4933
4934       if (!SPEC_USIGN (TETYPE (root->left->left)))
4935         return root;
4936
4937       if (!IS_AST_LIT_VALUE (root->left->right) ||
4938           !IS_AST_LIT_VALUE (root->right->right))
4939         goto tryNext0;
4940
4941       /* make sure it is the same expression */
4942       if (!isAstEqual (root->left->left,
4943                        root->right->left))
4944         goto tryNext0;
4945
4946       if (AST_LIT_VALUE (root->left->right) != 1)
4947         goto tryNext0;
4948
4949       if (AST_LIT_VALUE (root->right->right) !=
4950           (getSize (TTYPE (root->left->left)) * 8 - 1))
4951         goto tryNext0;
4952
4953       /* make sure the port supports RLC */
4954       if (port->hasExtBitOp
4955           && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4956         return root;
4957
4958       /* whew got the first case : create the AST */
4959       return newNode (RLC, root->left->left, NULL);
4960     }
4961
4962 tryNext0:
4963   /* check for second case */
4964   /* (?expr >> 7) | (?expr << 1) */
4965   if (IS_LEFT_OP (root->right) &&
4966       IS_RIGHT_OP (root->left))
4967     {
4968
4969       if (!SPEC_USIGN (TETYPE (root->left->left)))
4970         return root;
4971
4972       if (!IS_AST_LIT_VALUE (root->left->right) ||
4973           !IS_AST_LIT_VALUE (root->right->right))
4974         goto tryNext1;
4975
4976       /* make sure it is the same symbol */
4977       if (!isAstEqual (root->left->left,
4978                        root->right->left))
4979         goto tryNext1;
4980
4981       if (AST_LIT_VALUE (root->right->right) != 1)
4982         goto tryNext1;
4983
4984       if (AST_LIT_VALUE (root->left->right) !=
4985           (getSize (TTYPE (root->left->left)) * 8 - 1))
4986         goto tryNext1;
4987
4988       /* make sure the port supports RLC */
4989       if (port->hasExtBitOp
4990           && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4991         return root;
4992
4993       /* whew got the first case : create the AST */
4994       return newNode (RLC, root->left->left, NULL);
4995
4996     }
4997
4998 tryNext1:
4999   /* third case for RRC */
5000   /*  (?symbol >> 1) | (?symbol << 7) */
5001   if (IS_LEFT_OP (root->right) &&
5002       IS_RIGHT_OP (root->left))
5003     {
5004
5005       if (!SPEC_USIGN (TETYPE (root->left->left)))
5006         return root;
5007
5008       if (!IS_AST_LIT_VALUE (root->left->right) ||
5009           !IS_AST_LIT_VALUE (root->right->right))
5010         goto tryNext2;
5011
5012       /* make sure it is the same symbol */
5013       if (!isAstEqual (root->left->left,
5014                        root->right->left))
5015         goto tryNext2;
5016
5017       if (AST_LIT_VALUE (root->left->right) != 1)
5018         goto tryNext2;
5019
5020       if (AST_LIT_VALUE (root->right->right) !=
5021           (getSize (TTYPE (root->left->left)) * 8 - 1))
5022         goto tryNext2;
5023
5024       /* make sure the port supports RRC */
5025       if (port->hasExtBitOp
5026           && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5027         return root;
5028
5029       /* whew got the first case : create the AST */
5030       return newNode (RRC, root->left->left, NULL);
5031
5032     }
5033 tryNext2:
5034   /* fourth and last case for now */
5035   /* (?symbol << 7) | (?symbol >> 1) */
5036   if (IS_RIGHT_OP (root->right) &&
5037       IS_LEFT_OP (root->left))
5038     {
5039
5040       if (!SPEC_USIGN (TETYPE (root->left->left)))
5041         return root;
5042
5043       if (!IS_AST_LIT_VALUE (root->left->right) ||
5044           !IS_AST_LIT_VALUE (root->right->right))
5045         return root;
5046
5047       /* make sure it is the same symbol */
5048       if (!isAstEqual (root->left->left,
5049                        root->right->left))
5050         return root;
5051
5052       if (AST_LIT_VALUE (root->right->right) != 1)
5053         return root;
5054
5055       if (AST_LIT_VALUE (root->left->right) !=
5056           (getSize (TTYPE (root->left->left)) * 8 - 1))
5057         return root;
5058
5059       /* make sure the port supports RRC */
5060       if (port->hasExtBitOp
5061           && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5062         return root;
5063
5064       /* whew got the first case : create the AST */
5065       return newNode (RRC, root->left->left, NULL);
5066
5067     }
5068
5069   /* not found return root */
5070   return root;
5071 }
5072
5073 /*-----------------------------------------------------------------*/
5074 /* optimizeSWAP :- optimize for nibble/byte/word swaps             */
5075 /*-----------------------------------------------------------------*/
5076 ast *
5077 optimizeSWAP (ast * root)
5078 {
5079   /* will look for trees of the form
5080      (?expr << 4) | (?expr >> 4) or
5081      (?expr >> 4) | (?expr << 4) will make that
5082      into a SWAP : operation ..
5083      note : by 4 I mean (number of bits required to hold the
5084      variable /2 ) */
5085   /* if the root operations is not a | operation the not */
5086   if (!IS_BITOR (root))
5087     return root;
5088
5089   /* (?expr << 4) | (?expr >> 4) */
5090   if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5091       || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5092     {
5093
5094       if (!SPEC_USIGN (TETYPE (root->left->left)))
5095         return root;
5096
5097       if (!IS_AST_LIT_VALUE (root->left->right) ||
5098           !IS_AST_LIT_VALUE (root->right->right))
5099         return root;
5100
5101       /* make sure it is the same expression */
5102       if (!isAstEqual (root->left->left,
5103                        root->right->left))
5104         return root;
5105
5106       if (AST_LIT_VALUE (root->left->right) !=
5107           (getSize (TTYPE (root->left->left)) * 4))
5108         return root;
5109
5110       if (AST_LIT_VALUE (root->right->right) !=
5111           (getSize (TTYPE (root->left->left)) * 4))
5112         return root;
5113
5114       /* make sure the port supports SWAP */
5115       if (port->hasExtBitOp
5116           && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5117         return root;
5118
5119       /* found it : create the AST */
5120       return newNode (SWAP, root->left->left, NULL);
5121     }
5122
5123
5124   /* not found return root */
5125   return root;
5126 }
5127
5128 /*-----------------------------------------------------------------*/
5129 /* optimizeCompare - otimizes compares for bit variables     */
5130 /*-----------------------------------------------------------------*/
5131 static ast *
5132 optimizeCompare (ast * root)
5133 {
5134   ast *optExpr = NULL;
5135   value *vleft;
5136   value *vright;
5137   unsigned int litValue;
5138
5139   /* if nothing then return nothing */
5140   if (!root)
5141     return NULL;
5142
5143   /* if not a compare op then do leaves */
5144   if (!IS_COMPARE_OP (root))
5145     {
5146       root->left = optimizeCompare (root->left);
5147       root->right = optimizeCompare (root->right);
5148       return root;
5149     }
5150
5151   /* if left & right are the same then depending
5152      of the operation do */
5153   if (isAstEqual (root->left, root->right))
5154     {
5155       switch (root->opval.op)
5156         {
5157         case '>':
5158         case '<':
5159         case NE_OP:
5160           optExpr = newAst_VALUE (constVal ("0"));
5161           break;
5162         case GE_OP:
5163         case LE_OP:
5164         case EQ_OP:
5165           optExpr = newAst_VALUE (constVal ("1"));
5166           break;
5167         }
5168
5169       return decorateType (optExpr, RESULT_TYPE_NONE);
5170     }
5171
5172   vleft = (root->left->type == EX_VALUE ?
5173            root->left->opval.val : NULL);
5174
5175   vright = (root->right->type == EX_VALUE ?
5176             root->right->opval.val : NULL);
5177
5178   /* if left is a BITVAR in BITSPACE */
5179   /* and right is a LITERAL then opt- */
5180   /* imize else do nothing       */
5181   if (vleft && vright &&
5182       IS_BITVAR (vleft->etype) &&
5183       IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5184       IS_LITERAL (vright->etype))
5185     {
5186
5187       /* if right side > 1 then comparison may never succeed */
5188       if ((litValue = (int) floatFromVal (vright)) > 1)
5189         {
5190           werror (W_BAD_COMPARE);
5191           goto noOptimize;
5192         }
5193
5194       if (litValue)
5195         {
5196           switch (root->opval.op)
5197             {
5198             case '>':           /* bit value greater than 1 cannot be */
5199               werror (W_BAD_COMPARE);
5200               goto noOptimize;
5201               break;
5202
5203             case '<':           /* bit value < 1 means 0 */
5204             case NE_OP:
5205               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5206               break;
5207
5208             case LE_OP: /* bit value <= 1 means no check */
5209               optExpr = newAst_VALUE (vright);
5210               break;
5211
5212             case GE_OP: /* bit value >= 1 means only check for = */
5213             case EQ_OP:
5214               optExpr = newAst_VALUE (vleft);
5215               break;
5216             }
5217         }
5218       else
5219         {                       /* literal is zero */
5220           switch (root->opval.op)
5221             {
5222             case '<':           /* bit value < 0 cannot be */
5223               werror (W_BAD_COMPARE);
5224               goto noOptimize;
5225               break;
5226
5227             case '>':           /* bit value > 0 means 1 */
5228             case NE_OP:
5229               optExpr = newAst_VALUE (vleft);
5230               break;
5231
5232             case LE_OP: /* bit value <= 0 means no check */
5233             case GE_OP: /* bit value >= 0 means no check */
5234               werror (W_BAD_COMPARE);
5235               goto noOptimize;
5236               break;
5237
5238             case EQ_OP: /* bit == 0 means ! of bit */
5239               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5240               break;
5241             }
5242         }
5243       return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE);
5244     }                           /* end-of-if of BITVAR */
5245
5246 noOptimize:
5247   return root;
5248 }
5249 /*-----------------------------------------------------------------*/
5250 /* addSymToBlock : adds the symbol to the first block we find      */
5251 /*-----------------------------------------------------------------*/
5252 void 
5253 addSymToBlock (symbol * sym, ast * tree)
5254 {
5255   /* reached end of tree or a leaf */
5256   if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5257     return;
5258
5259   /* found a block */
5260   if (IS_AST_OP (tree) &&
5261       tree->opval.op == BLOCK)
5262     {
5263
5264       symbol *lsym = copySymbol (sym);
5265
5266       lsym->next = AST_VALUES (tree, sym);
5267       AST_VALUES (tree, sym) = lsym;
5268       return;
5269     }
5270
5271   addSymToBlock (sym, tree->left);
5272   addSymToBlock (sym, tree->right);
5273 }
5274
5275 /*-----------------------------------------------------------------*/
5276 /* processRegParms - do processing for register parameters         */
5277 /*-----------------------------------------------------------------*/
5278 static void 
5279 processRegParms (value * args, ast * body)
5280 {
5281   while (args)
5282     {
5283       if (IS_REGPARM (args->etype))
5284         addSymToBlock (args->sym, body);
5285       args = args->next;
5286     }
5287 }
5288
5289 /*-----------------------------------------------------------------*/
5290 /* resetParmKey - resets the operandkeys for the symbols           */
5291 /*-----------------------------------------------------------------*/
5292 DEFSETFUNC (resetParmKey)
5293 {
5294   symbol *sym = item;
5295
5296   sym->key = 0;
5297   sym->defs = NULL;
5298   sym->uses = NULL;
5299   sym->remat = 0;
5300   return 1;
5301 }
5302
5303 /*-----------------------------------------------------------------*/
5304 /* createFunction - This is the key node that calls the iCode for  */
5305 /*                  generating the code for a function. Note code  */
5306 /*                  is generated function by function, later when  */
5307 /*                  add inter-procedural analysis this will change */
5308 /*-----------------------------------------------------------------*/
5309 ast *
5310 createFunction (symbol * name, ast * body)
5311 {
5312   ast *ex;
5313   symbol *csym;
5314   int stack = 0;
5315   sym_link *fetype;
5316   iCode *piCode = NULL;
5317
5318   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5319     fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5320
5321   /* if check function return 0 then some problem */
5322   if (checkFunction (name, NULL) == 0)
5323     return NULL;
5324
5325   /* create a dummy block if none exists */
5326   if (!body)
5327     body = newNode (BLOCK, NULL, NULL);
5328
5329   noLineno++;
5330
5331   /* check if the function name already in the symbol table */
5332   if ((csym = findSym (SymbolTab, NULL, name->name)))
5333     {
5334       name = csym;
5335       /* special case for compiler defined functions
5336          we need to add the name to the publics list : this
5337          actually means we are now compiling the compiler
5338          support routine */
5339       if (name->cdef)
5340         {
5341           addSet (&publics, name);
5342         }
5343     }
5344   else
5345     {
5346       addSymChain (name);
5347       allocVariables (name);
5348     }
5349   name->lastLine = mylineno;
5350   currFunc = name;
5351
5352   /* set the stack pointer */
5353   stackPtr  = -port->stack.direction * port->stack.call_overhead;
5354   xstackPtr = -port->stack.direction * port->stack.call_overhead;
5355
5356   if (IFFUNC_ISISR (name->type))
5357     stackPtr -= port->stack.direction * port->stack.isr_overhead;
5358
5359   if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5360     {
5361       if (options.useXstack)
5362         xstackPtr -= port->stack.direction * port->stack.reent_overhead;
5363       else
5364         stackPtr  -= port->stack.direction * port->stack.reent_overhead;
5365     }
5366
5367   fetype = getSpec (name->type);        /* get the specifier for the function */
5368   /* if this is a reentrant function then */
5369   if (IFFUNC_ISREENT (name->type))
5370     reentrant++;
5371
5372   allocParms (FUNC_ARGS(name->type));   /* allocate the parameters */
5373
5374   /* do processing for parameters that are passed in registers */
5375   processRegParms (FUNC_ARGS(name->type), body);
5376
5377   /* set the stack pointer */
5378   stackPtr = 0;
5379   xstackPtr = -1;
5380
5381   /* allocate & autoinit the block variables */
5382   processBlockVars (body, &stack, ALLOCATE);
5383
5384   /* save the stack information */
5385   if (options.useXstack)
5386     name->xstack = SPEC_STAK (fetype) = stack;
5387   else
5388     name->stack = SPEC_STAK (fetype) = stack;
5389
5390   /* name needs to be mangled */
5391   SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5392
5393   body = resolveSymbols (body); /* resolve the symbols */
5394   body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5395                                         
5396
5397   ex = newAst_VALUE (symbolVal (name)); /* create name */
5398   ex = newNode (FUNCTION, ex, body);
5399   ex->values.args = FUNC_ARGS(name->type);
5400   ex->decorated=1;
5401   if (options.dump_tree) PA(ex);
5402   if (fatalError)
5403     {
5404       werror (E_FUNC_NO_CODE, name->name);
5405       goto skipall;
5406     }
5407
5408   /* create the node & generate intermediate code */
5409   GcurMemmap = code;
5410   codeOutFile = code->oFile;
5411   piCode = iCodeFromAst (ex);
5412
5413   if (fatalError)
5414     {
5415       werror (E_FUNC_NO_CODE, name->name);
5416       goto skipall;
5417     }
5418
5419   eBBlockFromiCode (piCode);
5420
5421   /* if there are any statics then do them */
5422   if (staticAutos)
5423     {
5424       GcurMemmap = statsg;
5425       codeOutFile = statsg->oFile;
5426       eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE)));
5427       staticAutos = NULL;
5428     }
5429
5430 skipall:
5431
5432   /* dealloc the block variables */
5433   processBlockVars (body, &stack, DEALLOCATE);
5434   outputDebugStackSymbols();
5435   /* deallocate paramaters */
5436   deallocParms (FUNC_ARGS(name->type));
5437
5438   if (IFFUNC_ISREENT (name->type))
5439     reentrant--;
5440
5441   /* we are done freeup memory & cleanup */
5442   noLineno--;
5443   if (port->reset_labelKey) labelKey = 1;
5444   name->key = 0;
5445   FUNC_HASBODY(name->type) = 1;
5446   addSet (&operKeyReset, name);
5447   applyToSet (operKeyReset, resetParmKey);
5448
5449   if (options.debug)
5450     cdbStructBlock(1);
5451
5452   cleanUpLevel (LabelTab, 0);
5453   cleanUpBlock (StructTab, 1);
5454   cleanUpBlock (TypedefTab, 1);
5455
5456   xstack->syms = NULL;
5457   istack->syms = NULL;
5458   return NULL;
5459 }
5460
5461
5462 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5463 /*-----------------------------------------------------------------*/
5464 /* ast_print : prints the ast (for debugging purposes)             */
5465 /*-----------------------------------------------------------------*/
5466
5467 void ast_print (ast * tree, FILE *outfile, int indent)
5468 {
5469
5470         if (!tree) return ;
5471
5472         /* can print only decorated trees */
5473         if (!tree->decorated) return;
5474
5475         /* if any child is an error | this one is an error do nothing */
5476         if (tree->isError ||
5477             (tree->left && tree->left->isError) ||
5478             (tree->right && tree->right->isError)) {
5479                 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5480         }
5481
5482
5483         /* print the line          */
5484         /* if not block & function */
5485         if (tree->type == EX_OP &&
5486             (tree->opval.op != FUNCTION &&
5487              tree->opval.op != BLOCK &&
5488              tree->opval.op != NULLOP)) {
5489         }
5490
5491         if (tree->opval.op == FUNCTION) {
5492                 int arg=0;
5493                 value *args=FUNC_ARGS(tree->left->opval.val->type);
5494                 fprintf(outfile,"FUNCTION (%s=%p) type (",
5495                         tree->left->opval.val->name, tree);
5496                 printTypeChain (tree->left->opval.val->type->next,outfile);
5497                 fprintf(outfile,") args (");
5498                 do {
5499                   if (arg) {
5500                     fprintf (outfile, ", ");
5501                   }
5502                   printTypeChain (args ? args->type : NULL, outfile);
5503                   arg++;
5504                   args= args ? args->next : NULL;
5505                 } while (args);
5506                 fprintf(outfile,")\n");
5507                 ast_print(tree->left,outfile,indent);
5508                 ast_print(tree->right,outfile,indent);
5509                 return ;
5510         }
5511         if (tree->opval.op == BLOCK) {
5512                 symbol *decls = tree->values.sym;
5513                 INDENT(indent,outfile);
5514                 fprintf(outfile,"{\n");
5515                 while (decls) {
5516                         INDENT(indent+2,outfile);
5517                         fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5518                                 decls->name, decls);
5519                         printTypeChain(decls->type,outfile);
5520                         fprintf(outfile,")\n");
5521
5522                         decls = decls->next;
5523                 }
5524                 ast_print(tree->right,outfile,indent+2);
5525                 INDENT(indent,outfile);
5526                 fprintf(outfile,"}\n");
5527                 return;
5528         }
5529         if (tree->opval.op == NULLOP) {
5530                 ast_print(tree->left,outfile,indent);
5531                 ast_print(tree->right,outfile,indent);
5532                 return ;
5533         }
5534         INDENT(indent,outfile);
5535
5536         /*------------------------------------------------------------------*/
5537         /*----------------------------*/
5538         /*   leaf has been reached    */
5539         /*----------------------------*/
5540         /* if this is of type value */
5541         /* just get the type        */
5542         if (tree->type == EX_VALUE) {
5543
5544                 if (IS_LITERAL (tree->opval.val->etype)) {
5545                         fprintf(outfile,"CONSTANT (%p) value = ", tree);
5546                         if (SPEC_USIGN (tree->opval.val->etype))
5547                                 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5548                         else
5549                                 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5550                         fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5551                                                       floatFromVal(tree->opval.val));
5552                 } else if (tree->opval.val->sym) {
5553                         /* if the undefined flag is set then give error message */
5554                         if (tree->opval.val->sym->undefined) {
5555                                 fprintf(outfile,"UNDEFINED SYMBOL ");
5556                         } else {
5557                                 fprintf(outfile,"SYMBOL ");
5558                         }
5559                         fprintf(outfile,"(%s=%p)",
5560                                 tree->opval.val->sym->name,tree);
5561                 }
5562                 if (tree->ftype) {
5563                         fprintf(outfile," type (");
5564                         printTypeChain(tree->ftype,outfile);
5565                         fprintf(outfile,")\n");
5566                 } else {
5567                         fprintf(outfile,"\n");
5568                 }
5569                 return ;
5570         }
5571
5572         /* if type link for the case of cast */
5573         if (tree->type == EX_LINK) {
5574                 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5575                 printTypeChain(tree->opval.lnk,outfile);
5576                 fprintf(outfile,")\n");
5577                 return ;
5578         }
5579
5580
5581         /* depending on type of operator do */
5582
5583         switch (tree->opval.op) {
5584                 /*------------------------------------------------------------------*/
5585                 /*----------------------------*/
5586                 /*        array node          */
5587                 /*----------------------------*/
5588         case '[':
5589                 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5590                 printTypeChain(tree->ftype,outfile);
5591                 fprintf(outfile,")\n");
5592                 ast_print(tree->left,outfile,indent+2);
5593                 ast_print(tree->right,outfile,indent+2);
5594                 return;
5595
5596                 /*------------------------------------------------------------------*/
5597                 /*----------------------------*/
5598                 /*      struct/union          */
5599                 /*----------------------------*/
5600         case '.':
5601                 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5602                 printTypeChain(tree->ftype,outfile);
5603                 fprintf(outfile,")\n");
5604                 ast_print(tree->left,outfile,indent+2);
5605                 ast_print(tree->right,outfile,indent+2);
5606                 return ;
5607
5608                 /*------------------------------------------------------------------*/
5609                 /*----------------------------*/
5610                 /*    struct/union pointer    */
5611                 /*----------------------------*/
5612         case PTR_OP:
5613                 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5614                 printTypeChain(tree->ftype,outfile);
5615                 fprintf(outfile,")\n");
5616                 ast_print(tree->left,outfile,indent+2);
5617                 ast_print(tree->right,outfile,indent+2);
5618                 return ;
5619
5620                 /*------------------------------------------------------------------*/
5621                 /*----------------------------*/
5622                 /*  ++/-- operation           */
5623                 /*----------------------------*/
5624         case INC_OP:
5625                 if (tree->left)
5626                   fprintf(outfile,"post-");
5627                 else
5628                   fprintf(outfile,"pre-");
5629                 fprintf(outfile,"INC_OP (%p) type (",tree);
5630                 printTypeChain(tree->ftype,outfile);
5631                 fprintf(outfile,")\n");
5632                 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5633                 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5634                 return ;
5635
5636         case DEC_OP:
5637                 if (tree->left)
5638                   fprintf(outfile,"post-");
5639                 else
5640                   fprintf(outfile,"pre-");
5641                 fprintf(outfile,"DEC_OP (%p) type (",tree);
5642                 printTypeChain(tree->ftype,outfile);
5643                 fprintf(outfile,")\n");
5644                 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5645                 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5646                 return ;
5647
5648                 /*------------------------------------------------------------------*/
5649                 /*----------------------------*/
5650                 /*  bitwise and               */
5651                 /*----------------------------*/
5652         case '&':
5653                 if (tree->right) {
5654                         fprintf(outfile,"& (%p) type (",tree);
5655                         printTypeChain(tree->ftype,outfile);
5656                         fprintf(outfile,")\n");
5657                         ast_print(tree->left,outfile,indent+2);
5658                         ast_print(tree->right,outfile,indent+2);
5659                 } else {
5660                         fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5661                         printTypeChain(tree->ftype,outfile);
5662                         fprintf(outfile,")\n");
5663                         ast_print(tree->left,outfile,indent+2);
5664                         ast_print(tree->right,outfile,indent+2);
5665                 }
5666                 return ;
5667                 /*----------------------------*/
5668                 /*  bitwise or                */
5669                 /*----------------------------*/
5670         case '|':
5671                 fprintf(outfile,"OR (%p) type (",tree);
5672                 printTypeChain(tree->ftype,outfile);
5673                 fprintf(outfile,")\n");
5674                 ast_print(tree->left,outfile,indent+2);
5675                 ast_print(tree->right,outfile,indent+2);
5676                 return ;
5677                 /*------------------------------------------------------------------*/
5678                 /*----------------------------*/
5679                 /*  bitwise xor               */
5680                 /*----------------------------*/
5681         case '^':
5682                 fprintf(outfile,"XOR (%p) type (",tree);
5683                 printTypeChain(tree->ftype,outfile);
5684                 fprintf(outfile,")\n");
5685                 ast_print(tree->left,outfile,indent+2);
5686                 ast_print(tree->right,outfile,indent+2);
5687                 return ;
5688
5689                 /*------------------------------------------------------------------*/
5690                 /*----------------------------*/
5691                 /*  division                  */
5692                 /*----------------------------*/
5693         case '/':
5694                 fprintf(outfile,"DIV (%p) type (",tree);
5695                 printTypeChain(tree->ftype,outfile);
5696                 fprintf(outfile,")\n");
5697                 ast_print(tree->left,outfile,indent+2);
5698                 ast_print(tree->right,outfile,indent+2);
5699                 return ;
5700                 /*------------------------------------------------------------------*/
5701                 /*----------------------------*/
5702                 /*            modulus         */
5703                 /*----------------------------*/
5704         case '%':
5705                 fprintf(outfile,"MOD (%p) type (",tree);
5706                 printTypeChain(tree->ftype,outfile);
5707                 fprintf(outfile,")\n");
5708                 ast_print(tree->left,outfile,indent+2);
5709                 ast_print(tree->right,outfile,indent+2);
5710                 return ;
5711
5712                 /*------------------------------------------------------------------*/
5713                 /*----------------------------*/
5714                 /*  address dereference       */
5715                 /*----------------------------*/
5716         case '*':                       /* can be unary  : if right is null then unary operation */
5717                 if (!tree->right) {
5718                         fprintf(outfile,"DEREF (%p) type (",tree);
5719                         printTypeChain(tree->ftype,outfile);
5720                         fprintf(outfile,")\n");
5721                         ast_print(tree->left,outfile,indent+2);
5722                         return ;
5723                 }                       
5724                 /*------------------------------------------------------------------*/
5725                 /*----------------------------*/
5726                 /*      multiplication        */
5727                 /*----------------------------*/                
5728                 fprintf(outfile,"MULT (%p) type (",tree);
5729                 printTypeChain(tree->ftype,outfile);
5730                 fprintf(outfile,")\n");
5731                 ast_print(tree->left,outfile,indent+2);
5732                 ast_print(tree->right,outfile,indent+2);
5733                 return ;
5734
5735
5736                 /*------------------------------------------------------------------*/
5737                 /*----------------------------*/
5738                 /*    unary '+' operator      */
5739                 /*----------------------------*/
5740         case '+':
5741                 /* if unary plus */
5742                 if (!tree->right) {
5743                         fprintf(outfile,"UPLUS (%p) type (",tree);
5744                         printTypeChain(tree->ftype,outfile);
5745                         fprintf(outfile,")\n");
5746                         ast_print(tree->left,outfile,indent+2);
5747                 } else {
5748                         /*------------------------------------------------------------------*/
5749                         /*----------------------------*/
5750                         /*      addition              */
5751                         /*----------------------------*/
5752                         fprintf(outfile,"ADD (%p) type (",tree);
5753                         printTypeChain(tree->ftype,outfile);
5754                         fprintf(outfile,")\n");
5755                         ast_print(tree->left,outfile,indent+2);
5756                         ast_print(tree->right,outfile,indent+2);
5757                 }
5758                 return;
5759                 /*------------------------------------------------------------------*/
5760                 /*----------------------------*/
5761                 /*      unary '-'             */
5762                 /*----------------------------*/
5763         case '-':                       /* can be unary   */
5764                 if (!tree->right) {
5765                         fprintf(outfile,"UMINUS (%p) type (",tree);
5766                         printTypeChain(tree->ftype,outfile);
5767                         fprintf(outfile,")\n");
5768                         ast_print(tree->left,outfile,indent+2);
5769                 } else {
5770                         /*------------------------------------------------------------------*/
5771                         /*----------------------------*/
5772                         /*      subtraction           */
5773                         /*----------------------------*/
5774                         fprintf(outfile,"SUB (%p) type (",tree);
5775                         printTypeChain(tree->ftype,outfile);
5776                         fprintf(outfile,")\n");
5777                         ast_print(tree->left,outfile,indent+2);
5778                         ast_print(tree->right,outfile,indent+2);
5779                 }
5780                 return;
5781                 /*------------------------------------------------------------------*/
5782                 /*----------------------------*/
5783                 /*    compliment              */
5784                 /*----------------------------*/
5785         case '~':
5786                 fprintf(outfile,"COMPL (%p) type (",tree);
5787                 printTypeChain(tree->ftype,outfile);
5788                 fprintf(outfile,")\n");
5789                 ast_print(tree->left,outfile,indent+2);
5790                 return ;
5791                 /*------------------------------------------------------------------*/
5792                 /*----------------------------*/
5793                 /*           not              */
5794                 /*----------------------------*/
5795         case '!':
5796                 fprintf(outfile,"NOT (%p) type (",tree);
5797                 printTypeChain(tree->ftype,outfile);
5798                 fprintf(outfile,")\n");
5799                 ast_print(tree->left,outfile,indent+2);
5800                 return ;
5801                 /*------------------------------------------------------------------*/
5802                 /*----------------------------*/
5803                 /*           shift            */
5804                 /*----------------------------*/
5805         case RRC:
5806                 fprintf(outfile,"RRC (%p) type (",tree);
5807                 printTypeChain(tree->ftype,outfile);
5808                 fprintf(outfile,")\n");
5809                 ast_print(tree->left,outfile,indent+2);
5810                 return ;
5811
5812         case RLC:
5813                 fprintf(outfile,"RLC (%p) type (",tree);
5814                 printTypeChain(tree->ftype,outfile);
5815                 fprintf(outfile,")\n");
5816                 ast_print(tree->left,outfile,indent+2);
5817                 return ;
5818         case SWAP:
5819                 fprintf(outfile,"SWAP (%p) type (",tree);
5820                 printTypeChain(tree->ftype,outfile);
5821                 fprintf(outfile,")\n");
5822                 ast_print(tree->left,outfile,indent+2);
5823                 return ;
5824         case GETHBIT:
5825                 fprintf(outfile,"GETHBIT (%p) type (",tree);
5826                 printTypeChain(tree->ftype,outfile);
5827                 fprintf(outfile,")\n");
5828                 ast_print(tree->left,outfile,indent+2);
5829                 return ;
5830         case LEFT_OP:
5831                 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5832                 printTypeChain(tree->ftype,outfile);
5833                 fprintf(outfile,")\n");
5834                 ast_print(tree->left,outfile,indent+2);
5835                 ast_print(tree->right,outfile,indent+2);
5836                 return ;
5837         case RIGHT_OP:
5838                 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5839                 printTypeChain(tree->ftype,outfile);
5840                 fprintf(outfile,")\n");
5841                 ast_print(tree->left,outfile,indent+2);
5842                 ast_print(tree->right,outfile,indent+2);
5843                 return ;
5844                 /*------------------------------------------------------------------*/
5845                 /*----------------------------*/
5846                 /*         casting            */
5847                 /*----------------------------*/
5848         case CAST:                      /* change the type   */
5849                 fprintf(outfile,"CAST (%p) from type (",tree);
5850                 printTypeChain(tree->right->ftype,outfile);
5851                 fprintf(outfile,") to type (");
5852                 printTypeChain(tree->ftype,outfile);
5853                 fprintf(outfile,")\n");
5854                 ast_print(tree->right,outfile,indent+2);
5855                 return ;
5856                 
5857         case AND_OP:
5858                 fprintf(outfile,"ANDAND (%p) type (",tree);
5859                 printTypeChain(tree->ftype,outfile);
5860                 fprintf(outfile,")\n");
5861                 ast_print(tree->left,outfile,indent+2);
5862                 ast_print(tree->right,outfile,indent+2);
5863                 return ;
5864         case OR_OP:
5865                 fprintf(outfile,"OROR (%p) type (",tree);
5866                 printTypeChain(tree->ftype,outfile);
5867                 fprintf(outfile,")\n");
5868                 ast_print(tree->left,outfile,indent+2);
5869                 ast_print(tree->right,outfile,indent+2);
5870                 return ;
5871                 
5872                 /*------------------------------------------------------------------*/
5873                 /*----------------------------*/
5874                 /*     comparison operators   */
5875                 /*----------------------------*/
5876         case '>':
5877                 fprintf(outfile,"GT(>) (%p) type (",tree);
5878                 printTypeChain(tree->ftype,outfile);
5879                 fprintf(outfile,")\n");
5880                 ast_print(tree->left,outfile,indent+2);
5881                 ast_print(tree->right,outfile,indent+2);
5882                 return ;
5883         case '<':
5884                 fprintf(outfile,"LT(<) (%p) type (",tree);
5885                 printTypeChain(tree->ftype,outfile);
5886                 fprintf(outfile,")\n");
5887                 ast_print(tree->left,outfile,indent+2);
5888                 ast_print(tree->right,outfile,indent+2);
5889                 return ;
5890         case LE_OP:
5891                 fprintf(outfile,"LE(<=) (%p) type (",tree);
5892                 printTypeChain(tree->ftype,outfile);
5893                 fprintf(outfile,")\n");
5894                 ast_print(tree->left,outfile,indent+2);
5895                 ast_print(tree->right,outfile,indent+2);
5896                 return ;
5897         case GE_OP:
5898                 fprintf(outfile,"GE(>=) (%p) type (",tree);
5899                 printTypeChain(tree->ftype,outfile);
5900                 fprintf(outfile,")\n");
5901                 ast_print(tree->left,outfile,indent+2);
5902                 ast_print(tree->right,outfile,indent+2);
5903                 return ;
5904         case EQ_OP:
5905                 fprintf(outfile,"EQ(==) (%p) type (",tree);
5906                 printTypeChain(tree->ftype,outfile);
5907                 fprintf(outfile,")\n");
5908                 ast_print(tree->left,outfile,indent+2);
5909                 ast_print(tree->right,outfile,indent+2);
5910                 return ;
5911         case NE_OP:
5912                 fprintf(outfile,"NE(!=) (%p) type (",tree);
5913                 printTypeChain(tree->ftype,outfile);
5914                 fprintf(outfile,")\n");
5915                 ast_print(tree->left,outfile,indent+2);
5916                 ast_print(tree->right,outfile,indent+2);
5917                 /*------------------------------------------------------------------*/
5918                 /*----------------------------*/
5919                 /*             sizeof         */
5920                 /*----------------------------*/
5921         case SIZEOF:            /* evaluate wihout code generation */
5922                 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5923                 return ;
5924
5925                 /*------------------------------------------------------------------*/
5926                 /*----------------------------*/
5927                 /* conditional operator  '?'  */
5928                 /*----------------------------*/
5929         case '?':
5930                 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5931                 printTypeChain(tree->ftype,outfile);
5932                 fprintf(outfile,")\n");
5933                 ast_print(tree->left,outfile,indent+2);
5934                 ast_print(tree->right,outfile,indent+2);
5935                 return;
5936
5937         case ':':
5938                 fprintf(outfile,"COLON(:) (%p) type (",tree);
5939                 printTypeChain(tree->ftype,outfile);
5940                 fprintf(outfile,")\n");
5941                 ast_print(tree->left,outfile,indent+2);
5942                 ast_print(tree->right,outfile,indent+2);
5943                 return ;
5944
5945                 /*------------------------------------------------------------------*/
5946                 /*----------------------------*/
5947                 /*    assignment operators    */
5948                 /*----------------------------*/
5949         case MUL_ASSIGN:
5950                 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5951                 printTypeChain(tree->ftype,outfile);
5952                 fprintf(outfile,")\n");
5953                 ast_print(tree->left,outfile,indent+2);
5954                 ast_print(tree->right,outfile,indent+2);
5955                 return;
5956         case DIV_ASSIGN:
5957                 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5958                 printTypeChain(tree->ftype,outfile);
5959                 fprintf(outfile,")\n");
5960                 ast_print(tree->left,outfile,indent+2);
5961                 ast_print(tree->right,outfile,indent+2);
5962                 return;
5963         case AND_ASSIGN:
5964                 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5965                 printTypeChain(tree->ftype,outfile);
5966                 fprintf(outfile,")\n");
5967                 ast_print(tree->left,outfile,indent+2);
5968                 ast_print(tree->right,outfile,indent+2);
5969                 return;
5970         case OR_ASSIGN:
5971                 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5972                 printTypeChain(tree->ftype,outfile);
5973                 fprintf(outfile,")\n");
5974                 ast_print(tree->left,outfile,indent+2);
5975                 ast_print(tree->right,outfile,indent+2);
5976                 return;
5977         case XOR_ASSIGN:
5978                 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5979                 printTypeChain(tree->ftype,outfile);
5980                 fprintf(outfile,")\n");
5981                 ast_print(tree->left,outfile,indent+2);
5982                 ast_print(tree->right,outfile,indent+2);
5983                 return;
5984         case RIGHT_ASSIGN:
5985                 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5986                 printTypeChain(tree->ftype,outfile);
5987                 fprintf(outfile,")\n");
5988                 ast_print(tree->left,outfile,indent+2);
5989                 ast_print(tree->right,outfile,indent+2);
5990                 return;
5991         case LEFT_ASSIGN:
5992                 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5993                 printTypeChain(tree->ftype,outfile);
5994                 fprintf(outfile,")\n");
5995                 ast_print(tree->left,outfile,indent+2);
5996                 ast_print(tree->right,outfile,indent+2);
5997                 return;
5998                 /*------------------------------------------------------------------*/
5999                 /*----------------------------*/
6000                 /*    -= operator             */
6001                 /*----------------------------*/
6002         case SUB_ASSIGN:
6003                 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
6004                 printTypeChain(tree->ftype,outfile);
6005                 fprintf(outfile,")\n");
6006                 ast_print(tree->left,outfile,indent+2);
6007                 ast_print(tree->right,outfile,indent+2);
6008                 return;
6009                 /*------------------------------------------------------------------*/
6010                 /*----------------------------*/
6011                 /*          += operator       */
6012                 /*----------------------------*/
6013         case ADD_ASSIGN:
6014                 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
6015                 printTypeChain(tree->ftype,outfile);
6016                 fprintf(outfile,")\n");
6017                 ast_print(tree->left,outfile,indent+2);
6018                 ast_print(tree->right,outfile,indent+2);
6019                 return;
6020                 /*------------------------------------------------------------------*/
6021                 /*----------------------------*/
6022                 /*      straight assignemnt   */
6023                 /*----------------------------*/
6024         case '=':
6025                 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
6026                 printTypeChain(tree->ftype,outfile);
6027                 fprintf(outfile,")\n");
6028                 ast_print(tree->left,outfile,indent+2);
6029                 ast_print(tree->right,outfile,indent+2);
6030                 return;     
6031                 /*------------------------------------------------------------------*/
6032                 /*----------------------------*/
6033                 /*      comma operator        */
6034                 /*----------------------------*/
6035         case ',':
6036                 fprintf(outfile,"COMMA(,) (%p) type (",tree);
6037                 printTypeChain(tree->ftype,outfile);
6038                 fprintf(outfile,")\n");
6039                 ast_print(tree->left,outfile,indent+2);
6040                 ast_print(tree->right,outfile,indent+2);
6041                 return;
6042                 /*------------------------------------------------------------------*/
6043                 /*----------------------------*/
6044                 /*       function call        */
6045                 /*----------------------------*/
6046         case CALL:
6047         case PCALL:
6048                 fprintf(outfile,"CALL (%p) type (",tree);
6049                 printTypeChain(tree->ftype,outfile);
6050                 fprintf(outfile,")\n");
6051                 ast_print(tree->left,outfile,indent+2);
6052                 ast_print(tree->right,outfile,indent+2);
6053                 return;
6054         case PARAM:
6055                 fprintf(outfile,"PARMS\n");
6056                 ast_print(tree->left,outfile,indent+2);
6057                 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
6058                         ast_print(tree->right,outfile,indent+2);
6059                 }
6060                 return ;
6061                 /*------------------------------------------------------------------*/
6062                 /*----------------------------*/
6063                 /*     return statement       */
6064                 /*----------------------------*/
6065         case RETURN:
6066                 fprintf(outfile,"RETURN (%p) type (",tree);
6067                 if (tree->right) {
6068                     printTypeChain(tree->right->ftype,outfile);
6069                 }
6070                 fprintf(outfile,")\n");
6071                 ast_print(tree->right,outfile,indent+2);
6072                 return ;
6073                 /*------------------------------------------------------------------*/
6074                 /*----------------------------*/
6075                 /*     label statement        */
6076                 /*----------------------------*/
6077         case LABEL :
6078                 fprintf(outfile,"LABEL (%p)\n",tree);
6079                 ast_print(tree->left,outfile,indent+2);
6080                 ast_print(tree->right,outfile,indent);
6081                 return;
6082                 /*------------------------------------------------------------------*/
6083                 /*----------------------------*/
6084                 /*     switch statement       */
6085                 /*----------------------------*/
6086         case SWITCH:
6087                 {
6088                         value *val;
6089                         fprintf(outfile,"SWITCH (%p) ",tree);
6090                         ast_print(tree->left,outfile,0);
6091                         for (val = tree->values.switchVals.swVals; val ; val = val->next) {
6092                                 INDENT(indent+2,outfile);
6093                                 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
6094                                         (int) floatFromVal(val),
6095                                         tree->values.switchVals.swNum,
6096                                         (int) floatFromVal(val));
6097                         }
6098                         ast_print(tree->right,outfile,indent);
6099                 }
6100                 return ;
6101                 /*------------------------------------------------------------------*/
6102                 /*----------------------------*/
6103                 /* ifx Statement              */
6104                 /*----------------------------*/
6105         case IFX:
6106                 fprintf(outfile,"IF (%p) \n",tree);
6107                 ast_print(tree->left,outfile,indent+2);
6108                 if (tree->trueLabel) {
6109                         INDENT(indent+2,outfile);
6110                         fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
6111                 }
6112                 if (tree->falseLabel) {
6113                         INDENT(indent+2,outfile);
6114                         fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
6115                 }
6116                 ast_print(tree->right,outfile,indent+2);
6117                 return ;
6118                 /*----------------------------*/
6119                 /* goto Statement              */
6120                 /*----------------------------*/
6121         case GOTO:
6122                 fprintf(outfile,"GOTO (%p) \n",tree);
6123                 ast_print(tree->left,outfile,indent+2);
6124                 fprintf(outfile,"\n");
6125                 return ;
6126                 /*------------------------------------------------------------------*/
6127                 /*----------------------------*/
6128                 /* for Statement              */
6129                 /*----------------------------*/
6130         case FOR:
6131                 fprintf(outfile,"FOR (%p) \n",tree);
6132                 if (AST_FOR( tree, initExpr)) {
6133                         INDENT(indent+2,outfile);
6134                         fprintf(outfile,"INIT EXPR ");
6135                         ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6136                 }
6137                 if (AST_FOR( tree, condExpr)) {
6138                         INDENT(indent+2,outfile);
6139                         fprintf(outfile,"COND EXPR ");
6140                         ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6141                 }
6142                 if (AST_FOR( tree, loopExpr)) {
6143                         INDENT(indent+2,outfile);
6144                         fprintf(outfile,"LOOP EXPR ");
6145                         ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6146                 }
6147                 fprintf(outfile,"FOR LOOP BODY \n");
6148                 ast_print(tree->left,outfile,indent+2);
6149                 return ;
6150         case CRITICAL:
6151                 fprintf(outfile,"CRITICAL (%p) \n",tree);
6152                 ast_print(tree->left,outfile,indent+2);
6153         default:
6154             return ;
6155         }
6156 }
6157
6158 void PA(ast *t)
6159 {
6160         ast_print(t,stdout,0);
6161 }
6162
6163
6164
6165 /*-----------------------------------------------------------------*/
6166 /* astErrors : returns non-zero if errors present in tree          */
6167 /*-----------------------------------------------------------------*/
6168 int astErrors(ast *t)
6169 {
6170   int errors=0;
6171   
6172   if (t)
6173     {
6174       if (t->isError)
6175         errors++;
6176   
6177       if (t->type == EX_VALUE
6178           && t->opval.val->sym
6179           && t->opval.val->sym->undefined)
6180         errors++;
6181
6182       errors += astErrors(t->left);
6183       errors += astErrors(t->right);
6184     }
6185     
6186   return errors;
6187 }