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