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