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