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 -------------------------------------------------------------------------*/
30 set *operKeyReset = NULL;
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 ast *createIval (ast *, sym_link *, initList *, ast *);
54 ast *createIvalCharPtr (ast *, sym_link *, ast *);
55 ast *optimizeRRCRLC ( ast * );
56 ast *optimizeGetHbit(ast *);
57 ast *backPatchLabels (ast *,symbol *,symbol *);
61 printTypeChain(tree->ftype,stdout);
66 /*-----------------------------------------------------------------*/
67 /* newAst - creates a fresh node for an expression tree */
68 /*-----------------------------------------------------------------*/
70 ast *newAst (int type, void *op )
73 static int oldLineno = 0 ;
75 Safe_calloc(1,ex,sizeof(ast));
78 ex->lineno = (noLineno ? oldLineno : yylineno);
79 ex->filename = currFname ;
80 ex->level = NestLevel ;
81 ex->block = currBlockno ;
82 ex->initMode = inInitMode;
84 /* depending on the type */
87 ex->opval.val = (value *) op;
90 ex->opval.op = (long) op ;
93 ex->opval.lnk = (sym_link *) op;
96 ex->opval.stmnt= (unsigned) op;
103 static ast* newAst_(unsigned type)
106 static int oldLineno = 0 ;
108 ex = Safe_calloc(1,sizeof(ast));
111 ex->lineno = (noLineno ? oldLineno : yylineno);
112 ex->filename = currFname ;
113 ex->level = NestLevel ;
114 ex->block = currBlockno ;
115 ex->initMode = inInitMode;
119 ast* newAst_VALUE(value*val)
121 ast* ex = newAst_(EX_VALUE);
126 ast* newAst_OP(unsigned op)
128 ast*ex = newAst_(EX_OP);
133 ast* newAst_LINK(sym_link*val)
135 ast* ex = newAst_(EX_LINK);
140 ast* newAst_STMNT(unsigned val)
142 ast* ex = newAst_(EX_STMNT);
143 ex->opval.stmnt = val;
147 /*-----------------------------------------------------------------*/
148 /* newNode - creates a new node */
149 /*-----------------------------------------------------------------*/
150 ast *newNode ( long op, ast *left, ast *right )
161 /*-----------------------------------------------------------------*/
162 /* newIfxNode - creates a new Ifx Node */
163 /*-----------------------------------------------------------------*/
164 ast *newIfxNode (ast *condAst, symbol *trueLabel, symbol *falseLabel)
168 /* if this is a literal then we already know the result */
169 if (condAst->etype && IS_LITERAL(condAst->etype)) {
171 /* then depending on the expression value */
172 if ( floatFromVal(condAst->opval.val) )
173 ifxNode = newNode(GOTO,
174 newAst_VALUE(symbolVal(trueLabel)),
177 ifxNode = newNode(GOTO,
178 newAst_VALUE(symbolVal(falseLabel)),
182 ifxNode = newNode(IFX,condAst,NULL);
183 ifxNode->trueLabel = trueLabel;
184 ifxNode->falseLabel= falseLabel;
190 /*-----------------------------------------------------------------*/
191 /* copyAstValues - copies value portion of ast if needed */
192 /*-----------------------------------------------------------------*/
193 void copyAstValues (ast *dest,ast *src)
195 switch (src->opval.op) {
197 dest->values.sym = copySymbolChain(src->values.sym);
201 dest->values.switchVals.swVals =
202 copyValue(src->values.switchVals.swVals);
203 dest->values.switchVals.swDefault =
204 src->values.switchVals.swDefault ;
205 dest->values.switchVals.swNum =
206 src->values.switchVals.swNum ;
210 dest->values.inlineasm = Safe_calloc(1,strlen(src->values.inlineasm)+1);
211 strcpy(dest->values.inlineasm,src->values.inlineasm);
214 AST_FOR(dest,trueLabel) = copySymbol(AST_FOR(src,trueLabel));
215 AST_FOR(dest,continueLabel) = copySymbol(AST_FOR(src,continueLabel));
216 AST_FOR(dest,falseLabel) = copySymbol(AST_FOR(src,falseLabel));
217 AST_FOR(dest,condLabel) = copySymbol(AST_FOR(src,condLabel));
218 AST_FOR(dest,initExpr) = copyAst (AST_FOR(src,initExpr)) ;
219 AST_FOR(dest,condExpr) = copyAst (AST_FOR(src,condExpr)) ;
220 AST_FOR(dest,loopExpr) = copyAst (AST_FOR(src,loopExpr)) ;
225 /*-----------------------------------------------------------------*/
226 /* copyAst - makes a copy of a given astession */
227 /*-----------------------------------------------------------------*/
228 ast *copyAst (ast *src)
232 if (!src) return NULL ;
234 dest = Safe_calloc(1,sizeof(ast));
236 dest->type = src->type ;
237 dest->lineno = src->lineno ;
238 dest->level = src->level ;
239 dest->funcName = src->funcName;
240 dest->argSym = src->argSym;
242 /* if this is a leaf */
244 if (src->type == EX_VALUE) {
245 dest->opval.val = copyValue(src->opval.val);
250 if (src->type == EX_LINK) {
251 dest->opval.lnk = copyLinkChain(src->opval.lnk);
255 dest->opval.op = src->opval.op ;
257 /* if this is a node that has special values */
258 copyAstValues (dest,src);
261 dest->etype = getSpec(dest->ftype = copyLinkChain(src->ftype)) ;
263 dest->trueLabel = copySymbol (src->trueLabel);
264 dest->falseLabel= copySymbol (src->falseLabel);
265 dest->left = copyAst(src->left);
266 dest->right= copyAst(src->right);
272 /*-----------------------------------------------------------------*/
273 /* hasSEFcalls - returns TRUE if tree has a function call */
274 /*-----------------------------------------------------------------*/
275 bool hasSEFcalls ( ast *tree)
280 if (tree->type == EX_OP &&
281 ( tree->opval.op == CALL ||
282 tree->opval.op == PCALL ||
283 tree->opval.op == '=' ||
284 tree->opval.op == INC_OP ||
285 tree->opval.op == DEC_OP ))
288 return ( hasSEFcalls(tree->left) |
289 hasSEFcalls(tree->right));
292 /*-----------------------------------------------------------------*/
293 /* isAstEqual - compares two asts & returns 1 if they are equal */
294 /*-----------------------------------------------------------------*/
295 int isAstEqual (ast *t1, ast *t2)
304 if (t1->type != t2->type)
309 if (t1->opval.op != t2->opval.op)
311 return ( isAstEqual(t1->left,t2->left) &&
312 isAstEqual(t1->right,t2->right));
316 if (t1->opval.val->sym) {
317 if (!t2->opval.val->sym)
320 return isSymbolEqual(t1->opval.val->sym,
324 if (t2->opval.val->sym)
327 return (floatFromVal(t1->opval.val) ==
328 floatFromVal(t2->opval.val));
332 /* only compare these two types */
340 /*-----------------------------------------------------------------*/
341 /* resolveSymbols - resolve symbols from the symbol table */
342 /*-----------------------------------------------------------------*/
343 ast *resolveSymbols (ast *tree)
345 /* walk the entire tree and check for values */
346 /* with symbols if we find one then replace */
347 /* symbol with that from the symbol table */
353 /* if not block & function */
354 if ( tree->type == EX_OP &&
355 ( tree->opval.op != FUNCTION &&
356 tree->opval.op != BLOCK &&
357 tree->opval.op != NULLOP )) {
358 filename = tree->filename ;
359 lineno = tree->lineno ;
362 /* make sure we resolve the true & false labels for ifx */
363 if (tree->type == EX_OP && tree->opval.op == IFX ) {
366 if (tree->trueLabel) {
367 if (( csym = findSym(LabelTab,tree->trueLabel,
368 tree->trueLabel->name)))
369 tree->trueLabel = csym ;
371 werror(E_LABEL_UNDEF,tree->trueLabel->name);
374 if (tree->falseLabel) {
375 if (( csym = findSym(LabelTab,
377 tree->falseLabel->name)))
378 tree->falseLabel = csym ;
380 werror(E_LABEL_UNDEF,tree->falseLabel->name);
385 /* if this is a label resolve it from the labelTab*/
386 if (IS_AST_VALUE(tree) &&
387 tree->opval.val->sym &&
388 tree->opval.val->sym->islbl) {
390 symbol *csym = findSym (LabelTab, tree->opval.val->sym ,
391 tree->opval.val->sym->name);
394 werror (E_LABEL_UNDEF,tree->opval.val->sym->name);
396 tree->opval.val->sym = csym ;
398 goto resolveChildren ;
401 /* do only for leafs */
402 if (IS_AST_VALUE(tree) &&
403 tree->opval.val->sym &&
404 ! tree->opval.val->sym->implicit ) {
406 symbol *csym = findSymWithLevel (SymbolTab,tree->opval.val->sym);
408 /* if found in the symbol table & they r not the same */
409 if (csym && tree->opval.val->sym != csym ) {
410 tree->opval.val->sym = csym ;
411 tree->opval.val->type = csym->type;
412 tree->opval.val->etype = csym->etype;
415 /* if not found in the symbol table */
416 /* mark it as undefined assume it is*/
417 /* an integer in data space */
418 if (!csym && !tree->opval.val->sym->implicit) {
420 /* if this is a function name then */
421 /* mark it as returning an int */
422 if (tree->funcName) {
423 tree->opval.val->sym->type = newLink();
424 DCL_TYPE(tree->opval.val->sym->type) = FUNCTION;
425 tree->opval.val->sym->type->next =
426 tree->opval.val->sym->etype = newIntLink();
427 tree->opval.val->etype = tree->opval.val->etype;
428 tree->opval.val->type = tree->opval.val->sym->type;
429 werror(W_IMPLICIT_FUNC,tree->opval.val->sym->name);
431 tree->opval.val->sym->undefined =1 ;
432 tree->opval.val->type =
433 tree->opval.val->etype = newIntLink();
434 tree->opval.val->sym->type =
435 tree->opval.val->sym->etype = newIntLink();
441 resolveSymbols (tree->left);
442 resolveSymbols (tree->right);
447 /*-----------------------------------------------------------------*/
448 /* setAstLineno - walks a ast tree & sets the line number */
449 /*-----------------------------------------------------------------*/
450 int setAstLineno ( ast *tree, int lineno)
455 tree->lineno = lineno ;
456 setAstLineno ( tree->left, lineno);
457 setAstLineno ( tree->right, lineno);
462 /* this functions seems to be superfluous?! kmh */
464 /*-----------------------------------------------------------------*/
465 /* resolveFromTable - will return the symbal table value */
466 /*-----------------------------------------------------------------*/
467 value *resolveFromTable (value *val)
474 csym = findSymWithLevel (SymbolTab,val->sym);
476 /* if found in the symbol table & they r not the same */
477 if (csym && val->sym != csym &&
478 csym->level == val->sym->level &&
483 val->type = csym->type;
484 val->etype = csym->etype;
491 /*-----------------------------------------------------------------*/
492 /* funcOfType :- function of type with name */
493 /*-----------------------------------------------------------------*/
494 symbol *funcOfType (char *name, sym_link *type, sym_link *argType,
495 int nArgs , int rent)
499 /* create the symbol */
500 sym = newSymbol (name,0);
502 /* if arguments required */
506 args = sym->args = newValue();
509 argStack += getSize(type);
510 args->type = copyLinkChain(argType);
511 args->etype = getSpec(args->type);
514 args = args->next = newValue();
518 /* setup return value */
519 sym->type = newLink();
520 DCL_TYPE(sym->type) = FUNCTION;
521 sym->type->next = copyLinkChain(type);
522 sym->etype = getSpec(sym->type);
523 SPEC_RENT(sym->etype) = rent;
528 sym->argStack = (rent ? argStack : 0);
529 allocVariables (sym);
534 /*-----------------------------------------------------------------*/
535 /* reverseParms - will reverse a parameter tree */
536 /*-----------------------------------------------------------------*/
537 void reverseParms (ast *ptree)
543 /* top down if we find a nonParm tree then quit */
544 if (ptree->type == EX_OP && ptree->opval.op == PARAM ) {
546 ptree->left = ptree->right;
547 ptree->right = ttree;
548 reverseParms(ptree->left);
549 reverseParms(ptree->right);
555 /*-----------------------------------------------------------------*/
556 /* processParms - makes sure the parameters are okay and do some */
557 /* processing with them */
558 /*-----------------------------------------------------------------*/
559 int processParms (ast *func,
565 sym_link *fetype = func->etype;
567 /* if none of them exist */
568 if ( !defParm && !actParm)
571 /* if the function is being called via a pointer & */
572 /* it has not been defined a reentrant then we cannot*/
573 /* have parameters */
574 if (func->type != EX_VALUE && !IS_RENT(fetype) && !options.stackAuto) {
575 werror (E_NONRENT_ARGS);
579 /* if defined parameters ended but actual parameters */
580 /* exist and this is not defined as a variable arg */
581 /* also check if statckAuto option is specified */
582 if ((! defParm) && actParm && (!func->hasVargs ) &&
583 !options.stackAuto && !IS_RENT(fetype)) {
584 werror(E_TOO_MANY_PARMS);
588 /* if defined parameters present but no actual parameters */
589 if ( defParm && ! actParm) {
590 werror(E_TOO_FEW_PARMS);
594 /* If this is a varargs function... */
595 if (!defParm && actParm && func->hasVargs )
599 if (IS_CAST_OP(actParm)
600 || (IS_AST_LIT_VALUE(actParm) && actParm->values.literalFromCast))
602 /* Parameter was explicitly typecast; don't touch it. */
606 /* If it's a small integer, upcast to int. */
607 if (IS_INTEGRAL(actParm->ftype)
608 && getSize(actParm->ftype) < (unsigned) INTSIZE)
610 newType = newAst_LINK(INTTYPE);
613 if (IS_PTR(actParm->ftype) && !IS_GENPTR(actParm->ftype))
615 newType = newAst_LINK(copyLinkChain(actParm->ftype));
616 DCL_TYPE(newType->opval.lnk) = GPOINTER;
619 if (IS_AGGREGATE(actParm->ftype))
621 newType = newAst_LINK(copyLinkChain(actParm->ftype));
622 DCL_TYPE(newType->opval.lnk) = GPOINTER;
627 /* cast required; change this op to a cast. */
628 ast *parmCopy = resolveSymbols(copyAst(actParm));
630 actParm->type = EX_OP;
631 actParm->opval.op = CAST;
632 actParm->left = newType;
633 actParm->right= parmCopy;
634 decorateType(actParm);
636 else if ( actParm->type == EX_OP && actParm->opval.op == PARAM)
638 return (processParms(func,NULL,actParm->left,parmNumber,FALSE) ||
639 processParms(func,NULL,actParm->right,parmNumber,rightmost));
644 /* if defined parameters ended but actual has not & */
646 if (! defParm && actParm &&
647 (options.stackAuto || IS_RENT(fetype)))
650 resolveSymbols(actParm);
651 /* if this is a PARAM node then match left & right */
652 if ( actParm->type == EX_OP && actParm->opval.op == PARAM)
654 return (processParms(func,defParm,actParm->left,parmNumber,FALSE) ||
655 processParms(func,defParm->next, actParm->right,parmNumber,rightmost));
659 /* If we have found a value node by following only right-hand links,
660 * then we know that there are no more values after us.
662 * Therefore, if there are more defined parameters, the caller didn't
665 if (rightmost && defParm->next)
667 werror(E_TOO_FEW_PARMS);
672 /* the parameter type must be at least castable */
673 if (checkType(defParm->type,actParm->ftype) == 0) {
674 werror(E_TYPE_MISMATCH_PARM,*parmNumber);
675 werror(E_CONTINUE,"defined type ");
676 printTypeChain(defParm->type,stderr);fprintf(stderr,"\n");
677 werror(E_CONTINUE,"actual type ");
678 printTypeChain(actParm->ftype,stderr);fprintf(stderr,"\n");
681 /* if the parameter is castable then add the cast */
682 if ( checkType (defParm->type,actParm->ftype) < 0) {
683 ast *pTree = resolveSymbols(copyAst(actParm));
685 /* now change the current one to a cast */
686 actParm->type = EX_OP ;
687 actParm->opval.op = CAST ;
688 actParm->left = newAst_LINK(defParm->type);
689 actParm->right= pTree ;
690 actParm->etype= defParm->etype;
691 actParm->ftype= defParm->type;
694 /* actParm->argSym = resolveFromTable(defParm)->sym ; */
696 actParm->argSym = defParm->sym;
697 /* make a copy and change the regparm type to the defined parm */
698 actParm->etype = getSpec(actParm->ftype = copyLinkChain(actParm->ftype));
699 SPEC_REGPARM(actParm->etype) = SPEC_REGPARM(defParm->etype);
703 /*-----------------------------------------------------------------*/
704 /* createIvalType - generates ival for basic types */
705 /*-----------------------------------------------------------------*/
706 ast *createIvalType ( ast *sym,sym_link *type, initList *ilist)
710 /* if initList is deep */
711 if ( ilist->type == INIT_DEEP )
712 ilist = ilist->init.deep ;
714 iExpr = decorateType(resolveSymbols(list2expr(ilist)));
715 return decorateType(newNode('=',sym,iExpr));
718 /*-----------------------------------------------------------------*/
719 /* createIvalStruct - generates initial value for structures */
720 /*-----------------------------------------------------------------*/
721 ast *createIvalStruct (ast *sym,sym_link *type,initList *ilist)
727 sflds = SPEC_STRUCT(type)->fields ;
728 if (ilist->type != INIT_DEEP) {
729 werror(E_INIT_STRUCT,"");
733 iloop = ilist->init.deep;
735 for ( ; sflds ; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL )) {
738 /* if we have come to end */
742 lAst = newNode(PTR_OP,newNode('&',sym,NULL),newAst_VALUE(symbolVal(sflds)));
743 lAst = decorateType(resolveSymbols(lAst));
744 rast = decorateType(resolveSymbols(createIval (lAst, sflds->type, iloop,rast)));
750 /*-----------------------------------------------------------------*/
751 /* createIvalArray - generates code for array initialization */
752 /*-----------------------------------------------------------------*/
753 ast *createIvalArray (ast *sym, sym_link *type, initList *ilist)
757 int lcnt = 0, size =0 ;
759 /* take care of the special case */
760 /* array of characters can be init */
762 if ( IS_CHAR(type->next) )
763 if ( (rast = createIvalCharPtr(sym,
765 decorateType(resolveSymbols(list2expr(ilist))))))
767 return decorateType(resolveSymbols(rast));
769 /* not the special case */
770 if (ilist->type != INIT_DEEP) {
771 werror(E_INIT_STRUCT,"");
775 iloop = ilist->init.deep ;
776 lcnt = DCL_ELEM(type);
782 aSym = newNode('[',sym,newAst_VALUE(valueFromLit((float) (size-1))));
783 aSym = decorateType(resolveSymbols(aSym));
784 rast = createIval (aSym,type->next,iloop,rast) ;
785 iloop = (iloop ? iloop->next : NULL) ;
788 /* if not array limits given & we */
789 /* are out of initialisers then */
790 if (!DCL_ELEM(type) && !iloop)
793 /* no of elements given and we */
794 /* have generated for all of them */
799 /* if we have not been given a size */
801 DCL_ELEM(type) = size;
803 return decorateType(resolveSymbols(rast));
807 /*-----------------------------------------------------------------*/
808 /* createIvalCharPtr - generates initial values for char pointers */
809 /*-----------------------------------------------------------------*/
810 ast *createIvalCharPtr (ast *sym, sym_link *type, ast *iexpr)
814 /* if this is a pointer & right is a literal array then */
815 /* just assignment will do */
816 if ( IS_PTR(type) && (( IS_LITERAL(iexpr->etype) ||
817 SPEC_SCLS(iexpr->etype) == S_CODE )
818 && IS_ARRAY(iexpr->ftype)))
819 return newNode('=',sym,iexpr);
821 /* left side is an array so we have to assign each */
823 if (( IS_LITERAL(iexpr->etype) ||
824 SPEC_SCLS(iexpr->etype) == S_CODE )
825 && IS_ARRAY(iexpr->ftype)) {
827 /* for each character generate an assignment */
828 /* to the array element */
829 char *s = SPEC_CVAL(iexpr->etype).v_char ;
833 rast = newNode(NULLOP,
837 newAst_VALUE(valueFromLit((float) i))),
838 newAst_VALUE(valueFromLit(*s))));
842 rast = newNode(NULLOP,
846 newAst_VALUE(valueFromLit((float) i))),
847 newAst_VALUE(valueFromLit(*s))));
848 return decorateType(resolveSymbols(rast));
854 /*-----------------------------------------------------------------*/
855 /* createIvalPtr - generates initial value for pointers */
856 /*-----------------------------------------------------------------*/
857 ast *createIvalPtr (ast *sym,sym_link *type,initList *ilist)
863 if ( ilist->type == INIT_DEEP )
864 ilist = ilist->init.deep ;
866 iexpr = decorateType(resolveSymbols(list2expr(ilist)));
868 /* if character pointer */
869 if (IS_CHAR(type->next))
870 if ((rast = createIvalCharPtr (sym,type,iexpr)))
873 return newNode('=',sym,iexpr);
876 /*-----------------------------------------------------------------*/
877 /* createIval - generates code for initial value */
878 /*-----------------------------------------------------------------*/
879 ast *createIval (ast *sym, sym_link *type, initList *ilist, ast *wid)
886 /* if structure then */
888 rast = createIvalStruct(sym, type,ilist);
890 /* if this is a pointer */
892 rast = createIvalPtr(sym, type,ilist);
894 /* if this is an array */
896 rast = createIvalArray(sym, type,ilist);
898 /* if type is SPECIFIER */
900 rast = createIvalType (sym,type,ilist);
902 return decorateType(resolveSymbols(newNode(NULLOP,wid,rast)));
904 return decorateType(resolveSymbols(rast)) ;
907 /*-----------------------------------------------------------------*/
908 /* initAggregates - initialises aggregate variables with initv */
909 /*-----------------------------------------------------------------*/
910 ast *initAggregates ( symbol *sym, initList *ival, ast *wid)
912 return createIval (newAst_VALUE(symbolVal(sym)),sym->type,ival,wid);
915 /*-----------------------------------------------------------------*/
916 /* gatherAutoInit - creates assignment expressions for initial */
918 /*-----------------------------------------------------------------*/
919 ast *gatherAutoInit ( symbol *autoChain )
926 for ( sym = autoChain ; sym ; sym = sym->next ) {
928 /* resolve the symbols in the ival */
930 resolveIvalSym(sym->ival);
932 /* if this is a static variable & has an */
933 /* initial value the code needs to be lifted */
934 /* here to the main portion since they can be */
935 /* initialised only once at the start */
936 if ( IS_STATIC(sym->etype) && sym->ival &&
937 SPEC_SCLS(sym->etype) != S_CODE) {
940 /* insert the symbol into the symbol table */
941 /* with level = 0 & name = rname */
942 newSym = copySymbol (sym);
943 addSym (SymbolTab,newSym,newSym->name,0,0);
945 /* now lift the code to main */
946 if (IS_AGGREGATE(sym->type))
947 work = initAggregates (sym, sym->ival,NULL);
949 work = newNode('=' ,newAst_VALUE(symbolVal(newSym)),
950 list2expr(sym->ival));
952 setAstLineno(work,sym->lineDef);
956 staticAutos = newNode(NULLOP,staticAutos,work);
963 /* if there is an initial value */
964 if ( sym->ival && SPEC_SCLS(sym->etype)!=S_CODE) {
965 if (IS_AGGREGATE(sym->type))
966 work = initAggregates (sym,sym->ival,NULL);
968 work = newNode('=' ,newAst_VALUE(symbolVal(sym)),
969 list2expr(sym->ival));
971 setAstLineno (work,sym->lineDef);
974 init = newNode(NULLOP,init,work);
983 /*-----------------------------------------------------------------*/
984 /* stringToSymbol - creates a symbol from a literal string */
985 /*-----------------------------------------------------------------*/
986 static value *stringToSymbol (value *val)
988 char name[SDCC_NAME_MAX+1];
989 static int charLbl = 0;
992 sprintf(name,"_str_%d",charLbl++);
993 sym = newSymbol(name,0); /* make it @ level 0 */
994 strcpy(sym->rname,name);
996 /* copy the type from the value passed */
997 sym->type = copyLinkChain(val->type);
998 sym->etype = getSpec(sym->type);
999 /* change to storage class & output class */
1000 SPEC_SCLS(sym->etype) = S_CODE ;
1001 SPEC_CVAL(sym->etype).v_char = SPEC_CVAL(val->etype).v_char ;
1002 SPEC_STAT(sym->etype) = 1;
1003 /* make the level & block = 0 */
1004 sym->block = sym->level = 0;
1006 /* create an ival */
1007 sym->ival = newiList(INIT_NODE,newAst_VALUE(val));
1011 allocVariables(sym);
1014 return symbolVal(sym);
1018 /*-----------------------------------------------------------------*/
1019 /* processBlockVars - will go thru the ast looking for block if */
1020 /* a block is found then will allocate the syms */
1021 /* will also gather the auto inits present */
1022 /*-----------------------------------------------------------------*/
1023 ast *processBlockVars ( ast *tree , int *stack, int action)
1028 /* if this is a block */
1029 if (tree->type == EX_OP && tree->opval.op == BLOCK ) {
1032 if (action == ALLOCATE) {
1033 autoInit = gatherAutoInit (tree->values.sym);
1034 *stack += allocVariables (tree->values.sym);
1036 /* if there are auto inits then do them */
1038 tree->left = newNode(NULLOP,autoInit,tree->left);
1039 } else /* action is deallocate */
1040 deallocLocal (tree->values.sym) ;
1043 processBlockVars (tree->left, stack, action);
1044 processBlockVars (tree->right, stack, action);
1048 /*-----------------------------------------------------------------*/
1049 /* constExprValue - returns the value of a constant expression */
1050 /*-----------------------------------------------------------------*/
1051 value *constExprValue (ast *cexpr, int check)
1053 cexpr = decorateType(resolveSymbols(cexpr));
1055 /* if this is not a constant then */
1056 if (!IS_LITERAL(cexpr->ftype)) {
1057 /* then check if this is a literal array
1059 if (SPEC_SCLS(cexpr->etype) == S_CODE &&
1060 SPEC_CVAL(cexpr->etype).v_char &&
1061 IS_ARRAY(cexpr->ftype)) {
1062 value *val = valFromType(cexpr->ftype);
1063 SPEC_SCLS(val->etype) = S_LITERAL;
1064 val->sym =cexpr->opval.val->sym ;
1065 val->sym->type = copyLinkChain(cexpr->ftype);
1066 val->sym->etype = getSpec(val->sym->type);
1067 strcpy(val->name,cexpr->opval.val->sym->rname);
1071 /* if we are casting a literal value then */
1072 if (IS_AST_OP(cexpr) &&
1073 cexpr->opval.op == CAST &&
1074 IS_LITERAL(cexpr->left->ftype))
1075 return valCastLiteral(cexpr->ftype,
1076 floatFromVal(cexpr->left->opval.val));
1078 if (IS_AST_VALUE(cexpr))
1079 return cexpr->opval.val;
1082 werror(E_CONST_EXPECTED,"found expression");
1087 /* return the value */
1088 return cexpr->opval.val ;
1092 /*-----------------------------------------------------------------*/
1093 /* isLabelInAst - will return true if a given label is found */
1094 /*-----------------------------------------------------------------*/
1095 bool isLabelInAst (symbol *label, ast *tree)
1097 if (!tree || IS_AST_VALUE(tree) || IS_AST_LINK(tree))
1100 if (IS_AST_OP(tree) &&
1101 tree->opval.op == LABEL &&
1102 isSymbolEqual(AST_SYMBOL(tree->left),label))
1105 return isLabelInAst(label,tree->right) &&
1106 isLabelInAst(label,tree->left);
1110 /*-----------------------------------------------------------------*/
1111 /* isLoopCountable - return true if the loop count can be determi- */
1112 /* -ned at compile time . */
1113 /*-----------------------------------------------------------------*/
1114 bool isLoopCountable (ast *initExpr, ast *condExpr, ast *loopExpr,
1115 symbol **sym,ast **init, ast **end)
1118 /* the loop is considered countable if the following
1119 conditions are true :-
1121 a) initExpr :- <sym> = <const>
1122 b) condExpr :- <sym> < <const1>
1123 c) loopExpr :- <sym> ++
1126 /* first check the initExpr */
1127 if ( IS_AST_OP(initExpr) &&
1128 initExpr->opval.op == '=' && /* is assignment */
1129 IS_AST_SYM_VALUE(initExpr->left)) { /* left is a symbol */
1131 *sym = AST_SYMBOL(initExpr->left);
1132 *init= initExpr->right;
1137 /* for now the symbol has to be of
1139 if (!IS_INTEGRAL((*sym)->type))
1142 /* now check condExpr */
1143 if (IS_AST_OP(condExpr)) {
1145 switch (condExpr->opval.op) {
1147 if (IS_AST_SYM_VALUE(condExpr->left) &&
1148 isSymbolEqual (*sym,AST_SYMBOL(condExpr->left)) &&
1149 IS_AST_LIT_VALUE(condExpr->right)) {
1150 *end = condExpr->right;
1156 if (IS_AST_OP(condExpr->left) &&
1157 condExpr->left->opval.op == '>' &&
1158 IS_AST_LIT_VALUE(condExpr->left->right) &&
1159 IS_AST_SYM_VALUE(condExpr->left->left)&&
1160 isSymbolEqual (*sym,AST_SYMBOL(condExpr->left->left))) {
1162 *end = newNode('+', condExpr->left->right,
1163 newAst_VALUE(constVal("1")));
1174 /* check loop expression is of the form <sym>++ */
1175 if (!IS_AST_OP(loopExpr))
1178 /* check if <sym> ++ */
1179 if (loopExpr->opval.op == INC_OP) {
1181 if (loopExpr->left) {
1183 if (IS_AST_SYM_VALUE(loopExpr->left) &&
1184 isSymbolEqual(*sym,AST_SYMBOL(loopExpr->left)))
1189 if (IS_AST_SYM_VALUE(loopExpr->right) &&
1190 isSymbolEqual(*sym,AST_SYMBOL(loopExpr->right)))
1197 if ( loopExpr->opval.op == ADD_ASSIGN ) {
1199 if (IS_AST_SYM_VALUE(loopExpr->left) &&
1200 isSymbolEqual(*sym,AST_SYMBOL(loopExpr->left)) &&
1201 IS_AST_LIT_VALUE(loopExpr->right) &&
1202 (int)AST_LIT_VALUE(loopExpr->right) != 1)
1210 /*-----------------------------------------------------------------*/
1211 /* astHasVolatile - returns true if ast contains any volatile */
1212 /*-----------------------------------------------------------------*/
1213 bool astHasVolatile (ast *tree)
1218 if (TETYPE(tree) && IS_VOLATILE(TETYPE(tree)))
1221 if (IS_AST_OP(tree))
1222 return astHasVolatile(tree->left) ||
1223 astHasVolatile(tree->right);
1228 /*-----------------------------------------------------------------*/
1229 /* astHasPointer - return true if the ast contains any ptr variable*/
1230 /*-----------------------------------------------------------------*/
1231 bool astHasPointer (ast *tree)
1236 if (IS_AST_LINK(tree))
1239 /* if we hit an array expression then check
1240 only the left side */
1241 if (IS_AST_OP(tree) && tree->opval.op == '[')
1242 return astHasPointer(tree->left);
1244 if (IS_AST_VALUE(tree))
1245 return IS_PTR(tree->ftype) || IS_ARRAY(tree->ftype);
1247 return astHasPointer(tree->left) ||
1248 astHasPointer(tree->right);
1252 /*-----------------------------------------------------------------*/
1253 /* astHasSymbol - return true if the ast has the given symbol */
1254 /*-----------------------------------------------------------------*/
1255 bool astHasSymbol (ast *tree, symbol *sym)
1257 if (!tree || IS_AST_LINK(tree))
1260 if (IS_AST_VALUE(tree)) {
1261 if (IS_AST_SYM_VALUE(tree))
1262 return isSymbolEqual(AST_SYMBOL(tree),sym);
1267 return astHasSymbol(tree->left,sym) ||
1268 astHasSymbol(tree->right,sym);
1271 /*-----------------------------------------------------------------*/
1272 /* isConformingBody - the loop body has to conform to a set of rules */
1273 /* for the loop to be considered reversible read on for rules */
1274 /*-----------------------------------------------------------------*/
1275 bool isConformingBody (ast *pbody, symbol *sym, ast *body)
1278 /* we are going to do a pre-order traversal of the
1279 tree && check for the following conditions. (essentially
1280 a set of very shallow tests )
1281 a) the sym passed does not participate in
1282 any arithmetic operation
1283 b) There are no function calls
1284 c) all jumps are within the body
1285 d) address of loop control variable not taken
1286 e) if an assignment has a pointer on the
1287 left hand side make sure right does not have
1288 loop control variable */
1290 /* if we reach the end or a leaf then true */
1291 if (!pbody || IS_AST_LINK(pbody) || IS_AST_VALUE(pbody))
1295 /* if anything else is "volatile" */
1296 if (IS_VOLATILE(TETYPE(pbody)))
1299 /* we will walk the body in a pre-order traversal for
1301 switch (pbody->opval.op) {
1302 /*------------------------------------------------------------------*/
1304 return isConformingBody (pbody->right,sym,body);
1306 /*------------------------------------------------------------------*/
1311 /*------------------------------------------------------------------*/
1312 case INC_OP: /* incerement operator unary so left only */
1315 /* sure we are not sym is not modified */
1317 IS_AST_SYM_VALUE(pbody->left) &&
1318 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1322 IS_AST_SYM_VALUE(pbody->right) &&
1323 isSymbolEqual(AST_SYMBOL(pbody->right),sym))
1328 /*------------------------------------------------------------------*/
1330 case '*' : /* can be unary : if right is null then unary operation */
1335 /* if right is NULL then unary operation */
1336 /*------------------------------------------------------------------*/
1337 /*----------------------------*/
1339 /*----------------------------*/
1340 if ( ! pbody->right ) {
1341 if (IS_AST_SYM_VALUE(pbody->left) &&
1342 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1345 return isConformingBody(pbody->left,sym,body) ;
1347 if (astHasSymbol(pbody->left,sym) ||
1348 astHasSymbol(pbody->right,sym))
1353 /*------------------------------------------------------------------*/
1361 if (IS_AST_SYM_VALUE(pbody->left) &&
1362 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1365 if (IS_AST_SYM_VALUE(pbody->right) &&
1366 isSymbolEqual(AST_SYMBOL(pbody->right),sym))
1369 return isConformingBody(pbody->left,sym,body) &&
1370 isConformingBody(pbody->right,sym,body);
1377 if (IS_AST_SYM_VALUE(pbody->left) &&
1378 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1380 return isConformingBody (pbody->left,sym,body);
1382 /*------------------------------------------------------------------*/
1394 case SIZEOF: /* evaluate wihout code generation */
1396 return isConformingBody(pbody->left,sym,body) &&
1397 isConformingBody(pbody->right,sym,body);
1399 /*------------------------------------------------------------------*/
1402 /* if left has a pointer & right has loop
1403 control variable then we cannot */
1404 if (astHasPointer(pbody->left) &&
1405 astHasSymbol (pbody->right,sym))
1407 if (astHasVolatile(pbody->left))
1410 if (IS_AST_SYM_VALUE(pbody->left) &&
1411 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1414 if (astHasVolatile(pbody->left))
1417 return isConformingBody(pbody->left,sym,body) &&
1418 isConformingBody(pbody->right,sym,body);
1429 assert("Parser should not have generated this\n");
1431 /*------------------------------------------------------------------*/
1432 /*----------------------------*/
1433 /* comma operator */
1434 /*----------------------------*/
1436 return isConformingBody(pbody->left,sym,body) &&
1437 isConformingBody(pbody->right,sym,body);
1439 /*------------------------------------------------------------------*/
1440 /*----------------------------*/
1442 /*----------------------------*/
1446 /*------------------------------------------------------------------*/
1447 /*----------------------------*/
1448 /* return statement */
1449 /*----------------------------*/
1454 if (isLabelInAst (AST_SYMBOL(pbody->left),body))
1459 if (astHasSymbol(pbody->left,sym))
1466 return isConformingBody(pbody->left,sym,body) &&
1467 isConformingBody(pbody->right,sym,body);
1473 /*-----------------------------------------------------------------*/
1474 /* isLoopReversible - takes a for loop as input && returns true */
1475 /* if the for loop is reversible. If yes will set the value of */
1476 /* the loop control var & init value & termination value */
1477 /*-----------------------------------------------------------------*/
1478 bool isLoopReversible (ast *loop, symbol **loopCntrl,
1479 ast **init, ast **end )
1481 /* if option says don't do it then don't */
1482 if (optimize.noLoopReverse)
1484 /* there are several tests to determine this */
1486 /* for loop has to be of the form
1487 for ( <sym> = <const1> ;
1488 [<sym> < <const2>] ;
1489 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1491 if (! isLoopCountable (AST_FOR(loop,initExpr),
1492 AST_FOR(loop,condExpr),
1493 AST_FOR(loop,loopExpr),
1494 loopCntrl,init,end))
1497 /* now do some serious checking on the body of the loop
1500 return isConformingBody(loop->left,*loopCntrl,loop->left);
1504 /*-----------------------------------------------------------------*/
1505 /* replLoopSym - replace the loop sym by loop sym -1 */
1506 /*-----------------------------------------------------------------*/
1507 static void replLoopSym ( ast *body, symbol *sym)
1510 if (!body || IS_AST_LINK(body))
1513 if (IS_AST_SYM_VALUE(body)) {
1515 if (isSymbolEqual(AST_SYMBOL(body),sym)) {
1518 body->opval.op = '-';
1519 body->left = newAst_VALUE(symbolVal(sym));
1520 body->right= newAst_VALUE(constVal("1"));
1528 replLoopSym(body->left,sym);
1529 replLoopSym(body->right,sym);
1533 /*-----------------------------------------------------------------*/
1534 /* reverseLoop - do the actual loop reversal */
1535 /*-----------------------------------------------------------------*/
1536 ast *reverseLoop (ast *loop, symbol *sym, ast *init, ast *end)
1540 /* create the following tree
1545 if (sym) goto for_continue ;
1548 /* put it together piece by piece */
1549 rloop = newNode (NULLOP,
1550 createIf(newAst_VALUE(symbolVal(sym)),
1552 newAst_VALUE(symbolVal(AST_FOR(loop,continueLabel))),
1555 newAst_VALUE(symbolVal(sym)),
1558 replLoopSym(loop->left, sym);
1560 rloop = newNode(NULLOP,
1562 newAst_VALUE(symbolVal(sym)),
1563 newNode('-',end,init)),
1564 createLabel(AST_FOR(loop,continueLabel),
1569 newAst_VALUE(symbolVal(sym)),
1570 newAst_VALUE(constVal("1"))),
1573 return decorateType(rloop);
1577 #define DEMAND_INTEGER_PROMOTION
1579 #ifdef DEMAND_INTEGER_PROMOTION
1581 /*-----------------------------------------------------------------*/
1582 /* walk a tree looking for the leaves. Add a typecast to the given */
1583 /* type to each value leaf node. */
1584 /*-----------------------------------------------------------------*/
1585 void pushTypeCastToLeaves(sym_link *type, ast *node, ast **parentPtr)
1589 /* WTF? We should never get here. */
1593 if (!node->left && !node->right)
1595 /* We're at a leaf; if it's a value, apply the typecast */
1596 if (node->type == EX_VALUE && IS_INTEGRAL(TTYPE(node)))
1598 *parentPtr = decorateType(newNode(CAST,
1599 newAst_LINK(copyLinkChain(type)),
1607 pushTypeCastToLeaves(type, node->left, &(node->left));
1611 pushTypeCastToLeaves(type, node->right, &(node->right));
1618 /*-----------------------------------------------------------------*/
1619 /* Given an assignment operation in a tree, determine if the LHS */
1620 /* (the result) has a different (integer) type than the RHS. */
1621 /* If so, walk the RHS and add a typecast to the type of the LHS */
1622 /* to all leaf nodes. */
1623 /*-----------------------------------------------------------------*/
1624 void propAsgType(ast *tree)
1626 #ifdef DEMAND_INTEGER_PROMOTION
1627 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree)))
1629 /* Nothing to do here... */
1633 if (getSize(LTYPE(tree)) > getSize(RTYPE(tree)))
1635 pushTypeCastToLeaves(LTYPE(tree), tree->right, &(tree->right));
1642 /*-----------------------------------------------------------------*/
1643 /* decorateType - compute type for this tree also does type cheking*/
1644 /* this is done bottom up, since type have to flow upwards*/
1645 /* it also does constant folding, and paramater checking */
1646 /*-----------------------------------------------------------------*/
1647 ast *decorateType (ast *tree)
1655 /* if already has type then do nothing */
1656 if ( tree->decorated )
1659 tree->decorated = 1;
1661 /* print the line */
1662 /* if not block & function */
1663 if ( tree->type == EX_OP &&
1664 ( tree->opval.op != FUNCTION &&
1665 tree->opval.op != BLOCK &&
1666 tree->opval.op != NULLOP )) {
1667 filename = tree->filename ;
1668 lineno = tree->lineno ;
1671 /* if any child is an error | this one is an error do nothing */
1672 if ( tree->isError ||
1673 ( tree->left && tree->left->isError) ||
1674 ( tree->right && tree->right->isError ))
1677 /*------------------------------------------------------------------*/
1678 /*----------------------------*/
1679 /* leaf has been reached */
1680 /*----------------------------*/
1681 /* if this is of type value */
1682 /* just get the type */
1683 if ( tree->type == EX_VALUE ) {
1685 if ( IS_LITERAL(tree->opval.val->etype) ) {
1687 /* if this is a character array then declare it */
1688 if (IS_ARRAY(tree->opval.val->type))
1689 tree->opval.val = stringToSymbol(tree->opval.val);
1691 /* otherwise just copy the type information */
1692 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.val->type);
1693 if (funcInChain(tree->opval.val->type)) {
1694 tree->hasVargs = tree->opval.val->sym->hasVargs;
1695 tree->args = copyValueChain(tree->opval.val->sym->args) ;
1700 if ( tree->opval.val->sym ) {
1701 /* if the undefined flag is set then give error message */
1702 if (tree->opval.val->sym->undefined ) {
1703 werror(E_ID_UNDEF,tree->opval.val->sym->name) ;
1705 TTYPE(tree) = TETYPE(tree) =
1706 tree->opval.val->type = tree->opval.val->sym->type =
1707 tree->opval.val->etype = tree->opval.val->sym->etype =
1708 copyLinkChain(INTTYPE);
1712 /* if impilicit i.e. struct/union member then no type */
1713 if (tree->opval.val->sym->implicit )
1714 TTYPE(tree) = TETYPE(tree) = NULL ;
1718 /* else copy the type */
1719 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.val->type);
1721 /* and mark it as referenced */
1722 tree->opval.val->sym->isref = 1;
1723 /* if this is of type function or function pointer */
1724 if (funcInChain(tree->opval.val->type)) {
1725 tree->hasVargs = tree->opval.val->sym->hasVargs;
1726 tree->args = copyValueChain(tree->opval.val->sym->args) ;
1736 /* if type link for the case of cast */
1737 if ( tree->type == EX_LINK ) {
1738 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.lnk);
1745 dtl = decorateType (tree->left);
1746 dtr = decorateType (tree->right);
1748 /* this is to take care of situations
1749 when the tree gets rewritten */
1750 if (dtl != tree->left)
1752 if (dtr != tree->right)
1756 /* depending on type of operator do */
1758 switch (tree->opval.op) {
1759 /*------------------------------------------------------------------*/
1760 /*----------------------------*/
1762 /*----------------------------*/
1765 /* determine which is the array & which the index */
1766 if ((IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree))) && IS_INTEGRAL(LTYPE(tree))) {
1768 ast *tempTree = tree->left ;
1769 tree->left = tree->right ;
1770 tree->right= tempTree ;
1773 /* first check if this is a array or a pointer */
1774 if ( (!IS_ARRAY(LTYPE(tree))) && (!IS_PTR(LTYPE(tree)))) {
1775 werror(E_NEED_ARRAY_PTR,"[]");
1776 goto errorTreeReturn ;
1779 /* check if the type of the idx */
1780 if (!IS_INTEGRAL(RTYPE(tree))) {
1781 werror(E_IDX_NOT_INT);
1782 goto errorTreeReturn ;
1785 /* if the left is an rvalue then error */
1787 werror(E_LVALUE_REQUIRED,"array access");
1788 goto errorTreeReturn ;
1791 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree)->next);
1794 /*------------------------------------------------------------------*/
1795 /*----------------------------*/
1797 /*----------------------------*/
1799 /* if this is not a structure */
1800 if (!IS_STRUCT(LTYPE(tree))) {
1801 werror(E_STRUCT_UNION,".");
1802 goto errorTreeReturn ;
1804 TTYPE(tree) = structElemType (LTYPE(tree),
1805 (tree->right->type == EX_VALUE ?
1806 tree->right->opval.val : NULL ),&tree->args);
1807 TETYPE(tree) = getSpec(TTYPE(tree));
1810 /*------------------------------------------------------------------*/
1811 /*----------------------------*/
1812 /* struct/union pointer */
1813 /*----------------------------*/
1815 /* if not pointer to a structure */
1816 if (!IS_PTR(LTYPE(tree))) {
1818 goto errorTreeReturn ;
1821 if (!IS_STRUCT(LTYPE(tree)->next)) {
1822 werror(E_STRUCT_UNION,"->");
1823 goto errorTreeReturn ;
1826 TTYPE(tree) = structElemType (LTYPE(tree)->next,
1827 (tree->right->type == EX_VALUE ?
1828 tree->right->opval.val : NULL ),&tree->args);
1829 TETYPE(tree) = getSpec(TTYPE(tree));
1832 /*------------------------------------------------------------------*/
1833 /*----------------------------*/
1834 /* ++/-- operation */
1835 /*----------------------------*/
1836 case INC_OP: /* incerement operator unary so left only */
1839 sym_link *ltc = (tree->right ? RTYPE(tree) : LTYPE(tree) );
1840 COPYTYPE(TTYPE(tree),TETYPE(tree),ltc);
1841 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
1842 werror(E_CODE_WRITE,"++/--");
1851 /*------------------------------------------------------------------*/
1852 /*----------------------------*/
1854 /*----------------------------*/
1855 case '&': /* can be unary */
1856 /* if right is NULL then unary operation */
1857 if ( tree->right ) /* not an unary operation */ {
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 ;
1869 /* if they are both literal */
1870 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1871 tree->type = EX_VALUE ;
1872 tree->opval.val = valBitwise (valFromType(LETYPE(tree)),
1873 valFromType(RETYPE(tree)),'&');
1875 tree->right = tree->left = NULL;
1876 TETYPE(tree) = tree->opval.val->etype ;
1877 TTYPE(tree) = tree->opval.val->type;
1881 /* see if this is a GETHBIT operation if yes
1884 ast *otree = optimizeGetHbit(tree);
1887 return decorateType(otree);
1890 /* if right or left is literal then result of that type*/
1891 if (IS_LITERAL(RTYPE(tree))) {
1893 TTYPE(tree) = copyLinkChain(RTYPE(tree));
1894 TETYPE(tree) = getSpec(TTYPE(tree));
1895 SPEC_SCLS(TETYPE(tree)) = S_AUTO;
1898 if (IS_LITERAL(LTYPE(tree))) {
1899 TTYPE(tree) = copyLinkChain(LTYPE(tree));
1900 TETYPE(tree) = getSpec(TTYPE(tree));
1901 SPEC_SCLS(TETYPE(tree)) = S_AUTO;
1906 computeType (LTYPE(tree), RTYPE(tree));
1907 TETYPE(tree) = getSpec(TTYPE(tree));
1910 LRVAL(tree) = RRVAL(tree) = 1;
1914 /*------------------------------------------------------------------*/
1915 /*----------------------------*/
1917 /*----------------------------*/
1919 p->class = DECLARATOR;
1920 /* if bit field then error */
1921 if (IS_BITVAR(tree->left->etype)) {
1922 werror (E_ILLEGAL_ADDR,"addrress of bit variable");
1923 goto errorTreeReturn ;
1926 if (SPEC_SCLS(tree->left->etype)== S_REGISTER ) {
1927 werror (E_ILLEGAL_ADDR,"address of register variable");
1928 goto errorTreeReturn;
1931 if (IS_FUNC(LTYPE(tree))) {
1932 werror(E_ILLEGAL_ADDR,"address of function");
1933 goto errorTreeReturn ;
1937 werror(E_LVALUE_REQUIRED,"address of");
1938 goto errorTreeReturn ;
1940 if (SPEC_SCLS(tree->left->etype) == S_CODE) {
1941 DCL_TYPE(p) = CPOINTER ;
1942 DCL_PTR_CONST(p) = port->mem.code_ro;
1945 if (SPEC_SCLS(tree->left->etype) == S_XDATA)
1946 DCL_TYPE(p) = FPOINTER;
1948 if (SPEC_SCLS(tree->left->etype) == S_XSTACK )
1949 DCL_TYPE(p) = PPOINTER ;
1951 if (SPEC_SCLS(tree->left->etype) == S_IDATA)
1952 DCL_TYPE(p) = IPOINTER ;
1954 if (SPEC_SCLS(tree->left->etype) == S_EEPROM)
1955 DCL_TYPE(p) = EEPPOINTER ;
1957 DCL_TYPE(p) = POINTER ;
1959 if (IS_AST_SYM_VALUE(tree->left)) {
1960 AST_SYMBOL(tree->left)->addrtaken = 1;
1961 AST_SYMBOL(tree->left)->allocreq = 1;
1964 p->next = LTYPE(tree);
1966 TETYPE(tree) = getSpec(TTYPE(tree));
1967 DCL_PTR_CONST(p) = SPEC_CONST(TETYPE(tree));
1968 DCL_PTR_VOLATILE(p) = SPEC_VOLATILE(TETYPE(tree));
1973 /*------------------------------------------------------------------*/
1974 /*----------------------------*/
1976 /*----------------------------*/
1978 /* if the rewrite succeeds then don't go any furthur */
1980 ast *wtree = optimizeRRCRLC ( tree );
1982 return decorateType(wtree) ;
1984 /*------------------------------------------------------------------*/
1985 /*----------------------------*/
1987 /*----------------------------*/
1989 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1990 werror(E_BITWISE_OP);
1991 werror(E_CONTINUE,"left & right types are ");
1992 printTypeChain(LTYPE(tree),stderr);
1993 fprintf(stderr,",");
1994 printTypeChain(RTYPE(tree),stderr);
1995 fprintf(stderr,"\n");
1996 goto errorTreeReturn ;
1999 /* if they are both literal then */
2000 /* rewrite the tree */
2001 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2002 tree->type = EX_VALUE ;
2003 tree->opval.val = valBitwise (valFromType(LETYPE(tree)),
2004 valFromType(RETYPE(tree)),
2006 tree->right = tree->left = NULL;
2007 TETYPE(tree) = tree->opval.val->etype;
2008 TTYPE(tree) = tree->opval.val->type;
2011 LRVAL(tree) = RRVAL(tree) = 1;
2012 TETYPE(tree) = getSpec (TTYPE(tree) =
2013 computeType(LTYPE(tree),
2016 /*------------------------------------------------------------------*/
2017 /*----------------------------*/
2019 /*----------------------------*/
2021 if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) {
2022 werror(E_INVALID_OP,"divide");
2023 goto errorTreeReturn ;
2025 /* if they are both literal then */
2026 /* rewrite the tree */
2027 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2028 tree->type = EX_VALUE ;
2029 tree->opval.val = valDiv (valFromType(LETYPE(tree)),
2030 valFromType(RETYPE(tree)));
2031 tree->right = tree->left = NULL;
2032 TETYPE(tree) = getSpec(TTYPE(tree) =
2033 tree->opval.val->type);
2036 LRVAL(tree) = RRVAL(tree) = 1;
2037 TETYPE(tree) = getSpec (TTYPE(tree) =
2038 computeType(LTYPE(tree),
2042 /*------------------------------------------------------------------*/
2043 /*----------------------------*/
2045 /*----------------------------*/
2047 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
2048 werror(E_BITWISE_OP);
2049 werror(E_CONTINUE,"left & right types are ");
2050 printTypeChain(LTYPE(tree),stderr);
2051 fprintf(stderr,",");
2052 printTypeChain(RTYPE(tree),stderr);
2053 fprintf(stderr,"\n");
2054 goto errorTreeReturn ;
2056 /* if they are both literal then */
2057 /* rewrite the tree */
2058 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2059 tree->type = EX_VALUE ;
2060 tree->opval.val = valMod (valFromType(LETYPE(tree)),
2061 valFromType(RETYPE(tree)));
2062 tree->right = tree->left = NULL;
2063 TETYPE(tree) = getSpec(TTYPE(tree) =
2064 tree->opval.val->type);
2067 LRVAL(tree) = RRVAL(tree) = 1;
2068 TETYPE(tree) = getSpec (TTYPE(tree) =
2069 computeType(LTYPE(tree),
2073 /*------------------------------------------------------------------*/
2074 /*----------------------------*/
2075 /* address dereference */
2076 /*----------------------------*/
2077 case '*': /* can be unary : if right is null then unary operation */
2078 if ( ! tree->right ) {
2079 if (!IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) {
2081 goto errorTreeReturn ;
2085 werror(E_LVALUE_REQUIRED,"pointer deref");
2086 goto errorTreeReturn ;
2088 TTYPE(tree) = copyLinkChain ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) ?
2089 LTYPE(tree)->next : NULL );
2090 TETYPE(tree) = getSpec(TTYPE(tree));
2091 tree->args = tree->left->args ;
2092 tree->hasVargs = tree->left->hasVargs ;
2093 SPEC_CONST(TETYPE(tree)) = DCL_PTR_CONST(LTYPE(tree));
2097 /*------------------------------------------------------------------*/
2098 /*----------------------------*/
2099 /* multiplication */
2100 /*----------------------------*/
2101 if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) {
2102 werror(E_INVALID_OP,"multiplication");
2103 goto errorTreeReturn ;
2106 /* if they are both literal then */
2107 /* rewrite the tree */
2108 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2109 tree->type = EX_VALUE ;
2110 tree->opval.val = valMult (valFromType(LETYPE(tree)),
2111 valFromType(RETYPE(tree)));
2112 tree->right = tree->left = NULL;
2113 TETYPE(tree) = getSpec(TTYPE(tree) =
2114 tree->opval.val->type);
2118 /* if left is a literal exchange left & right */
2119 if (IS_LITERAL(LTYPE(tree))) {
2120 ast *tTree = tree->left ;
2121 tree->left = tree->right ;
2122 tree->right= tTree ;
2125 LRVAL(tree) = RRVAL(tree) = 1;
2126 TETYPE(tree) = getSpec (TTYPE(tree) =
2127 computeType(LTYPE(tree),
2131 /*------------------------------------------------------------------*/
2132 /*----------------------------*/
2133 /* unary '+' operator */
2134 /*----------------------------*/
2137 if ( ! tree->right ) {
2138 if (!IS_INTEGRAL(LTYPE(tree))) {
2139 werror(E_UNARY_OP,'+');
2140 goto errorTreeReturn ;
2143 /* if left is a literal then do it */
2144 if (IS_LITERAL(LTYPE(tree))) {
2145 tree->type = EX_VALUE ;
2146 tree->opval.val = valFromType(LETYPE(tree));
2148 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2152 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2156 /*------------------------------------------------------------------*/
2157 /*----------------------------*/
2159 /*----------------------------*/
2161 /* this is not a unary operation */
2162 /* if both pointers then problem */
2163 if ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) &&
2164 (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)))) {
2165 werror(E_PTR_PLUS_PTR);
2166 goto errorTreeReturn ;
2169 if (!IS_ARITHMETIC(LTYPE(tree)) &&
2170 !IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) {
2171 werror(E_PLUS_INVALID,"+");
2172 goto errorTreeReturn ;
2175 if (!IS_ARITHMETIC(RTYPE(tree)) &&
2176 !IS_PTR(RTYPE(tree)) && !IS_ARRAY(RTYPE(tree))) {
2177 werror(E_PLUS_INVALID,"+");
2178 goto errorTreeReturn;
2180 /* if they are both literal then */
2181 /* rewrite the tree */
2182 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2183 tree->type = EX_VALUE ;
2184 tree->opval.val = valPlus (valFromType(LETYPE(tree)),
2185 valFromType(RETYPE(tree)));
2186 tree->right = tree->left = NULL;
2187 TETYPE(tree) = getSpec(TTYPE(tree) =
2188 tree->opval.val->type);
2192 /* if the right is a pointer or left is a literal
2193 xchange left & right */
2194 if (IS_ARRAY(RTYPE(tree)) ||
2195 IS_PTR(RTYPE(tree)) ||
2196 IS_LITERAL(LTYPE(tree))) {
2197 ast *tTree = tree->left ;
2198 tree->left = tree->right ;
2199 tree->right= tTree ;
2202 LRVAL(tree) = RRVAL(tree) = 1;
2203 /* if the left is a pointer */
2204 if (IS_PTR(LTYPE(tree)))
2205 TETYPE(tree) = getSpec(TTYPE(tree) =
2208 TETYPE(tree) = getSpec(TTYPE(tree) =
2209 computeType(LTYPE(tree),
2213 /*------------------------------------------------------------------*/
2214 /*----------------------------*/
2216 /*----------------------------*/
2217 case '-' : /* can be unary */
2218 /* if right is null then unary */
2219 if ( ! tree->right ) {
2221 if (!IS_ARITHMETIC(LTYPE(tree))) {
2222 werror(E_UNARY_OP,tree->opval.op);
2223 goto errorTreeReturn ;
2226 /* if left is a literal then do it */
2227 if (IS_LITERAL(LTYPE(tree))) {
2228 tree->type = EX_VALUE ;
2229 tree->opval.val = valUnaryPM(valFromType(LETYPE(tree)));
2231 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2235 TTYPE(tree) = LTYPE(tree);
2239 /*------------------------------------------------------------------*/
2240 /*----------------------------*/
2242 /*----------------------------*/
2244 if (!(IS_PTR(LTYPE(tree)) ||
2245 IS_ARRAY(LTYPE(tree)) ||
2246 IS_ARITHMETIC(LTYPE(tree)))) {
2247 werror(E_PLUS_INVALID,"-");
2248 goto errorTreeReturn ;
2251 if (!(IS_PTR(RTYPE(tree)) ||
2252 IS_ARRAY(RTYPE(tree)) ||
2253 IS_ARITHMETIC(RTYPE(tree)))) {
2254 werror(E_PLUS_INVALID,"-");
2255 goto errorTreeReturn ;
2258 if ( (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) &&
2259 ! (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)) ||
2260 IS_INTEGRAL(RTYPE(tree))) ) {
2261 werror(E_PLUS_INVALID,"-");
2262 goto errorTreeReturn ;
2265 /* if they are both literal then */
2266 /* rewrite the tree */
2267 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2268 tree->type = EX_VALUE ;
2269 tree->opval.val = valMinus (valFromType(LETYPE(tree)),
2270 valFromType(RETYPE(tree)));
2271 tree->right = tree->left = NULL;
2272 TETYPE(tree) = getSpec(TTYPE(tree) =
2273 tree->opval.val->type);
2277 /* if the left & right are equal then zero */
2278 if (isAstEqual(tree->left,tree->right)) {
2279 tree->type = EX_VALUE;
2280 tree->left = tree->right = NULL;
2281 tree->opval.val = constVal("0");
2282 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2286 /* if both of them are pointers or arrays then */
2287 /* the result is going to be an integer */
2288 if (( IS_ARRAY(LTYPE(tree)) || IS_PTR(LTYPE(tree))) &&
2289 ( IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree))))
2290 TETYPE(tree) = TTYPE(tree) = newIntLink();
2292 /* if only the left is a pointer */
2293 /* then result is a pointer */
2294 if (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree)))
2295 TETYPE(tree) = getSpec(TTYPE(tree) =
2298 TETYPE(tree) = getSpec (TTYPE(tree) =
2299 computeType(LTYPE(tree),
2301 LRVAL(tree) = RRVAL(tree) = 1;
2304 /*------------------------------------------------------------------*/
2305 /*----------------------------*/
2307 /*----------------------------*/
2309 /* can be only integral type */
2310 if (!IS_INTEGRAL(LTYPE(tree))) {
2311 werror(E_UNARY_OP,tree->opval.op);
2312 goto errorTreeReturn ;
2315 /* if left is a literal then do it */
2316 if (IS_LITERAL(LTYPE(tree))) {
2317 tree->type = EX_VALUE ;
2318 tree->opval.val = valComplement(valFromType(LETYPE(tree)));
2320 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2324 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2327 /*------------------------------------------------------------------*/
2328 /*----------------------------*/
2330 /*----------------------------*/
2332 /* can be pointer */
2333 if (!IS_ARITHMETIC(LTYPE(tree)) &&
2334 !IS_PTR(LTYPE(tree)) &&
2335 !IS_ARRAY(LTYPE(tree))) {
2336 werror(E_UNARY_OP,tree->opval.op);
2337 goto errorTreeReturn ;
2340 /* if left is a literal then do it */
2341 if (IS_LITERAL(LTYPE(tree))) {
2342 tree->type = EX_VALUE ;
2343 tree->opval.val = valNot(valFromType(LETYPE(tree)));
2345 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2349 TTYPE(tree) = TETYPE(tree) = newCharLink();
2352 /*------------------------------------------------------------------*/
2353 /*----------------------------*/
2355 /*----------------------------*/
2358 TTYPE(tree) = LTYPE(tree);
2359 TETYPE(tree) = LETYPE(tree);
2363 TTYPE(tree) = TETYPE(tree) = newCharLink();
2368 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(tree->left->etype)) {
2369 werror(E_SHIFT_OP_INVALID);
2370 werror(E_CONTINUE,"left & right types are ");
2371 printTypeChain(LTYPE(tree),stderr);
2372 fprintf(stderr,",");
2373 printTypeChain(RTYPE(tree),stderr);
2374 fprintf(stderr,"\n");
2375 goto errorTreeReturn ;
2378 /* if they are both literal then */
2379 /* rewrite the tree */
2380 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2381 tree->type = EX_VALUE ;
2382 tree->opval.val = valShift (valFromType(LETYPE(tree)),
2383 valFromType(RETYPE(tree)),
2384 (tree->opval.op == LEFT_OP ? 1 : 0));
2385 tree->right = tree->left = NULL;
2386 TETYPE(tree) = getSpec(TTYPE(tree) =
2387 tree->opval.val->type);
2390 /* if only the right side is a literal & we are
2391 shifting more than size of the left operand then zero */
2392 if (IS_LITERAL(RTYPE(tree)) &&
2393 ((unsigned)floatFromVal( valFromType(RETYPE(tree)))) >=
2394 (getSize(LTYPE(tree))*8)) {
2395 werror(W_SHIFT_CHANGED,
2396 (tree->opval.op == LEFT_OP ? "left" : "right"));
2397 tree->type = EX_VALUE;
2398 tree->left = tree->right = NULL;
2399 tree->opval.val = constVal("0");
2400 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2403 LRVAL(tree) = RRVAL(tree) = 1;
2404 if (IS_LITERAL(LTYPE(tree)) && !IS_LITERAL(RTYPE(tree))) {
2405 COPYTYPE(TTYPE(tree),TETYPE(tree),RTYPE(tree));
2407 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2411 /*------------------------------------------------------------------*/
2412 /*----------------------------*/
2414 /*----------------------------*/
2415 case CAST: /* change the type */
2416 /* cannot cast to an aggregate type */
2417 if (IS_AGGREGATE(LTYPE(tree))) {
2418 werror(E_CAST_ILLEGAL);
2419 goto errorTreeReturn ;
2422 /* if the right is a literal replace the tree */
2423 if (IS_LITERAL(RETYPE(tree)) && !IS_PTR(LTYPE(tree))) {
2424 tree->type = EX_VALUE ;
2426 valCastLiteral(LTYPE(tree),
2427 floatFromVal(valFromType(RETYPE(tree))));
2430 TTYPE(tree) = tree->opval.val->type;
2431 tree->values.literalFromCast = 1;
2434 TTYPE(tree) = LTYPE(tree);
2438 TETYPE(tree) = getSpec(TTYPE(tree));
2442 /*------------------------------------------------------------------*/
2443 /*----------------------------*/
2444 /* logical &&, || */
2445 /*----------------------------*/
2448 /* each must me arithmetic type or be a pointer */
2449 if (!IS_PTR(LTYPE(tree)) &&
2450 !IS_ARRAY(LTYPE(tree)) &&
2451 !IS_INTEGRAL(LTYPE(tree))) {
2452 werror(E_COMPARE_OP);
2453 goto errorTreeReturn ;
2456 if (!IS_PTR(RTYPE(tree)) &&
2457 !IS_ARRAY(RTYPE(tree)) &&
2458 !IS_INTEGRAL(RTYPE(tree))) {
2459 werror(E_COMPARE_OP);
2460 goto errorTreeReturn ;
2462 /* if they are both literal then */
2463 /* rewrite the tree */
2464 if (IS_LITERAL(RTYPE(tree)) &&
2465 IS_LITERAL(LTYPE(tree))) {
2466 tree->type = EX_VALUE ;
2467 tree->opval.val = valLogicAndOr (valFromType(LETYPE(tree)),
2468 valFromType(RETYPE(tree)),
2470 tree->right = tree->left = NULL;
2471 TETYPE(tree) = getSpec(TTYPE(tree) =
2472 tree->opval.val->type);
2475 LRVAL(tree) = RRVAL(tree) = 1;
2476 TTYPE(tree) = TETYPE(tree) = newCharLink();
2479 /*------------------------------------------------------------------*/
2480 /*----------------------------*/
2481 /* comparison operators */
2482 /*----------------------------*/
2490 ast *lt = optimizeCompare(tree);
2496 /* if they are pointers they must be castable */
2497 if ( IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree))) {
2498 if (checkType(LTYPE(tree),RTYPE(tree)) == 0) {
2499 werror(E_COMPARE_OP);
2500 fprintf(stderr,"comparing type ");
2501 printTypeChain(LTYPE(tree),stderr);
2502 fprintf(stderr,"to type ");
2503 printTypeChain(RTYPE(tree),stderr);
2504 fprintf(stderr,"\n");
2505 goto errorTreeReturn ;
2508 /* else they should be promotable to one another */
2510 if (!( ( IS_PTR(LTYPE(tree)) && IS_LITERAL(RTYPE(tree))) ||
2511 ( IS_PTR(RTYPE(tree)) && IS_LITERAL(LTYPE(tree)))))
2513 if (checkType (LTYPE(tree),RTYPE(tree)) == 0 ) {
2514 werror(E_COMPARE_OP);
2515 fprintf(stderr,"comparing type ");
2516 printTypeChain(LTYPE(tree),stderr);
2517 fprintf(stderr,"to type ");
2518 printTypeChain(RTYPE(tree),stderr);
2519 fprintf(stderr,"\n");
2520 goto errorTreeReturn ;
2524 /* if they are both literal then */
2525 /* rewrite the tree */
2526 if (IS_LITERAL(RTYPE(tree)) &&
2527 IS_LITERAL(LTYPE(tree))) {
2528 tree->type = EX_VALUE ;
2529 tree->opval.val = valCompare (valFromType(LETYPE(tree)),
2530 valFromType(RETYPE(tree)),
2532 tree->right = tree->left = NULL;
2533 TETYPE(tree) = getSpec(TTYPE(tree) =
2534 tree->opval.val->type);
2537 LRVAL(tree) = RRVAL(tree) = 1;
2538 TTYPE(tree) = TETYPE(tree) = newCharLink();
2541 /*------------------------------------------------------------------*/
2542 /*----------------------------*/
2544 /*----------------------------*/
2545 case SIZEOF : /* evaluate wihout code generation */
2546 /* change the type to a integer */
2547 tree->type = EX_VALUE;
2548 sprintf(buffer,"%d",(getSize(tree->right->ftype)));
2549 tree->opval.val = constVal(buffer);
2550 tree->right = tree->left = NULL;
2551 TETYPE(tree) = getSpec(TTYPE(tree) =
2552 tree->opval.val->type);
2555 /*------------------------------------------------------------------*/
2556 /*----------------------------*/
2557 /* conditional operator '?' */
2558 /*----------------------------*/
2560 /* the type is one on the left */
2561 TTYPE(tree) = LTYPE(tree);
2562 TETYPE(tree)= getSpec (TTYPE(tree));
2566 /* if they don't match we have a problem */
2567 if (checkType( LTYPE(tree), RTYPE(tree)) == 0) {
2568 werror(E_TYPE_MISMATCH,"conditional operator"," ");
2569 goto errorTreeReturn ;
2572 TTYPE(tree) = computeType(LTYPE(tree),RTYPE(tree));
2573 TETYPE(tree)= getSpec(TTYPE(tree));
2577 /*------------------------------------------------------------------*/
2578 /*----------------------------*/
2579 /* assignment operators */
2580 /*----------------------------*/
2583 /* for these it must be both must be integral */
2584 if (!IS_ARITHMETIC(LTYPE(tree)) ||
2585 !IS_ARITHMETIC(RTYPE(tree))) {
2586 werror (E_OPS_INTEGRAL);
2587 goto errorTreeReturn ;
2590 TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree));
2592 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2593 werror(E_CODE_WRITE," ");
2596 werror(E_LVALUE_REQUIRED,"*= or /=");
2597 goto errorTreeReturn ;
2610 /* for these it must be both must be integral */
2611 if (!IS_INTEGRAL(LTYPE(tree)) ||
2612 !IS_INTEGRAL(RTYPE(tree))) {
2613 werror (E_OPS_INTEGRAL);
2614 goto errorTreeReturn ;
2617 TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree));
2619 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2620 werror(E_CODE_WRITE," ");
2623 werror(E_LVALUE_REQUIRED,"&= or |= or ^= or >>= or <<=");
2624 goto errorTreeReturn ;
2632 /*------------------------------------------------------------------*/
2633 /*----------------------------*/
2635 /*----------------------------*/
2637 if (!(IS_PTR(LTYPE(tree)) ||
2638 IS_ARITHMETIC(LTYPE(tree)))) {
2639 werror(E_PLUS_INVALID,"-=");
2640 goto errorTreeReturn ;
2643 if (!(IS_PTR(RTYPE(tree)) ||
2644 IS_ARITHMETIC(RTYPE(tree)))) {
2645 werror(E_PLUS_INVALID,"-=");
2646 goto errorTreeReturn ;
2649 TETYPE(tree) = getSpec (TTYPE(tree) =
2650 computeType(LTYPE(tree),
2653 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2654 werror(E_CODE_WRITE," ");
2657 werror(E_LVALUE_REQUIRED,"-=");
2658 goto errorTreeReturn ;
2666 /*------------------------------------------------------------------*/
2667 /*----------------------------*/
2669 /*----------------------------*/
2671 /* this is not a unary operation */
2672 /* if both pointers then problem */
2673 if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) ) {
2674 werror(E_PTR_PLUS_PTR);
2675 goto errorTreeReturn ;
2678 if (!IS_ARITHMETIC(LTYPE(tree)) && !IS_PTR(LTYPE(tree))) {
2679 werror(E_PLUS_INVALID,"+=");
2680 goto errorTreeReturn ;
2683 if (!IS_ARITHMETIC(RTYPE(tree)) && !IS_PTR(RTYPE(tree))) {
2684 werror(E_PLUS_INVALID,"+=");
2685 goto errorTreeReturn;
2688 TETYPE(tree) = getSpec (TTYPE(tree) =
2689 computeType(LTYPE(tree),
2692 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2693 werror(E_CODE_WRITE," ");
2696 werror(E_LVALUE_REQUIRED,"+=");
2697 goto errorTreeReturn ;
2700 tree->right = decorateType(newNode('+',copyAst(tree->left),tree->right));
2701 tree->opval.op = '=';
2707 /*------------------------------------------------------------------*/
2708 /*----------------------------*/
2709 /* straight assignemnt */
2710 /*----------------------------*/
2712 /* cannot be an aggregate */
2713 if (IS_AGGREGATE(LTYPE(tree))) {
2714 werror(E_AGGR_ASSIGN);
2715 goto errorTreeReturn;
2718 /* they should either match or be castable */
2719 if (checkType (LTYPE(tree),RTYPE(tree)) == 0) {
2720 werror(E_TYPE_MISMATCH,"assignment"," ");
2721 fprintf(stderr,"type --> '");
2722 printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' ");
2723 fprintf(stderr,"assigned to type --> '");
2724 printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n");
2725 goto errorTreeReturn ;
2728 /* if the left side of the tree is of type void
2729 then report error */
2730 if (IS_VOID(LTYPE(tree))) {
2731 werror(E_CAST_ZERO);
2732 fprintf(stderr,"type --> '");
2733 printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' ");
2734 fprintf(stderr,"assigned to type --> '");
2735 printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n");
2738 /* extra checks for pointer types */
2739 if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) &&
2740 !IS_GENPTR(LTYPE(tree))) {
2741 if (DCL_TYPE(LTYPE(tree)) != DCL_TYPE(RTYPE(tree)))
2742 werror(W_PTR_ASSIGN);
2745 TETYPE(tree) = getSpec(TTYPE(tree) =
2749 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2750 werror(E_CODE_WRITE," ");
2753 werror(E_LVALUE_REQUIRED,"=");
2754 goto errorTreeReturn ;
2761 /*------------------------------------------------------------------*/
2762 /*----------------------------*/
2763 /* comma operator */
2764 /*----------------------------*/
2766 TETYPE(tree) = getSpec(TTYPE(tree) = RTYPE(tree));
2769 /*------------------------------------------------------------------*/
2770 /*----------------------------*/
2772 /*----------------------------*/
2776 if (processParms (tree->left,
2778 tree->right,&parmNumber,TRUE))
2779 goto errorTreeReturn ;
2781 if (options.stackAuto || IS_RENT(LETYPE(tree))) {
2782 tree->left->args = reverseVal(tree->left->args);
2783 reverseParms(tree->right);
2786 tree->args = tree->left->args ;
2787 TETYPE(tree) = getSpec (TTYPE(tree) = LTYPE(tree)->next);
2790 /*------------------------------------------------------------------*/
2791 /*----------------------------*/
2792 /* return statement */
2793 /*----------------------------*/
2798 if (checkType(currFunc->type->next,RTYPE(tree)) == 0) {
2799 werror(E_RETURN_MISMATCH);
2800 goto errorTreeReturn ;
2803 if (IS_VOID(currFunc->type->next)
2805 !IS_VOID(RTYPE(tree))) {
2806 werror(E_FUNC_VOID);
2807 goto errorTreeReturn ;
2810 /* if there is going to be a casing required then add it */
2811 if (checkType(currFunc->type->next,RTYPE(tree)) < 0 )
2813 #if 0 && defined DEMAND_INTEGER_PROMOTION
2814 if (IS_INTEGRAL(currFunc->type->next))
2816 pushTypeCastToLeaves(currFunc->type->next, tree->right, &(tree->right));
2822 decorateType(newNode(CAST,
2823 newAst_LINK(copyLinkChain(currFunc->type->next)),
2833 if (!IS_VOID(currFunc->type->next) && tree->right == NULL ) {
2834 werror(E_VOID_FUNC,currFunc->name);
2835 goto errorTreeReturn ;
2838 TTYPE(tree) = TETYPE(tree) = NULL ;
2841 /*------------------------------------------------------------------*/
2842 /*----------------------------*/
2843 /* switch statement */
2844 /*----------------------------*/
2846 /* the switch value must be an integer */
2847 if (!IS_INTEGRAL(LTYPE(tree))) {
2848 werror (E_SWITCH_NON_INTEGER);
2849 goto errorTreeReturn ;
2852 TTYPE(tree) = TETYPE(tree) = NULL ;
2855 /*------------------------------------------------------------------*/
2856 /*----------------------------*/
2858 /*----------------------------*/
2860 tree->left = backPatchLabels(tree->left,
2863 TTYPE(tree) = TETYPE(tree) = NULL;
2866 /*------------------------------------------------------------------*/
2867 /*----------------------------*/
2869 /*----------------------------*/
2872 decorateType(resolveSymbols(AST_FOR(tree,initExpr)));
2873 decorateType(resolveSymbols(AST_FOR(tree,condExpr)));
2874 decorateType(resolveSymbols(AST_FOR(tree,loopExpr)));
2876 /* if the for loop is reversible then
2877 reverse it otherwise do what we normally
2883 if (isLoopReversible (tree,&sym,&init,&end))
2884 return reverseLoop (tree,sym,init,end);
2886 return decorateType(createFor ( AST_FOR(tree,trueLabel),
2887 AST_FOR(tree,continueLabel) ,
2888 AST_FOR(tree,falseLabel) ,
2889 AST_FOR(tree,condLabel) ,
2890 AST_FOR(tree,initExpr) ,
2891 AST_FOR(tree,condExpr) ,
2892 AST_FOR(tree,loopExpr),
2896 TTYPE(tree) = TETYPE(tree) = NULL ;
2900 /* some error found this tree will be killed */
2902 TTYPE(tree) = TETYPE(tree) = newCharLink();
2903 tree->opval.op = NULLOP ;
2909 /*-----------------------------------------------------------------*/
2910 /* sizeofOp - processes size of operation */
2911 /*-----------------------------------------------------------------*/
2912 value *sizeofOp( sym_link *type)
2916 /* get the size and convert it to character */
2917 sprintf (buff,"%d", getSize(type));
2919 /* now convert into value */
2920 return constVal (buff);
2924 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
2925 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
2926 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
2927 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
2928 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
2929 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
2930 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
2932 /*-----------------------------------------------------------------*/
2933 /* backPatchLabels - change and or not operators to flow control */
2934 /*-----------------------------------------------------------------*/
2935 ast *backPatchLabels (ast *tree, symbol *trueLabel, symbol *falseLabel )
2941 if ( ! (IS_ANDORNOT(tree)))
2944 /* if this an and */
2946 static int localLbl = 0 ;
2947 symbol *localLabel ;
2949 sprintf (buffer,"_and_%d",localLbl++);
2950 localLabel = newSymbol(buffer,NestLevel);
2952 tree->left = backPatchLabels (tree->left, localLabel,falseLabel);
2954 /* if left is already a IFX then just change the if true label in that */
2955 if (!IS_IFX(tree->left))
2956 tree->left = newIfxNode(tree->left,localLabel,falseLabel);
2958 tree->right = backPatchLabels(tree->right,trueLabel,falseLabel);
2959 /* right is a IFX then just join */
2960 if (IS_IFX(tree->right))
2961 return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right));
2963 tree->right = createLabel(localLabel,tree->right);
2964 tree->right = newIfxNode(tree->right,trueLabel,falseLabel);
2966 return newNode(NULLOP,tree->left,tree->right);
2969 /* if this is an or operation */
2971 static int localLbl = 0 ;
2972 symbol *localLabel ;
2974 sprintf (buffer,"_or_%d",localLbl++);
2975 localLabel = newSymbol(buffer,NestLevel);
2977 tree->left = backPatchLabels (tree->left, trueLabel,localLabel);
2979 /* if left is already a IFX then just change the if true label in that */
2980 if (!IS_IFX(tree->left))
2981 tree->left = newIfxNode(tree->left,trueLabel,localLabel);
2983 tree->right = backPatchLabels(tree->right,trueLabel,falseLabel);
2984 /* right is a IFX then just join */
2985 if (IS_IFX(tree->right))
2986 return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right));
2988 tree->right = createLabel(localLabel,tree->right);
2989 tree->right = newIfxNode(tree->right,trueLabel,falseLabel);
2991 return newNode(NULLOP,tree->left,tree->right);
2996 int wasnot = IS_NOT(tree->left);
2997 tree->left = backPatchLabels (tree->left,falseLabel,trueLabel);
2999 /* if the left is already a IFX */
3000 if ( ! IS_IFX(tree->left) )
3001 tree->left = newNode (IFX,tree->left,NULL);
3004 tree->left->trueLabel = trueLabel ;
3005 tree->left->falseLabel= falseLabel ;
3007 tree->left->trueLabel = falseLabel ;
3008 tree->left->falseLabel= trueLabel ;
3014 tree->trueLabel = trueLabel ;
3015 tree->falseLabel= falseLabel;
3022 /*-----------------------------------------------------------------*/
3023 /* createBlock - create expression tree for block */
3024 /*-----------------------------------------------------------------*/
3025 ast *createBlock ( symbol *decl, ast *body )
3029 /* if the block has nothing */
3033 ex = newNode(BLOCK,NULL,body);
3034 ex->values.sym = decl ;
3036 ex->right = ex->right ;
3042 /*-----------------------------------------------------------------*/
3043 /* createLabel - creates the expression tree for labels */
3044 /*-----------------------------------------------------------------*/
3045 ast *createLabel ( symbol *label, ast *stmnt )
3048 char name[SDCC_NAME_MAX+1];
3051 /* must create fresh symbol if the symbol name */
3052 /* exists in the symbol table, since there can */
3053 /* be a variable with the same name as the labl */
3054 if ((csym = findSym (SymbolTab,NULL,label->name)) &&
3055 (csym->level == label->level))
3056 label = newSymbol(label->name,label->level);
3058 /* change the name before putting it in add _*/
3059 sprintf (name,"%s",label->name);
3061 /* put the label in the LabelSymbol table */
3062 /* but first check if a label of the same */
3064 if ( (csym = findSym(LabelTab,NULL,name)))
3065 werror(E_DUPLICATE_LABEL,label->name);
3067 addSym (LabelTab, label, name,label->level,0);
3070 label->key = labelKey++ ;
3071 rValue = newNode (LABEL,newAst_VALUE(symbolVal(label)),stmnt);
3077 /*-----------------------------------------------------------------*/
3078 /* createCase - generates the parsetree for a case statement */
3079 /*-----------------------------------------------------------------*/
3080 ast *createCase (ast *swStat, ast *caseVal, ast *stmnt )
3082 char caseLbl[SDCC_NAME_MAX+1];
3086 /* if the switch statement does not exist */
3087 /* then case is out of context */
3089 werror(E_CASE_CONTEXT);
3093 caseVal = decorateType(resolveSymbols(caseVal));
3094 /* if not a constant then error */
3095 if (!IS_LITERAL(caseVal->ftype)) {
3096 werror(E_CASE_CONSTANT);
3100 /* if not a integer than error */
3101 if (!IS_INTEGRAL(caseVal->ftype)) {
3102 werror(E_CASE_NON_INTEGER);
3106 /* find the end of the switch values chain */
3107 if (!(val = swStat->values.switchVals.swVals))
3108 swStat->values.switchVals.swVals = caseVal->opval.val ;
3110 /* also order the cases according to value */
3112 int cVal = (int) floatFromVal(caseVal->opval.val);
3113 while (val && (int) floatFromVal(val) < cVal) {
3118 /* if we reached the end then */
3120 pval->next = caseVal->opval.val;
3122 /* we found a value greater than */
3123 /* the current value we must add this */
3124 /* before the value */
3125 caseVal->opval.val->next = val;
3127 /* if this was the first in chain */
3128 if (swStat->values.switchVals.swVals == val)
3129 swStat->values.switchVals.swVals =
3132 pval->next = caseVal->opval.val;
3137 /* create the case label */
3138 sprintf(caseLbl,"_case_%d_%d",
3139 swStat->values.switchVals.swNum,
3140 (int) floatFromVal(caseVal->opval.val));
3142 rexpr = createLabel(newSymbol(caseLbl,0),stmnt);
3147 /*-----------------------------------------------------------------*/
3148 /* createDefault - creates the parse tree for the default statement*/
3149 /*-----------------------------------------------------------------*/
3150 ast *createDefault (ast *swStat, ast *stmnt)
3152 char defLbl[SDCC_NAME_MAX+1];
3154 /* if the switch statement does not exist */
3155 /* then case is out of context */
3157 werror(E_CASE_CONTEXT);
3161 /* turn on the default flag */
3162 swStat->values.switchVals.swDefault = 1 ;
3164 /* create the label */
3165 sprintf (defLbl,"_default_%d",swStat->values.switchVals.swNum);
3166 return createLabel(newSymbol(defLbl,0),stmnt);
3169 /*-----------------------------------------------------------------*/
3170 /* createIf - creates the parsetree for the if statement */
3171 /*-----------------------------------------------------------------*/
3172 ast *createIf ( ast *condAst, ast *ifBody, ast *elseBody )
3174 static int Lblnum = 0 ;
3176 symbol *ifTrue , *ifFalse, *ifEnd ;
3178 /* if neither exists */
3179 if (! elseBody && !ifBody)
3182 /* create the labels */
3183 sprintf (buffer,"_iffalse_%d",Lblnum);
3184 ifFalse = newSymbol (buffer,NestLevel);
3185 /* if no else body then end == false */
3189 sprintf (buffer,"_ifend_%d",Lblnum);
3190 ifEnd = newSymbol (buffer,NestLevel);
3193 sprintf (buffer,"_iftrue_%d",Lblnum);
3194 ifTrue = newSymbol (buffer,NestLevel);
3198 /* attach the ifTrue label to the top of it body */
3199 ifBody = createLabel(ifTrue,ifBody);
3200 /* attach a goto end to the ifBody if else is present */
3202 ifBody = newNode(NULLOP,ifBody,
3204 newAst_VALUE(symbolVal(ifEnd)),
3206 /* put the elseLabel on the else body */
3207 elseBody = createLabel (ifFalse,elseBody);
3208 /* out the end at the end of the body */
3209 elseBody = newNode(NULLOP,
3211 createLabel(ifEnd,NULL));
3214 ifBody = newNode(NULLOP,ifBody,
3215 createLabel(ifFalse,NULL));
3217 condAst = backPatchLabels (condAst,ifTrue,ifFalse);
3218 if (IS_IFX(condAst))
3221 ifTree = newIfxNode(condAst,ifTrue,ifFalse);
3223 return newNode(NULLOP,ifTree,
3224 newNode(NULLOP,ifBody,elseBody));
3228 /*-----------------------------------------------------------------*/
3229 /* createDo - creates parse tree for do */
3232 /* _docontinue_n: */
3233 /* condition_expression +-> trueLabel -> _dobody_n */
3235 /* +-> falseLabel-> _dobreak_n */
3237 /*-----------------------------------------------------------------*/
3238 ast *createDo ( symbol *trueLabel, symbol *continueLabel,
3239 symbol *falseLabel, ast *condAst, ast *doBody )
3244 /* if the body does not exist then it is simple */
3246 condAst = backPatchLabels(condAst,continueLabel,NULL);
3247 doTree = (IS_IFX(condAst) ? createLabel(continueLabel,condAst)
3248 : newNode(IFX,createLabel(continueLabel,condAst),NULL));
3249 doTree->trueLabel = continueLabel ;
3250 doTree->falseLabel= NULL ;
3254 /* otherwise we have a body */
3255 condAst = backPatchLabels(condAst,trueLabel,falseLabel);
3257 /* attach the body label to the top */
3258 doBody = createLabel(trueLabel,doBody);
3259 /* attach the continue label to end of body */
3260 doBody = newNode(NULLOP, doBody,
3261 createLabel(continueLabel,NULL));
3263 /* now put the break label at the end */
3264 if (IS_IFX(condAst))
3267 doTree = newIfxNode(condAst,trueLabel,falseLabel);
3269 doTree = newNode(NULLOP,doTree,createLabel(falseLabel,NULL));
3271 /* putting it together */
3272 return newNode(NULLOP,doBody,doTree);
3275 /*-----------------------------------------------------------------*/
3276 /* createFor - creates parse tree for 'for' statement */
3279 /* condExpr +-> trueLabel -> _forbody_n */
3281 /* +-> falseLabel-> _forbreak_n */
3284 /* _forcontinue_n: */
3286 /* goto _forcond_n ; */
3288 /*-----------------------------------------------------------------*/
3289 ast *createFor ( symbol *trueLabel, symbol *continueLabel ,
3290 symbol *falseLabel,symbol *condLabel ,
3291 ast *initExpr, ast *condExpr, ast *loopExpr,
3296 /* if loopexpression not present then we can generate it */
3297 /* the same way as a while */
3299 return newNode(NULLOP,initExpr,
3300 createWhile (trueLabel, continueLabel,
3301 falseLabel,condExpr, forBody ));
3302 /* vanilla for statement */
3303 condExpr = backPatchLabels(condExpr,trueLabel,falseLabel);
3305 if (condExpr && !IS_IFX(condExpr))
3306 condExpr = newIfxNode(condExpr,trueLabel,falseLabel);
3309 /* attach condition label to condition */
3310 condExpr = createLabel(condLabel,condExpr);
3312 /* attach body label to body */
3313 forBody = createLabel(trueLabel,forBody);
3315 /* attach continue to forLoop expression & attach */
3316 /* goto the forcond @ and of loopExpression */
3317 loopExpr = createLabel(continueLabel,
3321 newAst_VALUE(symbolVal(condLabel)),
3323 /* now start putting them together */
3324 forTree = newNode(NULLOP,initExpr,condExpr);
3325 forTree = newNode(NULLOP,forTree,forBody);
3326 forTree = newNode(NULLOP,forTree,loopExpr);
3327 /* finally add the break label */
3328 forTree = newNode(NULLOP,forTree,
3329 createLabel(falseLabel,NULL));
3333 /*-----------------------------------------------------------------*/
3334 /* createWhile - creates parse tree for while statement */
3335 /* the while statement will be created as follows */
3337 /* _while_continue_n: */
3338 /* condition_expression +-> trueLabel -> _while_boby_n */
3340 /* +-> falseLabel -> _while_break_n*/
3341 /* _while_body_n: */
3343 /* goto _while_continue_n */
3344 /* _while_break_n: */
3345 /*-----------------------------------------------------------------*/
3346 ast *createWhile (symbol *trueLabel, symbol *continueLabel,
3347 symbol *falseLabel,ast *condExpr, ast *whileBody )
3351 /* put the continue label */
3352 condExpr = backPatchLabels (condExpr,trueLabel,falseLabel);
3353 condExpr = createLabel(continueLabel,condExpr);
3354 condExpr->lineno = 0;
3356 /* put the body label in front of the body */
3357 whileBody = createLabel(trueLabel,whileBody);
3358 whileBody->lineno = 0;
3359 /* put a jump to continue at the end of the body */
3360 /* and put break label at the end of the body */
3361 whileBody = newNode(NULLOP,
3364 newAst_VALUE(symbolVal(continueLabel)),
3365 createLabel(falseLabel,NULL)));
3367 /* put it all together */
3368 if ( IS_IFX(condExpr) )
3369 whileTree = condExpr ;
3371 whileTree = newNode (IFX, condExpr,NULL );
3372 /* put the true & false labels in place */
3373 whileTree->trueLabel = trueLabel ;
3374 whileTree->falseLabel= falseLabel;
3377 return newNode(NULLOP,whileTree,whileBody );
3380 /*-----------------------------------------------------------------*/
3381 /* optimizeGetHbit - get highest order bit of the expression */
3382 /*-----------------------------------------------------------------*/
3383 ast *optimizeGetHbit (ast *tree)
3386 /* if this is not a bit and */
3387 if (!IS_BITAND(tree))
3390 /* will look for tree of the form
3391 ( expr >> ((sizeof expr) -1) ) & 1 */
3392 if (!IS_AST_LIT_VALUE(tree->right))
3395 if (AST_LIT_VALUE(tree->right) != 1)
3398 if (!IS_RIGHT_OP(tree->left))
3401 if (!IS_AST_LIT_VALUE(tree->left->right))
3404 if ((i = (int) AST_LIT_VALUE(tree->left->right)) !=
3405 ( j = (getSize(TTYPE(tree->left->left))*8 - 1)))
3408 return decorateType(newNode(GETHBIT,tree->left->left,NULL));
3412 /*-----------------------------------------------------------------*/
3413 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3414 /*-----------------------------------------------------------------*/
3415 ast *optimizeRRCRLC ( ast *root )
3417 /* will look for trees of the form
3418 (?expr << 1) | (?expr >> 7) or
3419 (?expr >> 7) | (?expr << 1) will make that
3420 into a RLC : operation ..
3422 (?expr >> 1) | (?expr << 7) or
3423 (?expr << 7) | (?expr >> 1) will make that
3424 into a RRC operation
3425 note : by 7 I mean (number of bits required to hold the
3427 /* if the root operations is not a | operation the not */
3428 if (!IS_BITOR(root))
3431 /* I have to think of a better way to match patterns this sucks */
3432 /* that aside let start looking for the first case : I use a the
3433 negative check a lot to improve the efficiency */
3434 /* (?expr << 1) | (?expr >> 7) */
3435 if (IS_LEFT_OP(root->left) &&
3436 IS_RIGHT_OP(root->right) ) {
3438 if (!SPEC_USIGN(TETYPE(root->left->left)))
3441 if (!IS_AST_LIT_VALUE(root->left->right) ||
3442 !IS_AST_LIT_VALUE(root->right->right))
3445 /* make sure it is the same expression */
3446 if (!isAstEqual(root->left->left,
3450 if (AST_LIT_VALUE(root->left->right) != 1 )
3453 if (AST_LIT_VALUE(root->right->right) !=
3454 (getSize(TTYPE(root->left->left))*8 - 1))
3457 /* whew got the first case : create the AST */
3458 return newNode(RLC,root->left->left,NULL);
3462 /* check for second case */
3463 /* (?expr >> 7) | (?expr << 1) */
3464 if (IS_LEFT_OP(root->right) &&
3465 IS_RIGHT_OP(root->left) ) {
3467 if (!SPEC_USIGN(TETYPE(root->left->left)))
3470 if (!IS_AST_LIT_VALUE(root->left->right) ||
3471 !IS_AST_LIT_VALUE(root->right->right))
3474 /* make sure it is the same symbol */
3475 if (!isAstEqual(root->left->left,
3479 if (AST_LIT_VALUE(root->right->right) != 1 )
3482 if (AST_LIT_VALUE(root->left->right) !=
3483 (getSize(TTYPE(root->left->left))*8 - 1))
3486 /* whew got the first case : create the AST */
3487 return newNode(RLC,root->left->left,NULL);
3492 /* third case for RRC */
3493 /* (?symbol >> 1) | (?symbol << 7) */
3494 if (IS_LEFT_OP(root->right) &&
3495 IS_RIGHT_OP(root->left) ) {
3497 if (!SPEC_USIGN(TETYPE(root->left->left)))
3500 if (!IS_AST_LIT_VALUE(root->left->right) ||
3501 !IS_AST_LIT_VALUE(root->right->right))
3504 /* make sure it is the same symbol */
3505 if (!isAstEqual(root->left->left,
3509 if (AST_LIT_VALUE(root->left->right) != 1 )
3512 if (AST_LIT_VALUE(root->right->right) !=
3513 (getSize(TTYPE(root->left->left))*8 - 1))
3516 /* whew got the first case : create the AST */
3517 return newNode(RRC,root->left->left,NULL);
3521 /* fourth and last case for now */
3522 /* (?symbol << 7) | (?symbol >> 1) */
3523 if (IS_RIGHT_OP(root->right) &&
3524 IS_LEFT_OP(root->left) ) {
3526 if (!SPEC_USIGN(TETYPE(root->left->left)))
3529 if (!IS_AST_LIT_VALUE(root->left->right) ||
3530 !IS_AST_LIT_VALUE(root->right->right))
3533 /* make sure it is the same symbol */
3534 if (!isAstEqual(root->left->left,
3538 if (AST_LIT_VALUE(root->right->right) != 1 )
3541 if (AST_LIT_VALUE(root->left->right) !=
3542 (getSize(TTYPE(root->left->left))*8 - 1))
3545 /* whew got the first case : create the AST */
3546 return newNode(RRC,root->left->left,NULL);
3550 /* not found return root */
3554 /*-----------------------------------------------------------------*/
3555 /* optimizeCompare - otimizes compares for bit variables */
3556 /*-----------------------------------------------------------------*/
3557 ast *optimizeCompare ( ast *root )
3559 ast *optExpr = NULL;
3562 unsigned int litValue ;
3564 /* if nothing then return nothing */
3568 /* if not a compare op then do leaves */
3569 if (!IS_COMPARE_OP(root)) {
3570 root->left = optimizeCompare (root->left);
3571 root->right= optimizeCompare (root->right);
3575 /* if left & right are the same then depending
3576 of the operation do */
3577 if (isAstEqual(root->left,root->right)) {
3578 switch (root->opval.op) {
3582 optExpr = newAst_VALUE(constVal("0"));
3587 optExpr = newAst_VALUE(constVal("1"));
3591 return decorateType(optExpr);
3594 vleft = (root->left->type == EX_VALUE ?
3595 root->left->opval.val : NULL );
3597 vright = (root->right->type == EX_VALUE ?
3598 root->right->opval.val : NULL);
3600 /* if left is a BITVAR in BITSPACE */
3601 /* and right is a LITERAL then opt-*/
3602 /* imize else do nothing */
3603 if (vleft && vright &&
3604 IS_BITVAR(vleft->etype) &&
3605 IN_BITSPACE(SPEC_OCLS(vleft->etype)) &&
3606 IS_LITERAL(vright->etype)) {
3608 /* if right side > 1 then comparison may never succeed */
3609 if ( (litValue = (int) floatFromVal(vright)) > 1 ) {
3610 werror(W_BAD_COMPARE);
3615 switch (root->opval.op) {
3616 case '>' : /* bit value greater than 1 cannot be */
3617 werror(W_BAD_COMPARE);
3621 case '<' : /* bit value < 1 means 0 */
3623 optExpr = newNode('!',newAst_VALUE(vleft),NULL);
3626 case LE_OP : /* bit value <= 1 means no check */
3627 optExpr = newAst_VALUE(vright);
3630 case GE_OP : /* bit value >= 1 means only check for = */
3632 optExpr = newAst_VALUE(vleft);
3635 } else { /* literal is zero */
3636 switch (root->opval.op) {
3637 case '<' : /* bit value < 0 cannot be */
3638 werror(W_BAD_COMPARE);
3642 case '>' : /* bit value > 0 means 1 */
3644 optExpr = newAst_VALUE(vleft);
3647 case LE_OP : /* bit value <= 0 means no check */
3648 case GE_OP : /* bit value >= 0 means no check */
3649 werror(W_BAD_COMPARE);
3653 case EQ_OP : /* bit == 0 means ! of bit */
3654 optExpr = newNode('!',newAst_VALUE(vleft),NULL);
3658 return decorateType(resolveSymbols(optExpr));
3659 } /* end-of-if of BITVAR */
3664 /*-----------------------------------------------------------------*/
3665 /* addSymToBlock : adds the symbol to the first block we find */
3666 /*-----------------------------------------------------------------*/
3667 void addSymToBlock (symbol *sym, ast *tree)
3669 /* reached end of tree or a leaf */
3670 if (!tree || IS_AST_LINK(tree) || IS_AST_VALUE(tree))
3674 if (IS_AST_OP(tree) &&
3675 tree->opval.op == BLOCK ) {
3677 symbol *lsym = copySymbol(sym);
3679 lsym->next = AST_VALUES(tree,sym);
3680 AST_VALUES(tree,sym) = lsym ;
3684 addSymToBlock(sym,tree->left);
3685 addSymToBlock(sym,tree->right);
3688 /*-----------------------------------------------------------------*/
3689 /* processRegParms - do processing for register parameters */
3690 /*-----------------------------------------------------------------*/
3691 static void processRegParms (value *args, ast *body)
3694 if (IS_REGPARM(args->etype))
3695 addSymToBlock(args->sym,body);
3700 /*-----------------------------------------------------------------*/
3701 /* resetParmKey - resets the operandkeys for the symbols */
3702 /*-----------------------------------------------------------------*/
3703 DEFSETFUNC(resetParmKey)
3714 /*-----------------------------------------------------------------*/
3715 /* createFunction - This is the key node that calls the iCode for */
3716 /* generating the code for a function. Note code */
3717 /* is generated function by function, later when */
3718 /* add inter-procedural analysis this will change */
3719 /*-----------------------------------------------------------------*/
3720 ast *createFunction (symbol *name, ast *body )
3726 iCode *piCode = NULL;
3728 /* if check function return 0 then some problem */
3729 if (checkFunction (name) == 0)
3732 /* create a dummy block if none exists */
3734 body = newNode(BLOCK,NULL,NULL);
3738 /* check if the function name already in the symbol table */
3739 if ((csym = findSym (SymbolTab,NULL,name->name))) {
3741 /* special case for compiler defined functions
3742 we need to add the name to the publics list : this
3743 actually means we are now compiling the compiler
3746 addSet(&publics,name);
3751 allocVariables(name);
3753 name->lastLine = yylineno;
3755 processFuncArgs(currFunc,0);
3757 /* set the stack pointer */
3758 /* PENDING: check this for the mcs51 */
3759 stackPtr = -port->stack.direction * port->stack.call_overhead;
3760 if (IS_ISR(name->etype))
3761 stackPtr -= port->stack.direction * port->stack.isr_overhead;
3762 if (IS_RENT(name->etype) || options.stackAuto)
3763 stackPtr -= port->stack.direction * port->stack.reent_overhead;
3765 xstackPtr = -port->stack.direction * port->stack.call_overhead;
3767 fetype = getSpec(name->type); /* get the specifier for the function */
3768 /* if this is a reentrant function then */
3769 if (IS_RENT(fetype))
3772 allocParms (name->args); /* allocate the parameters */
3774 /* do processing for parameters that are passed in registers */
3775 processRegParms (name->args,body);
3777 /* set the stack pointer */
3781 /* allocate & autoinit the block variables */
3782 processBlockVars (body, &stack,ALLOCATE);
3784 /* save the stack information */
3785 if (options.useXstack)
3786 name->xstack = SPEC_STAK(fetype) = stack;
3788 name->stack = SPEC_STAK(fetype) = stack;
3790 /* name needs to be mangled */
3791 sprintf (name->rname,"%s%s", port->fun_prefix, name->name);
3793 body = resolveSymbols(body); /* resolve the symbols */
3794 body = decorateType (body); /* propagateType & do semantic checks */
3796 ex = newAst_VALUE(symbolVal(name)); /* create name */
3797 ex = newNode (FUNCTION,ex,body);
3798 ex->values.args = name->args ;
3801 werror(E_FUNC_NO_CODE,name->name);
3805 /* create the node & generate intermediate code */
3806 codeOutFile = code->oFile;
3807 piCode = iCodeFromAst(ex);
3810 werror(E_FUNC_NO_CODE,name->name);
3814 eBBlockFromiCode(piCode);
3816 /* if there are any statics then do them */
3818 codeOutFile = statsg->oFile;
3819 eBBlockFromiCode (iCodeFromAst (decorateType(resolveSymbols(staticAutos))));
3825 /* dealloc the block variables */
3826 processBlockVars(body, &stack,DEALLOCATE);
3827 /* deallocate paramaters */
3828 deallocParms(name->args);
3830 if (IS_RENT(fetype))
3833 /* we are done freeup memory & cleanup */
3838 addSet(&operKeyReset,name);
3839 applyToSet(operKeyReset,resetParmKey);
3841 if (options.debug && !options.nodebug)
3842 cdbStructBlock(1,cdbFile);
3844 cleanUpLevel(LabelTab,0);
3845 cleanUpBlock(StructTab,1);
3846 cleanUpBlock(TypedefTab,1);
3848 xstack->syms = NULL;
3849 istack->syms = NULL;