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