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