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);
417 /*-----------------------------------------------------------------*/
418 /* resolveFromTable - will return the symbal table value */
419 /*-----------------------------------------------------------------*/
420 value *resolveFromTable (value *val)
427 csym = findSymWithLevel (SymbolTab,val->sym);
429 /* if found in the symbol table & they r not the same */
430 if (csym && val->sym != csym &&
431 csym->level == val->sym->level &&
436 val->type = csym->type;
437 val->etype = csym->etype;
443 /*-----------------------------------------------------------------*/
444 /* funcOfType :- function of type with name */
445 /*-----------------------------------------------------------------*/
446 symbol *funcOfType (char *name, link *type, link *argType,
447 int nArgs , int rent)
451 /* create the symbol */
452 sym = newSymbol (name,0);
454 /* if arguments required */
458 args = sym->args = newValue();
461 argStack += getSize(type);
462 args->type = copyLinkChain(argType);
463 args->etype = getSpec(args->type);
466 args = args->next = newValue();
470 /* setup return value */
471 sym->type = newLink();
472 DCL_TYPE(sym->type) = FUNCTION;
473 sym->type->next = copyLinkChain(type);
474 sym->etype = getSpec(sym->type);
475 SPEC_RENT(sym->etype) = rent;
480 sym->argStack = (rent ? argStack : 0);
481 allocVariables (sym);
486 /*-----------------------------------------------------------------*/
487 /* reverseParms - will reverse a parameter tree */
488 /*-----------------------------------------------------------------*/
489 void reverseParms (ast *ptree)
495 /* top down if we find a nonParm tree then quit */
496 if (ptree->type == EX_OP && ptree->opval.op == PARAM ) {
498 ptree->left = ptree->right;
499 ptree->right = ttree;
500 reverseParms(ptree->left);
501 reverseParms(ptree->right);
507 /*-----------------------------------------------------------------*/
508 /* processParms - makes sure the parameters are okay and do some */
509 /* processing with them */
510 /*-----------------------------------------------------------------*/
511 int processParms (ast *func, value *defParm,
515 link *fetype = func->etype;
517 /* if none of them exist */
518 if ( !defParm && !actParm)
521 /* if the function is being called via a pointer & */
522 /* it has not been defined a reentrant then we cannot*/
523 /* have parameters */
524 if (func->type != EX_VALUE && !IS_RENT(fetype) && !options.stackAuto) {
525 werror (E_NONRENT_ARGS);
529 /* if defined parameters ended but actual parameters */
530 /* exist and this is not defined as a variable arg */
531 /* also check if statckAuto option is specified */
532 if ((! defParm) && actParm && (!func->hasVargs ) &&
533 !options.stackAuto && !IS_RENT(fetype)) {
534 werror(E_TOO_MANY_PARMS);
538 /* if defined parameters present and actual paramters ended */
539 if ( defParm && ! actParm) {
540 werror(E_TO_FEW_PARMS);
544 /* if defined parameters ended but actual has not & */
545 /* has a variable argument list or statckAuto */
546 if (! defParm && actParm &&
547 (func->hasVargs || options.stackAuto || IS_RENT(fetype)))
550 resolveSymbols(actParm);
551 /* if this is a PARAM node then match left & right */
552 if ( actParm->type == EX_OP && actParm->opval.op == PARAM) {
554 return (processParms (func,defParm,actParm->left,parmNumber) ||
555 processParms (func,defParm->next, actParm->right,parmNumber) );
558 /* the parameter type must be atleast castable */
559 if (checkType(defParm->type,actParm->ftype) == 0) {
560 werror(E_TYPE_MISMATCH_PARM,*parmNumber);
561 werror(E_CONTINUE,"defined type ");
562 printTypeChain(defParm->type,stderr);fprintf(stderr,"\n");
563 werror(E_CONTINUE,"actual type ");
564 printTypeChain(actParm->ftype,stderr);fprintf(stderr,"\n");
567 /* if the parameter is castable then add the cast */
568 if ( checkType (defParm->type,actParm->ftype) < 0) {
569 ast *pTree = resolveSymbols(copyAst(actParm));
571 /* now change the current one to a cast */
572 actParm->type = EX_OP ;
573 actParm->opval.op = CAST ;
574 actParm->left = newAst(EX_LINK,defParm->type);
575 actParm->right= pTree ;
576 actParm->etype= defParm->etype;
577 actParm->ftype= defParm->type;
580 actParm->argSym = resolveFromTable(defParm)->sym ;
581 /* make a copy and change the regparm type to the defined parm */
582 actParm->etype = getSpec(actParm->ftype = copyLinkChain(actParm->ftype));
583 SPEC_REGPARM(actParm->etype) = SPEC_REGPARM(defParm->etype);
586 /*-----------------------------------------------------------------*/
587 /* createIvalType - generates ival for basic types */
588 /*-----------------------------------------------------------------*/
589 ast *createIvalType ( ast *sym,link *type, initList *ilist)
593 /* if initList is deep */
594 if ( ilist->type == INIT_DEEP )
595 ilist = ilist->init.deep ;
597 iExpr = decorateType(resolveSymbols(list2expr(ilist)));
598 return newNode('=',sym,iExpr);
601 /*-----------------------------------------------------------------*/
602 /* createIvalStruct - generates initial value for structures */
603 /*-----------------------------------------------------------------*/
604 ast *createIvalStruct (ast *sym,link *type,initList *ilist)
610 sflds = SPEC_STRUCT(type)->fields ;
611 if (ilist->type != INIT_DEEP) {
612 werror(E_INIT_STRUCT,"");
616 iloop = ilist->init.deep;
618 for ( ; sflds ; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL )) {
621 /* if we have come to end */
625 lAst = decorateType(resolveSymbols(newNode('.',sym,
626 newAst(EX_VALUE,symbolVal(sflds)))));
627 rast = createIval (lAst, sflds->type, iloop,rast);
633 /*-----------------------------------------------------------------*/
634 /* createIvalArray - generates code for array initialization */
635 /*-----------------------------------------------------------------*/
636 ast *createIvalArray (ast *sym, link *type, initList *ilist)
640 int lcnt = 0, size =0 ;
642 /* take care of the special case */
643 /* array of characters can be init */
645 if ( IS_CHAR(type->next) )
646 if ( (rast = createIvalCharPtr(sym,
648 decorateType(resolveSymbols(list2expr(ilist))))))
652 /* not the special case */
653 if (ilist->type != INIT_DEEP) {
654 werror(E_INIT_STRUCT,"");
658 iloop = ilist->init.deep ;
659 lcnt = DCL_ELEM(type);
665 aSym = newNode('[',sym,newAst(EX_VALUE,valueFromLit(size-1)));
666 aSym = decorateType(resolveSymbols(aSym));
667 rast = createIval (aSym,type->next,iloop,rast) ;
668 iloop = (iloop ? iloop->next : NULL) ;
671 /* if not array limits given & we */
672 /* are out of initialisers then */
673 if (!DCL_ELEM(type) && !iloop)
676 /* no of elements given and we */
677 /* have generated for all of them */
682 /* if we have not been given a size */
684 DCL_ELEM(type) = size;
690 /*-----------------------------------------------------------------*/
691 /* createIvalCharPtr - generates initial values for char pointers */
692 /*-----------------------------------------------------------------*/
693 ast *createIvalCharPtr (ast *sym, link *type, ast *iexpr)
697 /* if this is a pointer & right is a literal array then */
698 /* just assignment will do */
699 if ( IS_PTR(type) && (( IS_LITERAL(iexpr->etype) ||
700 SPEC_SCLS(iexpr->etype) == S_CODE )
701 && IS_ARRAY(iexpr->ftype)))
702 return newNode('=',sym,iexpr);
704 /* left side is an array so we have to assign each */
706 if (( IS_LITERAL(iexpr->etype) ||
707 SPEC_SCLS(iexpr->etype) == S_CODE )
708 && IS_ARRAY(iexpr->ftype)) {
710 /* for each character generate an assignment */
711 /* to the array element */
712 char *s = SPEC_CVAL(iexpr->etype).v_char ;
716 rast = newNode(NULLOP,
720 newAst(EX_VALUE,valueFromLit(i))),
721 newAst(EX_VALUE,valueFromLit(*s))));
725 rast = newNode(NULLOP,
729 newAst(EX_VALUE,valueFromLit(i))),
730 newAst(EX_VALUE,valueFromLit(*s))));
737 /*-----------------------------------------------------------------*/
738 /* createIvalPtr - generates initial value for pointers */
739 /*-----------------------------------------------------------------*/
740 ast *createIvalPtr (ast *sym,link *type,initList *ilist)
746 if ( ilist->type == INIT_DEEP )
747 ilist = ilist->init.deep ;
749 iexpr = decorateType(resolveSymbols(list2expr(ilist)));
751 /* if character pointer */
752 if (IS_CHAR(type->next))
753 if ((rast = createIvalCharPtr (sym,type,iexpr)))
756 return newNode('=',sym,iexpr);
759 /*-----------------------------------------------------------------*/
760 /* createIval - generates code for initial value */
761 /*-----------------------------------------------------------------*/
762 ast *createIval (ast *sym, link *type, initList *ilist, ast *wid)
769 /* if structure then */
771 rast = createIvalStruct(sym, type,ilist);
773 /* if this is a pointer */
775 rast = createIvalPtr(sym, type,ilist);
777 /* if this is an array */
779 rast = createIvalArray(sym, type,ilist);
781 /* if type is SPECIFIER */
783 rast = createIvalType (sym,type,ilist);
785 return newNode(NULLOP,wid,rast);
790 /*-----------------------------------------------------------------*/
791 /* initAggregates - initialises aggregate variables with initv */
792 /*-----------------------------------------------------------------*/
793 ast *initAggregates ( symbol *sym, initList *ival, ast *wid)
795 return createIval (newAst(EX_VALUE,symbolVal(sym)),sym->type,ival,wid);
798 /*-----------------------------------------------------------------*/
799 /* gatherAutoInit - creates assignment expressions for initial */
801 /*-----------------------------------------------------------------*/
802 ast *gatherAutoInit ( symbol *autoChain )
809 for ( sym = autoChain ; sym ; sym = sym->next ) {
811 /* resolve the symbols in the ival */
813 resolveIvalSym(sym->ival);
815 /* if this is a static variable & has an */
816 /* initial value the code needs to be lifted */
817 /* here to the main portion since they can be */
818 /* initialised only once at the start */
819 if ( IS_STATIC(sym->etype) && sym->ival &&
820 SPEC_SCLS(sym->etype) != S_CODE) {
823 /* insert the symbol into the symbol table */
824 /* with level = 0 & name = rname */
825 newSym = copySymbol (sym);
826 addSym (SymbolTab,newSym,newSym->name,0,0);
828 /* now lift the code to main */
829 if (IS_AGGREGATE(sym->type))
830 work = initAggregates (sym, sym->ival,NULL);
832 work = newNode('=' ,newAst(EX_VALUE,symbolVal(newSym)),
833 list2expr(sym->ival));
835 setAstLineno(work,sym->lineDef);
839 staticAutos = newNode(NULLOP,staticAutos,work);
846 /* if there is an initial value */
847 if ( sym->ival && SPEC_SCLS(sym->etype)!=S_CODE) {
848 if (IS_AGGREGATE(sym->type))
849 work = initAggregates (sym,sym->ival,NULL);
851 work = newNode('=' ,newAst(EX_VALUE,symbolVal(sym)),
852 list2expr(sym->ival));
854 setAstLineno (work,sym->lineDef);
857 init = newNode(NULLOP,init,work);
866 /*-----------------------------------------------------------------*/
867 /* stringToSymbol - creates a symbol from a literal string */
868 /*-----------------------------------------------------------------*/
869 static value *stringToSymbol (value *val)
871 char name[SDCC_NAME_MAX+1];
872 static int charLbl = 0;
875 sprintf(name,"_str_%d",charLbl++);
876 sym = newSymbol(name,0); /* make it @ level 0 */
877 strcpy(sym->rname,name);
879 /* copy the type from the value passed */
880 sym->type = copyLinkChain(val->type);
881 sym->etype = getSpec(sym->type);
882 /* change to storage class & output class */
883 SPEC_SCLS(sym->etype) = S_CODE ;
884 SPEC_CVAL(sym->etype).v_char = SPEC_CVAL(val->etype).v_char ;
885 SPEC_STAT(sym->etype) = 1;
886 /* make the level & block = 0 */
887 sym->block = sym->level = 0;
890 sym->ival = newiList(INIT_NODE,newAst(EX_VALUE,val));
897 return symbolVal(sym);
901 /*-----------------------------------------------------------------*/
902 /* processBlockVars - will go thru the ast looking for block if */
903 /* a block is found then will allocate the syms */
904 /* will also gather the auto inits present */
905 /*-----------------------------------------------------------------*/
906 ast *processBlockVars ( ast *tree , int *stack, int action)
911 /* if this is a block */
912 if (tree->type == EX_OP && tree->opval.op == BLOCK ) {
915 if (action == ALLOCATE) {
916 autoInit = gatherAutoInit (tree->values.sym);
917 *stack += allocVariables (tree->values.sym);
919 /* if there are auto inits then do them */
921 tree->left = newNode(NULLOP,autoInit,tree->left);
922 } else /* action is deallocate */
923 deallocLocal (tree->values.sym) ;
926 processBlockVars (tree->left, stack, action);
927 processBlockVars (tree->right, stack, action);
931 /*-----------------------------------------------------------------*/
932 /* constExprValue - returns the value of a constant expression */
933 /*-----------------------------------------------------------------*/
934 value *constExprValue (ast *cexpr, int check)
936 cexpr = decorateType(resolveSymbols(cexpr));
938 /* if this is not a constant then */
939 if (!IS_LITERAL(cexpr->ftype)) {
940 /* then check if this is a literal array
942 if (SPEC_SCLS(cexpr->etype) == S_CODE &&
943 SPEC_CVAL(cexpr->etype).v_char &&
944 IS_ARRAY(cexpr->ftype)) {
945 value *val = valFromType(cexpr->ftype);
946 SPEC_SCLS(val->etype) = S_LITERAL;
947 val->sym =cexpr->opval.val->sym ;
948 val->sym->type = copyLinkChain(cexpr->ftype);
949 val->sym->etype = getSpec(val->sym->type);
950 strcpy(val->name,cexpr->opval.val->sym->rname);
954 /* if we are casting a literal value then */
955 if (IS_AST_OP(cexpr) &&
956 cexpr->opval.op == CAST &&
957 IS_LITERAL(cexpr->left->ftype))
958 return valCastLiteral(cexpr->ftype,
959 floatFromVal(cexpr->left->opval.val));
961 if (IS_AST_VALUE(cexpr))
962 return cexpr->opval.val;
965 werror(E_CONST_EXPECTED,"found expression");
970 /* return the value */
971 return cexpr->opval.val ;
975 /*-----------------------------------------------------------------*/
976 /* isLabelInAst - will return true if a given label is found */
977 /*-----------------------------------------------------------------*/
978 bool isLabelInAst (symbol *label, ast *tree)
980 if (!tree || IS_AST_VALUE(tree) || IS_AST_LINK(tree))
983 if (IS_AST_OP(tree) &&
984 tree->opval.op == LABEL &&
985 isSymbolEqual(AST_SYMBOL(tree->left),label))
988 return isLabelInAst(label,tree->right) &&
989 isLabelInAst(label,tree->left);
993 /*-----------------------------------------------------------------*/
994 /* isLoopCountable - return true if the loop count can be determi- */
995 /* -ned at compile time . */
996 /*-----------------------------------------------------------------*/
997 bool isLoopCountable (ast *initExpr, ast *condExpr, ast *loopExpr,
998 symbol **sym,ast **init, ast **end)
1001 /* the loop is considered countable if the following
1002 conditions are true :-
1004 a) initExpr :- <sym> = <const>
1005 b) condExpr :- <sym> < <const1>
1006 c) loopExpr :- <sym> ++
1009 /* first check the initExpr */
1010 if ( IS_AST_OP(initExpr) &&
1011 initExpr->opval.op == '=' && /* is assignment */
1012 IS_AST_SYM_VALUE(initExpr->left)) { /* left is a symbol */
1014 *sym = AST_SYMBOL(initExpr->left);
1015 *init= initExpr->right;
1020 /* for now the symbol has to be of
1022 if (!IS_INTEGRAL((*sym)->type))
1025 /* now check condExpr */
1026 if (IS_AST_OP(condExpr)) {
1028 switch (condExpr->opval.op) {
1030 if (IS_AST_SYM_VALUE(condExpr->left) &&
1031 isSymbolEqual (*sym,AST_SYMBOL(condExpr->left)) &&
1032 IS_AST_LIT_VALUE(condExpr->right)) {
1033 *end = condExpr->right;
1039 if (IS_AST_OP(condExpr->left) &&
1040 condExpr->left->opval.op == '>' &&
1041 IS_AST_LIT_VALUE(condExpr->left->right) &&
1042 IS_AST_SYM_VALUE(condExpr->left->left)&&
1043 isSymbolEqual (*sym,AST_SYMBOL(condExpr->left->left))) {
1045 *end = newNode('+', condExpr->left->right,
1046 newAst(EX_VALUE,constVal("1")));
1057 /* check loop expression is of the form <sym>++ */
1058 if (!IS_AST_OP(loopExpr))
1061 /* check if <sym> ++ */
1062 if (loopExpr->opval.op == INC_OP) {
1064 if (loopExpr->left) {
1066 if (IS_AST_SYM_VALUE(loopExpr->left) &&
1067 isSymbolEqual(*sym,AST_SYMBOL(loopExpr->left)))
1072 if (IS_AST_SYM_VALUE(loopExpr->right) &&
1073 isSymbolEqual(*sym,AST_SYMBOL(loopExpr->right)))
1080 if ( loopExpr->opval.op == ADD_ASSIGN ) {
1082 if (IS_AST_SYM_VALUE(loopExpr->left) &&
1083 isSymbolEqual(*sym,AST_SYMBOL(loopExpr->left)) &&
1084 IS_AST_LIT_VALUE(loopExpr->right) &&
1085 (int)AST_LIT_VALUE(loopExpr->right) != 1)
1093 /*-----------------------------------------------------------------*/
1094 /* astHasVolatile - returns true if ast contains any volatile */
1095 /*-----------------------------------------------------------------*/
1096 bool astHasVolatile (ast *tree)
1101 if (TETYPE(tree) && IS_VOLATILE(TETYPE(tree)))
1104 if (IS_AST_OP(tree))
1105 return astHasVolatile(tree->left) ||
1106 astHasVolatile(tree->right);
1111 /*-----------------------------------------------------------------*/
1112 /* astHasPointer - return true if the ast contains any ptr variable*/
1113 /*-----------------------------------------------------------------*/
1114 bool astHasPointer (ast *tree)
1119 if (IS_AST_LINK(tree))
1122 /* if we hit an array expression then check
1123 only the left side */
1124 if (IS_AST_OP(tree) && tree->opval.op == '[')
1125 return astHasPointer(tree->left);
1127 if (IS_AST_VALUE(tree))
1128 return IS_PTR(tree->ftype) || IS_ARRAY(tree->ftype);
1130 return astHasPointer(tree->left) ||
1131 astHasPointer(tree->right);
1135 /*-----------------------------------------------------------------*/
1136 /* astHasSymbol - return true if the ast has the given symbol */
1137 /*-----------------------------------------------------------------*/
1138 bool astHasSymbol (ast *tree, symbol *sym)
1140 if (!tree || IS_AST_LINK(tree))
1143 if (IS_AST_VALUE(tree)) {
1144 if (IS_AST_SYM_VALUE(tree))
1145 return isSymbolEqual(AST_SYMBOL(tree),sym);
1150 return astHasSymbol(tree->left,sym) ||
1151 astHasSymbol(tree->right,sym);
1154 /*-----------------------------------------------------------------*/
1155 /* isConformingBody - the loop body has to conform to a set of rules */
1156 /* for the loop to be considered reversible read on for rules */
1157 /*-----------------------------------------------------------------*/
1158 bool isConformingBody (ast *pbody, symbol *sym, ast *body)
1161 /* we are going to do a pre-order traversal of the
1162 tree && check for the following conditions. (essentially
1163 a set of very shallow tests )
1164 a) the sym passed does not participate in
1165 any arithmetic operation
1166 b) There are no function calls
1167 c) all jumps are within the body
1168 d) address of loop control variable not taken
1169 e) if an assignment has a pointer on the
1170 left hand side make sure right does not have
1171 loop control variable */
1173 /* if we reach the end or a leaf then true */
1174 if (!pbody || IS_AST_LINK(pbody) || IS_AST_VALUE(pbody))
1178 /* if anything else is "volatile" */
1179 if (IS_VOLATILE(TETYPE(pbody)))
1182 /* we will walk the body in a pre-order traversal for
1184 switch (pbody->opval.op) {
1185 /*------------------------------------------------------------------*/
1187 return isConformingBody (pbody->right,sym,body);
1189 /*------------------------------------------------------------------*/
1194 /*------------------------------------------------------------------*/
1195 case INC_OP: /* incerement operator unary so left only */
1198 /* sure we are not sym is not modified */
1200 IS_AST_SYM_VALUE(pbody->left) &&
1201 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1205 IS_AST_SYM_VALUE(pbody->right) &&
1206 isSymbolEqual(AST_SYMBOL(pbody->right),sym))
1211 /*------------------------------------------------------------------*/
1213 case '*' : /* can be unary : if right is null then unary operation */
1218 /* if right is NULL then unary operation */
1219 /*------------------------------------------------------------------*/
1220 /*----------------------------*/
1222 /*----------------------------*/
1223 if ( ! pbody->right ) {
1224 if (IS_AST_SYM_VALUE(pbody->left) &&
1225 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1228 return isConformingBody(pbody->left,sym,body) ;
1231 /*------------------------------------------------------------------*/
1239 if (IS_AST_SYM_VALUE(pbody->left) &&
1240 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1243 if (IS_AST_SYM_VALUE(pbody->right) &&
1244 isSymbolEqual(AST_SYMBOL(pbody->right),sym))
1247 return isConformingBody(pbody->left,sym,body) &&
1248 isConformingBody(pbody->right,sym,body);
1255 if (IS_AST_SYM_VALUE(pbody->left) &&
1256 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1258 return isConformingBody (pbody->left,sym,body);
1260 /*------------------------------------------------------------------*/
1272 case SIZEOF: /* evaluate wihout code generation */
1274 return isConformingBody(pbody->left,sym,body) &&
1275 isConformingBody(pbody->right,sym,body);
1277 /*------------------------------------------------------------------*/
1280 /* if left has a pointer & right has loop
1281 control variable then we cannot */
1282 if (astHasPointer(pbody->left) &&
1283 astHasSymbol (pbody->right,sym))
1285 if (astHasVolatile(pbody->left))
1288 if (IS_AST_SYM_VALUE(pbody->left) &&
1289 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1292 if (astHasVolatile(pbody->left))
1295 return isConformingBody(pbody->left,sym,body) &&
1296 isConformingBody(pbody->right,sym,body);
1307 assert("Parser should not have generated this\n");
1309 /*------------------------------------------------------------------*/
1310 /*----------------------------*/
1311 /* comma operator */
1312 /*----------------------------*/
1314 return isConformingBody(pbody->left,sym,body) &&
1315 isConformingBody(pbody->right,sym,body);
1317 /*------------------------------------------------------------------*/
1318 /*----------------------------*/
1320 /*----------------------------*/
1324 /*------------------------------------------------------------------*/
1325 /*----------------------------*/
1326 /* return statement */
1327 /*----------------------------*/
1332 if (isLabelInAst (AST_SYMBOL(pbody->left),body))
1337 if (astHasSymbol(pbody->left,sym))
1344 return isConformingBody(pbody->left,sym,body) &&
1345 isConformingBody(pbody->right,sym,body);
1351 /*-----------------------------------------------------------------*/
1352 /* isLoopReversible - takes a for loop as input && returns true */
1353 /* if the for loop is reversible. If yes will set the value of */
1354 /* the loop control var & init value & termination value */
1355 /*-----------------------------------------------------------------*/
1356 bool isLoopReversible (ast *loop, symbol **loopCntrl,
1357 ast **init, ast **end )
1359 /* if option says don't do it then don't */
1360 if (optimize.noLoopReverse)
1362 /* there are several tests to determine this */
1364 /* for loop has to be of the form
1365 for ( <sym> = <const1> ;
1366 [<sym> < <const2>] ;
1367 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1369 if (! isLoopCountable (AST_FOR(loop,initExpr),
1370 AST_FOR(loop,condExpr),
1371 AST_FOR(loop,loopExpr),
1372 loopCntrl,init,end))
1375 /* now do some serious checking on the body of the loop
1378 return isConformingBody(loop->left,*loopCntrl,loop->left);
1382 /*-----------------------------------------------------------------*/
1383 /* replLoopSym - replace the loop sym by loop sym -1 */
1384 /*-----------------------------------------------------------------*/
1385 static void replLoopSym ( ast *body, symbol *sym)
1388 if (!body || IS_AST_LINK(body))
1391 if (IS_AST_SYM_VALUE(body)) {
1393 if (isSymbolEqual(AST_SYMBOL(body),sym)) {
1396 body->opval.op = '-';
1397 body->left = newAst(EX_VALUE,symbolVal(sym));
1398 body->right= newAst(EX_VALUE,constVal("1"));
1406 replLoopSym(body->left,sym);
1407 replLoopSym(body->right,sym);
1411 /*-----------------------------------------------------------------*/
1412 /* reverseLoop - do the actual loop reversal */
1413 /*-----------------------------------------------------------------*/
1414 ast *reverseLoop (ast *loop, symbol *sym, ast *init, ast *end)
1418 /* create the following tree
1423 if (sym) goto for_continue ;
1426 /* put it together piece by piece */
1427 rloop = newNode (NULLOP,
1428 createIf(newAst(EX_VALUE,symbolVal(sym)),
1431 symbolVal(AST_FOR(loop,continueLabel))),
1434 newAst(EX_VALUE,symbolVal(sym)),
1439 replLoopSym(loop->left, sym);
1441 rloop = newNode(NULLOP,
1443 newAst(EX_VALUE,symbolVal(sym)),
1444 newNode('-',end,init)),
1445 createLabel(AST_FOR(loop,continueLabel),
1450 newAst(EX_VALUE,symbolVal(sym)),
1451 newAst(EX_VALUE,constVal("1"))),
1454 return decorateType(rloop);
1458 /*-----------------------------------------------------------------*/
1459 /* decorateType - compute type for this tree also does type cheking*/
1460 /* this is done bottom up, since type have to flow upwards*/
1461 /* it also does constant folding, and paramater checking */
1462 /*-----------------------------------------------------------------*/
1463 ast *decorateType (ast *tree)
1471 /* if already has type then do nothing */
1472 if ( tree->decorated )
1475 tree->decorated = 1;
1477 /* print the line */
1478 /* if not block & function */
1479 if ( tree->type == EX_OP &&
1480 ( tree->opval.op != FUNCTION &&
1481 tree->opval.op != BLOCK &&
1482 tree->opval.op != NULLOP )) {
1483 filename = tree->filename ;
1484 lineno = tree->lineno ;
1487 /* if any child is an error | this one is an error do nothing */
1488 if ( tree->isError ||
1489 ( tree->left && tree->left->isError) ||
1490 ( tree->right && tree->right->isError ))
1493 /*------------------------------------------------------------------*/
1494 /*----------------------------*/
1495 /* leaf has been reached */
1496 /*----------------------------*/
1497 /* if this is of type value */
1498 /* just get the type */
1499 if ( tree->type == EX_VALUE ) {
1501 if ( IS_LITERAL(tree->opval.val->etype) ) {
1503 /* if this is a character array then declare it */
1504 if (IS_ARRAY(tree->opval.val->type))
1505 tree->opval.val = stringToSymbol(tree->opval.val);
1507 /* otherwise just copy the type information */
1508 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.val->type);
1512 if ( tree->opval.val->sym ) {
1513 /* if the undefined flag is set then give error message */
1514 if (tree->opval.val->sym->undefined ) {
1515 werror(E_ID_UNDEF,tree->opval.val->sym->name) ;
1517 TTYPE(tree) = TETYPE(tree) =
1518 tree->opval.val->type = tree->opval.val->sym->type =
1519 tree->opval.val->etype = tree->opval.val->sym->etype =
1520 copyLinkChain(intType);
1524 /* if impilicit i.e. struct/union member then no type */
1525 if (tree->opval.val->sym->implicit )
1526 TTYPE(tree) = TETYPE(tree) = NULL ;
1530 /* else copy the type */
1531 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.val->type);
1533 /* and mark it as referenced */
1534 tree->opval.val->sym->isref = 1;
1535 /* if this is of type function or function pointer */
1536 if (funcInChain(tree->opval.val->type)) {
1537 tree->hasVargs = tree->opval.val->sym->hasVargs;
1538 tree->args = copyValueChain(tree->opval.val->sym->args) ;
1548 /* if type link for the case of cast */
1549 if ( tree->type == EX_LINK ) {
1550 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.lnk);
1557 dtl = decorateType (tree->left);
1558 dtr = decorateType (tree->right);
1560 /* this is to take care of situations
1561 when the tree gets rewritten */
1562 if (dtl != tree->left)
1564 if (dtr != tree->right)
1568 /* depending on type of operator do */
1570 switch (tree->opval.op) {
1571 /*------------------------------------------------------------------*/
1572 /*----------------------------*/
1574 /*----------------------------*/
1577 /* determine which is the array & which the index */
1578 if ((IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree))) && IS_INTEGRAL(LTYPE(tree))) {
1580 ast *tempTree = tree->left ;
1581 tree->left = tree->right ;
1582 tree->right= tempTree ;
1585 /* first check if this is a array or a pointer */
1586 if ( (!IS_ARRAY(LTYPE(tree))) && (!IS_PTR(LTYPE(tree)))) {
1587 werror(E_NEED_ARRAY_PTR,"[]");
1588 goto errorTreeReturn ;
1591 /* check if the type of the idx */
1592 if (!IS_INTEGRAL(RTYPE(tree))) {
1593 werror(E_IDX_NOT_INT);
1594 goto errorTreeReturn ;
1597 /* if the left is an rvalue then error */
1599 werror(E_LVALUE_REQUIRED,"array access");
1600 goto errorTreeReturn ;
1603 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree)->next);
1606 /*------------------------------------------------------------------*/
1607 /*----------------------------*/
1609 /*----------------------------*/
1611 /* if this is not a structure */
1612 if (!IS_STRUCT(LTYPE(tree))) {
1613 werror(E_STRUCT_UNION,".");
1614 goto errorTreeReturn ;
1616 TTYPE(tree) = structElemType (LTYPE(tree),
1617 (tree->right->type == EX_VALUE ?
1618 tree->right->opval.val : NULL ),&tree->args);
1619 TETYPE(tree) = getSpec(TTYPE(tree));
1622 /*------------------------------------------------------------------*/
1623 /*----------------------------*/
1624 /* struct/union pointer */
1625 /*----------------------------*/
1627 /* if not pointer to a structure */
1628 if (!IS_PTR(LTYPE(tree))) {
1630 goto errorTreeReturn ;
1633 if (!IS_STRUCT(LTYPE(tree)->next)) {
1634 werror(E_STRUCT_UNION,"->");
1635 goto errorTreeReturn ;
1638 TTYPE(tree) = structElemType (LTYPE(tree)->next,
1639 (tree->right->type == EX_VALUE ?
1640 tree->right->opval.val : NULL ),&tree->args);
1641 TETYPE(tree) = getSpec(TTYPE(tree));
1644 /*------------------------------------------------------------------*/
1645 /*----------------------------*/
1646 /* ++/-- operation */
1647 /*----------------------------*/
1648 case INC_OP: /* incerement operator unary so left only */
1651 link *ltc = (tree->right ? RTYPE(tree) : LTYPE(tree) );
1652 COPYTYPE(TTYPE(tree),TETYPE(tree),ltc);
1653 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
1654 werror(E_CODE_WRITE,"++/--");
1663 /*------------------------------------------------------------------*/
1664 /*----------------------------*/
1666 /*----------------------------*/
1667 case '&': /* can be unary */
1668 /* if right is NULL then unary operation */
1669 if ( tree->right ) /* not an unary operation */ {
1671 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1672 werror(E_BITWISE_OP);
1673 werror(E_CONTINUE,"left & right types are ");
1674 printTypeChain(LTYPE(tree),stderr);
1675 fprintf(stderr,",");
1676 printTypeChain(RTYPE(tree),stderr);
1677 fprintf(stderr,"\n");
1678 goto errorTreeReturn ;
1681 /* if they are both literal */
1682 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1683 tree->type = EX_VALUE ;
1684 tree->opval.val = valBitwise (valFromType(LETYPE(tree)),
1685 valFromType(RETYPE(tree)),'&');
1687 tree->right = tree->left = NULL;
1688 TETYPE(tree) = tree->opval.val->etype ;
1689 TTYPE(tree) = tree->opval.val->type;
1693 /* see if this is a GETHBIT operation if yes
1696 ast *otree = optimizeGetHbit(tree);
1699 return decorateType(otree);
1702 /* if right or left is literal then result of that type*/
1703 if (IS_LITERAL(RTYPE(tree))) {
1705 TTYPE(tree) = copyLinkChain(RTYPE(tree));
1706 TETYPE(tree) = getSpec(TTYPE(tree));
1707 SPEC_SCLS(TETYPE(tree)) = S_AUTO;
1710 if (IS_LITERAL(LTYPE(tree))) {
1711 TTYPE(tree) = copyLinkChain(LTYPE(tree));
1712 TETYPE(tree) = getSpec(TTYPE(tree));
1713 SPEC_SCLS(TETYPE(tree)) = S_AUTO;
1718 computeType (LTYPE(tree), RTYPE(tree));
1719 TETYPE(tree) = getSpec(TTYPE(tree));
1722 LRVAL(tree) = RRVAL(tree) = 1;
1726 /*------------------------------------------------------------------*/
1727 /*----------------------------*/
1729 /*----------------------------*/
1731 p->class = DECLARATOR;
1732 /* if bit field then error */
1733 if (IS_BITVAR(tree->left->etype)) {
1734 werror (E_ILLEGAL_ADDR,"addrress of bit variable");
1735 goto errorTreeReturn ;
1738 if (SPEC_SCLS(tree->left->etype)== S_REGISTER ) {
1739 werror (E_ILLEGAL_ADDR,"address of register variable");
1740 goto errorTreeReturn;
1743 if (IS_FUNC(LTYPE(tree))) {
1744 werror(E_ILLEGAL_ADDR,"address of function");
1745 goto errorTreeReturn ;
1749 werror(E_LVALUE_REQUIRED,"address of");
1750 goto errorTreeReturn ;
1752 if (SPEC_SCLS(tree->left->etype) == S_CODE) {
1753 DCL_TYPE(p) = CPOINTER ;
1754 DCL_PTR_CONST(p) = 1;
1757 if (SPEC_SCLS(tree->left->etype) == S_XDATA)
1758 DCL_TYPE(p) = FPOINTER;
1760 if (SPEC_SCLS(tree->left->etype) == S_XSTACK )
1761 DCL_TYPE(p) = PPOINTER ;
1763 if (SPEC_SCLS(tree->left->etype) == S_IDATA)
1764 DCL_TYPE(p) = IPOINTER ;
1766 if (SPEC_SCLS(tree->left->etype) == S_FLASH)
1767 DCL_TYPE(p) = FLPOINTER ;
1769 DCL_TYPE(p) = POINTER ;
1771 if (IS_AST_SYM_VALUE(tree->left)) {
1772 AST_SYMBOL(tree->left)->addrtaken = 1;
1773 AST_SYMBOL(tree->left)->allocreq = 1;
1776 p->next = LTYPE(tree);
1778 TETYPE(tree) = getSpec(TTYPE(tree));
1779 DCL_PTR_CONST(p) = SPEC_CONST(TETYPE(tree));
1780 DCL_PTR_VOLATILE(p) = SPEC_VOLATILE(TETYPE(tree));
1785 /*------------------------------------------------------------------*/
1786 /*----------------------------*/
1788 /*----------------------------*/
1790 /* if the rewrite succeeds then don't go any furthur */
1792 ast *wtree = optimizeRRCRLC ( tree );
1794 return decorateType(wtree) ;
1796 /*------------------------------------------------------------------*/
1797 /*----------------------------*/
1799 /*----------------------------*/
1801 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1802 werror(E_BITWISE_OP);
1803 werror(E_CONTINUE,"left & right types are ");
1804 printTypeChain(LTYPE(tree),stderr);
1805 fprintf(stderr,",");
1806 printTypeChain(RTYPE(tree),stderr);
1807 fprintf(stderr,"\n");
1808 goto errorTreeReturn ;
1811 /* if they are both literal then */
1812 /* rewrite the tree */
1813 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1814 tree->type = EX_VALUE ;
1815 tree->opval.val = valBitwise (valFromType(LETYPE(tree)),
1816 valFromType(RETYPE(tree)),
1818 tree->right = tree->left = NULL;
1819 TETYPE(tree) = tree->opval.val->etype;
1820 TTYPE(tree) = tree->opval.val->type;
1823 LRVAL(tree) = RRVAL(tree) = 1;
1824 TETYPE(tree) = getSpec (TTYPE(tree) =
1825 computeType(LTYPE(tree),
1828 /*------------------------------------------------------------------*/
1829 /*----------------------------*/
1831 /*----------------------------*/
1833 if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) {
1834 werror(E_INVALID_OP,"divide");
1835 goto errorTreeReturn ;
1837 /* if they are both literal then */
1838 /* rewrite the tree */
1839 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1840 tree->type = EX_VALUE ;
1841 tree->opval.val = valDiv (valFromType(LETYPE(tree)),
1842 valFromType(RETYPE(tree)));
1843 tree->right = tree->left = NULL;
1844 TETYPE(tree) = getSpec(TTYPE(tree) =
1845 tree->opval.val->type);
1848 LRVAL(tree) = RRVAL(tree) = 1;
1849 TETYPE(tree) = getSpec (TTYPE(tree) =
1850 computeType(LTYPE(tree),
1854 /*------------------------------------------------------------------*/
1855 /*----------------------------*/
1857 /*----------------------------*/
1859 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1860 werror(E_BITWISE_OP);
1861 werror(E_CONTINUE,"left & right types are ");
1862 printTypeChain(LTYPE(tree),stderr);
1863 fprintf(stderr,",");
1864 printTypeChain(RTYPE(tree),stderr);
1865 fprintf(stderr,"\n");
1866 goto errorTreeReturn ;
1868 /* if they are both literal then */
1869 /* rewrite the tree */
1870 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1871 tree->type = EX_VALUE ;
1872 tree->opval.val = valMod (valFromType(LETYPE(tree)),
1873 valFromType(RETYPE(tree)));
1874 tree->right = tree->left = NULL;
1875 TETYPE(tree) = getSpec(TTYPE(tree) =
1876 tree->opval.val->type);
1879 LRVAL(tree) = RRVAL(tree) = 1;
1880 TETYPE(tree) = getSpec (TTYPE(tree) =
1881 computeType(LTYPE(tree),
1885 /*------------------------------------------------------------------*/
1886 /*----------------------------*/
1887 /* address dereference */
1888 /*----------------------------*/
1889 case '*': /* can be unary : if right is null then unary operation */
1890 if ( ! tree->right ) {
1891 if (!IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) {
1893 goto errorTreeReturn ;
1897 werror(E_LVALUE_REQUIRED,"pointer deref");
1898 goto errorTreeReturn ;
1900 TTYPE(tree) = copyLinkChain ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) ?
1901 LTYPE(tree)->next : NULL );
1902 TETYPE(tree) = getSpec(TTYPE(tree));
1903 tree->args = tree->left->args ;
1904 tree->hasVargs = tree->left->hasVargs ;
1905 SPEC_CONST(TETYPE(tree)) = DCL_PTR_CONST(LTYPE(tree));
1909 /*------------------------------------------------------------------*/
1910 /*----------------------------*/
1911 /* multiplication */
1912 /*----------------------------*/
1913 if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) {
1914 werror(E_INVALID_OP,"multiplication");
1915 goto errorTreeReturn ;
1918 /* if they are both literal then */
1919 /* rewrite the tree */
1920 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1921 tree->type = EX_VALUE ;
1922 tree->opval.val = valMult (valFromType(LETYPE(tree)),
1923 valFromType(RETYPE(tree)));
1924 tree->right = tree->left = NULL;
1925 TETYPE(tree) = getSpec(TTYPE(tree) =
1926 tree->opval.val->type);
1930 /* if left is a literal exchange left & right */
1931 if (IS_LITERAL(LTYPE(tree))) {
1932 ast *tTree = tree->left ;
1933 tree->left = tree->right ;
1934 tree->right= tTree ;
1937 LRVAL(tree) = RRVAL(tree) = 1;
1938 TETYPE(tree) = getSpec (TTYPE(tree) =
1939 computeType(LTYPE(tree),
1943 /*------------------------------------------------------------------*/
1944 /*----------------------------*/
1945 /* unary '+' operator */
1946 /*----------------------------*/
1949 if ( ! tree->right ) {
1950 if (!IS_INTEGRAL(LTYPE(tree))) {
1951 werror(E_UNARY_OP,'+');
1952 goto errorTreeReturn ;
1955 /* if left is a literal then do it */
1956 if (IS_LITERAL(LTYPE(tree))) {
1957 tree->type = EX_VALUE ;
1958 tree->opval.val = valFromType(LETYPE(tree));
1960 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
1964 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
1968 /*------------------------------------------------------------------*/
1969 /*----------------------------*/
1971 /*----------------------------*/
1973 /* this is not a unary operation */
1974 /* if both pointers then problem */
1975 if ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) &&
1976 (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)))) {
1977 werror(E_PTR_PLUS_PTR);
1978 goto errorTreeReturn ;
1981 if (!IS_ARITHMETIC(LTYPE(tree)) &&
1982 !IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) {
1983 werror(E_PLUS_INVALID,"+");
1984 goto errorTreeReturn ;
1987 if (!IS_ARITHMETIC(RTYPE(tree)) &&
1988 !IS_PTR(RTYPE(tree)) && !IS_ARRAY(RTYPE(tree))) {
1989 werror(E_PLUS_INVALID,"+");
1990 goto errorTreeReturn;
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 = valPlus (valFromType(LETYPE(tree)),
1997 valFromType(RETYPE(tree)));
1998 tree->right = tree->left = NULL;
1999 TETYPE(tree) = getSpec(TTYPE(tree) =
2000 tree->opval.val->type);
2004 /* if the right is a pointer or left is a literal
2005 xchange left & right */
2006 if (IS_ARRAY(RTYPE(tree)) ||
2007 IS_PTR(RTYPE(tree)) ||
2008 IS_LITERAL(LTYPE(tree))) {
2009 ast *tTree = tree->left ;
2010 tree->left = tree->right ;
2011 tree->right= tTree ;
2014 LRVAL(tree) = RRVAL(tree) = 1;
2015 /* if the left is a pointer */
2016 if (IS_PTR(LTYPE(tree)))
2017 TETYPE(tree) = getSpec(TTYPE(tree) =
2020 TETYPE(tree) = getSpec(TTYPE(tree) =
2021 computeType(LTYPE(tree),
2025 /*------------------------------------------------------------------*/
2026 /*----------------------------*/
2028 /*----------------------------*/
2029 case '-' : /* can be unary */
2030 /* if right is null then unary */
2031 if ( ! tree->right ) {
2033 if (!IS_ARITHMETIC(LTYPE(tree))) {
2034 werror(E_UNARY_OP,tree->opval.op);
2035 goto errorTreeReturn ;
2038 /* if left is a literal then do it */
2039 if (IS_LITERAL(LTYPE(tree))) {
2040 tree->type = EX_VALUE ;
2041 tree->opval.val = valUnaryPM(valFromType(LETYPE(tree)));
2043 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2047 TTYPE(tree) = LTYPE(tree);
2051 /*------------------------------------------------------------------*/
2052 /*----------------------------*/
2054 /*----------------------------*/
2056 if (!(IS_PTR(LTYPE(tree)) ||
2057 IS_ARRAY(LTYPE(tree)) ||
2058 IS_ARITHMETIC(LTYPE(tree)))) {
2059 werror(E_PLUS_INVALID,"-");
2060 goto errorTreeReturn ;
2063 if (!(IS_PTR(RTYPE(tree)) ||
2064 IS_ARRAY(RTYPE(tree)) ||
2065 IS_ARITHMETIC(RTYPE(tree)))) {
2066 werror(E_PLUS_INVALID,"-");
2067 goto errorTreeReturn ;
2070 if ( (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) &&
2071 ! (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)) ||
2072 IS_INTEGRAL(RTYPE(tree))) ) {
2073 werror(E_PLUS_INVALID,"-");
2074 goto errorTreeReturn ;
2077 /* if they are both literal then */
2078 /* rewrite the tree */
2079 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2080 tree->type = EX_VALUE ;
2081 tree->opval.val = valMinus (valFromType(LETYPE(tree)),
2082 valFromType(RETYPE(tree)));
2083 tree->right = tree->left = NULL;
2084 TETYPE(tree) = getSpec(TTYPE(tree) =
2085 tree->opval.val->type);
2089 /* if the left & right are equal then zero */
2090 if (isAstEqual(tree->left,tree->right)) {
2091 tree->type = EX_VALUE;
2092 tree->left = tree->right = NULL;
2093 tree->opval.val = constVal("0");
2094 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2098 /* if both of them are pointers or arrays then */
2099 /* the result is going to be an integer */
2100 if (( IS_ARRAY(LTYPE(tree)) || IS_PTR(LTYPE(tree))) &&
2101 ( IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree))))
2102 TETYPE(tree) = TTYPE(tree) = newIntLink();
2104 /* if only the left is a pointer */
2105 /* then result is a pointer */
2106 if (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree)))
2107 TETYPE(tree) = getSpec(TTYPE(tree) =
2110 TETYPE(tree) = getSpec (TTYPE(tree) =
2111 computeType(LTYPE(tree),
2113 LRVAL(tree) = RRVAL(tree) = 1;
2116 /*------------------------------------------------------------------*/
2117 /*----------------------------*/
2119 /*----------------------------*/
2121 /* can be only integral type */
2122 if (!IS_INTEGRAL(LTYPE(tree))) {
2123 werror(E_UNARY_OP,tree->opval.op);
2124 goto errorTreeReturn ;
2127 /* if left is a literal then do it */
2128 if (IS_LITERAL(LTYPE(tree))) {
2129 tree->type = EX_VALUE ;
2130 tree->opval.val = valComplement(valFromType(LETYPE(tree)));
2132 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2136 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2139 /*------------------------------------------------------------------*/
2140 /*----------------------------*/
2142 /*----------------------------*/
2144 /* can be pointer */
2145 if (!IS_ARITHMETIC(LTYPE(tree)) &&
2146 !IS_PTR(LTYPE(tree)) &&
2147 !IS_ARRAY(LTYPE(tree))) {
2148 werror(E_UNARY_OP,tree->opval.op);
2149 goto errorTreeReturn ;
2152 /* if left is a literal then do it */
2153 if (IS_LITERAL(LTYPE(tree))) {
2154 tree->type = EX_VALUE ;
2155 tree->opval.val = valNot(valFromType(LETYPE(tree)));
2157 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2161 TTYPE(tree) = TETYPE(tree) = newCharLink();
2164 /*------------------------------------------------------------------*/
2165 /*----------------------------*/
2167 /*----------------------------*/
2170 TTYPE(tree) = LTYPE(tree);
2171 TETYPE(tree) = LETYPE(tree);
2175 TTYPE(tree) = TETYPE(tree) = newCharLink();
2180 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(tree->left->etype)) {
2181 werror(E_SHIFT_OP_INVALID);
2182 werror(E_CONTINUE,"left & right types are ");
2183 printTypeChain(LTYPE(tree),stderr);
2184 fprintf(stderr,",");
2185 printTypeChain(RTYPE(tree),stderr);
2186 fprintf(stderr,"\n");
2187 goto errorTreeReturn ;
2190 /* if they are both literal then */
2191 /* rewrite the tree */
2192 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2193 tree->type = EX_VALUE ;
2194 tree->opval.val = valShift (valFromType(LETYPE(tree)),
2195 valFromType(RETYPE(tree)),
2196 (tree->opval.op == LEFT_OP ? 1 : 0));
2197 tree->right = tree->left = NULL;
2198 TETYPE(tree) = getSpec(TTYPE(tree) =
2199 tree->opval.val->type);
2202 /* if only the right side is a literal & we are
2203 shifting more than size of the left operand then zero */
2204 if (IS_LITERAL(RTYPE(tree)) &&
2205 ((int)floatFromVal( valFromType(RETYPE(tree)))) >=
2206 (getSize(LTYPE(tree))*8)) {
2207 werror(W_SHIFT_CHANGED,
2208 (tree->opval.op == LEFT_OP ? "left" : "right"));
2209 tree->type = EX_VALUE;
2210 tree->left = tree->right = NULL;
2211 tree->opval.val = constVal("0");
2212 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2215 LRVAL(tree) = RRVAL(tree) = 1;
2216 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2219 /*------------------------------------------------------------------*/
2220 /*----------------------------*/
2222 /*----------------------------*/
2223 case CAST : /* change the type */
2224 /* cannot cast to an aggregate type */
2225 if (IS_AGGREGATE(LTYPE(tree))) {
2226 werror(E_CAST_ILLEGAL);
2227 goto errorTreeReturn ;
2230 /* if the right is a literal replace the tree */
2231 if (IS_LITERAL(RETYPE(tree)) && !IS_PTR(LTYPE(tree))) {
2232 tree->type = EX_VALUE ;
2234 valCastLiteral(LTYPE(tree),
2235 floatFromVal(valFromType(RETYPE(tree))));
2238 TTYPE(tree) = tree->opval.val->type;
2241 TTYPE(tree) = LTYPE(tree);
2245 TETYPE(tree) = getSpec(TTYPE(tree));
2249 /*------------------------------------------------------------------*/
2250 /*----------------------------*/
2251 /* logical &&, || */
2252 /*----------------------------*/
2255 /* each must me arithmetic type or be a pointer */
2256 if (!IS_PTR(LTYPE(tree)) &&
2257 !IS_ARRAY(LTYPE(tree)) &&
2258 !IS_INTEGRAL(LTYPE(tree))) {
2259 werror(E_COMPARE_OP);
2260 goto errorTreeReturn ;
2263 if (!IS_PTR(RTYPE(tree)) &&
2264 !IS_ARRAY(RTYPE(tree)) &&
2265 !IS_INTEGRAL(RTYPE(tree))) {
2266 werror(E_COMPARE_OP);
2267 goto errorTreeReturn ;
2269 /* if they are both literal then */
2270 /* rewrite the tree */
2271 if (IS_LITERAL(RTYPE(tree)) &&
2272 IS_LITERAL(LTYPE(tree))) {
2273 tree->type = EX_VALUE ;
2274 tree->opval.val = valLogicAndOr (valFromType(LETYPE(tree)),
2275 valFromType(RETYPE(tree)),
2277 tree->right = tree->left = NULL;
2278 TETYPE(tree) = getSpec(TTYPE(tree) =
2279 tree->opval.val->type);
2282 LRVAL(tree) = RRVAL(tree) = 1;
2283 TTYPE(tree) = TETYPE(tree) = newCharLink();
2286 /*------------------------------------------------------------------*/
2287 /*----------------------------*/
2288 /* comparison operators */
2289 /*----------------------------*/
2297 ast *lt = optimizeCompare(tree);
2303 /* if they are pointers they must be castable */
2304 if ( IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree))) {
2305 if (checkType(LTYPE(tree),RTYPE(tree)) == 0) {
2306 werror(E_COMPARE_OP);
2307 fprintf(stderr,"comparing type ");
2308 printTypeChain(LTYPE(tree),stderr);
2309 fprintf(stderr,"to type ");
2310 printTypeChain(RTYPE(tree),stderr);
2311 fprintf(stderr,"\n");
2312 goto errorTreeReturn ;
2315 /* else they should be promotable to one another */
2317 if (!( ( IS_PTR(LTYPE(tree)) && IS_LITERAL(RTYPE(tree))) ||
2318 ( IS_PTR(RTYPE(tree)) && IS_LITERAL(LTYPE(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 ;
2331 /* if they are both literal then */
2332 /* rewrite the tree */
2333 if (IS_LITERAL(RTYPE(tree)) &&
2334 IS_LITERAL(LTYPE(tree))) {
2335 tree->type = EX_VALUE ;
2336 tree->opval.val = valCompare (valFromType(LETYPE(tree)),
2337 valFromType(RETYPE(tree)),
2339 tree->right = tree->left = NULL;
2340 TETYPE(tree) = getSpec(TTYPE(tree) =
2341 tree->opval.val->type);
2344 LRVAL(tree) = RRVAL(tree) = 1;
2345 TTYPE(tree) = TETYPE(tree) = newCharLink();
2348 /*------------------------------------------------------------------*/
2349 /*----------------------------*/
2351 /*----------------------------*/
2352 case SIZEOF : /* evaluate wihout code generation */
2353 /* change the type to a integer */
2354 tree->type = EX_VALUE;
2355 sprintf(buffer,"%d",(getSize(tree->right->ftype)));
2356 tree->opval.val = constVal(buffer);
2357 tree->right = tree->left = NULL;
2358 TETYPE(tree) = getSpec(TTYPE(tree) =
2359 tree->opval.val->type);
2362 /*------------------------------------------------------------------*/
2363 /*----------------------------*/
2364 /* conditional operator '?' */
2365 /*----------------------------*/
2367 /* the type is one on the left */
2368 TTYPE(tree) = LTYPE(tree);
2369 TETYPE(tree)= getSpec (TTYPE(tree));
2373 /* if they don't match we have a problem */
2374 if (checkType( LTYPE(tree), RTYPE(tree)) == 0) {
2375 werror(E_TYPE_MISMATCH,"conditional operator"," ");
2376 goto errorTreeReturn ;
2379 TTYPE(tree) = computeType(LTYPE(tree),RTYPE(tree));
2380 TETYPE(tree)= getSpec(TTYPE(tree));
2384 /*------------------------------------------------------------------*/
2385 /*----------------------------*/
2386 /* assignment operators */
2387 /*----------------------------*/
2390 /* for these it must be both must be integral */
2391 if (!IS_ARITHMETIC(LTYPE(tree)) ||
2392 !IS_ARITHMETIC(RTYPE(tree))) {
2393 werror (E_OPS_INTEGRAL);
2394 goto errorTreeReturn ;
2397 TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree));
2399 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2400 werror(E_CODE_WRITE," ");
2403 werror(E_LVALUE_REQUIRED,"*= or /=");
2404 goto errorTreeReturn ;
2414 /* for these it must be both must be integral */
2415 if (!IS_INTEGRAL(LTYPE(tree)) ||
2416 !IS_INTEGRAL(RTYPE(tree))) {
2417 werror (E_OPS_INTEGRAL);
2418 goto errorTreeReturn ;
2421 TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree));
2423 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2424 werror(E_CODE_WRITE," ");
2427 werror(E_LVALUE_REQUIRED,"&= or |= or ^= or >>= or <<=");
2428 goto errorTreeReturn ;
2433 /*------------------------------------------------------------------*/
2434 /*----------------------------*/
2436 /*----------------------------*/
2438 if (!(IS_PTR(LTYPE(tree)) ||
2439 IS_ARITHMETIC(LTYPE(tree)))) {
2440 werror(E_PLUS_INVALID,"-=");
2441 goto errorTreeReturn ;
2444 if (!(IS_PTR(RTYPE(tree)) ||
2445 IS_ARITHMETIC(RTYPE(tree)))) {
2446 werror(E_PLUS_INVALID,"-=");
2447 goto errorTreeReturn ;
2450 TETYPE(tree) = getSpec (TTYPE(tree) =
2451 computeType(LTYPE(tree),
2454 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2455 werror(E_CODE_WRITE," ");
2458 werror(E_LVALUE_REQUIRED,"-=");
2459 goto errorTreeReturn ;
2464 /*------------------------------------------------------------------*/
2465 /*----------------------------*/
2467 /*----------------------------*/
2469 /* this is not a unary operation */
2470 /* if both pointers then problem */
2471 if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) ) {
2472 werror(E_PTR_PLUS_PTR);
2473 goto errorTreeReturn ;
2476 if (!IS_ARITHMETIC(LTYPE(tree)) && !IS_PTR(LTYPE(tree))) {
2477 werror(E_PLUS_INVALID,"+=");
2478 goto errorTreeReturn ;
2481 if (!IS_ARITHMETIC(RTYPE(tree)) && !IS_PTR(RTYPE(tree))) {
2482 werror(E_PLUS_INVALID,"+=");
2483 goto errorTreeReturn;
2486 TETYPE(tree) = getSpec (TTYPE(tree) =
2487 computeType(LTYPE(tree),
2490 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2491 werror(E_CODE_WRITE," ");
2494 werror(E_LVALUE_REQUIRED,"+=");
2495 goto errorTreeReturn ;
2498 tree->right = decorateType(newNode('+',copyAst(tree->left),tree->right));
2499 tree->opval.op = '=';
2502 /*------------------------------------------------------------------*/
2503 /*----------------------------*/
2504 /* straight assignemnt */
2505 /*----------------------------*/
2507 /* cannot be an aggregate */
2508 if (IS_AGGREGATE(LTYPE(tree))) {
2509 werror(E_AGGR_ASSIGN);
2510 goto errorTreeReturn;
2513 /* they should either match or be castable */
2514 if (checkType (LTYPE(tree),RTYPE(tree)) == 0) {
2515 werror(E_TYPE_MISMATCH,"assignment"," ");
2516 fprintf(stderr,"type --> '");
2517 printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' ");
2518 fprintf(stderr,"assigned to type --> '");
2519 printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n");
2520 goto errorTreeReturn ;
2523 /* if the left side of the tree is of type void
2524 then report error */
2525 if (IS_VOID(LTYPE(tree))) {
2526 werror(E_CAST_ZERO);
2527 fprintf(stderr,"type --> '");
2528 printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' ");
2529 fprintf(stderr,"assigned to type --> '");
2530 printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n");
2533 /* extra checks for pointer types */
2534 if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) &&
2535 !IS_GENPTR(LTYPE(tree))) {
2536 if (DCL_TYPE(LTYPE(tree)) != DCL_TYPE(RTYPE(tree)))
2537 werror(W_PTR_ASSIGN);
2540 TETYPE(tree) = getSpec(TTYPE(tree) =
2544 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2545 werror(E_CODE_WRITE," ");
2548 werror(E_LVALUE_REQUIRED,"=");
2549 goto errorTreeReturn ;
2554 /*------------------------------------------------------------------*/
2555 /*----------------------------*/
2556 /* comma operator */
2557 /*----------------------------*/
2559 TETYPE(tree) = getSpec(TTYPE(tree) = RTYPE(tree));
2562 /*------------------------------------------------------------------*/
2563 /*----------------------------*/
2565 /*----------------------------*/
2570 if (processParms (tree->left,
2572 tree->right,&parmNumber))
2573 goto errorTreeReturn ;
2575 if (options.stackAuto || IS_RENT(LETYPE(tree))) {
2576 tree->left->args = reverseVal(tree->left->args);
2577 reverseParms(tree->right);
2580 tree->args = tree->left->args ;
2581 TETYPE(tree) = getSpec (TTYPE(tree) = LTYPE(tree)->next);
2584 /*------------------------------------------------------------------*/
2585 /*----------------------------*/
2586 /* return statement */
2587 /*----------------------------*/
2592 if (checkType(currFunc->type->next,RTYPE(tree)) == 0) {
2593 werror(E_RETURN_MISMATCH);
2594 goto errorTreeReturn ;
2597 if (IS_VOID(currFunc->type->next)
2599 !IS_VOID(RTYPE(tree))) {
2600 werror(E_FUNC_VOID);
2601 goto errorTreeReturn ;
2604 /* if there is going to be a casing required then add it */
2605 if (checkType(currFunc->type->next,RTYPE(tree)) < 0 ) {
2607 decorateType(newNode(CAST,
2609 copyLinkChain(currFunc->type->next)),
2618 if (!IS_VOID(currFunc->type->next) && tree->right == NULL ) {
2619 werror(E_VOID_FUNC,currFunc->name);
2620 goto errorTreeReturn ;
2623 TTYPE(tree) = TETYPE(tree) = NULL ;
2626 /*------------------------------------------------------------------*/
2627 /*----------------------------*/
2628 /* switch statement */
2629 /*----------------------------*/
2631 /* the switch value must be an integer */
2632 if (!IS_INTEGRAL(LTYPE(tree))) {
2633 werror (E_SWITCH_NON_INTEGER);
2634 goto errorTreeReturn ;
2637 TTYPE(tree) = TETYPE(tree) = NULL ;
2640 /*------------------------------------------------------------------*/
2641 /*----------------------------*/
2643 /*----------------------------*/
2645 tree->left = backPatchLabels(tree->left,
2648 TTYPE(tree) = TETYPE(tree) = NULL;
2651 /*------------------------------------------------------------------*/
2652 /*----------------------------*/
2654 /*----------------------------*/
2657 decorateType(resolveSymbols(AST_FOR(tree,initExpr)));
2658 decorateType(resolveSymbols(AST_FOR(tree,condExpr)));
2659 decorateType(resolveSymbols(AST_FOR(tree,loopExpr)));
2661 /* if the for loop is reversible then
2662 reverse it otherwise do what we normally
2668 if (isLoopReversible (tree,&sym,&init,&end))
2669 return reverseLoop (tree,sym,init,end);
2671 return decorateType(createFor ( AST_FOR(tree,trueLabel),
2672 AST_FOR(tree,continueLabel) ,
2673 AST_FOR(tree,falseLabel) ,
2674 AST_FOR(tree,condLabel) ,
2675 AST_FOR(tree,initExpr) ,
2676 AST_FOR(tree,condExpr) ,
2677 AST_FOR(tree,loopExpr),
2681 TTYPE(tree) = TETYPE(tree) = NULL ;
2685 /* some error found this tree will be killed */
2687 TTYPE(tree) = TETYPE(tree) = newCharLink();
2688 tree->opval.op = NULLOP ;
2694 /*-----------------------------------------------------------------*/
2695 /* sizeofOp - processes size of operation */
2696 /*-----------------------------------------------------------------*/
2697 value *sizeofOp( link *type)
2701 /* get the size and convert it to character */
2702 sprintf (buff,"%d", getSize(type));
2704 /* now convert into value */
2705 return constVal (buff);
2709 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
2710 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
2711 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
2712 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
2713 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
2714 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
2715 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
2717 /*-----------------------------------------------------------------*/
2718 /* backPatchLabels - change and or not operators to flow control */
2719 /*-----------------------------------------------------------------*/
2720 ast *backPatchLabels (ast *tree, symbol *trueLabel, symbol *falseLabel )
2726 if ( ! (IS_ANDORNOT(tree)))
2729 /* if this an and */
2731 static int localLbl = 0 ;
2732 symbol *localLabel ;
2734 sprintf (buffer,"_and_%d",localLbl++);
2735 localLabel = newSymbol(buffer,NestLevel);
2737 tree->left = backPatchLabels (tree->left, localLabel,falseLabel);
2739 /* if left is already a IFX then just change the if true label in that */
2740 if (!IS_IFX(tree->left))
2741 tree->left = newIfxNode(tree->left,localLabel,falseLabel);
2743 tree->right = backPatchLabels(tree->right,trueLabel,falseLabel);
2744 /* right is a IFX then just join */
2745 if (IS_IFX(tree->right))
2746 return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right));
2748 tree->right = createLabel(localLabel,tree->right);
2749 tree->right = newIfxNode(tree->right,trueLabel,falseLabel);
2751 return newNode(NULLOP,tree->left,tree->right);
2754 /* if this is an or operation */
2756 static int localLbl = 0 ;
2757 symbol *localLabel ;
2759 sprintf (buffer,"_or_%d",localLbl++);
2760 localLabel = newSymbol(buffer,NestLevel);
2762 tree->left = backPatchLabels (tree->left, trueLabel,localLabel);
2764 /* if left is already a IFX then just change the if true label in that */
2765 if (!IS_IFX(tree->left))
2766 tree->left = newIfxNode(tree->left,trueLabel,localLabel);
2768 tree->right = backPatchLabels(tree->right,trueLabel,falseLabel);
2769 /* right is a IFX then just join */
2770 if (IS_IFX(tree->right))
2771 return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right));
2773 tree->right = createLabel(localLabel,tree->right);
2774 tree->right = newIfxNode(tree->right,trueLabel,falseLabel);
2776 return newNode(NULLOP,tree->left,tree->right);
2781 tree->left = backPatchLabels (tree->left,falseLabel,trueLabel);
2783 /* if the left is already a IFX */
2784 if ( ! IS_IFX(tree->left) )
2785 tree->left = newNode (IFX,tree->left,NULL);
2787 tree->left->trueLabel = falseLabel ;
2788 tree->left->falseLabel= trueLabel ;
2793 tree->trueLabel = trueLabel ;
2794 tree->falseLabel= falseLabel;
2801 /*-----------------------------------------------------------------*/
2802 /* createBlock - create expression tree for block */
2803 /*-----------------------------------------------------------------*/
2804 ast *createBlock ( symbol *decl, ast *body )
2808 /* if the block has nothing */
2812 ex = newNode(BLOCK,NULL,body);
2813 ex->values.sym = decl ;
2815 ex->right = ex->right ;
2821 /*-----------------------------------------------------------------*/
2822 /* createLabel - creates the expression tree for labels */
2823 /*-----------------------------------------------------------------*/
2824 ast *createLabel ( symbol *label, ast *stmnt )
2827 char name[SDCC_NAME_MAX+1];
2830 /* must create fresh symbol if the symbol name */
2831 /* exists in the symbol table, since there can */
2832 /* be a variable with the same name as the labl */
2833 if ((csym = findSym (SymbolTab,NULL,label->name)) &&
2834 (csym->level == label->level))
2835 label = newSymbol(label->name,label->level);
2837 /* change the name before putting it in add _*/
2838 sprintf (name,"%s",label->name);
2840 /* put the label in the LabelSymbol table */
2841 /* but first check if a label of the same */
2843 if ( (csym = findSym(LabelTab,NULL,name)))
2844 werror(E_DUPLICATE_LABEL,label->name);
2846 addSym (LabelTab, label, name,label->level,0);
2849 label->key = labelKey++ ;
2850 rValue = newNode (LABEL,newAst(EX_VALUE,symbolVal(label)),stmnt);
2856 /*-----------------------------------------------------------------*/
2857 /* createCase - generates the parsetree for a case statement */
2858 /*-----------------------------------------------------------------*/
2859 ast *createCase (ast *swStat, ast *caseVal, ast *stmnt )
2861 char caseLbl[SDCC_NAME_MAX+1];
2865 /* if the switch statement does not exist */
2866 /* then case is out of context */
2868 werror(E_CASE_CONTEXT);
2872 caseVal = decorateType(resolveSymbols(caseVal));
2873 /* if not a constant then error */
2874 if (!IS_LITERAL(caseVal->ftype)) {
2875 werror(E_CASE_CONSTANT);
2879 /* if not a integer than error */
2880 if (!IS_INTEGRAL(caseVal->ftype)) {
2881 werror(E_CASE_NON_INTEGER);
2885 /* find the end of the switch values chain */
2886 if (!(val = swStat->values.switchVals.swVals))
2887 swStat->values.switchVals.swVals = caseVal->opval.val ;
2889 /* also order the cases according to value */
2891 int cVal = (int) floatFromVal(caseVal->opval.val);
2892 while (val && (int) floatFromVal(val) < cVal) {
2897 /* if we reached the end then */
2899 pval->next = caseVal->opval.val;
2901 /* we found a value greater than */
2902 /* the current value we must add this */
2903 /* before the value */
2904 caseVal->opval.val->next = val;
2906 /* if this was the first in chain */
2907 if (swStat->values.switchVals.swVals == val)
2908 swStat->values.switchVals.swVals =
2911 pval->next = caseVal->opval.val;
2916 /* create the case label */
2917 sprintf(caseLbl,"_case_%d_%d",
2918 swStat->values.switchVals.swNum,
2919 (int) floatFromVal(caseVal->opval.val));
2921 rexpr = createLabel(newSymbol(caseLbl,0),stmnt);
2926 /*-----------------------------------------------------------------*/
2927 /* createDefault - creates the parse tree for the default statement*/
2928 /*-----------------------------------------------------------------*/
2929 ast *createDefault (ast *swStat, ast *stmnt)
2931 char defLbl[SDCC_NAME_MAX+1];
2933 /* if the switch statement does not exist */
2934 /* then case is out of context */
2936 werror(E_CASE_CONTEXT);
2940 /* turn on the default flag */
2941 swStat->values.switchVals.swDefault = 1 ;
2943 /* create the label */
2944 sprintf (defLbl,"_default_%d",swStat->values.switchVals.swNum);
2945 return createLabel(newSymbol(defLbl,0),stmnt);
2948 /*-----------------------------------------------------------------*/
2949 /* createIf - creates the parsetree for the if statement */
2950 /*-----------------------------------------------------------------*/
2951 ast *createIf ( ast *condAst, ast *ifBody, ast *elseBody )
2953 static int Lblnum = 0 ;
2955 symbol *ifTrue , *ifFalse, *ifEnd ;
2957 /* if neither exists */
2958 if (! elseBody && !ifBody)
2961 /* create the labels */
2962 sprintf (buffer,"_iffalse_%d",Lblnum);
2963 ifFalse = newSymbol (buffer,NestLevel);
2964 /* if no else body then end == false */
2968 sprintf (buffer,"_ifend_%d",Lblnum);
2969 ifEnd = newSymbol (buffer,NestLevel);
2972 sprintf (buffer,"_iftrue_%d",Lblnum);
2973 ifTrue = newSymbol (buffer,NestLevel);
2977 /* attach the ifTrue label to the top of it body */
2978 ifBody = createLabel(ifTrue,ifBody);
2979 /* attach a goto end to the ifBody if else is present */
2981 ifBody = newNode(NULLOP,ifBody,
2983 newAst(EX_VALUE,symbolVal(ifEnd)),
2985 /* put the elseLabel on the else body */
2986 elseBody = createLabel (ifFalse,elseBody);
2987 /* out the end at the end of the body */
2988 elseBody = newNode(NULLOP,
2990 createLabel(ifEnd,NULL));
2993 ifBody = newNode(NULLOP,ifBody,
2994 createLabel(ifFalse,NULL));
2996 condAst = backPatchLabels (condAst,ifTrue,ifFalse);
2997 if (IS_IFX(condAst))
3000 ifTree = newIfxNode(condAst,ifTrue,ifFalse);
3002 return newNode(NULLOP,ifTree,
3003 newNode(NULLOP,ifBody,elseBody));
3007 /*-----------------------------------------------------------------*/
3008 /* createDo - creates parse tree for do */
3011 /* _docontinue_n: */
3012 /* condition_expression +-> trueLabel -> _dobody_n */
3014 /* +-> falseLabel-> _dobreak_n */
3016 /*-----------------------------------------------------------------*/
3017 ast *createDo ( symbol *trueLabel, symbol *continueLabel,
3018 symbol *falseLabel, ast *condAst, ast *doBody )
3023 /* if the body does not exist then it is simple */
3025 condAst = backPatchLabels(condAst,continueLabel,NULL);
3026 doTree = (IS_IFX(condAst) ? createLabel(continueLabel,condAst)
3027 : newNode(IFX,createLabel(continueLabel,condAst),NULL));
3028 doTree->trueLabel = continueLabel ;
3029 doTree->falseLabel= NULL ;
3033 /* otherwise we have a body */
3034 condAst = backPatchLabels(condAst,trueLabel,falseLabel);
3036 /* attach the body label to the top */
3037 doBody = createLabel(trueLabel,doBody);
3038 /* attach the continue label to end of body */
3039 doBody = newNode(NULLOP, doBody,
3040 createLabel(continueLabel,NULL));
3042 /* now put the break label at the end */
3043 if (IS_IFX(condAst))
3046 doTree = newIfxNode(condAst,trueLabel,falseLabel);
3048 doTree = newNode(NULLOP,doTree,createLabel(falseLabel,NULL));
3050 /* putting it together */
3051 return newNode(NULLOP,doBody,doTree);
3054 /*-----------------------------------------------------------------*/
3055 /* createFor - creates parse tree for 'for' statement */
3058 /* condExpr +-> trueLabel -> _forbody_n */
3060 /* +-> falseLabel-> _forbreak_n */
3063 /* _forcontinue_n: */
3065 /* goto _forcond_n ; */
3067 /*-----------------------------------------------------------------*/
3068 ast *createFor ( symbol *trueLabel, symbol *continueLabel ,
3069 symbol *falseLabel,symbol *condLabel ,
3070 ast *initExpr, ast *condExpr, ast *loopExpr,
3075 /* if loopexpression not present then we can generate it */
3076 /* the same way as a while */
3078 return newNode(NULLOP,initExpr,
3079 createWhile (trueLabel, continueLabel,
3080 falseLabel,condExpr, forBody ));
3081 /* vanilla for statement */
3082 condExpr = backPatchLabels(condExpr,trueLabel,falseLabel);
3084 if (condExpr && !IS_IFX(condExpr))
3085 condExpr = newIfxNode(condExpr,trueLabel,falseLabel);
3088 /* attach condition label to condition */
3089 condExpr = createLabel(condLabel,condExpr);
3091 /* attach body label to body */
3092 forBody = createLabel(trueLabel,forBody);
3094 /* attach continue to forLoop expression & attach */
3095 /* goto the forcond @ and of loopExpression */
3096 loopExpr = createLabel(continueLabel,
3100 newAst(EX_VALUE,symbolVal(condLabel)),
3102 /* now start putting them together */
3103 forTree = newNode(NULLOP,initExpr,condExpr);
3104 forTree = newNode(NULLOP,forTree,forBody);
3105 forTree = newNode(NULLOP,forTree,loopExpr);
3106 /* finally add the break label */
3107 forTree = newNode(NULLOP,forTree,
3108 createLabel(falseLabel,NULL));
3112 /*-----------------------------------------------------------------*/
3113 /* createWhile - creates parse tree for while statement */
3114 /* the while statement will be created as follows */
3116 /* _while_continue_n: */
3117 /* condition_expression +-> trueLabel -> _while_boby_n */
3119 /* +-> falseLabel -> _while_break_n*/
3120 /* _while_body_n: */
3122 /* goto _while_continue_n */
3123 /* _while_break_n: */
3124 /*-----------------------------------------------------------------*/
3125 ast *createWhile (symbol *trueLabel, symbol *continueLabel,
3126 symbol *falseLabel,ast *condExpr, ast *whileBody )
3130 /* put the continue label */
3131 condExpr = backPatchLabels (condExpr,trueLabel,falseLabel);
3132 condExpr = createLabel(continueLabel,condExpr);
3133 condExpr->lineno = 0;
3135 /* put the body label in front of the body */
3136 whileBody = createLabel(trueLabel,whileBody);
3137 whileBody->lineno = 0;
3138 /* put a jump to continue at the end of the body */
3139 /* and put break label at the end of the body */
3140 whileBody = newNode(NULLOP,
3144 symbolVal(continueLabel)),
3145 createLabel(falseLabel,NULL)));
3147 /* put it all together */
3148 if ( IS_IFX(condExpr) )
3149 whileTree = condExpr ;
3151 whileTree = newNode (IFX, condExpr,NULL );
3152 /* put the true & false labels in place */
3153 whileTree->trueLabel = trueLabel ;
3154 whileTree->falseLabel= falseLabel;
3157 return newNode(NULLOP,whileTree,whileBody );
3160 /*-----------------------------------------------------------------*/
3161 /* optimizeGetHbit - get highest order bit of the expression */
3162 /*-----------------------------------------------------------------*/
3163 ast *optimizeGetHbit (ast *tree)
3166 /* if this is not a bit and */
3167 if (!IS_BITAND(tree))
3170 /* will look for tree of the form
3171 ( expr >> ((sizeof expr) -1) ) & 1 */
3172 if (!IS_AST_LIT_VALUE(tree->right))
3175 if (AST_LIT_VALUE(tree->right) != 1)
3178 if (!IS_RIGHT_OP(tree->left))
3181 if (!IS_AST_LIT_VALUE(tree->left->right))
3184 if ((i = AST_LIT_VALUE(tree->left->right)) !=
3185 ( j = (getSize(TTYPE(tree->left->left))*8 - 1)))
3188 return decorateType(newNode(GETHBIT,tree->left->left,NULL));
3192 /*-----------------------------------------------------------------*/
3193 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3194 /*-----------------------------------------------------------------*/
3195 ast *optimizeRRCRLC ( ast *root )
3197 /* will look for trees of the form
3198 (?expr << 1) | (?expr >> 7) or
3199 (?expr >> 7) | (?expr << 1) will make that
3200 into a RLC : operation ..
3202 (?expr >> 1) | (?expr << 7) or
3203 (?expr << 7) | (?expr >> 1) will make that
3204 into a RRC operation
3205 note : by 7 I mean (number of bits required to hold the
3207 /* if the root operations is not a | operation the not */
3208 if (!IS_BITOR(root))
3211 /* I have to think of a better way to match patterns this sucks */
3212 /* that aside let start looking for the first case : I use a the
3213 negative check a lot to improve the efficiency */
3214 /* (?expr << 1) | (?expr >> 7) */
3215 if (IS_LEFT_OP(root->left) &&
3216 IS_RIGHT_OP(root->right) ) {
3218 if (!SPEC_USIGN(TETYPE(root->left->left)))
3221 if (!IS_AST_LIT_VALUE(root->left->right) ||
3222 !IS_AST_LIT_VALUE(root->right->right))
3225 /* make sure it is the same expression */
3226 if (!isAstEqual(root->left->left,
3230 if (AST_LIT_VALUE(root->left->right) != 1 )
3233 if (AST_LIT_VALUE(root->right->right) !=
3234 (getSize(TTYPE(root->left->left))*8 - 1))
3237 /* whew got the first case : create the AST */
3238 return newNode(RLC,root->left->left,NULL);
3242 /* check for second case */
3243 /* (?expr >> 7) | (?expr << 1) */
3244 if (IS_LEFT_OP(root->right) &&
3245 IS_RIGHT_OP(root->left) ) {
3247 if (!SPEC_USIGN(TETYPE(root->left->left)))
3250 if (!IS_AST_LIT_VALUE(root->left->right) ||
3251 !IS_AST_LIT_VALUE(root->right->right))
3254 /* make sure it is the same symbol */
3255 if (!isAstEqual(root->left->left,
3259 if (AST_LIT_VALUE(root->right->right) != 1 )
3262 if (AST_LIT_VALUE(root->left->right) !=
3263 (getSize(TTYPE(root->left->left))*8 - 1))
3266 /* whew got the first case : create the AST */
3267 return newNode(RLC,root->left->left,NULL);
3272 /* third case for RRC */
3273 /* (?symbol >> 1) | (?symbol << 7) */
3274 if (IS_LEFT_OP(root->right) &&
3275 IS_RIGHT_OP(root->left) ) {
3277 if (!SPEC_USIGN(TETYPE(root->left->left)))
3280 if (!IS_AST_LIT_VALUE(root->left->right) ||
3281 !IS_AST_LIT_VALUE(root->right->right))
3284 /* make sure it is the same symbol */
3285 if (!isAstEqual(root->left->left,
3289 if (AST_LIT_VALUE(root->left->right) != 1 )
3292 if (AST_LIT_VALUE(root->right->right) !=
3293 (getSize(TTYPE(root->left->left))*8 - 1))
3296 /* whew got the first case : create the AST */
3297 return newNode(RRC,root->left->left,NULL);
3301 /* fourth and last case for now */
3302 /* (?symbol << 7) | (?symbol >> 1) */
3303 if (IS_RIGHT_OP(root->right) &&
3304 IS_LEFT_OP(root->left) ) {
3306 if (!SPEC_USIGN(TETYPE(root->left->left)))
3309 if (!IS_AST_LIT_VALUE(root->left->right) ||
3310 !IS_AST_LIT_VALUE(root->right->right))
3313 /* make sure it is the same symbol */
3314 if (!isAstEqual(root->left->left,
3318 if (AST_LIT_VALUE(root->right->right) != 1 )
3321 if (AST_LIT_VALUE(root->left->right) !=
3322 (getSize(TTYPE(root->left->left))*8 - 1))
3325 /* whew got the first case : create the AST */
3326 return newNode(RRC,root->left->left,NULL);
3330 /* not found return root */
3334 /*-----------------------------------------------------------------*/
3335 /* optimizeCompare - otimizes compares for bit variables */
3336 /*-----------------------------------------------------------------*/
3337 ast *optimizeCompare ( ast *root )
3339 ast *optExpr = NULL;
3342 unsigned int litValue ;
3344 /* if nothing then return nothing */
3348 /* if not a compare op then do leaves */
3349 if (!IS_COMPARE_OP(root)) {
3350 root->left = optimizeCompare (root->left);
3351 root->right= optimizeCompare (root->right);
3355 /* if left & right are the same then depending
3356 of the operation do */
3357 if (isAstEqual(root->left,root->right)) {
3358 switch (root->opval.op) {
3362 optExpr = newAst(EX_VALUE,constVal("0"));
3367 optExpr = newAst(EX_VALUE,constVal("1"));
3371 return decorateType(optExpr);
3374 vleft = (root->left->type == EX_VALUE ?
3375 root->left->opval.val : NULL );
3377 vright = (root->right->type == EX_VALUE ?
3378 root->right->opval.val : NULL);
3380 /* if left is a BITVAR in BITSPACE */
3381 /* and right is a LITERAL then opt-*/
3382 /* imize else do nothing */
3383 if (vleft && vright &&
3384 IS_BITVAR(vleft->etype) &&
3385 IN_BITSPACE(SPEC_OCLS(vleft->etype)) &&
3386 IS_LITERAL(vright->etype)) {
3388 /* if right side > 1 then comparison may never succeed */
3389 if ( (litValue = (int) floatFromVal(vright)) > 1 ) {
3390 werror(W_BAD_COMPARE);
3395 switch (root->opval.op) {
3396 case '>' : /* bit value greater than 1 cannot be */
3397 werror(W_BAD_COMPARE);
3401 case '<' : /* bit value < 1 means 0 */
3403 optExpr = newNode('!',newAst(EX_VALUE,vleft),NULL);
3406 case LE_OP : /* bit value <= 1 means no check */
3407 optExpr = newAst(EX_VALUE,vright);
3410 case GE_OP : /* bit value >= 1 means only check for = */
3412 optExpr = newAst(EX_VALUE,vleft);
3415 } else { /* literal is zero */
3416 switch (root->opval.op) {
3417 case '<' : /* bit value < 0 cannot be */
3418 werror(W_BAD_COMPARE);
3422 case '>' : /* bit value > 0 means 1 */
3424 optExpr = newAst(EX_VALUE,vleft);
3427 case LE_OP : /* bit value <= 0 means no check */
3428 case GE_OP : /* bit value >= 0 means no check */
3429 werror(W_BAD_COMPARE);
3433 case EQ_OP : /* bit == 0 means ! of bit */
3434 optExpr = newNode('!',newAst(EX_VALUE,vleft),NULL);
3438 return decorateType(resolveSymbols(optExpr));
3439 } /* end-of-if of BITVAR */
3444 /*-----------------------------------------------------------------*/
3445 /* addSymToBlock : adds the symbol to the first block we find */
3446 /*-----------------------------------------------------------------*/
3447 void addSymToBlock (symbol *sym, ast *tree)
3449 /* reached end of tree or a leaf */
3450 if (!tree || IS_AST_LINK(tree) || IS_AST_VALUE(tree))
3454 if (IS_AST_OP(tree) &&
3455 tree->opval.op == BLOCK ) {
3457 symbol *lsym = copySymbol(sym);
3459 lsym->next = AST_VALUES(tree,sym);
3460 AST_VALUES(tree,sym) = lsym ;
3464 addSymToBlock(sym,tree->left);
3465 addSymToBlock(sym,tree->right);
3468 /*-----------------------------------------------------------------*/
3469 /* processRegParms - do processing for register parameters */
3470 /*-----------------------------------------------------------------*/
3471 static void processRegParms (value *args, ast *body)
3474 if (IS_REGPARM(args->etype))
3475 addSymToBlock(args->sym,body);
3480 /*-----------------------------------------------------------------*/
3481 /* resetParmKey - resets the operandkeys for the symbols */
3482 /*-----------------------------------------------------------------*/
3483 DEFSETFUNC(resetParmKey)
3494 /*-----------------------------------------------------------------*/
3495 /* createFunction - This is the key node that calls the iCode for */
3496 /* generating the code for a function. Note code */
3497 /* is generated function by function, later when */
3498 /* add inter-procedural analysis this will change */
3499 /*-----------------------------------------------------------------*/
3500 ast *createFunction (symbol *name, ast *body )
3506 iCode *piCode = NULL;
3508 /* if check function return 0 then some problem */
3509 if (checkFunction (name) == 0)
3512 /* create a dummy block if none exists */
3514 body = newNode(BLOCK,NULL,NULL);
3518 /* check if the function name already in the symbol table */
3519 if ((csym = findSym (SymbolTab,NULL,name->name))) {
3521 /* special case for compiler defined functions
3522 we need to add the name to the publics list : this
3523 actually means we are now compiling the compiler
3526 addSet(&publics,name);
3530 allocVariables(name);
3532 name->lastLine = yylineno;
3534 processFuncArgs(currFunc,0);
3536 /* set the stack pointer */
3537 /* PENDING: check this for the mcs51 */
3538 stackPtr = -port->stack.direction * port->stack.call_overhead;
3539 if (IS_ISR(name->etype))
3540 stackPtr -= port->stack.direction * port->stack.isr_overhead;
3541 if (IS_RENT(name->etype) || options.stackAuto)
3542 stackPtr -= port->stack.direction * port->stack.reent_overhead;
3544 xstackPtr = -port->stack.direction * port->stack.call_overhead;
3546 fetype = getSpec(name->type); /* get the specifier for the function */
3547 /* if this is a reentrant function then */
3548 if (IS_RENT(fetype))
3551 allocParms (name->args); /* allocate the parameters */
3553 /* do processing for parameters that are passed in registers */
3554 processRegParms (name->args,body);
3556 /* set the stack pointer */
3560 /* allocate & autoinit the block variables */
3561 processBlockVars (body, &stack,ALLOCATE);
3563 /* save the stack information */
3564 if (options.useXstack)
3565 name->xstack = SPEC_STAK(fetype) = stack;
3567 name->stack = SPEC_STAK(fetype) = stack;
3569 /* name needs to be mangled */
3570 sprintf (name->rname,"_%s",name->name);
3572 body = resolveSymbols(body); /* resolve the symbols */
3573 body = decorateType (body); /* propagateType & do semantic checks */
3575 ex = newAst (EX_VALUE, symbolVal(name)); /* create name */
3576 ex = newNode (FUNCTION,ex,body);
3577 ex->values.args = name->args ;
3580 werror(E_FUNC_NO_CODE,name->name);
3584 /* create the node & generate intermediate code */
3585 codeOutFile = code->oFile;
3586 piCode = iCodeFromAst(ex);
3589 werror(E_FUNC_NO_CODE,name->name);
3593 eBBlockFromiCode(piCode);
3595 /* if there are any statics then do them */
3597 codeOutFile = statsg->oFile;
3598 eBBlockFromiCode (iCodeFromAst (decorateType(resolveSymbols(staticAutos))));
3604 /* dealloc the block variables */
3605 processBlockVars(body, &stack,DEALLOCATE);
3606 /* deallocate paramaters */
3607 deallocParms(name->args);
3609 if (IS_RENT(fetype))
3612 /* we are done freeup memory & cleanup */
3617 addSet(&operKeyReset,name);
3618 applyToSet(operKeyReset,resetParmKey);
3621 cdbStructBlock(1,cdbFile);
3623 cleanUpLevel(LabelTab,0);
3624 cleanUpBlock(StructTab,1);
3625 cleanUpBlock(TypedefTab,1);
3627 xstack->syms = NULL;
3628 istack->syms = NULL;