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