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