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