1 /*-------------------------------------------------------------------------
2 SDCCast.c - source file for parser support & all ast related routines
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
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
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.
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.
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 -------------------------------------------------------------------------*/
29 set *operKeyReset = NULL;
30 extern char *currFname ;
31 ast *staticAutos = NULL;
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
53 extern int fatalError ;
55 extern char *filename ;
57 extern ast *createIval (ast *, link *, initList *, ast *);
58 extern ast *createIvalCharPtr (ast *, link *, ast *);
59 ast *optimizeRRCRLC ( ast * );
60 ast *optimizeGetHbit(ast *);
61 ast *backPatchLabels (ast *,symbol *,symbol *);
65 printTypeChain(tree->ftype,stdout);
70 /*-----------------------------------------------------------------*/
71 /* newAst - creates a fresh node for an expression tree */
72 /*-----------------------------------------------------------------*/
73 ast *newAst (int type, void *op )
76 static int oldLineno = 0 ;
78 ALLOC(ex,sizeof(ast));
81 ex->lineno = (noLineno ? oldLineno : yylineno);
82 ex->filename = currFname ;
83 ex->level = NestLevel ;
84 ex->block = currBlockno ;
85 ex->initMode = inInitMode;
87 /* depending on the type */
90 ex->opval.val = (value *) op;
93 ex->opval.op = (int) op ;
96 ex->opval.lnk = (link *) op;
99 ex->opval.stmnt= (unsigned) op;
105 /*-----------------------------------------------------------------*/
106 /* newNode - creates a new node */
107 /*-----------------------------------------------------------------*/
108 ast *newNode ( int op, ast *left, ast *right )
112 ex = newAst (EX_OP,(void *) op) ;
119 /*-----------------------------------------------------------------*/
120 /* newIfxNode - creates a new Ifx Node */
121 /*-----------------------------------------------------------------*/
122 ast *newIfxNode (ast *condAst, symbol *trueLabel, symbol *falseLabel)
126 /* if this is a literal then we already know the result */
127 if (condAst->etype && IS_LITERAL(condAst->etype)) {
129 /* then depending on the expression value */
130 if ( floatFromVal(condAst->opval.val) )
131 ifxNode = newNode(GOTO, newAst(EX_VALUE,
132 symbolVal (trueLabel )),NULL);
134 ifxNode = newNode(GOTO, newAst(EX_VALUE,
135 symbolVal (falseLabel )),NULL);
138 ifxNode = newNode(IFX,condAst,NULL);
139 ifxNode->trueLabel = trueLabel;
140 ifxNode->falseLabel= falseLabel;
146 /*-----------------------------------------------------------------*/
147 /* copyAstValues - copies value portion of ast if needed */
148 /*-----------------------------------------------------------------*/
149 void copyAstValues (ast *dest,ast *src)
151 switch (src->opval.op) {
153 dest->values.sym = copySymbolChain(src->values.sym);
157 dest->values.switchVals.swVals =
158 copyValue(src->values.switchVals.swVals);
159 dest->values.switchVals.swDefault =
160 src->values.switchVals.swDefault ;
161 dest->values.switchVals.swNum =
162 src->values.switchVals.swNum ;
166 ALLOC_ATOMIC(dest->values.inlineasm,strlen(src->values.inlineasm));
167 strcpy(dest->values.inlineasm,src->values.inlineasm);
170 AST_FOR(dest,trueLabel) = copySymbol(AST_FOR(src,trueLabel));
171 AST_FOR(dest,continueLabel) = copySymbol(AST_FOR(src,continueLabel));
172 AST_FOR(dest,falseLabel) = copySymbol(AST_FOR(src,falseLabel));
173 AST_FOR(dest,condLabel) = copySymbol(AST_FOR(src,condLabel));
174 AST_FOR(dest,initExpr) = copyAst (AST_FOR(src,initExpr)) ;
175 AST_FOR(dest,condExpr) = copyAst (AST_FOR(src,condExpr)) ;
176 AST_FOR(dest,loopExpr) = copyAst (AST_FOR(src,loopExpr)) ;
181 /*-----------------------------------------------------------------*/
182 /* copyAst - makes a copy of a given astession */
183 /*-----------------------------------------------------------------*/
184 ast *copyAst (ast *src)
188 if (!src) return NULL ;
190 ALLOC(dest,sizeof(ast));
192 dest->type = src->type ;
193 dest->lineno = src->lineno ;
194 dest->level = src->level ;
195 dest->funcName = src->funcName;
196 dest->argSym = src->argSym;
198 /* if this is a leaf */
200 if (src->type == EX_VALUE) {
201 dest->opval.val = copyValue(src->opval.val);
206 if (src->type == EX_LINK) {
207 dest->opval.lnk = copyLinkChain(src->opval.lnk);
211 dest->opval.op = src->opval.op ;
213 /* if this is a node that has special values */
214 copyAstValues (dest,src);
217 dest->etype = getSpec(dest->ftype = copyLinkChain(src->ftype)) ;
219 dest->trueLabel = copySymbol (src->trueLabel);
220 dest->falseLabel= copySymbol (src->falseLabel);
221 dest->left = copyAst(src->left);
222 dest->right= copyAst(src->right);
228 /*-----------------------------------------------------------------*/
229 /* hasSEFcalls - returns TRUE if tree has a function call */
230 /*-----------------------------------------------------------------*/
231 bool hasSEFcalls ( ast *tree)
236 if (tree->type == EX_OP &&
237 ( tree->opval.op == CALL ||
238 tree->opval.op == PCALL ||
239 tree->opval.op == '=' ||
240 tree->opval.op == INC_OP ||
241 tree->opval.op == DEC_OP ))
244 return ( hasSEFcalls(tree->left) |
245 hasSEFcalls(tree->right));
248 /*-----------------------------------------------------------------*/
249 /* isAstEqual - compares two asts & returns 1 if they are equal */
250 /*-----------------------------------------------------------------*/
251 int isAstEqual (ast *t1, ast *t2)
260 if (t1->type != t2->type)
265 if (t1->opval.op != t2->opval.op)
267 return ( isAstEqual(t1->left,t2->left) &&
268 isAstEqual(t1->right,t2->right));
272 if (t1->opval.val->sym) {
273 if (!t2->opval.val->sym)
276 return isSymbolEqual(t1->opval.val->sym,
280 if (t2->opval.val->sym)
283 return (floatFromVal(t1->opval.val) ==
284 floatFromVal(t2->opval.val));
288 /* only compare these two types */
296 /*-----------------------------------------------------------------*/
297 /* resolveSymbols - resolve symbols from the symbol table */
298 /*-----------------------------------------------------------------*/
299 ast *resolveSymbols (ast *tree)
301 /* walk the entire tree and check for values */
302 /* with symbols if we find one then replace */
303 /* symbol with that from the symbol table */
309 /* if not block & function */
310 if ( tree->type == EX_OP &&
311 ( tree->opval.op != FUNCTION &&
312 tree->opval.op != BLOCK &&
313 tree->opval.op != NULLOP )) {
314 filename = tree->filename ;
315 lineno = tree->lineno ;
318 /* make sure we resolve the true & false labels for ifx */
319 if (tree->type == EX_OP && tree->opval.op == IFX ) {
322 if (tree->trueLabel) {
323 if (( csym = findSym(LabelTab,tree->trueLabel,
324 tree->trueLabel->name)))
325 tree->trueLabel = csym ;
327 werror(E_LABEL_UNDEF,tree->trueLabel->name);
330 if (tree->falseLabel) {
331 if (( csym = findSym(LabelTab,
333 tree->falseLabel->name)))
334 tree->falseLabel = csym ;
336 werror(E_LABEL_UNDEF,tree->falseLabel->name);
341 /* if this is a label resolve it from the labelTab*/
342 if (IS_AST_VALUE(tree) &&
343 tree->opval.val->sym &&
344 tree->opval.val->sym->islbl) {
346 symbol *csym = findSym (LabelTab, tree->opval.val->sym ,
347 tree->opval.val->sym->name);
350 werror (E_LABEL_UNDEF,tree->opval.val->sym->name);
352 tree->opval.val->sym = csym ;
354 goto resolveChildren ;
357 /* do only for leafs */
358 if (IS_AST_VALUE(tree) &&
359 tree->opval.val->sym &&
360 ! tree->opval.val->sym->implicit ) {
362 symbol *csym = findSymWithLevel (SymbolTab,tree->opval.val->sym);
364 /* if found in the symbol table & they r not the same */
365 if (csym && tree->opval.val->sym != csym ) {
366 tree->opval.val->sym = csym ;
367 tree->opval.val->type = csym->type;
368 tree->opval.val->etype = csym->etype;
371 /* if not found in the symbol table */
372 /* mark it as undefined assume it is*/
373 /* an integer in data space */
374 if (!csym && !tree->opval.val->sym->implicit) {
376 /* if this is a function name then */
377 /* mark it as returning an int */
378 if (tree->funcName) {
379 tree->opval.val->sym->type = newLink();
380 DCL_TYPE(tree->opval.val->sym->type) = FUNCTION;
381 tree->opval.val->sym->type->next =
382 tree->opval.val->sym->etype = newIntLink();
383 tree->opval.val->etype = tree->opval.val->etype;
384 tree->opval.val->type = tree->opval.val->sym->type;
385 werror(W_IMPLICIT_FUNC,tree->opval.val->sym->name);
387 tree->opval.val->sym->undefined =1 ;
388 tree->opval.val->type =
389 tree->opval.val->etype = newIntLink();
390 tree->opval.val->sym->type =
391 tree->opval.val->sym->etype = newIntLink();
397 resolveSymbols (tree->left);
398 resolveSymbols (tree->right);
403 /*-----------------------------------------------------------------*/
404 /* setAstLineno - walks a ast tree & sets the line number */
405 /*-----------------------------------------------------------------*/
406 int setAstLineno ( ast *tree, int lineno)
411 tree->lineno = lineno ;
412 setAstLineno ( tree->left, lineno);
413 setAstLineno ( tree->right, lineno);
418 /* this functions seems to be superfluous?! kmh */
420 /*-----------------------------------------------------------------*/
421 /* resolveFromTable - will return the symbal table value */
422 /*-----------------------------------------------------------------*/
423 value *resolveFromTable (value *val)
430 csym = findSymWithLevel (SymbolTab,val->sym);
432 /* if found in the symbol table & they r not the same */
433 if (csym && val->sym != csym &&
434 csym->level == val->sym->level &&
439 val->type = csym->type;
440 val->etype = csym->etype;
447 /*-----------------------------------------------------------------*/
448 /* funcOfType :- function of type with name */
449 /*-----------------------------------------------------------------*/
450 symbol *funcOfType (char *name, link *type, link *argType,
451 int nArgs , int rent)
455 /* create the symbol */
456 sym = newSymbol (name,0);
458 /* if arguments required */
462 args = sym->args = newValue();
465 argStack += getSize(type);
466 args->type = copyLinkChain(argType);
467 args->etype = getSpec(args->type);
470 args = args->next = newValue();
474 /* setup return value */
475 sym->type = newLink();
476 DCL_TYPE(sym->type) = FUNCTION;
477 sym->type->next = copyLinkChain(type);
478 sym->etype = getSpec(sym->type);
479 SPEC_RENT(sym->etype) = rent;
484 sym->argStack = (rent ? argStack : 0);
485 allocVariables (sym);
490 /*-----------------------------------------------------------------*/
491 /* reverseParms - will reverse a parameter tree */
492 /*-----------------------------------------------------------------*/
493 void reverseParms (ast *ptree)
499 /* top down if we find a nonParm tree then quit */
500 if (ptree->type == EX_OP && ptree->opval.op == PARAM ) {
502 ptree->left = ptree->right;
503 ptree->right = ttree;
504 reverseParms(ptree->left);
505 reverseParms(ptree->right);
511 /*-----------------------------------------------------------------*/
512 /* processParms - makes sure the parameters are okay and do some */
513 /* processing with them */
514 /*-----------------------------------------------------------------*/
515 int processParms (ast *func, value *defParm,
519 link *fetype = func->etype;
521 /* if none of them exist */
522 if ( !defParm && !actParm)
525 /* if the function is being called via a pointer & */
526 /* it has not been defined a reentrant then we cannot*/
527 /* have parameters */
528 if (func->type != EX_VALUE && !IS_RENT(fetype) && !options.stackAuto) {
529 werror (E_NONRENT_ARGS);
533 /* if defined parameters ended but actual parameters */
534 /* exist and this is not defined as a variable arg */
535 /* also check if statckAuto option is specified */
536 if ((! defParm) && actParm && (!func->hasVargs ) &&
537 !options.stackAuto && !IS_RENT(fetype)) {
538 werror(E_TOO_MANY_PARMS);
542 /* if defined parameters present and actual paramters ended */
543 if ( defParm && ! actParm) {
544 werror(E_TO_FEW_PARMS);
548 /* if defined parameters ended but actual has not & */
549 /* has a variable argument list or statckAuto */
550 if (! defParm && actParm &&
551 (func->hasVargs || options.stackAuto || IS_RENT(fetype)))
554 resolveSymbols(actParm);
555 /* if this is a PARAM node then match left & right */
556 if ( actParm->type == EX_OP && actParm->opval.op == PARAM) {
558 return (processParms (func,defParm,actParm->left,parmNumber) ||
559 processParms (func,defParm->next, actParm->right,parmNumber) );
562 /* the parameter type must be atleast castable */
563 if (checkType(defParm->type,actParm->ftype) == 0) {
564 werror(E_TYPE_MISMATCH_PARM,*parmNumber);
565 werror(E_CONTINUE,"defined type ");
566 printTypeChain(defParm->type,stderr);fprintf(stderr,"\n");
567 werror(E_CONTINUE,"actual type ");
568 printTypeChain(actParm->ftype,stderr);fprintf(stderr,"\n");
571 /* if the parameter is castable then add the cast */
572 if ( checkType (defParm->type,actParm->ftype) < 0) {
573 ast *pTree = resolveSymbols(copyAst(actParm));
575 /* now change the current one to a cast */
576 actParm->type = EX_OP ;
577 actParm->opval.op = CAST ;
578 actParm->left = newAst(EX_LINK,defParm->type);
579 actParm->right= pTree ;
580 actParm->etype= defParm->etype;
581 actParm->ftype= defParm->type;
584 /* actParm->argSym = resolveFromTable(defParm)->sym ; */
585 actParm->argSym = defParm->sym;
586 /* make a copy and change the regparm type to the defined parm */
587 actParm->etype = getSpec(actParm->ftype = copyLinkChain(actParm->ftype));
588 SPEC_REGPARM(actParm->etype) = SPEC_REGPARM(defParm->etype);
592 /*-----------------------------------------------------------------*/
593 /* createIvalType - generates ival for basic types */
594 /*-----------------------------------------------------------------*/
595 ast *createIvalType ( ast *sym,link *type, initList *ilist)
599 /* if initList is deep */
600 if ( ilist->type == INIT_DEEP )
601 ilist = ilist->init.deep ;
603 iExpr = decorateType(resolveSymbols(list2expr(ilist)));
604 return decorateType(newNode('=',sym,iExpr));
607 /*-----------------------------------------------------------------*/
608 /* createIvalStruct - generates initial value for structures */
609 /*-----------------------------------------------------------------*/
610 ast *createIvalStruct (ast *sym,link *type,initList *ilist)
616 sflds = SPEC_STRUCT(type)->fields ;
617 if (ilist->type != INIT_DEEP) {
618 werror(E_INIT_STRUCT,"");
622 iloop = ilist->init.deep;
624 for ( ; sflds ; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL )) {
627 /* if we have come to end */
631 lAst = newNode(PTR_OP,newNode('&',sym,NULL),newAst(EX_VALUE,symbolVal(sflds)));
632 lAst = decorateType(resolveSymbols(lAst));
633 rast = decorateType(resolveSymbols(createIval (lAst, sflds->type, iloop,rast)));
639 /*-----------------------------------------------------------------*/
640 /* createIvalArray - generates code for array initialization */
641 /*-----------------------------------------------------------------*/
642 ast *createIvalArray (ast *sym, link *type, initList *ilist)
646 int lcnt = 0, size =0 ;
648 /* take care of the special case */
649 /* array of characters can be init */
651 if ( IS_CHAR(type->next) )
652 if ( (rast = createIvalCharPtr(sym,
654 decorateType(resolveSymbols(list2expr(ilist))))))
656 return decorateType(resolveSymbols(rast));
658 /* not the special case */
659 if (ilist->type != INIT_DEEP) {
660 werror(E_INIT_STRUCT,"");
664 iloop = ilist->init.deep ;
665 lcnt = DCL_ELEM(type);
671 aSym = newNode('[',sym,newAst(EX_VALUE,valueFromLit(size-1)));
672 aSym = decorateType(resolveSymbols(aSym));
673 rast = createIval (aSym,type->next,iloop,rast) ;
674 iloop = (iloop ? iloop->next : NULL) ;
677 /* if not array limits given & we */
678 /* are out of initialisers then */
679 if (!DCL_ELEM(type) && !iloop)
682 /* no of elements given and we */
683 /* have generated for all of them */
688 /* if we have not been given a size */
690 DCL_ELEM(type) = size;
692 return decorateType(resolveSymbols(rast));
696 /*-----------------------------------------------------------------*/
697 /* createIvalCharPtr - generates initial values for char pointers */
698 /*-----------------------------------------------------------------*/
699 ast *createIvalCharPtr (ast *sym, link *type, ast *iexpr)
703 /* if this is a pointer & right is a literal array then */
704 /* just assignment will do */
705 if ( IS_PTR(type) && (( IS_LITERAL(iexpr->etype) ||
706 SPEC_SCLS(iexpr->etype) == S_CODE )
707 && IS_ARRAY(iexpr->ftype)))
708 return newNode('=',sym,iexpr);
710 /* left side is an array so we have to assign each */
712 if (( IS_LITERAL(iexpr->etype) ||
713 SPEC_SCLS(iexpr->etype) == S_CODE )
714 && IS_ARRAY(iexpr->ftype)) {
716 /* for each character generate an assignment */
717 /* to the array element */
718 char *s = SPEC_CVAL(iexpr->etype).v_char ;
722 rast = newNode(NULLOP,
726 newAst(EX_VALUE,valueFromLit(i))),
727 newAst(EX_VALUE,valueFromLit(*s))));
731 rast = newNode(NULLOP,
735 newAst(EX_VALUE,valueFromLit(i))),
736 newAst(EX_VALUE,valueFromLit(*s))));
737 return decorateType(resolveSymbols(rast));
743 /*-----------------------------------------------------------------*/
744 /* createIvalPtr - generates initial value for pointers */
745 /*-----------------------------------------------------------------*/
746 ast *createIvalPtr (ast *sym,link *type,initList *ilist)
752 if ( ilist->type == INIT_DEEP )
753 ilist = ilist->init.deep ;
755 iexpr = decorateType(resolveSymbols(list2expr(ilist)));
757 /* if character pointer */
758 if (IS_CHAR(type->next))
759 if ((rast = createIvalCharPtr (sym,type,iexpr)))
762 return newNode('=',sym,iexpr);
765 /*-----------------------------------------------------------------*/
766 /* createIval - generates code for initial value */
767 /*-----------------------------------------------------------------*/
768 ast *createIval (ast *sym, link *type, initList *ilist, ast *wid)
775 /* if structure then */
777 rast = createIvalStruct(sym, type,ilist);
779 /* if this is a pointer */
781 rast = createIvalPtr(sym, type,ilist);
783 /* if this is an array */
785 rast = createIvalArray(sym, type,ilist);
787 /* if type is SPECIFIER */
789 rast = createIvalType (sym,type,ilist);
791 return decorateType(resolveSymbols(newNode(NULLOP,wid,rast)));
793 return decorateType(resolveSymbols(rast)) ;
796 /*-----------------------------------------------------------------*/
797 /* initAggregates - initialises aggregate variables with initv */
798 /*-----------------------------------------------------------------*/
799 ast *initAggregates ( symbol *sym, initList *ival, ast *wid)
801 return createIval (newAst(EX_VALUE,symbolVal(sym)),sym->type,ival,wid);
804 /*-----------------------------------------------------------------*/
805 /* gatherAutoInit - creates assignment expressions for initial */
807 /*-----------------------------------------------------------------*/
808 ast *gatherAutoInit ( symbol *autoChain )
815 for ( sym = autoChain ; sym ; sym = sym->next ) {
817 /* resolve the symbols in the ival */
819 resolveIvalSym(sym->ival);
821 /* if this is a static variable & has an */
822 /* initial value the code needs to be lifted */
823 /* here to the main portion since they can be */
824 /* initialised only once at the start */
825 if ( IS_STATIC(sym->etype) && sym->ival &&
826 SPEC_SCLS(sym->etype) != S_CODE) {
829 /* insert the symbol into the symbol table */
830 /* with level = 0 & name = rname */
831 newSym = copySymbol (sym);
832 addSym (SymbolTab,newSym,newSym->name,0,0);
834 /* now lift the code to main */
835 if (IS_AGGREGATE(sym->type))
836 work = initAggregates (sym, sym->ival,NULL);
838 work = newNode('=' ,newAst(EX_VALUE,symbolVal(newSym)),
839 list2expr(sym->ival));
841 setAstLineno(work,sym->lineDef);
845 staticAutos = newNode(NULLOP,staticAutos,work);
852 /* if there is an initial value */
853 if ( sym->ival && SPEC_SCLS(sym->etype)!=S_CODE) {
854 if (IS_AGGREGATE(sym->type))
855 work = initAggregates (sym,sym->ival,NULL);
857 work = newNode('=' ,newAst(EX_VALUE,symbolVal(sym)),
858 list2expr(sym->ival));
860 setAstLineno (work,sym->lineDef);
863 init = newNode(NULLOP,init,work);
872 /*-----------------------------------------------------------------*/
873 /* stringToSymbol - creates a symbol from a literal string */
874 /*-----------------------------------------------------------------*/
875 static value *stringToSymbol (value *val)
877 char name[SDCC_NAME_MAX+1];
878 static int charLbl = 0;
881 sprintf(name,"_str_%d",charLbl++);
882 sym = newSymbol(name,0); /* make it @ level 0 */
883 strcpy(sym->rname,name);
885 /* copy the type from the value passed */
886 sym->type = copyLinkChain(val->type);
887 sym->etype = getSpec(sym->type);
888 /* change to storage class & output class */
889 SPEC_SCLS(sym->etype) = S_CODE ;
890 SPEC_CVAL(sym->etype).v_char = SPEC_CVAL(val->etype).v_char ;
891 SPEC_STAT(sym->etype) = 1;
892 /* make the level & block = 0 */
893 sym->block = sym->level = 0;
896 sym->ival = newiList(INIT_NODE,newAst(EX_VALUE,val));
903 return symbolVal(sym);
907 /*-----------------------------------------------------------------*/
908 /* processBlockVars - will go thru the ast looking for block if */
909 /* a block is found then will allocate the syms */
910 /* will also gather the auto inits present */
911 /*-----------------------------------------------------------------*/
912 ast *processBlockVars ( ast *tree , int *stack, int action)
917 /* if this is a block */
918 if (tree->type == EX_OP && tree->opval.op == BLOCK ) {
921 if (action == ALLOCATE) {
922 autoInit = gatherAutoInit (tree->values.sym);
923 *stack += allocVariables (tree->values.sym);
925 /* if there are auto inits then do them */
927 tree->left = newNode(NULLOP,autoInit,tree->left);
928 } else /* action is deallocate */
929 deallocLocal (tree->values.sym) ;
932 processBlockVars (tree->left, stack, action);
933 processBlockVars (tree->right, stack, action);
937 /*-----------------------------------------------------------------*/
938 /* constExprValue - returns the value of a constant expression */
939 /*-----------------------------------------------------------------*/
940 value *constExprValue (ast *cexpr, int check)
942 cexpr = decorateType(resolveSymbols(cexpr));
944 /* if this is not a constant then */
945 if (!IS_LITERAL(cexpr->ftype)) {
946 /* then check if this is a literal array
948 if (SPEC_SCLS(cexpr->etype) == S_CODE &&
949 SPEC_CVAL(cexpr->etype).v_char &&
950 IS_ARRAY(cexpr->ftype)) {
951 value *val = valFromType(cexpr->ftype);
952 SPEC_SCLS(val->etype) = S_LITERAL;
953 val->sym =cexpr->opval.val->sym ;
954 val->sym->type = copyLinkChain(cexpr->ftype);
955 val->sym->etype = getSpec(val->sym->type);
956 strcpy(val->name,cexpr->opval.val->sym->rname);
960 /* if we are casting a literal value then */
961 if (IS_AST_OP(cexpr) &&
962 cexpr->opval.op == CAST &&
963 IS_LITERAL(cexpr->left->ftype))
964 return valCastLiteral(cexpr->ftype,
965 floatFromVal(cexpr->left->opval.val));
967 if (IS_AST_VALUE(cexpr))
968 return cexpr->opval.val;
971 werror(E_CONST_EXPECTED,"found expression");
976 /* return the value */
977 return cexpr->opval.val ;
981 /*-----------------------------------------------------------------*/
982 /* isLabelInAst - will return true if a given label is found */
983 /*-----------------------------------------------------------------*/
984 bool isLabelInAst (symbol *label, ast *tree)
986 if (!tree || IS_AST_VALUE(tree) || IS_AST_LINK(tree))
989 if (IS_AST_OP(tree) &&
990 tree->opval.op == LABEL &&
991 isSymbolEqual(AST_SYMBOL(tree->left),label))
994 return isLabelInAst(label,tree->right) &&
995 isLabelInAst(label,tree->left);
999 /*-----------------------------------------------------------------*/
1000 /* isLoopCountable - return true if the loop count can be determi- */
1001 /* -ned at compile time . */
1002 /*-----------------------------------------------------------------*/
1003 bool isLoopCountable (ast *initExpr, ast *condExpr, ast *loopExpr,
1004 symbol **sym,ast **init, ast **end)
1007 /* the loop is considered countable if the following
1008 conditions are true :-
1010 a) initExpr :- <sym> = <const>
1011 b) condExpr :- <sym> < <const1>
1012 c) loopExpr :- <sym> ++
1015 /* first check the initExpr */
1016 if ( IS_AST_OP(initExpr) &&
1017 initExpr->opval.op == '=' && /* is assignment */
1018 IS_AST_SYM_VALUE(initExpr->left)) { /* left is a symbol */
1020 *sym = AST_SYMBOL(initExpr->left);
1021 *init= initExpr->right;
1026 /* for now the symbol has to be of
1028 if (!IS_INTEGRAL((*sym)->type))
1031 /* now check condExpr */
1032 if (IS_AST_OP(condExpr)) {
1034 switch (condExpr->opval.op) {
1036 if (IS_AST_SYM_VALUE(condExpr->left) &&
1037 isSymbolEqual (*sym,AST_SYMBOL(condExpr->left)) &&
1038 IS_AST_LIT_VALUE(condExpr->right)) {
1039 *end = condExpr->right;
1045 if (IS_AST_OP(condExpr->left) &&
1046 condExpr->left->opval.op == '>' &&
1047 IS_AST_LIT_VALUE(condExpr->left->right) &&
1048 IS_AST_SYM_VALUE(condExpr->left->left)&&
1049 isSymbolEqual (*sym,AST_SYMBOL(condExpr->left->left))) {
1051 *end = newNode('+', condExpr->left->right,
1052 newAst(EX_VALUE,constVal("1")));
1063 /* check loop expression is of the form <sym>++ */
1064 if (!IS_AST_OP(loopExpr))
1067 /* check if <sym> ++ */
1068 if (loopExpr->opval.op == INC_OP) {
1070 if (loopExpr->left) {
1072 if (IS_AST_SYM_VALUE(loopExpr->left) &&
1073 isSymbolEqual(*sym,AST_SYMBOL(loopExpr->left)))
1078 if (IS_AST_SYM_VALUE(loopExpr->right) &&
1079 isSymbolEqual(*sym,AST_SYMBOL(loopExpr->right)))
1086 if ( loopExpr->opval.op == ADD_ASSIGN ) {
1088 if (IS_AST_SYM_VALUE(loopExpr->left) &&
1089 isSymbolEqual(*sym,AST_SYMBOL(loopExpr->left)) &&
1090 IS_AST_LIT_VALUE(loopExpr->right) &&
1091 (int)AST_LIT_VALUE(loopExpr->right) != 1)
1099 /*-----------------------------------------------------------------*/
1100 /* astHasVolatile - returns true if ast contains any volatile */
1101 /*-----------------------------------------------------------------*/
1102 bool astHasVolatile (ast *tree)
1107 if (TETYPE(tree) && IS_VOLATILE(TETYPE(tree)))
1110 if (IS_AST_OP(tree))
1111 return astHasVolatile(tree->left) ||
1112 astHasVolatile(tree->right);
1117 /*-----------------------------------------------------------------*/
1118 /* astHasPointer - return true if the ast contains any ptr variable*/
1119 /*-----------------------------------------------------------------*/
1120 bool astHasPointer (ast *tree)
1125 if (IS_AST_LINK(tree))
1128 /* if we hit an array expression then check
1129 only the left side */
1130 if (IS_AST_OP(tree) && tree->opval.op == '[')
1131 return astHasPointer(tree->left);
1133 if (IS_AST_VALUE(tree))
1134 return IS_PTR(tree->ftype) || IS_ARRAY(tree->ftype);
1136 return astHasPointer(tree->left) ||
1137 astHasPointer(tree->right);
1141 /*-----------------------------------------------------------------*/
1142 /* astHasSymbol - return true if the ast has the given symbol */
1143 /*-----------------------------------------------------------------*/
1144 bool astHasSymbol (ast *tree, symbol *sym)
1146 if (!tree || IS_AST_LINK(tree))
1149 if (IS_AST_VALUE(tree)) {
1150 if (IS_AST_SYM_VALUE(tree))
1151 return isSymbolEqual(AST_SYMBOL(tree),sym);
1156 return astHasSymbol(tree->left,sym) ||
1157 astHasSymbol(tree->right,sym);
1160 /*-----------------------------------------------------------------*/
1161 /* isConformingBody - the loop body has to conform to a set of rules */
1162 /* for the loop to be considered reversible read on for rules */
1163 /*-----------------------------------------------------------------*/
1164 bool isConformingBody (ast *pbody, symbol *sym, ast *body)
1167 /* we are going to do a pre-order traversal of the
1168 tree && check for the following conditions. (essentially
1169 a set of very shallow tests )
1170 a) the sym passed does not participate in
1171 any arithmetic operation
1172 b) There are no function calls
1173 c) all jumps are within the body
1174 d) address of loop control variable not taken
1175 e) if an assignment has a pointer on the
1176 left hand side make sure right does not have
1177 loop control variable */
1179 /* if we reach the end or a leaf then true */
1180 if (!pbody || IS_AST_LINK(pbody) || IS_AST_VALUE(pbody))
1184 /* if anything else is "volatile" */
1185 if (IS_VOLATILE(TETYPE(pbody)))
1188 /* we will walk the body in a pre-order traversal for
1190 switch (pbody->opval.op) {
1191 /*------------------------------------------------------------------*/
1193 return isConformingBody (pbody->right,sym,body);
1195 /*------------------------------------------------------------------*/
1200 /*------------------------------------------------------------------*/
1201 case INC_OP: /* incerement operator unary so left only */
1204 /* sure we are not sym is not modified */
1206 IS_AST_SYM_VALUE(pbody->left) &&
1207 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1211 IS_AST_SYM_VALUE(pbody->right) &&
1212 isSymbolEqual(AST_SYMBOL(pbody->right),sym))
1217 /*------------------------------------------------------------------*/
1219 case '*' : /* can be unary : if right is null then unary operation */
1224 /* if right is NULL then unary operation */
1225 /*------------------------------------------------------------------*/
1226 /*----------------------------*/
1228 /*----------------------------*/
1229 if ( ! pbody->right ) {
1230 if (IS_AST_SYM_VALUE(pbody->left) &&
1231 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1234 return isConformingBody(pbody->left,sym,body) ;
1236 if (astHasSymbol(pbody->left,sym) ||
1237 astHasSymbol(pbody->right,sym))
1242 /*------------------------------------------------------------------*/
1250 if (IS_AST_SYM_VALUE(pbody->left) &&
1251 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1254 if (IS_AST_SYM_VALUE(pbody->right) &&
1255 isSymbolEqual(AST_SYMBOL(pbody->right),sym))
1258 return isConformingBody(pbody->left,sym,body) &&
1259 isConformingBody(pbody->right,sym,body);
1266 if (IS_AST_SYM_VALUE(pbody->left) &&
1267 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1269 return isConformingBody (pbody->left,sym,body);
1271 /*------------------------------------------------------------------*/
1283 case SIZEOF: /* evaluate wihout code generation */
1285 return isConformingBody(pbody->left,sym,body) &&
1286 isConformingBody(pbody->right,sym,body);
1288 /*------------------------------------------------------------------*/
1291 /* if left has a pointer & right has loop
1292 control variable then we cannot */
1293 if (astHasPointer(pbody->left) &&
1294 astHasSymbol (pbody->right,sym))
1296 if (astHasVolatile(pbody->left))
1299 if (IS_AST_SYM_VALUE(pbody->left) &&
1300 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1303 if (astHasVolatile(pbody->left))
1306 return isConformingBody(pbody->left,sym,body) &&
1307 isConformingBody(pbody->right,sym,body);
1318 assert("Parser should not have generated this\n");
1320 /*------------------------------------------------------------------*/
1321 /*----------------------------*/
1322 /* comma operator */
1323 /*----------------------------*/
1325 return isConformingBody(pbody->left,sym,body) &&
1326 isConformingBody(pbody->right,sym,body);
1328 /*------------------------------------------------------------------*/
1329 /*----------------------------*/
1331 /*----------------------------*/
1335 /*------------------------------------------------------------------*/
1336 /*----------------------------*/
1337 /* return statement */
1338 /*----------------------------*/
1343 if (isLabelInAst (AST_SYMBOL(pbody->left),body))
1348 if (astHasSymbol(pbody->left,sym))
1355 return isConformingBody(pbody->left,sym,body) &&
1356 isConformingBody(pbody->right,sym,body);
1362 /*-----------------------------------------------------------------*/
1363 /* isLoopReversible - takes a for loop as input && returns true */
1364 /* if the for loop is reversible. If yes will set the value of */
1365 /* the loop control var & init value & termination value */
1366 /*-----------------------------------------------------------------*/
1367 bool isLoopReversible (ast *loop, symbol **loopCntrl,
1368 ast **init, ast **end )
1370 /* if option says don't do it then don't */
1371 if (optimize.noLoopReverse)
1373 /* there are several tests to determine this */
1375 /* for loop has to be of the form
1376 for ( <sym> = <const1> ;
1377 [<sym> < <const2>] ;
1378 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1380 if (! isLoopCountable (AST_FOR(loop,initExpr),
1381 AST_FOR(loop,condExpr),
1382 AST_FOR(loop,loopExpr),
1383 loopCntrl,init,end))
1386 /* now do some serious checking on the body of the loop
1389 return isConformingBody(loop->left,*loopCntrl,loop->left);
1393 /*-----------------------------------------------------------------*/
1394 /* replLoopSym - replace the loop sym by loop sym -1 */
1395 /*-----------------------------------------------------------------*/
1396 static void replLoopSym ( ast *body, symbol *sym)
1399 if (!body || IS_AST_LINK(body))
1402 if (IS_AST_SYM_VALUE(body)) {
1404 if (isSymbolEqual(AST_SYMBOL(body),sym)) {
1407 body->opval.op = '-';
1408 body->left = newAst(EX_VALUE,symbolVal(sym));
1409 body->right= newAst(EX_VALUE,constVal("1"));
1417 replLoopSym(body->left,sym);
1418 replLoopSym(body->right,sym);
1422 /*-----------------------------------------------------------------*/
1423 /* reverseLoop - do the actual loop reversal */
1424 /*-----------------------------------------------------------------*/
1425 ast *reverseLoop (ast *loop, symbol *sym, ast *init, ast *end)
1429 /* create the following tree
1434 if (sym) goto for_continue ;
1437 /* put it together piece by piece */
1438 rloop = newNode (NULLOP,
1439 createIf(newAst(EX_VALUE,symbolVal(sym)),
1442 symbolVal(AST_FOR(loop,continueLabel))),
1445 newAst(EX_VALUE,symbolVal(sym)),
1450 replLoopSym(loop->left, sym);
1452 rloop = newNode(NULLOP,
1454 newAst(EX_VALUE,symbolVal(sym)),
1455 newNode('-',end,init)),
1456 createLabel(AST_FOR(loop,continueLabel),
1461 newAst(EX_VALUE,symbolVal(sym)),
1462 newAst(EX_VALUE,constVal("1"))),
1465 return decorateType(rloop);
1469 /*-----------------------------------------------------------------*/
1470 /* decorateType - compute type for this tree also does type cheking*/
1471 /* this is done bottom up, since type have to flow upwards*/
1472 /* it also does constant folding, and paramater checking */
1473 /*-----------------------------------------------------------------*/
1474 ast *decorateType (ast *tree)
1482 /* if already has type then do nothing */
1483 if ( tree->decorated )
1486 tree->decorated = 1;
1488 /* print the line */
1489 /* if not block & function */
1490 if ( tree->type == EX_OP &&
1491 ( tree->opval.op != FUNCTION &&
1492 tree->opval.op != BLOCK &&
1493 tree->opval.op != NULLOP )) {
1494 filename = tree->filename ;
1495 lineno = tree->lineno ;
1498 /* if any child is an error | this one is an error do nothing */
1499 if ( tree->isError ||
1500 ( tree->left && tree->left->isError) ||
1501 ( tree->right && tree->right->isError ))
1504 /*------------------------------------------------------------------*/
1505 /*----------------------------*/
1506 /* leaf has been reached */
1507 /*----------------------------*/
1508 /* if this is of type value */
1509 /* just get the type */
1510 if ( tree->type == EX_VALUE ) {
1512 if ( IS_LITERAL(tree->opval.val->etype) ) {
1514 /* if this is a character array then declare it */
1515 if (IS_ARRAY(tree->opval.val->type))
1516 tree->opval.val = stringToSymbol(tree->opval.val);
1518 /* otherwise just copy the type information */
1519 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.val->type);
1523 if ( tree->opval.val->sym ) {
1524 /* if the undefined flag is set then give error message */
1525 if (tree->opval.val->sym->undefined ) {
1526 werror(E_ID_UNDEF,tree->opval.val->sym->name) ;
1528 TTYPE(tree) = TETYPE(tree) =
1529 tree->opval.val->type = tree->opval.val->sym->type =
1530 tree->opval.val->etype = tree->opval.val->sym->etype =
1531 copyLinkChain(INTTYPE);
1535 /* if impilicit i.e. struct/union member then no type */
1536 if (tree->opval.val->sym->implicit )
1537 TTYPE(tree) = TETYPE(tree) = NULL ;
1541 /* else copy the type */
1542 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.val->type);
1544 /* and mark it as referenced */
1545 tree->opval.val->sym->isref = 1;
1546 /* if this is of type function or function pointer */
1547 if (funcInChain(tree->opval.val->type)) {
1548 tree->hasVargs = tree->opval.val->sym->hasVargs;
1549 tree->args = copyValueChain(tree->opval.val->sym->args) ;
1559 /* if type link for the case of cast */
1560 if ( tree->type == EX_LINK ) {
1561 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.lnk);
1568 dtl = decorateType (tree->left);
1569 dtr = decorateType (tree->right);
1571 /* this is to take care of situations
1572 when the tree gets rewritten */
1573 if (dtl != tree->left)
1575 if (dtr != tree->right)
1579 /* depending on type of operator do */
1581 switch (tree->opval.op) {
1582 /*------------------------------------------------------------------*/
1583 /*----------------------------*/
1585 /*----------------------------*/
1588 /* determine which is the array & which the index */
1589 if ((IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree))) && IS_INTEGRAL(LTYPE(tree))) {
1591 ast *tempTree = tree->left ;
1592 tree->left = tree->right ;
1593 tree->right= tempTree ;
1596 /* first check if this is a array or a pointer */
1597 if ( (!IS_ARRAY(LTYPE(tree))) && (!IS_PTR(LTYPE(tree)))) {
1598 werror(E_NEED_ARRAY_PTR,"[]");
1599 goto errorTreeReturn ;
1602 /* check if the type of the idx */
1603 if (!IS_INTEGRAL(RTYPE(tree))) {
1604 werror(E_IDX_NOT_INT);
1605 goto errorTreeReturn ;
1608 /* if the left is an rvalue then error */
1610 werror(E_LVALUE_REQUIRED,"array access");
1611 goto errorTreeReturn ;
1614 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree)->next);
1617 /*------------------------------------------------------------------*/
1618 /*----------------------------*/
1620 /*----------------------------*/
1622 /* if this is not a structure */
1623 if (!IS_STRUCT(LTYPE(tree))) {
1624 werror(E_STRUCT_UNION,".");
1625 goto errorTreeReturn ;
1627 TTYPE(tree) = structElemType (LTYPE(tree),
1628 (tree->right->type == EX_VALUE ?
1629 tree->right->opval.val : NULL ),&tree->args);
1630 TETYPE(tree) = getSpec(TTYPE(tree));
1633 /*------------------------------------------------------------------*/
1634 /*----------------------------*/
1635 /* struct/union pointer */
1636 /*----------------------------*/
1638 /* if not pointer to a structure */
1639 if (!IS_PTR(LTYPE(tree))) {
1641 goto errorTreeReturn ;
1644 if (!IS_STRUCT(LTYPE(tree)->next)) {
1645 werror(E_STRUCT_UNION,"->");
1646 goto errorTreeReturn ;
1649 TTYPE(tree) = structElemType (LTYPE(tree)->next,
1650 (tree->right->type == EX_VALUE ?
1651 tree->right->opval.val : NULL ),&tree->args);
1652 TETYPE(tree) = getSpec(TTYPE(tree));
1655 /*------------------------------------------------------------------*/
1656 /*----------------------------*/
1657 /* ++/-- operation */
1658 /*----------------------------*/
1659 case INC_OP: /* incerement operator unary so left only */
1662 link *ltc = (tree->right ? RTYPE(tree) : LTYPE(tree) );
1663 COPYTYPE(TTYPE(tree),TETYPE(tree),ltc);
1664 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
1665 werror(E_CODE_WRITE,"++/--");
1674 /*------------------------------------------------------------------*/
1675 /*----------------------------*/
1677 /*----------------------------*/
1678 case '&': /* can be unary */
1679 /* if right is NULL then unary operation */
1680 if ( tree->right ) /* not an unary operation */ {
1682 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1683 werror(E_BITWISE_OP);
1684 werror(E_CONTINUE,"left & right types are ");
1685 printTypeChain(LTYPE(tree),stderr);
1686 fprintf(stderr,",");
1687 printTypeChain(RTYPE(tree),stderr);
1688 fprintf(stderr,"\n");
1689 goto errorTreeReturn ;
1692 /* if they are both literal */
1693 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1694 tree->type = EX_VALUE ;
1695 tree->opval.val = valBitwise (valFromType(LETYPE(tree)),
1696 valFromType(RETYPE(tree)),'&');
1698 tree->right = tree->left = NULL;
1699 TETYPE(tree) = tree->opval.val->etype ;
1700 TTYPE(tree) = tree->opval.val->type;
1704 /* see if this is a GETHBIT operation if yes
1707 ast *otree = optimizeGetHbit(tree);
1710 return decorateType(otree);
1713 /* if right or left is literal then result of that type*/
1714 if (IS_LITERAL(RTYPE(tree))) {
1716 TTYPE(tree) = copyLinkChain(RTYPE(tree));
1717 TETYPE(tree) = getSpec(TTYPE(tree));
1718 SPEC_SCLS(TETYPE(tree)) = S_AUTO;
1721 if (IS_LITERAL(LTYPE(tree))) {
1722 TTYPE(tree) = copyLinkChain(LTYPE(tree));
1723 TETYPE(tree) = getSpec(TTYPE(tree));
1724 SPEC_SCLS(TETYPE(tree)) = S_AUTO;
1729 computeType (LTYPE(tree), RTYPE(tree));
1730 TETYPE(tree) = getSpec(TTYPE(tree));
1733 LRVAL(tree) = RRVAL(tree) = 1;
1737 /*------------------------------------------------------------------*/
1738 /*----------------------------*/
1740 /*----------------------------*/
1742 p->class = DECLARATOR;
1743 /* if bit field then error */
1744 if (IS_BITVAR(tree->left->etype)) {
1745 werror (E_ILLEGAL_ADDR,"addrress of bit variable");
1746 goto errorTreeReturn ;
1749 if (SPEC_SCLS(tree->left->etype)== S_REGISTER ) {
1750 werror (E_ILLEGAL_ADDR,"address of register variable");
1751 goto errorTreeReturn;
1754 if (IS_FUNC(LTYPE(tree))) {
1755 werror(E_ILLEGAL_ADDR,"address of function");
1756 goto errorTreeReturn ;
1760 werror(E_LVALUE_REQUIRED,"address of");
1761 goto errorTreeReturn ;
1763 if (SPEC_SCLS(tree->left->etype) == S_CODE) {
1764 DCL_TYPE(p) = CPOINTER ;
1765 DCL_PTR_CONST(p) = port->mem.code_ro;
1768 if (SPEC_SCLS(tree->left->etype) == S_XDATA)
1769 DCL_TYPE(p) = FPOINTER;
1771 if (SPEC_SCLS(tree->left->etype) == S_XSTACK )
1772 DCL_TYPE(p) = PPOINTER ;
1774 if (SPEC_SCLS(tree->left->etype) == S_IDATA)
1775 DCL_TYPE(p) = IPOINTER ;
1777 if (SPEC_SCLS(tree->left->etype) == S_EEPROM)
1778 DCL_TYPE(p) = EEPPOINTER ;
1780 DCL_TYPE(p) = POINTER ;
1782 if (IS_AST_SYM_VALUE(tree->left)) {
1783 AST_SYMBOL(tree->left)->addrtaken = 1;
1784 AST_SYMBOL(tree->left)->allocreq = 1;
1787 p->next = LTYPE(tree);
1789 TETYPE(tree) = getSpec(TTYPE(tree));
1790 DCL_PTR_CONST(p) = SPEC_CONST(TETYPE(tree));
1791 DCL_PTR_VOLATILE(p) = SPEC_VOLATILE(TETYPE(tree));
1796 /*------------------------------------------------------------------*/
1797 /*----------------------------*/
1799 /*----------------------------*/
1801 /* if the rewrite succeeds then don't go any furthur */
1803 ast *wtree = optimizeRRCRLC ( tree );
1805 return decorateType(wtree) ;
1807 /*------------------------------------------------------------------*/
1808 /*----------------------------*/
1810 /*----------------------------*/
1812 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1813 werror(E_BITWISE_OP);
1814 werror(E_CONTINUE,"left & right types are ");
1815 printTypeChain(LTYPE(tree),stderr);
1816 fprintf(stderr,",");
1817 printTypeChain(RTYPE(tree),stderr);
1818 fprintf(stderr,"\n");
1819 goto errorTreeReturn ;
1822 /* if they are both literal then */
1823 /* rewrite the tree */
1824 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1825 tree->type = EX_VALUE ;
1826 tree->opval.val = valBitwise (valFromType(LETYPE(tree)),
1827 valFromType(RETYPE(tree)),
1829 tree->right = tree->left = NULL;
1830 TETYPE(tree) = tree->opval.val->etype;
1831 TTYPE(tree) = tree->opval.val->type;
1834 LRVAL(tree) = RRVAL(tree) = 1;
1835 TETYPE(tree) = getSpec (TTYPE(tree) =
1836 computeType(LTYPE(tree),
1839 /*------------------------------------------------------------------*/
1840 /*----------------------------*/
1842 /*----------------------------*/
1844 if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) {
1845 werror(E_INVALID_OP,"divide");
1846 goto errorTreeReturn ;
1848 /* if they are both literal then */
1849 /* rewrite the tree */
1850 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1851 tree->type = EX_VALUE ;
1852 tree->opval.val = valDiv (valFromType(LETYPE(tree)),
1853 valFromType(RETYPE(tree)));
1854 tree->right = tree->left = NULL;
1855 TETYPE(tree) = getSpec(TTYPE(tree) =
1856 tree->opval.val->type);
1859 LRVAL(tree) = RRVAL(tree) = 1;
1860 TETYPE(tree) = getSpec (TTYPE(tree) =
1861 computeType(LTYPE(tree),
1865 /*------------------------------------------------------------------*/
1866 /*----------------------------*/
1868 /*----------------------------*/
1870 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1871 werror(E_BITWISE_OP);
1872 werror(E_CONTINUE,"left & right types are ");
1873 printTypeChain(LTYPE(tree),stderr);
1874 fprintf(stderr,",");
1875 printTypeChain(RTYPE(tree),stderr);
1876 fprintf(stderr,"\n");
1877 goto errorTreeReturn ;
1879 /* if they are both literal then */
1880 /* rewrite the tree */
1881 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1882 tree->type = EX_VALUE ;
1883 tree->opval.val = valMod (valFromType(LETYPE(tree)),
1884 valFromType(RETYPE(tree)));
1885 tree->right = tree->left = NULL;
1886 TETYPE(tree) = getSpec(TTYPE(tree) =
1887 tree->opval.val->type);
1890 LRVAL(tree) = RRVAL(tree) = 1;
1891 TETYPE(tree) = getSpec (TTYPE(tree) =
1892 computeType(LTYPE(tree),
1896 /*------------------------------------------------------------------*/
1897 /*----------------------------*/
1898 /* address dereference */
1899 /*----------------------------*/
1900 case '*': /* can be unary : if right is null then unary operation */
1901 if ( ! tree->right ) {
1902 if (!IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) {
1904 goto errorTreeReturn ;
1908 werror(E_LVALUE_REQUIRED,"pointer deref");
1909 goto errorTreeReturn ;
1911 TTYPE(tree) = copyLinkChain ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) ?
1912 LTYPE(tree)->next : NULL );
1913 TETYPE(tree) = getSpec(TTYPE(tree));
1914 tree->args = tree->left->args ;
1915 tree->hasVargs = tree->left->hasVargs ;
1916 SPEC_CONST(TETYPE(tree)) = DCL_PTR_CONST(LTYPE(tree));
1920 /*------------------------------------------------------------------*/
1921 /*----------------------------*/
1922 /* multiplication */
1923 /*----------------------------*/
1924 if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) {
1925 werror(E_INVALID_OP,"multiplication");
1926 goto errorTreeReturn ;
1929 /* if they are both literal then */
1930 /* rewrite the tree */
1931 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1932 tree->type = EX_VALUE ;
1933 tree->opval.val = valMult (valFromType(LETYPE(tree)),
1934 valFromType(RETYPE(tree)));
1935 tree->right = tree->left = NULL;
1936 TETYPE(tree) = getSpec(TTYPE(tree) =
1937 tree->opval.val->type);
1941 /* if left is a literal exchange left & right */
1942 if (IS_LITERAL(LTYPE(tree))) {
1943 ast *tTree = tree->left ;
1944 tree->left = tree->right ;
1945 tree->right= tTree ;
1948 LRVAL(tree) = RRVAL(tree) = 1;
1949 TETYPE(tree) = getSpec (TTYPE(tree) =
1950 computeType(LTYPE(tree),
1954 /*------------------------------------------------------------------*/
1955 /*----------------------------*/
1956 /* unary '+' operator */
1957 /*----------------------------*/
1960 if ( ! tree->right ) {
1961 if (!IS_INTEGRAL(LTYPE(tree))) {
1962 werror(E_UNARY_OP,'+');
1963 goto errorTreeReturn ;
1966 /* if left is a literal then do it */
1967 if (IS_LITERAL(LTYPE(tree))) {
1968 tree->type = EX_VALUE ;
1969 tree->opval.val = valFromType(LETYPE(tree));
1971 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
1975 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
1979 /*------------------------------------------------------------------*/
1980 /*----------------------------*/
1982 /*----------------------------*/
1984 /* this is not a unary operation */
1985 /* if both pointers then problem */
1986 if ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) &&
1987 (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)))) {
1988 werror(E_PTR_PLUS_PTR);
1989 goto errorTreeReturn ;
1992 if (!IS_ARITHMETIC(LTYPE(tree)) &&
1993 !IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) {
1994 werror(E_PLUS_INVALID,"+");
1995 goto errorTreeReturn ;
1998 if (!IS_ARITHMETIC(RTYPE(tree)) &&
1999 !IS_PTR(RTYPE(tree)) && !IS_ARRAY(RTYPE(tree))) {
2000 werror(E_PLUS_INVALID,"+");
2001 goto errorTreeReturn;
2003 /* if they are both literal then */
2004 /* rewrite the tree */
2005 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2006 tree->type = EX_VALUE ;
2007 tree->opval.val = valPlus (valFromType(LETYPE(tree)),
2008 valFromType(RETYPE(tree)));
2009 tree->right = tree->left = NULL;
2010 TETYPE(tree) = getSpec(TTYPE(tree) =
2011 tree->opval.val->type);
2015 /* if the right is a pointer or left is a literal
2016 xchange left & right */
2017 if (IS_ARRAY(RTYPE(tree)) ||
2018 IS_PTR(RTYPE(tree)) ||
2019 IS_LITERAL(LTYPE(tree))) {
2020 ast *tTree = tree->left ;
2021 tree->left = tree->right ;
2022 tree->right= tTree ;
2025 LRVAL(tree) = RRVAL(tree) = 1;
2026 /* if the left is a pointer */
2027 if (IS_PTR(LTYPE(tree)))
2028 TETYPE(tree) = getSpec(TTYPE(tree) =
2031 TETYPE(tree) = getSpec(TTYPE(tree) =
2032 computeType(LTYPE(tree),
2036 /*------------------------------------------------------------------*/
2037 /*----------------------------*/
2039 /*----------------------------*/
2040 case '-' : /* can be unary */
2041 /* if right is null then unary */
2042 if ( ! tree->right ) {
2044 if (!IS_ARITHMETIC(LTYPE(tree))) {
2045 werror(E_UNARY_OP,tree->opval.op);
2046 goto errorTreeReturn ;
2049 /* if left is a literal then do it */
2050 if (IS_LITERAL(LTYPE(tree))) {
2051 tree->type = EX_VALUE ;
2052 tree->opval.val = valUnaryPM(valFromType(LETYPE(tree)));
2054 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2058 TTYPE(tree) = LTYPE(tree);
2062 /*------------------------------------------------------------------*/
2063 /*----------------------------*/
2065 /*----------------------------*/
2067 if (!(IS_PTR(LTYPE(tree)) ||
2068 IS_ARRAY(LTYPE(tree)) ||
2069 IS_ARITHMETIC(LTYPE(tree)))) {
2070 werror(E_PLUS_INVALID,"-");
2071 goto errorTreeReturn ;
2074 if (!(IS_PTR(RTYPE(tree)) ||
2075 IS_ARRAY(RTYPE(tree)) ||
2076 IS_ARITHMETIC(RTYPE(tree)))) {
2077 werror(E_PLUS_INVALID,"-");
2078 goto errorTreeReturn ;
2081 if ( (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) &&
2082 ! (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)) ||
2083 IS_INTEGRAL(RTYPE(tree))) ) {
2084 werror(E_PLUS_INVALID,"-");
2085 goto errorTreeReturn ;
2088 /* if they are both literal then */
2089 /* rewrite the tree */
2090 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2091 tree->type = EX_VALUE ;
2092 tree->opval.val = valMinus (valFromType(LETYPE(tree)),
2093 valFromType(RETYPE(tree)));
2094 tree->right = tree->left = NULL;
2095 TETYPE(tree) = getSpec(TTYPE(tree) =
2096 tree->opval.val->type);
2100 /* if the left & right are equal then zero */
2101 if (isAstEqual(tree->left,tree->right)) {
2102 tree->type = EX_VALUE;
2103 tree->left = tree->right = NULL;
2104 tree->opval.val = constVal("0");
2105 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2109 /* if both of them are pointers or arrays then */
2110 /* the result is going to be an integer */
2111 if (( IS_ARRAY(LTYPE(tree)) || IS_PTR(LTYPE(tree))) &&
2112 ( IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree))))
2113 TETYPE(tree) = TTYPE(tree) = newIntLink();
2115 /* if only the left is a pointer */
2116 /* then result is a pointer */
2117 if (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree)))
2118 TETYPE(tree) = getSpec(TTYPE(tree) =
2121 TETYPE(tree) = getSpec (TTYPE(tree) =
2122 computeType(LTYPE(tree),
2124 LRVAL(tree) = RRVAL(tree) = 1;
2127 /*------------------------------------------------------------------*/
2128 /*----------------------------*/
2130 /*----------------------------*/
2132 /* can be only integral type */
2133 if (!IS_INTEGRAL(LTYPE(tree))) {
2134 werror(E_UNARY_OP,tree->opval.op);
2135 goto errorTreeReturn ;
2138 /* if left is a literal then do it */
2139 if (IS_LITERAL(LTYPE(tree))) {
2140 tree->type = EX_VALUE ;
2141 tree->opval.val = valComplement(valFromType(LETYPE(tree)));
2143 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2147 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2150 /*------------------------------------------------------------------*/
2151 /*----------------------------*/
2153 /*----------------------------*/
2155 /* can be pointer */
2156 if (!IS_ARITHMETIC(LTYPE(tree)) &&
2157 !IS_PTR(LTYPE(tree)) &&
2158 !IS_ARRAY(LTYPE(tree))) {
2159 werror(E_UNARY_OP,tree->opval.op);
2160 goto errorTreeReturn ;
2163 /* if left is a literal then do it */
2164 if (IS_LITERAL(LTYPE(tree))) {
2165 tree->type = EX_VALUE ;
2166 tree->opval.val = valNot(valFromType(LETYPE(tree)));
2168 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2172 TTYPE(tree) = TETYPE(tree) = newCharLink();
2175 /*------------------------------------------------------------------*/
2176 /*----------------------------*/
2178 /*----------------------------*/
2181 TTYPE(tree) = LTYPE(tree);
2182 TETYPE(tree) = LETYPE(tree);
2186 TTYPE(tree) = TETYPE(tree) = newCharLink();
2191 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(tree->left->etype)) {
2192 werror(E_SHIFT_OP_INVALID);
2193 werror(E_CONTINUE,"left & right types are ");
2194 printTypeChain(LTYPE(tree),stderr);
2195 fprintf(stderr,",");
2196 printTypeChain(RTYPE(tree),stderr);
2197 fprintf(stderr,"\n");
2198 goto errorTreeReturn ;
2201 /* if they are both literal then */
2202 /* rewrite the tree */
2203 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2204 tree->type = EX_VALUE ;
2205 tree->opval.val = valShift (valFromType(LETYPE(tree)),
2206 valFromType(RETYPE(tree)),
2207 (tree->opval.op == LEFT_OP ? 1 : 0));
2208 tree->right = tree->left = NULL;
2209 TETYPE(tree) = getSpec(TTYPE(tree) =
2210 tree->opval.val->type);
2213 /* if only the right side is a literal & we are
2214 shifting more than size of the left operand then zero */
2215 if (IS_LITERAL(RTYPE(tree)) &&
2216 ((int)floatFromVal( valFromType(RETYPE(tree)))) >=
2217 (getSize(LTYPE(tree))*8)) {
2218 werror(W_SHIFT_CHANGED,
2219 (tree->opval.op == LEFT_OP ? "left" : "right"));
2220 tree->type = EX_VALUE;
2221 tree->left = tree->right = NULL;
2222 tree->opval.val = constVal("0");
2223 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2226 LRVAL(tree) = RRVAL(tree) = 1;
2227 if (IS_LITERAL(LTYPE(tree)) && !IS_LITERAL(RTYPE(tree))) {
2228 COPYTYPE(TTYPE(tree),TETYPE(tree),RTYPE(tree));
2230 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2234 /*------------------------------------------------------------------*/
2235 /*----------------------------*/
2237 /*----------------------------*/
2238 case CAST : /* change the type */
2239 /* cannot cast to an aggregate type */
2240 if (IS_AGGREGATE(LTYPE(tree))) {
2241 werror(E_CAST_ILLEGAL);
2242 goto errorTreeReturn ;
2245 /* if the right is a literal replace the tree */
2246 if (IS_LITERAL(RETYPE(tree)) && !IS_PTR(LTYPE(tree))) {
2247 tree->type = EX_VALUE ;
2249 valCastLiteral(LTYPE(tree),
2250 floatFromVal(valFromType(RETYPE(tree))));
2253 TTYPE(tree) = tree->opval.val->type;
2256 TTYPE(tree) = LTYPE(tree);
2260 TETYPE(tree) = getSpec(TTYPE(tree));
2264 /*------------------------------------------------------------------*/
2265 /*----------------------------*/
2266 /* logical &&, || */
2267 /*----------------------------*/
2270 /* each must me arithmetic type or be a pointer */
2271 if (!IS_PTR(LTYPE(tree)) &&
2272 !IS_ARRAY(LTYPE(tree)) &&
2273 !IS_INTEGRAL(LTYPE(tree))) {
2274 werror(E_COMPARE_OP);
2275 goto errorTreeReturn ;
2278 if (!IS_PTR(RTYPE(tree)) &&
2279 !IS_ARRAY(RTYPE(tree)) &&
2280 !IS_INTEGRAL(RTYPE(tree))) {
2281 werror(E_COMPARE_OP);
2282 goto errorTreeReturn ;
2284 /* if they are both literal then */
2285 /* rewrite the tree */
2286 if (IS_LITERAL(RTYPE(tree)) &&
2287 IS_LITERAL(LTYPE(tree))) {
2288 tree->type = EX_VALUE ;
2289 tree->opval.val = valLogicAndOr (valFromType(LETYPE(tree)),
2290 valFromType(RETYPE(tree)),
2292 tree->right = tree->left = NULL;
2293 TETYPE(tree) = getSpec(TTYPE(tree) =
2294 tree->opval.val->type);
2297 LRVAL(tree) = RRVAL(tree) = 1;
2298 TTYPE(tree) = TETYPE(tree) = newCharLink();
2301 /*------------------------------------------------------------------*/
2302 /*----------------------------*/
2303 /* comparison operators */
2304 /*----------------------------*/
2312 ast *lt = optimizeCompare(tree);
2318 /* if they are pointers they must be castable */
2319 if ( IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree))) {
2320 if (checkType(LTYPE(tree),RTYPE(tree)) == 0) {
2321 werror(E_COMPARE_OP);
2322 fprintf(stderr,"comparing type ");
2323 printTypeChain(LTYPE(tree),stderr);
2324 fprintf(stderr,"to type ");
2325 printTypeChain(RTYPE(tree),stderr);
2326 fprintf(stderr,"\n");
2327 goto errorTreeReturn ;
2330 /* else they should be promotable to one another */
2332 if (!( ( IS_PTR(LTYPE(tree)) && IS_LITERAL(RTYPE(tree))) ||
2333 ( IS_PTR(RTYPE(tree)) && IS_LITERAL(LTYPE(tree)))))
2335 if (checkType (LTYPE(tree),RTYPE(tree)) == 0 ) {
2336 werror(E_COMPARE_OP);
2337 fprintf(stderr,"comparing type ");
2338 printTypeChain(LTYPE(tree),stderr);
2339 fprintf(stderr,"to type ");
2340 printTypeChain(RTYPE(tree),stderr);
2341 fprintf(stderr,"\n");
2342 goto errorTreeReturn ;
2346 /* if they are both literal then */
2347 /* rewrite the tree */
2348 if (IS_LITERAL(RTYPE(tree)) &&
2349 IS_LITERAL(LTYPE(tree))) {
2350 tree->type = EX_VALUE ;
2351 tree->opval.val = valCompare (valFromType(LETYPE(tree)),
2352 valFromType(RETYPE(tree)),
2354 tree->right = tree->left = NULL;
2355 TETYPE(tree) = getSpec(TTYPE(tree) =
2356 tree->opval.val->type);
2359 LRVAL(tree) = RRVAL(tree) = 1;
2360 TTYPE(tree) = TETYPE(tree) = newCharLink();
2363 /*------------------------------------------------------------------*/
2364 /*----------------------------*/
2366 /*----------------------------*/
2367 case SIZEOF : /* evaluate wihout code generation */
2368 /* change the type to a integer */
2369 tree->type = EX_VALUE;
2370 sprintf(buffer,"%d",(getSize(tree->right->ftype)));
2371 tree->opval.val = constVal(buffer);
2372 tree->right = tree->left = NULL;
2373 TETYPE(tree) = getSpec(TTYPE(tree) =
2374 tree->opval.val->type);
2377 /*------------------------------------------------------------------*/
2378 /*----------------------------*/
2379 /* conditional operator '?' */
2380 /*----------------------------*/
2382 /* the type is one on the left */
2383 TTYPE(tree) = LTYPE(tree);
2384 TETYPE(tree)= getSpec (TTYPE(tree));
2388 /* if they don't match we have a problem */
2389 if (checkType( LTYPE(tree), RTYPE(tree)) == 0) {
2390 werror(E_TYPE_MISMATCH,"conditional operator"," ");
2391 goto errorTreeReturn ;
2394 TTYPE(tree) = computeType(LTYPE(tree),RTYPE(tree));
2395 TETYPE(tree)= getSpec(TTYPE(tree));
2399 /*------------------------------------------------------------------*/
2400 /*----------------------------*/
2401 /* assignment operators */
2402 /*----------------------------*/
2405 /* for these it must be both must be integral */
2406 if (!IS_ARITHMETIC(LTYPE(tree)) ||
2407 !IS_ARITHMETIC(RTYPE(tree))) {
2408 werror (E_OPS_INTEGRAL);
2409 goto errorTreeReturn ;
2412 TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree));
2414 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2415 werror(E_CODE_WRITE," ");
2418 werror(E_LVALUE_REQUIRED,"*= or /=");
2419 goto errorTreeReturn ;
2429 /* for these it must be both must be integral */
2430 if (!IS_INTEGRAL(LTYPE(tree)) ||
2431 !IS_INTEGRAL(RTYPE(tree))) {
2432 werror (E_OPS_INTEGRAL);
2433 goto errorTreeReturn ;
2436 TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree));
2438 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2439 werror(E_CODE_WRITE," ");
2442 werror(E_LVALUE_REQUIRED,"&= or |= or ^= or >>= or <<=");
2443 goto errorTreeReturn ;
2448 /*------------------------------------------------------------------*/
2449 /*----------------------------*/
2451 /*----------------------------*/
2453 if (!(IS_PTR(LTYPE(tree)) ||
2454 IS_ARITHMETIC(LTYPE(tree)))) {
2455 werror(E_PLUS_INVALID,"-=");
2456 goto errorTreeReturn ;
2459 if (!(IS_PTR(RTYPE(tree)) ||
2460 IS_ARITHMETIC(RTYPE(tree)))) {
2461 werror(E_PLUS_INVALID,"-=");
2462 goto errorTreeReturn ;
2465 TETYPE(tree) = getSpec (TTYPE(tree) =
2466 computeType(LTYPE(tree),
2469 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2470 werror(E_CODE_WRITE," ");
2473 werror(E_LVALUE_REQUIRED,"-=");
2474 goto errorTreeReturn ;
2479 /*------------------------------------------------------------------*/
2480 /*----------------------------*/
2482 /*----------------------------*/
2484 /* this is not a unary operation */
2485 /* if both pointers then problem */
2486 if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) ) {
2487 werror(E_PTR_PLUS_PTR);
2488 goto errorTreeReturn ;
2491 if (!IS_ARITHMETIC(LTYPE(tree)) && !IS_PTR(LTYPE(tree))) {
2492 werror(E_PLUS_INVALID,"+=");
2493 goto errorTreeReturn ;
2496 if (!IS_ARITHMETIC(RTYPE(tree)) && !IS_PTR(RTYPE(tree))) {
2497 werror(E_PLUS_INVALID,"+=");
2498 goto errorTreeReturn;
2501 TETYPE(tree) = getSpec (TTYPE(tree) =
2502 computeType(LTYPE(tree),
2505 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2506 werror(E_CODE_WRITE," ");
2509 werror(E_LVALUE_REQUIRED,"+=");
2510 goto errorTreeReturn ;
2513 tree->right = decorateType(newNode('+',copyAst(tree->left),tree->right));
2514 tree->opval.op = '=';
2517 /*------------------------------------------------------------------*/
2518 /*----------------------------*/
2519 /* straight assignemnt */
2520 /*----------------------------*/
2522 /* cannot be an aggregate */
2523 if (IS_AGGREGATE(LTYPE(tree))) {
2524 werror(E_AGGR_ASSIGN);
2525 goto errorTreeReturn;
2528 /* they should either match or be castable */
2529 if (checkType (LTYPE(tree),RTYPE(tree)) == 0) {
2530 werror(E_TYPE_MISMATCH,"assignment"," ");
2531 fprintf(stderr,"type --> '");
2532 printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' ");
2533 fprintf(stderr,"assigned to type --> '");
2534 printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n");
2535 goto errorTreeReturn ;
2538 /* if the left side of the tree is of type void
2539 then report error */
2540 if (IS_VOID(LTYPE(tree))) {
2541 werror(E_CAST_ZERO);
2542 fprintf(stderr,"type --> '");
2543 printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' ");
2544 fprintf(stderr,"assigned to type --> '");
2545 printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n");
2548 /* extra checks for pointer types */
2549 if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) &&
2550 !IS_GENPTR(LTYPE(tree))) {
2551 if (DCL_TYPE(LTYPE(tree)) != DCL_TYPE(RTYPE(tree)))
2552 werror(W_PTR_ASSIGN);
2555 TETYPE(tree) = getSpec(TTYPE(tree) =
2559 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2560 werror(E_CODE_WRITE," ");
2563 werror(E_LVALUE_REQUIRED,"=");
2564 goto errorTreeReturn ;
2569 /*------------------------------------------------------------------*/
2570 /*----------------------------*/
2571 /* comma operator */
2572 /*----------------------------*/
2574 TETYPE(tree) = getSpec(TTYPE(tree) = RTYPE(tree));
2577 /*------------------------------------------------------------------*/
2578 /*----------------------------*/
2580 /*----------------------------*/
2585 if (processParms (tree->left,
2587 tree->right,&parmNumber))
2588 goto errorTreeReturn ;
2590 if (options.stackAuto || IS_RENT(LETYPE(tree))) {
2591 tree->left->args = reverseVal(tree->left->args);
2592 reverseParms(tree->right);
2595 tree->args = tree->left->args ;
2596 TETYPE(tree) = getSpec (TTYPE(tree) = LTYPE(tree)->next);
2599 /*------------------------------------------------------------------*/
2600 /*----------------------------*/
2601 /* return statement */
2602 /*----------------------------*/
2607 if (checkType(currFunc->type->next,RTYPE(tree)) == 0) {
2608 werror(E_RETURN_MISMATCH);
2609 goto errorTreeReturn ;
2612 if (IS_VOID(currFunc->type->next)
2614 !IS_VOID(RTYPE(tree))) {
2615 werror(E_FUNC_VOID);
2616 goto errorTreeReturn ;
2619 /* if there is going to be a casing required then add it */
2620 if (checkType(currFunc->type->next,RTYPE(tree)) < 0 ) {
2622 decorateType(newNode(CAST,
2624 copyLinkChain(currFunc->type->next)),
2633 if (!IS_VOID(currFunc->type->next) && tree->right == NULL ) {
2634 werror(E_VOID_FUNC,currFunc->name);
2635 goto errorTreeReturn ;
2638 TTYPE(tree) = TETYPE(tree) = NULL ;
2641 /*------------------------------------------------------------------*/
2642 /*----------------------------*/
2643 /* switch statement */
2644 /*----------------------------*/
2646 /* the switch value must be an integer */
2647 if (!IS_INTEGRAL(LTYPE(tree))) {
2648 werror (E_SWITCH_NON_INTEGER);
2649 goto errorTreeReturn ;
2652 TTYPE(tree) = TETYPE(tree) = NULL ;
2655 /*------------------------------------------------------------------*/
2656 /*----------------------------*/
2658 /*----------------------------*/
2660 tree->left = backPatchLabels(tree->left,
2663 TTYPE(tree) = TETYPE(tree) = NULL;
2666 /*------------------------------------------------------------------*/
2667 /*----------------------------*/
2669 /*----------------------------*/
2672 decorateType(resolveSymbols(AST_FOR(tree,initExpr)));
2673 decorateType(resolveSymbols(AST_FOR(tree,condExpr)));
2674 decorateType(resolveSymbols(AST_FOR(tree,loopExpr)));
2676 /* if the for loop is reversible then
2677 reverse it otherwise do what we normally
2683 if (isLoopReversible (tree,&sym,&init,&end))
2684 return reverseLoop (tree,sym,init,end);
2686 return decorateType(createFor ( AST_FOR(tree,trueLabel),
2687 AST_FOR(tree,continueLabel) ,
2688 AST_FOR(tree,falseLabel) ,
2689 AST_FOR(tree,condLabel) ,
2690 AST_FOR(tree,initExpr) ,
2691 AST_FOR(tree,condExpr) ,
2692 AST_FOR(tree,loopExpr),
2696 TTYPE(tree) = TETYPE(tree) = NULL ;
2700 /* some error found this tree will be killed */
2702 TTYPE(tree) = TETYPE(tree) = newCharLink();
2703 tree->opval.op = NULLOP ;
2709 /*-----------------------------------------------------------------*/
2710 /* sizeofOp - processes size of operation */
2711 /*-----------------------------------------------------------------*/
2712 value *sizeofOp( link *type)
2716 /* get the size and convert it to character */
2717 sprintf (buff,"%d", getSize(type));
2719 /* now convert into value */
2720 return constVal (buff);
2724 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
2725 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
2726 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
2727 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
2728 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
2729 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
2730 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
2732 /*-----------------------------------------------------------------*/
2733 /* backPatchLabels - change and or not operators to flow control */
2734 /*-----------------------------------------------------------------*/
2735 ast *backPatchLabels (ast *tree, symbol *trueLabel, symbol *falseLabel )
2741 if ( ! (IS_ANDORNOT(tree)))
2744 /* if this an and */
2746 static int localLbl = 0 ;
2747 symbol *localLabel ;
2749 sprintf (buffer,"_and_%d",localLbl++);
2750 localLabel = newSymbol(buffer,NestLevel);
2752 tree->left = backPatchLabels (tree->left, localLabel,falseLabel);
2754 /* if left is already a IFX then just change the if true label in that */
2755 if (!IS_IFX(tree->left))
2756 tree->left = newIfxNode(tree->left,localLabel,falseLabel);
2758 tree->right = backPatchLabels(tree->right,trueLabel,falseLabel);
2759 /* right is a IFX then just join */
2760 if (IS_IFX(tree->right))
2761 return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right));
2763 tree->right = createLabel(localLabel,tree->right);
2764 tree->right = newIfxNode(tree->right,trueLabel,falseLabel);
2766 return newNode(NULLOP,tree->left,tree->right);
2769 /* if this is an or operation */
2771 static int localLbl = 0 ;
2772 symbol *localLabel ;
2774 sprintf (buffer,"_or_%d",localLbl++);
2775 localLabel = newSymbol(buffer,NestLevel);
2777 tree->left = backPatchLabels (tree->left, trueLabel,localLabel);
2779 /* if left is already a IFX then just change the if true label in that */
2780 if (!IS_IFX(tree->left))
2781 tree->left = newIfxNode(tree->left,trueLabel,localLabel);
2783 tree->right = backPatchLabels(tree->right,trueLabel,falseLabel);
2784 /* right is a IFX then just join */
2785 if (IS_IFX(tree->right))
2786 return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right));
2788 tree->right = createLabel(localLabel,tree->right);
2789 tree->right = newIfxNode(tree->right,trueLabel,falseLabel);
2791 return newNode(NULLOP,tree->left,tree->right);
2796 int wasnot = IS_NOT(tree->left);
2797 tree->left = backPatchLabels (tree->left,falseLabel,trueLabel);
2799 /* if the left is already a IFX */
2800 if ( ! IS_IFX(tree->left) )
2801 tree->left = newNode (IFX,tree->left,NULL);
2804 tree->left->trueLabel = trueLabel ;
2805 tree->left->falseLabel= falseLabel ;
2807 tree->left->trueLabel = falseLabel ;
2808 tree->left->falseLabel= trueLabel ;
2814 tree->trueLabel = trueLabel ;
2815 tree->falseLabel= falseLabel;
2822 /*-----------------------------------------------------------------*/
2823 /* createBlock - create expression tree for block */
2824 /*-----------------------------------------------------------------*/
2825 ast *createBlock ( symbol *decl, ast *body )
2829 /* if the block has nothing */
2833 ex = newNode(BLOCK,NULL,body);
2834 ex->values.sym = decl ;
2836 ex->right = ex->right ;
2842 /*-----------------------------------------------------------------*/
2843 /* createLabel - creates the expression tree for labels */
2844 /*-----------------------------------------------------------------*/
2845 ast *createLabel ( symbol *label, ast *stmnt )
2848 char name[SDCC_NAME_MAX+1];
2851 /* must create fresh symbol if the symbol name */
2852 /* exists in the symbol table, since there can */
2853 /* be a variable with the same name as the labl */
2854 if ((csym = findSym (SymbolTab,NULL,label->name)) &&
2855 (csym->level == label->level))
2856 label = newSymbol(label->name,label->level);
2858 /* change the name before putting it in add _*/
2859 sprintf (name,"%s",label->name);
2861 /* put the label in the LabelSymbol table */
2862 /* but first check if a label of the same */
2864 if ( (csym = findSym(LabelTab,NULL,name)))
2865 werror(E_DUPLICATE_LABEL,label->name);
2867 addSym (LabelTab, label, name,label->level,0);
2870 label->key = labelKey++ ;
2871 rValue = newNode (LABEL,newAst(EX_VALUE,symbolVal(label)),stmnt);
2877 /*-----------------------------------------------------------------*/
2878 /* createCase - generates the parsetree for a case statement */
2879 /*-----------------------------------------------------------------*/
2880 ast *createCase (ast *swStat, ast *caseVal, ast *stmnt )
2882 char caseLbl[SDCC_NAME_MAX+1];
2886 /* if the switch statement does not exist */
2887 /* then case is out of context */
2889 werror(E_CASE_CONTEXT);
2893 caseVal = decorateType(resolveSymbols(caseVal));
2894 /* if not a constant then error */
2895 if (!IS_LITERAL(caseVal->ftype)) {
2896 werror(E_CASE_CONSTANT);
2900 /* if not a integer than error */
2901 if (!IS_INTEGRAL(caseVal->ftype)) {
2902 werror(E_CASE_NON_INTEGER);
2906 /* find the end of the switch values chain */
2907 if (!(val = swStat->values.switchVals.swVals))
2908 swStat->values.switchVals.swVals = caseVal->opval.val ;
2910 /* also order the cases according to value */
2912 int cVal = (int) floatFromVal(caseVal->opval.val);
2913 while (val && (int) floatFromVal(val) < cVal) {
2918 /* if we reached the end then */
2920 pval->next = caseVal->opval.val;
2922 /* we found a value greater than */
2923 /* the current value we must add this */
2924 /* before the value */
2925 caseVal->opval.val->next = val;
2927 /* if this was the first in chain */
2928 if (swStat->values.switchVals.swVals == val)
2929 swStat->values.switchVals.swVals =
2932 pval->next = caseVal->opval.val;
2937 /* create the case label */
2938 sprintf(caseLbl,"_case_%d_%d",
2939 swStat->values.switchVals.swNum,
2940 (int) floatFromVal(caseVal->opval.val));
2942 rexpr = createLabel(newSymbol(caseLbl,0),stmnt);
2947 /*-----------------------------------------------------------------*/
2948 /* createDefault - creates the parse tree for the default statement*/
2949 /*-----------------------------------------------------------------*/
2950 ast *createDefault (ast *swStat, ast *stmnt)
2952 char defLbl[SDCC_NAME_MAX+1];
2954 /* if the switch statement does not exist */
2955 /* then case is out of context */
2957 werror(E_CASE_CONTEXT);
2961 /* turn on the default flag */
2962 swStat->values.switchVals.swDefault = 1 ;
2964 /* create the label */
2965 sprintf (defLbl,"_default_%d",swStat->values.switchVals.swNum);
2966 return createLabel(newSymbol(defLbl,0),stmnt);
2969 /*-----------------------------------------------------------------*/
2970 /* createIf - creates the parsetree for the if statement */
2971 /*-----------------------------------------------------------------*/
2972 ast *createIf ( ast *condAst, ast *ifBody, ast *elseBody )
2974 static int Lblnum = 0 ;
2976 symbol *ifTrue , *ifFalse, *ifEnd ;
2978 /* if neither exists */
2979 if (! elseBody && !ifBody)
2982 /* create the labels */
2983 sprintf (buffer,"_iffalse_%d",Lblnum);
2984 ifFalse = newSymbol (buffer,NestLevel);
2985 /* if no else body then end == false */
2989 sprintf (buffer,"_ifend_%d",Lblnum);
2990 ifEnd = newSymbol (buffer,NestLevel);
2993 sprintf (buffer,"_iftrue_%d",Lblnum);
2994 ifTrue = newSymbol (buffer,NestLevel);
2998 /* attach the ifTrue label to the top of it body */
2999 ifBody = createLabel(ifTrue,ifBody);
3000 /* attach a goto end to the ifBody if else is present */
3002 ifBody = newNode(NULLOP,ifBody,
3004 newAst(EX_VALUE,symbolVal(ifEnd)),
3006 /* put the elseLabel on the else body */
3007 elseBody = createLabel (ifFalse,elseBody);
3008 /* out the end at the end of the body */
3009 elseBody = newNode(NULLOP,
3011 createLabel(ifEnd,NULL));
3014 ifBody = newNode(NULLOP,ifBody,
3015 createLabel(ifFalse,NULL));
3017 condAst = backPatchLabels (condAst,ifTrue,ifFalse);
3018 if (IS_IFX(condAst))
3021 ifTree = newIfxNode(condAst,ifTrue,ifFalse);
3023 return newNode(NULLOP,ifTree,
3024 newNode(NULLOP,ifBody,elseBody));
3028 /*-----------------------------------------------------------------*/
3029 /* createDo - creates parse tree for do */
3032 /* _docontinue_n: */
3033 /* condition_expression +-> trueLabel -> _dobody_n */
3035 /* +-> falseLabel-> _dobreak_n */
3037 /*-----------------------------------------------------------------*/
3038 ast *createDo ( symbol *trueLabel, symbol *continueLabel,
3039 symbol *falseLabel, ast *condAst, ast *doBody )
3044 /* if the body does not exist then it is simple */
3046 condAst = backPatchLabels(condAst,continueLabel,NULL);
3047 doTree = (IS_IFX(condAst) ? createLabel(continueLabel,condAst)
3048 : newNode(IFX,createLabel(continueLabel,condAst),NULL));
3049 doTree->trueLabel = continueLabel ;
3050 doTree->falseLabel= NULL ;
3054 /* otherwise we have a body */
3055 condAst = backPatchLabels(condAst,trueLabel,falseLabel);
3057 /* attach the body label to the top */
3058 doBody = createLabel(trueLabel,doBody);
3059 /* attach the continue label to end of body */
3060 doBody = newNode(NULLOP, doBody,
3061 createLabel(continueLabel,NULL));
3063 /* now put the break label at the end */
3064 if (IS_IFX(condAst))
3067 doTree = newIfxNode(condAst,trueLabel,falseLabel);
3069 doTree = newNode(NULLOP,doTree,createLabel(falseLabel,NULL));
3071 /* putting it together */
3072 return newNode(NULLOP,doBody,doTree);
3075 /*-----------------------------------------------------------------*/
3076 /* createFor - creates parse tree for 'for' statement */
3079 /* condExpr +-> trueLabel -> _forbody_n */
3081 /* +-> falseLabel-> _forbreak_n */
3084 /* _forcontinue_n: */
3086 /* goto _forcond_n ; */
3088 /*-----------------------------------------------------------------*/
3089 ast *createFor ( symbol *trueLabel, symbol *continueLabel ,
3090 symbol *falseLabel,symbol *condLabel ,
3091 ast *initExpr, ast *condExpr, ast *loopExpr,
3096 /* if loopexpression not present then we can generate it */
3097 /* the same way as a while */
3099 return newNode(NULLOP,initExpr,
3100 createWhile (trueLabel, continueLabel,
3101 falseLabel,condExpr, forBody ));
3102 /* vanilla for statement */
3103 condExpr = backPatchLabels(condExpr,trueLabel,falseLabel);
3105 if (condExpr && !IS_IFX(condExpr))
3106 condExpr = newIfxNode(condExpr,trueLabel,falseLabel);
3109 /* attach condition label to condition */
3110 condExpr = createLabel(condLabel,condExpr);
3112 /* attach body label to body */
3113 forBody = createLabel(trueLabel,forBody);
3115 /* attach continue to forLoop expression & attach */
3116 /* goto the forcond @ and of loopExpression */
3117 loopExpr = createLabel(continueLabel,
3121 newAst(EX_VALUE,symbolVal(condLabel)),
3123 /* now start putting them together */
3124 forTree = newNode(NULLOP,initExpr,condExpr);
3125 forTree = newNode(NULLOP,forTree,forBody);
3126 forTree = newNode(NULLOP,forTree,loopExpr);
3127 /* finally add the break label */
3128 forTree = newNode(NULLOP,forTree,
3129 createLabel(falseLabel,NULL));
3133 /*-----------------------------------------------------------------*/
3134 /* createWhile - creates parse tree for while statement */
3135 /* the while statement will be created as follows */
3137 /* _while_continue_n: */
3138 /* condition_expression +-> trueLabel -> _while_boby_n */
3140 /* +-> falseLabel -> _while_break_n*/
3141 /* _while_body_n: */
3143 /* goto _while_continue_n */
3144 /* _while_break_n: */
3145 /*-----------------------------------------------------------------*/
3146 ast *createWhile (symbol *trueLabel, symbol *continueLabel,
3147 symbol *falseLabel,ast *condExpr, ast *whileBody )
3151 /* put the continue label */
3152 condExpr = backPatchLabels (condExpr,trueLabel,falseLabel);
3153 condExpr = createLabel(continueLabel,condExpr);
3154 condExpr->lineno = 0;
3156 /* put the body label in front of the body */
3157 whileBody = createLabel(trueLabel,whileBody);
3158 whileBody->lineno = 0;
3159 /* put a jump to continue at the end of the body */
3160 /* and put break label at the end of the body */
3161 whileBody = newNode(NULLOP,
3165 symbolVal(continueLabel)),
3166 createLabel(falseLabel,NULL)));
3168 /* put it all together */
3169 if ( IS_IFX(condExpr) )
3170 whileTree = condExpr ;
3172 whileTree = newNode (IFX, condExpr,NULL );
3173 /* put the true & false labels in place */
3174 whileTree->trueLabel = trueLabel ;
3175 whileTree->falseLabel= falseLabel;
3178 return newNode(NULLOP,whileTree,whileBody );
3181 /*-----------------------------------------------------------------*/
3182 /* optimizeGetHbit - get highest order bit of the expression */
3183 /*-----------------------------------------------------------------*/
3184 ast *optimizeGetHbit (ast *tree)
3187 /* if this is not a bit and */
3188 if (!IS_BITAND(tree))
3191 /* will look for tree of the form
3192 ( expr >> ((sizeof expr) -1) ) & 1 */
3193 if (!IS_AST_LIT_VALUE(tree->right))
3196 if (AST_LIT_VALUE(tree->right) != 1)
3199 if (!IS_RIGHT_OP(tree->left))
3202 if (!IS_AST_LIT_VALUE(tree->left->right))
3205 if ((i = AST_LIT_VALUE(tree->left->right)) !=
3206 ( j = (getSize(TTYPE(tree->left->left))*8 - 1)))
3209 return decorateType(newNode(GETHBIT,tree->left->left,NULL));
3213 /*-----------------------------------------------------------------*/
3214 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3215 /*-----------------------------------------------------------------*/
3216 ast *optimizeRRCRLC ( ast *root )
3218 /* will look for trees of the form
3219 (?expr << 1) | (?expr >> 7) or
3220 (?expr >> 7) | (?expr << 1) will make that
3221 into a RLC : operation ..
3223 (?expr >> 1) | (?expr << 7) or
3224 (?expr << 7) | (?expr >> 1) will make that
3225 into a RRC operation
3226 note : by 7 I mean (number of bits required to hold the
3228 /* if the root operations is not a | operation the not */
3229 if (!IS_BITOR(root))
3232 /* I have to think of a better way to match patterns this sucks */
3233 /* that aside let start looking for the first case : I use a the
3234 negative check a lot to improve the efficiency */
3235 /* (?expr << 1) | (?expr >> 7) */
3236 if (IS_LEFT_OP(root->left) &&
3237 IS_RIGHT_OP(root->right) ) {
3239 if (!SPEC_USIGN(TETYPE(root->left->left)))
3242 if (!IS_AST_LIT_VALUE(root->left->right) ||
3243 !IS_AST_LIT_VALUE(root->right->right))
3246 /* make sure it is the same expression */
3247 if (!isAstEqual(root->left->left,
3251 if (AST_LIT_VALUE(root->left->right) != 1 )
3254 if (AST_LIT_VALUE(root->right->right) !=
3255 (getSize(TTYPE(root->left->left))*8 - 1))
3258 /* whew got the first case : create the AST */
3259 return newNode(RLC,root->left->left,NULL);
3263 /* check for second case */
3264 /* (?expr >> 7) | (?expr << 1) */
3265 if (IS_LEFT_OP(root->right) &&
3266 IS_RIGHT_OP(root->left) ) {
3268 if (!SPEC_USIGN(TETYPE(root->left->left)))
3271 if (!IS_AST_LIT_VALUE(root->left->right) ||
3272 !IS_AST_LIT_VALUE(root->right->right))
3275 /* make sure it is the same symbol */
3276 if (!isAstEqual(root->left->left,
3280 if (AST_LIT_VALUE(root->right->right) != 1 )
3283 if (AST_LIT_VALUE(root->left->right) !=
3284 (getSize(TTYPE(root->left->left))*8 - 1))
3287 /* whew got the first case : create the AST */
3288 return newNode(RLC,root->left->left,NULL);
3293 /* third case for RRC */
3294 /* (?symbol >> 1) | (?symbol << 7) */
3295 if (IS_LEFT_OP(root->right) &&
3296 IS_RIGHT_OP(root->left) ) {
3298 if (!SPEC_USIGN(TETYPE(root->left->left)))
3301 if (!IS_AST_LIT_VALUE(root->left->right) ||
3302 !IS_AST_LIT_VALUE(root->right->right))
3305 /* make sure it is the same symbol */
3306 if (!isAstEqual(root->left->left,
3310 if (AST_LIT_VALUE(root->left->right) != 1 )
3313 if (AST_LIT_VALUE(root->right->right) !=
3314 (getSize(TTYPE(root->left->left))*8 - 1))
3317 /* whew got the first case : create the AST */
3318 return newNode(RRC,root->left->left,NULL);
3322 /* fourth and last case for now */
3323 /* (?symbol << 7) | (?symbol >> 1) */
3324 if (IS_RIGHT_OP(root->right) &&
3325 IS_LEFT_OP(root->left) ) {
3327 if (!SPEC_USIGN(TETYPE(root->left->left)))
3330 if (!IS_AST_LIT_VALUE(root->left->right) ||
3331 !IS_AST_LIT_VALUE(root->right->right))
3334 /* make sure it is the same symbol */
3335 if (!isAstEqual(root->left->left,
3339 if (AST_LIT_VALUE(root->right->right) != 1 )
3342 if (AST_LIT_VALUE(root->left->right) !=
3343 (getSize(TTYPE(root->left->left))*8 - 1))
3346 /* whew got the first case : create the AST */
3347 return newNode(RRC,root->left->left,NULL);
3351 /* not found return root */
3355 /*-----------------------------------------------------------------*/
3356 /* optimizeCompare - otimizes compares for bit variables */
3357 /*-----------------------------------------------------------------*/
3358 ast *optimizeCompare ( ast *root )
3360 ast *optExpr = NULL;
3363 unsigned int litValue ;
3365 /* if nothing then return nothing */
3369 /* if not a compare op then do leaves */
3370 if (!IS_COMPARE_OP(root)) {
3371 root->left = optimizeCompare (root->left);
3372 root->right= optimizeCompare (root->right);
3376 /* if left & right are the same then depending
3377 of the operation do */
3378 if (isAstEqual(root->left,root->right)) {
3379 switch (root->opval.op) {
3383 optExpr = newAst(EX_VALUE,constVal("0"));
3388 optExpr = newAst(EX_VALUE,constVal("1"));
3392 return decorateType(optExpr);
3395 vleft = (root->left->type == EX_VALUE ?
3396 root->left->opval.val : NULL );
3398 vright = (root->right->type == EX_VALUE ?
3399 root->right->opval.val : NULL);
3401 /* if left is a BITVAR in BITSPACE */
3402 /* and right is a LITERAL then opt-*/
3403 /* imize else do nothing */
3404 if (vleft && vright &&
3405 IS_BITVAR(vleft->etype) &&
3406 IN_BITSPACE(SPEC_OCLS(vleft->etype)) &&
3407 IS_LITERAL(vright->etype)) {
3409 /* if right side > 1 then comparison may never succeed */
3410 if ( (litValue = (int) floatFromVal(vright)) > 1 ) {
3411 werror(W_BAD_COMPARE);
3416 switch (root->opval.op) {
3417 case '>' : /* bit value greater than 1 cannot be */
3418 werror(W_BAD_COMPARE);
3422 case '<' : /* bit value < 1 means 0 */
3424 optExpr = newNode('!',newAst(EX_VALUE,vleft),NULL);
3427 case LE_OP : /* bit value <= 1 means no check */
3428 optExpr = newAst(EX_VALUE,vright);
3431 case GE_OP : /* bit value >= 1 means only check for = */
3433 optExpr = newAst(EX_VALUE,vleft);
3436 } else { /* literal is zero */
3437 switch (root->opval.op) {
3438 case '<' : /* bit value < 0 cannot be */
3439 werror(W_BAD_COMPARE);
3443 case '>' : /* bit value > 0 means 1 */
3445 optExpr = newAst(EX_VALUE,vleft);
3448 case LE_OP : /* bit value <= 0 means no check */
3449 case GE_OP : /* bit value >= 0 means no check */
3450 werror(W_BAD_COMPARE);
3454 case EQ_OP : /* bit == 0 means ! of bit */
3455 optExpr = newNode('!',newAst(EX_VALUE,vleft),NULL);
3459 return decorateType(resolveSymbols(optExpr));
3460 } /* end-of-if of BITVAR */
3465 /*-----------------------------------------------------------------*/
3466 /* addSymToBlock : adds the symbol to the first block we find */
3467 /*-----------------------------------------------------------------*/
3468 void addSymToBlock (symbol *sym, ast *tree)
3470 /* reached end of tree or a leaf */
3471 if (!tree || IS_AST_LINK(tree) || IS_AST_VALUE(tree))
3475 if (IS_AST_OP(tree) &&
3476 tree->opval.op == BLOCK ) {
3478 symbol *lsym = copySymbol(sym);
3480 lsym->next = AST_VALUES(tree,sym);
3481 AST_VALUES(tree,sym) = lsym ;
3485 addSymToBlock(sym,tree->left);
3486 addSymToBlock(sym,tree->right);
3489 /*-----------------------------------------------------------------*/
3490 /* processRegParms - do processing for register parameters */
3491 /*-----------------------------------------------------------------*/
3492 static void processRegParms (value *args, ast *body)
3495 if (IS_REGPARM(args->etype))
3496 addSymToBlock(args->sym,body);
3501 /*-----------------------------------------------------------------*/
3502 /* resetParmKey - resets the operandkeys for the symbols */
3503 /*-----------------------------------------------------------------*/
3504 DEFSETFUNC(resetParmKey)
3515 /*-----------------------------------------------------------------*/
3516 /* createFunction - This is the key node that calls the iCode for */
3517 /* generating the code for a function. Note code */
3518 /* is generated function by function, later when */
3519 /* add inter-procedural analysis this will change */
3520 /*-----------------------------------------------------------------*/
3521 ast *createFunction (symbol *name, ast *body )
3527 iCode *piCode = NULL;
3529 /* if check function return 0 then some problem */
3530 if (checkFunction (name) == 0)
3533 /* create a dummy block if none exists */
3535 body = newNode(BLOCK,NULL,NULL);
3539 /* check if the function name already in the symbol table */
3540 if ((csym = findSym (SymbolTab,NULL,name->name))) {
3542 /* special case for compiler defined functions
3543 we need to add the name to the publics list : this
3544 actually means we are now compiling the compiler
3547 addSet(&publics,name);
3551 allocVariables(name);
3553 name->lastLine = yylineno;
3555 processFuncArgs(currFunc,0);
3557 /* set the stack pointer */
3558 /* PENDING: check this for the mcs51 */
3559 stackPtr = -port->stack.direction * port->stack.call_overhead;
3560 if (IS_ISR(name->etype))
3561 stackPtr -= port->stack.direction * port->stack.isr_overhead;
3562 if (IS_RENT(name->etype) || options.stackAuto)
3563 stackPtr -= port->stack.direction * port->stack.reent_overhead;
3565 xstackPtr = -port->stack.direction * port->stack.call_overhead;
3567 fetype = getSpec(name->type); /* get the specifier for the function */
3568 /* if this is a reentrant function then */
3569 if (IS_RENT(fetype))
3572 allocParms (name->args); /* allocate the parameters */
3574 /* do processing for parameters that are passed in registers */
3575 processRegParms (name->args,body);
3577 /* set the stack pointer */
3581 /* allocate & autoinit the block variables */
3582 processBlockVars (body, &stack,ALLOCATE);
3584 /* save the stack information */
3585 if (options.useXstack)
3586 name->xstack = SPEC_STAK(fetype) = stack;
3588 name->stack = SPEC_STAK(fetype) = stack;
3590 /* name needs to be mangled */
3591 sprintf (name->rname,"%s%s", port->fun_prefix, name->name);
3593 body = resolveSymbols(body); /* resolve the symbols */
3594 body = decorateType (body); /* propagateType & do semantic checks */
3596 ex = newAst (EX_VALUE, symbolVal(name)); /* create name */
3597 ex = newNode (FUNCTION,ex,body);
3598 ex->values.args = name->args ;
3601 werror(E_FUNC_NO_CODE,name->name);
3605 /* create the node & generate intermediate code */
3606 codeOutFile = code->oFile;
3607 piCode = iCodeFromAst(ex);
3610 werror(E_FUNC_NO_CODE,name->name);
3614 eBBlockFromiCode(piCode);
3616 /* if there are any statics then do them */
3618 codeOutFile = statsg->oFile;
3619 eBBlockFromiCode (iCodeFromAst (decorateType(resolveSymbols(staticAutos))));
3625 /* dealloc the block variables */
3626 processBlockVars(body, &stack,DEALLOCATE);
3627 /* deallocate paramaters */
3628 deallocParms(name->args);
3630 if (IS_RENT(fetype))
3633 /* we are done freeup memory & cleanup */
3638 addSet(&operKeyReset,name);
3639 applyToSet(operKeyReset,resetParmKey);
3642 cdbStructBlock(1,cdbFile);
3644 cleanUpLevel(LabelTab,0);
3645 cleanUpBlock(StructTab,1);
3646 cleanUpBlock(TypedefTab,1);
3648 xstack->syms = NULL;
3649 istack->syms = NULL;