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