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