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