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