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