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