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