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