55cfd9d29e298353f3a53d569b866726f7a282e2
[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, bool upcast)
2031 {
2032   sym_link *newLink;
2033   bool upCasted = FALSE;
2034   
2035   switch (resultType)
2036     {
2037       case RESULT_TYPE_NONE:
2038         /* char: promote to int */
2039         if (!upcast ||
2040             getSize ((*tree)->etype) >= INTSIZE)
2041           return;
2042         newLink = newIntLink();
2043         upCasted = TRUE;
2044         break;
2045       case RESULT_TYPE_CHAR:
2046         if (getSize ((*tree)->etype) <= 1)
2047           return;
2048         newLink = newCharLink();
2049         break;
2050       case RESULT_TYPE_INT:
2051 #if 0
2052         if (getSize ((*tree)->etype) > INTSIZE)
2053           {
2054             /* warn ("Loosing significant digits"); */
2055             return;
2056           }
2057 #endif
2058         /* char: promote to int */
2059         if (!upcast ||
2060             getSize ((*tree)->etype) >= INTSIZE)
2061           return;
2062         newLink = newIntLink();
2063         upCasted = TRUE;
2064         break;
2065       case RESULT_TYPE_OTHER:
2066         if (!upcast)
2067           return;
2068         /* return type is long, float: promote char to int */
2069         if (getSize ((*tree)->etype) >= INTSIZE)
2070           return;
2071         newLink = newIntLink();
2072         upCasted = TRUE;
2073         break;
2074       default:
2075         return;
2076     }
2077   (*tree)->decorated = 0;
2078   *tree = newNode (CAST, newAst_LINK (newLink), *tree);
2079   /* keep unsigned type during cast to smaller type,
2080      but not when promoting from char to int */
2081   if (!upCasted)
2082     SPEC_USIGN ((*tree)->left->opval.lnk) = IS_UNSIGNED ((*tree)->right->etype) ? 1 : 0;
2083   *tree = decorateType (*tree, resultType);
2084 }
2085
2086 /*-----------------------------------------------------------------*/
2087 /* resultTypePropagate - decides if resultType can be propagated   */
2088 /*-----------------------------------------------------------------*/
2089 static RESULT_TYPE
2090 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2091 {
2092   switch (tree->opval.op)
2093     {
2094       case '=':
2095       case '?':
2096       case ':':
2097       case '|':
2098       case '^':
2099         return resultType;
2100       case '&':
2101         if (!tree->right)
2102           /* can be unary */
2103           return RESULT_TYPE_NONE;
2104         else
2105           return resultType;
2106       default:
2107         return RESULT_TYPE_NONE;
2108     }
2109 }
2110
2111 /*-----------------------------------------------------------------*/
2112 /* getLeftResultType - gets type from left branch for propagation  */
2113 /*-----------------------------------------------------------------*/
2114 static RESULT_TYPE
2115 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2116 {
2117   switch (tree->opval.op)
2118     {
2119       case '=':
2120       case CAST:
2121         if (IS_PTR (tree->left->ftype))
2122           return RESULT_TYPE_NONE;
2123         else
2124           return getResultTypeFromType (tree->left->etype);
2125       case RETURN:
2126         if (IS_PTR (currFunc->type->next))
2127           return RESULT_TYPE_NONE;
2128         else
2129           return getResultTypeFromType (currFunc->type->next);
2130       default:
2131         return resultType;
2132     }
2133 }
2134
2135 /*--------------------------------------------------------------------*/
2136 /* decorateType - compute type for this tree, also does type checking.*/
2137 /* This is done bottom up, since type has to flow upwards.            */
2138 /* resultType flows top-down and forces e.g. char-arithmetik, if the  */
2139 /* result is a char and the operand(s) are int's.                     */
2140 /* It also does constant folding, and parameter checking.             */
2141 /*--------------------------------------------------------------------*/
2142 ast *
2143 decorateType (ast * tree, RESULT_TYPE resultType)
2144 {
2145   int parmNumber;
2146   sym_link *p;
2147   RESULT_TYPE resultTypeProp;
2148
2149   if (!tree)
2150     return tree;
2151
2152   /* if already has type then do nothing */
2153   if (tree->decorated)
2154     return tree;
2155
2156   tree->decorated = 1;
2157
2158 #if 0
2159   /* print the line          */
2160   /* if not block & function */
2161   if (tree->type == EX_OP &&
2162       (tree->opval.op != FUNCTION &&
2163        tree->opval.op != BLOCK &&
2164        tree->opval.op != NULLOP))
2165     {
2166       filename = tree->filename;
2167       lineno = tree->lineno;
2168     }
2169 #endif
2170
2171   /* if any child is an error | this one is an error do nothing */
2172   if (tree->isError ||
2173       (tree->left && tree->left->isError) ||
2174       (tree->right && tree->right->isError))
2175     return tree;
2176
2177 /*------------------------------------------------------------------*/
2178 /*----------------------------*/
2179 /*   leaf has been reached    */
2180 /*----------------------------*/
2181   lineno=tree->lineno;
2182   /* if this is of type value */
2183   /* just get the type        */
2184   if (tree->type == EX_VALUE)
2185     {
2186
2187       if (IS_LITERAL (tree->opval.val->etype))
2188         {
2189
2190           /* if this is a character array then declare it */
2191           if (IS_ARRAY (tree->opval.val->type))
2192             tree->opval.val = stringToSymbol (tree->opval.val);
2193
2194           /* otherwise just copy the type information */
2195           COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2196           return tree;
2197         }
2198
2199       if (tree->opval.val->sym)
2200         {
2201           /* if the undefined flag is set then give error message */
2202           if (tree->opval.val->sym->undefined)
2203             {
2204               werror (E_ID_UNDEF, tree->opval.val->sym->name);
2205               /* assume int */
2206               TTYPE (tree) = TETYPE (tree) =
2207                 tree->opval.val->type = tree->opval.val->sym->type =
2208                 tree->opval.val->etype = tree->opval.val->sym->etype =
2209                 copyLinkChain (INTTYPE);
2210             }
2211           else
2212             {
2213
2214               /* if impilicit i.e. struct/union member then no type */
2215               if (tree->opval.val->sym->implicit)
2216                 TTYPE (tree) = TETYPE (tree) = NULL;
2217
2218               else
2219                 {
2220
2221                   /* else copy the type */
2222                   COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2223
2224                   /* and mark it as referenced */
2225                   tree->opval.val->sym->isref = 1;
2226                 }
2227             }
2228         }
2229
2230       return tree;
2231     }
2232
2233   /* if type link for the case of cast */
2234   if (tree->type == EX_LINK)
2235     {
2236       COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2237       return tree;
2238     }
2239
2240   {
2241     ast *dtl, *dtr;
2242
2243     #if 0
2244     if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2245       {
2246         if (tree->left && tree->left->type == EX_OPERAND
2247             && (tree->left->opval.op == INC_OP
2248                 || tree->left->opval.op == DEC_OP)
2249             && tree->left->left)
2250           {
2251             tree->left->right = tree->left->left;
2252             tree->left->left = NULL;
2253           }
2254         if (tree->right && tree->right->type == EX_OPERAND
2255             && (tree->right->opval.op == INC_OP
2256                 || tree->right->opval.op == DEC_OP)
2257             && tree->right->left)
2258           {
2259             tree->right->right = tree->right->left;
2260             tree->right->left = NULL;
2261           }
2262       }
2263     #endif
2264
2265     /* Before decorating the left branch we've to decide in dependence
2266        upon tree->opval.op, if resultType can be propagated */
2267     if (getenv ("SDCC_NEWTYPEFLOW"))
2268       resultTypeProp = resultTypePropagate (tree, resultType);
2269     else
2270       resultTypeProp = RESULT_TYPE_NONE; /* provide initialization */
2271
2272     dtl = decorateType (tree->left, resultTypeProp);
2273
2274     /* After decorating the left branch there's type information available
2275        in tree->left->?type. If the op is e.g. '=' we extract the type
2276        information from there and propagate it to the right branch. */
2277     if (getenv ("SDCC_NEWTYPEFLOW"))
2278       resultTypeProp = getLeftResultType (tree, resultTypeProp);
2279     
2280     /* delay right side for '?' operator since conditional macro expansions
2281        might rely on this */
2282     dtr = tree->opval.op == '?' ? tree->right :
2283                                   decorateType (tree->right, resultTypeProp);
2284
2285     /* this is to take care of situations
2286        when the tree gets rewritten */
2287     if (dtl != tree->left)
2288       tree->left = dtl;
2289     if (dtr != tree->right)
2290       tree->right = dtr;
2291     if ((dtl && dtl->isError) || (dtr && dtr->isError))
2292       return tree;
2293
2294     if (!getenv ("SDCC_NEWTYPEFLOW"))
2295       {
2296         if (IS_AST_OP(tree) &&
2297             (tree->opval.op == CAST || tree->opval.op == '=') &&
2298             (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) &&
2299             (getSize(RTYPE(tree)) < (unsigned) INTSIZE)) {
2300           /* this is a cast/assign to a bigger type */
2301           if (IS_AST_OP(tree->right) &&
2302               IS_INTEGRAL(tree->right->ftype) &&
2303               (tree->right->opval.op == LEFT_OP ||
2304                tree->right->opval.op == '*' ||
2305                tree->right->opval.op == '+' ||
2306                tree->right->opval.op == '-') &&
2307                tree->right->right) {
2308             /* we should cast an operand instead of the result */
2309             tree->right->decorated = 0;
2310             tree->right->left = newNode( CAST, newAst_LINK(newIntLink()),
2311                                          tree->right->left);
2312             tree->right = decorateType(tree->right, RESULT_CHECK);
2313           }
2314         }
2315       }
2316   }
2317
2318   /* depending on type of operator do */
2319
2320   switch (tree->opval.op)
2321     {
2322         /*------------------------------------------------------------------*/
2323         /*----------------------------*/
2324         /*        array node          */
2325         /*----------------------------*/
2326     case '[':
2327
2328       /* determine which is the array & which the index */
2329       if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2330         {
2331
2332           ast *tempTree = tree->left;
2333           tree->left = tree->right;
2334           tree->right = tempTree;
2335         }
2336
2337       /* first check if this is a array or a pointer */
2338       if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2339         {
2340           werror (E_NEED_ARRAY_PTR, "[]");
2341           goto errorTreeReturn;
2342         }
2343
2344       /* check if the type of the idx */
2345       if (!IS_INTEGRAL (RTYPE (tree)))
2346         {
2347           werror (E_IDX_NOT_INT);
2348           goto errorTreeReturn;
2349         }
2350
2351       /* if the left is an rvalue then error */
2352       if (LRVAL (tree))
2353         {
2354           werror (E_LVALUE_REQUIRED, "array access");
2355           goto errorTreeReturn;
2356         }
2357       RRVAL (tree) = 1;
2358       COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2359       return tree;
2360
2361       /*------------------------------------------------------------------*/
2362       /*----------------------------*/
2363       /*      struct/union          */
2364       /*----------------------------*/
2365     case '.':
2366       /* if this is not a structure */
2367       if (!IS_STRUCT (LTYPE (tree)))
2368         {
2369           werror (E_STRUCT_UNION, ".");
2370           goto errorTreeReturn;
2371         }
2372       TTYPE (tree) = structElemType (LTYPE (tree),
2373                                      (tree->right->type == EX_VALUE ?
2374                                tree->right->opval.val : NULL));
2375       TETYPE (tree) = getSpec (TTYPE (tree));
2376       return tree;
2377
2378       /*------------------------------------------------------------------*/
2379       /*----------------------------*/
2380       /*    struct/union pointer    */
2381       /*----------------------------*/
2382     case PTR_OP:
2383       /* if not pointer to a structure */
2384       if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2385         {
2386           werror (E_PTR_REQD);
2387           goto errorTreeReturn;
2388         }
2389
2390       if (!IS_STRUCT (LTYPE (tree)->next))
2391         {
2392           werror (E_STRUCT_UNION, "->");
2393           goto errorTreeReturn;
2394         }
2395
2396       TTYPE (tree) = structElemType (LTYPE (tree)->next,
2397                                      (tree->right->type == EX_VALUE ?
2398                                tree->right->opval.val : NULL));
2399       TETYPE (tree) = getSpec (TTYPE (tree));
2400
2401       /* adjust the storage class */
2402       switch (DCL_TYPE(tree->left->ftype)) {
2403       case POINTER:
2404         SPEC_SCLS(TETYPE(tree)) = S_DATA; 
2405         break;
2406       case FPOINTER:
2407         SPEC_SCLS(TETYPE(tree)) = S_XDATA; 
2408         break;
2409       case CPOINTER:
2410         SPEC_SCLS(TETYPE(tree)) = S_CODE; 
2411         break;
2412       case GPOINTER:
2413         SPEC_SCLS (TETYPE (tree)) = 0;
2414         break;
2415       case PPOINTER:
2416         SPEC_SCLS(TETYPE(tree)) = S_XSTACK; 
2417         break;
2418       case IPOINTER:
2419         SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2420         break;
2421       case EEPPOINTER:
2422         SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2423         break;
2424       case UPOINTER:
2425         SPEC_SCLS (TETYPE (tree)) = 0;
2426         break;
2427       case ARRAY:
2428       case FUNCTION:
2429         break;
2430       }
2431       
2432       /* This breaks with extern declarations, bitfields, and perhaps other */
2433       /* cases (gcse). Let's leave this optimization disabled for now and   */
2434       /* ponder if there's a safe way to do this. -- EEP                    */
2435       #if 0
2436       if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2437           && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2438         {
2439             /* If defined    struct type at addr var
2440                then rewrite  (&struct var)->member
2441                as            temp
2442                and define    membertype at (addr+offsetof(struct var,member)) temp
2443             */
2444             symbol *sym;
2445             symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2446                                                 AST_SYMBOL(tree->right));
2447
2448             sym = newSymbol(genSymName (0), 0);
2449             sym->type = TTYPE (tree);
2450             sym->etype = getSpec(sym->type);
2451             sym->lineDef = tree->lineno;
2452             sym->cdef = 1;
2453             sym->isref = 1;
2454             SPEC_STAT (sym->etype) = 1;
2455             SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2456                                      + element->offset;
2457             SPEC_ABSA(sym->etype) = 1;
2458             addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2459             allocGlobal (sym);
2460             
2461             AST_VALUE (tree) = symbolVal(sym);
2462             TLVAL (tree) = 1;
2463             TRVAL (tree) = 0;
2464             tree->type = EX_VALUE;
2465             tree->left = NULL;
2466             tree->right = NULL;
2467         }
2468       #endif
2469       
2470       return tree;
2471
2472       /*------------------------------------------------------------------*/
2473       /*----------------------------*/
2474       /*  ++/-- operation           */
2475       /*----------------------------*/
2476     case INC_OP:
2477     case DEC_OP:
2478       {
2479         sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2480         COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2481         if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2482           werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2483
2484         if (tree->right)
2485           RLVAL (tree) = 1;
2486         else
2487           LLVAL (tree) = 1;
2488         return tree;
2489       }
2490
2491       /*------------------------------------------------------------------*/
2492       /*----------------------------*/
2493       /*  bitwise and               */
2494       /*----------------------------*/
2495     case '&':                   /* can be unary   */
2496       /* if right is NULL then unary operation  */
2497       if (tree->right)          /* not an unary operation */
2498         {
2499
2500           if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2501             {
2502               werror (E_BITWISE_OP);
2503               werror (W_CONTINUE, "left & right types are ");
2504               printTypeChain (LTYPE (tree), stderr);
2505               fprintf (stderr, ",");
2506               printTypeChain (RTYPE (tree), stderr);
2507               fprintf (stderr, "\n");
2508               goto errorTreeReturn;
2509             }
2510
2511           /* if they are both literal */
2512           if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2513             {
2514               tree->type = EX_VALUE;
2515               tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2516                                           valFromType (RETYPE (tree)), '&');
2517
2518               tree->right = tree->left = NULL;
2519               TETYPE (tree) = tree->opval.val->etype;
2520               TTYPE (tree) = tree->opval.val->type;
2521               return tree;
2522             }
2523
2524           /* see if this is a GETHBIT operation if yes
2525              then return that */
2526           {
2527             ast *otree = optimizeGetHbit (tree);
2528
2529             if (otree != tree)
2530               return decorateType (otree, RESULT_CHECK);
2531           }
2532
2533           if (getenv ("SDCC_NEWTYPEFLOW"))
2534             {
2535               addCast (&tree->left,  resultType, FALSE);
2536               addCast (&tree->right, resultType, FALSE);
2537             }
2538           TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
2539           TETYPE (tree) = getSpec (TTYPE (tree));
2540
2541           /* if left is a literal exchange left & right */
2542           if (IS_LITERAL (LTYPE (tree)))
2543             {
2544               ast *tTree = tree->left;
2545               tree->left = tree->right;
2546               tree->right = tTree;
2547             }
2548
2549           /* if right is a literal and */
2550           /* we can find a 2nd literal in a and-tree then */
2551           /* rearrange the tree */
2552           if (IS_LITERAL (RTYPE (tree)))
2553             {
2554               ast *parent;
2555               ast *litTree = searchLitOp (tree, &parent, "&");
2556               if (litTree)
2557                 {
2558                   ast *tTree = litTree->left;
2559                   litTree->left = tree->right;
2560                   tree->right = tTree;
2561                   /* both operands in tTree are literal now */
2562                   decorateType (parent, RESULT_CHECK);
2563                 }
2564             }
2565
2566           LRVAL (tree) = RRVAL (tree) = 1;
2567           
2568           return tree;
2569         }
2570
2571       /*------------------------------------------------------------------*/
2572       /*----------------------------*/
2573       /*  address of                */
2574       /*----------------------------*/
2575       p = newLink (DECLARATOR);
2576       /* if bit field then error */
2577       if (IS_BITVAR (tree->left->etype))
2578         {
2579           werror (E_ILLEGAL_ADDR, "address of bit variable");
2580           goto errorTreeReturn;
2581         }
2582
2583       if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2584         {
2585           werror (E_ILLEGAL_ADDR, "address of register variable");
2586           goto errorTreeReturn;
2587         }
2588
2589       if (IS_FUNC (LTYPE (tree)))
2590         {
2591           // this ought to be ignored
2592           return (tree->left);
2593         }
2594
2595       if (IS_LITERAL(LTYPE(tree)))
2596         {
2597           werror (E_ILLEGAL_ADDR, "address of literal");
2598           goto errorTreeReturn;
2599         }
2600
2601      if (LRVAL (tree))
2602         {
2603           werror (E_LVALUE_REQUIRED, "address of");
2604           goto errorTreeReturn;
2605         }
2606       if (!LETYPE (tree))
2607         DCL_TYPE (p) = POINTER;
2608       else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2609         DCL_TYPE (p) = CPOINTER;
2610       else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2611         DCL_TYPE (p) = FPOINTER;
2612       else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2613         DCL_TYPE (p) = PPOINTER;
2614       else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2615         DCL_TYPE (p) = IPOINTER;
2616       else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2617         DCL_TYPE (p) = EEPPOINTER;
2618       else if (SPEC_OCLS(tree->left->etype))
2619           DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2620       else
2621           DCL_TYPE (p) = POINTER;
2622
2623       if (IS_AST_SYM_VALUE (tree->left))
2624         {
2625           AST_SYMBOL (tree->left)->addrtaken = 1;
2626           AST_SYMBOL (tree->left)->allocreq = 1;
2627         }
2628
2629       p->next = LTYPE (tree);
2630       TTYPE (tree) = p;
2631       TETYPE (tree) = getSpec (TTYPE (tree));
2632       LLVAL (tree) = 1;
2633       TLVAL (tree) = 1;
2634
2635       #if 0
2636       if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2637           && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2638         {
2639           symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2640                                       AST_SYMBOL(tree->left->right));
2641           AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2642                                     valueFromLit(element->offset));
2643           tree->left = NULL;
2644           tree->right = NULL;
2645           tree->type = EX_VALUE;
2646           tree->values.literalFromCast = 1;
2647         }
2648       #endif
2649
2650       return tree;
2651
2652       /*------------------------------------------------------------------*/
2653       /*----------------------------*/
2654       /*  bitwise or                */
2655       /*----------------------------*/
2656     case '|':
2657       /* if the rewrite succeeds then don't go any furthur */
2658       {
2659         ast *wtree = optimizeRRCRLC (tree);
2660         if (wtree != tree)
2661           return decorateType (wtree, RESULT_CHECK);
2662         
2663         wtree = optimizeSWAP (tree);
2664         if (wtree != tree)
2665           return decorateType (wtree, RESULT_CHECK);
2666       }
2667
2668       /* if left is a literal exchange left & right */
2669       if (IS_LITERAL (LTYPE (tree)))
2670         {
2671           ast *tTree = tree->left;
2672           tree->left = tree->right;
2673           tree->right = tTree;
2674         }
2675
2676       /* if right is a literal and */
2677       /* we can find a 2nd literal in a or-tree then */
2678       /* rearrange the tree */
2679       if (IS_LITERAL (RTYPE (tree)))
2680         {
2681           ast *parent;
2682           ast *litTree = searchLitOp (tree, &parent, "|");
2683           if (litTree)
2684             {
2685               ast *tTree = litTree->left;
2686               litTree->left = tree->right;
2687               tree->right = tTree;
2688               /* both operands in tTree are literal now */
2689               decorateType (parent, RESULT_CHECK);
2690             }
2691         }
2692       /* fall through */
2693
2694       /*------------------------------------------------------------------*/
2695       /*----------------------------*/
2696       /*  bitwise xor               */
2697       /*----------------------------*/
2698     case '^':
2699       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2700         {
2701           werror (E_BITWISE_OP);
2702           werror (W_CONTINUE, "left & right types are ");
2703           printTypeChain (LTYPE (tree), stderr);
2704           fprintf (stderr, ",");
2705           printTypeChain (RTYPE (tree), stderr);
2706           fprintf (stderr, "\n");
2707           goto errorTreeReturn;
2708         }
2709
2710       /* if they are both literal then */
2711       /* rewrite the tree */
2712       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2713         {
2714           tree->type = EX_VALUE;
2715           tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2716                                         valFromType (RETYPE (tree)),
2717                                         tree->opval.op);
2718           tree->right = tree->left = NULL;
2719           TETYPE (tree) = tree->opval.val->etype;
2720           TTYPE (tree) = tree->opval.val->type;
2721           return tree;
2722         }
2723
2724       /* if left is a literal exchange left & right */
2725       if (IS_LITERAL (LTYPE (tree)))
2726         {
2727           ast *tTree = tree->left;
2728           tree->left = tree->right;
2729           tree->right = tTree;
2730         }
2731
2732       /* if right is a literal and */
2733       /* we can find a 2nd literal in a xor-tree then */
2734       /* rearrange the tree */
2735       if (IS_LITERAL (RTYPE (tree)) &&
2736           tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2737         {
2738           ast *parent;
2739           ast *litTree = searchLitOp (tree, &parent, "^");
2740           if (litTree)
2741             {
2742               ast *tTree = litTree->left;
2743               litTree->left = tree->right;
2744               tree->right = tTree;
2745               /* both operands in litTree are literal now */
2746               decorateType (parent, RESULT_CHECK);
2747             }
2748         }
2749
2750       LRVAL (tree) = RRVAL (tree) = 1;
2751       if (getenv ("SDCC_NEWTYPEFLOW"))
2752         {
2753           addCast (&tree->left,  resultType, FALSE);
2754           addCast (&tree->right, resultType, FALSE);
2755         }
2756       TETYPE (tree) = getSpec (TTYPE (tree) =
2757                                computeType (LTYPE (tree),
2758                                             RTYPE (tree),
2759                                             FALSE));
2760
2761       return tree;
2762
2763       /*------------------------------------------------------------------*/
2764       /*----------------------------*/
2765       /*  division                  */
2766       /*----------------------------*/
2767     case '/':
2768       if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2769         {
2770           werror (E_INVALID_OP, "divide");
2771           goto errorTreeReturn;
2772         }
2773       /* if they are both literal then */
2774       /* rewrite the tree */
2775       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2776         {
2777           tree->type = EX_VALUE;
2778           tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2779                                     valFromType (RETYPE (tree)));
2780           tree->right = tree->left = NULL;
2781           TETYPE (tree) = getSpec (TTYPE (tree) =
2782                                    tree->opval.val->type);
2783           return tree;
2784         }
2785
2786       LRVAL (tree) = RRVAL (tree) = 1;
2787       TETYPE (tree) = getSpec (TTYPE (tree) =
2788                                computeType (LTYPE (tree),
2789                                             RTYPE (tree),
2790                 ! (IS_UNSIGNED (LTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)))));
2791
2792       /* if right is a literal and */
2793       /* left is also a division by a literal then */
2794       /* rearrange the tree */
2795       if (IS_LITERAL (RTYPE (tree))
2796           /* avoid infinite loop */
2797           && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2798         {
2799           ast *parent;
2800           ast *litTree = searchLitOp (tree, &parent, "/");
2801           if (litTree)
2802             {
2803               if (IS_LITERAL (RTYPE (litTree)))
2804                 {
2805                   /* foo_div */
2806                   litTree->right = newNode ('*', litTree->right, tree->right);
2807                   litTree->right->lineno = tree->lineno;
2808
2809                   tree->right->opval.val = constVal ("1");
2810                   decorateType (parent, RESULT_CHECK);
2811                 }
2812               else
2813                 {
2814                   /* litTree->left is literal: no gcse possible.
2815                      We can't call decorateType(parent, RESULT_CHECK), because
2816                      this would cause an infinit loop. */
2817                   parent->decorated = 1;
2818                   decorateType (litTree, RESULT_CHECK);
2819                 }
2820             }
2821         }
2822
2823       return tree;
2824
2825       /*------------------------------------------------------------------*/
2826       /*----------------------------*/
2827       /*            modulus         */
2828       /*----------------------------*/
2829     case '%':
2830       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2831         {
2832           werror (E_BITWISE_OP);
2833           werror (W_CONTINUE, "left & right types are ");
2834           printTypeChain (LTYPE (tree), stderr);
2835           fprintf (stderr, ",");
2836           printTypeChain (RTYPE (tree), stderr);
2837           fprintf (stderr, "\n");
2838           goto errorTreeReturn;
2839         }
2840       /* if they are both literal then */
2841       /* rewrite the tree */
2842       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2843         {
2844           tree->type = EX_VALUE;
2845           tree->opval.val = valMod (valFromType (LETYPE (tree)),
2846                                     valFromType (RETYPE (tree)));
2847           tree->right = tree->left = NULL;
2848           TETYPE (tree) = getSpec (TTYPE (tree) =
2849                                    tree->opval.val->type);
2850           return tree;
2851         }
2852       LRVAL (tree) = RRVAL (tree) = 1;
2853       TETYPE (tree) = getSpec (TTYPE (tree) =
2854                                computeType (LTYPE (tree),
2855                                             RTYPE (tree),
2856                 ! (IS_UNSIGNED (LTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)))));
2857       return tree;
2858
2859       /*------------------------------------------------------------------*/
2860       /*----------------------------*/
2861       /*  address dereference       */
2862       /*----------------------------*/
2863     case '*':                   /* can be unary  : if right is null then unary operation */
2864       if (!tree->right)
2865         {
2866           if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2867             {
2868               werror (E_PTR_REQD);
2869               goto errorTreeReturn;
2870             }
2871
2872           if (LRVAL (tree))
2873             {
2874               werror (E_LVALUE_REQUIRED, "pointer deref");
2875               goto errorTreeReturn;
2876             }
2877           if (IS_ADDRESS_OF_OP(tree->left))
2878             {
2879               /* replace *&obj with obj */
2880               return tree->left->left;
2881             }
2882           TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2883           TETYPE (tree) = getSpec (TTYPE (tree));
2884           /* adjust the storage class */
2885           switch (DCL_TYPE(tree->left->ftype)) {
2886             case POINTER:
2887               SPEC_SCLS(TETYPE(tree)) = S_DATA;
2888               break;
2889             case FPOINTER:
2890               SPEC_SCLS(TETYPE(tree)) = S_XDATA; 
2891               break;
2892             case CPOINTER:
2893               SPEC_SCLS(TETYPE(tree)) = S_CODE; 
2894               break;
2895             case GPOINTER:
2896               SPEC_SCLS (TETYPE (tree)) = 0;
2897               break;
2898             case PPOINTER:
2899               SPEC_SCLS(TETYPE(tree)) = S_XSTACK; 
2900               break;
2901             case IPOINTER:
2902               SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2903               break;
2904             case EEPPOINTER:
2905               SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2906               break;
2907             case UPOINTER:
2908               SPEC_SCLS (TETYPE (tree)) = 0;
2909               break;
2910             case ARRAY:
2911             case FUNCTION:
2912               break;
2913           }
2914           return tree;
2915         }
2916
2917       /*------------------------------------------------------------------*/
2918       /*----------------------------*/
2919       /*      multiplication        */
2920       /*----------------------------*/
2921       if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2922         {
2923           werror (E_INVALID_OP, "multiplication");
2924           goto errorTreeReturn;
2925         }
2926
2927       /* if they are both literal then */
2928       /* rewrite the tree */
2929       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2930         {
2931           tree->type = EX_VALUE;
2932           tree->opval.val = valMult (valFromType (LETYPE (tree)),
2933                                      valFromType (RETYPE (tree)));
2934           tree->right = tree->left = NULL;
2935           TETYPE (tree) = getSpec (TTYPE (tree) =
2936                                    tree->opval.val->type);
2937           return tree;
2938         }
2939
2940       /* if left is a literal exchange left & right */
2941       if (IS_LITERAL (LTYPE (tree)))
2942         {
2943           ast *tTree = tree->left;
2944           tree->left = tree->right;
2945           tree->right = tTree;
2946         }
2947
2948       /* if right is a literal and */
2949       /* we can find a 2nd literal in a mul-tree then */
2950       /* rearrange the tree */
2951       if (IS_LITERAL (RTYPE (tree)))
2952         {
2953           ast *parent;
2954           ast *litTree = searchLitOp (tree, &parent, "*");
2955           if (litTree)
2956             {
2957               ast *tTree = litTree->left;
2958               litTree->left = tree->right;
2959               tree->right = tTree;
2960               /* both operands in litTree are literal now */
2961               decorateType (parent, RESULT_CHECK);
2962             }
2963         }
2964
2965       LRVAL (tree) = RRVAL (tree) = 1;
2966       if (!getenv ("SDCC_NEWTYPEFLOW"))
2967         TETYPE (tree) = getSpec (TTYPE (tree) =
2968                                  computeType (LTYPE (tree),
2969                                               RTYPE (tree),
2970                                               TRUE));
2971       else
2972         {
2973           addCast (&tree->left,  resultType, FALSE);
2974           addCast (&tree->right, resultType, FALSE);
2975           TETYPE (tree) = getSpec (TTYPE (tree) =
2976                                    computeType (LTYPE (tree),
2977                                                 RTYPE (tree),
2978                                resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
2979         }
2980       
2981       return tree;
2982
2983       /*------------------------------------------------------------------*/
2984       /*----------------------------*/
2985       /*    unary '+' operator      */
2986       /*----------------------------*/
2987     case '+':
2988       /* if unary plus */
2989       if (!tree->right)
2990         {
2991           if (!IS_ARITHMETIC (LTYPE (tree)))
2992             {
2993               werror (E_UNARY_OP, '+');
2994               goto errorTreeReturn;
2995             }
2996
2997           /* if left is a literal then do it */
2998           if (IS_LITERAL (LTYPE (tree)))
2999             {
3000               tree->type = EX_VALUE;
3001               tree->opval.val = valFromType (LETYPE (tree));
3002               tree->left = NULL;
3003               TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3004               return tree;
3005             }
3006           LRVAL (tree) = 1;
3007           COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3008           return tree;
3009         }
3010
3011       /*------------------------------------------------------------------*/
3012       /*----------------------------*/
3013       /*      addition              */
3014       /*----------------------------*/
3015
3016       /* this is not a unary operation */
3017       /* if both pointers then problem */
3018       if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3019           (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3020         {
3021           werror (E_PTR_PLUS_PTR);
3022           goto errorTreeReturn;
3023         }
3024
3025       if (!IS_ARITHMETIC (LTYPE (tree)) &&
3026           !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3027         {
3028           werror (E_PLUS_INVALID, "+");
3029           goto errorTreeReturn;
3030         }
3031
3032       if (!IS_ARITHMETIC (RTYPE (tree)) &&
3033           !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3034         {
3035           werror (E_PLUS_INVALID, "+");
3036           goto errorTreeReturn;
3037         }
3038       /* if they are both literal then */
3039       /* rewrite the tree */
3040       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3041         {
3042           tree->type = EX_VALUE;
3043           tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3044                                      valFromType (RETYPE (tree)));
3045           tree->right = tree->left = NULL;
3046           TETYPE (tree) = getSpec (TTYPE (tree) =
3047                                    tree->opval.val->type);
3048           return tree;
3049         }
3050
3051       /* if the right is a pointer or left is a literal
3052          xchange left & right */
3053       if (IS_ARRAY (RTYPE (tree)) ||
3054           IS_PTR (RTYPE (tree)) ||
3055           IS_LITERAL (LTYPE (tree)))
3056         {
3057           ast *tTree = tree->left;
3058           tree->left = tree->right;
3059           tree->right = tTree;
3060         }
3061
3062       /* if right is a literal and */
3063       /* left is also an addition/subtraction with a literal then */
3064       /* rearrange the tree */
3065       if (IS_LITERAL (RTYPE (tree)))
3066         {
3067           ast *litTree, *parent;
3068           litTree = searchLitOp (tree, &parent, "+-");
3069           if (litTree)
3070             {
3071               if (litTree->opval.op == '+')
3072                 {
3073                   /* foo_aa */
3074                   ast *tTree = litTree->left;
3075                   litTree->left = tree->right;
3076                   tree->right = tree->left;
3077                   tree->left = tTree;
3078                 }
3079               else if (litTree->opval.op == '-')
3080                 {
3081                   if (IS_LITERAL (RTYPE (litTree)))
3082                     {
3083                       /* foo_asr */
3084                       ast *tTree = litTree->left;
3085                       litTree->left = tree->right;
3086                       tree->right = tTree;
3087                     }
3088                   else
3089                     {
3090                       /* foo_asl */
3091                       ast *tTree = litTree->right;
3092                       litTree->right = tree->right;
3093                       tree->right = tTree;
3094                       litTree->opval.op = '+';
3095                       tree->opval.op = '-';
3096                     }
3097                 }
3098               decorateType (parent, RESULT_CHECK);
3099             }
3100         }
3101
3102       LRVAL (tree) = RRVAL (tree) = 1;
3103       /* if the left is a pointer */
3104       if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3105         TETYPE (tree) = getSpec (TTYPE (tree) =
3106                                  LTYPE (tree));
3107       else
3108         if (!getenv ("SDCC_NEWTYPEFLOW"))
3109           TETYPE (tree) = getSpec (TTYPE (tree) =
3110                                    computeType (LTYPE (tree),
3111                                                 RTYPE (tree),
3112                                                 FALSE));
3113         else
3114           {
3115             addCast (&tree->left,  resultType, TRUE);
3116             addCast (&tree->right, resultType, TRUE);
3117             TETYPE (tree) = getSpec (TTYPE (tree) =
3118                                      computeType (LTYPE (tree),
3119                                                   RTYPE (tree),
3120                                resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
3121            }
3122         
3123       return tree;
3124
3125       /*------------------------------------------------------------------*/
3126       /*----------------------------*/
3127       /*      unary '-'             */
3128       /*----------------------------*/
3129     case '-':                   /* can be unary   */
3130       /* if right is null then unary */
3131       if (!tree->right)
3132         {
3133
3134           if (!IS_ARITHMETIC (LTYPE (tree)))
3135             {
3136               werror (E_UNARY_OP, tree->opval.op);
3137               goto errorTreeReturn;
3138             }
3139
3140           /* if left is a literal then do it */
3141           if (IS_LITERAL (LTYPE (tree)))
3142             {
3143               tree->type = EX_VALUE;
3144               tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3145               tree->left = NULL;
3146               TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3147               SPEC_USIGN(TETYPE(tree)) = 0;
3148               return tree;
3149             }
3150           LRVAL (tree) = 1;
3151           TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3152           return tree;
3153         }
3154
3155       /*------------------------------------------------------------------*/
3156       /*----------------------------*/
3157       /*    subtraction             */
3158       /*----------------------------*/
3159
3160       if (!(IS_PTR (LTYPE (tree)) ||
3161             IS_ARRAY (LTYPE (tree)) ||
3162             IS_ARITHMETIC (LTYPE (tree))))
3163         {
3164           werror (E_PLUS_INVALID, "-");
3165           goto errorTreeReturn;
3166         }
3167
3168       if (!(IS_PTR (RTYPE (tree)) ||
3169             IS_ARRAY (RTYPE (tree)) ||
3170             IS_ARITHMETIC (RTYPE (tree))))
3171         {
3172           werror (E_PLUS_INVALID, "-");
3173           goto errorTreeReturn;
3174         }
3175
3176       if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3177           !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3178             IS_INTEGRAL (RTYPE (tree))))
3179         {
3180           werror (E_PLUS_INVALID, "-");
3181           goto errorTreeReturn;
3182         }
3183
3184       /* if they are both literal then */
3185       /* rewrite the tree */
3186       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3187         {
3188           tree->type = EX_VALUE;
3189           tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3190                                       valFromType (RETYPE (tree)));
3191           tree->right = tree->left = NULL;
3192           TETYPE (tree) = getSpec (TTYPE (tree) =
3193                                    tree->opval.val->type);
3194           return tree;
3195         }
3196
3197       /* if the left & right are equal then zero */
3198       if (isAstEqual (tree->left, tree->right))
3199         {
3200           tree->type = EX_VALUE;
3201           tree->left = tree->right = NULL;
3202           tree->opval.val = constVal ("0");
3203           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3204           return tree;
3205         }
3206
3207       /* if both of them are pointers or arrays then */
3208       /* the result is going to be an integer        */
3209       if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3210           (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3211         TETYPE (tree) = TTYPE (tree) = newIntLink ();
3212       else
3213         /* if only the left is a pointer */
3214         /* then result is a pointer      */
3215       if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3216         TETYPE (tree) = getSpec (TTYPE (tree) =
3217                                  LTYPE (tree));
3218       else
3219         if (!getenv ("SDCC_NEWTYPEFLOW"))
3220           TETYPE (tree) = getSpec (TTYPE (tree) =
3221                                    computeType (LTYPE (tree),
3222                                                 RTYPE (tree),
3223                                                 FALSE));
3224         else
3225           {
3226             addCast (&tree->left,  resultType, TRUE);
3227             addCast (&tree->right, resultType, TRUE);
3228             TETYPE (tree) = getSpec (TTYPE (tree) =
3229                                      computeType (LTYPE (tree),
3230                                                   RTYPE (tree),
3231                                resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
3232           }
3233
3234       LRVAL (tree) = RRVAL (tree) = 1;
3235
3236       /* if right is a literal and */
3237       /* left is also an addition/subtraction with a literal then */
3238       /* rearrange the tree */
3239       if (IS_LITERAL (RTYPE (tree))
3240           /* avoid infinite loop */
3241           && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3242         {
3243           ast *litTree, *litParent;
3244           litTree = searchLitOp (tree, &litParent, "+-");
3245           if (litTree)
3246             {
3247               if (litTree->opval.op == '+')
3248                 {
3249                   /* foo_sa */
3250                   litTree->right = newNode ('-', litTree->right, tree->right);
3251                   litTree->right->lineno = tree->lineno;
3252
3253                   tree->right->opval.val = constVal ("0");
3254                 }
3255               else if (litTree->opval.op == '-')
3256                 {
3257                   if (IS_LITERAL (RTYPE (litTree)))
3258                     {
3259                       /* foo_ssr */
3260                       litTree->right = newNode ('+', tree->right, litTree->right);
3261                       litTree->right->lineno = tree->lineno;
3262
3263                       tree->right->opval.val = constVal ("0");
3264                     }
3265                   else
3266                     {
3267                       /* foo_ssl */
3268                       ast *tTree = litTree->right;
3269                       litTree->right = tree->right;
3270                       tree->right = tTree;
3271                     }
3272                 }
3273               decorateType (litParent, RESULT_CHECK);
3274             }
3275         }
3276       return tree;
3277
3278       /*------------------------------------------------------------------*/
3279       /*----------------------------*/
3280       /*    complement              */
3281       /*----------------------------*/
3282     case '~':
3283       /* can be only integral type */
3284       if (!IS_INTEGRAL (LTYPE (tree)))
3285         {
3286           werror (E_UNARY_OP, tree->opval.op);
3287           goto errorTreeReturn;
3288         }
3289
3290       /* if left is a literal then do it */
3291       if (IS_LITERAL (LTYPE (tree)))
3292         {
3293           tree->type = EX_VALUE;
3294           tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3295           tree->left = NULL;
3296           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3297           return tree;
3298         }
3299       LRVAL (tree) = 1;
3300       COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3301       return tree;
3302
3303       /*------------------------------------------------------------------*/
3304       /*----------------------------*/
3305       /*           not              */
3306       /*----------------------------*/
3307     case '!':
3308       /* can be pointer */
3309       if (!IS_ARITHMETIC (LTYPE (tree)) &&
3310           !IS_PTR (LTYPE (tree)) &&
3311           !IS_ARRAY (LTYPE (tree)))
3312         {
3313           werror (E_UNARY_OP, tree->opval.op);
3314           goto errorTreeReturn;
3315         }
3316
3317       /* if left is a literal then do it */
3318       if (IS_LITERAL (LTYPE (tree)))
3319         {
3320           tree->type = EX_VALUE;
3321           tree->opval.val = valNot (valFromType (LETYPE (tree)));
3322           tree->left = NULL;
3323           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3324           return tree;
3325         }
3326       LRVAL (tree) = 1;
3327       TTYPE (tree) = TETYPE (tree) = newCharLink ();
3328       return tree;
3329
3330       /*------------------------------------------------------------------*/
3331       /*----------------------------*/
3332       /*           shift            */
3333       /*----------------------------*/
3334     case RRC:
3335     case RLC:
3336     case SWAP:
3337       TTYPE (tree) = LTYPE (tree);
3338       TETYPE (tree) = LETYPE (tree);
3339       return tree;
3340
3341     case GETHBIT:
3342       TTYPE (tree) = TETYPE (tree) = newCharLink ();
3343       return tree;
3344
3345     case LEFT_OP:
3346     case RIGHT_OP:
3347       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3348         {
3349           werror (E_SHIFT_OP_INVALID);
3350           werror (W_CONTINUE, "left & right types are ");
3351           printTypeChain (LTYPE (tree), stderr);
3352           fprintf (stderr, ",");
3353           printTypeChain (RTYPE (tree), stderr);
3354           fprintf (stderr, "\n");
3355           goto errorTreeReturn;
3356         }
3357
3358       /* if they are both literal then */
3359       /* rewrite the tree */
3360       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3361         {
3362           tree->type = EX_VALUE;
3363           tree->opval.val = valShift (valFromType (LETYPE (tree)),
3364                                       valFromType (RETYPE (tree)),
3365                                       (tree->opval.op == LEFT_OP ? 1 : 0));
3366           tree->right = tree->left = NULL;
3367           TETYPE (tree) = getSpec (TTYPE (tree) =
3368                                    tree->opval.val->type);
3369           return tree;
3370         }
3371
3372       LRVAL (tree) = RRVAL (tree) = 1;
3373       if (tree->opval.op == LEFT_OP)
3374         {
3375           if (!getenv ("SDCC_NEWTYPEFLOW"))
3376             /* promote char to int */
3377             TETYPE (tree) = getSpec (TTYPE (tree) =
3378                                      computeType (LTYPE (tree),
3379                                                   LTYPE (tree), /* no, not RTYPE! */
3380                                                   TRUE));
3381           else
3382             {
3383               addCast (&tree->left,  resultType, TRUE);
3384               TETYPE (tree) = getSpec (TTYPE (tree) =
3385                                        computeType (LTYPE (tree),
3386                                                     RTYPE (tree),
3387                                resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
3388             }
3389         }
3390       else /* RIGHT_OP */
3391         {
3392           /* no promotion necessary */
3393           TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3394           if (IS_LITERAL (TTYPE (tree)))
3395             SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3396         }
3397
3398       /* if only the right side is a literal & we are
3399          shifting more than size of the left operand then zero */
3400       if (IS_LITERAL (RTYPE (tree)) &&
3401           ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3402           (getSize (TETYPE (tree)) * 8))
3403         {
3404           if (tree->opval.op==LEFT_OP ||
3405               (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3406             {
3407               lineno=tree->lineno;
3408               werror (W_SHIFT_CHANGED,
3409                       (tree->opval.op == LEFT_OP ? "left" : "right"));
3410               tree->type = EX_VALUE;
3411               tree->left = tree->right = NULL;
3412               tree->opval.val = constVal ("0");
3413               TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3414               return tree;
3415             }
3416         }
3417
3418       return tree;
3419
3420       /*------------------------------------------------------------------*/
3421       /*----------------------------*/
3422       /*         casting            */
3423       /*----------------------------*/
3424     case CAST:                  /* change the type   */
3425       /* cannot cast to an aggregate type */
3426       if (IS_AGGREGATE (LTYPE (tree)))
3427         {
3428           werror (E_CAST_ILLEGAL);
3429           goto errorTreeReturn;
3430         }
3431
3432       /* make sure the type is complete and sane */
3433       checkTypeSanity(LETYPE(tree), "(cast)");
3434
3435       /* If code memory is read only, then pointers to code memory */
3436       /* implicitly point to constants -- make this explicit       */
3437       {
3438         sym_link *t = LTYPE(tree);
3439         while (t && t->next)
3440           {
3441             if (IS_CODEPTR(t) && port->mem.code_ro)
3442               {
3443                 if (IS_SPEC(t->next))
3444                   SPEC_CONST (t->next) = 1;
3445                 else
3446                   DCL_PTR_CONST (t->next) = 1;
3447               }
3448             t = t->next;
3449           }
3450       }
3451
3452 #if 0
3453       /* if the right is a literal replace the tree */
3454       if (IS_LITERAL (RETYPE (tree))) {
3455               if (!IS_PTR (LTYPE (tree))) {
3456                       tree->type = EX_VALUE;
3457                       tree->opval.val =
3458                               valCastLiteral (LTYPE (tree),
3459                                               floatFromVal (valFromType (RETYPE (tree))));
3460                       tree->left = NULL;
3461                       tree->right = NULL;
3462                       TTYPE (tree) = tree->opval.val->type;
3463                       tree->values.literalFromCast = 1;
3464               } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3465                          ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */  {
3466                       sym_link *rest = LTYPE(tree)->next;
3467                       werror(W_LITERAL_GENERIC);
3468                       TTYPE(tree) = newLink(DECLARATOR);
3469                       DCL_TYPE(TTYPE(tree)) = FPOINTER;
3470                       TTYPE(tree)->next = rest;
3471                       tree->left->opval.lnk = TTYPE(tree);
3472                       LRVAL (tree) = 1;
3473               } else {
3474                       TTYPE (tree) = LTYPE (tree);
3475                       LRVAL (tree) = 1;
3476               }
3477       } else {
3478               TTYPE (tree) = LTYPE (tree);
3479               LRVAL (tree) = 1;
3480       }
3481 #else
3482 #if 0 // this is already checked, now this could be explicit
3483       /* if pointer to struct then check names */
3484       if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3485           IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3486           strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3487         {
3488           werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3489                  SPEC_STRUCT(LETYPE(tree))->tag);
3490         }
3491 #endif
3492       if (IS_ADDRESS_OF_OP(tree->right)
3493           && IS_AST_SYM_VALUE (tree->right->left)
3494           && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3495
3496         tree->type = EX_VALUE;
3497         tree->opval.val =
3498           valCastLiteral (LTYPE (tree),
3499                           SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3500         TTYPE (tree) = tree->opval.val->type;
3501         TETYPE (tree) = getSpec (TTYPE (tree));
3502         tree->left = NULL;
3503         tree->right = NULL;
3504         tree->values.literalFromCast = 1;
3505         return tree;
3506       }
3507
3508       /* handle offsetof macro:            */
3509       /* #define offsetof(TYPE, MEMBER) \  */
3510       /* ((unsigned) &((TYPE *)0)->MEMBER) */
3511       if (IS_ADDRESS_OF_OP(tree->right)
3512           && IS_AST_OP (tree->right->left)
3513           && tree->right->left->opval.op == PTR_OP
3514           && IS_AST_OP (tree->right->left->left)
3515           && tree->right->left->left->opval.op == CAST
3516           && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3517
3518         symbol *element = getStructElement (
3519           SPEC_STRUCT (LETYPE(tree->right->left)),
3520           AST_SYMBOL(tree->right->left->right)
3521         );
3522
3523         if (element) {
3524           tree->type = EX_VALUE;
3525           tree->opval.val = valCastLiteral (
3526             LTYPE (tree),
3527             element->offset
3528             + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3529           );
3530
3531           TTYPE (tree) = tree->opval.val->type;
3532           TETYPE (tree) = getSpec (TTYPE (tree));
3533           tree->left = NULL;
3534           tree->right = NULL;
3535           return tree;
3536         }
3537       }
3538
3539       /* if the right is a literal replace the tree */
3540       if (IS_LITERAL (RETYPE (tree))) {
3541         #if 0
3542         if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3543           /* rewrite      (type *)litaddr
3544              as           &temp
3545              and define   type at litaddr temp
3546              (but only if type's storage class is not generic)
3547           */
3548           ast *newTree = newNode ('&', NULL, NULL);
3549           symbol *sym;
3550
3551           TTYPE (newTree) = LTYPE (tree);
3552           TETYPE (newTree) = getSpec(LTYPE (tree));
3553
3554           /* define a global symbol at the casted address*/
3555           sym = newSymbol(genSymName (0), 0);
3556           sym->type = LTYPE (tree)->next;
3557           if (!sym->type)
3558             sym->type = newLink (V_VOID);
3559           sym->etype = getSpec(sym->type);
3560           SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3561           sym->lineDef = tree->lineno;
3562           sym->cdef = 1;
3563           sym->isref = 1;
3564           SPEC_STAT (sym->etype) = 1;
3565           SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3566           SPEC_ABSA(sym->etype) = 1;
3567           addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3568           allocGlobal (sym);
3569
3570           newTree->left = newAst_VALUE(symbolVal(sym));
3571           newTree->left->lineno = tree->lineno;
3572           LTYPE (newTree) = sym->type;
3573           LETYPE (newTree) = sym->etype;
3574           LLVAL (newTree) = 1;
3575           LRVAL (newTree) = 0;
3576           TLVAL (newTree) = 1;
3577           return newTree;
3578         }
3579         #endif
3580         if (!IS_PTR (LTYPE (tree))) {
3581           tree->type = EX_VALUE;
3582           tree->opval.val =
3583           valCastLiteral (LTYPE (tree),
3584                           floatFromVal (valFromType (RTYPE (tree))));
3585           TTYPE (tree) = tree->opval.val->type;
3586           tree->left = NULL;
3587           tree->right = NULL;
3588           tree->values.literalFromCast = 1;
3589           TETYPE (tree) = getSpec (TTYPE (tree));
3590           return tree;
3591         }
3592       }
3593       TTYPE (tree) = LTYPE (tree);
3594       LRVAL (tree) = 1;
3595
3596 #endif
3597       TETYPE (tree) = getSpec (TTYPE (tree));
3598
3599       return tree;
3600
3601       /*------------------------------------------------------------------*/
3602       /*----------------------------*/
3603       /*       logical &&, ||       */
3604       /*----------------------------*/
3605     case AND_OP:
3606     case OR_OP:
3607       /* each must me arithmetic type or be a pointer */
3608       if (!IS_PTR (LTYPE (tree)) &&
3609           !IS_ARRAY (LTYPE (tree)) &&
3610           !IS_INTEGRAL (LTYPE (tree)))
3611         {
3612           werror (E_COMPARE_OP);
3613           goto errorTreeReturn;
3614         }
3615
3616       if (!IS_PTR (RTYPE (tree)) &&
3617           !IS_ARRAY (RTYPE (tree)) &&
3618           !IS_INTEGRAL (RTYPE (tree)))
3619         {
3620           werror (E_COMPARE_OP);
3621           goto errorTreeReturn;
3622         }
3623       /* if they are both literal then */
3624       /* rewrite the tree */
3625       if (IS_LITERAL (RTYPE (tree)) &&
3626           IS_LITERAL (LTYPE (tree)))
3627         {
3628           tree->type = EX_VALUE;
3629           tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3630                                            valFromType (RTYPE (tree)),
3631                                            tree->opval.op);
3632           tree->right = tree->left = NULL;
3633           TETYPE (tree) = getSpec (TTYPE (tree) =
3634                                    tree->opval.val->type);
3635           return tree;
3636         }
3637       LRVAL (tree) = RRVAL (tree) = 1;
3638       TTYPE (tree) = TETYPE (tree) = newCharLink ();
3639       return tree;
3640
3641       /*------------------------------------------------------------------*/
3642       /*----------------------------*/
3643       /*     comparison operators   */
3644       /*----------------------------*/
3645     case '>':
3646     case '<':
3647     case LE_OP:
3648     case GE_OP:
3649     case EQ_OP:
3650     case NE_OP:
3651       {
3652         ast *lt = optimizeCompare (tree);
3653
3654         if (tree != lt)
3655           return lt;
3656       }
3657
3658       /* if they are pointers they must be castable */
3659       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3660         {
3661           if (tree->opval.op==EQ_OP &&
3662               !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3663             // we cannot cast a gptr to a !gptr: switch the leaves
3664             struct ast *s=tree->left;
3665             tree->left=tree->right;
3666             tree->right=s;
3667           }
3668           if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3669             {
3670               werror (E_COMPARE_OP);
3671               fprintf (stderr, "comparing type ");
3672               printTypeChain (LTYPE (tree), stderr);
3673               fprintf (stderr, "to type ");
3674               printTypeChain (RTYPE (tree), stderr);
3675               fprintf (stderr, "\n");
3676               goto errorTreeReturn;
3677             }
3678         }
3679       /* else they should be promotable to one another */
3680       else
3681         {
3682           if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3683                 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3684
3685             if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3686               {
3687                 werror (E_COMPARE_OP);
3688                 fprintf (stderr, "comparing type ");
3689                 printTypeChain (LTYPE (tree), stderr);
3690                 fprintf (stderr, "to type ");
3691                 printTypeChain (RTYPE (tree), stderr);
3692                 fprintf (stderr, "\n");
3693                 goto errorTreeReturn;
3694               }
3695         }
3696       /* if unsigned value < 0  then always false */
3697       /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3698       if (SPEC_USIGN(LETYPE(tree)) &&
3699           !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3700           IS_LITERAL(RTYPE(tree))  &&
3701           ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3702         {
3703           if (tree->opval.op == '<')
3704             {
3705               return tree->right;
3706             }
3707           if (tree->opval.op == '>')
3708             {
3709               /* if the parent is an ifx, then we could do */
3710               /* return tree->left; */
3711               tree->opval.op = '?';
3712               tree->right = newNode (':',
3713                                      newAst_VALUE (constVal ("1")),
3714                                      tree->right); /* val 0 */
3715               tree->right->lineno = tree->lineno;
3716               tree->right->left->lineno = tree->lineno;
3717               decorateType (tree->right, RESULT_CHECK);
3718             }
3719         }
3720       /* if they are both literal then */
3721       /* rewrite the tree */
3722       if (IS_LITERAL (RTYPE (tree)) &&
3723           IS_LITERAL (LTYPE (tree)))
3724         {
3725           tree->type = EX_VALUE;
3726           tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3727                                         valFromType (RETYPE (tree)),
3728                                         tree->opval.op);
3729           tree->right = tree->left = NULL;
3730           TETYPE (tree) = getSpec (TTYPE (tree) =
3731                                    tree->opval.val->type);
3732           return tree;
3733         }
3734       LRVAL (tree) = RRVAL (tree) = 1;
3735       TTYPE (tree) = TETYPE (tree) = newCharLink ();
3736       return tree;
3737
3738       /*------------------------------------------------------------------*/
3739       /*----------------------------*/
3740       /*             sizeof         */
3741       /*----------------------------*/
3742     case SIZEOF:                /* evaluate wihout code generation */
3743       /* change the type to a integer */
3744       tree->type = EX_VALUE;
3745       SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
3746       tree->opval.val = constVal (buffer);
3747       tree->right = tree->left = NULL;
3748       TETYPE (tree) = getSpec (TTYPE (tree) =
3749                                tree->opval.val->type);
3750       return tree;
3751
3752       /*------------------------------------------------------------------*/
3753       /*----------------------------*/
3754       /*             typeof         */
3755       /*----------------------------*/
3756     case TYPEOF:
3757         /* return typeof enum value */
3758         tree->type = EX_VALUE;
3759         {
3760             int typeofv = 0;
3761             if (IS_SPEC(tree->right->ftype)) {
3762                 switch (SPEC_NOUN(tree->right->ftype)) {
3763                 case V_INT:
3764                     if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3765                     else typeofv = TYPEOF_INT;
3766                     break;
3767                 case V_FLOAT:
3768                     typeofv = TYPEOF_FLOAT;
3769                     break;
3770                 case V_CHAR:
3771                     typeofv = TYPEOF_CHAR;
3772                     break;
3773                 case V_VOID:
3774                     typeofv = TYPEOF_VOID;
3775                     break;
3776                 case V_STRUCT:
3777                     typeofv = TYPEOF_STRUCT;
3778                     break;
3779                 case V_BITFIELD:
3780                     typeofv = TYPEOF_BITFIELD;
3781                     break;
3782                 case V_BIT:
3783                     typeofv = TYPEOF_BIT;
3784                     break;
3785                 case V_SBIT:
3786                     typeofv = TYPEOF_SBIT;
3787                     break;
3788                 default:
3789                     break;
3790                 }
3791             } else {
3792                 switch (DCL_TYPE(tree->right->ftype)) {
3793                 case POINTER:
3794                     typeofv = TYPEOF_POINTER;
3795                     break;
3796                 case FPOINTER:
3797                     typeofv = TYPEOF_FPOINTER;
3798                     break;
3799                 case CPOINTER:
3800                     typeofv = TYPEOF_CPOINTER;
3801                     break;
3802                 case GPOINTER:
3803                     typeofv = TYPEOF_GPOINTER;
3804                     break;
3805                 case PPOINTER:
3806                     typeofv = TYPEOF_PPOINTER;
3807                     break;
3808                 case IPOINTER:
3809                     typeofv = TYPEOF_IPOINTER;
3810                     break;
3811                 case ARRAY:
3812                     typeofv = TYPEOF_ARRAY;
3813                     break;
3814                 case FUNCTION:
3815                     typeofv = TYPEOF_FUNCTION;
3816                     break;
3817                 default:
3818                     break;
3819                 }
3820             }
3821             SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3822             tree->opval.val = constVal (buffer);
3823             tree->right = tree->left = NULL;
3824             TETYPE (tree) = getSpec (TTYPE (tree) =
3825                                      tree->opval.val->type);
3826         }
3827         return tree;
3828       /*------------------------------------------------------------------*/
3829       /*----------------------------*/
3830       /* conditional operator  '?'  */
3831       /*----------------------------*/
3832     case '?':
3833       /* the type is value of the colon operator (on the right) */
3834       assert (IS_COLON_OP (tree->right));
3835       /* if already known then replace the tree : optimizer will do it
3836          but faster to do it here */
3837       if (IS_LITERAL (LTYPE (tree)))
3838         {
3839           if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
3840             return decorateType (tree->right->left, resultTypeProp);
3841           else
3842             return decorateType (tree->right->right, resultTypeProp);
3843         }
3844       else
3845         {
3846           tree->right = decorateType (tree->right, resultTypeProp);
3847           TTYPE (tree) = RTYPE (tree);
3848           TETYPE (tree) = getSpec (TTYPE (tree));
3849         }
3850       return tree;
3851
3852     case ':':
3853       /* if they don't match we have a problem */
3854       if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3855         {
3856           werror (E_TYPE_MISMATCH, "conditional operator", " ");
3857           goto errorTreeReturn;
3858         }
3859
3860       TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
3861       TETYPE (tree) = getSpec (TTYPE (tree));
3862       return tree;
3863
3864
3865 #if 0 // assignment operators are converted by the parser
3866       /*------------------------------------------------------------------*/
3867       /*----------------------------*/
3868       /*    assignment operators    */
3869       /*----------------------------*/
3870     case MUL_ASSIGN:
3871     case DIV_ASSIGN:
3872       /* for these it must be both must be integral */
3873       if (!IS_ARITHMETIC (LTYPE (tree)) ||
3874           !IS_ARITHMETIC (RTYPE (tree)))
3875         {
3876           werror (E_OPS_INTEGRAL);
3877           goto errorTreeReturn;
3878         }
3879       RRVAL (tree) = 1;
3880       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3881
3882       if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3883         werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3884
3885       if (LRVAL (tree))
3886         {
3887           werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3888           goto errorTreeReturn;
3889         }
3890       LLVAL (tree) = 1;
3891
3892       return tree;
3893
3894     case AND_ASSIGN:
3895     case OR_ASSIGN:
3896     case XOR_ASSIGN:
3897     case RIGHT_ASSIGN:
3898     case LEFT_ASSIGN:
3899       /* for these it must be both must be integral */
3900       if (!IS_INTEGRAL (LTYPE (tree)) ||
3901           !IS_INTEGRAL (RTYPE (tree)))
3902         {
3903           werror (E_OPS_INTEGRAL);
3904           goto errorTreeReturn;
3905         }
3906       RRVAL (tree) = 1;
3907       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3908
3909       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3910         werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3911
3912       if (LRVAL (tree))
3913         {
3914           werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3915           goto errorTreeReturn;
3916         }
3917       LLVAL (tree) = 1;
3918
3919       return tree;
3920
3921       /*------------------------------------------------------------------*/
3922       /*----------------------------*/
3923       /*    -= operator             */
3924       /*----------------------------*/
3925     case SUB_ASSIGN:
3926       if (!(IS_PTR (LTYPE (tree)) ||
3927             IS_ARITHMETIC (LTYPE (tree))))
3928         {
3929           werror (E_PLUS_INVALID, "-=");
3930           goto errorTreeReturn;
3931         }
3932
3933       if (!(IS_PTR (RTYPE (tree)) ||
3934             IS_ARITHMETIC (RTYPE (tree))))
3935         {
3936           werror (E_PLUS_INVALID, "-=");
3937           goto errorTreeReturn;
3938         }
3939       RRVAL (tree) = 1;
3940       TETYPE (tree) = getSpec (TTYPE (tree) =
3941                                computeType (LTYPE (tree),
3942                                             RTYPE (tree),
3943                                             FALSE));
3944
3945       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3946         werror (E_CODE_WRITE, "-=");
3947
3948       if (LRVAL (tree))
3949         {
3950           werror (E_LVALUE_REQUIRED, "-=");
3951           goto errorTreeReturn;
3952         }
3953       LLVAL (tree) = 1;
3954
3955       return tree;
3956
3957       /*------------------------------------------------------------------*/
3958       /*----------------------------*/
3959       /*          += operator       */
3960       /*----------------------------*/
3961     case ADD_ASSIGN:
3962       /* this is not a unary operation */
3963       /* if both pointers then problem */
3964       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3965         {
3966           werror (E_PTR_PLUS_PTR);
3967           goto errorTreeReturn;
3968         }
3969
3970       if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3971         {
3972           werror (E_PLUS_INVALID, "+=");
3973           goto errorTreeReturn;
3974         }
3975
3976       if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3977         {
3978           werror (E_PLUS_INVALID, "+=");
3979           goto errorTreeReturn;
3980         }
3981       RRVAL (tree) = 1;
3982       TETYPE (tree) = getSpec (TTYPE (tree) =
3983                                computeType (LTYPE (tree),
3984                                             RTYPE (tree),
3985                                             FALSE));
3986
3987       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3988         werror (E_CODE_WRITE, "+=");
3989
3990       if (LRVAL (tree))
3991         {
3992           werror (E_LVALUE_REQUIRED, "+=");
3993           goto errorTreeReturn;
3994         }
3995
3996       tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_CHECK);
3997       tree->opval.op = '=';
3998
3999       return tree;
4000 #endif
4001
4002       /*------------------------------------------------------------------*/
4003       /*----------------------------*/
4004       /*      straight assignemnt   */
4005       /*----------------------------*/
4006     case '=':
4007       /* cannot be an aggregate */
4008       if (IS_AGGREGATE (LTYPE (tree)))
4009         {
4010           werror (E_AGGR_ASSIGN);
4011           goto errorTreeReturn;
4012         }
4013
4014       /* they should either match or be castable */
4015       if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4016         {
4017           werror (E_TYPE_MISMATCH, "assignment", " ");
4018           printFromToType(RTYPE(tree),LTYPE(tree));
4019         }
4020
4021       /* if the left side of the tree is of type void
4022          then report error */
4023       if (IS_VOID (LTYPE (tree)))
4024         {
4025           werror (E_CAST_ZERO);
4026           printFromToType(RTYPE(tree), LTYPE(tree));
4027         }
4028
4029       TETYPE (tree) = getSpec (TTYPE (tree) =
4030                                LTYPE (tree));
4031       RRVAL (tree) = 1;
4032       LLVAL (tree) = 1;
4033       if (!tree->initMode ) {
4034         if (IS_CONSTANT(LTYPE(tree)))
4035           werror (E_CODE_WRITE, "=");
4036       }
4037       if (LRVAL (tree))
4038         {
4039           werror (E_LVALUE_REQUIRED, "=");
4040           goto errorTreeReturn;
4041         }
4042
4043       return tree;
4044
4045       /*------------------------------------------------------------------*/
4046       /*----------------------------*/
4047       /*      comma operator        */
4048       /*----------------------------*/
4049     case ',':
4050       TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4051       return tree;
4052
4053       /*------------------------------------------------------------------*/
4054       /*----------------------------*/
4055       /*       function call        */
4056       /*----------------------------*/
4057     case CALL:
4058       parmNumber = 1;
4059
4060       if (processParms (tree->left,
4061                         FUNC_ARGS(tree->left->ftype),
4062                         tree->right, &parmNumber, TRUE)) {
4063         goto errorTreeReturn;
4064       }
4065
4066       if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) && 
4067           !IFFUNC_ISBUILTIN(LTYPE(tree)))
4068         {
4069           reverseParms (tree->right);
4070         }
4071
4072       if (IS_CODEPTR(LTYPE(tree))) {
4073         TTYPE(tree) = LTYPE(tree)->next->next;
4074       } else {
4075         TTYPE(tree) = LTYPE(tree)->next;
4076       }
4077       TETYPE (tree) = getSpec (TTYPE (tree));
4078       return tree;
4079
4080       /*------------------------------------------------------------------*/
4081       /*----------------------------*/
4082       /*     return statement       */
4083       /*----------------------------*/
4084     case RETURN:
4085       if (!tree->right)
4086         goto voidcheck;
4087
4088       if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4089         {
4090           werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4091           printFromToType (RTYPE(tree), currFunc->type->next);
4092           goto errorTreeReturn;
4093         }
4094
4095       if (IS_VOID (currFunc->type->next)
4096           && tree->right &&
4097           !IS_VOID (RTYPE (tree)))
4098         {
4099           werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4100           goto errorTreeReturn;
4101         }
4102
4103       /* if there is going to be a casting required then add it */
4104       if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4105         {
4106           tree->right =
4107             decorateType (newNode (CAST,
4108                           newAst_LINK (copyLinkChain (currFunc->type->next)),
4109                                         tree->right),
4110                           RESULT_CHECK);
4111         }
4112
4113       RRVAL (tree) = 1;
4114       return tree;
4115
4116     voidcheck:
4117
4118       if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4119         {
4120           werror (W_VOID_FUNC, currFunc->name);
4121           goto errorTreeReturn;
4122         }
4123
4124       TTYPE (tree) = TETYPE (tree) = NULL;
4125       return tree;
4126
4127       /*------------------------------------------------------------------*/
4128       /*----------------------------*/
4129       /*     switch statement       */
4130       /*----------------------------*/
4131     case SWITCH:
4132       /* the switch value must be an integer */
4133       if (!IS_INTEGRAL (LTYPE (tree)))
4134         {
4135           werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4136           goto errorTreeReturn;
4137         }
4138       LRVAL (tree) = 1;
4139       TTYPE (tree) = TETYPE (tree) = NULL;
4140       return tree;
4141
4142       /*------------------------------------------------------------------*/
4143       /*----------------------------*/
4144       /* ifx Statement              */
4145       /*----------------------------*/
4146     case IFX:
4147       tree->left = backPatchLabels (tree->left,
4148                                     tree->trueLabel,
4149                                     tree->falseLabel);
4150       TTYPE (tree) = TETYPE (tree) = NULL;
4151       return tree;
4152
4153       /*------------------------------------------------------------------*/
4154       /*----------------------------*/
4155       /* for Statement              */
4156       /*----------------------------*/
4157     case FOR:
4158
4159       decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_CHECK);
4160       decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_CHECK);
4161       decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_CHECK);
4162
4163       /* if the for loop is reversible then
4164          reverse it otherwise do what we normally
4165          do */
4166       {
4167         symbol *sym;
4168         ast *init, *end;
4169
4170         if (isLoopReversible (tree, &sym, &init, &end))
4171           return reverseLoop (tree, sym, init, end);
4172         else
4173           return decorateType (createFor (AST_FOR (tree, trueLabel),
4174                                           AST_FOR (tree, continueLabel),
4175                                           AST_FOR (tree, falseLabel),
4176                                           AST_FOR (tree, condLabel),
4177                                           AST_FOR (tree, initExpr),
4178                                           AST_FOR (tree, condExpr),
4179                                           AST_FOR (tree, loopExpr),
4180                                           tree->left), RESULT_CHECK);
4181       }
4182     default:
4183       TTYPE (tree) = TETYPE (tree) = NULL;
4184       return tree;
4185     }
4186
4187   /* some error found this tree will be killed */
4188 errorTreeReturn:
4189   TTYPE (tree) = TETYPE (tree) = newCharLink ();
4190   tree->opval.op = NULLOP;
4191   tree->isError = 1;
4192
4193   return tree;
4194 }
4195
4196 /*-----------------------------------------------------------------*/
4197 /* sizeofOp - processes size of operation                          */
4198 /*-----------------------------------------------------------------*/
4199 value *
4200 sizeofOp (sym_link * type)
4201 {
4202   char buff[10];
4203
4204   /* make sure the type is complete and sane */
4205   checkTypeSanity(type, "(sizeof)");
4206
4207   /* get the size and convert it to character  */
4208   SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
4209
4210   /* now convert into value  */
4211   return constVal (buff);
4212 }
4213
4214
4215 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4216 #define IS_OR(ex)  (ex->type == EX_OP && ex->opval.op == OR_OP )
4217 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4218 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4219 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4220 #define IS_LT(ex)  (ex->type == EX_OP && ex->opval.op == '<' )
4221 #define IS_GT(ex)  (ex->type == EX_OP && ex->opval.op == '>')
4222
4223 /*-----------------------------------------------------------------*/
4224 /* backPatchLabels - change and or not operators to flow control    */
4225 /*-----------------------------------------------------------------*/
4226 ast *
4227 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4228 {
4229
4230   if (!tree)
4231     return NULL;
4232
4233   if (!(IS_ANDORNOT (tree)))
4234     return tree;
4235
4236   /* if this an and */
4237   if (IS_AND (tree))
4238     {
4239       static int localLbl = 0;
4240       symbol *localLabel;
4241
4242       SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4243       localLabel = newSymbol (buffer, NestLevel);
4244
4245       tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4246
4247       /* if left is already a IFX then just change the if true label in that */
4248       if (!IS_IFX (tree->left))
4249         tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4250
4251       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4252       /* right is a IFX then just join */
4253       if (IS_IFX (tree->right))
4254         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4255
4256       tree->right = createLabel (localLabel, tree->right);
4257       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4258
4259       return newNode (NULLOP, tree->left, tree->right);
4260     }
4261
4262   /* if this is an or operation */
4263   if (IS_OR (tree))
4264     {
4265       static int localLbl = 0;
4266       symbol *localLabel;
4267
4268       SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4269       localLabel = newSymbol (buffer, NestLevel);
4270
4271       tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4272
4273       /* if left is already a IFX then just change the if true label in that */
4274       if (!IS_IFX (tree->left))
4275         tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4276
4277       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4278       /* right is a IFX then just join */
4279       if (IS_IFX (tree->right))
4280         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4281
4282       tree->right = createLabel (localLabel, tree->right);
4283       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4284
4285       return newNode (NULLOP, tree->left, tree->right);
4286     }
4287
4288   /* change not */
4289   if (IS_NOT (tree))
4290     {
4291       int wasnot = IS_NOT (tree->left);
4292       tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4293
4294       /* if the left is already a IFX */
4295       if (!IS_IFX (tree->left))
4296         tree->left = newNode (IFX, tree->left, NULL);
4297
4298       if (wasnot)
4299         {
4300           tree->left->trueLabel = trueLabel;
4301           tree->left->falseLabel = falseLabel;
4302         }
4303       else
4304         {
4305           tree->left->trueLabel = falseLabel;
4306           tree->left->falseLabel = trueLabel;
4307         }
4308       return tree->left;
4309     }
4310
4311   if (IS_IFX (tree))
4312     {
4313       tree->trueLabel = trueLabel;
4314       tree->falseLabel = falseLabel;
4315     }
4316
4317   return tree;
4318 }
4319
4320
4321 /*-----------------------------------------------------------------*/
4322 /* createBlock - create expression tree for block                  */
4323 /*-----------------------------------------------------------------*/
4324 ast *
4325 createBlock (symbol * decl, ast * body)
4326 {
4327   ast *ex;
4328
4329   /* if the block has nothing */
4330   if (!body && !decl)
4331     return NULL;
4332
4333   ex = newNode (BLOCK, NULL, body);
4334   ex->values.sym = decl;
4335   
4336   ex->right = ex->right;
4337   ex->level++;
4338   ex->lineno = 0;
4339   return ex;
4340 }
4341
4342 /*-----------------------------------------------------------------*/
4343 /* createLabel - creates the expression tree for labels            */
4344 /*-----------------------------------------------------------------*/
4345 ast *
4346 createLabel (symbol * label, ast * stmnt)
4347 {
4348   symbol *csym;
4349   char name[SDCC_NAME_MAX + 1];
4350   ast *rValue;
4351
4352   /* must create fresh symbol if the symbol name  */
4353   /* exists in the symbol table, since there can  */
4354   /* be a variable with the same name as the labl */
4355   if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4356       (csym->level == label->level))
4357     label = newSymbol (label->name, label->level);
4358
4359   /* change the name before putting it in add _ */
4360   SNPRINTF(name, sizeof(name), "%s", label->name);
4361
4362   /* put the label in the LabelSymbol table    */
4363   /* but first check if a label of the same    */
4364   /* name exists                               */
4365   if ((csym = findSym (LabelTab, NULL, name)))
4366     werror (E_DUPLICATE_LABEL, label->name);
4367   else
4368     addSym (LabelTab, label, name, label->level, 0, 0);
4369
4370   label->islbl = 1;
4371   label->key = labelKey++;
4372   rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4373   rValue->lineno = 0;
4374
4375   return rValue;
4376 }
4377
4378 /*-----------------------------------------------------------------*/
4379 /* createCase - generates the parsetree for a case statement       */
4380 /*-----------------------------------------------------------------*/
4381 ast *
4382 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4383 {
4384   char caseLbl[SDCC_NAME_MAX + 1];
4385   ast *rexpr;
4386   value *val;
4387
4388   /* if the switch statement does not exist */
4389   /* then case is out of context            */
4390   if (!swStat)
4391     {
4392       werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4393       return NULL;
4394     }
4395
4396   caseVal = decorateType (resolveSymbols (caseVal), RESULT_CHECK);
4397   /* if not a constant then error  */
4398   if (!IS_LITERAL (caseVal->ftype))
4399     {
4400       werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4401       return NULL;
4402     }
4403
4404   /* if not a integer than error */
4405   if (!IS_INTEGRAL (caseVal->ftype))
4406     {
4407       werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4408       return NULL;
4409     }
4410
4411   /* find the end of the switch values chain   */
4412   if (!(val = swStat->values.switchVals.swVals))
4413     swStat->values.switchVals.swVals = caseVal->opval.val;
4414   else
4415     {
4416       /* also order the cases according to value */
4417       value *pval = NULL;
4418       int cVal = (int) floatFromVal (caseVal->opval.val);
4419       while (val && (int) floatFromVal (val) < cVal)
4420         {
4421           pval = val;
4422           val = val->next;
4423         }
4424
4425       /* if we reached the end then */
4426       if (!val)
4427         {
4428           pval->next = caseVal->opval.val;
4429         }
4430       else if ((int) floatFromVal (val) == cVal)
4431         {
4432           werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4433                     "case");
4434           return NULL;
4435         }
4436       else
4437         {
4438           /* we found a value greater than */
4439           /* the current value we must add this */
4440           /* before the value */
4441           caseVal->opval.val->next = val;
4442
4443           /* if this was the first in chain */
4444           if (swStat->values.switchVals.swVals == val)
4445             swStat->values.switchVals.swVals =
4446               caseVal->opval.val;
4447           else
4448             pval->next = caseVal->opval.val;
4449         }
4450
4451     }
4452
4453   /* create the case label   */
4454   SNPRINTF(caseLbl, sizeof(caseLbl), 
4455            "_case_%d_%d",
4456            swStat->values.switchVals.swNum,
4457            (int) floatFromVal (caseVal->opval.val));
4458
4459   rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4460   rexpr->lineno = 0;
4461   return rexpr;
4462 }
4463
4464 /*-----------------------------------------------------------------*/
4465 /* createDefault - creates the parse tree for the default statement */
4466 /*-----------------------------------------------------------------*/
4467 ast *
4468 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4469 {
4470   char defLbl[SDCC_NAME_MAX + 1];
4471
4472   /* if the switch statement does not exist */
4473   /* then case is out of context            */
4474   if (!swStat)
4475     {
4476       werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4477       return NULL;
4478     }
4479
4480   if (swStat->values.switchVals.swDefault)
4481     {
4482       werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4483                 "default");
4484       return NULL;
4485     }
4486
4487   /* turn on the default flag   */
4488   swStat->values.switchVals.swDefault = 1;
4489
4490   /* create the label  */
4491   SNPRINTF (defLbl, sizeof(defLbl),
4492             "_default_%d", swStat->values.switchVals.swNum);
4493   return createLabel (newSymbol (defLbl, 0), stmnt);
4494 }
4495
4496 /*-----------------------------------------------------------------*/
4497 /* createIf - creates the parsetree for the if statement           */
4498 /*-----------------------------------------------------------------*/
4499 ast *
4500 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4501 {
4502   static int Lblnum = 0;
4503   ast *ifTree;
4504   symbol *ifTrue, *ifFalse, *ifEnd;
4505
4506   /* if neither exists */
4507   if (!elseBody && !ifBody) {
4508     // if there are no side effects (i++, j() etc)
4509     if (!hasSEFcalls(condAst)) {
4510       return condAst;
4511     }
4512   }
4513
4514   /* create the labels */
4515   SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4516   ifFalse = newSymbol (buffer, NestLevel);
4517   /* if no else body then end == false */
4518   if (!elseBody)
4519     ifEnd = ifFalse;
4520   else
4521     {
4522       SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4523       ifEnd = newSymbol (buffer, NestLevel);
4524     }
4525
4526   SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4527   ifTrue = newSymbol (buffer, NestLevel);
4528
4529   Lblnum++;
4530
4531   /* attach the ifTrue label to the top of it body */
4532   ifBody = createLabel (ifTrue, ifBody);
4533   /* attach a goto end to the ifBody if else is present */
4534   if (elseBody)
4535     {
4536       ifBody = newNode (NULLOP, ifBody,
4537                         newNode (GOTO,
4538                                  newAst_VALUE (symbolVal (ifEnd)),
4539                                  NULL));
4540       /* put the elseLabel on the else body */
4541       elseBody = createLabel (ifFalse, elseBody);
4542       /* out the end at the end of the body */
4543       elseBody = newNode (NULLOP,
4544                           elseBody,
4545                           createLabel (ifEnd, NULL));
4546     }
4547   else
4548     {
4549       ifBody = newNode (NULLOP, ifBody,
4550                         createLabel (ifFalse, NULL));
4551     }
4552   condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4553   if (IS_IFX (condAst))
4554     ifTree = condAst;
4555   else
4556     ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4557
4558   return newNode (NULLOP, ifTree,
4559                   newNode (NULLOP, ifBody, elseBody));
4560
4561 }
4562
4563 /*-----------------------------------------------------------------*/
4564 /* createDo - creates parse tree for do                            */
4565 /*        _dobody_n:                                               */
4566 /*            statements                                           */
4567 /*        _docontinue_n:                                           */
4568 /*            condition_expression +-> trueLabel -> _dobody_n      */
4569 /*                                 |                               */
4570 /*                                 +-> falseLabel-> _dobreak_n     */
4571 /*        _dobreak_n:                                              */
4572 /*-----------------------------------------------------------------*/
4573 ast *
4574 createDo (symbol * trueLabel, symbol * continueLabel,
4575           symbol * falseLabel, ast * condAst, ast * doBody)
4576 {
4577   ast *doTree;
4578
4579
4580   /* if the body does not exist then it is simple */
4581   if (!doBody)
4582     {
4583       condAst = backPatchLabels (condAst, continueLabel, NULL);
4584       doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4585                 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4586       doTree->trueLabel = continueLabel;
4587       doTree->falseLabel = NULL;
4588       return doTree;
4589     }
4590
4591   /* otherwise we have a body */
4592   condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4593
4594   /* attach the body label to the top */
4595   doBody = createLabel (trueLabel, doBody);
4596   /* attach the continue label to end of body */
4597   doBody = newNode (NULLOP, doBody,
4598                     createLabel (continueLabel, NULL));
4599
4600   /* now put the break label at the end */
4601   if (IS_IFX (condAst))
4602     doTree = condAst;
4603   else
4604     doTree = newIfxNode (condAst, trueLabel, falseLabel);
4605
4606   doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4607
4608   /* putting it together */
4609   return newNode (NULLOP, doBody, doTree);
4610 }
4611
4612 /*-----------------------------------------------------------------*/
4613 /* createFor - creates parse tree for 'for' statement              */
4614 /*        initExpr                                                 */
4615 /*   _forcond_n:                                                   */
4616 /*        condExpr  +-> trueLabel -> _forbody_n                    */
4617 /*                  |                                              */
4618 /*                  +-> falseLabel-> _forbreak_n                   */
4619 /*   _forbody_n:                                                   */
4620 /*        statements                                               */
4621 /*   _forcontinue_n:                                               */
4622 /*        loopExpr                                                 */
4623 /*        goto _forcond_n ;                                        */
4624 /*   _forbreak_n:                                                  */
4625 /*-----------------------------------------------------------------*/
4626 ast *
4627 createFor (symbol * trueLabel, symbol * continueLabel,
4628            symbol * falseLabel, symbol * condLabel,
4629            ast * initExpr, ast * condExpr, ast * loopExpr,
4630            ast * forBody)
4631 {
4632   ast *forTree;
4633
4634   /* if loopexpression not present then we can generate it */
4635   /* the same way as a while */
4636   if (!loopExpr)
4637     return newNode (NULLOP, initExpr,
4638                     createWhile (trueLabel, continueLabel,
4639                                  falseLabel, condExpr, forBody));
4640   /* vanilla for statement */
4641   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4642
4643   if (condExpr && !IS_IFX (condExpr))
4644     condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4645
4646
4647   /* attach condition label to condition */
4648   condExpr = createLabel (condLabel, condExpr);
4649
4650   /* attach body label to body */
4651   forBody = createLabel (trueLabel, forBody);
4652
4653   /* attach continue to forLoop expression & attach */
4654   /* goto the forcond @ and of loopExpression       */
4655   loopExpr = createLabel (continueLabel,
4656                           newNode (NULLOP,
4657                                    loopExpr,
4658                                    newNode (GOTO,
4659                                        newAst_VALUE (symbolVal (condLabel)),
4660                                             NULL)));
4661   /* now start putting them together */
4662   forTree = newNode (NULLOP, initExpr, condExpr);
4663   forTree = newNode (NULLOP, forTree, forBody);
4664   forTree = newNode (NULLOP, forTree, loopExpr);
4665   /* finally add the break label */
4666   forTree = newNode (NULLOP, forTree,
4667                      createLabel (falseLabel, NULL));
4668   return forTree;
4669 }
4670
4671 /*-----------------------------------------------------------------*/
4672 /* createWhile - creates parse tree for while statement            */
4673 /*               the while statement will be created as follows    */
4674 /*                                                                 */
4675 /*      _while_continue_n:                                         */
4676 /*            condition_expression +-> trueLabel -> _while_boby_n  */
4677 /*                                 |                               */
4678 /*                                 +-> falseLabel -> _while_break_n */
4679 /*      _while_body_n:                                             */
4680 /*            statements                                           */
4681 /*            goto _while_continue_n                               */
4682 /*      _while_break_n:                                            */
4683 /*-----------------------------------------------------------------*/
4684 ast *
4685 createWhile (symbol * trueLabel, symbol * continueLabel,
4686              symbol * falseLabel, ast * condExpr, ast * whileBody)
4687 {
4688   ast *whileTree;
4689
4690   /* put the continue label */
4691   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4692   condExpr = createLabel (continueLabel, condExpr);
4693   condExpr->lineno = 0;
4694
4695   /* put the body label in front of the body */
4696   whileBody = createLabel (trueLabel, whileBody);
4697   whileBody->lineno = 0;
4698   /* put a jump to continue at the end of the body */
4699   /* and put break label at the end of the body */
4700   whileBody = newNode (NULLOP,
4701                        whileBody,
4702                        newNode (GOTO,
4703                                 newAst_VALUE (symbolVal (continueLabel)),
4704                                 createLabel (falseLabel, NULL)));
4705
4706   /* put it all together */
4707   if (IS_IFX (condExpr))
4708     whileTree = condExpr;
4709   else
4710     {
4711       whileTree = newNode (IFX, condExpr, NULL);
4712       /* put the true & false labels in place */
4713       whileTree->trueLabel = trueLabel;
4714       whileTree->falseLabel = falseLabel;
4715     }
4716
4717   return newNode (NULLOP, whileTree, whileBody);
4718 }
4719
4720 /*-----------------------------------------------------------------*/
4721 /* optimizeGetHbit - get highest order bit of the expression       */
4722 /*-----------------------------------------------------------------*/
4723 ast *
4724 optimizeGetHbit (ast * tree)
4725 {
4726   int i, j;
4727   /* if this is not a bit and */
4728   if (!IS_BITAND (tree))
4729     return tree;
4730
4731   /* will look for tree of the form
4732      ( expr >> ((sizeof expr) -1) ) & 1 */
4733   if (!IS_AST_LIT_VALUE (tree->right))
4734     return tree;
4735
4736   if (AST_LIT_VALUE (tree->right) != 1)
4737     return tree;
4738
4739   if (!IS_RIGHT_OP (tree->left))
4740     return tree;
4741
4742   if (!IS_AST_LIT_VALUE (tree->left->right))
4743     return tree;
4744
4745   if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4746       (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4747     return tree;
4748       
4749   /* make sure the port supports GETHBIT */
4750   if (port->hasExtBitOp
4751       && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4752     return tree;
4753
4754   return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_CHECK);
4755
4756 }
4757
4758 /*-----------------------------------------------------------------*/
4759 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry     */
4760 /*-----------------------------------------------------------------*/
4761 ast *
4762 optimizeRRCRLC (ast * root)
4763 {
4764   /* will look for trees of the form
4765      (?expr << 1) | (?expr >> 7) or
4766      (?expr >> 7) | (?expr << 1) will make that
4767      into a RLC : operation ..
4768      Will also look for
4769      (?expr >> 1) | (?expr << 7) or
4770      (?expr << 7) | (?expr >> 1) will make that
4771      into a RRC operation
4772      note : by 7 I mean (number of bits required to hold the
4773      variable -1 ) */
4774   /* if the root operations is not a | operation the not */
4775   if (!IS_BITOR (root))
4776     return root;
4777
4778   /* I have to think of a better way to match patterns this sucks */
4779   /* that aside let start looking for the first case : I use a the
4780      negative check a lot to improve the efficiency */
4781   /* (?expr << 1) | (?expr >> 7) */
4782   if (IS_LEFT_OP (root->left) &&
4783       IS_RIGHT_OP (root->right))
4784     {
4785
4786       if (!SPEC_USIGN (TETYPE (root->left->left)))
4787         return root;
4788
4789       if (!IS_AST_LIT_VALUE (root->left->right) ||
4790           !IS_AST_LIT_VALUE (root->right->right))
4791         goto tryNext0;
4792
4793       /* make sure it is the same expression */
4794       if (!isAstEqual (root->left->left,
4795                        root->right->left))
4796         goto tryNext0;
4797
4798       if (AST_LIT_VALUE (root->left->right) != 1)
4799         goto tryNext0;
4800
4801       if (AST_LIT_VALUE (root->right->right) !=
4802           (getSize (TTYPE (root->left->left)) * 8 - 1))
4803         goto tryNext0;
4804
4805       /* make sure the port supports RLC */
4806       if (port->hasExtBitOp
4807           && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4808         return root;
4809
4810       /* whew got the first case : create the AST */
4811       return newNode (RLC, root->left->left, NULL);
4812     }
4813
4814 tryNext0:
4815   /* check for second case */
4816   /* (?expr >> 7) | (?expr << 1) */
4817   if (IS_LEFT_OP (root->right) &&
4818       IS_RIGHT_OP (root->left))
4819     {
4820
4821       if (!SPEC_USIGN (TETYPE (root->left->left)))
4822         return root;
4823
4824       if (!IS_AST_LIT_VALUE (root->left->right) ||
4825           !IS_AST_LIT_VALUE (root->right->right))
4826         goto tryNext1;
4827
4828       /* make sure it is the same symbol */
4829       if (!isAstEqual (root->left->left,
4830                        root->right->left))
4831         goto tryNext1;
4832
4833       if (AST_LIT_VALUE (root->right->right) != 1)
4834         goto tryNext1;
4835
4836       if (AST_LIT_VALUE (root->left->right) !=
4837           (getSize (TTYPE (root->left->left)) * 8 - 1))
4838         goto tryNext1;
4839
4840       /* make sure the port supports RLC */
4841       if (port->hasExtBitOp
4842           && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4843         return root;
4844
4845       /* whew got the first case : create the AST */
4846       return newNode (RLC, root->left->left, NULL);
4847
4848     }
4849
4850 tryNext1:
4851   /* third case for RRC */
4852   /*  (?symbol >> 1) | (?symbol << 7) */
4853   if (IS_LEFT_OP (root->right) &&
4854       IS_RIGHT_OP (root->left))
4855     {
4856
4857       if (!SPEC_USIGN (TETYPE (root->left->left)))
4858         return root;
4859
4860       if (!IS_AST_LIT_VALUE (root->left->right) ||
4861           !IS_AST_LIT_VALUE (root->right->right))
4862         goto tryNext2;
4863
4864       /* make sure it is the same symbol */
4865       if (!isAstEqual (root->left->left,
4866                        root->right->left))
4867         goto tryNext2;
4868
4869       if (AST_LIT_VALUE (root->left->right) != 1)
4870         goto tryNext2;
4871
4872       if (AST_LIT_VALUE (root->right->right) !=
4873           (getSize (TTYPE (root->left->left)) * 8 - 1))
4874         goto tryNext2;
4875
4876       /* make sure the port supports RRC */
4877       if (port->hasExtBitOp
4878           && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4879         return root;
4880
4881       /* whew got the first case : create the AST */
4882       return newNode (RRC, root->left->left, NULL);
4883
4884     }
4885 tryNext2:
4886   /* fourth and last case for now */
4887   /* (?symbol << 7) | (?symbol >> 1) */
4888   if (IS_RIGHT_OP (root->right) &&
4889       IS_LEFT_OP (root->left))
4890     {
4891
4892       if (!SPEC_USIGN (TETYPE (root->left->left)))
4893         return root;
4894
4895       if (!IS_AST_LIT_VALUE (root->left->right) ||
4896           !IS_AST_LIT_VALUE (root->right->right))
4897         return root;
4898
4899       /* make sure it is the same symbol */
4900       if (!isAstEqual (root->left->left,
4901                        root->right->left))
4902         return root;
4903
4904       if (AST_LIT_VALUE (root->right->right) != 1)
4905         return root;
4906
4907       if (AST_LIT_VALUE (root->left->right) !=
4908           (getSize (TTYPE (root->left->left)) * 8 - 1))
4909         return root;
4910
4911       /* make sure the port supports RRC */
4912       if (port->hasExtBitOp
4913           && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4914         return root;
4915
4916       /* whew got the first case : create the AST */
4917       return newNode (RRC, root->left->left, NULL);
4918
4919     }
4920
4921   /* not found return root */
4922   return root;
4923 }
4924
4925 /*-----------------------------------------------------------------*/
4926 /* optimizeSWAP :- optimize for nibble/byte/word swaps             */
4927 /*-----------------------------------------------------------------*/
4928 ast *
4929 optimizeSWAP (ast * root)
4930 {
4931   /* will look for trees of the form
4932      (?expr << 4) | (?expr >> 4) or
4933      (?expr >> 4) | (?expr << 4) will make that
4934      into a SWAP : operation ..
4935      note : by 4 I mean (number of bits required to hold the
4936      variable /2 ) */
4937   /* if the root operations is not a | operation the not */
4938   if (!IS_BITOR (root))
4939     return root;
4940
4941   /* (?expr << 4) | (?expr >> 4) */
4942   if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
4943       || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
4944     {
4945
4946       if (!SPEC_USIGN (TETYPE (root->left->left)))
4947         return root;
4948
4949       if (!IS_AST_LIT_VALUE (root->left->right) ||
4950           !IS_AST_LIT_VALUE (root->right->right))
4951         return root;
4952
4953       /* make sure it is the same expression */
4954       if (!isAstEqual (root->left->left,
4955                        root->right->left))
4956         return root;
4957
4958       if (AST_LIT_VALUE (root->left->right) !=
4959           (getSize (TTYPE (root->left->left)) * 4))
4960         return root;
4961
4962       if (AST_LIT_VALUE (root->right->right) !=
4963           (getSize (TTYPE (root->left->left)) * 4))
4964         return root;
4965
4966       /* make sure the port supports SWAP */
4967       if (port->hasExtBitOp
4968           && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
4969         return root;
4970
4971       /* found it : create the AST */
4972       return newNode (SWAP, root->left->left, NULL);
4973     }
4974
4975
4976   /* not found return root */
4977   return root;
4978 }
4979
4980 /*-----------------------------------------------------------------*/
4981 /* optimizeCompare - otimizes compares for bit variables     */
4982 /*-----------------------------------------------------------------*/
4983 static ast *
4984 optimizeCompare (ast * root)
4985 {
4986   ast *optExpr = NULL;
4987   value *vleft;
4988   value *vright;
4989   unsigned int litValue;
4990
4991   /* if nothing then return nothing */
4992   if (!root)
4993     return NULL;
4994
4995   /* if not a compare op then do leaves */
4996   if (!IS_COMPARE_OP (root))
4997     {
4998       root->left = optimizeCompare (root->left);
4999       root->right = optimizeCompare (root->right);
5000       return root;
5001     }
5002
5003   /* if left & right are the same then depending
5004      of the operation do */
5005   if (isAstEqual (root->left, root->right))
5006     {
5007       switch (root->opval.op)
5008         {
5009         case '>':
5010         case '<':
5011         case NE_OP:
5012           optExpr = newAst_VALUE (constVal ("0"));
5013           break;
5014         case GE_OP:
5015         case LE_OP:
5016         case EQ_OP:
5017           optExpr = newAst_VALUE (constVal ("1"));
5018           break;
5019         }
5020
5021       return decorateType (optExpr, RESULT_CHECK);
5022     }
5023
5024   vleft = (root->left->type == EX_VALUE ?
5025            root->left->opval.val : NULL);
5026
5027   vright = (root->right->type == EX_VALUE ?
5028             root->right->opval.val : NULL);
5029
5030   /* if left is a BITVAR in BITSPACE */
5031   /* and right is a LITERAL then opt- */
5032   /* imize else do nothing       */
5033   if (vleft && vright &&
5034       IS_BITVAR (vleft->etype) &&
5035       IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5036       IS_LITERAL (vright->etype))
5037     {
5038
5039       /* if right side > 1 then comparison may never succeed */
5040       if ((litValue = (int) floatFromVal (vright)) > 1)
5041         {
5042           werror (W_BAD_COMPARE);
5043           goto noOptimize;
5044         }
5045
5046       if (litValue)
5047         {
5048           switch (root->opval.op)
5049             {
5050             case '>':           /* bit value greater than 1 cannot be */
5051               werror (W_BAD_COMPARE);
5052               goto noOptimize;
5053               break;
5054
5055             case '<':           /* bit value < 1 means 0 */
5056             case NE_OP:
5057               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5058               break;
5059
5060             case LE_OP: /* bit value <= 1 means no check */
5061               optExpr = newAst_VALUE (vright);
5062               break;
5063
5064             case GE_OP: /* bit value >= 1 means only check for = */
5065             case EQ_OP:
5066               optExpr = newAst_VALUE (vleft);
5067               break;
5068             }
5069         }
5070       else
5071         {                       /* literal is zero */
5072           switch (root->opval.op)
5073             {
5074             case '<':           /* bit value < 0 cannot be */
5075               werror (W_BAD_COMPARE);
5076               goto noOptimize;
5077               break;
5078
5079             case '>':           /* bit value > 0 means 1 */
5080             case NE_OP:
5081               optExpr = newAst_VALUE (vleft);
5082               break;
5083
5084             case LE_OP: /* bit value <= 0 means no check */
5085             case GE_OP: /* bit value >= 0 means no check */
5086               werror (W_BAD_COMPARE);
5087               goto noOptimize;
5088               break;
5089
5090             case EQ_OP: /* bit == 0 means ! of bit */
5091               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5092               break;
5093             }
5094         }
5095       return decorateType (resolveSymbols (optExpr), RESULT_CHECK);
5096     }                           /* end-of-if of BITVAR */
5097
5098 noOptimize:
5099   return root;
5100 }
5101 /*-----------------------------------------------------------------*/
5102 /* addSymToBlock : adds the symbol to the first block we find      */
5103 /*-----------------------------------------------------------------*/
5104 void 
5105 addSymToBlock (symbol * sym, ast * tree)
5106 {
5107   /* reached end of tree or a leaf */
5108   if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5109     return;
5110
5111   /* found a block */
5112   if (IS_AST_OP (tree) &&
5113       tree->opval.op == BLOCK)
5114     {
5115
5116       symbol *lsym = copySymbol (sym);
5117
5118       lsym->next = AST_VALUES (tree, sym);
5119       AST_VALUES (tree, sym) = lsym;
5120       return;
5121     }
5122
5123   addSymToBlock (sym, tree->left);
5124   addSymToBlock (sym, tree->right);
5125 }
5126
5127 /*-----------------------------------------------------------------*/
5128 /* processRegParms - do processing for register parameters         */
5129 /*-----------------------------------------------------------------*/
5130 static void 
5131 processRegParms (value * args, ast * body)
5132 {
5133   while (args)
5134     {
5135       if (IS_REGPARM (args->etype))
5136         addSymToBlock (args->sym, body);
5137       args = args->next;
5138     }
5139 }
5140
5141 /*-----------------------------------------------------------------*/
5142 /* resetParmKey - resets the operandkeys for the symbols           */
5143 /*-----------------------------------------------------------------*/
5144 DEFSETFUNC (resetParmKey)
5145 {
5146   symbol *sym = item;
5147
5148   sym->key = 0;
5149   sym->defs = NULL;
5150   sym->uses = NULL;
5151   sym->remat = 0;
5152   return 1;
5153 }
5154
5155 /*-----------------------------------------------------------------*/
5156 /* createFunction - This is the key node that calls the iCode for  */
5157 /*                  generating the code for a function. Note code  */
5158 /*                  is generated function by function, later when  */
5159 /*                  add inter-procedural analysis this will change */
5160 /*-----------------------------------------------------------------*/
5161 ast *
5162 createFunction (symbol * name, ast * body)
5163 {
5164   ast *ex;
5165   symbol *csym;
5166   int stack = 0;
5167   sym_link *fetype;
5168   iCode *piCode = NULL;
5169
5170   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5171     fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5172
5173   /* if check function return 0 then some problem */
5174   if (checkFunction (name, NULL) == 0)
5175     return NULL;
5176
5177   /* create a dummy block if none exists */
5178   if (!body)
5179     body = newNode (BLOCK, NULL, NULL);
5180
5181   noLineno++;
5182
5183   /* check if the function name already in the symbol table */
5184   if ((csym = findSym (SymbolTab, NULL, name->name)))
5185     {
5186       name = csym;
5187       /* special case for compiler defined functions
5188          we need to add the name to the publics list : this
5189          actually means we are now compiling the compiler
5190          support routine */
5191       if (name->cdef)
5192         {
5193           addSet (&publics, name);
5194         }
5195     }
5196   else
5197     {
5198       addSymChain (name);
5199       allocVariables (name);
5200     }
5201   name->lastLine = mylineno;
5202   currFunc = name;
5203
5204   /* set the stack pointer */
5205   /* PENDING: check this for the mcs51 */
5206   stackPtr = -port->stack.direction * port->stack.call_overhead;
5207   if (IFFUNC_ISISR (name->type))
5208     stackPtr -= port->stack.direction * port->stack.isr_overhead;
5209   if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5210     stackPtr -= port->stack.direction * port->stack.reent_overhead;
5211
5212   xstackPtr = -port->stack.direction * port->stack.call_overhead;
5213
5214   fetype = getSpec (name->type);        /* get the specifier for the function */
5215   /* if this is a reentrant function then */
5216   if (IFFUNC_ISREENT (name->type))
5217     reentrant++;
5218
5219   allocParms (FUNC_ARGS(name->type));   /* allocate the parameters */
5220
5221   /* do processing for parameters that are passed in registers */
5222   processRegParms (FUNC_ARGS(name->type), body);
5223
5224   /* set the stack pointer */
5225   stackPtr = 0;
5226   xstackPtr = -1;
5227
5228   /* allocate & autoinit the block variables */
5229   processBlockVars (body, &stack, ALLOCATE);
5230
5231   /* save the stack information */
5232   if (options.useXstack)
5233     name->xstack = SPEC_STAK (fetype) = stack;
5234   else
5235     name->stack = SPEC_STAK (fetype) = stack;
5236
5237   /* name needs to be mangled */
5238   SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5239
5240   body = resolveSymbols (body); /* resolve the symbols */
5241   body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5242                                         
5243
5244   ex = newAst_VALUE (symbolVal (name)); /* create name */
5245   ex = newNode (FUNCTION, ex, body);
5246   ex->values.args = FUNC_ARGS(name->type);
5247   ex->decorated=1;
5248   if (options.dump_tree) PA(ex);
5249   if (fatalError)
5250     {
5251       werror (E_FUNC_NO_CODE, name->name);
5252       goto skipall;
5253     }
5254
5255   /* create the node & generate intermediate code */
5256   GcurMemmap = code;
5257   codeOutFile = code->oFile;
5258   piCode = iCodeFromAst (ex);
5259
5260   if (fatalError)
5261     {
5262       werror (E_FUNC_NO_CODE, name->name);
5263       goto skipall;
5264     }
5265
5266   eBBlockFromiCode (piCode);
5267
5268   /* if there are any statics then do them */
5269   if (staticAutos)
5270     {
5271       GcurMemmap = statsg;
5272       codeOutFile = statsg->oFile;
5273       eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_CHECK)));
5274       staticAutos = NULL;
5275     }
5276
5277 skipall:
5278
5279   /* dealloc the block variables */
5280   processBlockVars (body, &stack, DEALLOCATE);
5281   outputDebugStackSymbols();
5282   /* deallocate paramaters */
5283   deallocParms (FUNC_ARGS(name->type));
5284
5285   if (IFFUNC_ISREENT (name->type))
5286     reentrant--;
5287
5288   /* we are done freeup memory & cleanup */
5289   noLineno--;
5290   if (port->reset_labelKey) labelKey = 1;
5291   name->key = 0;
5292   FUNC_HASBODY(name->type) = 1;
5293   addSet (&operKeyReset, name);
5294   applyToSet (operKeyReset, resetParmKey);
5295
5296   if (options.debug)
5297     cdbStructBlock(1);
5298
5299   cleanUpLevel (LabelTab, 0);
5300   cleanUpBlock (StructTab, 1);
5301   cleanUpBlock (TypedefTab, 1);
5302
5303   xstack->syms = NULL;
5304   istack->syms = NULL;
5305   return NULL;
5306 }
5307
5308
5309 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5310 /*-----------------------------------------------------------------*/
5311 /* ast_print : prints the ast (for debugging purposes)             */
5312 /*-----------------------------------------------------------------*/
5313
5314 void ast_print (ast * tree, FILE *outfile, int indent)
5315 {
5316
5317         if (!tree) return ;
5318
5319         /* can print only decorated trees */
5320         if (!tree->decorated) return;
5321
5322         /* if any child is an error | this one is an error do nothing */
5323         if (tree->isError ||
5324             (tree->left && tree->left->isError) ||
5325             (tree->right && tree->right->isError)) {
5326                 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5327         }
5328
5329
5330         /* print the line          */
5331         /* if not block & function */
5332         if (tree->type == EX_OP &&
5333             (tree->opval.op != FUNCTION &&
5334              tree->opval.op != BLOCK &&
5335              tree->opval.op != NULLOP)) {
5336         }
5337
5338         if (tree->opval.op == FUNCTION) {
5339                 int arg=0;
5340                 value *args=FUNC_ARGS(tree->left->opval.val->type);
5341                 fprintf(outfile,"FUNCTION (%s=%p) type (",
5342                         tree->left->opval.val->name, tree);
5343                 printTypeChain (tree->left->opval.val->type->next,outfile);
5344                 fprintf(outfile,") args (");
5345                 do {
5346                   if (arg) {
5347                     fprintf (outfile, ", ");
5348                   }
5349                   printTypeChain (args ? args->type : NULL, outfile);
5350                   arg++;
5351                   args= args ? args->next : NULL;
5352                 } while (args);
5353                 fprintf(outfile,")\n");
5354                 ast_print(tree->left,outfile,indent);
5355                 ast_print(tree->right,outfile,indent);
5356                 return ;
5357         }
5358         if (tree->opval.op == BLOCK) {
5359                 symbol *decls = tree->values.sym;
5360                 INDENT(indent,outfile);
5361                 fprintf(outfile,"{\n");
5362                 while (decls) {
5363                         INDENT(indent+2,outfile);
5364                         fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5365                                 decls->name, decls);
5366                         printTypeChain(decls->type,outfile);
5367                         fprintf(outfile,")\n");
5368
5369                         decls = decls->next;
5370                 }
5371                 ast_print(tree->right,outfile,indent+2);
5372                 INDENT(indent,outfile);
5373                 fprintf(outfile,"}\n");
5374                 return;
5375         }
5376         if (tree->opval.op == NULLOP) {
5377                 ast_print(tree->left,outfile,indent);
5378                 ast_print(tree->right,outfile,indent);
5379                 return ;
5380         }
5381         INDENT(indent,outfile);
5382
5383         /*------------------------------------------------------------------*/
5384         /*----------------------------*/
5385         /*   leaf has been reached    */
5386         /*----------------------------*/
5387         /* if this is of type value */
5388         /* just get the type        */
5389         if (tree->type == EX_VALUE) {
5390
5391                 if (IS_LITERAL (tree->opval.val->etype)) {
5392                         fprintf(outfile,"CONSTANT (%p) value = ", tree);
5393                         if (SPEC_USIGN (tree->opval.val->etype))
5394                                 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5395                         else
5396                                 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5397                         fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5398                                                       floatFromVal(tree->opval.val));
5399                 } else if (tree->opval.val->sym) {
5400                         /* if the undefined flag is set then give error message */
5401                         if (tree->opval.val->sym->undefined) {
5402                                 fprintf(outfile,"UNDEFINED SYMBOL ");
5403                         } else {
5404                                 fprintf(outfile,"SYMBOL ");
5405                         }
5406                         fprintf(outfile,"(%s=%p)",
5407                                 tree->opval.val->sym->name,tree);
5408                 }
5409                 if (tree->ftype) {
5410                         fprintf(outfile," type (");
5411                         printTypeChain(tree->ftype,outfile);
5412                         fprintf(outfile,")\n");
5413                 } else {
5414                         fprintf(outfile,"\n");
5415                 }
5416                 return ;
5417         }
5418
5419         /* if type link for the case of cast */
5420         if (tree->type == EX_LINK) {
5421                 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5422                 printTypeChain(tree->opval.lnk,outfile);
5423                 fprintf(outfile,")\n");
5424                 return ;
5425         }
5426
5427
5428         /* depending on type of operator do */
5429
5430         switch (tree->opval.op) {
5431                 /*------------------------------------------------------------------*/
5432                 /*----------------------------*/
5433                 /*        array node          */
5434                 /*----------------------------*/
5435         case '[':
5436                 fprintf(outfile,"ARRAY_OP (%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                 /*      struct/union          */
5446                 /*----------------------------*/
5447         case '.':
5448                 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5449                 printTypeChain(tree->ftype,outfile);
5450                 fprintf(outfile,")\n");
5451                 ast_print(tree->left,outfile,indent+2);
5452                 ast_print(tree->right,outfile,indent+2);
5453                 return ;
5454
5455                 /*------------------------------------------------------------------*/
5456                 /*----------------------------*/
5457                 /*    struct/union pointer    */
5458                 /*----------------------------*/
5459         case PTR_OP:
5460                 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5461                 printTypeChain(tree->ftype,outfile);
5462                 fprintf(outfile,")\n");
5463                 ast_print(tree->left,outfile,indent+2);
5464                 ast_print(tree->right,outfile,indent+2);
5465                 return ;
5466
5467                 /*------------------------------------------------------------------*/
5468                 /*----------------------------*/
5469                 /*  ++/-- operation           */
5470                 /*----------------------------*/
5471         case INC_OP:
5472                 if (tree->left)
5473                   fprintf(outfile,"post-");
5474                 else
5475                   fprintf(outfile,"pre-");
5476                 fprintf(outfile,"INC_OP (%p) type (",tree);
5477                 printTypeChain(tree->ftype,outfile);
5478                 fprintf(outfile,")\n");
5479                 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5480                 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5481                 return ;
5482
5483         case DEC_OP:
5484                 if (tree->left)
5485                   fprintf(outfile,"post-");
5486                 else
5487                   fprintf(outfile,"pre-");
5488                 fprintf(outfile,"DEC_OP (%p) type (",tree);
5489                 printTypeChain(tree->ftype,outfile);
5490                 fprintf(outfile,")\n");
5491                 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5492                 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5493                 return ;
5494
5495                 /*------------------------------------------------------------------*/
5496                 /*----------------------------*/
5497                 /*  bitwise and               */
5498                 /*----------------------------*/
5499         case '&':
5500                 if (tree->right) {
5501                         fprintf(outfile,"& (%p) type (",tree);
5502                         printTypeChain(tree->ftype,outfile);
5503                         fprintf(outfile,")\n");
5504                         ast_print(tree->left,outfile,indent+2);
5505                         ast_print(tree->right,outfile,indent+2);
5506                 } else {
5507                         fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5508                         printTypeChain(tree->ftype,outfile);
5509                         fprintf(outfile,")\n");
5510                         ast_print(tree->left,outfile,indent+2);
5511                         ast_print(tree->right,outfile,indent+2);
5512                 }
5513                 return ;
5514                 /*----------------------------*/
5515                 /*  bitwise or                */
5516                 /*----------------------------*/
5517         case '|':
5518                 fprintf(outfile,"OR (%p) type (",tree);
5519                 printTypeChain(tree->ftype,outfile);
5520                 fprintf(outfile,")\n");
5521                 ast_print(tree->left,outfile,indent+2);
5522                 ast_print(tree->right,outfile,indent+2);
5523                 return ;
5524                 /*------------------------------------------------------------------*/
5525                 /*----------------------------*/
5526                 /*  bitwise xor               */
5527                 /*----------------------------*/
5528         case '^':
5529                 fprintf(outfile,"XOR (%p) type (",tree);
5530                 printTypeChain(tree->ftype,outfile);
5531                 fprintf(outfile,")\n");
5532                 ast_print(tree->left,outfile,indent+2);
5533                 ast_print(tree->right,outfile,indent+2);
5534                 return ;
5535
5536                 /*------------------------------------------------------------------*/
5537                 /*----------------------------*/
5538                 /*  division                  */
5539                 /*----------------------------*/
5540         case '/':
5541                 fprintf(outfile,"DIV (%p) type (",tree);
5542                 printTypeChain(tree->ftype,outfile);
5543                 fprintf(outfile,")\n");
5544                 ast_print(tree->left,outfile,indent+2);
5545                 ast_print(tree->right,outfile,indent+2);
5546                 return ;
5547                 /*------------------------------------------------------------------*/
5548                 /*----------------------------*/
5549                 /*            modulus         */
5550                 /*----------------------------*/
5551         case '%':
5552                 fprintf(outfile,"MOD (%p) type (",tree);
5553                 printTypeChain(tree->ftype,outfile);
5554                 fprintf(outfile,")\n");
5555                 ast_print(tree->left,outfile,indent+2);
5556                 ast_print(tree->right,outfile,indent+2);
5557                 return ;
5558
5559                 /*------------------------------------------------------------------*/
5560                 /*----------------------------*/
5561                 /*  address dereference       */
5562                 /*----------------------------*/
5563         case '*':                       /* can be unary  : if right is null then unary operation */
5564                 if (!tree->right) {
5565                         fprintf(outfile,"DEREF (%p) type (",tree);
5566                         printTypeChain(tree->ftype,outfile);
5567                         fprintf(outfile,")\n");
5568                         ast_print(tree->left,outfile,indent+2);
5569                         return ;
5570                 }                       
5571                 /*------------------------------------------------------------------*/
5572                 /*----------------------------*/
5573                 /*      multiplication        */
5574                 /*----------------------------*/                
5575                 fprintf(outfile,"MULT (%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                 return ;
5581
5582
5583                 /*------------------------------------------------------------------*/
5584                 /*----------------------------*/
5585                 /*    unary '+' operator      */
5586                 /*----------------------------*/
5587         case '+':
5588                 /* if unary plus */
5589                 if (!tree->right) {
5590                         fprintf(outfile,"UPLUS (%p) type (",tree);
5591                         printTypeChain(tree->ftype,outfile);
5592                         fprintf(outfile,")\n");
5593                         ast_print(tree->left,outfile,indent+2);
5594                 } else {
5595                         /*------------------------------------------------------------------*/
5596                         /*----------------------------*/
5597                         /*      addition              */
5598                         /*----------------------------*/
5599                         fprintf(outfile,"ADD (%p) type (",tree);
5600                         printTypeChain(tree->ftype,outfile);
5601                         fprintf(outfile,")\n");
5602                         ast_print(tree->left,outfile,indent+2);
5603                         ast_print(tree->right,outfile,indent+2);
5604                 }
5605                 return;
5606                 /*------------------------------------------------------------------*/
5607                 /*----------------------------*/
5608                 /*      unary '-'             */
5609                 /*----------------------------*/
5610         case '-':                       /* can be unary   */
5611                 if (!tree->right) {
5612                         fprintf(outfile,"UMINUS (%p) type (",tree);
5613                         printTypeChain(tree->ftype,outfile);
5614                         fprintf(outfile,")\n");
5615                         ast_print(tree->left,outfile,indent+2);
5616                 } else {
5617                         /*------------------------------------------------------------------*/
5618                         /*----------------------------*/
5619                         /*      subtraction           */
5620                         /*----------------------------*/
5621                         fprintf(outfile,"SUB (%p) type (",tree);
5622                         printTypeChain(tree->ftype,outfile);
5623                         fprintf(outfile,")\n");
5624                         ast_print(tree->left,outfile,indent+2);
5625                         ast_print(tree->right,outfile,indent+2);
5626                 }
5627                 return;
5628                 /*------------------------------------------------------------------*/
5629                 /*----------------------------*/
5630                 /*    compliment              */
5631                 /*----------------------------*/
5632         case '~':
5633                 fprintf(outfile,"COMPL (%p) type (",tree);
5634                 printTypeChain(tree->ftype,outfile);
5635                 fprintf(outfile,")\n");
5636                 ast_print(tree->left,outfile,indent+2);
5637                 return ;
5638                 /*------------------------------------------------------------------*/
5639                 /*----------------------------*/
5640                 /*           not              */
5641                 /*----------------------------*/
5642         case '!':
5643                 fprintf(outfile,"NOT (%p) type (",tree);
5644                 printTypeChain(tree->ftype,outfile);
5645                 fprintf(outfile,")\n");
5646                 ast_print(tree->left,outfile,indent+2);
5647                 return ;
5648                 /*------------------------------------------------------------------*/
5649                 /*----------------------------*/
5650                 /*           shift            */
5651                 /*----------------------------*/
5652         case RRC:
5653                 fprintf(outfile,"RRC (%p) type (",tree);
5654                 printTypeChain(tree->ftype,outfile);
5655                 fprintf(outfile,")\n");
5656                 ast_print(tree->left,outfile,indent+2);
5657                 return ;
5658
5659         case RLC:
5660                 fprintf(outfile,"RLC (%p) type (",tree);
5661                 printTypeChain(tree->ftype,outfile);
5662                 fprintf(outfile,")\n");
5663                 ast_print(tree->left,outfile,indent+2);
5664                 return ;
5665         case SWAP:
5666                 fprintf(outfile,"SWAP (%p) type (",tree);
5667                 printTypeChain(tree->ftype,outfile);
5668                 fprintf(outfile,")\n");
5669                 ast_print(tree->left,outfile,indent+2);
5670                 return ;
5671         case GETHBIT:
5672                 fprintf(outfile,"GETHBIT (%p) type (",tree);
5673                 printTypeChain(tree->ftype,outfile);
5674                 fprintf(outfile,")\n");
5675                 ast_print(tree->left,outfile,indent+2);
5676                 return ;
5677         case LEFT_OP:
5678                 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5679                 printTypeChain(tree->ftype,outfile);
5680                 fprintf(outfile,")\n");
5681                 ast_print(tree->left,outfile,indent+2);
5682                 ast_print(tree->right,outfile,indent+2);
5683                 return ;
5684         case RIGHT_OP:
5685                 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5686                 printTypeChain(tree->ftype,outfile);
5687                 fprintf(outfile,")\n");
5688                 ast_print(tree->left,outfile,indent+2);
5689                 ast_print(tree->right,outfile,indent+2);
5690                 return ;
5691                 /*------------------------------------------------------------------*/
5692                 /*----------------------------*/
5693                 /*         casting            */
5694                 /*----------------------------*/
5695         case CAST:                      /* change the type   */
5696                 fprintf(outfile,"CAST (%p) from type (",tree);
5697                 printTypeChain(tree->right->ftype,outfile);
5698                 fprintf(outfile,") to type (");
5699                 printTypeChain(tree->ftype,outfile);
5700                 fprintf(outfile,")\n");
5701                 ast_print(tree->right,outfile,indent+2);
5702                 return ;
5703                 
5704         case AND_OP:
5705                 fprintf(outfile,"ANDAND (%p) type (",tree);
5706                 printTypeChain(tree->ftype,outfile);
5707                 fprintf(outfile,")\n");
5708                 ast_print(tree->left,outfile,indent+2);
5709                 ast_print(tree->right,outfile,indent+2);
5710                 return ;
5711         case OR_OP:
5712                 fprintf(outfile,"OROR (%p) type (",tree);
5713                 printTypeChain(tree->ftype,outfile);
5714                 fprintf(outfile,")\n");
5715                 ast_print(tree->left,outfile,indent+2);
5716                 ast_print(tree->right,outfile,indent+2);
5717                 return ;
5718                 
5719                 /*------------------------------------------------------------------*/
5720                 /*----------------------------*/
5721                 /*     comparison operators   */
5722                 /*----------------------------*/
5723         case '>':
5724                 fprintf(outfile,"GT(>) (%p) type (",tree);
5725                 printTypeChain(tree->ftype,outfile);
5726                 fprintf(outfile,")\n");
5727                 ast_print(tree->left,outfile,indent+2);
5728                 ast_print(tree->right,outfile,indent+2);
5729                 return ;
5730         case '<':
5731                 fprintf(outfile,"LT(<) (%p) type (",tree);
5732                 printTypeChain(tree->ftype,outfile);
5733                 fprintf(outfile,")\n");
5734                 ast_print(tree->left,outfile,indent+2);
5735                 ast_print(tree->right,outfile,indent+2);
5736                 return ;
5737         case LE_OP:
5738                 fprintf(outfile,"LE(<=) (%p) type (",tree);
5739                 printTypeChain(tree->ftype,outfile);
5740                 fprintf(outfile,")\n");
5741                 ast_print(tree->left,outfile,indent+2);
5742                 ast_print(tree->right,outfile,indent+2);
5743                 return ;
5744         case GE_OP:
5745                 fprintf(outfile,"GE(>=) (%p) type (",tree);
5746                 printTypeChain(tree->ftype,outfile);
5747                 fprintf(outfile,")\n");
5748                 ast_print(tree->left,outfile,indent+2);
5749                 ast_print(tree->right,outfile,indent+2);
5750                 return ;
5751         case EQ_OP:
5752                 fprintf(outfile,"EQ(==) (%p) type (",tree);
5753                 printTypeChain(tree->ftype,outfile);
5754                 fprintf(outfile,")\n");
5755                 ast_print(tree->left,outfile,indent+2);
5756                 ast_print(tree->right,outfile,indent+2);
5757                 return ;
5758         case NE_OP:
5759                 fprintf(outfile,"NE(!=) (%p) type (",tree);
5760                 printTypeChain(tree->ftype,outfile);
5761                 fprintf(outfile,")\n");
5762                 ast_print(tree->left,outfile,indent+2);
5763                 ast_print(tree->right,outfile,indent+2);
5764                 /*------------------------------------------------------------------*/
5765                 /*----------------------------*/
5766                 /*             sizeof         */
5767                 /*----------------------------*/
5768         case SIZEOF:            /* evaluate wihout code generation */
5769                 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5770                 return ;
5771
5772                 /*------------------------------------------------------------------*/
5773                 /*----------------------------*/
5774                 /* conditional operator  '?'  */
5775                 /*----------------------------*/
5776         case '?':
5777                 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5778                 printTypeChain(tree->ftype,outfile);
5779                 fprintf(outfile,")\n");
5780                 ast_print(tree->left,outfile,indent+2);
5781                 ast_print(tree->right,outfile,indent+2);
5782                 return;
5783
5784         case ':':
5785                 fprintf(outfile,"COLON(:) (%p) type (",tree);
5786                 printTypeChain(tree->ftype,outfile);
5787                 fprintf(outfile,")\n");
5788                 ast_print(tree->left,outfile,indent+2);
5789                 ast_print(tree->right,outfile,indent+2);
5790                 return ;
5791
5792                 /*------------------------------------------------------------------*/
5793                 /*----------------------------*/
5794                 /*    assignment operators    */
5795                 /*----------------------------*/
5796         case MUL_ASSIGN:
5797                 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5798                 printTypeChain(tree->ftype,outfile);
5799                 fprintf(outfile,")\n");
5800                 ast_print(tree->left,outfile,indent+2);
5801                 ast_print(tree->right,outfile,indent+2);
5802                 return;
5803         case DIV_ASSIGN:
5804                 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5805                 printTypeChain(tree->ftype,outfile);
5806                 fprintf(outfile,")\n");
5807                 ast_print(tree->left,outfile,indent+2);
5808                 ast_print(tree->right,outfile,indent+2);
5809                 return;
5810         case AND_ASSIGN:
5811                 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5812                 printTypeChain(tree->ftype,outfile);
5813                 fprintf(outfile,")\n");
5814                 ast_print(tree->left,outfile,indent+2);
5815                 ast_print(tree->right,outfile,indent+2);
5816                 return;
5817         case OR_ASSIGN:
5818                 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5819                 printTypeChain(tree->ftype,outfile);
5820                 fprintf(outfile,")\n");
5821                 ast_print(tree->left,outfile,indent+2);
5822                 ast_print(tree->right,outfile,indent+2);
5823                 return;
5824         case XOR_ASSIGN:
5825                 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5826                 printTypeChain(tree->ftype,outfile);
5827                 fprintf(outfile,")\n");
5828                 ast_print(tree->left,outfile,indent+2);
5829                 ast_print(tree->right,outfile,indent+2);
5830                 return;
5831         case RIGHT_ASSIGN:
5832                 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5833                 printTypeChain(tree->ftype,outfile);
5834                 fprintf(outfile,")\n");
5835                 ast_print(tree->left,outfile,indent+2);
5836                 ast_print(tree->right,outfile,indent+2);
5837                 return;
5838         case LEFT_ASSIGN:
5839                 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5840                 printTypeChain(tree->ftype,outfile);
5841                 fprintf(outfile,")\n");
5842                 ast_print(tree->left,outfile,indent+2);
5843                 ast_print(tree->right,outfile,indent+2);
5844                 return;
5845                 /*------------------------------------------------------------------*/
5846                 /*----------------------------*/
5847                 /*    -= operator             */
5848                 /*----------------------------*/
5849         case SUB_ASSIGN:
5850                 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5851                 printTypeChain(tree->ftype,outfile);
5852                 fprintf(outfile,")\n");
5853                 ast_print(tree->left,outfile,indent+2);
5854                 ast_print(tree->right,outfile,indent+2);
5855                 return;
5856                 /*------------------------------------------------------------------*/
5857                 /*----------------------------*/
5858                 /*          += operator       */
5859                 /*----------------------------*/
5860         case ADD_ASSIGN:
5861                 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5862                 printTypeChain(tree->ftype,outfile);
5863                 fprintf(outfile,")\n");
5864                 ast_print(tree->left,outfile,indent+2);
5865                 ast_print(tree->right,outfile,indent+2);
5866                 return;
5867                 /*------------------------------------------------------------------*/
5868                 /*----------------------------*/
5869                 /*      straight assignemnt   */
5870                 /*----------------------------*/
5871         case '=':
5872                 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5873                 printTypeChain(tree->ftype,outfile);
5874                 fprintf(outfile,")\n");
5875                 ast_print(tree->left,outfile,indent+2);
5876                 ast_print(tree->right,outfile,indent+2);
5877                 return;     
5878                 /*------------------------------------------------------------------*/
5879                 /*----------------------------*/
5880                 /*      comma operator        */
5881                 /*----------------------------*/
5882         case ',':
5883                 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5884                 printTypeChain(tree->ftype,outfile);
5885                 fprintf(outfile,")\n");
5886                 ast_print(tree->left,outfile,indent+2);
5887                 ast_print(tree->right,outfile,indent+2);
5888                 return;
5889                 /*------------------------------------------------------------------*/
5890                 /*----------------------------*/
5891                 /*       function call        */
5892                 /*----------------------------*/
5893         case CALL:
5894         case PCALL:
5895                 fprintf(outfile,"CALL (%p) type (",tree);
5896                 printTypeChain(tree->ftype,outfile);
5897                 fprintf(outfile,")\n");
5898                 ast_print(tree->left,outfile,indent+2);
5899                 ast_print(tree->right,outfile,indent+2);
5900                 return;
5901         case PARAM:
5902                 fprintf(outfile,"PARMS\n");
5903                 ast_print(tree->left,outfile,indent+2);
5904                 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5905                         ast_print(tree->right,outfile,indent+2);
5906                 }
5907                 return ;
5908                 /*------------------------------------------------------------------*/
5909                 /*----------------------------*/
5910                 /*     return statement       */
5911                 /*----------------------------*/
5912         case RETURN:
5913                 fprintf(outfile,"RETURN (%p) type (",tree);
5914                 if (tree->right) {
5915                     printTypeChain(tree->right->ftype,outfile);
5916                 }
5917                 fprintf(outfile,")\n");
5918                 ast_print(tree->right,outfile,indent+2);
5919                 return ;
5920                 /*------------------------------------------------------------------*/
5921                 /*----------------------------*/
5922                 /*     label statement        */
5923                 /*----------------------------*/
5924         case LABEL :
5925                 fprintf(outfile,"LABEL (%p)\n",tree);
5926                 ast_print(tree->left,outfile,indent+2);
5927                 ast_print(tree->right,outfile,indent);
5928                 return;
5929                 /*------------------------------------------------------------------*/
5930                 /*----------------------------*/
5931                 /*     switch statement       */
5932                 /*----------------------------*/
5933         case SWITCH:
5934                 {
5935                         value *val;
5936                         fprintf(outfile,"SWITCH (%p) ",tree);
5937                         ast_print(tree->left,outfile,0);
5938                         for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5939                                 INDENT(indent+2,outfile);
5940                                 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5941                                         (int) floatFromVal(val),
5942                                         tree->values.switchVals.swNum,
5943                                         (int) floatFromVal(val));
5944                         }
5945                         ast_print(tree->right,outfile,indent);
5946                 }
5947                 return ;
5948                 /*------------------------------------------------------------------*/
5949                 /*----------------------------*/
5950                 /* ifx Statement              */
5951                 /*----------------------------*/
5952         case IFX:
5953                 fprintf(outfile,"IF (%p) \n",tree);
5954                 ast_print(tree->left,outfile,indent+2);
5955                 if (tree->trueLabel) {
5956                         INDENT(indent+2,outfile);
5957                         fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5958                 }
5959                 if (tree->falseLabel) {
5960                         INDENT(indent+2,outfile);
5961                         fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5962                 }
5963                 ast_print(tree->right,outfile,indent+2);
5964                 return ;
5965                 /*----------------------------*/
5966                 /* goto Statement              */
5967                 /*----------------------------*/
5968         case GOTO:
5969                 fprintf(outfile,"GOTO (%p) \n",tree);
5970                 ast_print(tree->left,outfile,indent+2);
5971                 fprintf(outfile,"\n");
5972                 return ;
5973                 /*------------------------------------------------------------------*/
5974                 /*----------------------------*/
5975                 /* for Statement              */
5976                 /*----------------------------*/
5977         case FOR:
5978                 fprintf(outfile,"FOR (%p) \n",tree);
5979                 if (AST_FOR( tree, initExpr)) {
5980                         INDENT(indent+2,outfile);
5981                         fprintf(outfile,"INIT EXPR ");
5982                         ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5983                 }
5984                 if (AST_FOR( tree, condExpr)) {
5985                         INDENT(indent+2,outfile);
5986                         fprintf(outfile,"COND EXPR ");
5987                         ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5988                 }
5989                 if (AST_FOR( tree, loopExpr)) {
5990                         INDENT(indent+2,outfile);
5991                         fprintf(outfile,"LOOP EXPR ");
5992                         ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5993                 }
5994                 fprintf(outfile,"FOR LOOP BODY \n");
5995                 ast_print(tree->left,outfile,indent+2);
5996                 return ;
5997         case CRITICAL:
5998                 fprintf(outfile,"CRITICAL (%p) \n",tree);
5999                 ast_print(tree->left,outfile,indent+2);
6000         default:
6001             return ;
6002         }
6003 }
6004
6005 void PA(ast *t)
6006 {
6007         ast_print(t,stdout,0);
6008 }
6009
6010
6011
6012 /*-----------------------------------------------------------------*/
6013 /* astErrors : returns non-zero if errors present in tree          */
6014 /*-----------------------------------------------------------------*/
6015 int astErrors(ast *t)
6016 {
6017   int errors=0;
6018   
6019   if (t)
6020     {
6021       if (t->isError)
6022         errors++;
6023   
6024       if (t->type == EX_VALUE
6025           && t->opval.val->sym
6026           && t->opval.val->sym->undefined)
6027         errors++;
6028
6029       errors += astErrors(t->left);
6030       errors += astErrors(t->right);
6031     }
6032     
6033   return errors;
6034 }