Cleanup warnings by adding explicit casts
[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 #include "common.h"
26 #include "newalloc.h"
27
28 int currLineno  = 0;
29 set *astList = NULL ;
30 set *operKeyReset = NULL;
31 ast *staticAutos = NULL;
32 int labelKey = 1 ;
33
34 #define LRVAL(x) x->left->rvalue
35 #define RRVAL(x) x->right->rvalue
36 #define TRVAL(x) x->rvalue
37 #define LLVAL(x) x->left->lvalue
38 #define RLVAL(x) x->right->lvalue
39 #define TLVAL(x) x->lvalue
40 #define RTYPE(x) x->right->ftype
41 #define RETYPE(x) x->right->etype
42 #define LTYPE(x) x->left->ftype
43 #define LETYPE(x) x->left->etype
44 #define TTYPE(x) x->ftype
45 #define TETYPE(x) x->etype
46 #define ALLOCATE 1
47 #define DEALLOCATE 2
48
49 char  buffer[1024];
50 int noLineno = 0;
51 int noAlloc = 0 ;
52 symbol *currFunc ;
53 ast  *createIval  (ast *, sym_link *, initList *, ast *);
54 ast *createIvalCharPtr (ast *, sym_link *, ast *);
55 ast *optimizeRRCRLC ( ast * );
56 ast *optimizeGetHbit(ast *);
57 ast *backPatchLabels (ast *,symbol *,symbol *);
58 int  inInitMode = 0;
59 FILE *codeOutFile ;
60 int ptt(ast *tree) {
61     printTypeChain(tree->ftype,stdout);
62     return 0;
63 }
64
65
66 /*-----------------------------------------------------------------*/
67 /* newAst - creates a fresh node for an expression tree           */
68 /*-----------------------------------------------------------------*/
69 #if 0
70 ast  *newAst (int  type, void *op )
71 {
72     ast  *ex ;
73     static int oldLineno = 0 ;
74
75     Safe_calloc(1,ex,sizeof(ast));
76
77     ex->type = type ;
78     ex->lineno = (noLineno ? oldLineno : yylineno);
79     ex->filename = currFname ;
80     ex->level = NestLevel ;
81     ex->block = currBlockno ;
82     ex->initMode = inInitMode;
83
84     /* depending on the type */
85     switch (type)   {
86     case  EX_VALUE :
87   ex->opval.val = (value *) op;
88   break ;
89     case EX_OP     :
90   ex->opval.op   = (long) op ;
91   break ;
92     case EX_LINK   :
93   ex->opval.lnk  = (sym_link *) op;
94   break ;
95     case EX_STMNT  :
96   ex->opval.stmnt= (unsigned) op;
97     }
98
99     return ex;
100 }
101 #endif
102
103 static ast* newAst_(unsigned type)
104 {
105     ast  *ex ;
106     static int oldLineno = 0 ;
107
108     ex = Safe_calloc(1,sizeof(ast));
109
110     ex->type = type ;
111     ex->lineno = (noLineno ? oldLineno : yylineno);
112     ex->filename = currFname ;
113     ex->level = NestLevel ;
114     ex->block = currBlockno ;
115     ex->initMode = inInitMode;
116     return ex;
117 }
118
119 ast* newAst_VALUE(value*val)
120 {
121       ast* ex = newAst_(EX_VALUE);
122       ex->opval.val = val;
123       return ex;
124 }
125
126 ast* newAst_OP(unsigned op)
127 {
128       ast*ex = newAst_(EX_OP);
129       ex->opval.op = op;
130       return ex;
131 }
132
133 ast* newAst_LINK(sym_link*val)
134 {
135       ast* ex = newAst_(EX_LINK);
136       ex->opval.lnk = val;
137       return ex;
138 }
139
140 ast* newAst_STMNT(unsigned val)
141 {
142       ast* ex = newAst_(EX_STMNT);
143       ex->opval.stmnt = val;
144       return ex;
145 }
146
147 /*-----------------------------------------------------------------*/
148 /* newNode - creates a new node                                    */
149 /*-----------------------------------------------------------------*/
150 ast  *newNode ( long op,   ast  *left, ast *right   )
151 {
152     ast  *ex ;
153
154     ex = newAst_OP(op) ;
155     ex->left    = left ;
156     ex->right   = right;
157
158     return ex ;
159 }
160
161 /*-----------------------------------------------------------------*/
162 /* newIfxNode - creates a new Ifx Node                             */
163 /*-----------------------------------------------------------------*/
164 ast *newIfxNode (ast *condAst, symbol *trueLabel, symbol *falseLabel)
165 {
166     ast *ifxNode ;
167
168     /* if this is a literal then we already know the result */
169     if (condAst->etype && IS_LITERAL(condAst->etype)) {
170
171   /* then depending on the expression value */
172   if ( floatFromVal(condAst->opval.val) )
173         ifxNode = newNode(GOTO,
174         newAst_VALUE(symbolVal(trueLabel)),
175         NULL);
176   else
177         ifxNode = newNode(GOTO,
178         newAst_VALUE(symbolVal(falseLabel)),
179         NULL);
180     }
181     else {
182   ifxNode = newNode(IFX,condAst,NULL);
183   ifxNode->trueLabel = trueLabel;
184   ifxNode->falseLabel= falseLabel;
185     }
186
187     return ifxNode ;
188 }
189
190 /*-----------------------------------------------------------------*/
191 /* copyAstValues - copies value portion of ast if needed     */
192 /*-----------------------------------------------------------------*/
193 void copyAstValues (ast *dest,ast *src)
194 {
195     switch (src->opval.op) {
196     case BLOCK:
197   dest->values.sym     = copySymbolChain(src->values.sym);
198   break;
199
200     case SWITCH:
201   dest->values.switchVals.swVals =
202       copyValue(src->values.switchVals.swVals);
203   dest->values.switchVals.swDefault =
204       src->values.switchVals.swDefault ;
205   dest->values.switchVals.swNum  =
206       src->values.switchVals.swNum ;
207   break ;
208
209     case INLINEASM:
210   dest->values.inlineasm = Safe_calloc(1,strlen(src->values.inlineasm)+1);
211   strcpy(dest->values.inlineasm,src->values.inlineasm);
212
213     case FOR:
214    AST_FOR(dest,trueLabel) = copySymbol(AST_FOR(src,trueLabel));
215    AST_FOR(dest,continueLabel) = copySymbol(AST_FOR(src,continueLabel));
216    AST_FOR(dest,falseLabel) =  copySymbol(AST_FOR(src,falseLabel));
217    AST_FOR(dest,condLabel)  =  copySymbol(AST_FOR(src,condLabel));
218    AST_FOR(dest,initExpr)   =  copyAst (AST_FOR(src,initExpr)) ;
219    AST_FOR(dest,condExpr)   =  copyAst (AST_FOR(src,condExpr)) ;
220    AST_FOR(dest,loopExpr)   =  copyAst (AST_FOR(src,loopExpr)) ;
221     }
222
223 }
224
225 /*-----------------------------------------------------------------*/
226 /* copyAst - makes a copy of a given astession                     */
227 /*-----------------------------------------------------------------*/
228 ast  *copyAst (ast   *src)
229 {
230     ast  *dest;
231
232     if (!src)  return NULL ;
233
234     dest = Safe_calloc(1,sizeof(ast));
235
236     dest->type = src->type  ;
237     dest->lineno = src->lineno ;
238     dest->level  = src->level  ;
239     dest->funcName = src->funcName;
240     dest->argSym = src->argSym;
241
242     /* if this is a leaf */
243     /* if value */
244     if (src->type == EX_VALUE)   {
245   dest->opval.val = copyValue(src->opval.val);
246   goto exit;
247     }
248
249     /* if link */
250     if (src->type == EX_LINK)   {
251   dest->opval.lnk = copyLinkChain(src->opval.lnk);
252   goto exit ;
253     }
254
255     dest->opval.op = src->opval.op ;
256
257     /* if this is a node that has special values */
258     copyAstValues (dest,src);
259
260     if ( src->ftype )
261   dest->etype = getSpec(dest->ftype = copyLinkChain(src->ftype)) ;
262
263     dest->trueLabel = copySymbol (src->trueLabel);
264     dest->falseLabel= copySymbol (src->falseLabel);
265     dest->left = copyAst(src->left);
266     dest->right= copyAst(src->right);
267  exit:
268     return dest ;
269
270 }
271
272 /*-----------------------------------------------------------------*/
273 /* hasSEFcalls - returns TRUE if tree has a function call          */
274 /*-----------------------------------------------------------------*/
275 bool hasSEFcalls ( ast *tree)
276 {
277     if (!tree)
278   return FALSE ;
279
280     if (tree->type == EX_OP &&
281   ( tree->opval.op == CALL  ||
282     tree->opval.op == PCALL ||
283     tree->opval.op == '='   ||
284     tree->opval.op == INC_OP ||
285     tree->opval.op == DEC_OP ))
286   return TRUE;
287
288     return ( hasSEFcalls(tree->left) |
289        hasSEFcalls(tree->right));
290 }
291
292 /*-----------------------------------------------------------------*/
293 /* isAstEqual - compares two asts & returns 1 if they are equal    */
294 /*-----------------------------------------------------------------*/
295 int isAstEqual (ast *t1, ast *t2)
296 {
297     if (!t1 && !t2)
298   return 1;
299
300     if (!t1 || !t2)
301   return 0;
302
303     /* match type */
304     if (t1->type != t2->type)
305   return 0;
306
307     switch (t1->type) {
308     case EX_OP:
309   if (t1->opval.op != t2->opval.op)
310       return 0;
311   return ( isAstEqual(t1->left,t2->left) &&
312      isAstEqual(t1->right,t2->right));
313   break;
314
315     case EX_VALUE:
316   if (t1->opval.val->sym) {
317       if (!t2->opval.val->sym)
318     return 0;
319       else
320     return isSymbolEqual(t1->opval.val->sym,
321              t2->opval.val->sym);
322   }
323   else {
324       if (t2->opval.val->sym)
325     return 0;
326       else
327     return (floatFromVal(t1->opval.val) ==
328       floatFromVal(t2->opval.val));
329   }
330   break;
331
332   /* only compare these two types */
333     default :
334   return 0;
335     }
336
337     return 0;
338 }
339
340 /*-----------------------------------------------------------------*/
341 /* resolveSymbols - resolve symbols from the symbol table          */
342 /*-----------------------------------------------------------------*/
343 ast *resolveSymbols (ast *tree)
344 {
345     /* walk the entire tree and check for values */
346     /* with symbols if we find one then replace  */
347     /* symbol with that from the symbol table    */
348
349     if ( tree == NULL )
350   return tree ;
351
352     /* print the line          */
353     /* if not block & function */
354     if ( tree->type == EX_OP &&
355    ( tree->opval.op != FUNCTION  &&
356      tree->opval.op != BLOCK     &&
357      tree->opval.op != NULLOP    )) {
358   filename = tree->filename ;
359   lineno = tree->lineno ;
360     }
361
362     /* make sure we resolve the true & false labels for ifx */
363     if (tree->type == EX_OP && tree->opval.op == IFX ) {
364   symbol *csym ;
365
366   if (tree->trueLabel) {
367       if (( csym = findSym(LabelTab,tree->trueLabel,
368          tree->trueLabel->name)))
369     tree->trueLabel = csym ;
370       else
371     werror(E_LABEL_UNDEF,tree->trueLabel->name);
372   }
373
374   if (tree->falseLabel) {
375       if (( csym = findSym(LabelTab,
376          tree->falseLabel,
377          tree->falseLabel->name)))
378     tree->falseLabel = csym ;
379       else
380     werror(E_LABEL_UNDEF,tree->falseLabel->name);
381   }
382
383     }
384
385     /* if this is a label resolve it from the labelTab*/
386     if (IS_AST_VALUE(tree)   &&
387   tree->opval.val->sym &&
388   tree->opval.val->sym->islbl) {
389
390   symbol *csym = findSym (LabelTab, tree->opval.val->sym ,
391         tree->opval.val->sym->name);
392
393   if (!csym)
394       werror (E_LABEL_UNDEF,tree->opval.val->sym->name);
395   else
396       tree->opval.val->sym = csym ;
397
398   goto resolveChildren ;
399     }
400
401     /* do only for leafs */
402     if (IS_AST_VALUE(tree)   &&
403   tree->opval.val->sym &&
404   ! tree->opval.val->sym->implicit ) {
405
406   symbol *csym = findSymWithLevel (SymbolTab,tree->opval.val->sym);
407
408   /* if found in the symbol table & they r not the same */
409   if (csym && tree->opval.val->sym != csym ) {
410       tree->opval.val->sym = csym ;
411       tree->opval.val->type = csym->type;
412       tree->opval.val->etype = csym->etype;
413   }
414
415   /* if not found in the symbol table */
416   /* mark it as undefined assume it is*/
417   /* an integer in data space         */
418   if (!csym && !tree->opval.val->sym->implicit) {
419
420       /* if this is a function name then */
421       /* mark it as returning an int     */
422       if (tree->funcName) {
423     tree->opval.val->sym->type = newLink();
424     DCL_TYPE(tree->opval.val->sym->type) = FUNCTION;
425     tree->opval.val->sym->type->next =
426         tree->opval.val->sym->etype = newIntLink();
427     tree->opval.val->etype = tree->opval.val->etype;
428     tree->opval.val->type = tree->opval.val->sym->type;
429     werror(W_IMPLICIT_FUNC,tree->opval.val->sym->name);
430       } else {
431     tree->opval.val->sym->undefined =1 ;
432     tree->opval.val->type =
433         tree->opval.val->etype = newIntLink();
434     tree->opval.val->sym->type =
435         tree->opval.val->sym->etype = newIntLink();
436       }
437   }
438     }
439
440  resolveChildren:
441     resolveSymbols (tree->left);
442     resolveSymbols (tree->right);
443
444     return tree;
445 }
446
447 /*-----------------------------------------------------------------*/
448 /* setAstLineno - walks a ast tree & sets the line number          */
449 /*-----------------------------------------------------------------*/
450 int setAstLineno ( ast *tree, int lineno)
451 {
452     if (!tree)
453   return 0;
454
455     tree->lineno = lineno ;
456     setAstLineno ( tree->left, lineno);
457     setAstLineno ( tree->right, lineno);
458     return 0;
459 }
460
461 #if 0
462 /* this functions seems to be superfluous?! kmh */
463
464 /*-----------------------------------------------------------------*/
465 /* resolveFromTable - will return the symbal table value           */
466 /*-----------------------------------------------------------------*/
467 value *resolveFromTable (value *val)
468 {
469     symbol *csym ;
470
471     if (!val->sym)
472   return val;
473
474     csym = findSymWithLevel (SymbolTab,val->sym);
475
476     /* if found in the symbol table & they r not the same */
477     if (csym && val->sym != csym &&
478   csym->level == val->sym->level &&
479         csym->_isparm &&
480   !csym->ismyparm) {
481
482   val->sym = csym ;
483   val->type = csym->type;
484   val->etype = csym->etype;
485     }
486
487     return val;
488 }
489 #endif
490
491 /*-----------------------------------------------------------------*/
492 /* funcOfType :- function of type with name                        */
493 /*-----------------------------------------------------------------*/
494 symbol *funcOfType (char *name, sym_link *type, sym_link *argType,
495         int nArgs , int rent)
496 {
497     symbol *sym;
498     int argStack = 0;
499     /* create the symbol */
500     sym = newSymbol (name,0);
501
502     /* if arguments required */
503     if (nArgs) {
504
505   value *args ;
506   args = sym->args = newValue();
507
508   while (nArgs--) {
509       argStack += getSize(type);
510       args->type = copyLinkChain(argType);
511       args->etype = getSpec(args->type);
512       if (!nArgs)
513     break;
514       args = args->next = newValue();
515   }
516     }
517
518     /* setup return value */
519     sym->type = newLink();
520     DCL_TYPE(sym->type) = FUNCTION;
521     sym->type->next = copyLinkChain(type);
522     sym->etype = getSpec(sym->type);
523     SPEC_RENT(sym->etype) = rent;
524
525     /* save it */
526     addSymChain(sym);
527     sym->cdef = 1;
528     sym->argStack = (rent ? argStack : 0);
529     allocVariables (sym);
530     return sym;
531
532 }
533
534 /*-----------------------------------------------------------------*/
535 /* reverseParms - will reverse a parameter tree                    */
536 /*-----------------------------------------------------------------*/
537 void reverseParms (ast *ptree)
538 {
539     ast *ttree;
540     if (!ptree)
541   return ;
542
543     /* top down if we find a nonParm tree then quit */
544     if (ptree->type == EX_OP && ptree->opval.op == PARAM ) {
545   ttree = ptree->left;
546   ptree->left = ptree->right;
547   ptree->right = ttree;
548   reverseParms(ptree->left);
549   reverseParms(ptree->right);
550     }
551
552     return ;
553 }
554
555 /*-----------------------------------------------------------------*/
556 /* processParms  - makes sure the parameters are okay and do some  */
557 /*                 processing with them                            */
558 /*-----------------------------------------------------------------*/
559 int processParms (ast   *func,
560                   value *defParm,
561                   ast   *actParm,
562                   int   *parmNumber,
563                   bool  rightmost)
564 {
565     sym_link *fetype = func->etype;
566
567     /* if none of them exist */
568     if ( !defParm && !actParm)
569   return 0;
570
571     /* if the function is being called via a pointer &   */
572     /* it has not been defined a reentrant then we cannot*/
573     /* have parameters                                   */
574     if (func->type != EX_VALUE && !IS_RENT(fetype) && !options.stackAuto) {
575   werror (E_NONRENT_ARGS);
576   return 1;
577     }
578
579     /* if defined parameters ended but actual parameters */
580     /* exist and this is not defined as a variable arg   */
581     /* also check if statckAuto option is specified      */
582     if ((! defParm) && actParm && (!func->hasVargs ) &&
583   !options.stackAuto && !IS_RENT(fetype)) {
584   werror(E_TOO_MANY_PARMS);
585   return 1;
586     }
587
588     /* if defined parameters present but no actual parameters */
589     if ( defParm && ! actParm) {
590       werror(E_TOO_FEW_PARMS);
591       return 1;
592     }
593
594     /* If this is a varargs function... */
595     if (!defParm && actParm && func->hasVargs )
596     {
597         ast *newType = NULL;
598
599   if (IS_CAST_OP(actParm)
600    || (IS_AST_LIT_VALUE(actParm) && actParm->values.literalFromCast))
601   {
602      /* Parameter was explicitly typecast; don't touch it. */
603      return 0;
604   }
605
606         /* If it's a small integer, upcast to int. */
607       if (IS_INTEGRAL(actParm->ftype)
608          && getSize(actParm->ftype) < (unsigned) INTSIZE)
609         {
610       newType = newAst_LINK(INTTYPE);
611         }
612
613         if (IS_PTR(actParm->ftype) && !IS_GENPTR(actParm->ftype))
614         {
615             newType = newAst_LINK(copyLinkChain(actParm->ftype));
616             DCL_TYPE(newType->opval.lnk) = GPOINTER;
617         }
618
619         if (IS_AGGREGATE(actParm->ftype))
620         {
621             newType = newAst_LINK(copyLinkChain(actParm->ftype));
622             DCL_TYPE(newType->opval.lnk) = GPOINTER;
623         }
624
625         if (newType)
626         {
627           /* cast required; change this op to a cast. */
628             ast *parmCopy = resolveSymbols(copyAst(actParm));
629
630       actParm->type = EX_OP;
631       actParm->opval.op = CAST;
632       actParm->left = newType;
633       actParm->right= parmCopy;
634       decorateType(actParm);
635         }
636         else if ( actParm->type == EX_OP && actParm->opval.op == PARAM)
637       {
638       return (processParms(func,NULL,actParm->left,parmNumber,FALSE) ||
639               processParms(func,NULL,actParm->right,parmNumber,rightmost));
640         }
641         return 0;
642     }
643
644     /* if defined parameters ended but actual has not & */
645     /* stackAuto                */
646     if (! defParm && actParm &&
647   (options.stackAuto || IS_RENT(fetype)))
648   return 0;
649
650     resolveSymbols(actParm);
651     /* if this is a PARAM node then match left & right */
652     if ( actParm->type == EX_OP && actParm->opval.op == PARAM) 
653     {
654       return (processParms(func,defParm,actParm->left,parmNumber,FALSE) ||
655               processParms(func,defParm->next, actParm->right,parmNumber,rightmost));
656     }
657     else 
658     {
659         /* If we have found a value node by following only right-hand links,
660          * then we know that there are no more values after us.
661          *
662          * Therefore, if there are more defined parameters, the caller didn't
663          * supply enough.
664          */
665         if (rightmost && defParm->next) 
666         {
667             werror(E_TOO_FEW_PARMS);
668             return 1;
669         }
670     }
671     
672     /* the parameter type must be at least castable */
673     if (checkType(defParm->type,actParm->ftype) == 0) {
674   werror(E_TYPE_MISMATCH_PARM,*parmNumber);
675         werror(E_CONTINUE,"defined type ");
676   printTypeChain(defParm->type,stderr);fprintf(stderr,"\n");
677   werror(E_CONTINUE,"actual type ");
678   printTypeChain(actParm->ftype,stderr);fprintf(stderr,"\n");
679     }
680
681     /* if the parameter is castable then add the cast */
682     if ( checkType (defParm->type,actParm->ftype) < 0) {
683   ast *pTree = resolveSymbols(copyAst(actParm));
684
685   /* now change the current one to a cast */
686   actParm->type = EX_OP ;
687   actParm->opval.op = CAST ;
688   actParm->left = newAst_LINK(defParm->type);
689   actParm->right= pTree ;
690   actParm->etype= defParm->etype;
691   actParm->ftype= defParm->type;
692     }
693
694 /*    actParm->argSym = resolveFromTable(defParm)->sym ; */
695
696     actParm->argSym = defParm->sym;
697     /* make a copy and change the regparm type to the defined parm */
698     actParm->etype = getSpec(actParm->ftype = copyLinkChain(actParm->ftype));
699     SPEC_REGPARM(actParm->etype) = SPEC_REGPARM(defParm->etype);
700     (*parmNumber)++;
701     return 0;
702 }
703 /*-----------------------------------------------------------------*/
704 /* createIvalType - generates ival for basic types                 */
705 /*-----------------------------------------------------------------*/
706 ast *createIvalType ( ast *sym,sym_link  *type, initList *ilist)
707 {
708     ast *iExpr;
709
710     /* if initList is deep */
711     if ( ilist->type == INIT_DEEP )
712   ilist =  ilist->init.deep  ;
713
714     iExpr = decorateType(resolveSymbols(list2expr(ilist)));
715     return decorateType(newNode('=',sym,iExpr));
716 }
717
718 /*-----------------------------------------------------------------*/
719 /* createIvalStruct - generates initial value for structures       */
720 /*-----------------------------------------------------------------*/
721 ast *createIvalStruct (ast *sym,sym_link *type,initList *ilist)
722 {
723     ast *rast = NULL ;
724     symbol   *sflds  ;
725     initList *iloop  ;
726
727     sflds = SPEC_STRUCT(type)->fields  ;
728     if (ilist->type != INIT_DEEP) {
729   werror(E_INIT_STRUCT,"");
730   return NULL ;
731     }
732
733     iloop = ilist->init.deep;
734
735     for ( ; sflds ; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL )) {
736   ast *lAst ;
737
738   /* if we have come to end */
739   if (!iloop)
740       break;
741   sflds->implicit = 1;
742   lAst = newNode(PTR_OP,newNode('&',sym,NULL),newAst_VALUE(symbolVal(sflds)));
743   lAst = decorateType(resolveSymbols(lAst));
744   rast = decorateType(resolveSymbols(createIval (lAst, sflds->type, iloop,rast)));
745     }
746     return rast ;
747 }
748
749
750 /*-----------------------------------------------------------------*/
751 /* createIvalArray - generates code for array initialization       */
752 /*-----------------------------------------------------------------*/
753 ast *createIvalArray (ast  *sym, sym_link *type, initList *ilist)
754 {
755     ast *rast = NULL;
756     initList *iloop ;
757     int lcnt = 0, size =0 ;
758
759     /* take care of the special   case  */
760     /* array of characters can be init  */
761     /* by a string                      */
762     if ( IS_CHAR(type->next) )
763   if ( (rast = createIvalCharPtr(sym,
764                type,
765                decorateType(resolveSymbols(list2expr(ilist))))))
766
767       return decorateType(resolveSymbols(rast));
768
769     /* not the special case             */
770     if (ilist->type != INIT_DEEP) {
771   werror(E_INIT_STRUCT,"");
772   return NULL;
773     }
774
775     iloop = ilist->init.deep   ;
776     lcnt = DCL_ELEM(type);
777
778     for (;;)  {
779   ast *aSym ;
780   size++ ;
781
782   aSym = newNode('[',sym,newAst_VALUE(valueFromLit((float) (size-1))));
783   aSym = decorateType(resolveSymbols(aSym));
784   rast = createIval (aSym,type->next,iloop,rast)   ;
785   iloop = (iloop ? iloop->next : NULL) ;
786   if (!iloop)
787       break;
788   /* if not array limits given & we */
789   /* are out of initialisers then   */
790   if (!DCL_ELEM(type) && !iloop)
791       break ;
792
793   /* no of elements given and we    */
794   /* have generated for all of them */
795   if (!--lcnt)
796       break ;
797     }
798
799     /* if we have not been given a size  */
800     if (!DCL_ELEM(type))
801   DCL_ELEM(type) = size;
802
803     return decorateType(resolveSymbols(rast));
804 }
805
806
807 /*-----------------------------------------------------------------*/
808 /* createIvalCharPtr - generates initial values for char pointers  */
809 /*-----------------------------------------------------------------*/
810 ast *createIvalCharPtr (ast *sym, sym_link *type, ast *iexpr)
811 {
812     ast *rast = NULL ;
813
814     /* if this is a pointer & right is a literal array then */
815     /* just assignment will do                              */
816     if ( IS_PTR(type) && (( IS_LITERAL(iexpr->etype) ||
817     SPEC_SCLS(iexpr->etype) == S_CODE )
818         && IS_ARRAY(iexpr->ftype)))
819   return newNode('=',sym,iexpr);
820
821     /* left side is an array so we have to assign each */
822     /* element                                         */
823     if (( IS_LITERAL(iexpr->etype) ||
824     SPEC_SCLS(iexpr->etype) == S_CODE )
825   && IS_ARRAY(iexpr->ftype))  {
826
827   /* for each character generate an assignment */
828   /* to the array element */
829   char *s = SPEC_CVAL(iexpr->etype).v_char ;
830   int i = 0 ;
831
832   while (*s) {
833       rast = newNode(NULLOP,
834          rast,
835          newNode('=',
836            newNode('[', sym,
837              newAst_VALUE(valueFromLit((float) i))),
838            newAst_VALUE(valueFromLit(*s))));
839       i++;
840       s++;
841   }
842   rast = newNode(NULLOP,
843          rast,
844          newNode('=',
845            newNode('[', sym,
846              newAst_VALUE(valueFromLit((float) i))),
847            newAst_VALUE(valueFromLit(*s))));
848   return decorateType(resolveSymbols(rast));
849     }
850
851     return NULL ;
852 }
853
854 /*-----------------------------------------------------------------*/
855 /* createIvalPtr - generates initial value for pointers            */
856 /*-----------------------------------------------------------------*/
857 ast *createIvalPtr (ast *sym,sym_link *type,initList *ilist)
858 {
859     ast *rast;
860     ast *iexpr ;
861
862     /* if deep then   */
863     if ( ilist->type == INIT_DEEP )
864   ilist = ilist->init.deep   ;
865
866     iexpr = decorateType(resolveSymbols(list2expr(ilist)));
867
868     /* if character pointer */
869     if (IS_CHAR(type->next))
870   if ((rast = createIvalCharPtr (sym,type,iexpr)))
871       return rast;
872
873     return newNode('=',sym,iexpr);
874 }
875
876 /*-----------------------------------------------------------------*/
877 /* createIval - generates code for initial value                   */
878 /*-----------------------------------------------------------------*/
879 ast  *createIval  (ast *sym, sym_link *type, initList *ilist, ast *wid)
880 {
881     ast *rast = NULL;
882
883     if (!ilist)
884   return NULL ;
885
886     /* if structure then    */
887     if (IS_STRUCT(type))
888   rast =  createIvalStruct(sym, type,ilist);
889     else
890   /* if this is a pointer */
891   if (IS_PTR(type))
892       rast = createIvalPtr(sym, type,ilist);
893   else
894       /* if this is an array   */
895       if (IS_ARRAY(type))
896     rast = createIvalArray(sym, type,ilist);
897       else
898     /* if type is SPECIFIER */
899     if (IS_SPEC(type))
900         rast =  createIvalType (sym,type,ilist);
901     if ( wid )
902   return decorateType(resolveSymbols(newNode(NULLOP,wid,rast)));
903     else
904   return decorateType(resolveSymbols(rast)) ;
905 }
906
907 /*-----------------------------------------------------------------*/
908 /* initAggregates - initialises aggregate variables with initv     */
909 /*-----------------------------------------------------------------*/
910 ast *initAggregates ( symbol *sym, initList *ival, ast *wid)
911 {
912     return createIval (newAst_VALUE(symbolVal(sym)),sym->type,ival,wid);
913 }
914
915 /*-----------------------------------------------------------------*/
916 /* gatherAutoInit - creates assignment expressions for initial     */
917 /*    values                 */
918 /*-----------------------------------------------------------------*/
919 ast *gatherAutoInit ( symbol *autoChain )
920 {
921     ast *init = NULL ;
922     ast *work ;
923     symbol  *sym;
924
925     inInitMode =1;
926     for ( sym = autoChain ; sym ; sym = sym->next ) {
927
928   /* resolve the symbols in the ival */
929   if (sym->ival)
930       resolveIvalSym(sym->ival);
931
932   /* if this is a static variable & has an */
933   /* initial value the code needs to be lifted */
934   /* here to the main portion since they can be */
935   /* initialised only once at the start    */
936   if ( IS_STATIC(sym->etype) && sym->ival &&
937        SPEC_SCLS(sym->etype) != S_CODE) {
938       symbol *newSym ;
939
940       /* insert the symbol into the symbol table */
941       /* with level = 0 & name = rname       */
942       newSym = copySymbol (sym);
943       addSym (SymbolTab,newSym,newSym->name,0,0);
944
945       /* now lift the code to main */
946       if (IS_AGGREGATE(sym->type))
947     work = initAggregates (sym, sym->ival,NULL);
948       else
949     work = newNode('=' ,newAst_VALUE(symbolVal(newSym)),
950              list2expr(sym->ival));
951
952       setAstLineno(work,sym->lineDef);
953
954       sym->ival = NULL ;
955       if ( staticAutos )
956     staticAutos = newNode(NULLOP,staticAutos,work);
957       else
958     staticAutos = work ;
959
960       continue;
961   }
962
963   /* if there is an initial value */
964   if ( sym->ival && SPEC_SCLS(sym->etype)!=S_CODE) {
965       if (IS_AGGREGATE(sym->type))
966     work = initAggregates (sym,sym->ival,NULL);
967       else
968     work = newNode('=' ,newAst_VALUE(symbolVal(sym)),
969              list2expr(sym->ival));
970
971       setAstLineno (work,sym->lineDef);
972       sym->ival = NULL ;
973       if ( init )
974     init = newNode(NULLOP,init,work);
975       else
976     init = work ;
977   }
978     }
979     inInitMode = 0;
980     return init ;
981 }
982
983 /*-----------------------------------------------------------------*/
984 /* stringToSymbol - creates a symbol from a literal string         */
985 /*-----------------------------------------------------------------*/
986 static value *stringToSymbol (value *val)
987 {
988     char name[SDCC_NAME_MAX+1];
989     static int charLbl = 0;
990     symbol *sym ;
991
992     sprintf(name,"_str_%d",charLbl++);
993     sym = newSymbol(name,0); /* make it @ level 0 */
994     strcpy(sym->rname,name);
995
996     /* copy the type from the value passed */
997     sym->type = copyLinkChain(val->type);
998     sym->etype = getSpec(sym->type);
999     /* change to storage class & output class */
1000     SPEC_SCLS(sym->etype) = S_CODE ;
1001     SPEC_CVAL(sym->etype).v_char = SPEC_CVAL(val->etype).v_char ;
1002     SPEC_STAT(sym->etype) = 1;
1003     /* make the level & block = 0 */
1004     sym->block = sym->level = 0;
1005     sym->isstrlit = 1;
1006     /* create an ival */
1007     sym->ival = newiList(INIT_NODE,newAst_VALUE(val));
1008     if (noAlloc == 0) {
1009   /* allocate it */
1010   addSymChain(sym);
1011   allocVariables(sym);
1012     }
1013     sym->ival = NULL;
1014     return symbolVal(sym);
1015
1016 }
1017
1018 /*-----------------------------------------------------------------*/
1019 /* processBlockVars - will go thru the ast looking for block if    */
1020 /*                    a block is found then will allocate the syms */
1021 /*                    will also gather the auto inits present      */
1022 /*-----------------------------------------------------------------*/
1023 ast *processBlockVars ( ast *tree , int *stack, int action)
1024 {
1025     if (! tree)
1026   return NULL ;
1027
1028     /* if this is a block */
1029     if (tree->type == EX_OP && tree->opval.op == BLOCK ) {
1030   ast *autoInit ;
1031
1032   if (action == ALLOCATE) {
1033       autoInit = gatherAutoInit (tree->values.sym);
1034       *stack += allocVariables (tree->values.sym);
1035
1036       /* if there are auto inits then do them */
1037       if (autoInit)
1038     tree->left = newNode(NULLOP,autoInit,tree->left);
1039   } else /* action is deallocate */
1040       deallocLocal (tree->values.sym) ;
1041     }
1042
1043     processBlockVars (tree->left, stack, action);
1044     processBlockVars (tree->right, stack, action);
1045     return tree ;
1046 }
1047
1048 /*-----------------------------------------------------------------*/
1049 /* constExprValue - returns the value of a constant expression     */
1050 /*-----------------------------------------------------------------*/
1051 value *constExprValue (ast *cexpr, int check)
1052 {
1053     cexpr = decorateType(resolveSymbols(cexpr));
1054
1055     /* if this is not a constant then */
1056     if (!IS_LITERAL(cexpr->ftype)) {
1057   /* then check if this is a literal array
1058      in code segment */
1059   if (SPEC_SCLS(cexpr->etype) == S_CODE &&
1060       SPEC_CVAL(cexpr->etype).v_char    &&
1061       IS_ARRAY(cexpr->ftype)) {
1062       value *val = valFromType(cexpr->ftype);
1063       SPEC_SCLS(val->etype) = S_LITERAL;
1064       val->sym =cexpr->opval.val->sym ;
1065       val->sym->type = copyLinkChain(cexpr->ftype);
1066       val->sym->etype = getSpec(val->sym->type);
1067       strcpy(val->name,cexpr->opval.val->sym->rname);
1068       return val;
1069   }
1070
1071   /* if we are casting a literal value then */
1072   if (IS_AST_OP(cexpr)        &&
1073       cexpr->opval.op == CAST &&
1074       IS_LITERAL(cexpr->left->ftype))
1075       return valCastLiteral(cexpr->ftype,
1076           floatFromVal(cexpr->left->opval.val));
1077
1078   if (IS_AST_VALUE(cexpr))
1079       return cexpr->opval.val;
1080
1081   if (check)
1082       werror(E_CONST_EXPECTED,"found expression");
1083
1084   return NULL ;
1085     }
1086
1087     /* return the value */
1088     return cexpr->opval.val ;
1089
1090 }
1091
1092 /*-----------------------------------------------------------------*/
1093 /* isLabelInAst - will return true if a given label is found       */
1094 /*-----------------------------------------------------------------*/
1095 bool isLabelInAst (symbol *label, ast *tree)
1096 {
1097     if (!tree  || IS_AST_VALUE(tree) || IS_AST_LINK(tree))
1098   return FALSE ;
1099
1100     if (IS_AST_OP(tree) &&
1101   tree->opval.op == LABEL &&
1102   isSymbolEqual(AST_SYMBOL(tree->left),label))
1103   return TRUE;
1104
1105     return isLabelInAst(label,tree->right) &&
1106   isLabelInAst(label,tree->left);
1107
1108 }
1109
1110 /*-----------------------------------------------------------------*/
1111 /* isLoopCountable - return true if the loop count can be determi- */
1112 /* -ned at compile time .                                          */
1113 /*-----------------------------------------------------------------*/
1114 bool isLoopCountable (ast *initExpr, ast *condExpr, ast *loopExpr,
1115           symbol **sym,ast **init, ast **end)
1116 {
1117
1118     /* the loop is considered countable if the following
1119        conditions are true :-
1120
1121        a) initExpr :- <sym> = <const>
1122        b) condExpr :- <sym> < <const1>
1123        c) loopExpr :- <sym> ++
1124     */
1125
1126     /* first check the initExpr */
1127     if ( IS_AST_OP(initExpr)       &&
1128    initExpr->opval.op == '=' && /* is assignment */
1129    IS_AST_SYM_VALUE(initExpr->left)) { /* left is a symbol */
1130
1131   *sym = AST_SYMBOL(initExpr->left);
1132   *init= initExpr->right;
1133     }
1134     else
1135   return FALSE;
1136
1137     /* for now the symbol has to be of
1138        integral type */
1139     if (!IS_INTEGRAL((*sym)->type))
1140   return FALSE;
1141
1142     /* now check condExpr */
1143     if (IS_AST_OP(condExpr)) {
1144
1145   switch (condExpr->opval.op) {
1146   case '<':
1147       if (IS_AST_SYM_VALUE(condExpr->left) &&
1148     isSymbolEqual (*sym,AST_SYMBOL(condExpr->left)) &&
1149     IS_AST_LIT_VALUE(condExpr->right)) {
1150     *end = condExpr->right;
1151     break;
1152       }
1153       return FALSE;
1154
1155   case '!':
1156       if (IS_AST_OP(condExpr->left) &&
1157     condExpr->left->opval.op == '>' &&
1158     IS_AST_LIT_VALUE(condExpr->left->right) &&
1159     IS_AST_SYM_VALUE(condExpr->left->left)&&
1160     isSymbolEqual (*sym,AST_SYMBOL(condExpr->left->left))) {
1161
1162     *end = newNode('+', condExpr->left->right,
1163              newAst_VALUE(constVal("1")));
1164     break;
1165       }
1166       return FALSE ;
1167
1168   default:
1169       return FALSE ;
1170   }
1171
1172     }
1173
1174     /* check loop expression is of the form <sym>++ */
1175     if (!IS_AST_OP(loopExpr))
1176   return FALSE ;
1177
1178     /* check if <sym> ++ */
1179     if (loopExpr->opval.op == INC_OP) {
1180
1181   if (loopExpr->left) {
1182       /* pre */
1183       if (IS_AST_SYM_VALUE(loopExpr->left) &&
1184     isSymbolEqual(*sym,AST_SYMBOL(loopExpr->left)))
1185     return TRUE ;
1186
1187   } else {
1188       /* post */
1189       if (IS_AST_SYM_VALUE(loopExpr->right) &&
1190     isSymbolEqual(*sym,AST_SYMBOL(loopExpr->right)))
1191     return TRUE ;
1192   }
1193
1194     }
1195     else {
1196   /* check for += */
1197   if ( loopExpr->opval.op == ADD_ASSIGN ) {
1198
1199       if (IS_AST_SYM_VALUE(loopExpr->left) &&
1200     isSymbolEqual(*sym,AST_SYMBOL(loopExpr->left)) &&
1201     IS_AST_LIT_VALUE(loopExpr->right) &&
1202     (int)AST_LIT_VALUE(loopExpr->right) != 1)
1203     return TRUE ;
1204   }
1205     }
1206
1207     return FALSE;
1208 }
1209
1210 /*-----------------------------------------------------------------*/
1211 /* astHasVolatile - returns true if ast contains any volatile      */
1212 /*-----------------------------------------------------------------*/
1213 bool astHasVolatile (ast *tree)
1214 {
1215     if (!tree)
1216   return FALSE ;
1217
1218     if (TETYPE(tree) && IS_VOLATILE(TETYPE(tree)))
1219   return TRUE;
1220
1221     if (IS_AST_OP(tree))
1222   return astHasVolatile(tree->left) ||
1223       astHasVolatile(tree->right);
1224     else
1225   return FALSE ;
1226 }
1227
1228 /*-----------------------------------------------------------------*/
1229 /* astHasPointer - return true if the ast contains any ptr variable*/
1230 /*-----------------------------------------------------------------*/
1231 bool astHasPointer (ast *tree)
1232 {
1233     if (!tree)
1234   return FALSE ;
1235
1236     if (IS_AST_LINK(tree))
1237   return TRUE;
1238
1239     /* if we hit an array expression then check
1240        only the left side */
1241     if (IS_AST_OP(tree) && tree->opval.op == '[')
1242   return astHasPointer(tree->left);
1243
1244     if (IS_AST_VALUE(tree))
1245       return IS_PTR(tree->ftype) || IS_ARRAY(tree->ftype);
1246
1247     return astHasPointer(tree->left) ||
1248   astHasPointer(tree->right);
1249
1250 }
1251
1252 /*-----------------------------------------------------------------*/
1253 /* astHasSymbol - return true if the ast has the given symbol      */
1254 /*-----------------------------------------------------------------*/
1255 bool astHasSymbol (ast *tree, symbol *sym)
1256 {
1257     if (!tree || IS_AST_LINK(tree))
1258   return FALSE ;
1259
1260     if (IS_AST_VALUE(tree)) {
1261   if (IS_AST_SYM_VALUE(tree))
1262       return isSymbolEqual(AST_SYMBOL(tree),sym);
1263   else
1264       return FALSE;
1265     }
1266
1267     return astHasSymbol(tree->left,sym) ||
1268   astHasSymbol(tree->right,sym);
1269 }
1270
1271 /*-----------------------------------------------------------------*/
1272 /* isConformingBody - the loop body has to conform to a set of rules */
1273 /* for the loop to be considered reversible read on for rules      */
1274 /*-----------------------------------------------------------------*/
1275 bool isConformingBody (ast *pbody, symbol *sym, ast *body)
1276 {
1277
1278     /* we are going to do a pre-order traversal of the
1279        tree && check for the following conditions. (essentially
1280        a set of very shallow tests )
1281        a) the sym passed does not participate in
1282           any arithmetic operation
1283        b) There are no function calls
1284        c) all jumps are within the body
1285        d) address of loop control variable not taken
1286        e) if an assignment has a pointer on the
1287           left hand side make sure right does not have
1288     loop control variable */
1289
1290     /* if we reach the end or a leaf then true */
1291     if (!pbody ||  IS_AST_LINK(pbody) || IS_AST_VALUE(pbody))
1292   return TRUE ;
1293
1294
1295     /* if anything else is "volatile" */
1296     if (IS_VOLATILE(TETYPE(pbody)))
1297   return FALSE;
1298
1299     /* we will walk the body in a pre-order traversal for
1300        efficiency sake */
1301     switch (pbody->opval.op) {
1302     /*------------------------------------------------------------------*/
1303     case  '['   :
1304   return isConformingBody (pbody->right,sym,body);
1305
1306   /*------------------------------------------------------------------*/
1307     case  PTR_OP:
1308     case  '.'   :
1309   return TRUE;
1310
1311   /*------------------------------------------------------------------*/
1312     case  INC_OP:  /* incerement operator unary so left only */
1313     case  DEC_OP:
1314
1315   /* sure we are not sym is not modified */
1316   if (pbody->left                &&
1317       IS_AST_SYM_VALUE(pbody->left) &&
1318       isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1319       return FALSE;
1320
1321   if (pbody->right                &&
1322       IS_AST_SYM_VALUE(pbody->right) &&
1323       isSymbolEqual(AST_SYMBOL(pbody->right),sym))
1324       return FALSE;
1325
1326   return TRUE;
1327
1328   /*------------------------------------------------------------------*/
1329
1330     case '*' :  /* can be unary  : if right is null then unary operation */
1331     case '+' :
1332     case '-' :
1333     case  '&':
1334
1335   /* if right is NULL then unary operation  */
1336   /*------------------------------------------------------------------*/
1337   /*----------------------------*/
1338   /*  address of                */
1339   /*----------------------------*/
1340   if ( ! pbody->right ) {
1341       if (IS_AST_SYM_VALUE(pbody->left) &&
1342     isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1343     return FALSE;
1344       else
1345     return isConformingBody(pbody->left,sym,body) ;
1346   } else {
1347       if (astHasSymbol(pbody->left,sym) ||
1348     astHasSymbol(pbody->right,sym))
1349     return FALSE;
1350   }
1351
1352
1353   /*------------------------------------------------------------------*/
1354     case  '|':
1355     case  '^':
1356     case  '/':
1357     case  '%':
1358     case LEFT_OP:
1359     case RIGHT_OP:
1360
1361   if (IS_AST_SYM_VALUE(pbody->left) &&
1362       isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1363       return FALSE ;
1364
1365   if (IS_AST_SYM_VALUE(pbody->right) &&
1366       isSymbolEqual(AST_SYMBOL(pbody->right),sym))
1367       return FALSE ;
1368
1369   return isConformingBody(pbody->left,sym,body) &&
1370       isConformingBody(pbody->right,sym,body);
1371
1372     case '~' :
1373     case '!' :
1374     case RRC:
1375     case RLC:
1376     case GETHBIT:
1377   if (IS_AST_SYM_VALUE(pbody->left) &&
1378       isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1379       return FALSE;
1380   return isConformingBody (pbody->left,sym,body);
1381
1382   /*------------------------------------------------------------------*/
1383
1384     case AND_OP:
1385     case OR_OP:
1386     case '>' :
1387     case '<' :
1388     case LE_OP:
1389     case GE_OP:
1390     case EQ_OP:
1391     case NE_OP:
1392     case '?' :
1393     case ':' :
1394     case SIZEOF:  /* evaluate wihout code generation */
1395
1396   return isConformingBody(pbody->left,sym,body) &&
1397       isConformingBody(pbody->right,sym,body);
1398
1399   /*------------------------------------------------------------------*/
1400     case '=' :
1401
1402   /* if left has a pointer & right has loop
1403      control variable then we cannot */
1404   if (astHasPointer(pbody->left) &&
1405       astHasSymbol (pbody->right,sym))
1406       return FALSE ;
1407   if (astHasVolatile(pbody->left))
1408       return FALSE ;
1409
1410   if (IS_AST_SYM_VALUE(pbody->left) &&
1411       isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1412       return FALSE ;
1413
1414   if (astHasVolatile(pbody->left))
1415       return FALSE;
1416
1417   return isConformingBody(pbody->left,sym,body) &&
1418       isConformingBody(pbody->right,sym,body);
1419
1420     case MUL_ASSIGN:
1421     case DIV_ASSIGN:
1422     case AND_ASSIGN:
1423     case OR_ASSIGN:
1424     case XOR_ASSIGN:
1425     case RIGHT_ASSIGN:
1426     case LEFT_ASSIGN:
1427     case SUB_ASSIGN:
1428     case ADD_ASSIGN:
1429       assert("Parser should not have generated this\n");
1430
1431   /*------------------------------------------------------------------*/
1432   /*----------------------------*/
1433   /*      comma operator        */
1434   /*----------------------------*/
1435     case ',' :
1436   return isConformingBody(pbody->left,sym,body) &&
1437       isConformingBody(pbody->right,sym,body);
1438
1439   /*------------------------------------------------------------------*/
1440   /*----------------------------*/
1441   /*       function call        */
1442   /*----------------------------*/
1443     case CALL:
1444   return FALSE;
1445
1446   /*------------------------------------------------------------------*/
1447   /*----------------------------*/
1448   /*     return statement       */
1449   /*----------------------------*/
1450     case RETURN:
1451   return FALSE ;
1452
1453     case GOTO:
1454   if (isLabelInAst (AST_SYMBOL(pbody->left),body))
1455       return TRUE ;
1456   else
1457       return FALSE;
1458     case SWITCH:
1459   if (astHasSymbol(pbody->left,sym))
1460       return FALSE ;
1461
1462     default:
1463   break;
1464     }
1465
1466     return isConformingBody(pbody->left,sym,body) &&
1467   isConformingBody(pbody->right,sym,body);
1468
1469
1470
1471 }
1472
1473 /*-----------------------------------------------------------------*/
1474 /* isLoopReversible - takes a for loop as input && returns true    */
1475 /* if the for loop is reversible. If yes will set the value of     */
1476 /* the loop control var & init value & termination value           */
1477 /*-----------------------------------------------------------------*/
1478 bool isLoopReversible (ast *loop, symbol **loopCntrl,
1479            ast **init, ast **end )
1480 {
1481     /* if option says don't do it then don't */
1482     if (optimize.noLoopReverse)
1483   return 0;
1484     /* there are several tests to determine this */
1485
1486     /* for loop has to be of the form
1487        for ( <sym> = <const1> ;
1488              [<sym> < <const2>]  ;
1489        [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1490        forBody */
1491     if (! isLoopCountable (AST_FOR(loop,initExpr),
1492          AST_FOR(loop,condExpr),
1493          AST_FOR(loop,loopExpr),
1494          loopCntrl,init,end))
1495   return 0;
1496
1497     /* now do some serious checking on the body of the loop
1498      */
1499
1500     return isConformingBody(loop->left,*loopCntrl,loop->left);
1501
1502 }
1503
1504 /*-----------------------------------------------------------------*/
1505 /* replLoopSym - replace the loop sym by loop sym -1               */
1506 /*-----------------------------------------------------------------*/
1507 static void replLoopSym ( ast *body, symbol *sym)
1508 {
1509     /* reached end */
1510     if (!body || IS_AST_LINK(body))
1511   return ;
1512
1513     if (IS_AST_SYM_VALUE(body)) {
1514
1515   if (isSymbolEqual(AST_SYMBOL(body),sym)) {
1516
1517       body->type = EX_OP;
1518       body->opval.op = '-';
1519       body->left = newAst_VALUE(symbolVal(sym));
1520       body->right= newAst_VALUE(constVal("1"));
1521
1522   }
1523
1524   return;
1525
1526     }
1527
1528     replLoopSym(body->left,sym);
1529     replLoopSym(body->right,sym);
1530
1531 }
1532
1533 /*-----------------------------------------------------------------*/
1534 /* reverseLoop - do the actual loop reversal                       */
1535 /*-----------------------------------------------------------------*/
1536 ast *reverseLoop (ast *loop, symbol *sym, ast *init, ast *end)
1537 {
1538     ast *rloop ;
1539
1540     /* create the following tree
1541     <sym> = loopCount ;
1542    for_continue:
1543           forbody
1544     <sym> -= 1;
1545     if (sym) goto for_continue ;
1546     <sym> = end */
1547
1548     /* put it together piece by piece */
1549     rloop = newNode (NULLOP,
1550          createIf(newAst_VALUE(symbolVal(sym)),
1551             newNode(GOTO,
1552               newAst_VALUE(symbolVal(AST_FOR(loop,continueLabel))),
1553               NULL),NULL),
1554          newNode('=',
1555            newAst_VALUE(symbolVal(sym)),
1556            end));
1557
1558     replLoopSym(loop->left, sym);
1559
1560     rloop = newNode(NULLOP,
1561         newNode('=',
1562           newAst_VALUE(symbolVal(sym)),
1563           newNode('-',end,init)),
1564         createLabel(AST_FOR(loop,continueLabel),
1565         newNode(NULLOP,
1566           loop->left,
1567           newNode(NULLOP,
1568             newNode(SUB_ASSIGN,
1569               newAst_VALUE(symbolVal(sym)),
1570               newAst_VALUE(constVal("1"))),
1571             rloop ))));
1572
1573     return decorateType(rloop);
1574
1575 }
1576
1577 #define DEMAND_INTEGER_PROMOTION
1578
1579 #ifdef DEMAND_INTEGER_PROMOTION
1580
1581 /*-----------------------------------------------------------------*/
1582 /* walk a tree looking for the leaves. Add a typecast to the given */
1583 /* type to each value leaf node.           */
1584 /*-----------------------------------------------------------------*/
1585 void pushTypeCastToLeaves(sym_link *type, ast *node, ast **parentPtr)
1586 {
1587     if (!node)
1588     {
1589         /* WTF? We should never get here. */
1590         return;
1591     }
1592
1593     if (!node->left && !node->right)
1594     {
1595         /* We're at a leaf; if it's a value, apply the typecast */
1596         if (node->type == EX_VALUE && IS_INTEGRAL(TTYPE(node)))
1597         {
1598             *parentPtr = decorateType(newNode(CAST,
1599                             newAst_LINK(copyLinkChain(type)),
1600                             node));
1601   }
1602     }
1603     else
1604     {
1605       if (node->left)
1606       {
1607           pushTypeCastToLeaves(type, node->left, &(node->left));
1608       }
1609       if (node->right)
1610       {
1611             pushTypeCastToLeaves(type, node->right, &(node->right));
1612       }
1613     }
1614 }
1615
1616 #endif
1617
1618 /*-----------------------------------------------------------------*/
1619 /* Given an assignment operation in a tree, determine if the LHS   */
1620 /* (the result) has a different (integer) type than the RHS.     */
1621 /* If so, walk the RHS and add a typecast to the type of the LHS   */
1622 /* to all leaf nodes.              */
1623 /*-----------------------------------------------------------------*/
1624 void propAsgType(ast *tree)
1625 {
1626 #ifdef DEMAND_INTEGER_PROMOTION
1627     if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree)))
1628     {
1629       /* Nothing to do here... */
1630       return;
1631     }
1632
1633     if (getSize(LTYPE(tree)) > getSize(RTYPE(tree)))
1634     {
1635         pushTypeCastToLeaves(LTYPE(tree), tree->right, &(tree->right));
1636     }
1637 #else
1638     (void)tree;
1639 #endif
1640 }
1641
1642 /*-----------------------------------------------------------------*/
1643 /* decorateType - compute type for this tree also does type cheking*/
1644 /*          this is done bottom up, since type have to flow upwards*/
1645 /*          it also does constant folding, and paramater checking  */
1646 /*-----------------------------------------------------------------*/
1647 ast *decorateType (ast *tree)
1648 {
1649     int parmNumber ;
1650     sym_link *p;
1651
1652     if ( ! tree )
1653   return tree ;
1654
1655     /* if already has type then do nothing */
1656     if ( tree->decorated )
1657   return tree ;
1658
1659     tree->decorated = 1;
1660
1661     /* print the line          */
1662     /* if not block & function */
1663     if ( tree->type == EX_OP &&
1664    ( tree->opval.op != FUNCTION  &&
1665      tree->opval.op != BLOCK     &&
1666      tree->opval.op != NULLOP    )) {
1667   filename = tree->filename ;
1668   lineno = tree->lineno ;
1669     }
1670
1671     /* if any child is an error | this one is an error do nothing */
1672     if ( tree->isError ||
1673    ( tree->left && tree->left->isError) ||
1674    ( tree->right && tree->right->isError ))
1675   return tree ;
1676
1677     /*------------------------------------------------------------------*/
1678     /*----------------------------*/
1679     /*   leaf has been reached    */
1680     /*----------------------------*/
1681     /* if this is of type value */
1682     /* just get the type        */
1683     if ( tree->type == EX_VALUE ) {
1684
1685   if ( IS_LITERAL(tree->opval.val->etype) ) {
1686
1687       /* if this is a character array then declare it */
1688       if (IS_ARRAY(tree->opval.val->type))
1689     tree->opval.val = stringToSymbol(tree->opval.val);
1690
1691       /* otherwise just copy the type information */
1692       COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.val->type);
1693       if (funcInChain(tree->opval.val->type)) {
1694         tree->hasVargs = tree->opval.val->sym->hasVargs;
1695         tree->args = copyValueChain(tree->opval.val->sym->args) ;
1696       }
1697       return tree ;
1698   }
1699
1700   if ( tree->opval.val->sym ) {
1701       /* if the undefined flag is set then give error message */
1702     if (tree->opval.val->sym->undefined ) {
1703       werror(E_ID_UNDEF,tree->opval.val->sym->name) ;
1704       /* assume int */
1705       TTYPE(tree) = TETYPE(tree) =
1706         tree->opval.val->type = tree->opval.val->sym->type =
1707         tree->opval.val->etype = tree->opval.val->sym->etype =
1708         copyLinkChain(INTTYPE);
1709     }
1710     else {
1711
1712       /* if impilicit i.e. struct/union member then no type */
1713       if (tree->opval.val->sym->implicit )
1714         TTYPE(tree) = TETYPE(tree) = NULL ;
1715
1716       else {
1717
1718         /* else copy the type */
1719         COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.val->type);
1720
1721         /* and mark it as referenced */
1722         tree->opval.val->sym->isref = 1;
1723         /* if this is of type function or function pointer */
1724         if (funcInChain(tree->opval.val->type)) {
1725           tree->hasVargs = tree->opval.val->sym->hasVargs;
1726           tree->args = copyValueChain(tree->opval.val->sym->args) ;
1727
1728         }
1729       }
1730     }
1731   }
1732
1733   return tree ;
1734     }
1735
1736     /* if type link for the case of cast */
1737     if ( tree->type == EX_LINK ) {
1738   COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.lnk);
1739   return tree ;
1740     }
1741
1742     {
1743   ast *dtl, *dtr;
1744
1745   dtl = decorateType (tree->left);
1746   dtr = decorateType (tree->right);
1747
1748   /* this is to take care of situations
1749      when the tree gets rewritten */
1750   if (dtl != tree->left)
1751       tree->left = dtl;
1752   if (dtr != tree->right)
1753       tree->right = dtr;
1754     }
1755
1756     /* depending on type of operator do */
1757
1758     switch   (tree->opval.op) {
1759   /*------------------------------------------------------------------*/
1760   /*----------------------------*/
1761   /*        array node          */
1762   /*----------------------------*/
1763     case  '['   :
1764
1765   /* determine which is the array & which the index */
1766   if ((IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree))) && IS_INTEGRAL(LTYPE(tree))) {
1767
1768       ast *tempTree = tree->left ;
1769       tree->left = tree->right ;
1770       tree->right= tempTree ;
1771   }
1772
1773   /* first check if this is a array or a pointer */
1774   if ( (!IS_ARRAY(LTYPE(tree)))  && (!IS_PTR(LTYPE(tree)))) {
1775       werror(E_NEED_ARRAY_PTR,"[]");
1776       goto errorTreeReturn ;
1777   }
1778
1779   /* check if the type of the idx */
1780   if (!IS_INTEGRAL(RTYPE(tree))) {
1781       werror(E_IDX_NOT_INT);
1782       goto errorTreeReturn ;
1783   }
1784
1785   /* if the left is an rvalue then error */
1786   if (LRVAL(tree)) {
1787       werror(E_LVALUE_REQUIRED,"array access");
1788       goto errorTreeReturn ;
1789   }
1790   RRVAL(tree) = 1;
1791   COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree)->next);
1792   return tree;
1793
1794   /*------------------------------------------------------------------*/
1795   /*----------------------------*/
1796   /*      struct/union          */
1797   /*----------------------------*/
1798     case  '.'   :
1799   /* if this is not a structure */
1800   if (!IS_STRUCT(LTYPE(tree))) {
1801       werror(E_STRUCT_UNION,".");
1802       goto errorTreeReturn ;
1803   }
1804   TTYPE(tree) = structElemType (LTYPE(tree),
1805               (tree->right->type == EX_VALUE ?
1806                tree->right->opval.val : NULL ),&tree->args);
1807   TETYPE(tree) = getSpec(TTYPE(tree));
1808   return tree ;
1809
1810   /*------------------------------------------------------------------*/
1811   /*----------------------------*/
1812   /*    struct/union pointer    */
1813   /*----------------------------*/
1814     case  PTR_OP:
1815   /* if not pointer to a structure */
1816   if (!IS_PTR(LTYPE(tree)))  {
1817       werror(E_PTR_REQD);
1818       goto errorTreeReturn ;
1819   }
1820
1821   if (!IS_STRUCT(LTYPE(tree)->next))  {
1822       werror(E_STRUCT_UNION,"->");
1823       goto errorTreeReturn ;
1824   }
1825
1826   TTYPE(tree) = structElemType (LTYPE(tree)->next,
1827               (tree->right->type == EX_VALUE ?
1828                tree->right->opval.val : NULL ),&tree->args);
1829   TETYPE(tree) = getSpec(TTYPE(tree));
1830   return tree ;
1831
1832   /*------------------------------------------------------------------*/
1833   /*----------------------------*/
1834   /*  ++/-- operation           */
1835   /*----------------------------*/
1836     case  INC_OP:  /* incerement operator unary so left only */
1837     case  DEC_OP:
1838   {
1839       sym_link *ltc = (tree->right ? RTYPE(tree) : LTYPE(tree) );
1840       COPYTYPE(TTYPE(tree),TETYPE(tree),ltc);
1841       if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
1842     werror(E_CODE_WRITE,"++/--");
1843
1844       if (tree->right)
1845     RLVAL(tree) = 1;
1846       else
1847     LLVAL(tree) = 1;
1848       return tree ;
1849   }
1850
1851   /*------------------------------------------------------------------*/
1852   /*----------------------------*/
1853   /*  bitwise and               */
1854   /*----------------------------*/
1855     case  '&':     /* can be unary   */
1856   /* if right is NULL then unary operation  */
1857   if ( tree->right ) /* not an unary operation */ {
1858
1859       if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1860     werror(E_BITWISE_OP);
1861     werror(E_CONTINUE,"left & right types are ");
1862     printTypeChain(LTYPE(tree),stderr);
1863     fprintf(stderr,",");
1864     printTypeChain(RTYPE(tree),stderr);
1865     fprintf(stderr,"\n");
1866     goto errorTreeReturn ;
1867       }
1868
1869       /* if they are both literal */
1870       if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1871     tree->type = EX_VALUE ;
1872     tree->opval.val = valBitwise (valFromType(LETYPE(tree)),
1873                 valFromType(RETYPE(tree)),'&');
1874
1875     tree->right = tree->left = NULL;
1876     TETYPE(tree) = tree->opval.val->etype ;
1877     TTYPE(tree) =  tree->opval.val->type;
1878     return tree ;
1879       }
1880
1881       /* see if this is a GETHBIT operation if yes
1882          then return that */
1883       {
1884     ast *otree = optimizeGetHbit(tree);
1885
1886     if (otree != tree)
1887         return decorateType(otree);
1888       }
1889
1890       /* if right or left is literal then result of that type*/
1891       if (IS_LITERAL(RTYPE(tree))) {
1892
1893     TTYPE(tree) = copyLinkChain(RTYPE(tree));
1894     TETYPE(tree) = getSpec(TTYPE(tree));
1895     SPEC_SCLS(TETYPE(tree)) = S_AUTO;
1896       }
1897       else {
1898     if (IS_LITERAL(LTYPE(tree))) {
1899         TTYPE(tree) = copyLinkChain(LTYPE(tree));
1900         TETYPE(tree) = getSpec(TTYPE(tree));
1901         SPEC_SCLS(TETYPE(tree)) = S_AUTO;
1902
1903     }
1904     else {
1905         TTYPE(tree) =
1906       computeType (LTYPE(tree), RTYPE(tree));
1907         TETYPE(tree) = getSpec(TTYPE(tree));
1908     }
1909       }
1910       LRVAL(tree) = RRVAL(tree) = 1;
1911       return tree ;
1912   }
1913
1914   /*------------------------------------------------------------------*/
1915   /*----------------------------*/
1916   /*  address of                */
1917   /*----------------------------*/
1918   p = newLink();
1919   p->class = DECLARATOR;
1920   /* if bit field then error */
1921   if (IS_BITVAR(tree->left->etype)) {
1922       werror (E_ILLEGAL_ADDR,"addrress of bit variable");
1923       goto errorTreeReturn ;
1924   }
1925
1926   if (SPEC_SCLS(tree->left->etype)== S_REGISTER ) {
1927       werror (E_ILLEGAL_ADDR,"address of register variable");
1928       goto errorTreeReturn;
1929   }
1930
1931   if (IS_FUNC(LTYPE(tree))) {
1932       werror(E_ILLEGAL_ADDR,"address of function");
1933       goto errorTreeReturn ;
1934   }
1935
1936   if (LRVAL(tree)) {
1937       werror(E_LVALUE_REQUIRED,"address of");
1938       goto errorTreeReturn ;
1939   }
1940   if (SPEC_SCLS(tree->left->etype) == S_CODE) {
1941       DCL_TYPE(p) = CPOINTER ;
1942       DCL_PTR_CONST(p) = port->mem.code_ro;
1943   }
1944   else
1945       if (SPEC_SCLS(tree->left->etype) == S_XDATA)
1946     DCL_TYPE(p) = FPOINTER;
1947       else
1948     if (SPEC_SCLS(tree->left->etype) == S_XSTACK )
1949         DCL_TYPE(p) = PPOINTER ;
1950     else
1951         if (SPEC_SCLS(tree->left->etype) == S_IDATA)
1952       DCL_TYPE(p) = IPOINTER ;
1953         else
1954       if (SPEC_SCLS(tree->left->etype) == S_EEPROM)
1955           DCL_TYPE(p) = EEPPOINTER ;
1956       else
1957           DCL_TYPE(p) = POINTER ;
1958
1959   if (IS_AST_SYM_VALUE(tree->left)) {
1960       AST_SYMBOL(tree->left)->addrtaken = 1;
1961       AST_SYMBOL(tree->left)->allocreq = 1;
1962   }
1963
1964   p->next = LTYPE(tree);
1965   TTYPE(tree) = p;
1966   TETYPE(tree) = getSpec(TTYPE(tree));
1967   DCL_PTR_CONST(p) = SPEC_CONST(TETYPE(tree));
1968   DCL_PTR_VOLATILE(p) = SPEC_VOLATILE(TETYPE(tree));
1969   LLVAL(tree) = 1;
1970   TLVAL(tree) = 1;
1971   return tree ;
1972
1973   /*------------------------------------------------------------------*/
1974   /*----------------------------*/
1975   /*  bitwise or                */
1976   /*----------------------------*/
1977     case  '|':
1978   /* if the rewrite succeeds then don't go any furthur */
1979   {
1980       ast *wtree = optimizeRRCRLC ( tree );
1981       if (wtree != tree)
1982     return decorateType(wtree) ;
1983   }
1984   /*------------------------------------------------------------------*/
1985   /*----------------------------*/
1986   /*  bitwise xor               */
1987   /*----------------------------*/
1988     case  '^':
1989   if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1990       werror(E_BITWISE_OP);
1991       werror(E_CONTINUE,"left & right types are ");
1992       printTypeChain(LTYPE(tree),stderr);
1993       fprintf(stderr,",");
1994       printTypeChain(RTYPE(tree),stderr);
1995       fprintf(stderr,"\n");
1996       goto errorTreeReturn ;
1997   }
1998
1999   /* if they are both literal then */
2000   /* rewrite the tree */
2001   if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2002       tree->type = EX_VALUE ;
2003       tree->opval.val = valBitwise (valFromType(LETYPE(tree)),
2004             valFromType(RETYPE(tree)),
2005             tree->opval.op);
2006       tree->right = tree->left = NULL;
2007       TETYPE(tree) = tree->opval.val->etype;
2008       TTYPE(tree) = tree->opval.val->type;
2009       return tree ;
2010   }
2011   LRVAL(tree) = RRVAL(tree) = 1;
2012   TETYPE(tree) = getSpec (TTYPE(tree) =
2013         computeType(LTYPE(tree),
2014               RTYPE(tree)));
2015
2016   /*------------------------------------------------------------------*/
2017   /*----------------------------*/
2018   /*  division                  */
2019   /*----------------------------*/
2020     case  '/':
2021   if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) {
2022       werror(E_INVALID_OP,"divide");
2023       goto errorTreeReturn ;
2024   }
2025   /* if they are both literal then */
2026   /* rewrite the tree */
2027   if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2028       tree->type = EX_VALUE ;
2029       tree->opval.val = valDiv (valFromType(LETYPE(tree)),
2030               valFromType(RETYPE(tree)));
2031       tree->right = tree->left = NULL;
2032       TETYPE(tree) = getSpec(TTYPE(tree) =
2033            tree->opval.val->type);
2034       return tree ;
2035   }
2036   LRVAL(tree) = RRVAL(tree) = 1;
2037   TETYPE(tree) = getSpec (TTYPE(tree) =
2038         computeType(LTYPE(tree),
2039               RTYPE(tree)));
2040   return tree;
2041
2042   /*------------------------------------------------------------------*/
2043   /*----------------------------*/
2044   /*            modulus         */
2045   /*----------------------------*/
2046     case  '%':
2047   if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
2048       werror(E_BITWISE_OP);
2049       werror(E_CONTINUE,"left & right types are ");
2050       printTypeChain(LTYPE(tree),stderr);
2051       fprintf(stderr,",");
2052       printTypeChain(RTYPE(tree),stderr);
2053       fprintf(stderr,"\n");
2054       goto errorTreeReturn ;
2055   }
2056   /* if they are both literal then */
2057   /* rewrite the tree */
2058   if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2059       tree->type = EX_VALUE ;
2060       tree->opval.val = valMod (valFromType(LETYPE(tree)),
2061               valFromType(RETYPE(tree)));
2062       tree->right = tree->left = NULL;
2063       TETYPE(tree) = getSpec(TTYPE(tree) =
2064            tree->opval.val->type);
2065       return tree ;
2066   }
2067   LRVAL(tree) = RRVAL(tree) = 1;
2068   TETYPE(tree) = getSpec (TTYPE(tree) =
2069         computeType(LTYPE(tree),
2070               RTYPE(tree)));
2071   return tree;
2072
2073   /*------------------------------------------------------------------*/
2074   /*----------------------------*/
2075   /*  address dereference       */
2076   /*----------------------------*/
2077     case  '*':     /* can be unary  : if right is null then unary operation */
2078   if ( ! tree->right ) {
2079       if (!IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) {
2080     werror(E_PTR_REQD);
2081     goto errorTreeReturn ;
2082       }
2083
2084       if (LRVAL(tree)) {
2085     werror(E_LVALUE_REQUIRED,"pointer deref");
2086     goto errorTreeReturn ;
2087       }
2088       TTYPE(tree) = copyLinkChain ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) ?
2089            LTYPE(tree)->next : NULL );
2090       TETYPE(tree) = getSpec(TTYPE(tree));
2091       tree->args = tree->left->args ;
2092       tree->hasVargs = tree->left->hasVargs ;
2093       SPEC_CONST(TETYPE(tree)) = DCL_PTR_CONST(LTYPE(tree));
2094       return tree ;
2095   }
2096
2097   /*------------------------------------------------------------------*/
2098   /*----------------------------*/
2099   /*      multiplication        */
2100   /*----------------------------*/
2101   if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) {
2102       werror(E_INVALID_OP,"multiplication");
2103       goto errorTreeReturn ;
2104   }
2105
2106   /* if they are both literal then */
2107   /* rewrite the tree */
2108   if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2109       tree->type = EX_VALUE ;
2110       tree->opval.val = valMult (valFromType(LETYPE(tree)),
2111                valFromType(RETYPE(tree)));
2112       tree->right = tree->left = NULL;
2113       TETYPE(tree) = getSpec(TTYPE(tree) =
2114            tree->opval.val->type);
2115       return tree ;
2116   }
2117
2118   /* if left is a literal exchange left & right */
2119   if (IS_LITERAL(LTYPE(tree))) {
2120       ast *tTree = tree->left ;
2121       tree->left = tree->right ;
2122       tree->right= tTree ;
2123   }
2124
2125   LRVAL(tree) = RRVAL(tree) = 1;
2126   TETYPE(tree) = getSpec (TTYPE(tree) =
2127         computeType(LTYPE(tree),
2128               RTYPE(tree)));
2129   return tree ;
2130
2131   /*------------------------------------------------------------------*/
2132   /*----------------------------*/
2133   /*    unary '+' operator      */
2134   /*----------------------------*/
2135     case '+' :
2136   /* if unary plus */
2137   if ( ! tree->right ) {
2138       if (!IS_INTEGRAL(LTYPE(tree))) {
2139     werror(E_UNARY_OP,'+');
2140     goto errorTreeReturn ;
2141       }
2142
2143       /* if left is a literal then do it */
2144       if (IS_LITERAL(LTYPE(tree))) {
2145     tree->type = EX_VALUE ;
2146     tree->opval.val = valFromType(LETYPE(tree));
2147     tree->left = NULL ;
2148     TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2149     return tree ;
2150       }
2151       LRVAL(tree) = 1;
2152       COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2153       return tree ;
2154   }
2155
2156   /*------------------------------------------------------------------*/
2157   /*----------------------------*/
2158   /*      addition              */
2159   /*----------------------------*/
2160
2161   /* this is not a unary operation */
2162   /* if both pointers then problem */
2163   if ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) &&
2164       (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)))) {
2165       werror(E_PTR_PLUS_PTR);
2166       goto errorTreeReturn ;
2167   }
2168
2169   if (!IS_ARITHMETIC(LTYPE(tree)) &&
2170       !IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) {
2171       werror(E_PLUS_INVALID,"+");
2172       goto errorTreeReturn ;
2173   }
2174
2175   if (!IS_ARITHMETIC(RTYPE(tree)) &&
2176       !IS_PTR(RTYPE(tree)) && !IS_ARRAY(RTYPE(tree))) {
2177       werror(E_PLUS_INVALID,"+");
2178       goto errorTreeReturn;
2179   }
2180   /* if they are both literal then */
2181   /* rewrite the tree */
2182   if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2183       tree->type = EX_VALUE ;
2184       tree->opval.val = valPlus (valFromType(LETYPE(tree)),
2185                valFromType(RETYPE(tree)));
2186       tree->right = tree->left = NULL;
2187       TETYPE(tree) = getSpec(TTYPE(tree) =
2188            tree->opval.val->type);
2189       return tree ;
2190   }
2191
2192   /* if the right is a pointer or left is a literal
2193      xchange left & right */
2194   if (IS_ARRAY(RTYPE(tree)) ||
2195       IS_PTR(RTYPE(tree))   ||
2196       IS_LITERAL(LTYPE(tree))) {
2197       ast *tTree = tree->left ;
2198       tree->left = tree->right ;
2199       tree->right= tTree ;
2200   }
2201
2202   LRVAL(tree) = RRVAL(tree) = 1;
2203   /* if the left is a pointer */
2204   if (IS_PTR(LTYPE(tree)))
2205       TETYPE(tree) = getSpec(TTYPE(tree) =
2206            LTYPE(tree));
2207   else
2208       TETYPE(tree) = getSpec(TTYPE(tree) =
2209            computeType(LTYPE(tree),
2210                  RTYPE(tree)));
2211   return tree ;
2212
2213   /*------------------------------------------------------------------*/
2214   /*----------------------------*/
2215   /*      unary '-'             */
2216   /*----------------------------*/
2217     case '-' :  /* can be unary   */
2218   /* if right is null then unary */
2219   if ( ! tree->right ) {
2220
2221       if (!IS_ARITHMETIC(LTYPE(tree))) {
2222     werror(E_UNARY_OP,tree->opval.op);
2223     goto errorTreeReturn ;
2224       }
2225
2226       /* if left is a literal then do it */
2227       if (IS_LITERAL(LTYPE(tree))) {
2228     tree->type = EX_VALUE ;
2229     tree->opval.val = valUnaryPM(valFromType(LETYPE(tree)));
2230     tree->left = NULL ;
2231     TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2232     return tree ;
2233       }
2234       LRVAL(tree) = 1;
2235       TTYPE(tree) =  LTYPE(tree);
2236       return tree ;
2237   }
2238
2239   /*------------------------------------------------------------------*/
2240   /*----------------------------*/
2241   /*    subtraction             */
2242   /*----------------------------*/
2243
2244   if (!(IS_PTR(LTYPE(tree)) ||
2245         IS_ARRAY(LTYPE(tree)) ||
2246         IS_ARITHMETIC(LTYPE(tree)))) {
2247       werror(E_PLUS_INVALID,"-");
2248       goto errorTreeReturn ;
2249   }
2250
2251   if (!(IS_PTR(RTYPE(tree)) ||
2252         IS_ARRAY(RTYPE(tree)) ||
2253         IS_ARITHMETIC(RTYPE(tree)))) {
2254       werror(E_PLUS_INVALID,"-");
2255       goto errorTreeReturn ;
2256   }
2257
2258   if ( (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) &&
2259       ! (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)) ||
2260          IS_INTEGRAL(RTYPE(tree)))   ) {
2261       werror(E_PLUS_INVALID,"-");
2262       goto errorTreeReturn ;
2263   }
2264
2265   /* if they are both literal then */
2266   /* rewrite the tree */
2267   if (IS_LITERAL(RTYPE(tree)) &&  IS_LITERAL(LTYPE(tree))) {
2268       tree->type = EX_VALUE ;
2269       tree->opval.val = valMinus (valFromType(LETYPE(tree)),
2270           valFromType(RETYPE(tree)));
2271       tree->right = tree->left = NULL;
2272       TETYPE(tree) = getSpec(TTYPE(tree) =
2273            tree->opval.val->type);
2274       return tree ;
2275   }
2276
2277   /* if the left & right are equal then zero */
2278   if (isAstEqual(tree->left,tree->right)) {
2279       tree->type = EX_VALUE;
2280       tree->left = tree->right = NULL;
2281       tree->opval.val = constVal("0");
2282       TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2283       return tree;
2284   }
2285
2286   /* if both of them are pointers or arrays then */
2287   /* the result is going to be an integer        */
2288   if (( IS_ARRAY(LTYPE(tree)) || IS_PTR(LTYPE(tree))) &&
2289       ( IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree))))
2290       TETYPE(tree) = TTYPE(tree) = newIntLink();
2291   else
2292       /* if only the left is a pointer */
2293       /* then result is a pointer      */
2294       if (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree)))
2295     TETYPE(tree) = getSpec(TTYPE(tree) =
2296                LTYPE(tree));
2297       else
2298     TETYPE(tree) = getSpec (TTYPE(tree) =
2299           computeType(LTYPE(tree),
2300                 RTYPE(tree)));
2301   LRVAL(tree) = RRVAL(tree) = 1;
2302   return tree ;
2303
2304   /*------------------------------------------------------------------*/
2305   /*----------------------------*/
2306   /*    compliment              */
2307   /*----------------------------*/
2308     case '~' :
2309   /* can be only integral type */
2310   if (!IS_INTEGRAL(LTYPE(tree))) {
2311       werror(E_UNARY_OP,tree->opval.op);
2312       goto errorTreeReturn ;
2313   }
2314
2315   /* if left is a literal then do it */
2316   if (IS_LITERAL(LTYPE(tree))) {
2317       tree->type = EX_VALUE ;
2318       tree->opval.val = valComplement(valFromType(LETYPE(tree)));
2319       tree->left = NULL ;
2320       TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2321       return tree ;
2322   }
2323   LRVAL(tree) = 1;
2324   COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2325   return tree ;
2326
2327   /*------------------------------------------------------------------*/
2328   /*----------------------------*/
2329   /*           not              */
2330   /*----------------------------*/
2331     case '!' :
2332   /* can be pointer */
2333   if (!IS_ARITHMETIC(LTYPE(tree)) &&
2334       !IS_PTR(LTYPE(tree))        &&
2335       !IS_ARRAY(LTYPE(tree))) {
2336       werror(E_UNARY_OP,tree->opval.op);
2337       goto errorTreeReturn ;
2338   }
2339
2340   /* if left is a literal then do it */
2341   if (IS_LITERAL(LTYPE(tree))) {
2342       tree->type = EX_VALUE ;
2343       tree->opval.val = valNot(valFromType(LETYPE(tree)));
2344       tree->left = NULL ;
2345       TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2346       return tree ;
2347   }
2348   LRVAL(tree) = 1;
2349   TTYPE(tree) = TETYPE(tree) = newCharLink();
2350   return tree ;
2351
2352   /*------------------------------------------------------------------*/
2353   /*----------------------------*/
2354   /*           shift            */
2355   /*----------------------------*/
2356     case RRC:
2357     case RLC:
2358   TTYPE(tree) = LTYPE(tree);
2359   TETYPE(tree) = LETYPE(tree);
2360   return tree ;
2361
2362     case GETHBIT:
2363   TTYPE(tree) = TETYPE(tree) = newCharLink();
2364   return tree;
2365
2366     case LEFT_OP:
2367     case RIGHT_OP:
2368   if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(tree->left->etype)) {
2369       werror(E_SHIFT_OP_INVALID);
2370       werror(E_CONTINUE,"left & right types are ");
2371       printTypeChain(LTYPE(tree),stderr);
2372       fprintf(stderr,",");
2373       printTypeChain(RTYPE(tree),stderr);
2374       fprintf(stderr,"\n");
2375       goto errorTreeReturn ;
2376   }
2377
2378   /* if they are both literal then */
2379   /* rewrite the tree */
2380   if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2381       tree->type = EX_VALUE ;
2382       tree->opval.val = valShift (valFromType(LETYPE(tree)),
2383           valFromType(RETYPE(tree)),
2384           (tree->opval.op == LEFT_OP ? 1 : 0));
2385       tree->right = tree->left = NULL;
2386       TETYPE(tree) = getSpec(TTYPE(tree) =
2387            tree->opval.val->type);
2388       return tree ;
2389   }
2390   /* if only the right side is a literal & we are
2391      shifting more than size of the left operand then zero */
2392   if (IS_LITERAL(RTYPE(tree)) &&
2393       ((unsigned)floatFromVal( valFromType(RETYPE(tree)))) >=
2394       (getSize(LTYPE(tree))*8)) {
2395       werror(W_SHIFT_CHANGED,
2396        (tree->opval.op == LEFT_OP ? "left" : "right"));
2397       tree->type = EX_VALUE;
2398       tree->left = tree->right = NULL;
2399       tree->opval.val = constVal("0");
2400       TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2401       return tree;
2402   }
2403   LRVAL(tree) = RRVAL(tree) = 1;
2404   if (IS_LITERAL(LTYPE(tree)) && !IS_LITERAL(RTYPE(tree))) {
2405       COPYTYPE(TTYPE(tree),TETYPE(tree),RTYPE(tree));
2406   } else {
2407       COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2408   }
2409   return tree ;
2410
2411   /*------------------------------------------------------------------*/
2412   /*----------------------------*/
2413   /*         casting            */
2414   /*----------------------------*/
2415     case CAST:  /* change the type   */
2416   /* cannot cast to an aggregate type */
2417   if (IS_AGGREGATE(LTYPE(tree))) {
2418       werror(E_CAST_ILLEGAL);
2419       goto errorTreeReturn ;
2420   }
2421
2422   /* if the right is a literal replace the tree */
2423   if (IS_LITERAL(RETYPE(tree)) && !IS_PTR(LTYPE(tree))) {
2424       tree->type = EX_VALUE ;
2425       tree->opval.val =
2426     valCastLiteral(LTYPE(tree),
2427              floatFromVal(valFromType(RETYPE(tree))));
2428       tree->left = NULL;
2429       tree->right = NULL;
2430       TTYPE(tree) = tree->opval.val->type;
2431       tree->values.literalFromCast = 1;
2432   }
2433   else {
2434       TTYPE(tree) = LTYPE(tree);
2435       LRVAL(tree) = 1;
2436   }
2437
2438   TETYPE(tree) = getSpec(TTYPE(tree));
2439
2440   return tree;
2441
2442   /*------------------------------------------------------------------*/
2443   /*----------------------------*/
2444   /*       logical &&, ||       */
2445   /*----------------------------*/
2446     case AND_OP:
2447     case OR_OP:
2448   /* each must me arithmetic type or be a pointer */
2449   if (!IS_PTR(LTYPE(tree)) &&
2450       !IS_ARRAY(LTYPE(tree)) &&
2451       !IS_INTEGRAL(LTYPE(tree))) {
2452       werror(E_COMPARE_OP);
2453       goto errorTreeReturn ;
2454   }
2455
2456   if (!IS_PTR(RTYPE(tree)) &&
2457       !IS_ARRAY(RTYPE(tree)) &&
2458       !IS_INTEGRAL(RTYPE(tree))) {
2459       werror(E_COMPARE_OP);
2460       goto errorTreeReturn ;
2461   }
2462   /* if they are both literal then */
2463   /* rewrite the tree */
2464   if (IS_LITERAL(RTYPE(tree)) &&
2465       IS_LITERAL(LTYPE(tree))) {
2466       tree->type = EX_VALUE ;
2467       tree->opval.val = valLogicAndOr (valFromType(LETYPE(tree)),
2468                valFromType(RETYPE(tree)),
2469                tree->opval.op);
2470       tree->right = tree->left = NULL;
2471       TETYPE(tree) = getSpec(TTYPE(tree) =
2472            tree->opval.val->type);
2473       return tree ;
2474   }
2475   LRVAL(tree) = RRVAL(tree) = 1;
2476   TTYPE(tree) = TETYPE(tree) = newCharLink();
2477   return tree ;
2478
2479   /*------------------------------------------------------------------*/
2480   /*----------------------------*/
2481   /*     comparison operators   */
2482   /*----------------------------*/
2483     case '>' :
2484     case '<' :
2485     case LE_OP :
2486     case GE_OP :
2487     case EQ_OP :
2488     case NE_OP :
2489   {
2490       ast *lt = optimizeCompare(tree);
2491
2492       if ( tree != lt )
2493     return lt;
2494   }
2495
2496   /* if they are pointers they must be castable */
2497   if ( IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree))) {
2498       if (checkType(LTYPE(tree),RTYPE(tree)) == 0) {
2499     werror(E_COMPARE_OP);
2500     fprintf(stderr,"comparing type ");
2501     printTypeChain(LTYPE(tree),stderr);
2502     fprintf(stderr,"to type ");
2503     printTypeChain(RTYPE(tree),stderr);
2504     fprintf(stderr,"\n");
2505     goto errorTreeReturn ;
2506       }
2507   }
2508   /* else they should be promotable to one another */
2509   else {
2510       if (!(  ( IS_PTR(LTYPE(tree)) && IS_LITERAL(RTYPE(tree))) ||
2511         ( IS_PTR(RTYPE(tree)) && IS_LITERAL(LTYPE(tree)))))
2512
2513     if (checkType (LTYPE(tree),RTYPE(tree)) == 0 ) {
2514         werror(E_COMPARE_OP);
2515         fprintf(stderr,"comparing type ");
2516         printTypeChain(LTYPE(tree),stderr);
2517         fprintf(stderr,"to type ");
2518         printTypeChain(RTYPE(tree),stderr);
2519         fprintf(stderr,"\n");
2520         goto errorTreeReturn ;
2521     }
2522   }
2523
2524   /* if they are both literal then */
2525   /* rewrite the tree */
2526   if (IS_LITERAL(RTYPE(tree)) &&
2527       IS_LITERAL(LTYPE(tree))) {
2528       tree->type = EX_VALUE ;
2529       tree->opval.val = valCompare (valFromType(LETYPE(tree)),
2530             valFromType(RETYPE(tree)),
2531             tree->opval.op);
2532       tree->right = tree->left = NULL;
2533       TETYPE(tree) = getSpec(TTYPE(tree) =
2534            tree->opval.val->type);
2535       return tree ;
2536   }
2537   LRVAL(tree) = RRVAL(tree) = 1;
2538   TTYPE(tree) = TETYPE(tree) = newCharLink();
2539   return tree ;
2540
2541   /*------------------------------------------------------------------*/
2542   /*----------------------------*/
2543   /*             sizeof         */
2544   /*----------------------------*/
2545     case SIZEOF :  /* evaluate wihout code generation */
2546   /* change the type to a integer */
2547   tree->type = EX_VALUE;
2548   sprintf(buffer,"%d",(getSize(tree->right->ftype)));
2549   tree->opval.val = constVal(buffer);
2550   tree->right = tree->left = NULL;
2551   TETYPE(tree) = getSpec(TTYPE(tree) =
2552              tree->opval.val->type);
2553   return tree;
2554
2555   /*------------------------------------------------------------------*/
2556   /*----------------------------*/
2557   /* conditional operator  '?'  */
2558   /*----------------------------*/
2559     case '?' :
2560   /* the type is one on the left */
2561   TTYPE(tree) = LTYPE(tree);
2562   TETYPE(tree)= getSpec (TTYPE(tree));
2563   return tree ;
2564
2565     case ':' :
2566   /* if they don't match we have a problem */
2567   if (checkType( LTYPE(tree), RTYPE(tree)) == 0) {
2568       werror(E_TYPE_MISMATCH,"conditional operator"," ");
2569       goto errorTreeReturn ;
2570   }
2571
2572   TTYPE(tree) = computeType(LTYPE(tree),RTYPE(tree));
2573   TETYPE(tree)= getSpec(TTYPE(tree));
2574   return tree ;
2575
2576
2577   /*------------------------------------------------------------------*/
2578   /*----------------------------*/
2579   /*    assignment operators    */
2580   /*----------------------------*/
2581     case MUL_ASSIGN:
2582     case DIV_ASSIGN:
2583   /* for these it must be both must be integral */
2584   if (!IS_ARITHMETIC(LTYPE(tree)) ||
2585       !IS_ARITHMETIC(RTYPE(tree))) {
2586       werror (E_OPS_INTEGRAL);
2587       goto errorTreeReturn ;
2588   }
2589         RRVAL(tree) = 1;
2590   TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree));
2591
2592   if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2593       werror(E_CODE_WRITE," ");
2594
2595   if (LRVAL(tree)) {
2596       werror(E_LVALUE_REQUIRED,"*= or /=");
2597       goto errorTreeReturn ;
2598   }
2599   LLVAL(tree) = 1;
2600
2601   propAsgType(tree);
2602
2603   return tree ;
2604
2605     case AND_ASSIGN:
2606     case OR_ASSIGN:
2607     case XOR_ASSIGN:
2608     case RIGHT_ASSIGN:
2609     case LEFT_ASSIGN:
2610   /* for these it must be both must be integral */
2611   if (!IS_INTEGRAL(LTYPE(tree)) ||
2612       !IS_INTEGRAL(RTYPE(tree))) {
2613       werror (E_OPS_INTEGRAL);
2614       goto errorTreeReturn ;
2615   }
2616         RRVAL(tree) = 1;
2617   TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree));
2618
2619   if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2620       werror(E_CODE_WRITE," ");
2621
2622   if (LRVAL(tree)) {
2623       werror(E_LVALUE_REQUIRED,"&= or |= or ^= or >>= or <<=");
2624       goto errorTreeReturn ;
2625   }
2626   LLVAL(tree) = 1;
2627
2628   propAsgType(tree);
2629
2630   return tree ;
2631
2632   /*------------------------------------------------------------------*/
2633   /*----------------------------*/
2634   /*    -= operator             */
2635   /*----------------------------*/
2636     case SUB_ASSIGN:
2637   if (!(IS_PTR(LTYPE(tree))   ||
2638         IS_ARITHMETIC(LTYPE(tree)))) {
2639       werror(E_PLUS_INVALID,"-=");
2640       goto errorTreeReturn ;
2641   }
2642
2643   if (!(IS_PTR(RTYPE(tree))   ||
2644         IS_ARITHMETIC(RTYPE(tree)))) {
2645       werror(E_PLUS_INVALID,"-=");
2646       goto errorTreeReturn ;
2647   }
2648   RRVAL(tree) = 1;
2649   TETYPE(tree) = getSpec (TTYPE(tree) =
2650         computeType(LTYPE(tree),
2651               RTYPE(tree)));
2652
2653   if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2654       werror(E_CODE_WRITE," ");
2655
2656   if (LRVAL(tree)) {
2657       werror(E_LVALUE_REQUIRED,"-=");
2658       goto errorTreeReturn ;
2659   }
2660   LLVAL(tree) = 1;
2661
2662   propAsgType(tree);
2663
2664   return tree;
2665
2666   /*------------------------------------------------------------------*/
2667   /*----------------------------*/
2668   /*          += operator       */
2669   /*----------------------------*/
2670     case ADD_ASSIGN:
2671   /* this is not a unary operation */
2672   /* if both pointers then problem */
2673   if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) ) {
2674       werror(E_PTR_PLUS_PTR);
2675       goto errorTreeReturn ;
2676   }
2677
2678   if (!IS_ARITHMETIC(LTYPE(tree)) && !IS_PTR(LTYPE(tree)))  {
2679       werror(E_PLUS_INVALID,"+=");
2680       goto errorTreeReturn ;
2681   }
2682
2683   if (!IS_ARITHMETIC(RTYPE(tree)) && !IS_PTR(RTYPE(tree)))  {
2684       werror(E_PLUS_INVALID,"+=");
2685       goto errorTreeReturn;
2686   }
2687   RRVAL(tree) = 1;
2688   TETYPE(tree) = getSpec (TTYPE(tree) =
2689         computeType(LTYPE(tree),
2690               RTYPE(tree)));
2691
2692   if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2693       werror(E_CODE_WRITE," ");
2694
2695   if (LRVAL(tree)) {
2696       werror(E_LVALUE_REQUIRED,"+=");
2697       goto errorTreeReturn ;
2698   }
2699
2700   tree->right = decorateType(newNode('+',copyAst(tree->left),tree->right));
2701   tree->opval.op = '=';
2702
2703   propAsgType(tree);
2704
2705   return tree;
2706
2707   /*------------------------------------------------------------------*/
2708   /*----------------------------*/
2709   /*      straight assignemnt   */
2710   /*----------------------------*/
2711     case '=' :
2712   /* cannot be an aggregate */
2713   if (IS_AGGREGATE(LTYPE(tree))) {
2714       werror(E_AGGR_ASSIGN);
2715       goto errorTreeReturn;
2716   }
2717
2718   /* they should either match or be castable */
2719   if (checkType (LTYPE(tree),RTYPE(tree)) == 0) {
2720       werror(E_TYPE_MISMATCH,"assignment"," ");
2721       fprintf(stderr,"type --> '");
2722       printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' ");
2723       fprintf(stderr,"assigned to type --> '");
2724       printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n");
2725       goto errorTreeReturn ;
2726   }
2727
2728   /* if the left side of the tree is of type void
2729      then report error */
2730   if (IS_VOID(LTYPE(tree))) {
2731       werror(E_CAST_ZERO);
2732       fprintf(stderr,"type --> '");
2733       printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' ");
2734       fprintf(stderr,"assigned to type --> '");
2735       printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n");
2736   }
2737
2738   /* extra checks for pointer types */
2739   if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) &&
2740       !IS_GENPTR(LTYPE(tree))) {
2741     if (DCL_TYPE(LTYPE(tree)) != DCL_TYPE(RTYPE(tree)))
2742       werror(W_PTR_ASSIGN);
2743   }
2744
2745   TETYPE(tree) = getSpec(TTYPE(tree) =
2746              LTYPE(tree));
2747   RRVAL(tree) = 1;
2748   LLVAL(tree) = 1;
2749   if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2750       werror(E_CODE_WRITE," ");
2751
2752   if (LRVAL(tree)) {
2753       werror(E_LVALUE_REQUIRED,"=");
2754       goto errorTreeReturn ;
2755   }
2756
2757         propAsgType(tree);
2758
2759   return tree ;
2760
2761   /*------------------------------------------------------------------*/
2762   /*----------------------------*/
2763   /*      comma operator        */
2764   /*----------------------------*/
2765     case ',' :
2766   TETYPE(tree) = getSpec(TTYPE(tree) =  RTYPE(tree));
2767   return tree ;
2768
2769   /*------------------------------------------------------------------*/
2770   /*----------------------------*/
2771   /*       function call        */
2772   /*----------------------------*/
2773     case CALL   :
2774   parmNumber = 1;
2775
2776   if (processParms (tree->left,
2777         tree->left->args,
2778         tree->right,&parmNumber,TRUE))
2779       goto errorTreeReturn ;
2780
2781   if (options.stackAuto || IS_RENT(LETYPE(tree))) {
2782     tree->left->args = reverseVal(tree->left->args);
2783     reverseParms(tree->right);
2784   }
2785
2786   tree->args = tree->left->args ;
2787   TETYPE(tree) = getSpec (TTYPE(tree) = LTYPE(tree)->next);
2788   return tree;
2789
2790   /*------------------------------------------------------------------*/
2791   /*----------------------------*/
2792   /*     return statement       */
2793   /*----------------------------*/
2794     case RETURN :
2795   if (!tree->right)
2796       goto voidcheck ;
2797
2798   if (checkType(currFunc->type->next,RTYPE(tree)) == 0) {
2799       werror(E_RETURN_MISMATCH);
2800       goto errorTreeReturn ;
2801   }
2802
2803   if (IS_VOID(currFunc->type->next)
2804       && tree->right &&
2805       !IS_VOID(RTYPE(tree))) {
2806       werror(E_FUNC_VOID);
2807       goto errorTreeReturn ;
2808   }
2809
2810   /* if there is going to be a casing required then add it */
2811   if (checkType(currFunc->type->next,RTYPE(tree)) < 0 )
2812   {
2813 #if 0 && defined DEMAND_INTEGER_PROMOTION
2814       if (IS_INTEGRAL(currFunc->type->next))
2815       {
2816         pushTypeCastToLeaves(currFunc->type->next, tree->right, &(tree->right));
2817       }
2818       else
2819 #endif
2820       {
2821         tree->right =
2822     decorateType(newNode(CAST,
2823              newAst_LINK(copyLinkChain(currFunc->type->next)),
2824              tree->right));
2825       }
2826   }
2827
2828   RRVAL(tree) = 1;
2829   return tree;
2830
2831   voidcheck :
2832
2833   if (!IS_VOID(currFunc->type->next) && tree->right == NULL ) {
2834       werror(E_VOID_FUNC,currFunc->name);
2835       goto errorTreeReturn ;
2836   }
2837
2838   TTYPE(tree) = TETYPE(tree) = NULL ;
2839   return tree ;
2840
2841   /*------------------------------------------------------------------*/
2842   /*----------------------------*/
2843   /*     switch statement       */
2844   /*----------------------------*/
2845     case SWITCH:
2846   /* the switch value must be an integer */
2847   if (!IS_INTEGRAL(LTYPE(tree))) {
2848       werror (E_SWITCH_NON_INTEGER);
2849       goto errorTreeReturn ;
2850   }
2851   LRVAL(tree) = 1;
2852   TTYPE(tree) = TETYPE(tree) = NULL ;
2853   return tree ;
2854
2855   /*------------------------------------------------------------------*/
2856   /*----------------------------*/
2857   /* ifx Statement              */
2858   /*----------------------------*/
2859     case IFX:
2860   tree->left = backPatchLabels(tree->left,
2861              tree->trueLabel,
2862              tree->falseLabel);
2863   TTYPE(tree) = TETYPE(tree) = NULL;
2864   return tree;
2865
2866   /*------------------------------------------------------------------*/
2867   /*----------------------------*/
2868   /* for Statement              */
2869   /*----------------------------*/
2870     case FOR:
2871
2872   decorateType(resolveSymbols(AST_FOR(tree,initExpr)));
2873   decorateType(resolveSymbols(AST_FOR(tree,condExpr)));
2874   decorateType(resolveSymbols(AST_FOR(tree,loopExpr)));
2875
2876   /* if the for loop is reversible then
2877      reverse it otherwise do what we normally
2878      do */
2879   {
2880       symbol *sym ;
2881       ast *init, *end;
2882
2883       if (isLoopReversible (tree,&sym,&init,&end))
2884     return reverseLoop (tree,sym,init,end);
2885       else
2886     return decorateType(createFor ( AST_FOR(tree,trueLabel),
2887             AST_FOR(tree,continueLabel) ,
2888             AST_FOR(tree,falseLabel) ,
2889             AST_FOR(tree,condLabel)  ,
2890             AST_FOR(tree,initExpr)   ,
2891             AST_FOR(tree,condExpr)   ,
2892             AST_FOR(tree,loopExpr),
2893             tree->left ) );
2894   }
2895     default :
2896   TTYPE(tree) = TETYPE(tree) = NULL ;
2897   return tree ;
2898     }
2899
2900     /* some error found this tree will be killed */
2901     errorTreeReturn :
2902   TTYPE(tree) = TETYPE(tree) = newCharLink();
2903     tree->opval.op = NULLOP ;
2904     tree->isError = 1;
2905
2906     return tree ;
2907 }
2908
2909 /*-----------------------------------------------------------------*/
2910 /* sizeofOp - processes size of operation                          */
2911 /*-----------------------------------------------------------------*/
2912 value  *sizeofOp( sym_link  *type)
2913 {
2914   char buff[10];
2915
2916   /* get the size and convert it to character  */
2917   sprintf (buff,"%d", getSize(type));
2918
2919   /* now convert into value  */
2920   return  constVal (buff);
2921 }
2922
2923
2924 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
2925 #define IS_OR(ex)  (ex->type == EX_OP && ex->opval.op == OR_OP )
2926 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
2927 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
2928 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
2929 #define IS_LT(ex)  (ex->type == EX_OP && ex->opval.op == '<' )
2930 #define IS_GT(ex)  (ex->type == EX_OP && ex->opval.op == '>')
2931
2932 /*-----------------------------------------------------------------*/
2933 /* backPatchLabels - change and or not operators to flow control    */
2934 /*-----------------------------------------------------------------*/
2935 ast *backPatchLabels (ast *tree, symbol *trueLabel, symbol *falseLabel )
2936 {
2937
2938     if ( ! tree )
2939   return NULL ;
2940
2941     if ( ! (IS_ANDORNOT(tree)))
2942   return tree ;
2943
2944     /* if this an and */
2945     if (IS_AND(tree)) {
2946   static int localLbl = 0 ;
2947   symbol *localLabel ;
2948
2949   sprintf (buffer,"_and_%d",localLbl++);
2950   localLabel = newSymbol(buffer,NestLevel);
2951
2952   tree->left = backPatchLabels (tree->left, localLabel,falseLabel);
2953
2954   /* if left is already a IFX then just change the if true label in that */
2955   if (!IS_IFX(tree->left))
2956       tree->left = newIfxNode(tree->left,localLabel,falseLabel);
2957
2958   tree->right = backPatchLabels(tree->right,trueLabel,falseLabel);
2959   /* right is a IFX then just join */
2960   if (IS_IFX(tree->right))
2961       return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right));
2962
2963   tree->right = createLabel(localLabel,tree->right);
2964   tree->right = newIfxNode(tree->right,trueLabel,falseLabel);
2965
2966   return newNode(NULLOP,tree->left,tree->right);
2967     }
2968
2969     /* if this is an or operation */
2970     if (IS_OR(tree)) {
2971   static int localLbl = 0 ;
2972   symbol *localLabel ;
2973
2974   sprintf (buffer,"_or_%d",localLbl++);
2975   localLabel = newSymbol(buffer,NestLevel);
2976
2977   tree->left = backPatchLabels (tree->left, trueLabel,localLabel);
2978
2979   /* if left is already a IFX then just change the if true label in that */
2980   if (!IS_IFX(tree->left))
2981       tree->left = newIfxNode(tree->left,trueLabel,localLabel);
2982
2983   tree->right = backPatchLabels(tree->right,trueLabel,falseLabel);
2984   /* right is a IFX then just join */
2985   if (IS_IFX(tree->right))
2986       return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right));
2987
2988   tree->right = createLabel(localLabel,tree->right);
2989   tree->right = newIfxNode(tree->right,trueLabel,falseLabel);
2990
2991   return newNode(NULLOP,tree->left,tree->right);
2992     }
2993
2994     /* change not */
2995     if (IS_NOT(tree)) {
2996   int wasnot = IS_NOT(tree->left);
2997   tree->left = backPatchLabels (tree->left,falseLabel,trueLabel);
2998
2999   /* if the left is already a IFX */
3000   if ( ! IS_IFX(tree->left) )
3001       tree->left = newNode (IFX,tree->left,NULL);
3002
3003   if (wasnot) {
3004       tree->left->trueLabel = trueLabel ;
3005       tree->left->falseLabel= falseLabel ;
3006   } else {
3007       tree->left->trueLabel = falseLabel ;
3008       tree->left->falseLabel= trueLabel ;
3009   }
3010   return tree->left ;
3011     }
3012
3013     if (IS_IFX(tree)) {
3014   tree->trueLabel = trueLabel ;
3015   tree->falseLabel= falseLabel;
3016     }
3017
3018     return tree ;
3019 }
3020
3021
3022 /*-----------------------------------------------------------------*/
3023 /* createBlock - create expression tree for block                  */
3024 /*-----------------------------------------------------------------*/
3025 ast  *createBlock   ( symbol *decl,   ast  *body )
3026 {
3027     ast *ex ;
3028
3029     /* if the block has nothing */
3030     if (!body)
3031   return NULL;
3032
3033     ex = newNode(BLOCK,NULL,body);
3034     ex->values.sym = decl ;
3035
3036     ex->right = ex->right ;
3037     ex->level++ ;
3038     ex->lineno = 0 ;
3039     return ex;
3040 }
3041
3042 /*-----------------------------------------------------------------*/
3043 /* createLabel - creates the expression tree for labels            */
3044 /*-----------------------------------------------------------------*/
3045 ast  *createLabel  ( symbol  *label,  ast  *stmnt  )
3046 {
3047     symbol *csym;
3048     char  name[SDCC_NAME_MAX+1];
3049     ast   *rValue ;
3050
3051     /* must create fresh symbol if the symbol name  */
3052     /* exists in the symbol table, since there can  */
3053     /* be a variable with the same name as the labl */
3054     if ((csym = findSym (SymbolTab,NULL,label->name)) &&
3055         (csym->level == label->level))
3056   label = newSymbol(label->name,label->level);
3057
3058     /* change the name before putting it in add _*/
3059     sprintf (name,"%s",label->name);
3060
3061     /* put the label in the LabelSymbol table    */
3062     /* but first check if a label of the same    */
3063     /* name exists                               */
3064     if ( (csym = findSym(LabelTab,NULL,name)))
3065   werror(E_DUPLICATE_LABEL,label->name);
3066     else
3067   addSym (LabelTab, label, name,label->level,0);
3068
3069     label->islbl = 1;
3070     label->key = labelKey++ ;
3071     rValue =  newNode (LABEL,newAst_VALUE(symbolVal(label)),stmnt);
3072     rValue->lineno = 0;
3073
3074     return rValue ;
3075 }
3076
3077 /*-----------------------------------------------------------------*/
3078 /* createCase - generates the parsetree for a case statement       */
3079 /*-----------------------------------------------------------------*/
3080 ast  *createCase (ast *swStat, ast *caseVal, ast *stmnt   )
3081 {
3082     char caseLbl[SDCC_NAME_MAX+1];
3083     ast *rexpr;
3084     value *val;
3085
3086     /* if the switch statement does not exist */
3087     /* then case is out of context            */
3088     if (!swStat) {
3089   werror(E_CASE_CONTEXT);
3090   return NULL ;
3091     }
3092
3093     caseVal = decorateType(resolveSymbols(caseVal));
3094     /* if not a constant then error  */
3095     if (!IS_LITERAL(caseVal->ftype)) {
3096   werror(E_CASE_CONSTANT);
3097   return NULL ;
3098     }
3099
3100     /* if not a integer than error */
3101     if (!IS_INTEGRAL(caseVal->ftype)) {
3102   werror(E_CASE_NON_INTEGER);
3103   return NULL;
3104     }
3105
3106     /* find the end of the switch values chain   */
3107     if (!(val = swStat->values.switchVals.swVals))
3108   swStat->values.switchVals.swVals = caseVal->opval.val ;
3109     else {
3110   /* also order the cases according to value */
3111   value *pval = NULL;
3112   int cVal = (int) floatFromVal(caseVal->opval.val);
3113   while (val && (int) floatFromVal(val) < cVal) {
3114       pval = val;
3115       val = val->next ;
3116   }
3117
3118   /* if we reached the end then */
3119   if (!val) {
3120       pval->next =  caseVal->opval.val;
3121   } else {
3122       /* we found a value greater than */
3123       /* the current value we must add this */
3124       /* before the value */
3125       caseVal->opval.val->next = val;
3126
3127       /* if this was the first in chain */
3128       if (swStat->values.switchVals.swVals == val)
3129     swStat->values.switchVals.swVals =
3130         caseVal->opval.val;
3131       else
3132     pval->next =  caseVal->opval.val;
3133   }
3134
3135     }
3136
3137     /* create the case label   */
3138     sprintf(caseLbl,"_case_%d_%d",
3139       swStat->values.switchVals.swNum,
3140       (int) floatFromVal(caseVal->opval.val));
3141
3142     rexpr = createLabel(newSymbol(caseLbl,0),stmnt);
3143     rexpr->lineno = 0;
3144     return rexpr;
3145 }
3146
3147 /*-----------------------------------------------------------------*/
3148 /* createDefault - creates the parse tree for the default statement*/
3149 /*-----------------------------------------------------------------*/
3150 ast  *createDefault (ast *swStat, ast *stmnt)
3151 {
3152     char  defLbl[SDCC_NAME_MAX+1];
3153
3154     /* if the switch statement does not exist */
3155     /* then case is out of context            */
3156     if (!swStat) {
3157   werror(E_CASE_CONTEXT);
3158   return NULL ;
3159     }
3160
3161     /* turn on the default flag   */
3162     swStat->values.switchVals.swDefault = 1   ;
3163
3164     /* create the label  */
3165     sprintf (defLbl,"_default_%d",swStat->values.switchVals.swNum);
3166     return createLabel(newSymbol(defLbl,0),stmnt);
3167 }
3168
3169 /*-----------------------------------------------------------------*/
3170 /* createIf - creates the parsetree for the if statement           */
3171 /*-----------------------------------------------------------------*/
3172 ast *createIf ( ast *condAst, ast *ifBody, ast *elseBody )
3173 {
3174     static int Lblnum = 0 ;
3175     ast *ifTree ;
3176     symbol *ifTrue , *ifFalse, *ifEnd ;
3177
3178     /* if neither exists */
3179     if (! elseBody && !ifBody)
3180   return condAst ;
3181
3182     /* create the labels */
3183     sprintf (buffer,"_iffalse_%d",Lblnum);
3184     ifFalse = newSymbol (buffer,NestLevel);
3185     /* if no else body then end == false */
3186     if ( ! elseBody )
3187   ifEnd = ifFalse ;
3188     else {
3189   sprintf (buffer,"_ifend_%d",Lblnum);
3190   ifEnd = newSymbol (buffer,NestLevel);
3191     }
3192
3193     sprintf (buffer,"_iftrue_%d",Lblnum);
3194     ifTrue = newSymbol (buffer,NestLevel);
3195
3196     Lblnum++ ;
3197
3198     /* attach the ifTrue label to the top of it body */
3199     ifBody = createLabel(ifTrue,ifBody);
3200     /* attach a goto end to the ifBody if else is present */
3201     if ( elseBody ) {
3202   ifBody = newNode(NULLOP,ifBody,
3203        newNode(GOTO,
3204          newAst_VALUE(symbolVal(ifEnd)),
3205          NULL));
3206   /* put the elseLabel on the else body */
3207   elseBody = createLabel (ifFalse,elseBody);
3208   /* out the end at the end of the body */
3209   elseBody = newNode(NULLOP,
3210          elseBody,
3211          createLabel(ifEnd,NULL));
3212     }
3213     else {
3214   ifBody = newNode(NULLOP,ifBody,
3215        createLabel(ifFalse,NULL));
3216     }
3217     condAst = backPatchLabels (condAst,ifTrue,ifFalse);
3218     if (IS_IFX(condAst))
3219   ifTree = condAst;
3220     else
3221   ifTree = newIfxNode(condAst,ifTrue,ifFalse);
3222
3223     return newNode(NULLOP,ifTree,
3224        newNode(NULLOP,ifBody,elseBody));
3225
3226 }
3227
3228 /*-----------------------------------------------------------------*/
3229 /* createDo - creates parse tree for do                            */
3230 /*        _dobody_n:                                               */
3231 /*            statements                                           */
3232 /*        _docontinue_n:                                           */
3233 /*            condition_expression +-> trueLabel -> _dobody_n      */
3234 /*                                 |                               */
3235 /*                                 +-> falseLabel-> _dobreak_n     */
3236 /*        _dobreak_n:                                              */
3237 /*-----------------------------------------------------------------*/
3238 ast *createDo ( symbol *trueLabel, symbol *continueLabel,
3239     symbol *falseLabel, ast *condAst, ast *doBody )
3240 {
3241     ast *doTree ;
3242
3243
3244     /* if the body does not exist then it is simple */
3245     if ( ! doBody ) {
3246   condAst = backPatchLabels(condAst,continueLabel,NULL);
3247   doTree = (IS_IFX(condAst) ? createLabel(continueLabel,condAst)
3248       : newNode(IFX,createLabel(continueLabel,condAst),NULL));
3249   doTree->trueLabel = continueLabel ;
3250   doTree->falseLabel= NULL ;
3251   return doTree ;
3252     }
3253
3254     /* otherwise we have a body */
3255     condAst = backPatchLabels(condAst,trueLabel,falseLabel);
3256
3257     /* attach the body label to the top */
3258     doBody = createLabel(trueLabel,doBody);
3259     /* attach the continue label to end of body */
3260     doBody = newNode(NULLOP, doBody,
3261          createLabel(continueLabel,NULL));
3262
3263     /* now put the break label at the end */
3264     if (IS_IFX(condAst))
3265   doTree = condAst;
3266     else
3267   doTree = newIfxNode(condAst,trueLabel,falseLabel);
3268
3269     doTree = newNode(NULLOP,doTree,createLabel(falseLabel,NULL));
3270
3271     /* putting it together */
3272     return newNode(NULLOP,doBody,doTree);
3273 }
3274
3275 /*-----------------------------------------------------------------*/
3276 /* createFor - creates parse tree for 'for' statement              */
3277 /*        initExpr                                                 */
3278 /*   _forcond_n:                                                   */
3279 /*        condExpr  +-> trueLabel -> _forbody_n                    */
3280 /*                  |                                              */
3281 /*                  +-> falseLabel-> _forbreak_n                   */
3282 /*   _forbody_n:                                                   */
3283 /*        statements                                               */
3284 /*   _forcontinue_n:                                               */
3285 /*        loopExpr                                                 */
3286 /*        goto _forcond_n ;                                        */
3287 /*   _forbreak_n:                                                  */
3288 /*-----------------------------------------------------------------*/
3289 ast *createFor ( symbol *trueLabel, symbol *continueLabel ,
3290      symbol *falseLabel,symbol *condLabel     ,
3291      ast *initExpr, ast *condExpr, ast *loopExpr,
3292      ast *forBody )
3293 {
3294     ast *forTree ;
3295
3296     /* if loopexpression not present then we can generate it */
3297     /* the same way as a while */
3298     if ( ! loopExpr )
3299   return newNode(NULLOP,initExpr,
3300            createWhile (trueLabel, continueLabel,
3301             falseLabel,condExpr, forBody ));
3302     /* vanilla for statement */
3303     condExpr = backPatchLabels(condExpr,trueLabel,falseLabel);
3304
3305     if (condExpr && !IS_IFX(condExpr))
3306   condExpr = newIfxNode(condExpr,trueLabel,falseLabel);
3307
3308
3309     /* attach condition label to condition */
3310     condExpr = createLabel(condLabel,condExpr);
3311
3312     /* attach body label to body */
3313     forBody = createLabel(trueLabel,forBody);
3314
3315     /* attach continue to forLoop expression & attach */
3316     /* goto the forcond @ and of loopExpression       */
3317     loopExpr = createLabel(continueLabel,
3318          newNode(NULLOP,
3319            loopExpr,
3320            newNode(GOTO,
3321              newAst_VALUE(symbolVal(condLabel)),
3322              NULL)));
3323     /* now start putting them together */
3324     forTree = newNode(NULLOP,initExpr,condExpr);
3325     forTree = newNode(NULLOP,forTree,forBody);
3326     forTree = newNode(NULLOP,forTree,loopExpr);
3327     /* finally add the break label */
3328     forTree = newNode(NULLOP,forTree,
3329           createLabel(falseLabel,NULL));
3330     return forTree ;
3331 }
3332
3333 /*-----------------------------------------------------------------*/
3334 /* createWhile - creates parse tree for while statement            */
3335 /*               the while statement will be created as follows    */
3336 /*                                                                 */
3337 /*      _while_continue_n:                                         */
3338 /*            condition_expression +-> trueLabel -> _while_boby_n  */
3339 /*                                 |                               */
3340 /*                                 +-> falseLabel -> _while_break_n*/
3341 /*      _while_body_n:                                             */
3342 /*            statements                                           */
3343 /*            goto _while_continue_n                               */
3344 /*      _while_break_n:                                            */
3345 /*-----------------------------------------------------------------*/
3346 ast *createWhile (symbol *trueLabel, symbol *continueLabel,
3347        symbol *falseLabel,ast *condExpr, ast *whileBody )
3348 {
3349     ast *whileTree ;
3350
3351     /* put the continue label */
3352     condExpr = backPatchLabels (condExpr,trueLabel,falseLabel);
3353     condExpr = createLabel(continueLabel,condExpr);
3354     condExpr->lineno = 0;
3355
3356     /* put the body label in front of the body */
3357     whileBody = createLabel(trueLabel,whileBody);
3358     whileBody->lineno = 0;
3359     /* put a jump to continue at the end of the body */
3360     /* and put break label at the end of the body */
3361     whileBody = newNode(NULLOP,
3362       whileBody,
3363       newNode(GOTO,
3364         newAst_VALUE(symbolVal(continueLabel)),
3365         createLabel(falseLabel,NULL)));
3366
3367     /* put it all together */
3368     if ( IS_IFX(condExpr) )
3369   whileTree = condExpr ;
3370     else {
3371   whileTree = newNode (IFX, condExpr,NULL );
3372   /* put the true & false labels in place */
3373   whileTree->trueLabel = trueLabel ;
3374   whileTree->falseLabel= falseLabel;
3375     }
3376
3377     return newNode(NULLOP,whileTree,whileBody );
3378 }
3379
3380 /*-----------------------------------------------------------------*/
3381 /* optimizeGetHbit - get highest order bit of the expression       */
3382 /*-----------------------------------------------------------------*/
3383 ast *optimizeGetHbit (ast *tree)
3384 {
3385     int i,j;
3386     /* if this is not a bit and */
3387     if (!IS_BITAND(tree))
3388   return tree;
3389
3390     /* will look for tree of the form
3391        ( expr >> ((sizeof expr) -1) ) & 1 */
3392     if (!IS_AST_LIT_VALUE(tree->right))
3393   return tree;
3394
3395     if (AST_LIT_VALUE(tree->right) != 1)
3396   return tree;
3397
3398     if (!IS_RIGHT_OP(tree->left))
3399   return tree;
3400
3401     if (!IS_AST_LIT_VALUE(tree->left->right))
3402   return tree;
3403
3404     if ((i = (int) AST_LIT_VALUE(tree->left->right)) !=
3405   ( j = (getSize(TTYPE(tree->left->left))*8 - 1)))
3406   return tree;
3407
3408     return decorateType(newNode(GETHBIT,tree->left->left,NULL));
3409
3410 }
3411
3412 /*-----------------------------------------------------------------*/
3413 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry     */
3414 /*-----------------------------------------------------------------*/
3415 ast *optimizeRRCRLC ( ast *root )
3416 {
3417     /* will look for trees of the form
3418        (?expr << 1) | (?expr >> 7) or
3419        (?expr >> 7) | (?expr << 1) will make that
3420        into a RLC : operation ..
3421        Will also look for
3422        (?expr >> 1) | (?expr << 7) or
3423        (?expr << 7) | (?expr >> 1) will make that
3424        into a RRC operation
3425        note : by 7 I mean (number of bits required to hold the
3426        variable -1 ) */
3427     /* if the root operations is not a | operation the not */
3428     if (!IS_BITOR(root))
3429   return root ;
3430
3431     /* I have to think of a better way to match patterns this sucks */
3432     /* that aside let start looking for the first case : I use a the
3433        negative check a lot to improve the efficiency */
3434     /* (?expr << 1) | (?expr >> 7) */
3435     if (IS_LEFT_OP(root->left)    &&
3436   IS_RIGHT_OP(root->right)  ) {
3437
3438   if (!SPEC_USIGN(TETYPE(root->left->left)))
3439       return root;
3440
3441   if (!IS_AST_LIT_VALUE(root->left->right) ||
3442       !IS_AST_LIT_VALUE(root->right->right))
3443       goto tryNext0;
3444
3445   /* make sure it is the same expression */
3446   if (!isAstEqual(root->left->left,
3447       root->right->left))
3448       goto tryNext0;
3449
3450   if (AST_LIT_VALUE(root->left->right) != 1 )
3451       goto tryNext0 ;
3452
3453   if (AST_LIT_VALUE(root->right->right) !=
3454       (getSize(TTYPE(root->left->left))*8 - 1))
3455       goto tryNext0 ;
3456
3457   /* whew got the first case : create the AST */
3458   return  newNode(RLC,root->left->left,NULL);
3459     }
3460
3461  tryNext0:
3462     /* check for second case */
3463     /* (?expr >> 7) | (?expr << 1) */
3464     if (IS_LEFT_OP(root->right)    &&
3465   IS_RIGHT_OP(root->left)  ) {
3466
3467   if (!SPEC_USIGN(TETYPE(root->left->left)))
3468       return root;
3469
3470   if (!IS_AST_LIT_VALUE(root->left->right) ||
3471       !IS_AST_LIT_VALUE(root->right->right))
3472       goto tryNext1 ;
3473
3474   /* make sure it is the same symbol */
3475   if (!isAstEqual(root->left->left,
3476       root->right->left))
3477       goto tryNext1 ;
3478
3479   if (AST_LIT_VALUE(root->right->right) != 1 )
3480       goto tryNext1 ;
3481
3482   if (AST_LIT_VALUE(root->left->right) !=
3483       (getSize(TTYPE(root->left->left))*8 - 1))
3484       goto tryNext1 ;
3485
3486   /* whew got the first case : create the AST */
3487   return  newNode(RLC,root->left->left,NULL);
3488
3489     }
3490
3491  tryNext1:
3492     /* third case for RRC */
3493     /*  (?symbol >> 1) | (?symbol << 7) */
3494     if (IS_LEFT_OP(root->right)    &&
3495   IS_RIGHT_OP(root->left)  ) {
3496
3497   if (!SPEC_USIGN(TETYPE(root->left->left)))
3498       return root;
3499
3500   if (!IS_AST_LIT_VALUE(root->left->right) ||
3501       !IS_AST_LIT_VALUE(root->right->right))
3502       goto tryNext2;
3503
3504   /* make sure it is the same symbol */
3505   if (!isAstEqual(root->left->left,
3506       root->right->left))
3507       goto tryNext2;
3508
3509   if (AST_LIT_VALUE(root->left->right) != 1 )
3510       goto tryNext2;
3511
3512   if (AST_LIT_VALUE(root->right->right) !=
3513       (getSize(TTYPE(root->left->left))*8 - 1))
3514       goto tryNext2;
3515
3516   /* whew got the first case : create the AST */
3517   return newNode(RRC,root->left->left,NULL);
3518
3519     }
3520  tryNext2:
3521     /* fourth and last case for now */
3522     /* (?symbol << 7) | (?symbol >> 1) */
3523     if (IS_RIGHT_OP(root->right)    &&
3524   IS_LEFT_OP(root->left)  ) {
3525
3526   if (!SPEC_USIGN(TETYPE(root->left->left)))
3527       return root;
3528
3529   if (!IS_AST_LIT_VALUE(root->left->right) ||
3530       !IS_AST_LIT_VALUE(root->right->right))
3531       return root;
3532
3533   /* make sure it is the same symbol */
3534   if (!isAstEqual(root->left->left,
3535       root->right->left))
3536       return root;
3537
3538   if (AST_LIT_VALUE(root->right->right) != 1 )
3539       return root ;
3540
3541   if (AST_LIT_VALUE(root->left->right) !=
3542       (getSize(TTYPE(root->left->left))*8 - 1))
3543       return root ;
3544
3545   /* whew got the first case : create the AST */
3546   return  newNode(RRC,root->left->left,NULL);
3547
3548     }
3549
3550     /* not found return root */
3551     return root;
3552 }
3553
3554 /*-----------------------------------------------------------------*/
3555 /* optimizeCompare - otimizes compares for bit variables     */
3556 /*-----------------------------------------------------------------*/
3557 ast  *optimizeCompare ( ast *root )
3558 {
3559     ast *optExpr = NULL;
3560     value *vleft;
3561     value *vright;
3562     unsigned int litValue ;
3563
3564     /* if nothing then return nothing */
3565     if (!root)
3566   return NULL ;
3567
3568     /* if not a compare op then do leaves */
3569     if (!IS_COMPARE_OP(root)) {
3570   root->left = optimizeCompare (root->left);
3571   root->right= optimizeCompare (root->right);
3572   return root ;
3573     }
3574
3575     /* if left & right are the same then depending
3576        of the operation do */
3577     if (isAstEqual(root->left,root->right)) {
3578   switch (root->opval.op) {
3579   case '>' :
3580   case '<' :
3581   case NE_OP :
3582       optExpr = newAst_VALUE(constVal("0"));
3583       break;
3584   case GE_OP :
3585   case LE_OP :
3586   case EQ_OP :
3587       optExpr = newAst_VALUE(constVal("1"));
3588       break;
3589   }
3590
3591   return decorateType(optExpr);
3592     }
3593
3594     vleft = (root->left->type == EX_VALUE ?
3595        root->left->opval.val : NULL );
3596
3597     vright = (root->right->type == EX_VALUE ?
3598         root->right->opval.val : NULL);
3599
3600     /* if left is a BITVAR in BITSPACE */
3601     /* and right is a LITERAL then opt-*/
3602     /* imize else do nothing       */
3603     if (vleft && vright                   &&
3604   IS_BITVAR(vleft->etype)     &&
3605   IN_BITSPACE(SPEC_OCLS(vleft->etype))  &&
3606   IS_LITERAL(vright->etype)) {
3607
3608   /* if right side > 1 then comparison may never succeed */
3609   if ( (litValue = (int) floatFromVal(vright)) > 1 ) {
3610       werror(W_BAD_COMPARE);
3611       goto noOptimize ;
3612   }
3613
3614   if ( litValue ) {
3615       switch (root->opval.op) {
3616       case '>' :  /* bit value greater than 1 cannot be */
3617     werror(W_BAD_COMPARE);
3618     goto noOptimize ;
3619     break;
3620
3621       case '<' : /* bit value < 1 means 0 */
3622       case NE_OP :
3623     optExpr = newNode('!',newAst_VALUE(vleft),NULL);
3624     break;
3625
3626       case LE_OP : /* bit value <= 1 means no check */
3627     optExpr = newAst_VALUE(vright);
3628     break;
3629
3630       case GE_OP : /* bit value >= 1 means only check for = */
3631       case EQ_OP :
3632     optExpr = newAst_VALUE(vleft);
3633     break;
3634       }
3635   } else { /* literal is zero */
3636       switch (root->opval.op) {
3637       case '<' :  /* bit value < 0 cannot be */
3638     werror(W_BAD_COMPARE);
3639     goto noOptimize ;
3640     break;
3641
3642       case '>' : /* bit value > 0 means 1 */
3643       case NE_OP :
3644     optExpr = newAst_VALUE(vleft);
3645     break;
3646
3647       case LE_OP : /* bit value <= 0 means no check */
3648       case GE_OP : /* bit value >= 0 means no check */
3649     werror(W_BAD_COMPARE);
3650     goto noOptimize ;
3651     break;
3652
3653       case EQ_OP : /* bit == 0 means ! of bit */
3654     optExpr = newNode('!',newAst_VALUE(vleft),NULL);
3655     break;
3656       }
3657   }
3658   return decorateType(resolveSymbols(optExpr));
3659     } /* end-of-if of BITVAR */
3660
3661     noOptimize :
3662   return root;
3663 }
3664 /*-----------------------------------------------------------------*/
3665 /* addSymToBlock : adds the symbol to the first block we find      */
3666 /*-----------------------------------------------------------------*/
3667 void addSymToBlock (symbol *sym, ast *tree)
3668 {
3669     /* reached end of tree or a leaf */
3670     if (!tree || IS_AST_LINK(tree) || IS_AST_VALUE(tree))
3671   return ;
3672
3673     /* found a block */
3674     if (IS_AST_OP(tree) &&
3675   tree->opval.op == BLOCK ) {
3676
3677   symbol *lsym = copySymbol(sym);
3678
3679   lsym->next = AST_VALUES(tree,sym);
3680   AST_VALUES(tree,sym) = lsym ;
3681   return ;
3682     }
3683
3684     addSymToBlock(sym,tree->left);
3685     addSymToBlock(sym,tree->right);
3686 }
3687
3688 /*-----------------------------------------------------------------*/
3689 /* processRegParms - do processing for register parameters         */
3690 /*-----------------------------------------------------------------*/
3691 static void processRegParms (value *args, ast *body)
3692 {
3693     while (args) {
3694   if (IS_REGPARM(args->etype))
3695       addSymToBlock(args->sym,body);
3696   args = args->next;
3697     }
3698 }
3699
3700 /*-----------------------------------------------------------------*/
3701 /* resetParmKey - resets the operandkeys for the symbols           */
3702 /*-----------------------------------------------------------------*/
3703 DEFSETFUNC(resetParmKey)
3704 {
3705     symbol *sym = item;
3706
3707     sym->key = 0 ;
3708     sym->defs = NULL ;
3709     sym->uses = NULL ;
3710     sym->remat= 0;
3711     return 1;
3712 }
3713
3714 /*-----------------------------------------------------------------*/
3715 /* createFunction - This is the key node that calls the iCode for  */
3716 /*                  generating the code for a function. Note code  */
3717 /*                  is generated function by function, later when  */
3718 /*                  add inter-procedural analysis this will change */
3719 /*-----------------------------------------------------------------*/
3720 ast  *createFunction   (symbol  *name,   ast  *body )
3721 {
3722     ast  *ex ;
3723     symbol *csym;
3724     int stack = 0 ;
3725     sym_link *fetype;
3726     iCode *piCode = NULL;
3727
3728     /* if check function return 0 then some problem */
3729     if (checkFunction (name) == 0)
3730   return NULL;
3731
3732     /* create a dummy block if none exists */
3733     if (!body)
3734   body = newNode(BLOCK,NULL,NULL);
3735
3736     noLineno++ ;
3737
3738     /* check if the function name already in the symbol table */
3739     if ((csym = findSym (SymbolTab,NULL,name->name))) {
3740   name = csym ;
3741   /* special case for compiler defined functions
3742      we need to add the name to the publics list : this
3743      actually means we are now compiling the compiler
3744      support routine */
3745   if (name->cdef) {
3746       addSet(&publics,name);
3747   }
3748     }
3749     else {
3750   addSymChain(name);
3751   allocVariables(name);
3752     }
3753     name->lastLine = yylineno;
3754     currFunc = name ;
3755     processFuncArgs(currFunc,0);
3756
3757     /* set the stack pointer */
3758     /* PENDING: check this for the mcs51 */
3759     stackPtr = -port->stack.direction * port->stack.call_overhead;
3760     if (IS_ISR(name->etype))
3761   stackPtr -= port->stack.direction * port->stack.isr_overhead;
3762     if (IS_RENT(name->etype) || options.stackAuto)
3763   stackPtr -= port->stack.direction * port->stack.reent_overhead;
3764
3765     xstackPtr = -port->stack.direction * port->stack.call_overhead;
3766
3767     fetype = getSpec(name->type); /* get the specifier for the function */
3768     /* if this is a reentrant function then */
3769     if (IS_RENT(fetype))
3770   reentrant++ ;
3771
3772     allocParms (name->args);           /* allocate the parameters */
3773
3774     /* do processing for parameters that are passed in registers */
3775     processRegParms (name->args,body);
3776
3777    /* set the stack pointer */
3778     stackPtr = 0;
3779     xstackPtr= -1;
3780
3781     /* allocate & autoinit the block variables */
3782     processBlockVars (body, &stack,ALLOCATE);
3783
3784     /* save the stack information */
3785     if (options.useXstack)
3786   name->xstack = SPEC_STAK(fetype) = stack;
3787     else
3788   name->stack = SPEC_STAK(fetype) = stack;
3789
3790     /* name needs to be mangled */
3791     sprintf (name->rname,"%s%s", port->fun_prefix, name->name);
3792
3793     body = resolveSymbols(body); /* resolve the symbols */
3794     body = decorateType (body);  /* propagateType & do semantic checks */
3795
3796     ex = newAst_VALUE(symbolVal(name));    /* create name       */
3797     ex = newNode (FUNCTION,ex,body);
3798     ex->values.args = name->args ;
3799
3800     if (fatalError) {
3801   werror(E_FUNC_NO_CODE,name->name);
3802   goto skipall ;
3803     }
3804
3805     /* create the node & generate intermediate code */
3806     codeOutFile = code->oFile;
3807     piCode = iCodeFromAst(ex);
3808
3809      if (fatalError) {
3810    werror(E_FUNC_NO_CODE,name->name);
3811    goto skipall ;
3812      }
3813
3814      eBBlockFromiCode(piCode);
3815
3816     /* if there are any statics then do them */
3817     if (staticAutos) {
3818   codeOutFile = statsg->oFile;
3819   eBBlockFromiCode (iCodeFromAst (decorateType(resolveSymbols(staticAutos))));
3820   staticAutos = NULL;
3821     }
3822
3823  skipall:
3824
3825     /* dealloc the block variables */
3826     processBlockVars(body, &stack,DEALLOCATE);
3827     /* deallocate paramaters */
3828     deallocParms(name->args);
3829
3830     if (IS_RENT(fetype))
3831   reentrant-- ;
3832
3833     /* we are done freeup memory & cleanup */
3834     noLineno-- ;
3835     labelKey = 1 ;
3836     name->key = 0;
3837     name->fbody = 1;
3838     addSet(&operKeyReset,name);
3839     applyToSet(operKeyReset,resetParmKey);
3840
3841     if (options.debug && !options.nodebug)
3842   cdbStructBlock(1,cdbFile);
3843
3844     cleanUpLevel(LabelTab,0);
3845     cleanUpBlock(StructTab,1);
3846     cleanUpBlock(TypedefTab,1);
3847
3848     xstack->syms = NULL;
3849     istack->syms = NULL;
3850     return NULL ;
3851 }
3852
3853