* src/SDCCicode.c (geniCodeParms),
[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       tree->type = EX_VALUE;
3721       SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
3722       tree->opval.val = constVal (buffer);
3723       tree->right = tree->left = NULL;
3724       TETYPE (tree) = getSpec (TTYPE (tree) =
3725                                tree->opval.val->type);
3726       return tree;
3727
3728       /*------------------------------------------------------------------*/
3729       /*----------------------------*/
3730       /*             typeof         */
3731       /*----------------------------*/
3732     case TYPEOF:
3733         /* return typeof enum value */
3734         tree->type = EX_VALUE;
3735         {
3736             int typeofv = 0;
3737             if (IS_SPEC(tree->right->ftype)) {
3738                 switch (SPEC_NOUN(tree->right->ftype)) {
3739                 case V_INT:
3740                     if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3741                     else typeofv = TYPEOF_INT;
3742                     break;
3743                 case V_FLOAT:
3744                     typeofv = TYPEOF_FLOAT;
3745                     break;
3746                 case V_CHAR:
3747                     typeofv = TYPEOF_CHAR;
3748                     break;
3749                 case V_VOID:
3750                     typeofv = TYPEOF_VOID;
3751                     break;
3752                 case V_STRUCT:
3753                     typeofv = TYPEOF_STRUCT;
3754                     break;
3755                 case V_BITFIELD:
3756                     typeofv = TYPEOF_BITFIELD;
3757                     break;
3758                 case V_BIT:
3759                     typeofv = TYPEOF_BIT;
3760                     break;
3761                 case V_SBIT:
3762                     typeofv = TYPEOF_SBIT;
3763                     break;
3764                 default:
3765                     break;
3766                 }
3767             } else {
3768                 switch (DCL_TYPE(tree->right->ftype)) {
3769                 case POINTER:
3770                     typeofv = TYPEOF_POINTER;
3771                     break;
3772                 case FPOINTER:
3773                     typeofv = TYPEOF_FPOINTER;
3774                     break;
3775                 case CPOINTER:
3776                     typeofv = TYPEOF_CPOINTER;
3777                     break;
3778                 case GPOINTER:
3779                     typeofv = TYPEOF_GPOINTER;
3780                     break;
3781                 case PPOINTER:
3782                     typeofv = TYPEOF_PPOINTER;
3783                     break;
3784                 case IPOINTER:
3785                     typeofv = TYPEOF_IPOINTER;
3786                     break;
3787                 case ARRAY:
3788                     typeofv = TYPEOF_ARRAY;
3789                     break;
3790                 case FUNCTION:
3791                     typeofv = TYPEOF_FUNCTION;
3792                     break;
3793                 default:
3794                     break;
3795                 }
3796             }
3797             SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3798             tree->opval.val = constVal (buffer);
3799             tree->right = tree->left = NULL;
3800             TETYPE (tree) = getSpec (TTYPE (tree) =
3801                                      tree->opval.val->type);
3802         }
3803         return tree;
3804       /*------------------------------------------------------------------*/
3805       /*----------------------------*/
3806       /* conditional operator  '?'  */
3807       /*----------------------------*/
3808     case '?':
3809       /* the type is value of the colon operator (on the right) */
3810       assert (IS_COLON_OP (tree->right));
3811       /* if already known then replace the tree : optimizer will do it
3812          but faster to do it here */
3813       if (IS_LITERAL (LTYPE (tree)))
3814         {
3815           if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
3816             return decorateType (tree->right->left, resultTypeProp);
3817           else
3818             return decorateType (tree->right->right, resultTypeProp);
3819         }
3820       else
3821         {
3822           tree->right = decorateType (tree->right, resultTypeProp);
3823           TTYPE (tree) = RTYPE (tree);
3824           TETYPE (tree) = getSpec (TTYPE (tree));
3825         }
3826       return tree;
3827
3828     case ':':
3829       /* if they don't match we have a problem */
3830       if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3831         {
3832           werror (E_TYPE_MISMATCH, "conditional operator", " ");
3833           goto errorTreeReturn;
3834         }
3835
3836       TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
3837       TETYPE (tree) = getSpec (TTYPE (tree));
3838       return tree;
3839
3840
3841 #if 0 // assignment operators are converted by the parser
3842       /*------------------------------------------------------------------*/
3843       /*----------------------------*/
3844       /*    assignment operators    */
3845       /*----------------------------*/
3846     case MUL_ASSIGN:
3847     case DIV_ASSIGN:
3848       /* for these it must be both must be integral */
3849       if (!IS_ARITHMETIC (LTYPE (tree)) ||
3850           !IS_ARITHMETIC (RTYPE (tree)))
3851         {
3852           werror (E_OPS_INTEGRAL);
3853           goto errorTreeReturn;
3854         }
3855       RRVAL (tree) = 1;
3856       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3857
3858       if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3859         werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3860
3861       if (LRVAL (tree))
3862         {
3863           werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3864           goto errorTreeReturn;
3865         }
3866       LLVAL (tree) = 1;
3867
3868       return tree;
3869
3870     case AND_ASSIGN:
3871     case OR_ASSIGN:
3872     case XOR_ASSIGN:
3873     case RIGHT_ASSIGN:
3874     case LEFT_ASSIGN:
3875       /* for these it must be both must be integral */
3876       if (!IS_INTEGRAL (LTYPE (tree)) ||
3877           !IS_INTEGRAL (RTYPE (tree)))
3878         {
3879           werror (E_OPS_INTEGRAL);
3880           goto errorTreeReturn;
3881         }
3882       RRVAL (tree) = 1;
3883       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3884
3885       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3886         werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3887
3888       if (LRVAL (tree))
3889         {
3890           werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3891           goto errorTreeReturn;
3892         }
3893       LLVAL (tree) = 1;
3894
3895       return tree;
3896
3897       /*------------------------------------------------------------------*/
3898       /*----------------------------*/
3899       /*    -= operator             */
3900       /*----------------------------*/
3901     case SUB_ASSIGN:
3902       if (!(IS_PTR (LTYPE (tree)) ||
3903             IS_ARITHMETIC (LTYPE (tree))))
3904         {
3905           werror (E_PLUS_INVALID, "-=");
3906           goto errorTreeReturn;
3907         }
3908
3909       if (!(IS_PTR (RTYPE (tree)) ||
3910             IS_ARITHMETIC (RTYPE (tree))))
3911         {
3912           werror (E_PLUS_INVALID, "-=");
3913           goto errorTreeReturn;
3914         }
3915       RRVAL (tree) = 1;
3916       TETYPE (tree) = getSpec (TTYPE (tree) =
3917                                computeType (LTYPE (tree),
3918                                             RTYPE (tree),
3919                                             FALSE));
3920
3921       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3922         werror (E_CODE_WRITE, "-=");
3923
3924       if (LRVAL (tree))
3925         {
3926           werror (E_LVALUE_REQUIRED, "-=");
3927           goto errorTreeReturn;
3928         }
3929       LLVAL (tree) = 1;
3930
3931       return tree;
3932
3933       /*------------------------------------------------------------------*/
3934       /*----------------------------*/
3935       /*          += operator       */
3936       /*----------------------------*/
3937     case ADD_ASSIGN:
3938       /* this is not a unary operation */
3939       /* if both pointers then problem */
3940       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3941         {
3942           werror (E_PTR_PLUS_PTR);
3943           goto errorTreeReturn;
3944         }
3945
3946       if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3947         {
3948           werror (E_PLUS_INVALID, "+=");
3949           goto errorTreeReturn;
3950         }
3951
3952       if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3953         {
3954           werror (E_PLUS_INVALID, "+=");
3955           goto errorTreeReturn;
3956         }
3957       RRVAL (tree) = 1;
3958       TETYPE (tree) = getSpec (TTYPE (tree) =
3959                                computeType (LTYPE (tree),
3960                                             RTYPE (tree),
3961                                             FALSE));
3962
3963       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3964         werror (E_CODE_WRITE, "+=");
3965
3966       if (LRVAL (tree))
3967         {
3968           werror (E_LVALUE_REQUIRED, "+=");
3969           goto errorTreeReturn;
3970         }
3971
3972       tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_CHECK);
3973       tree->opval.op = '=';
3974
3975       return tree;
3976 #endif
3977
3978       /*------------------------------------------------------------------*/
3979       /*----------------------------*/
3980       /*      straight assignemnt   */
3981       /*----------------------------*/
3982     case '=':
3983       /* cannot be an aggregate */
3984       if (IS_AGGREGATE (LTYPE (tree)))
3985         {
3986           werror (E_AGGR_ASSIGN);
3987           goto errorTreeReturn;
3988         }
3989
3990       /* they should either match or be castable */
3991       if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3992         {
3993           werror (E_TYPE_MISMATCH, "assignment", " ");
3994           printFromToType(RTYPE(tree),LTYPE(tree));
3995         }
3996
3997       /* if the left side of the tree is of type void
3998          then report error */
3999       if (IS_VOID (LTYPE (tree)))
4000         {
4001           werror (E_CAST_ZERO);
4002           printFromToType(RTYPE(tree), LTYPE(tree));
4003         }
4004
4005       TETYPE (tree) = getSpec (TTYPE (tree) =
4006                                LTYPE (tree));
4007       RRVAL (tree) = 1;
4008       LLVAL (tree) = 1;
4009       if (!tree->initMode ) {
4010         if (IS_CONSTANT(LTYPE(tree)))
4011           werror (E_CODE_WRITE, "=");
4012       }
4013       if (LRVAL (tree))
4014         {
4015           werror (E_LVALUE_REQUIRED, "=");
4016           goto errorTreeReturn;
4017         }
4018
4019       return tree;
4020
4021       /*------------------------------------------------------------------*/
4022       /*----------------------------*/
4023       /*      comma operator        */
4024       /*----------------------------*/
4025     case ',':
4026       TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4027       return tree;
4028
4029       /*------------------------------------------------------------------*/
4030       /*----------------------------*/
4031       /*       function call        */
4032       /*----------------------------*/
4033     case CALL:
4034       
4035       /* undo any explicit pointer derefernce; PCALL will handle it instead */
4036       if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4037         {
4038           if (tree->left->opval.op == '*' && !tree->left->right)
4039             tree->left = tree->left->left;
4040         }
4041
4042       /* require a function or pointer to function */
4043       if (!IS_FUNC (LTYPE (tree))
4044           && !(IS_CODEPTR (LTYPE (tree)) && IS_FUNC (LTYPE (tree)->next)))
4045         {
4046           werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4047           goto errorTreeReturn;
4048         }
4049               
4050       parmNumber = 1;
4051
4052       if (processParms (tree->left,
4053                         IS_CODEPTR(LTYPE(tree)) ?
4054                           FUNC_ARGS(tree->left->ftype->next)
4055                           : FUNC_ARGS(tree->left->ftype),
4056                         tree->right, &parmNumber, TRUE)) {
4057         goto errorTreeReturn;
4058       }
4059
4060       if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) && 
4061           !IFFUNC_ISBUILTIN(LTYPE(tree)))
4062         {
4063           reverseParms (tree->right);
4064         }
4065
4066       if (IS_CODEPTR(LTYPE(tree))) {
4067         TTYPE(tree) = LTYPE(tree)->next->next;
4068       } else {
4069         TTYPE(tree) = LTYPE(tree)->next;
4070       }
4071       TETYPE (tree) = getSpec (TTYPE (tree));
4072       return tree;
4073
4074       /*------------------------------------------------------------------*/
4075       /*----------------------------*/
4076       /*     return statement       */
4077       /*----------------------------*/
4078     case RETURN:
4079       if (!tree->right)
4080         goto voidcheck;
4081
4082       if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4083         {
4084           werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4085           printFromToType (RTYPE(tree), currFunc->type->next);
4086           goto errorTreeReturn;
4087         }
4088
4089       if (IS_VOID (currFunc->type->next)
4090           && tree->right &&
4091           !IS_VOID (RTYPE (tree)))
4092         {
4093           werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4094           goto errorTreeReturn;
4095         }
4096
4097       /* if there is going to be a casting required then add it */
4098       if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4099         {
4100           tree->right =
4101             decorateType (newNode (CAST,
4102                           newAst_LINK (copyLinkChain (currFunc->type->next)),
4103                                         tree->right),
4104                           RESULT_CHECK);
4105         }
4106
4107       RRVAL (tree) = 1;
4108       return tree;
4109
4110     voidcheck:
4111
4112       if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4113         {
4114           werror (W_VOID_FUNC, currFunc->name);
4115           goto errorTreeReturn;
4116         }
4117
4118       TTYPE (tree) = TETYPE (tree) = NULL;
4119       return tree;
4120
4121       /*------------------------------------------------------------------*/
4122       /*----------------------------*/
4123       /*     switch statement       */
4124       /*----------------------------*/
4125     case SWITCH:
4126       /* the switch value must be an integer */
4127       if (!IS_INTEGRAL (LTYPE (tree)))
4128         {
4129           werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4130           goto errorTreeReturn;
4131         }
4132       LRVAL (tree) = 1;
4133       TTYPE (tree) = TETYPE (tree) = NULL;
4134       return tree;
4135
4136       /*------------------------------------------------------------------*/
4137       /*----------------------------*/
4138       /* ifx Statement              */
4139       /*----------------------------*/
4140     case IFX:
4141       tree->left = backPatchLabels (tree->left,
4142                                     tree->trueLabel,
4143                                     tree->falseLabel);
4144       TTYPE (tree) = TETYPE (tree) = NULL;
4145       return tree;
4146
4147       /*------------------------------------------------------------------*/
4148       /*----------------------------*/
4149       /* for Statement              */
4150       /*----------------------------*/
4151     case FOR:
4152
4153       decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_CHECK);
4154       decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_CHECK);
4155       decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_CHECK);
4156
4157       /* if the for loop is reversible then
4158          reverse it otherwise do what we normally
4159          do */
4160       {
4161         symbol *sym;
4162         ast *init, *end;
4163
4164         if (isLoopReversible (tree, &sym, &init, &end))
4165           return reverseLoop (tree, sym, init, end);
4166         else
4167           return decorateType (createFor (AST_FOR (tree, trueLabel),
4168                                           AST_FOR (tree, continueLabel),
4169                                           AST_FOR (tree, falseLabel),
4170                                           AST_FOR (tree, condLabel),
4171                                           AST_FOR (tree, initExpr),
4172                                           AST_FOR (tree, condExpr),
4173                                           AST_FOR (tree, loopExpr),
4174                                           tree->left), RESULT_CHECK);
4175       }
4176     case PARAM:
4177       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4178               "node PARAM shouldn't be processed here");
4179               /* but in processParams() */
4180       return tree;
4181     default:
4182       TTYPE (tree) = TETYPE (tree) = NULL;
4183       return tree;
4184     }
4185
4186   /* some error found this tree will be killed */
4187 errorTreeReturn:
4188   TTYPE (tree) = TETYPE (tree) = newCharLink ();
4189   tree->opval.op = NULLOP;
4190   tree->isError = 1;
4191
4192   return tree;
4193 }
4194
4195 /*-----------------------------------------------------------------*/
4196 /* sizeofOp - processes size of operation                          */
4197 /*-----------------------------------------------------------------*/
4198 value *
4199 sizeofOp (sym_link * type)
4200 {
4201   char buff[10];
4202
4203   /* make sure the type is complete and sane */
4204   checkTypeSanity(type, "(sizeof)");
4205
4206   /* get the size and convert it to character  */
4207   SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
4208
4209   /* now convert into value  */
4210   return constVal (buff);
4211 }
4212
4213
4214 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4215 #define IS_OR(ex)  (ex->type == EX_OP && ex->opval.op == OR_OP )
4216 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4217 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4218 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4219 #define IS_LT(ex)  (ex->type == EX_OP && ex->opval.op == '<' )
4220 #define IS_GT(ex)  (ex->type == EX_OP && ex->opval.op == '>')
4221
4222 /*-----------------------------------------------------------------*/
4223 /* backPatchLabels - change and or not operators to flow control    */
4224 /*-----------------------------------------------------------------*/
4225 ast *
4226 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4227 {
4228
4229   if (!tree)
4230     return NULL;
4231
4232   if (!(IS_ANDORNOT (tree)))
4233     return tree;
4234
4235   /* if this an and */
4236   if (IS_AND (tree))
4237     {
4238       static int localLbl = 0;
4239       symbol *localLabel;
4240
4241       SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4242       localLabel = newSymbol (buffer, NestLevel);
4243
4244       tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4245
4246       /* if left is already a IFX then just change the if true label in that */
4247       if (!IS_IFX (tree->left))
4248         tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4249
4250       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4251       /* right is a IFX then just join */
4252       if (IS_IFX (tree->right))
4253         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4254
4255       tree->right = createLabel (localLabel, tree->right);
4256       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4257
4258       return newNode (NULLOP, tree->left, tree->right);
4259     }
4260
4261   /* if this is an or operation */
4262   if (IS_OR (tree))
4263     {
4264       static int localLbl = 0;
4265       symbol *localLabel;
4266
4267       SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4268       localLabel = newSymbol (buffer, NestLevel);
4269
4270       tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4271
4272       /* if left is already a IFX then just change the if true label in that */
4273       if (!IS_IFX (tree->left))
4274         tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4275
4276       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4277       /* right is a IFX then just join */
4278       if (IS_IFX (tree->right))
4279         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4280
4281       tree->right = createLabel (localLabel, tree->right);
4282       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4283
4284       return newNode (NULLOP, tree->left, tree->right);
4285     }
4286
4287   /* change not */
4288   if (IS_NOT (tree))
4289     {
4290       int wasnot = IS_NOT (tree->left);
4291       tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4292
4293       /* if the left is already a IFX */
4294       if (!IS_IFX (tree->left))
4295         tree->left = newNode (IFX, tree->left, NULL);
4296
4297       if (wasnot)
4298         {
4299           tree->left->trueLabel = trueLabel;
4300           tree->left->falseLabel = falseLabel;
4301         }
4302       else
4303         {
4304           tree->left->trueLabel = falseLabel;
4305           tree->left->falseLabel = trueLabel;
4306         }
4307       return tree->left;
4308     }
4309
4310   if (IS_IFX (tree))
4311     {
4312       tree->trueLabel = trueLabel;
4313       tree->falseLabel = falseLabel;
4314     }
4315
4316   return tree;
4317 }
4318
4319
4320 /*-----------------------------------------------------------------*/
4321 /* createBlock - create expression tree for block                  */
4322 /*-----------------------------------------------------------------*/
4323 ast *
4324 createBlock (symbol * decl, ast * body)
4325 {
4326   ast *ex;
4327
4328   /* if the block has nothing */
4329   if (!body && !decl)
4330     return NULL;
4331
4332   ex = newNode (BLOCK, NULL, body);
4333   ex->values.sym = decl;
4334   
4335   ex->right = ex->right;
4336   ex->level++;
4337   ex->lineno = 0;
4338   return ex;
4339 }
4340
4341 /*-----------------------------------------------------------------*/
4342 /* createLabel - creates the expression tree for labels            */
4343 /*-----------------------------------------------------------------*/
4344 ast *
4345 createLabel (symbol * label, ast * stmnt)
4346 {
4347   symbol *csym;
4348   char name[SDCC_NAME_MAX + 1];
4349   ast *rValue;
4350
4351   /* must create fresh symbol if the symbol name  */
4352   /* exists in the symbol table, since there can  */
4353   /* be a variable with the same name as the labl */
4354   if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4355       (csym->level == label->level))
4356     label = newSymbol (label->name, label->level);
4357
4358   /* change the name before putting it in add _ */
4359   SNPRINTF(name, sizeof(name), "%s", label->name);
4360
4361   /* put the label in the LabelSymbol table    */
4362   /* but first check if a label of the same    */
4363   /* name exists                               */
4364   if ((csym = findSym (LabelTab, NULL, name)))
4365     werror (E_DUPLICATE_LABEL, label->name);
4366   else
4367     addSym (LabelTab, label, name, label->level, 0, 0);
4368
4369   label->islbl = 1;
4370   label->key = labelKey++;
4371   rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4372   rValue->lineno = 0;
4373
4374   return rValue;
4375 }
4376
4377 /*-----------------------------------------------------------------*/
4378 /* createCase - generates the parsetree for a case statement       */
4379 /*-----------------------------------------------------------------*/
4380 ast *
4381 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4382 {
4383   char caseLbl[SDCC_NAME_MAX + 1];
4384   ast *rexpr;
4385   value *val;
4386
4387   /* if the switch statement does not exist */
4388   /* then case is out of context            */
4389   if (!swStat)
4390     {
4391       werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4392       return NULL;
4393     }
4394
4395   caseVal = decorateType (resolveSymbols (caseVal), RESULT_CHECK);
4396   /* if not a constant then error  */
4397   if (!IS_LITERAL (caseVal->ftype))
4398     {
4399       werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4400       return NULL;
4401     }
4402
4403   /* if not a integer than error */
4404   if (!IS_INTEGRAL (caseVal->ftype))
4405     {
4406       werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4407       return NULL;
4408     }
4409
4410   /* find the end of the switch values chain   */
4411   if (!(val = swStat->values.switchVals.swVals))
4412     swStat->values.switchVals.swVals = caseVal->opval.val;
4413   else
4414     {
4415       /* also order the cases according to value */
4416       value *pval = NULL;
4417       int cVal = (int) floatFromVal (caseVal->opval.val);
4418       while (val && (int) floatFromVal (val) < cVal)
4419         {
4420           pval = val;
4421           val = val->next;
4422         }
4423
4424       /* if we reached the end then */
4425       if (!val)
4426         {
4427           pval->next = caseVal->opval.val;
4428         }
4429       else if ((int) floatFromVal (val) == cVal)
4430         {
4431           werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4432                     "case");
4433           return NULL;
4434         }
4435       else
4436         {
4437           /* we found a value greater than */
4438           /* the current value we must add this */
4439           /* before the value */
4440           caseVal->opval.val->next = val;
4441
4442           /* if this was the first in chain */
4443           if (swStat->values.switchVals.swVals == val)
4444             swStat->values.switchVals.swVals =
4445               caseVal->opval.val;
4446           else
4447             pval->next = caseVal->opval.val;
4448         }
4449
4450     }
4451
4452   /* create the case label   */
4453   SNPRINTF(caseLbl, sizeof(caseLbl), 
4454            "_case_%d_%d",
4455            swStat->values.switchVals.swNum,
4456            (int) floatFromVal (caseVal->opval.val));
4457
4458   rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4459   rexpr->lineno = 0;
4460   return rexpr;
4461 }
4462
4463 /*-----------------------------------------------------------------*/
4464 /* createDefault - creates the parse tree for the default statement */
4465 /*-----------------------------------------------------------------*/
4466 ast *
4467 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4468 {
4469   char defLbl[SDCC_NAME_MAX + 1];
4470
4471   /* if the switch statement does not exist */
4472   /* then case is out of context            */
4473   if (!swStat)
4474     {
4475       werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4476       return NULL;
4477     }
4478
4479   if (swStat->values.switchVals.swDefault)
4480     {
4481       werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4482                 "default");
4483       return NULL;
4484     }
4485
4486   /* turn on the default flag   */
4487   swStat->values.switchVals.swDefault = 1;
4488
4489   /* create the label  */
4490   SNPRINTF (defLbl, sizeof(defLbl),
4491             "_default_%d", swStat->values.switchVals.swNum);
4492   return createLabel (newSymbol (defLbl, 0), stmnt);
4493 }
4494
4495 /*-----------------------------------------------------------------*/
4496 /* createIf - creates the parsetree for the if statement           */
4497 /*-----------------------------------------------------------------*/
4498 ast *
4499 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4500 {
4501   static int Lblnum = 0;
4502   ast *ifTree;
4503   symbol *ifTrue, *ifFalse, *ifEnd;
4504
4505   /* if neither exists */
4506   if (!elseBody && !ifBody) {
4507     // if there are no side effects (i++, j() etc)
4508     if (!hasSEFcalls(condAst)) {
4509       return condAst;
4510     }
4511   }
4512
4513   /* create the labels */
4514   SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4515   ifFalse = newSymbol (buffer, NestLevel);
4516   /* if no else body then end == false */
4517   if (!elseBody)
4518     ifEnd = ifFalse;
4519   else
4520     {
4521       SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4522       ifEnd = newSymbol (buffer, NestLevel);
4523     }
4524
4525   SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4526   ifTrue = newSymbol (buffer, NestLevel);
4527
4528   Lblnum++;
4529
4530   /* attach the ifTrue label to the top of it body */
4531   ifBody = createLabel (ifTrue, ifBody);
4532   /* attach a goto end to the ifBody if else is present */
4533   if (elseBody)
4534     {
4535       ifBody = newNode (NULLOP, ifBody,
4536                         newNode (GOTO,
4537                                  newAst_VALUE (symbolVal (ifEnd)),
4538                                  NULL));
4539       /* put the elseLabel on the else body */
4540       elseBody = createLabel (ifFalse, elseBody);
4541       /* out the end at the end of the body */
4542       elseBody = newNode (NULLOP,
4543                           elseBody,
4544                           createLabel (ifEnd, NULL));
4545     }
4546   else
4547     {
4548       ifBody = newNode (NULLOP, ifBody,
4549                         createLabel (ifFalse, NULL));
4550     }
4551   condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4552   if (IS_IFX (condAst))
4553     ifTree = condAst;
4554   else
4555     ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4556
4557   return newNode (NULLOP, ifTree,
4558                   newNode (NULLOP, ifBody, elseBody));
4559
4560 }
4561
4562 /*-----------------------------------------------------------------*/
4563 /* createDo - creates parse tree for do                            */
4564 /*        _dobody_n:                                               */
4565 /*            statements                                           */
4566 /*        _docontinue_n:                                           */
4567 /*            condition_expression +-> trueLabel -> _dobody_n      */
4568 /*                                 |                               */
4569 /*                                 +-> falseLabel-> _dobreak_n     */
4570 /*        _dobreak_n:                                              */
4571 /*-----------------------------------------------------------------*/
4572 ast *
4573 createDo (symbol * trueLabel, symbol * continueLabel,
4574           symbol * falseLabel, ast * condAst, ast * doBody)
4575 {
4576   ast *doTree;
4577
4578
4579   /* if the body does not exist then it is simple */
4580   if (!doBody)
4581     {
4582       condAst = backPatchLabels (condAst, continueLabel, NULL);
4583       doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4584                 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4585       doTree->trueLabel = continueLabel;
4586       doTree->falseLabel = NULL;
4587       return doTree;
4588     }
4589
4590   /* otherwise we have a body */
4591   condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4592
4593   /* attach the body label to the top */
4594   doBody = createLabel (trueLabel, doBody);
4595   /* attach the continue label to end of body */
4596   doBody = newNode (NULLOP, doBody,
4597                     createLabel (continueLabel, NULL));
4598
4599   /* now put the break label at the end */
4600   if (IS_IFX (condAst))
4601     doTree = condAst;
4602   else
4603     doTree = newIfxNode (condAst, trueLabel, falseLabel);
4604
4605   doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4606
4607   /* putting it together */
4608   return newNode (NULLOP, doBody, doTree);
4609 }
4610
4611 /*-----------------------------------------------------------------*/
4612 /* createFor - creates parse tree for 'for' statement              */
4613 /*        initExpr                                                 */
4614 /*   _forcond_n:                                                   */
4615 /*        condExpr  +-> trueLabel -> _forbody_n                    */
4616 /*                  |                                              */
4617 /*                  +-> falseLabel-> _forbreak_n                   */
4618 /*   _forbody_n:                                                   */
4619 /*        statements                                               */
4620 /*   _forcontinue_n:                                               */
4621 /*        loopExpr                                                 */
4622 /*        goto _forcond_n ;                                        */
4623 /*   _forbreak_n:                                                  */
4624 /*-----------------------------------------------------------------*/
4625 ast *
4626 createFor (symbol * trueLabel, symbol * continueLabel,
4627            symbol * falseLabel, symbol * condLabel,
4628            ast * initExpr, ast * condExpr, ast * loopExpr,
4629            ast * forBody)
4630 {
4631   ast *forTree;
4632
4633   /* if loopexpression not present then we can generate it */
4634   /* the same way as a while */
4635   if (!loopExpr)
4636     return newNode (NULLOP, initExpr,
4637                     createWhile (trueLabel, continueLabel,
4638                                  falseLabel, condExpr, forBody));
4639   /* vanilla for statement */
4640   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4641
4642   if (condExpr && !IS_IFX (condExpr))
4643     condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4644
4645
4646   /* attach condition label to condition */
4647   condExpr = createLabel (condLabel, condExpr);
4648
4649   /* attach body label to body */
4650   forBody = createLabel (trueLabel, forBody);
4651
4652   /* attach continue to forLoop expression & attach */
4653   /* goto the forcond @ and of loopExpression       */
4654   loopExpr = createLabel (continueLabel,
4655                           newNode (NULLOP,
4656                                    loopExpr,
4657                                    newNode (GOTO,
4658                                        newAst_VALUE (symbolVal (condLabel)),
4659                                             NULL)));
4660   /* now start putting them together */
4661   forTree = newNode (NULLOP, initExpr, condExpr);
4662   forTree = newNode (NULLOP, forTree, forBody);
4663   forTree = newNode (NULLOP, forTree, loopExpr);
4664   /* finally add the break label */
4665   forTree = newNode (NULLOP, forTree,
4666                      createLabel (falseLabel, NULL));
4667   return forTree;
4668 }
4669
4670 /*-----------------------------------------------------------------*/
4671 /* createWhile - creates parse tree for while statement            */
4672 /*               the while statement will be created as follows    */
4673 /*                                                                 */
4674 /*      _while_continue_n:                                         */
4675 /*            condition_expression +-> trueLabel -> _while_boby_n  */
4676 /*                                 |                               */
4677 /*                                 +-> falseLabel -> _while_break_n */
4678 /*      _while_body_n:                                             */
4679 /*            statements                                           */
4680 /*            goto _while_continue_n                               */
4681 /*      _while_break_n:                                            */
4682 /*-----------------------------------------------------------------*/
4683 ast *
4684 createWhile (symbol * trueLabel, symbol * continueLabel,
4685              symbol * falseLabel, ast * condExpr, ast * whileBody)
4686 {
4687   ast *whileTree;
4688
4689   /* put the continue label */
4690   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4691   condExpr = createLabel (continueLabel, condExpr);
4692   condExpr->lineno = 0;
4693
4694   /* put the body label in front of the body */
4695   whileBody = createLabel (trueLabel, whileBody);
4696   whileBody->lineno = 0;
4697   /* put a jump to continue at the end of the body */
4698   /* and put break label at the end of the body */
4699   whileBody = newNode (NULLOP,
4700                        whileBody,
4701                        newNode (GOTO,
4702                                 newAst_VALUE (symbolVal (continueLabel)),
4703                                 createLabel (falseLabel, NULL)));
4704
4705   /* put it all together */
4706   if (IS_IFX (condExpr))
4707     whileTree = condExpr;
4708   else
4709     {
4710       whileTree = newNode (IFX, condExpr, NULL);
4711       /* put the true & false labels in place */
4712       whileTree->trueLabel = trueLabel;
4713       whileTree->falseLabel = falseLabel;
4714     }
4715
4716   return newNode (NULLOP, whileTree, whileBody);
4717 }
4718
4719 /*-----------------------------------------------------------------*/
4720 /* optimizeGetHbit - get highest order bit of the expression       */
4721 /*-----------------------------------------------------------------*/
4722 ast *
4723 optimizeGetHbit (ast * tree)
4724 {
4725   int i, j;
4726   /* if this is not a bit and */
4727   if (!IS_BITAND (tree))
4728     return tree;
4729
4730   /* will look for tree of the form
4731      ( expr >> ((sizeof expr) -1) ) & 1 */
4732   if (!IS_AST_LIT_VALUE (tree->right))
4733     return tree;
4734
4735   if (AST_LIT_VALUE (tree->right) != 1)
4736     return tree;
4737
4738   if (!IS_RIGHT_OP (tree->left))
4739     return tree;
4740
4741   if (!IS_AST_LIT_VALUE (tree->left->right))
4742     return tree;
4743
4744   if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4745       (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4746     return tree;
4747       
4748   /* make sure the port supports GETHBIT */
4749   if (port->hasExtBitOp
4750       && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4751     return tree;
4752
4753   return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_CHECK);
4754
4755 }
4756
4757 /*-----------------------------------------------------------------*/
4758 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry     */
4759 /*-----------------------------------------------------------------*/
4760 ast *
4761 optimizeRRCRLC (ast * root)
4762 {
4763   /* will look for trees of the form
4764      (?expr << 1) | (?expr >> 7) or
4765      (?expr >> 7) | (?expr << 1) will make that
4766      into a RLC : operation ..
4767      Will also look for
4768      (?expr >> 1) | (?expr << 7) or
4769      (?expr << 7) | (?expr >> 1) will make that
4770      into a RRC operation
4771      note : by 7 I mean (number of bits required to hold the
4772      variable -1 ) */
4773   /* if the root operations is not a | operation the not */
4774   if (!IS_BITOR (root))
4775     return root;
4776
4777   /* I have to think of a better way to match patterns this sucks */
4778   /* that aside let start looking for the first case : I use a the
4779      negative check a lot to improve the efficiency */
4780   /* (?expr << 1) | (?expr >> 7) */
4781   if (IS_LEFT_OP (root->left) &&
4782       IS_RIGHT_OP (root->right))
4783     {
4784
4785       if (!SPEC_USIGN (TETYPE (root->left->left)))
4786         return root;
4787
4788       if (!IS_AST_LIT_VALUE (root->left->right) ||
4789           !IS_AST_LIT_VALUE (root->right->right))
4790         goto tryNext0;
4791
4792       /* make sure it is the same expression */
4793       if (!isAstEqual (root->left->left,
4794                        root->right->left))
4795         goto tryNext0;
4796
4797       if (AST_LIT_VALUE (root->left->right) != 1)
4798         goto tryNext0;
4799
4800       if (AST_LIT_VALUE (root->right->right) !=
4801           (getSize (TTYPE (root->left->left)) * 8 - 1))
4802         goto tryNext0;
4803
4804       /* make sure the port supports RLC */
4805       if (port->hasExtBitOp
4806           && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4807         return root;
4808
4809       /* whew got the first case : create the AST */
4810       return newNode (RLC, root->left->left, NULL);
4811     }
4812
4813 tryNext0:
4814   /* check for second case */
4815   /* (?expr >> 7) | (?expr << 1) */
4816   if (IS_LEFT_OP (root->right) &&
4817       IS_RIGHT_OP (root->left))
4818     {
4819
4820       if (!SPEC_USIGN (TETYPE (root->left->left)))
4821         return root;
4822
4823       if (!IS_AST_LIT_VALUE (root->left->right) ||
4824           !IS_AST_LIT_VALUE (root->right->right))
4825         goto tryNext1;
4826
4827       /* make sure it is the same symbol */
4828       if (!isAstEqual (root->left->left,
4829                        root->right->left))
4830         goto tryNext1;
4831
4832       if (AST_LIT_VALUE (root->right->right) != 1)
4833         goto tryNext1;
4834
4835       if (AST_LIT_VALUE (root->left->right) !=
4836           (getSize (TTYPE (root->left->left)) * 8 - 1))
4837         goto tryNext1;
4838
4839       /* make sure the port supports RLC */
4840       if (port->hasExtBitOp
4841           && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4842         return root;
4843
4844       /* whew got the first case : create the AST */
4845       return newNode (RLC, root->left->left, NULL);
4846
4847     }
4848
4849 tryNext1:
4850   /* third case for RRC */
4851   /*  (?symbol >> 1) | (?symbol << 7) */
4852   if (IS_LEFT_OP (root->right) &&
4853       IS_RIGHT_OP (root->left))
4854     {
4855
4856       if (!SPEC_USIGN (TETYPE (root->left->left)))
4857         return root;
4858
4859       if (!IS_AST_LIT_VALUE (root->left->right) ||
4860           !IS_AST_LIT_VALUE (root->right->right))
4861         goto tryNext2;
4862
4863       /* make sure it is the same symbol */
4864       if (!isAstEqual (root->left->left,
4865                        root->right->left))
4866         goto tryNext2;
4867
4868       if (AST_LIT_VALUE (root->left->right) != 1)
4869         goto tryNext2;
4870
4871       if (AST_LIT_VALUE (root->right->right) !=
4872           (getSize (TTYPE (root->left->left)) * 8 - 1))
4873         goto tryNext2;
4874
4875       /* make sure the port supports RRC */
4876       if (port->hasExtBitOp
4877           && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4878         return root;
4879
4880       /* whew got the first case : create the AST */
4881       return newNode (RRC, root->left->left, NULL);
4882
4883     }
4884 tryNext2:
4885   /* fourth and last case for now */
4886   /* (?symbol << 7) | (?symbol >> 1) */
4887   if (IS_RIGHT_OP (root->right) &&
4888       IS_LEFT_OP (root->left))
4889     {
4890
4891       if (!SPEC_USIGN (TETYPE (root->left->left)))
4892         return root;
4893
4894       if (!IS_AST_LIT_VALUE (root->left->right) ||
4895           !IS_AST_LIT_VALUE (root->right->right))
4896         return root;
4897
4898       /* make sure it is the same symbol */
4899       if (!isAstEqual (root->left->left,
4900                        root->right->left))
4901         return root;
4902
4903       if (AST_LIT_VALUE (root->right->right) != 1)
4904         return root;
4905
4906       if (AST_LIT_VALUE (root->left->right) !=
4907           (getSize (TTYPE (root->left->left)) * 8 - 1))
4908         return root;
4909
4910       /* make sure the port supports RRC */
4911       if (port->hasExtBitOp
4912           && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4913         return root;
4914
4915       /* whew got the first case : create the AST */
4916       return newNode (RRC, root->left->left, NULL);
4917
4918     }
4919
4920   /* not found return root */
4921   return root;
4922 }
4923
4924 /*-----------------------------------------------------------------*/
4925 /* optimizeSWAP :- optimize for nibble/byte/word swaps             */
4926 /*-----------------------------------------------------------------*/
4927 ast *
4928 optimizeSWAP (ast * root)
4929 {
4930   /* will look for trees of the form
4931      (?expr << 4) | (?expr >> 4) or
4932      (?expr >> 4) | (?expr << 4) will make that
4933      into a SWAP : operation ..
4934      note : by 4 I mean (number of bits required to hold the
4935      variable /2 ) */
4936   /* if the root operations is not a | operation the not */
4937   if (!IS_BITOR (root))
4938     return root;
4939
4940   /* (?expr << 4) | (?expr >> 4) */
4941   if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
4942       || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
4943     {
4944
4945       if (!SPEC_USIGN (TETYPE (root->left->left)))
4946         return root;
4947
4948       if (!IS_AST_LIT_VALUE (root->left->right) ||
4949           !IS_AST_LIT_VALUE (root->right->right))
4950         return root;
4951
4952       /* make sure it is the same expression */
4953       if (!isAstEqual (root->left->left,
4954                        root->right->left))
4955         return root;
4956
4957       if (AST_LIT_VALUE (root->left->right) !=
4958           (getSize (TTYPE (root->left->left)) * 4))
4959         return root;
4960
4961       if (AST_LIT_VALUE (root->right->right) !=
4962           (getSize (TTYPE (root->left->left)) * 4))
4963         return root;
4964
4965       /* make sure the port supports SWAP */
4966       if (port->hasExtBitOp
4967           && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
4968         return root;
4969
4970       /* found it : create the AST */
4971       return newNode (SWAP, root->left->left, NULL);
4972     }
4973
4974
4975   /* not found return root */
4976   return root;
4977 }
4978
4979 /*-----------------------------------------------------------------*/
4980 /* optimizeCompare - otimizes compares for bit variables     */
4981 /*-----------------------------------------------------------------*/
4982 static ast *
4983 optimizeCompare (ast * root)
4984 {
4985   ast *optExpr = NULL;
4986   value *vleft;
4987   value *vright;
4988   unsigned int litValue;
4989
4990   /* if nothing then return nothing */
4991   if (!root)
4992     return NULL;
4993
4994   /* if not a compare op then do leaves */
4995   if (!IS_COMPARE_OP (root))
4996     {
4997       root->left = optimizeCompare (root->left);
4998       root->right = optimizeCompare (root->right);
4999       return root;
5000     }
5001
5002   /* if left & right are the same then depending
5003      of the operation do */
5004   if (isAstEqual (root->left, root->right))
5005     {
5006       switch (root->opval.op)
5007         {
5008         case '>':
5009         case '<':
5010         case NE_OP:
5011           optExpr = newAst_VALUE (constVal ("0"));
5012           break;
5013         case GE_OP:
5014         case LE_OP:
5015         case EQ_OP:
5016           optExpr = newAst_VALUE (constVal ("1"));
5017           break;
5018         }
5019
5020       return decorateType (optExpr, RESULT_CHECK);
5021     }
5022
5023   vleft = (root->left->type == EX_VALUE ?
5024            root->left->opval.val : NULL);
5025
5026   vright = (root->right->type == EX_VALUE ?
5027             root->right->opval.val : NULL);
5028
5029   /* if left is a BITVAR in BITSPACE */
5030   /* and right is a LITERAL then opt- */
5031   /* imize else do nothing       */
5032   if (vleft && vright &&
5033       IS_BITVAR (vleft->etype) &&
5034       IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5035       IS_LITERAL (vright->etype))
5036     {
5037
5038       /* if right side > 1 then comparison may never succeed */
5039       if ((litValue = (int) floatFromVal (vright)) > 1)
5040         {
5041           werror (W_BAD_COMPARE);
5042           goto noOptimize;
5043         }
5044
5045       if (litValue)
5046         {
5047           switch (root->opval.op)
5048             {
5049             case '>':           /* bit value greater than 1 cannot be */
5050               werror (W_BAD_COMPARE);
5051               goto noOptimize;
5052               break;
5053
5054             case '<':           /* bit value < 1 means 0 */
5055             case NE_OP:
5056               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5057               break;
5058
5059             case LE_OP: /* bit value <= 1 means no check */
5060               optExpr = newAst_VALUE (vright);
5061               break;
5062
5063             case GE_OP: /* bit value >= 1 means only check for = */
5064             case EQ_OP:
5065               optExpr = newAst_VALUE (vleft);
5066               break;
5067             }
5068         }
5069       else
5070         {                       /* literal is zero */
5071           switch (root->opval.op)
5072             {
5073             case '<':           /* bit value < 0 cannot be */
5074               werror (W_BAD_COMPARE);
5075               goto noOptimize;
5076               break;
5077
5078             case '>':           /* bit value > 0 means 1 */
5079             case NE_OP:
5080               optExpr = newAst_VALUE (vleft);
5081               break;
5082
5083             case LE_OP: /* bit value <= 0 means no check */
5084             case GE_OP: /* bit value >= 0 means no check */
5085               werror (W_BAD_COMPARE);
5086               goto noOptimize;
5087               break;
5088
5089             case EQ_OP: /* bit == 0 means ! of bit */
5090               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5091               break;
5092             }
5093         }
5094       return decorateType (resolveSymbols (optExpr), RESULT_CHECK);
5095     }                           /* end-of-if of BITVAR */
5096
5097 noOptimize:
5098   return root;
5099 }
5100 /*-----------------------------------------------------------------*/
5101 /* addSymToBlock : adds the symbol to the first block we find      */
5102 /*-----------------------------------------------------------------*/
5103 void 
5104 addSymToBlock (symbol * sym, ast * tree)
5105 {
5106   /* reached end of tree or a leaf */
5107   if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5108     return;
5109
5110   /* found a block */
5111   if (IS_AST_OP (tree) &&
5112       tree->opval.op == BLOCK)
5113     {
5114
5115       symbol *lsym = copySymbol (sym);
5116
5117       lsym->next = AST_VALUES (tree, sym);
5118       AST_VALUES (tree, sym) = lsym;
5119       return;
5120     }
5121
5122   addSymToBlock (sym, tree->left);
5123   addSymToBlock (sym, tree->right);
5124 }
5125
5126 /*-----------------------------------------------------------------*/
5127 /* processRegParms - do processing for register parameters         */
5128 /*-----------------------------------------------------------------*/
5129 static void 
5130 processRegParms (value * args, ast * body)
5131 {
5132   while (args)
5133     {
5134       if (IS_REGPARM (args->etype))
5135         addSymToBlock (args->sym, body);
5136       args = args->next;
5137     }
5138 }
5139
5140 /*-----------------------------------------------------------------*/
5141 /* resetParmKey - resets the operandkeys for the symbols           */
5142 /*-----------------------------------------------------------------*/
5143 DEFSETFUNC (resetParmKey)
5144 {
5145   symbol *sym = item;
5146
5147   sym->key = 0;
5148   sym->defs = NULL;
5149   sym->uses = NULL;
5150   sym->remat = 0;
5151   return 1;
5152 }
5153
5154 /*-----------------------------------------------------------------*/
5155 /* createFunction - This is the key node that calls the iCode for  */
5156 /*                  generating the code for a function. Note code  */
5157 /*                  is generated function by function, later when  */
5158 /*                  add inter-procedural analysis this will change */
5159 /*-----------------------------------------------------------------*/
5160 ast *
5161 createFunction (symbol * name, ast * body)
5162 {
5163   ast *ex;
5164   symbol *csym;
5165   int stack = 0;
5166   sym_link *fetype;
5167   iCode *piCode = NULL;
5168
5169   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5170     fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5171
5172   /* if check function return 0 then some problem */
5173   if (checkFunction (name, NULL) == 0)
5174     return NULL;
5175
5176   /* create a dummy block if none exists */
5177   if (!body)
5178     body = newNode (BLOCK, NULL, NULL);
5179
5180   noLineno++;
5181
5182   /* check if the function name already in the symbol table */
5183   if ((csym = findSym (SymbolTab, NULL, name->name)))
5184     {
5185       name = csym;
5186       /* special case for compiler defined functions
5187          we need to add the name to the publics list : this
5188          actually means we are now compiling the compiler
5189          support routine */
5190       if (name->cdef)
5191         {
5192           addSet (&publics, name);
5193         }
5194     }
5195   else
5196     {
5197       addSymChain (name);
5198       allocVariables (name);
5199     }
5200   name->lastLine = mylineno;
5201   currFunc = name;
5202
5203   /* set the stack pointer */
5204   /* PENDING: check this for the mcs51 */
5205   stackPtr = -port->stack.direction * port->stack.call_overhead;
5206   if (IFFUNC_ISISR (name->type))
5207     stackPtr -= port->stack.direction * port->stack.isr_overhead;
5208   if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5209     stackPtr -= port->stack.direction * port->stack.reent_overhead;
5210
5211   xstackPtr = -port->stack.direction * port->stack.call_overhead;
5212
5213   fetype = getSpec (name->type);        /* get the specifier for the function */
5214   /* if this is a reentrant function then */
5215   if (IFFUNC_ISREENT (name->type))
5216     reentrant++;
5217
5218   allocParms (FUNC_ARGS(name->type));   /* allocate the parameters */
5219
5220   /* do processing for parameters that are passed in registers */
5221   processRegParms (FUNC_ARGS(name->type), body);
5222
5223   /* set the stack pointer */
5224   stackPtr = 0;
5225   xstackPtr = -1;
5226
5227   /* allocate & autoinit the block variables */
5228   processBlockVars (body, &stack, ALLOCATE);
5229
5230   /* save the stack information */
5231   if (options.useXstack)
5232     name->xstack = SPEC_STAK (fetype) = stack;
5233   else
5234     name->stack = SPEC_STAK (fetype) = stack;
5235
5236   /* name needs to be mangled */
5237   SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5238
5239   body = resolveSymbols (body); /* resolve the symbols */
5240   body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5241                                         
5242
5243   ex = newAst_VALUE (symbolVal (name)); /* create name */
5244   ex = newNode (FUNCTION, ex, body);
5245   ex->values.args = FUNC_ARGS(name->type);
5246   ex->decorated=1;
5247   if (options.dump_tree) PA(ex);
5248   if (fatalError)
5249     {
5250       werror (E_FUNC_NO_CODE, name->name);
5251       goto skipall;
5252     }
5253
5254   /* create the node & generate intermediate code */
5255   GcurMemmap = code;
5256   codeOutFile = code->oFile;
5257   piCode = iCodeFromAst (ex);
5258
5259   if (fatalError)
5260     {
5261       werror (E_FUNC_NO_CODE, name->name);
5262       goto skipall;
5263     }
5264
5265   eBBlockFromiCode (piCode);
5266
5267   /* if there are any statics then do them */
5268   if (staticAutos)
5269     {
5270       GcurMemmap = statsg;
5271       codeOutFile = statsg->oFile;
5272       eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_CHECK)));
5273       staticAutos = NULL;
5274     }
5275
5276 skipall:
5277
5278   /* dealloc the block variables */
5279   processBlockVars (body, &stack, DEALLOCATE);
5280   outputDebugStackSymbols();
5281   /* deallocate paramaters */
5282   deallocParms (FUNC_ARGS(name->type));
5283
5284   if (IFFUNC_ISREENT (name->type))
5285     reentrant--;
5286
5287   /* we are done freeup memory & cleanup */
5288   noLineno--;
5289   if (port->reset_labelKey) labelKey = 1;
5290   name->key = 0;
5291   FUNC_HASBODY(name->type) = 1;
5292   addSet (&operKeyReset, name);
5293   applyToSet (operKeyReset, resetParmKey);
5294
5295   if (options.debug)
5296     cdbStructBlock(1);
5297
5298   cleanUpLevel (LabelTab, 0);
5299   cleanUpBlock (StructTab, 1);
5300   cleanUpBlock (TypedefTab, 1);
5301
5302   xstack->syms = NULL;
5303   istack->syms = NULL;
5304   return NULL;
5305 }
5306
5307
5308 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5309 /*-----------------------------------------------------------------*/
5310 /* ast_print : prints the ast (for debugging purposes)             */
5311 /*-----------------------------------------------------------------*/
5312
5313 void ast_print (ast * tree, FILE *outfile, int indent)
5314 {
5315
5316         if (!tree) return ;
5317
5318         /* can print only decorated trees */
5319         if (!tree->decorated) return;
5320
5321         /* if any child is an error | this one is an error do nothing */
5322         if (tree->isError ||
5323             (tree->left && tree->left->isError) ||
5324             (tree->right && tree->right->isError)) {
5325                 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5326         }
5327
5328
5329         /* print the line          */
5330         /* if not block & function */
5331         if (tree->type == EX_OP &&
5332             (tree->opval.op != FUNCTION &&
5333              tree->opval.op != BLOCK &&
5334              tree->opval.op != NULLOP)) {
5335         }
5336
5337         if (tree->opval.op == FUNCTION) {
5338                 int arg=0;
5339                 value *args=FUNC_ARGS(tree->left->opval.val->type);
5340                 fprintf(outfile,"FUNCTION (%s=%p) type (",
5341                         tree->left->opval.val->name, tree);
5342                 printTypeChain (tree->left->opval.val->type->next,outfile);
5343                 fprintf(outfile,") args (");
5344                 do {
5345                   if (arg) {
5346                     fprintf (outfile, ", ");
5347                   }
5348                   printTypeChain (args ? args->type : NULL, outfile);
5349                   arg++;
5350                   args= args ? args->next : NULL;
5351                 } while (args);
5352                 fprintf(outfile,")\n");
5353                 ast_print(tree->left,outfile,indent);
5354                 ast_print(tree->right,outfile,indent);
5355                 return ;
5356         }
5357         if (tree->opval.op == BLOCK) {
5358                 symbol *decls = tree->values.sym;
5359                 INDENT(indent,outfile);
5360                 fprintf(outfile,"{\n");
5361                 while (decls) {
5362                         INDENT(indent+2,outfile);
5363                         fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5364                                 decls->name, decls);
5365                         printTypeChain(decls->type,outfile);
5366                         fprintf(outfile,")\n");
5367
5368                         decls = decls->next;
5369                 }
5370                 ast_print(tree->right,outfile,indent+2);
5371                 INDENT(indent,outfile);
5372                 fprintf(outfile,"}\n");
5373                 return;
5374         }
5375         if (tree->opval.op == NULLOP) {
5376                 ast_print(tree->left,outfile,indent);
5377                 ast_print(tree->right,outfile,indent);
5378                 return ;
5379         }
5380         INDENT(indent,outfile);
5381
5382         /*------------------------------------------------------------------*/
5383         /*----------------------------*/
5384         /*   leaf has been reached    */
5385         /*----------------------------*/
5386         /* if this is of type value */
5387         /* just get the type        */
5388         if (tree->type == EX_VALUE) {
5389
5390                 if (IS_LITERAL (tree->opval.val->etype)) {
5391                         fprintf(outfile,"CONSTANT (%p) value = ", tree);
5392                         if (SPEC_USIGN (tree->opval.val->etype))
5393                                 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5394                         else
5395                                 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5396                         fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5397                                                       floatFromVal(tree->opval.val));
5398                 } else if (tree->opval.val->sym) {
5399                         /* if the undefined flag is set then give error message */
5400                         if (tree->opval.val->sym->undefined) {
5401                                 fprintf(outfile,"UNDEFINED SYMBOL ");
5402                         } else {
5403                                 fprintf(outfile,"SYMBOL ");
5404                         }
5405                         fprintf(outfile,"(%s=%p)",
5406                                 tree->opval.val->sym->name,tree);
5407                 }
5408                 if (tree->ftype) {
5409                         fprintf(outfile," type (");
5410                         printTypeChain(tree->ftype,outfile);
5411                         fprintf(outfile,")\n");
5412                 } else {
5413                         fprintf(outfile,"\n");
5414                 }
5415                 return ;
5416         }
5417
5418         /* if type link for the case of cast */
5419         if (tree->type == EX_LINK) {
5420                 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5421                 printTypeChain(tree->opval.lnk,outfile);
5422                 fprintf(outfile,")\n");
5423                 return ;
5424         }
5425
5426
5427         /* depending on type of operator do */
5428
5429         switch (tree->opval.op) {
5430                 /*------------------------------------------------------------------*/
5431                 /*----------------------------*/
5432                 /*        array node          */
5433                 /*----------------------------*/
5434         case '[':
5435                 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5436                 printTypeChain(tree->ftype,outfile);
5437                 fprintf(outfile,")\n");
5438                 ast_print(tree->left,outfile,indent+2);
5439                 ast_print(tree->right,outfile,indent+2);
5440                 return;
5441
5442                 /*------------------------------------------------------------------*/
5443                 /*----------------------------*/
5444                 /*      struct/union          */
5445                 /*----------------------------*/
5446         case '.':
5447                 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5448                 printTypeChain(tree->ftype,outfile);
5449                 fprintf(outfile,")\n");
5450                 ast_print(tree->left,outfile,indent+2);
5451                 ast_print(tree->right,outfile,indent+2);
5452                 return ;
5453
5454                 /*------------------------------------------------------------------*/
5455                 /*----------------------------*/
5456                 /*    struct/union pointer    */
5457                 /*----------------------------*/
5458         case PTR_OP:
5459                 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5460                 printTypeChain(tree->ftype,outfile);
5461                 fprintf(outfile,")\n");
5462                 ast_print(tree->left,outfile,indent+2);
5463                 ast_print(tree->right,outfile,indent+2);
5464                 return ;
5465
5466                 /*------------------------------------------------------------------*/
5467                 /*----------------------------*/
5468                 /*  ++/-- operation           */
5469                 /*----------------------------*/
5470         case INC_OP:
5471                 if (tree->left)
5472                   fprintf(outfile,"post-");
5473                 else
5474                   fprintf(outfile,"pre-");
5475                 fprintf(outfile,"INC_OP (%p) type (",tree);
5476                 printTypeChain(tree->ftype,outfile);
5477                 fprintf(outfile,")\n");
5478                 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5479                 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5480                 return ;
5481
5482         case DEC_OP:
5483                 if (tree->left)
5484                   fprintf(outfile,"post-");
5485                 else
5486                   fprintf(outfile,"pre-");
5487                 fprintf(outfile,"DEC_OP (%p) type (",tree);
5488                 printTypeChain(tree->ftype,outfile);
5489                 fprintf(outfile,")\n");
5490                 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5491                 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5492                 return ;
5493
5494                 /*------------------------------------------------------------------*/
5495                 /*----------------------------*/
5496                 /*  bitwise and               */
5497                 /*----------------------------*/
5498         case '&':
5499                 if (tree->right) {
5500                         fprintf(outfile,"& (%p) type (",tree);
5501                         printTypeChain(tree->ftype,outfile);
5502                         fprintf(outfile,")\n");
5503                         ast_print(tree->left,outfile,indent+2);
5504                         ast_print(tree->right,outfile,indent+2);
5505                 } else {
5506                         fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5507                         printTypeChain(tree->ftype,outfile);
5508                         fprintf(outfile,")\n");
5509                         ast_print(tree->left,outfile,indent+2);
5510                         ast_print(tree->right,outfile,indent+2);
5511                 }
5512                 return ;
5513                 /*----------------------------*/
5514                 /*  bitwise or                */
5515                 /*----------------------------*/
5516         case '|':
5517                 fprintf(outfile,"OR (%p) type (",tree);
5518                 printTypeChain(tree->ftype,outfile);
5519                 fprintf(outfile,")\n");
5520                 ast_print(tree->left,outfile,indent+2);
5521                 ast_print(tree->right,outfile,indent+2);
5522                 return ;
5523                 /*------------------------------------------------------------------*/
5524                 /*----------------------------*/
5525                 /*  bitwise xor               */
5526                 /*----------------------------*/
5527         case '^':
5528                 fprintf(outfile,"XOR (%p) type (",tree);
5529                 printTypeChain(tree->ftype,outfile);
5530                 fprintf(outfile,")\n");
5531                 ast_print(tree->left,outfile,indent+2);
5532                 ast_print(tree->right,outfile,indent+2);
5533                 return ;
5534
5535                 /*------------------------------------------------------------------*/
5536                 /*----------------------------*/
5537                 /*  division                  */
5538                 /*----------------------------*/
5539         case '/':
5540                 fprintf(outfile,"DIV (%p) type (",tree);
5541                 printTypeChain(tree->ftype,outfile);
5542                 fprintf(outfile,")\n");
5543                 ast_print(tree->left,outfile,indent+2);
5544                 ast_print(tree->right,outfile,indent+2);
5545                 return ;
5546                 /*------------------------------------------------------------------*/
5547                 /*----------------------------*/
5548                 /*            modulus         */
5549                 /*----------------------------*/
5550         case '%':
5551                 fprintf(outfile,"MOD (%p) type (",tree);
5552                 printTypeChain(tree->ftype,outfile);
5553                 fprintf(outfile,")\n");
5554                 ast_print(tree->left,outfile,indent+2);
5555                 ast_print(tree->right,outfile,indent+2);
5556                 return ;
5557
5558                 /*------------------------------------------------------------------*/
5559                 /*----------------------------*/
5560                 /*  address dereference       */
5561                 /*----------------------------*/
5562         case '*':                       /* can be unary  : if right is null then unary operation */
5563                 if (!tree->right) {
5564                         fprintf(outfile,"DEREF (%p) type (",tree);
5565                         printTypeChain(tree->ftype,outfile);
5566                         fprintf(outfile,")\n");
5567                         ast_print(tree->left,outfile,indent+2);
5568                         return ;
5569                 }                       
5570                 /*------------------------------------------------------------------*/
5571                 /*----------------------------*/
5572                 /*      multiplication        */
5573                 /*----------------------------*/                
5574                 fprintf(outfile,"MULT (%p) type (",tree);
5575                 printTypeChain(tree->ftype,outfile);
5576                 fprintf(outfile,")\n");
5577                 ast_print(tree->left,outfile,indent+2);
5578                 ast_print(tree->right,outfile,indent+2);
5579                 return ;
5580
5581
5582                 /*------------------------------------------------------------------*/
5583                 /*----------------------------*/
5584                 /*    unary '+' operator      */
5585                 /*----------------------------*/
5586         case '+':
5587                 /* if unary plus */
5588                 if (!tree->right) {
5589                         fprintf(outfile,"UPLUS (%p) type (",tree);
5590                         printTypeChain(tree->ftype,outfile);
5591                         fprintf(outfile,")\n");
5592                         ast_print(tree->left,outfile,indent+2);
5593                 } else {
5594                         /*------------------------------------------------------------------*/
5595                         /*----------------------------*/
5596                         /*      addition              */
5597                         /*----------------------------*/
5598                         fprintf(outfile,"ADD (%p) type (",tree);
5599                         printTypeChain(tree->ftype,outfile);
5600                         fprintf(outfile,")\n");
5601                         ast_print(tree->left,outfile,indent+2);
5602                         ast_print(tree->right,outfile,indent+2);
5603                 }
5604                 return;
5605                 /*------------------------------------------------------------------*/
5606                 /*----------------------------*/
5607                 /*      unary '-'             */
5608                 /*----------------------------*/
5609         case '-':                       /* can be unary   */
5610                 if (!tree->right) {
5611                         fprintf(outfile,"UMINUS (%p) type (",tree);
5612                         printTypeChain(tree->ftype,outfile);
5613                         fprintf(outfile,")\n");
5614                         ast_print(tree->left,outfile,indent+2);
5615                 } else {
5616                         /*------------------------------------------------------------------*/
5617                         /*----------------------------*/
5618                         /*      subtraction           */
5619                         /*----------------------------*/
5620                         fprintf(outfile,"SUB (%p) type (",tree);
5621                         printTypeChain(tree->ftype,outfile);
5622                         fprintf(outfile,")\n");
5623                         ast_print(tree->left,outfile,indent+2);
5624                         ast_print(tree->right,outfile,indent+2);
5625                 }
5626                 return;
5627                 /*------------------------------------------------------------------*/
5628                 /*----------------------------*/
5629                 /*    compliment              */
5630                 /*----------------------------*/
5631         case '~':
5632                 fprintf(outfile,"COMPL (%p) type (",tree);
5633                 printTypeChain(tree->ftype,outfile);
5634                 fprintf(outfile,")\n");
5635                 ast_print(tree->left,outfile,indent+2);
5636                 return ;
5637                 /*------------------------------------------------------------------*/
5638                 /*----------------------------*/
5639                 /*           not              */
5640                 /*----------------------------*/
5641         case '!':
5642                 fprintf(outfile,"NOT (%p) type (",tree);
5643                 printTypeChain(tree->ftype,outfile);
5644                 fprintf(outfile,")\n");
5645                 ast_print(tree->left,outfile,indent+2);
5646                 return ;
5647                 /*------------------------------------------------------------------*/
5648                 /*----------------------------*/
5649                 /*           shift            */
5650                 /*----------------------------*/
5651         case RRC:
5652                 fprintf(outfile,"RRC (%p) type (",tree);
5653                 printTypeChain(tree->ftype,outfile);
5654                 fprintf(outfile,")\n");
5655                 ast_print(tree->left,outfile,indent+2);
5656                 return ;
5657
5658         case RLC:
5659                 fprintf(outfile,"RLC (%p) type (",tree);
5660                 printTypeChain(tree->ftype,outfile);
5661                 fprintf(outfile,")\n");
5662                 ast_print(tree->left,outfile,indent+2);
5663                 return ;
5664         case SWAP:
5665                 fprintf(outfile,"SWAP (%p) type (",tree);
5666                 printTypeChain(tree->ftype,outfile);
5667                 fprintf(outfile,")\n");
5668                 ast_print(tree->left,outfile,indent+2);
5669                 return ;
5670         case GETHBIT:
5671                 fprintf(outfile,"GETHBIT (%p) type (",tree);
5672                 printTypeChain(tree->ftype,outfile);
5673                 fprintf(outfile,")\n");
5674                 ast_print(tree->left,outfile,indent+2);
5675                 return ;
5676         case LEFT_OP:
5677                 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5678                 printTypeChain(tree->ftype,outfile);
5679                 fprintf(outfile,")\n");
5680                 ast_print(tree->left,outfile,indent+2);
5681                 ast_print(tree->right,outfile,indent+2);
5682                 return ;
5683         case RIGHT_OP:
5684                 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5685                 printTypeChain(tree->ftype,outfile);
5686                 fprintf(outfile,")\n");
5687                 ast_print(tree->left,outfile,indent+2);
5688                 ast_print(tree->right,outfile,indent+2);
5689                 return ;
5690                 /*------------------------------------------------------------------*/
5691                 /*----------------------------*/
5692                 /*         casting            */
5693                 /*----------------------------*/
5694         case CAST:                      /* change the type   */
5695                 fprintf(outfile,"CAST (%p) from type (",tree);
5696                 printTypeChain(tree->right->ftype,outfile);
5697                 fprintf(outfile,") to type (");
5698                 printTypeChain(tree->ftype,outfile);
5699                 fprintf(outfile,")\n");
5700                 ast_print(tree->right,outfile,indent+2);
5701                 return ;
5702                 
5703         case AND_OP:
5704                 fprintf(outfile,"ANDAND (%p) type (",tree);
5705                 printTypeChain(tree->ftype,outfile);
5706                 fprintf(outfile,")\n");
5707                 ast_print(tree->left,outfile,indent+2);
5708                 ast_print(tree->right,outfile,indent+2);
5709                 return ;
5710         case OR_OP:
5711                 fprintf(outfile,"OROR (%p) type (",tree);
5712                 printTypeChain(tree->ftype,outfile);
5713                 fprintf(outfile,")\n");
5714                 ast_print(tree->left,outfile,indent+2);
5715                 ast_print(tree->right,outfile,indent+2);
5716                 return ;
5717                 
5718                 /*------------------------------------------------------------------*/
5719                 /*----------------------------*/
5720                 /*     comparison operators   */
5721                 /*----------------------------*/
5722         case '>':
5723                 fprintf(outfile,"GT(>) (%p) type (",tree);
5724                 printTypeChain(tree->ftype,outfile);
5725                 fprintf(outfile,")\n");
5726                 ast_print(tree->left,outfile,indent+2);
5727                 ast_print(tree->right,outfile,indent+2);
5728                 return ;
5729         case '<':
5730                 fprintf(outfile,"LT(<) (%p) type (",tree);
5731                 printTypeChain(tree->ftype,outfile);
5732                 fprintf(outfile,")\n");
5733                 ast_print(tree->left,outfile,indent+2);
5734                 ast_print(tree->right,outfile,indent+2);
5735                 return ;
5736         case LE_OP:
5737                 fprintf(outfile,"LE(<=) (%p) type (",tree);
5738                 printTypeChain(tree->ftype,outfile);
5739                 fprintf(outfile,")\n");
5740                 ast_print(tree->left,outfile,indent+2);
5741                 ast_print(tree->right,outfile,indent+2);
5742                 return ;
5743         case GE_OP:
5744                 fprintf(outfile,"GE(>=) (%p) type (",tree);
5745                 printTypeChain(tree->ftype,outfile);
5746                 fprintf(outfile,")\n");
5747                 ast_print(tree->left,outfile,indent+2);
5748                 ast_print(tree->right,outfile,indent+2);
5749                 return ;
5750         case EQ_OP:
5751                 fprintf(outfile,"EQ(==) (%p) type (",tree);
5752                 printTypeChain(tree->ftype,outfile);
5753                 fprintf(outfile,")\n");
5754                 ast_print(tree->left,outfile,indent+2);
5755                 ast_print(tree->right,outfile,indent+2);
5756                 return ;
5757         case NE_OP:
5758                 fprintf(outfile,"NE(!=) (%p) type (",tree);
5759                 printTypeChain(tree->ftype,outfile);
5760                 fprintf(outfile,")\n");
5761                 ast_print(tree->left,outfile,indent+2);
5762                 ast_print(tree->right,outfile,indent+2);
5763                 /*------------------------------------------------------------------*/
5764                 /*----------------------------*/
5765                 /*             sizeof         */
5766                 /*----------------------------*/
5767         case SIZEOF:            /* evaluate wihout code generation */
5768                 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5769                 return ;
5770
5771                 /*------------------------------------------------------------------*/
5772                 /*----------------------------*/
5773                 /* conditional operator  '?'  */
5774                 /*----------------------------*/
5775         case '?':
5776                 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5777                 printTypeChain(tree->ftype,outfile);
5778                 fprintf(outfile,")\n");
5779                 ast_print(tree->left,outfile,indent+2);
5780                 ast_print(tree->right,outfile,indent+2);
5781                 return;
5782
5783         case ':':
5784                 fprintf(outfile,"COLON(:) (%p) type (",tree);
5785                 printTypeChain(tree->ftype,outfile);
5786                 fprintf(outfile,")\n");
5787                 ast_print(tree->left,outfile,indent+2);
5788                 ast_print(tree->right,outfile,indent+2);
5789                 return ;
5790
5791                 /*------------------------------------------------------------------*/
5792                 /*----------------------------*/
5793                 /*    assignment operators    */
5794                 /*----------------------------*/
5795         case MUL_ASSIGN:
5796                 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5797                 printTypeChain(tree->ftype,outfile);
5798                 fprintf(outfile,")\n");
5799                 ast_print(tree->left,outfile,indent+2);
5800                 ast_print(tree->right,outfile,indent+2);
5801                 return;
5802         case DIV_ASSIGN:
5803                 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5804                 printTypeChain(tree->ftype,outfile);
5805                 fprintf(outfile,")\n");
5806                 ast_print(tree->left,outfile,indent+2);
5807                 ast_print(tree->right,outfile,indent+2);
5808                 return;
5809         case AND_ASSIGN:
5810                 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5811                 printTypeChain(tree->ftype,outfile);
5812                 fprintf(outfile,")\n");
5813                 ast_print(tree->left,outfile,indent+2);
5814                 ast_print(tree->right,outfile,indent+2);
5815                 return;
5816         case OR_ASSIGN:
5817                 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5818                 printTypeChain(tree->ftype,outfile);
5819                 fprintf(outfile,")\n");
5820                 ast_print(tree->left,outfile,indent+2);
5821                 ast_print(tree->right,outfile,indent+2);
5822                 return;
5823         case XOR_ASSIGN:
5824                 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5825                 printTypeChain(tree->ftype,outfile);
5826                 fprintf(outfile,")\n");
5827                 ast_print(tree->left,outfile,indent+2);
5828                 ast_print(tree->right,outfile,indent+2);
5829                 return;
5830         case RIGHT_ASSIGN:
5831                 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5832                 printTypeChain(tree->ftype,outfile);
5833                 fprintf(outfile,")\n");
5834                 ast_print(tree->left,outfile,indent+2);
5835                 ast_print(tree->right,outfile,indent+2);
5836                 return;
5837         case LEFT_ASSIGN:
5838                 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5839                 printTypeChain(tree->ftype,outfile);
5840                 fprintf(outfile,")\n");
5841                 ast_print(tree->left,outfile,indent+2);
5842                 ast_print(tree->right,outfile,indent+2);
5843                 return;
5844                 /*------------------------------------------------------------------*/
5845                 /*----------------------------*/
5846                 /*    -= operator             */
5847                 /*----------------------------*/
5848         case SUB_ASSIGN:
5849                 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5850                 printTypeChain(tree->ftype,outfile);
5851                 fprintf(outfile,")\n");
5852                 ast_print(tree->left,outfile,indent+2);
5853                 ast_print(tree->right,outfile,indent+2);
5854                 return;
5855                 /*------------------------------------------------------------------*/
5856                 /*----------------------------*/
5857                 /*          += operator       */
5858                 /*----------------------------*/
5859         case ADD_ASSIGN:
5860                 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5861                 printTypeChain(tree->ftype,outfile);
5862                 fprintf(outfile,")\n");
5863                 ast_print(tree->left,outfile,indent+2);
5864                 ast_print(tree->right,outfile,indent+2);
5865                 return;
5866                 /*------------------------------------------------------------------*/
5867                 /*----------------------------*/
5868                 /*      straight assignemnt   */
5869                 /*----------------------------*/
5870         case '=':
5871                 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5872                 printTypeChain(tree->ftype,outfile);
5873                 fprintf(outfile,")\n");
5874                 ast_print(tree->left,outfile,indent+2);
5875                 ast_print(tree->right,outfile,indent+2);
5876                 return;     
5877                 /*------------------------------------------------------------------*/
5878                 /*----------------------------*/
5879                 /*      comma operator        */
5880                 /*----------------------------*/
5881         case ',':
5882                 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5883                 printTypeChain(tree->ftype,outfile);
5884                 fprintf(outfile,")\n");
5885                 ast_print(tree->left,outfile,indent+2);
5886                 ast_print(tree->right,outfile,indent+2);
5887                 return;
5888                 /*------------------------------------------------------------------*/
5889                 /*----------------------------*/
5890                 /*       function call        */
5891                 /*----------------------------*/
5892         case CALL:
5893         case PCALL:
5894                 fprintf(outfile,"CALL (%p) type (",tree);
5895                 printTypeChain(tree->ftype,outfile);
5896                 fprintf(outfile,")\n");
5897                 ast_print(tree->left,outfile,indent+2);
5898                 ast_print(tree->right,outfile,indent+2);
5899                 return;
5900         case PARAM:
5901                 fprintf(outfile,"PARMS\n");
5902                 ast_print(tree->left,outfile,indent+2);
5903                 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5904                         ast_print(tree->right,outfile,indent+2);
5905                 }
5906                 return ;
5907                 /*------------------------------------------------------------------*/
5908                 /*----------------------------*/
5909                 /*     return statement       */
5910                 /*----------------------------*/
5911         case RETURN:
5912                 fprintf(outfile,"RETURN (%p) type (",tree);
5913                 if (tree->right) {
5914                     printTypeChain(tree->right->ftype,outfile);
5915                 }
5916                 fprintf(outfile,")\n");
5917                 ast_print(tree->right,outfile,indent+2);
5918                 return ;
5919                 /*------------------------------------------------------------------*/
5920                 /*----------------------------*/
5921                 /*     label statement        */
5922                 /*----------------------------*/
5923         case LABEL :
5924                 fprintf(outfile,"LABEL (%p)\n",tree);
5925                 ast_print(tree->left,outfile,indent+2);
5926                 ast_print(tree->right,outfile,indent);
5927                 return;
5928                 /*------------------------------------------------------------------*/
5929                 /*----------------------------*/
5930                 /*     switch statement       */
5931                 /*----------------------------*/
5932         case SWITCH:
5933                 {
5934                         value *val;
5935                         fprintf(outfile,"SWITCH (%p) ",tree);
5936                         ast_print(tree->left,outfile,0);
5937                         for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5938                                 INDENT(indent+2,outfile);
5939                                 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5940                                         (int) floatFromVal(val),
5941                                         tree->values.switchVals.swNum,
5942                                         (int) floatFromVal(val));
5943                         }
5944                         ast_print(tree->right,outfile,indent);
5945                 }
5946                 return ;
5947                 /*------------------------------------------------------------------*/
5948                 /*----------------------------*/
5949                 /* ifx Statement              */
5950                 /*----------------------------*/
5951         case IFX:
5952                 fprintf(outfile,"IF (%p) \n",tree);
5953                 ast_print(tree->left,outfile,indent+2);
5954                 if (tree->trueLabel) {
5955                         INDENT(indent+2,outfile);
5956                         fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5957                 }
5958                 if (tree->falseLabel) {
5959                         INDENT(indent+2,outfile);
5960                         fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5961                 }
5962                 ast_print(tree->right,outfile,indent+2);
5963                 return ;
5964                 /*----------------------------*/
5965                 /* goto Statement              */
5966                 /*----------------------------*/
5967         case GOTO:
5968                 fprintf(outfile,"GOTO (%p) \n",tree);
5969                 ast_print(tree->left,outfile,indent+2);
5970                 fprintf(outfile,"\n");
5971                 return ;
5972                 /*------------------------------------------------------------------*/
5973                 /*----------------------------*/
5974                 /* for Statement              */
5975                 /*----------------------------*/
5976         case FOR:
5977                 fprintf(outfile,"FOR (%p) \n",tree);
5978                 if (AST_FOR( tree, initExpr)) {
5979                         INDENT(indent+2,outfile);
5980                         fprintf(outfile,"INIT EXPR ");
5981                         ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5982                 }
5983                 if (AST_FOR( tree, condExpr)) {
5984                         INDENT(indent+2,outfile);
5985                         fprintf(outfile,"COND EXPR ");
5986                         ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5987                 }
5988                 if (AST_FOR( tree, loopExpr)) {
5989                         INDENT(indent+2,outfile);
5990                         fprintf(outfile,"LOOP EXPR ");
5991                         ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5992                 }
5993                 fprintf(outfile,"FOR LOOP BODY \n");
5994                 ast_print(tree->left,outfile,indent+2);
5995                 return ;
5996         case CRITICAL:
5997                 fprintf(outfile,"CRITICAL (%p) \n",tree);
5998                 ast_print(tree->left,outfile,indent+2);
5999         default:
6000             return ;
6001         }
6002 }
6003
6004 void PA(ast *t)
6005 {
6006         ast_print(t,stdout,0);
6007 }
6008
6009
6010
6011 /*-----------------------------------------------------------------*/
6012 /* astErrors : returns non-zero if errors present in tree          */
6013 /*-----------------------------------------------------------------*/
6014 int astErrors(ast *t)
6015 {
6016   int errors=0;
6017   
6018   if (t)
6019     {
6020       if (t->isError)
6021         errors++;
6022   
6023       if (t->type == EX_VALUE
6024           && t->opval.val->sym
6025           && t->opval.val->sym->undefined)
6026         errors++;
6027
6028       errors += astErrors(t->left);
6029       errors += astErrors(t->right);
6030     }
6031     
6032   return errors;
6033 }