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