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