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