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