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