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(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(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(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(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, value *defParm,
563 sym_link *fetype = func->etype;
565 /* if none of them exist */
566 if ( !defParm && !actParm)
569 /* if the function is being called via a pointer & */
570 /* it has not been defined a reentrant then we cannot*/
571 /* have parameters */
572 if (func->type != EX_VALUE && !IS_RENT(fetype) && !options.stackAuto) {
573 werror (E_NONRENT_ARGS);
577 /* if defined parameters ended but actual parameters */
578 /* exist and this is not defined as a variable arg */
579 /* also check if statckAuto option is specified */
580 if ((! defParm) && actParm && (!func->hasVargs ) &&
581 !options.stackAuto && !IS_RENT(fetype)) {
582 werror(E_TOO_MANY_PARMS);
586 /* if defined parameters present but no actual parameters */
587 if ( defParm && ! actParm) {
588 werror(E_TOO_FEW_PARMS);
592 /* If this is a varargs function... */
593 if (!defParm && actParm && func->hasVargs )
597 if (IS_CAST_OP(actParm)
598 || (IS_AST_LIT_VALUE(actParm) && actParm->values.literalFromCast))
600 /* Parameter was explicitly typecast; don't touch it. */
604 /* If it's a small integer, upcast to int. */
605 if (IS_INTEGRAL(actParm->ftype)
606 && getSize(actParm->ftype) < INTSIZE)
608 newType = newAst_LINK(INTTYPE);
611 if (IS_PTR(actParm->ftype) && !IS_GENPTR(actParm->ftype))
613 newType = newAst_LINK(copyLinkChain(actParm->ftype));
614 DCL_TYPE(newType->opval.lnk) = GPOINTER;
617 if (IS_AGGREGATE(actParm->ftype))
619 newType = newAst_LINK(copyLinkChain(actParm->ftype));
620 DCL_TYPE(newType->opval.lnk) = GPOINTER;
625 /* cast required; change this op to a cast. */
626 ast *parmCopy = resolveSymbols(copyAst(actParm));
628 actParm->type = EX_OP;
629 actParm->opval.op = CAST;
630 actParm->left = newType;
631 actParm->right= parmCopy;
632 decorateType(actParm);
634 else if ( actParm->type == EX_OP && actParm->opval.op == PARAM)
636 return (processParms (func,NULL,actParm->left,parmNumber) ||
637 processParms (func,NULL,actParm->right,parmNumber) );
642 /* if defined parameters ended but actual has not & */
644 if (! defParm && actParm &&
645 (options.stackAuto || IS_RENT(fetype)))
648 resolveSymbols(actParm);
649 /* if this is a PARAM node then match left & right */
650 if ( actParm->type == EX_OP && actParm->opval.op == PARAM) {
651 return (processParms (func,defParm,actParm->left,parmNumber) ||
652 processParms (func,defParm->next, actParm->right,parmNumber) );
655 /* Pending discussion with Johan. */
657 /* if more defined parameters present but no more actual parameters */
659 werror(E_TOO_FEW_PARMS);
665 /* the parameter type must be atleast castable */
666 if (checkType(defParm->type,actParm->ftype) == 0) {
667 werror(E_TYPE_MISMATCH_PARM,*parmNumber);
668 werror(E_CONTINUE,"defined type ");
669 printTypeChain(defParm->type,stderr);fprintf(stderr,"\n");
670 werror(E_CONTINUE,"actual type ");
671 printTypeChain(actParm->ftype,stderr);fprintf(stderr,"\n");
674 /* if the parameter is castable then add the cast */
675 if ( checkType (defParm->type,actParm->ftype) < 0) {
676 ast *pTree = resolveSymbols(copyAst(actParm));
678 /* now change the current one to a cast */
679 actParm->type = EX_OP ;
680 actParm->opval.op = CAST ;
681 actParm->left = newAst_LINK(defParm->type);
682 actParm->right= pTree ;
683 actParm->etype= defParm->etype;
684 actParm->ftype= defParm->type;
687 /* actParm->argSym = resolveFromTable(defParm)->sym ; */
689 actParm->argSym = defParm->sym;
690 /* make a copy and change the regparm type to the defined parm */
691 actParm->etype = getSpec(actParm->ftype = copyLinkChain(actParm->ftype));
692 SPEC_REGPARM(actParm->etype) = SPEC_REGPARM(defParm->etype);
696 /*-----------------------------------------------------------------*/
697 /* createIvalType - generates ival for basic types */
698 /*-----------------------------------------------------------------*/
699 ast *createIvalType ( ast *sym,sym_link *type, initList *ilist)
703 /* if initList is deep */
704 if ( ilist->type == INIT_DEEP )
705 ilist = ilist->init.deep ;
707 iExpr = decorateType(resolveSymbols(list2expr(ilist)));
708 return decorateType(newNode('=',sym,iExpr));
711 /*-----------------------------------------------------------------*/
712 /* createIvalStruct - generates initial value for structures */
713 /*-----------------------------------------------------------------*/
714 ast *createIvalStruct (ast *sym,sym_link *type,initList *ilist)
720 sflds = SPEC_STRUCT(type)->fields ;
721 if (ilist->type != INIT_DEEP) {
722 werror(E_INIT_STRUCT,"");
726 iloop = ilist->init.deep;
728 for ( ; sflds ; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL )) {
731 /* if we have come to end */
735 lAst = newNode(PTR_OP,newNode('&',sym,NULL),newAst_VALUE(symbolVal(sflds)));
736 lAst = decorateType(resolveSymbols(lAst));
737 rast = decorateType(resolveSymbols(createIval (lAst, sflds->type, iloop,rast)));
743 /*-----------------------------------------------------------------*/
744 /* createIvalArray - generates code for array initialization */
745 /*-----------------------------------------------------------------*/
746 ast *createIvalArray (ast *sym, sym_link *type, initList *ilist)
750 int lcnt = 0, size =0 ;
752 /* take care of the special case */
753 /* array of characters can be init */
755 if ( IS_CHAR(type->next) )
756 if ( (rast = createIvalCharPtr(sym,
758 decorateType(resolveSymbols(list2expr(ilist))))))
760 return decorateType(resolveSymbols(rast));
762 /* not the special case */
763 if (ilist->type != INIT_DEEP) {
764 werror(E_INIT_STRUCT,"");
768 iloop = ilist->init.deep ;
769 lcnt = DCL_ELEM(type);
775 aSym = newNode('[',sym,newAst_VALUE(valueFromLit(size-1)));
776 aSym = decorateType(resolveSymbols(aSym));
777 rast = createIval (aSym,type->next,iloop,rast) ;
778 iloop = (iloop ? iloop->next : NULL) ;
781 /* if not array limits given & we */
782 /* are out of initialisers then */
783 if (!DCL_ELEM(type) && !iloop)
786 /* no of elements given and we */
787 /* have generated for all of them */
792 /* if we have not been given a size */
794 DCL_ELEM(type) = size;
796 return decorateType(resolveSymbols(rast));
800 /*-----------------------------------------------------------------*/
801 /* createIvalCharPtr - generates initial values for char pointers */
802 /*-----------------------------------------------------------------*/
803 ast *createIvalCharPtr (ast *sym, sym_link *type, ast *iexpr)
807 /* if this is a pointer & right is a literal array then */
808 /* just assignment will do */
809 if ( IS_PTR(type) && (( IS_LITERAL(iexpr->etype) ||
810 SPEC_SCLS(iexpr->etype) == S_CODE )
811 && IS_ARRAY(iexpr->ftype)))
812 return newNode('=',sym,iexpr);
814 /* left side is an array so we have to assign each */
816 if (( IS_LITERAL(iexpr->etype) ||
817 SPEC_SCLS(iexpr->etype) == S_CODE )
818 && IS_ARRAY(iexpr->ftype)) {
820 /* for each character generate an assignment */
821 /* to the array element */
822 char *s = SPEC_CVAL(iexpr->etype).v_char ;
826 rast = newNode(NULLOP,
830 newAst_VALUE(valueFromLit(i))),
831 newAst_VALUE(valueFromLit(*s))));
835 rast = newNode(NULLOP,
839 newAst_VALUE(valueFromLit(i))),
840 newAst_VALUE(valueFromLit(*s))));
841 return decorateType(resolveSymbols(rast));
847 /*-----------------------------------------------------------------*/
848 /* createIvalPtr - generates initial value for pointers */
849 /*-----------------------------------------------------------------*/
850 ast *createIvalPtr (ast *sym,sym_link *type,initList *ilist)
856 if ( ilist->type == INIT_DEEP )
857 ilist = ilist->init.deep ;
859 iexpr = decorateType(resolveSymbols(list2expr(ilist)));
861 /* if character pointer */
862 if (IS_CHAR(type->next))
863 if ((rast = createIvalCharPtr (sym,type,iexpr)))
866 return newNode('=',sym,iexpr);
869 /*-----------------------------------------------------------------*/
870 /* createIval - generates code for initial value */
871 /*-----------------------------------------------------------------*/
872 ast *createIval (ast *sym, sym_link *type, initList *ilist, ast *wid)
879 /* if structure then */
881 rast = createIvalStruct(sym, type,ilist);
883 /* if this is a pointer */
885 rast = createIvalPtr(sym, type,ilist);
887 /* if this is an array */
889 rast = createIvalArray(sym, type,ilist);
891 /* if type is SPECIFIER */
893 rast = createIvalType (sym,type,ilist);
895 return decorateType(resolveSymbols(newNode(NULLOP,wid,rast)));
897 return decorateType(resolveSymbols(rast)) ;
900 /*-----------------------------------------------------------------*/
901 /* initAggregates - initialises aggregate variables with initv */
902 /*-----------------------------------------------------------------*/
903 ast *initAggregates ( symbol *sym, initList *ival, ast *wid)
905 return createIval (newAst_VALUE(symbolVal(sym)),sym->type,ival,wid);
908 /*-----------------------------------------------------------------*/
909 /* gatherAutoInit - creates assignment expressions for initial */
911 /*-----------------------------------------------------------------*/
912 ast *gatherAutoInit ( symbol *autoChain )
919 for ( sym = autoChain ; sym ; sym = sym->next ) {
921 /* resolve the symbols in the ival */
923 resolveIvalSym(sym->ival);
925 /* if this is a static variable & has an */
926 /* initial value the code needs to be lifted */
927 /* here to the main portion since they can be */
928 /* initialised only once at the start */
929 if ( IS_STATIC(sym->etype) && sym->ival &&
930 SPEC_SCLS(sym->etype) != S_CODE) {
933 /* insert the symbol into the symbol table */
934 /* with level = 0 & name = rname */
935 newSym = copySymbol (sym);
936 addSym (SymbolTab,newSym,newSym->name,0,0);
938 /* now lift the code to main */
939 if (IS_AGGREGATE(sym->type))
940 work = initAggregates (sym, sym->ival,NULL);
942 work = newNode('=' ,newAst_VALUE(symbolVal(newSym)),
943 list2expr(sym->ival));
945 setAstLineno(work,sym->lineDef);
949 staticAutos = newNode(NULLOP,staticAutos,work);
956 /* if there is an initial value */
957 if ( sym->ival && SPEC_SCLS(sym->etype)!=S_CODE) {
958 if (IS_AGGREGATE(sym->type))
959 work = initAggregates (sym,sym->ival,NULL);
961 work = newNode('=' ,newAst_VALUE(symbolVal(sym)),
962 list2expr(sym->ival));
964 setAstLineno (work,sym->lineDef);
967 init = newNode(NULLOP,init,work);
976 /*-----------------------------------------------------------------*/
977 /* stringToSymbol - creates a symbol from a literal string */
978 /*-----------------------------------------------------------------*/
979 static value *stringToSymbol (value *val)
981 char name[SDCC_NAME_MAX+1];
982 static int charLbl = 0;
985 sprintf(name,"_str_%d",charLbl++);
986 sym = newSymbol(name,0); /* make it @ level 0 */
987 strcpy(sym->rname,name);
989 /* copy the type from the value passed */
990 sym->type = copyLinkChain(val->type);
991 sym->etype = getSpec(sym->type);
992 /* change to storage class & output class */
993 SPEC_SCLS(sym->etype) = S_CODE ;
994 SPEC_CVAL(sym->etype).v_char = SPEC_CVAL(val->etype).v_char ;
995 SPEC_STAT(sym->etype) = 1;
996 /* make the level & block = 0 */
997 sym->block = sym->level = 0;
1000 sym->ival = newiList(INIT_NODE,newAst_VALUE(val));
1004 allocVariables(sym);
1007 return symbolVal(sym);
1011 /*-----------------------------------------------------------------*/
1012 /* processBlockVars - will go thru the ast looking for block if */
1013 /* a block is found then will allocate the syms */
1014 /* will also gather the auto inits present */
1015 /*-----------------------------------------------------------------*/
1016 ast *processBlockVars ( ast *tree , int *stack, int action)
1021 /* if this is a block */
1022 if (tree->type == EX_OP && tree->opval.op == BLOCK ) {
1025 if (action == ALLOCATE) {
1026 autoInit = gatherAutoInit (tree->values.sym);
1027 *stack += allocVariables (tree->values.sym);
1029 /* if there are auto inits then do them */
1031 tree->left = newNode(NULLOP,autoInit,tree->left);
1032 } else /* action is deallocate */
1033 deallocLocal (tree->values.sym) ;
1036 processBlockVars (tree->left, stack, action);
1037 processBlockVars (tree->right, stack, action);
1041 /*-----------------------------------------------------------------*/
1042 /* constExprValue - returns the value of a constant expression */
1043 /*-----------------------------------------------------------------*/
1044 value *constExprValue (ast *cexpr, int check)
1046 cexpr = decorateType(resolveSymbols(cexpr));
1048 /* if this is not a constant then */
1049 if (!IS_LITERAL(cexpr->ftype)) {
1050 /* then check if this is a literal array
1052 if (SPEC_SCLS(cexpr->etype) == S_CODE &&
1053 SPEC_CVAL(cexpr->etype).v_char &&
1054 IS_ARRAY(cexpr->ftype)) {
1055 value *val = valFromType(cexpr->ftype);
1056 SPEC_SCLS(val->etype) = S_LITERAL;
1057 val->sym =cexpr->opval.val->sym ;
1058 val->sym->type = copyLinkChain(cexpr->ftype);
1059 val->sym->etype = getSpec(val->sym->type);
1060 strcpy(val->name,cexpr->opval.val->sym->rname);
1064 /* if we are casting a literal value then */
1065 if (IS_AST_OP(cexpr) &&
1066 cexpr->opval.op == CAST &&
1067 IS_LITERAL(cexpr->left->ftype))
1068 return valCastLiteral(cexpr->ftype,
1069 floatFromVal(cexpr->left->opval.val));
1071 if (IS_AST_VALUE(cexpr))
1072 return cexpr->opval.val;
1075 werror(E_CONST_EXPECTED,"found expression");
1080 /* return the value */
1081 return cexpr->opval.val ;
1085 /*-----------------------------------------------------------------*/
1086 /* isLabelInAst - will return true if a given label is found */
1087 /*-----------------------------------------------------------------*/
1088 bool isLabelInAst (symbol *label, ast *tree)
1090 if (!tree || IS_AST_VALUE(tree) || IS_AST_LINK(tree))
1093 if (IS_AST_OP(tree) &&
1094 tree->opval.op == LABEL &&
1095 isSymbolEqual(AST_SYMBOL(tree->left),label))
1098 return isLabelInAst(label,tree->right) &&
1099 isLabelInAst(label,tree->left);
1103 /*-----------------------------------------------------------------*/
1104 /* isLoopCountable - return true if the loop count can be determi- */
1105 /* -ned at compile time . */
1106 /*-----------------------------------------------------------------*/
1107 bool isLoopCountable (ast *initExpr, ast *condExpr, ast *loopExpr,
1108 symbol **sym,ast **init, ast **end)
1111 /* the loop is considered countable if the following
1112 conditions are true :-
1114 a) initExpr :- <sym> = <const>
1115 b) condExpr :- <sym> < <const1>
1116 c) loopExpr :- <sym> ++
1119 /* first check the initExpr */
1120 if ( IS_AST_OP(initExpr) &&
1121 initExpr->opval.op == '=' && /* is assignment */
1122 IS_AST_SYM_VALUE(initExpr->left)) { /* left is a symbol */
1124 *sym = AST_SYMBOL(initExpr->left);
1125 *init= initExpr->right;
1130 /* for now the symbol has to be of
1132 if (!IS_INTEGRAL((*sym)->type))
1135 /* now check condExpr */
1136 if (IS_AST_OP(condExpr)) {
1138 switch (condExpr->opval.op) {
1140 if (IS_AST_SYM_VALUE(condExpr->left) &&
1141 isSymbolEqual (*sym,AST_SYMBOL(condExpr->left)) &&
1142 IS_AST_LIT_VALUE(condExpr->right)) {
1143 *end = condExpr->right;
1149 if (IS_AST_OP(condExpr->left) &&
1150 condExpr->left->opval.op == '>' &&
1151 IS_AST_LIT_VALUE(condExpr->left->right) &&
1152 IS_AST_SYM_VALUE(condExpr->left->left)&&
1153 isSymbolEqual (*sym,AST_SYMBOL(condExpr->left->left))) {
1155 *end = newNode('+', condExpr->left->right,
1156 newAst_VALUE(constVal("1")));
1167 /* check loop expression is of the form <sym>++ */
1168 if (!IS_AST_OP(loopExpr))
1171 /* check if <sym> ++ */
1172 if (loopExpr->opval.op == INC_OP) {
1174 if (loopExpr->left) {
1176 if (IS_AST_SYM_VALUE(loopExpr->left) &&
1177 isSymbolEqual(*sym,AST_SYMBOL(loopExpr->left)))
1182 if (IS_AST_SYM_VALUE(loopExpr->right) &&
1183 isSymbolEqual(*sym,AST_SYMBOL(loopExpr->right)))
1190 if ( loopExpr->opval.op == ADD_ASSIGN ) {
1192 if (IS_AST_SYM_VALUE(loopExpr->left) &&
1193 isSymbolEqual(*sym,AST_SYMBOL(loopExpr->left)) &&
1194 IS_AST_LIT_VALUE(loopExpr->right) &&
1195 (int)AST_LIT_VALUE(loopExpr->right) != 1)
1203 /*-----------------------------------------------------------------*/
1204 /* astHasVolatile - returns true if ast contains any volatile */
1205 /*-----------------------------------------------------------------*/
1206 bool astHasVolatile (ast *tree)
1211 if (TETYPE(tree) && IS_VOLATILE(TETYPE(tree)))
1214 if (IS_AST_OP(tree))
1215 return astHasVolatile(tree->left) ||
1216 astHasVolatile(tree->right);
1221 /*-----------------------------------------------------------------*/
1222 /* astHasPointer - return true if the ast contains any ptr variable*/
1223 /*-----------------------------------------------------------------*/
1224 bool astHasPointer (ast *tree)
1229 if (IS_AST_LINK(tree))
1232 /* if we hit an array expression then check
1233 only the left side */
1234 if (IS_AST_OP(tree) && tree->opval.op == '[')
1235 return astHasPointer(tree->left);
1237 if (IS_AST_VALUE(tree))
1238 return IS_PTR(tree->ftype) || IS_ARRAY(tree->ftype);
1240 return astHasPointer(tree->left) ||
1241 astHasPointer(tree->right);
1245 /*-----------------------------------------------------------------*/
1246 /* astHasSymbol - return true if the ast has the given symbol */
1247 /*-----------------------------------------------------------------*/
1248 bool astHasSymbol (ast *tree, symbol *sym)
1250 if (!tree || IS_AST_LINK(tree))
1253 if (IS_AST_VALUE(tree)) {
1254 if (IS_AST_SYM_VALUE(tree))
1255 return isSymbolEqual(AST_SYMBOL(tree),sym);
1260 return astHasSymbol(tree->left,sym) ||
1261 astHasSymbol(tree->right,sym);
1264 /*-----------------------------------------------------------------*/
1265 /* isConformingBody - the loop body has to conform to a set of rules */
1266 /* for the loop to be considered reversible read on for rules */
1267 /*-----------------------------------------------------------------*/
1268 bool isConformingBody (ast *pbody, symbol *sym, ast *body)
1271 /* we are going to do a pre-order traversal of the
1272 tree && check for the following conditions. (essentially
1273 a set of very shallow tests )
1274 a) the sym passed does not participate in
1275 any arithmetic operation
1276 b) There are no function calls
1277 c) all jumps are within the body
1278 d) address of loop control variable not taken
1279 e) if an assignment has a pointer on the
1280 left hand side make sure right does not have
1281 loop control variable */
1283 /* if we reach the end or a leaf then true */
1284 if (!pbody || IS_AST_LINK(pbody) || IS_AST_VALUE(pbody))
1288 /* if anything else is "volatile" */
1289 if (IS_VOLATILE(TETYPE(pbody)))
1292 /* we will walk the body in a pre-order traversal for
1294 switch (pbody->opval.op) {
1295 /*------------------------------------------------------------------*/
1297 return isConformingBody (pbody->right,sym,body);
1299 /*------------------------------------------------------------------*/
1304 /*------------------------------------------------------------------*/
1305 case INC_OP: /* incerement operator unary so left only */
1308 /* sure we are not sym is not modified */
1310 IS_AST_SYM_VALUE(pbody->left) &&
1311 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1315 IS_AST_SYM_VALUE(pbody->right) &&
1316 isSymbolEqual(AST_SYMBOL(pbody->right),sym))
1321 /*------------------------------------------------------------------*/
1323 case '*' : /* can be unary : if right is null then unary operation */
1328 /* if right is NULL then unary operation */
1329 /*------------------------------------------------------------------*/
1330 /*----------------------------*/
1332 /*----------------------------*/
1333 if ( ! pbody->right ) {
1334 if (IS_AST_SYM_VALUE(pbody->left) &&
1335 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1338 return isConformingBody(pbody->left,sym,body) ;
1340 if (astHasSymbol(pbody->left,sym) ||
1341 astHasSymbol(pbody->right,sym))
1346 /*------------------------------------------------------------------*/
1354 if (IS_AST_SYM_VALUE(pbody->left) &&
1355 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1358 if (IS_AST_SYM_VALUE(pbody->right) &&
1359 isSymbolEqual(AST_SYMBOL(pbody->right),sym))
1362 return isConformingBody(pbody->left,sym,body) &&
1363 isConformingBody(pbody->right,sym,body);
1370 if (IS_AST_SYM_VALUE(pbody->left) &&
1371 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1373 return isConformingBody (pbody->left,sym,body);
1375 /*------------------------------------------------------------------*/
1387 case SIZEOF: /* evaluate wihout code generation */
1389 return isConformingBody(pbody->left,sym,body) &&
1390 isConformingBody(pbody->right,sym,body);
1392 /*------------------------------------------------------------------*/
1395 /* if left has a pointer & right has loop
1396 control variable then we cannot */
1397 if (astHasPointer(pbody->left) &&
1398 astHasSymbol (pbody->right,sym))
1400 if (astHasVolatile(pbody->left))
1403 if (IS_AST_SYM_VALUE(pbody->left) &&
1404 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1407 if (astHasVolatile(pbody->left))
1410 return isConformingBody(pbody->left,sym,body) &&
1411 isConformingBody(pbody->right,sym,body);
1422 assert("Parser should not have generated this\n");
1424 /*------------------------------------------------------------------*/
1425 /*----------------------------*/
1426 /* comma operator */
1427 /*----------------------------*/
1429 return isConformingBody(pbody->left,sym,body) &&
1430 isConformingBody(pbody->right,sym,body);
1432 /*------------------------------------------------------------------*/
1433 /*----------------------------*/
1435 /*----------------------------*/
1439 /*------------------------------------------------------------------*/
1440 /*----------------------------*/
1441 /* return statement */
1442 /*----------------------------*/
1447 if (isLabelInAst (AST_SYMBOL(pbody->left),body))
1452 if (astHasSymbol(pbody->left,sym))
1459 return isConformingBody(pbody->left,sym,body) &&
1460 isConformingBody(pbody->right,sym,body);
1466 /*-----------------------------------------------------------------*/
1467 /* isLoopReversible - takes a for loop as input && returns true */
1468 /* if the for loop is reversible. If yes will set the value of */
1469 /* the loop control var & init value & termination value */
1470 /*-----------------------------------------------------------------*/
1471 bool isLoopReversible (ast *loop, symbol **loopCntrl,
1472 ast **init, ast **end )
1474 /* if option says don't do it then don't */
1475 if (optimize.noLoopReverse)
1477 /* there are several tests to determine this */
1479 /* for loop has to be of the form
1480 for ( <sym> = <const1> ;
1481 [<sym> < <const2>] ;
1482 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1484 if (! isLoopCountable (AST_FOR(loop,initExpr),
1485 AST_FOR(loop,condExpr),
1486 AST_FOR(loop,loopExpr),
1487 loopCntrl,init,end))
1490 /* now do some serious checking on the body of the loop
1493 return isConformingBody(loop->left,*loopCntrl,loop->left);
1497 /*-----------------------------------------------------------------*/
1498 /* replLoopSym - replace the loop sym by loop sym -1 */
1499 /*-----------------------------------------------------------------*/
1500 static void replLoopSym ( ast *body, symbol *sym)
1503 if (!body || IS_AST_LINK(body))
1506 if (IS_AST_SYM_VALUE(body)) {
1508 if (isSymbolEqual(AST_SYMBOL(body),sym)) {
1511 body->opval.op = '-';
1512 body->left = newAst_VALUE(symbolVal(sym));
1513 body->right= newAst_VALUE(constVal("1"));
1521 replLoopSym(body->left,sym);
1522 replLoopSym(body->right,sym);
1526 /*-----------------------------------------------------------------*/
1527 /* reverseLoop - do the actual loop reversal */
1528 /*-----------------------------------------------------------------*/
1529 ast *reverseLoop (ast *loop, symbol *sym, ast *init, ast *end)
1533 /* create the following tree
1538 if (sym) goto for_continue ;
1541 /* put it together piece by piece */
1542 rloop = newNode (NULLOP,
1543 createIf(newAst_VALUE(symbolVal(sym)),
1545 newAst_VALUE(symbolVal(AST_FOR(loop,continueLabel))),
1548 newAst_VALUE(symbolVal(sym)),
1551 replLoopSym(loop->left, sym);
1553 rloop = newNode(NULLOP,
1555 newAst_VALUE(symbolVal(sym)),
1556 newNode('-',end,init)),
1557 createLabel(AST_FOR(loop,continueLabel),
1562 newAst_VALUE(symbolVal(sym)),
1563 newAst_VALUE(constVal("1"))),
1566 return decorateType(rloop);
1570 #define DEMAND_INTEGER_PROMOTION
1572 #ifdef DEMAND_INTEGER_PROMOTION
1574 /*-----------------------------------------------------------------*/
1575 /* walk a tree looking for the leaves. Add a typecast to the given */
1576 /* type to each value leaf node. */
1577 /*-----------------------------------------------------------------*/
1578 void pushTypeCastToLeaves(sym_link *type, ast *node, ast **parentPtr)
1582 /* WTF? We should never get here. */
1586 if (!node->left && !node->right)
1588 /* We're at a leaf; if it's a value, apply the typecast */
1589 if (node->type == EX_VALUE && IS_INTEGRAL(TTYPE(node)))
1591 *parentPtr = decorateType(newNode(CAST,
1592 newAst_LINK(copyLinkChain(type)),
1600 pushTypeCastToLeaves(type, node->left, &(node->left));
1604 pushTypeCastToLeaves(type, node->right, &(node->right));
1611 /*-----------------------------------------------------------------*/
1612 /* Given an assignment operation in a tree, determine if the LHS */
1613 /* (the result) has a different (integer) type than the RHS. */
1614 /* If so, walk the RHS and add a typecast to the type of the LHS */
1615 /* to all leaf nodes. */
1616 /*-----------------------------------------------------------------*/
1617 void propAsgType(ast *tree)
1619 #ifdef DEMAND_INTEGER_PROMOTION
1620 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree)))
1622 /* Nothing to do here... */
1626 if (getSize(LTYPE(tree)) > getSize(RTYPE(tree)))
1628 pushTypeCastToLeaves(LTYPE(tree), tree->right, &(tree->right));
1635 /*-----------------------------------------------------------------*/
1636 /* decorateType - compute type for this tree also does type cheking*/
1637 /* this is done bottom up, since type have to flow upwards*/
1638 /* it also does constant folding, and paramater checking */
1639 /*-----------------------------------------------------------------*/
1640 ast *decorateType (ast *tree)
1648 /* if already has type then do nothing */
1649 if ( tree->decorated )
1652 tree->decorated = 1;
1654 /* print the line */
1655 /* if not block & function */
1656 if ( tree->type == EX_OP &&
1657 ( tree->opval.op != FUNCTION &&
1658 tree->opval.op != BLOCK &&
1659 tree->opval.op != NULLOP )) {
1660 filename = tree->filename ;
1661 lineno = tree->lineno ;
1664 /* if any child is an error | this one is an error do nothing */
1665 if ( tree->isError ||
1666 ( tree->left && tree->left->isError) ||
1667 ( tree->right && tree->right->isError ))
1670 /*------------------------------------------------------------------*/
1671 /*----------------------------*/
1672 /* leaf has been reached */
1673 /*----------------------------*/
1674 /* if this is of type value */
1675 /* just get the type */
1676 if ( tree->type == EX_VALUE ) {
1678 if ( IS_LITERAL(tree->opval.val->etype) ) {
1680 /* if this is a character array then declare it */
1681 if (IS_ARRAY(tree->opval.val->type))
1682 tree->opval.val = stringToSymbol(tree->opval.val);
1684 /* otherwise just copy the type information */
1685 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.val->type);
1686 if (funcInChain(tree->opval.val->type)) {
1687 tree->hasVargs = tree->opval.val->sym->hasVargs;
1688 tree->args = copyValueChain(tree->opval.val->sym->args) ;
1693 if ( tree->opval.val->sym ) {
1694 /* if the undefined flag is set then give error message */
1695 if (tree->opval.val->sym->undefined ) {
1696 werror(E_ID_UNDEF,tree->opval.val->sym->name) ;
1698 TTYPE(tree) = TETYPE(tree) =
1699 tree->opval.val->type = tree->opval.val->sym->type =
1700 tree->opval.val->etype = tree->opval.val->sym->etype =
1701 copyLinkChain(INTTYPE);
1705 /* if impilicit i.e. struct/union member then no type */
1706 if (tree->opval.val->sym->implicit )
1707 TTYPE(tree) = TETYPE(tree) = NULL ;
1711 /* else copy the type */
1712 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.val->type);
1714 /* and mark it as referenced */
1715 tree->opval.val->sym->isref = 1;
1716 /* if this is of type function or function pointer */
1717 if (funcInChain(tree->opval.val->type)) {
1718 tree->hasVargs = tree->opval.val->sym->hasVargs;
1719 tree->args = copyValueChain(tree->opval.val->sym->args) ;
1729 /* if type link for the case of cast */
1730 if ( tree->type == EX_LINK ) {
1731 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.lnk);
1738 dtl = decorateType (tree->left);
1739 dtr = decorateType (tree->right);
1741 /* this is to take care of situations
1742 when the tree gets rewritten */
1743 if (dtl != tree->left)
1745 if (dtr != tree->right)
1749 /* depending on type of operator do */
1751 switch (tree->opval.op) {
1752 /*------------------------------------------------------------------*/
1753 /*----------------------------*/
1755 /*----------------------------*/
1758 /* determine which is the array & which the index */
1759 if ((IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree))) && IS_INTEGRAL(LTYPE(tree))) {
1761 ast *tempTree = tree->left ;
1762 tree->left = tree->right ;
1763 tree->right= tempTree ;
1766 /* first check if this is a array or a pointer */
1767 if ( (!IS_ARRAY(LTYPE(tree))) && (!IS_PTR(LTYPE(tree)))) {
1768 werror(E_NEED_ARRAY_PTR,"[]");
1769 goto errorTreeReturn ;
1772 /* check if the type of the idx */
1773 if (!IS_INTEGRAL(RTYPE(tree))) {
1774 werror(E_IDX_NOT_INT);
1775 goto errorTreeReturn ;
1778 /* if the left is an rvalue then error */
1780 werror(E_LVALUE_REQUIRED,"array access");
1781 goto errorTreeReturn ;
1784 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree)->next);
1787 /*------------------------------------------------------------------*/
1788 /*----------------------------*/
1790 /*----------------------------*/
1792 /* if this is not a structure */
1793 if (!IS_STRUCT(LTYPE(tree))) {
1794 werror(E_STRUCT_UNION,".");
1795 goto errorTreeReturn ;
1797 TTYPE(tree) = structElemType (LTYPE(tree),
1798 (tree->right->type == EX_VALUE ?
1799 tree->right->opval.val : NULL ),&tree->args);
1800 TETYPE(tree) = getSpec(TTYPE(tree));
1803 /*------------------------------------------------------------------*/
1804 /*----------------------------*/
1805 /* struct/union pointer */
1806 /*----------------------------*/
1808 /* if not pointer to a structure */
1809 if (!IS_PTR(LTYPE(tree))) {
1811 goto errorTreeReturn ;
1814 if (!IS_STRUCT(LTYPE(tree)->next)) {
1815 werror(E_STRUCT_UNION,"->");
1816 goto errorTreeReturn ;
1819 TTYPE(tree) = structElemType (LTYPE(tree)->next,
1820 (tree->right->type == EX_VALUE ?
1821 tree->right->opval.val : NULL ),&tree->args);
1822 TETYPE(tree) = getSpec(TTYPE(tree));
1825 /*------------------------------------------------------------------*/
1826 /*----------------------------*/
1827 /* ++/-- operation */
1828 /*----------------------------*/
1829 case INC_OP: /* incerement operator unary so left only */
1832 sym_link *ltc = (tree->right ? RTYPE(tree) : LTYPE(tree) );
1833 COPYTYPE(TTYPE(tree),TETYPE(tree),ltc);
1834 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
1835 werror(E_CODE_WRITE,"++/--");
1844 /*------------------------------------------------------------------*/
1845 /*----------------------------*/
1847 /*----------------------------*/
1848 case '&': /* can be unary */
1849 /* if right is NULL then unary operation */
1850 if ( tree->right ) /* not an unary operation */ {
1852 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1853 werror(E_BITWISE_OP);
1854 werror(E_CONTINUE,"left & right types are ");
1855 printTypeChain(LTYPE(tree),stderr);
1856 fprintf(stderr,",");
1857 printTypeChain(RTYPE(tree),stderr);
1858 fprintf(stderr,"\n");
1859 goto errorTreeReturn ;
1862 /* if they are both literal */
1863 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1864 tree->type = EX_VALUE ;
1865 tree->opval.val = valBitwise (valFromType(LETYPE(tree)),
1866 valFromType(RETYPE(tree)),'&');
1868 tree->right = tree->left = NULL;
1869 TETYPE(tree) = tree->opval.val->etype ;
1870 TTYPE(tree) = tree->opval.val->type;
1874 /* see if this is a GETHBIT operation if yes
1877 ast *otree = optimizeGetHbit(tree);
1880 return decorateType(otree);
1883 /* if right or left is literal then result of that type*/
1884 if (IS_LITERAL(RTYPE(tree))) {
1886 TTYPE(tree) = copyLinkChain(RTYPE(tree));
1887 TETYPE(tree) = getSpec(TTYPE(tree));
1888 SPEC_SCLS(TETYPE(tree)) = S_AUTO;
1891 if (IS_LITERAL(LTYPE(tree))) {
1892 TTYPE(tree) = copyLinkChain(LTYPE(tree));
1893 TETYPE(tree) = getSpec(TTYPE(tree));
1894 SPEC_SCLS(TETYPE(tree)) = S_AUTO;
1899 computeType (LTYPE(tree), RTYPE(tree));
1900 TETYPE(tree) = getSpec(TTYPE(tree));
1903 LRVAL(tree) = RRVAL(tree) = 1;
1907 /*------------------------------------------------------------------*/
1908 /*----------------------------*/
1910 /*----------------------------*/
1912 p->class = DECLARATOR;
1913 /* if bit field then error */
1914 if (IS_BITVAR(tree->left->etype)) {
1915 werror (E_ILLEGAL_ADDR,"addrress of bit variable");
1916 goto errorTreeReturn ;
1919 if (SPEC_SCLS(tree->left->etype)== S_REGISTER ) {
1920 werror (E_ILLEGAL_ADDR,"address of register variable");
1921 goto errorTreeReturn;
1924 if (IS_FUNC(LTYPE(tree))) {
1925 werror(E_ILLEGAL_ADDR,"address of function");
1926 goto errorTreeReturn ;
1930 werror(E_LVALUE_REQUIRED,"address of");
1931 goto errorTreeReturn ;
1933 if (SPEC_SCLS(tree->left->etype) == S_CODE) {
1934 DCL_TYPE(p) = CPOINTER ;
1935 DCL_PTR_CONST(p) = port->mem.code_ro;
1938 if (SPEC_SCLS(tree->left->etype) == S_XDATA)
1939 DCL_TYPE(p) = FPOINTER;
1941 if (SPEC_SCLS(tree->left->etype) == S_XSTACK )
1942 DCL_TYPE(p) = PPOINTER ;
1944 if (SPEC_SCLS(tree->left->etype) == S_IDATA)
1945 DCL_TYPE(p) = IPOINTER ;
1947 if (SPEC_SCLS(tree->left->etype) == S_EEPROM)
1948 DCL_TYPE(p) = EEPPOINTER ;
1950 DCL_TYPE(p) = POINTER ;
1952 if (IS_AST_SYM_VALUE(tree->left)) {
1953 AST_SYMBOL(tree->left)->addrtaken = 1;
1954 AST_SYMBOL(tree->left)->allocreq = 1;
1957 p->next = LTYPE(tree);
1959 TETYPE(tree) = getSpec(TTYPE(tree));
1960 DCL_PTR_CONST(p) = SPEC_CONST(TETYPE(tree));
1961 DCL_PTR_VOLATILE(p) = SPEC_VOLATILE(TETYPE(tree));
1966 /*------------------------------------------------------------------*/
1967 /*----------------------------*/
1969 /*----------------------------*/
1971 /* if the rewrite succeeds then don't go any furthur */
1973 ast *wtree = optimizeRRCRLC ( tree );
1975 return decorateType(wtree) ;
1977 /*------------------------------------------------------------------*/
1978 /*----------------------------*/
1980 /*----------------------------*/
1982 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1983 werror(E_BITWISE_OP);
1984 werror(E_CONTINUE,"left & right types are ");
1985 printTypeChain(LTYPE(tree),stderr);
1986 fprintf(stderr,",");
1987 printTypeChain(RTYPE(tree),stderr);
1988 fprintf(stderr,"\n");
1989 goto errorTreeReturn ;
1992 /* if they are both literal then */
1993 /* rewrite the tree */
1994 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1995 tree->type = EX_VALUE ;
1996 tree->opval.val = valBitwise (valFromType(LETYPE(tree)),
1997 valFromType(RETYPE(tree)),
1999 tree->right = tree->left = NULL;
2000 TETYPE(tree) = tree->opval.val->etype;
2001 TTYPE(tree) = tree->opval.val->type;
2004 LRVAL(tree) = RRVAL(tree) = 1;
2005 TETYPE(tree) = getSpec (TTYPE(tree) =
2006 computeType(LTYPE(tree),
2009 /*------------------------------------------------------------------*/
2010 /*----------------------------*/
2012 /*----------------------------*/
2014 if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) {
2015 werror(E_INVALID_OP,"divide");
2016 goto errorTreeReturn ;
2018 /* if they are both literal then */
2019 /* rewrite the tree */
2020 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2021 tree->type = EX_VALUE ;
2022 tree->opval.val = valDiv (valFromType(LETYPE(tree)),
2023 valFromType(RETYPE(tree)));
2024 tree->right = tree->left = NULL;
2025 TETYPE(tree) = getSpec(TTYPE(tree) =
2026 tree->opval.val->type);
2029 LRVAL(tree) = RRVAL(tree) = 1;
2030 TETYPE(tree) = getSpec (TTYPE(tree) =
2031 computeType(LTYPE(tree),
2035 /*------------------------------------------------------------------*/
2036 /*----------------------------*/
2038 /*----------------------------*/
2040 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
2041 werror(E_BITWISE_OP);
2042 werror(E_CONTINUE,"left & right types are ");
2043 printTypeChain(LTYPE(tree),stderr);
2044 fprintf(stderr,",");
2045 printTypeChain(RTYPE(tree),stderr);
2046 fprintf(stderr,"\n");
2047 goto errorTreeReturn ;
2049 /* if they are both literal then */
2050 /* rewrite the tree */
2051 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2052 tree->type = EX_VALUE ;
2053 tree->opval.val = valMod (valFromType(LETYPE(tree)),
2054 valFromType(RETYPE(tree)));
2055 tree->right = tree->left = NULL;
2056 TETYPE(tree) = getSpec(TTYPE(tree) =
2057 tree->opval.val->type);
2060 LRVAL(tree) = RRVAL(tree) = 1;
2061 TETYPE(tree) = getSpec (TTYPE(tree) =
2062 computeType(LTYPE(tree),
2066 /*------------------------------------------------------------------*/
2067 /*----------------------------*/
2068 /* address dereference */
2069 /*----------------------------*/
2070 case '*': /* can be unary : if right is null then unary operation */
2071 if ( ! tree->right ) {
2072 if (!IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) {
2074 goto errorTreeReturn ;
2078 werror(E_LVALUE_REQUIRED,"pointer deref");
2079 goto errorTreeReturn ;
2081 TTYPE(tree) = copyLinkChain ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) ?
2082 LTYPE(tree)->next : NULL );
2083 TETYPE(tree) = getSpec(TTYPE(tree));
2084 tree->args = tree->left->args ;
2085 tree->hasVargs = tree->left->hasVargs ;
2086 SPEC_CONST(TETYPE(tree)) = DCL_PTR_CONST(LTYPE(tree));
2090 /*------------------------------------------------------------------*/
2091 /*----------------------------*/
2092 /* multiplication */
2093 /*----------------------------*/
2094 if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) {
2095 werror(E_INVALID_OP,"multiplication");
2096 goto errorTreeReturn ;
2099 /* if they are both literal then */
2100 /* rewrite the tree */
2101 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2102 tree->type = EX_VALUE ;
2103 tree->opval.val = valMult (valFromType(LETYPE(tree)),
2104 valFromType(RETYPE(tree)));
2105 tree->right = tree->left = NULL;
2106 TETYPE(tree) = getSpec(TTYPE(tree) =
2107 tree->opval.val->type);
2111 /* if left is a literal exchange left & right */
2112 if (IS_LITERAL(LTYPE(tree))) {
2113 ast *tTree = tree->left ;
2114 tree->left = tree->right ;
2115 tree->right= tTree ;
2118 LRVAL(tree) = RRVAL(tree) = 1;
2119 TETYPE(tree) = getSpec (TTYPE(tree) =
2120 computeType(LTYPE(tree),
2124 /*------------------------------------------------------------------*/
2125 /*----------------------------*/
2126 /* unary '+' operator */
2127 /*----------------------------*/
2130 if ( ! tree->right ) {
2131 if (!IS_INTEGRAL(LTYPE(tree))) {
2132 werror(E_UNARY_OP,'+');
2133 goto errorTreeReturn ;
2136 /* if left is a literal then do it */
2137 if (IS_LITERAL(LTYPE(tree))) {
2138 tree->type = EX_VALUE ;
2139 tree->opval.val = valFromType(LETYPE(tree));
2141 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2145 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2149 /*------------------------------------------------------------------*/
2150 /*----------------------------*/
2152 /*----------------------------*/
2154 /* this is not a unary operation */
2155 /* if both pointers then problem */
2156 if ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) &&
2157 (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)))) {
2158 werror(E_PTR_PLUS_PTR);
2159 goto errorTreeReturn ;
2162 if (!IS_ARITHMETIC(LTYPE(tree)) &&
2163 !IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) {
2164 werror(E_PLUS_INVALID,"+");
2165 goto errorTreeReturn ;
2168 if (!IS_ARITHMETIC(RTYPE(tree)) &&
2169 !IS_PTR(RTYPE(tree)) && !IS_ARRAY(RTYPE(tree))) {
2170 werror(E_PLUS_INVALID,"+");
2171 goto errorTreeReturn;
2173 /* if they are both literal then */
2174 /* rewrite the tree */
2175 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2176 tree->type = EX_VALUE ;
2177 tree->opval.val = valPlus (valFromType(LETYPE(tree)),
2178 valFromType(RETYPE(tree)));
2179 tree->right = tree->left = NULL;
2180 TETYPE(tree) = getSpec(TTYPE(tree) =
2181 tree->opval.val->type);
2185 /* if the right is a pointer or left is a literal
2186 xchange left & right */
2187 if (IS_ARRAY(RTYPE(tree)) ||
2188 IS_PTR(RTYPE(tree)) ||
2189 IS_LITERAL(LTYPE(tree))) {
2190 ast *tTree = tree->left ;
2191 tree->left = tree->right ;
2192 tree->right= tTree ;
2195 LRVAL(tree) = RRVAL(tree) = 1;
2196 /* if the left is a pointer */
2197 if (IS_PTR(LTYPE(tree)))
2198 TETYPE(tree) = getSpec(TTYPE(tree) =
2201 TETYPE(tree) = getSpec(TTYPE(tree) =
2202 computeType(LTYPE(tree),
2206 /*------------------------------------------------------------------*/
2207 /*----------------------------*/
2209 /*----------------------------*/
2210 case '-' : /* can be unary */
2211 /* if right is null then unary */
2212 if ( ! tree->right ) {
2214 if (!IS_ARITHMETIC(LTYPE(tree))) {
2215 werror(E_UNARY_OP,tree->opval.op);
2216 goto errorTreeReturn ;
2219 /* if left is a literal then do it */
2220 if (IS_LITERAL(LTYPE(tree))) {
2221 tree->type = EX_VALUE ;
2222 tree->opval.val = valUnaryPM(valFromType(LETYPE(tree)));
2224 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2228 TTYPE(tree) = LTYPE(tree);
2232 /*------------------------------------------------------------------*/
2233 /*----------------------------*/
2235 /*----------------------------*/
2237 if (!(IS_PTR(LTYPE(tree)) ||
2238 IS_ARRAY(LTYPE(tree)) ||
2239 IS_ARITHMETIC(LTYPE(tree)))) {
2240 werror(E_PLUS_INVALID,"-");
2241 goto errorTreeReturn ;
2244 if (!(IS_PTR(RTYPE(tree)) ||
2245 IS_ARRAY(RTYPE(tree)) ||
2246 IS_ARITHMETIC(RTYPE(tree)))) {
2247 werror(E_PLUS_INVALID,"-");
2248 goto errorTreeReturn ;
2251 if ( (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) &&
2252 ! (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)) ||
2253 IS_INTEGRAL(RTYPE(tree))) ) {
2254 werror(E_PLUS_INVALID,"-");
2255 goto errorTreeReturn ;
2258 /* if they are both literal then */
2259 /* rewrite the tree */
2260 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2261 tree->type = EX_VALUE ;
2262 tree->opval.val = valMinus (valFromType(LETYPE(tree)),
2263 valFromType(RETYPE(tree)));
2264 tree->right = tree->left = NULL;
2265 TETYPE(tree) = getSpec(TTYPE(tree) =
2266 tree->opval.val->type);
2270 /* if the left & right are equal then zero */
2271 if (isAstEqual(tree->left,tree->right)) {
2272 tree->type = EX_VALUE;
2273 tree->left = tree->right = NULL;
2274 tree->opval.val = constVal("0");
2275 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2279 /* if both of them are pointers or arrays then */
2280 /* the result is going to be an integer */
2281 if (( IS_ARRAY(LTYPE(tree)) || IS_PTR(LTYPE(tree))) &&
2282 ( IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree))))
2283 TETYPE(tree) = TTYPE(tree) = newIntLink();
2285 /* if only the left is a pointer */
2286 /* then result is a pointer */
2287 if (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree)))
2288 TETYPE(tree) = getSpec(TTYPE(tree) =
2291 TETYPE(tree) = getSpec (TTYPE(tree) =
2292 computeType(LTYPE(tree),
2294 LRVAL(tree) = RRVAL(tree) = 1;
2297 /*------------------------------------------------------------------*/
2298 /*----------------------------*/
2300 /*----------------------------*/
2302 /* can be only integral type */
2303 if (!IS_INTEGRAL(LTYPE(tree))) {
2304 werror(E_UNARY_OP,tree->opval.op);
2305 goto errorTreeReturn ;
2308 /* if left is a literal then do it */
2309 if (IS_LITERAL(LTYPE(tree))) {
2310 tree->type = EX_VALUE ;
2311 tree->opval.val = valComplement(valFromType(LETYPE(tree)));
2313 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2317 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2320 /*------------------------------------------------------------------*/
2321 /*----------------------------*/
2323 /*----------------------------*/
2325 /* can be pointer */
2326 if (!IS_ARITHMETIC(LTYPE(tree)) &&
2327 !IS_PTR(LTYPE(tree)) &&
2328 !IS_ARRAY(LTYPE(tree))) {
2329 werror(E_UNARY_OP,tree->opval.op);
2330 goto errorTreeReturn ;
2333 /* if left is a literal then do it */
2334 if (IS_LITERAL(LTYPE(tree))) {
2335 tree->type = EX_VALUE ;
2336 tree->opval.val = valNot(valFromType(LETYPE(tree)));
2338 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2342 TTYPE(tree) = TETYPE(tree) = newCharLink();
2345 /*------------------------------------------------------------------*/
2346 /*----------------------------*/
2348 /*----------------------------*/
2351 TTYPE(tree) = LTYPE(tree);
2352 TETYPE(tree) = LETYPE(tree);
2356 TTYPE(tree) = TETYPE(tree) = newCharLink();
2361 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(tree->left->etype)) {
2362 werror(E_SHIFT_OP_INVALID);
2363 werror(E_CONTINUE,"left & right types are ");
2364 printTypeChain(LTYPE(tree),stderr);
2365 fprintf(stderr,",");
2366 printTypeChain(RTYPE(tree),stderr);
2367 fprintf(stderr,"\n");
2368 goto errorTreeReturn ;
2371 /* if they are both literal then */
2372 /* rewrite the tree */
2373 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2374 tree->type = EX_VALUE ;
2375 tree->opval.val = valShift (valFromType(LETYPE(tree)),
2376 valFromType(RETYPE(tree)),
2377 (tree->opval.op == LEFT_OP ? 1 : 0));
2378 tree->right = tree->left = NULL;
2379 TETYPE(tree) = getSpec(TTYPE(tree) =
2380 tree->opval.val->type);
2383 /* if only the right side is a literal & we are
2384 shifting more than size of the left operand then zero */
2385 if (IS_LITERAL(RTYPE(tree)) &&
2386 ((int)floatFromVal( valFromType(RETYPE(tree)))) >=
2387 (getSize(LTYPE(tree))*8)) {
2388 werror(W_SHIFT_CHANGED,
2389 (tree->opval.op == LEFT_OP ? "left" : "right"));
2390 tree->type = EX_VALUE;
2391 tree->left = tree->right = NULL;
2392 tree->opval.val = constVal("0");
2393 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2396 LRVAL(tree) = RRVAL(tree) = 1;
2397 if (IS_LITERAL(LTYPE(tree)) && !IS_LITERAL(RTYPE(tree))) {
2398 COPYTYPE(TTYPE(tree),TETYPE(tree),RTYPE(tree));
2400 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2404 /*------------------------------------------------------------------*/
2405 /*----------------------------*/
2407 /*----------------------------*/
2408 case CAST: /* change the type */
2409 /* cannot cast to an aggregate type */
2410 if (IS_AGGREGATE(LTYPE(tree))) {
2411 werror(E_CAST_ILLEGAL);
2412 goto errorTreeReturn ;
2415 /* if the right is a literal replace the tree */
2416 if (IS_LITERAL(RETYPE(tree)) && !IS_PTR(LTYPE(tree))) {
2417 tree->type = EX_VALUE ;
2419 valCastLiteral(LTYPE(tree),
2420 floatFromVal(valFromType(RETYPE(tree))));
2423 TTYPE(tree) = tree->opval.val->type;
2424 tree->values.literalFromCast = 1;
2427 TTYPE(tree) = LTYPE(tree);
2431 TETYPE(tree) = getSpec(TTYPE(tree));
2435 /*------------------------------------------------------------------*/
2436 /*----------------------------*/
2437 /* logical &&, || */
2438 /*----------------------------*/
2441 /* each must me arithmetic type or be a pointer */
2442 if (!IS_PTR(LTYPE(tree)) &&
2443 !IS_ARRAY(LTYPE(tree)) &&
2444 !IS_INTEGRAL(LTYPE(tree))) {
2445 werror(E_COMPARE_OP);
2446 goto errorTreeReturn ;
2449 if (!IS_PTR(RTYPE(tree)) &&
2450 !IS_ARRAY(RTYPE(tree)) &&
2451 !IS_INTEGRAL(RTYPE(tree))) {
2452 werror(E_COMPARE_OP);
2453 goto errorTreeReturn ;
2455 /* if they are both literal then */
2456 /* rewrite the tree */
2457 if (IS_LITERAL(RTYPE(tree)) &&
2458 IS_LITERAL(LTYPE(tree))) {
2459 tree->type = EX_VALUE ;
2460 tree->opval.val = valLogicAndOr (valFromType(LETYPE(tree)),
2461 valFromType(RETYPE(tree)),
2463 tree->right = tree->left = NULL;
2464 TETYPE(tree) = getSpec(TTYPE(tree) =
2465 tree->opval.val->type);
2468 LRVAL(tree) = RRVAL(tree) = 1;
2469 TTYPE(tree) = TETYPE(tree) = newCharLink();
2472 /*------------------------------------------------------------------*/
2473 /*----------------------------*/
2474 /* comparison operators */
2475 /*----------------------------*/
2483 ast *lt = optimizeCompare(tree);
2489 /* if they are pointers they must be castable */
2490 if ( IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree))) {
2491 if (checkType(LTYPE(tree),RTYPE(tree)) == 0) {
2492 werror(E_COMPARE_OP);
2493 fprintf(stderr,"comparing type ");
2494 printTypeChain(LTYPE(tree),stderr);
2495 fprintf(stderr,"to type ");
2496 printTypeChain(RTYPE(tree),stderr);
2497 fprintf(stderr,"\n");
2498 goto errorTreeReturn ;
2501 /* else they should be promotable to one another */
2503 if (!( ( IS_PTR(LTYPE(tree)) && IS_LITERAL(RTYPE(tree))) ||
2504 ( IS_PTR(RTYPE(tree)) && IS_LITERAL(LTYPE(tree)))))
2506 if (checkType (LTYPE(tree),RTYPE(tree)) == 0 ) {
2507 werror(E_COMPARE_OP);
2508 fprintf(stderr,"comparing type ");
2509 printTypeChain(LTYPE(tree),stderr);
2510 fprintf(stderr,"to type ");
2511 printTypeChain(RTYPE(tree),stderr);
2512 fprintf(stderr,"\n");
2513 goto errorTreeReturn ;
2517 /* if they are both literal then */
2518 /* rewrite the tree */
2519 if (IS_LITERAL(RTYPE(tree)) &&
2520 IS_LITERAL(LTYPE(tree))) {
2521 tree->type = EX_VALUE ;
2522 tree->opval.val = valCompare (valFromType(LETYPE(tree)),
2523 valFromType(RETYPE(tree)),
2525 tree->right = tree->left = NULL;
2526 TETYPE(tree) = getSpec(TTYPE(tree) =
2527 tree->opval.val->type);
2530 LRVAL(tree) = RRVAL(tree) = 1;
2531 TTYPE(tree) = TETYPE(tree) = newCharLink();
2534 /*------------------------------------------------------------------*/
2535 /*----------------------------*/
2537 /*----------------------------*/
2538 case SIZEOF : /* evaluate wihout code generation */
2539 /* change the type to a integer */
2540 tree->type = EX_VALUE;
2541 sprintf(buffer,"%d",(getSize(tree->right->ftype)));
2542 tree->opval.val = constVal(buffer);
2543 tree->right = tree->left = NULL;
2544 TETYPE(tree) = getSpec(TTYPE(tree) =
2545 tree->opval.val->type);
2548 /*------------------------------------------------------------------*/
2549 /*----------------------------*/
2550 /* conditional operator '?' */
2551 /*----------------------------*/
2553 /* the type is one on the left */
2554 TTYPE(tree) = LTYPE(tree);
2555 TETYPE(tree)= getSpec (TTYPE(tree));
2559 /* if they don't match we have a problem */
2560 if (checkType( LTYPE(tree), RTYPE(tree)) == 0) {
2561 werror(E_TYPE_MISMATCH,"conditional operator"," ");
2562 goto errorTreeReturn ;
2565 TTYPE(tree) = computeType(LTYPE(tree),RTYPE(tree));
2566 TETYPE(tree)= getSpec(TTYPE(tree));
2570 /*------------------------------------------------------------------*/
2571 /*----------------------------*/
2572 /* assignment operators */
2573 /*----------------------------*/
2576 /* for these it must be both must be integral */
2577 if (!IS_ARITHMETIC(LTYPE(tree)) ||
2578 !IS_ARITHMETIC(RTYPE(tree))) {
2579 werror (E_OPS_INTEGRAL);
2580 goto errorTreeReturn ;
2583 TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree));
2585 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2586 werror(E_CODE_WRITE," ");
2589 werror(E_LVALUE_REQUIRED,"*= or /=");
2590 goto errorTreeReturn ;
2603 /* for these it must be both must be integral */
2604 if (!IS_INTEGRAL(LTYPE(tree)) ||
2605 !IS_INTEGRAL(RTYPE(tree))) {
2606 werror (E_OPS_INTEGRAL);
2607 goto errorTreeReturn ;
2610 TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree));
2612 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2613 werror(E_CODE_WRITE," ");
2616 werror(E_LVALUE_REQUIRED,"&= or |= or ^= or >>= or <<=");
2617 goto errorTreeReturn ;
2625 /*------------------------------------------------------------------*/
2626 /*----------------------------*/
2628 /*----------------------------*/
2630 if (!(IS_PTR(LTYPE(tree)) ||
2631 IS_ARITHMETIC(LTYPE(tree)))) {
2632 werror(E_PLUS_INVALID,"-=");
2633 goto errorTreeReturn ;
2636 if (!(IS_PTR(RTYPE(tree)) ||
2637 IS_ARITHMETIC(RTYPE(tree)))) {
2638 werror(E_PLUS_INVALID,"-=");
2639 goto errorTreeReturn ;
2642 TETYPE(tree) = getSpec (TTYPE(tree) =
2643 computeType(LTYPE(tree),
2646 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2647 werror(E_CODE_WRITE," ");
2650 werror(E_LVALUE_REQUIRED,"-=");
2651 goto errorTreeReturn ;
2659 /*------------------------------------------------------------------*/
2660 /*----------------------------*/
2662 /*----------------------------*/
2664 /* this is not a unary operation */
2665 /* if both pointers then problem */
2666 if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) ) {
2667 werror(E_PTR_PLUS_PTR);
2668 goto errorTreeReturn ;
2671 if (!IS_ARITHMETIC(LTYPE(tree)) && !IS_PTR(LTYPE(tree))) {
2672 werror(E_PLUS_INVALID,"+=");
2673 goto errorTreeReturn ;
2676 if (!IS_ARITHMETIC(RTYPE(tree)) && !IS_PTR(RTYPE(tree))) {
2677 werror(E_PLUS_INVALID,"+=");
2678 goto errorTreeReturn;
2681 TETYPE(tree) = getSpec (TTYPE(tree) =
2682 computeType(LTYPE(tree),
2685 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2686 werror(E_CODE_WRITE," ");
2689 werror(E_LVALUE_REQUIRED,"+=");
2690 goto errorTreeReturn ;
2693 tree->right = decorateType(newNode('+',copyAst(tree->left),tree->right));
2694 tree->opval.op = '=';
2700 /*------------------------------------------------------------------*/
2701 /*----------------------------*/
2702 /* straight assignemnt */
2703 /*----------------------------*/
2705 /* cannot be an aggregate */
2706 if (IS_AGGREGATE(LTYPE(tree))) {
2707 werror(E_AGGR_ASSIGN);
2708 goto errorTreeReturn;
2711 /* they should either match or be castable */
2712 if (checkType (LTYPE(tree),RTYPE(tree)) == 0) {
2713 werror(E_TYPE_MISMATCH,"assignment"," ");
2714 fprintf(stderr,"type --> '");
2715 printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' ");
2716 fprintf(stderr,"assigned to type --> '");
2717 printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n");
2718 goto errorTreeReturn ;
2721 /* if the left side of the tree is of type void
2722 then report error */
2723 if (IS_VOID(LTYPE(tree))) {
2724 werror(E_CAST_ZERO);
2725 fprintf(stderr,"type --> '");
2726 printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' ");
2727 fprintf(stderr,"assigned to type --> '");
2728 printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n");
2731 /* extra checks for pointer types */
2732 if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) &&
2733 !IS_GENPTR(LTYPE(tree))) {
2734 if (DCL_TYPE(LTYPE(tree)) != DCL_TYPE(RTYPE(tree)))
2735 werror(W_PTR_ASSIGN);
2738 TETYPE(tree) = getSpec(TTYPE(tree) =
2742 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2743 werror(E_CODE_WRITE," ");
2746 werror(E_LVALUE_REQUIRED,"=");
2747 goto errorTreeReturn ;
2754 /*------------------------------------------------------------------*/
2755 /*----------------------------*/
2756 /* comma operator */
2757 /*----------------------------*/
2759 TETYPE(tree) = getSpec(TTYPE(tree) = RTYPE(tree));
2762 /*------------------------------------------------------------------*/
2763 /*----------------------------*/
2765 /*----------------------------*/
2769 if (processParms (tree->left,
2771 tree->right,&parmNumber))
2772 goto errorTreeReturn ;
2774 if (options.stackAuto || IS_RENT(LETYPE(tree))) {
2775 tree->left->args = reverseVal(tree->left->args);
2776 reverseParms(tree->right);
2779 tree->args = tree->left->args ;
2780 TETYPE(tree) = getSpec (TTYPE(tree) = LTYPE(tree)->next);
2783 /*------------------------------------------------------------------*/
2784 /*----------------------------*/
2785 /* return statement */
2786 /*----------------------------*/
2791 if (checkType(currFunc->type->next,RTYPE(tree)) == 0) {
2792 werror(E_RETURN_MISMATCH);
2793 goto errorTreeReturn ;
2796 if (IS_VOID(currFunc->type->next)
2798 !IS_VOID(RTYPE(tree))) {
2799 werror(E_FUNC_VOID);
2800 goto errorTreeReturn ;
2803 /* if there is going to be a casing required then add it */
2804 if (checkType(currFunc->type->next,RTYPE(tree)) < 0 )
2806 #if 0 && defined DEMAND_INTEGER_PROMOTION
2807 if (IS_INTEGRAL(currFunc->type->next))
2809 pushTypeCastToLeaves(currFunc->type->next, tree->right, &(tree->right));
2815 decorateType(newNode(CAST,
2816 newAst_LINK(copyLinkChain(currFunc->type->next)),
2826 if (!IS_VOID(currFunc->type->next) && tree->right == NULL ) {
2827 werror(E_VOID_FUNC,currFunc->name);
2828 goto errorTreeReturn ;
2831 TTYPE(tree) = TETYPE(tree) = NULL ;
2834 /*------------------------------------------------------------------*/
2835 /*----------------------------*/
2836 /* switch statement */
2837 /*----------------------------*/
2839 /* the switch value must be an integer */
2840 if (!IS_INTEGRAL(LTYPE(tree))) {
2841 werror (E_SWITCH_NON_INTEGER);
2842 goto errorTreeReturn ;
2845 TTYPE(tree) = TETYPE(tree) = NULL ;
2848 /*------------------------------------------------------------------*/
2849 /*----------------------------*/
2851 /*----------------------------*/
2853 tree->left = backPatchLabels(tree->left,
2856 TTYPE(tree) = TETYPE(tree) = NULL;
2859 /*------------------------------------------------------------------*/
2860 /*----------------------------*/
2862 /*----------------------------*/
2865 decorateType(resolveSymbols(AST_FOR(tree,initExpr)));
2866 decorateType(resolveSymbols(AST_FOR(tree,condExpr)));
2867 decorateType(resolveSymbols(AST_FOR(tree,loopExpr)));
2869 /* if the for loop is reversible then
2870 reverse it otherwise do what we normally
2876 if (isLoopReversible (tree,&sym,&init,&end))
2877 return reverseLoop (tree,sym,init,end);
2879 return decorateType(createFor ( AST_FOR(tree,trueLabel),
2880 AST_FOR(tree,continueLabel) ,
2881 AST_FOR(tree,falseLabel) ,
2882 AST_FOR(tree,condLabel) ,
2883 AST_FOR(tree,initExpr) ,
2884 AST_FOR(tree,condExpr) ,
2885 AST_FOR(tree,loopExpr),
2889 TTYPE(tree) = TETYPE(tree) = NULL ;
2893 /* some error found this tree will be killed */
2895 TTYPE(tree) = TETYPE(tree) = newCharLink();
2896 tree->opval.op = NULLOP ;
2902 /*-----------------------------------------------------------------*/
2903 /* sizeofOp - processes size of operation */
2904 /*-----------------------------------------------------------------*/
2905 value *sizeofOp( sym_link *type)
2909 /* get the size and convert it to character */
2910 sprintf (buff,"%d", getSize(type));
2912 /* now convert into value */
2913 return constVal (buff);
2917 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
2918 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
2919 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
2920 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
2921 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
2922 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
2923 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
2925 /*-----------------------------------------------------------------*/
2926 /* backPatchLabels - change and or not operators to flow control */
2927 /*-----------------------------------------------------------------*/
2928 ast *backPatchLabels (ast *tree, symbol *trueLabel, symbol *falseLabel )
2934 if ( ! (IS_ANDORNOT(tree)))
2937 /* if this an and */
2939 static int localLbl = 0 ;
2940 symbol *localLabel ;
2942 sprintf (buffer,"_and_%d",localLbl++);
2943 localLabel = newSymbol(buffer,NestLevel);
2945 tree->left = backPatchLabels (tree->left, localLabel,falseLabel);
2947 /* if left is already a IFX then just change the if true label in that */
2948 if (!IS_IFX(tree->left))
2949 tree->left = newIfxNode(tree->left,localLabel,falseLabel);
2951 tree->right = backPatchLabels(tree->right,trueLabel,falseLabel);
2952 /* right is a IFX then just join */
2953 if (IS_IFX(tree->right))
2954 return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right));
2956 tree->right = createLabel(localLabel,tree->right);
2957 tree->right = newIfxNode(tree->right,trueLabel,falseLabel);
2959 return newNode(NULLOP,tree->left,tree->right);
2962 /* if this is an or operation */
2964 static int localLbl = 0 ;
2965 symbol *localLabel ;
2967 sprintf (buffer,"_or_%d",localLbl++);
2968 localLabel = newSymbol(buffer,NestLevel);
2970 tree->left = backPatchLabels (tree->left, trueLabel,localLabel);
2972 /* if left is already a IFX then just change the if true label in that */
2973 if (!IS_IFX(tree->left))
2974 tree->left = newIfxNode(tree->left,trueLabel,localLabel);
2976 tree->right = backPatchLabels(tree->right,trueLabel,falseLabel);
2977 /* right is a IFX then just join */
2978 if (IS_IFX(tree->right))
2979 return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right));
2981 tree->right = createLabel(localLabel,tree->right);
2982 tree->right = newIfxNode(tree->right,trueLabel,falseLabel);
2984 return newNode(NULLOP,tree->left,tree->right);
2989 int wasnot = IS_NOT(tree->left);
2990 tree->left = backPatchLabels (tree->left,falseLabel,trueLabel);
2992 /* if the left is already a IFX */
2993 if ( ! IS_IFX(tree->left) )
2994 tree->left = newNode (IFX,tree->left,NULL);
2997 tree->left->trueLabel = trueLabel ;
2998 tree->left->falseLabel= falseLabel ;
3000 tree->left->trueLabel = falseLabel ;
3001 tree->left->falseLabel= trueLabel ;
3007 tree->trueLabel = trueLabel ;
3008 tree->falseLabel= falseLabel;
3015 /*-----------------------------------------------------------------*/
3016 /* createBlock - create expression tree for block */
3017 /*-----------------------------------------------------------------*/
3018 ast *createBlock ( symbol *decl, ast *body )
3022 /* if the block has nothing */
3026 ex = newNode(BLOCK,NULL,body);
3027 ex->values.sym = decl ;
3029 ex->right = ex->right ;
3035 /*-----------------------------------------------------------------*/
3036 /* createLabel - creates the expression tree for labels */
3037 /*-----------------------------------------------------------------*/
3038 ast *createLabel ( symbol *label, ast *stmnt )
3041 char name[SDCC_NAME_MAX+1];
3044 /* must create fresh symbol if the symbol name */
3045 /* exists in the symbol table, since there can */
3046 /* be a variable with the same name as the labl */
3047 if ((csym = findSym (SymbolTab,NULL,label->name)) &&
3048 (csym->level == label->level))
3049 label = newSymbol(label->name,label->level);
3051 /* change the name before putting it in add _*/
3052 sprintf (name,"%s",label->name);
3054 /* put the label in the LabelSymbol table */
3055 /* but first check if a label of the same */
3057 if ( (csym = findSym(LabelTab,NULL,name)))
3058 werror(E_DUPLICATE_LABEL,label->name);
3060 addSym (LabelTab, label, name,label->level,0);
3063 label->key = labelKey++ ;
3064 rValue = newNode (LABEL,newAst_VALUE(symbolVal(label)),stmnt);
3070 /*-----------------------------------------------------------------*/
3071 /* createCase - generates the parsetree for a case statement */
3072 /*-----------------------------------------------------------------*/
3073 ast *createCase (ast *swStat, ast *caseVal, ast *stmnt )
3075 char caseLbl[SDCC_NAME_MAX+1];
3079 /* if the switch statement does not exist */
3080 /* then case is out of context */
3082 werror(E_CASE_CONTEXT);
3086 caseVal = decorateType(resolveSymbols(caseVal));
3087 /* if not a constant then error */
3088 if (!IS_LITERAL(caseVal->ftype)) {
3089 werror(E_CASE_CONSTANT);
3093 /* if not a integer than error */
3094 if (!IS_INTEGRAL(caseVal->ftype)) {
3095 werror(E_CASE_NON_INTEGER);
3099 /* find the end of the switch values chain */
3100 if (!(val = swStat->values.switchVals.swVals))
3101 swStat->values.switchVals.swVals = caseVal->opval.val ;
3103 /* also order the cases according to value */
3105 int cVal = (int) floatFromVal(caseVal->opval.val);
3106 while (val && (int) floatFromVal(val) < cVal) {
3111 /* if we reached the end then */
3113 pval->next = caseVal->opval.val;
3115 /* we found a value greater than */
3116 /* the current value we must add this */
3117 /* before the value */
3118 caseVal->opval.val->next = val;
3120 /* if this was the first in chain */
3121 if (swStat->values.switchVals.swVals == val)
3122 swStat->values.switchVals.swVals =
3125 pval->next = caseVal->opval.val;
3130 /* create the case label */
3131 sprintf(caseLbl,"_case_%d_%d",
3132 swStat->values.switchVals.swNum,
3133 (int) floatFromVal(caseVal->opval.val));
3135 rexpr = createLabel(newSymbol(caseLbl,0),stmnt);
3140 /*-----------------------------------------------------------------*/
3141 /* createDefault - creates the parse tree for the default statement*/
3142 /*-----------------------------------------------------------------*/
3143 ast *createDefault (ast *swStat, ast *stmnt)
3145 char defLbl[SDCC_NAME_MAX+1];
3147 /* if the switch statement does not exist */
3148 /* then case is out of context */
3150 werror(E_CASE_CONTEXT);
3154 /* turn on the default flag */
3155 swStat->values.switchVals.swDefault = 1 ;
3157 /* create the label */
3158 sprintf (defLbl,"_default_%d",swStat->values.switchVals.swNum);
3159 return createLabel(newSymbol(defLbl,0),stmnt);
3162 /*-----------------------------------------------------------------*/
3163 /* createIf - creates the parsetree for the if statement */
3164 /*-----------------------------------------------------------------*/
3165 ast *createIf ( ast *condAst, ast *ifBody, ast *elseBody )
3167 static int Lblnum = 0 ;
3169 symbol *ifTrue , *ifFalse, *ifEnd ;
3171 /* if neither exists */
3172 if (! elseBody && !ifBody)
3175 /* create the labels */
3176 sprintf (buffer,"_iffalse_%d",Lblnum);
3177 ifFalse = newSymbol (buffer,NestLevel);
3178 /* if no else body then end == false */
3182 sprintf (buffer,"_ifend_%d",Lblnum);
3183 ifEnd = newSymbol (buffer,NestLevel);
3186 sprintf (buffer,"_iftrue_%d",Lblnum);
3187 ifTrue = newSymbol (buffer,NestLevel);
3191 /* attach the ifTrue label to the top of it body */
3192 ifBody = createLabel(ifTrue,ifBody);
3193 /* attach a goto end to the ifBody if else is present */
3195 ifBody = newNode(NULLOP,ifBody,
3197 newAst_VALUE(symbolVal(ifEnd)),
3199 /* put the elseLabel on the else body */
3200 elseBody = createLabel (ifFalse,elseBody);
3201 /* out the end at the end of the body */
3202 elseBody = newNode(NULLOP,
3204 createLabel(ifEnd,NULL));
3207 ifBody = newNode(NULLOP,ifBody,
3208 createLabel(ifFalse,NULL));
3210 condAst = backPatchLabels (condAst,ifTrue,ifFalse);
3211 if (IS_IFX(condAst))
3214 ifTree = newIfxNode(condAst,ifTrue,ifFalse);
3216 return newNode(NULLOP,ifTree,
3217 newNode(NULLOP,ifBody,elseBody));
3221 /*-----------------------------------------------------------------*/
3222 /* createDo - creates parse tree for do */
3225 /* _docontinue_n: */
3226 /* condition_expression +-> trueLabel -> _dobody_n */
3228 /* +-> falseLabel-> _dobreak_n */
3230 /*-----------------------------------------------------------------*/
3231 ast *createDo ( symbol *trueLabel, symbol *continueLabel,
3232 symbol *falseLabel, ast *condAst, ast *doBody )
3237 /* if the body does not exist then it is simple */
3239 condAst = backPatchLabels(condAst,continueLabel,NULL);
3240 doTree = (IS_IFX(condAst) ? createLabel(continueLabel,condAst)
3241 : newNode(IFX,createLabel(continueLabel,condAst),NULL));
3242 doTree->trueLabel = continueLabel ;
3243 doTree->falseLabel= NULL ;
3247 /* otherwise we have a body */
3248 condAst = backPatchLabels(condAst,trueLabel,falseLabel);
3250 /* attach the body label to the top */
3251 doBody = createLabel(trueLabel,doBody);
3252 /* attach the continue label to end of body */
3253 doBody = newNode(NULLOP, doBody,
3254 createLabel(continueLabel,NULL));
3256 /* now put the break label at the end */
3257 if (IS_IFX(condAst))
3260 doTree = newIfxNode(condAst,trueLabel,falseLabel);
3262 doTree = newNode(NULLOP,doTree,createLabel(falseLabel,NULL));
3264 /* putting it together */
3265 return newNode(NULLOP,doBody,doTree);
3268 /*-----------------------------------------------------------------*/
3269 /* createFor - creates parse tree for 'for' statement */
3272 /* condExpr +-> trueLabel -> _forbody_n */
3274 /* +-> falseLabel-> _forbreak_n */
3277 /* _forcontinue_n: */
3279 /* goto _forcond_n ; */
3281 /*-----------------------------------------------------------------*/
3282 ast *createFor ( symbol *trueLabel, symbol *continueLabel ,
3283 symbol *falseLabel,symbol *condLabel ,
3284 ast *initExpr, ast *condExpr, ast *loopExpr,
3289 /* if loopexpression not present then we can generate it */
3290 /* the same way as a while */
3292 return newNode(NULLOP,initExpr,
3293 createWhile (trueLabel, continueLabel,
3294 falseLabel,condExpr, forBody ));
3295 /* vanilla for statement */
3296 condExpr = backPatchLabels(condExpr,trueLabel,falseLabel);
3298 if (condExpr && !IS_IFX(condExpr))
3299 condExpr = newIfxNode(condExpr,trueLabel,falseLabel);
3302 /* attach condition label to condition */
3303 condExpr = createLabel(condLabel,condExpr);
3305 /* attach body label to body */
3306 forBody = createLabel(trueLabel,forBody);
3308 /* attach continue to forLoop expression & attach */
3309 /* goto the forcond @ and of loopExpression */
3310 loopExpr = createLabel(continueLabel,
3314 newAst_VALUE(symbolVal(condLabel)),
3316 /* now start putting them together */
3317 forTree = newNode(NULLOP,initExpr,condExpr);
3318 forTree = newNode(NULLOP,forTree,forBody);
3319 forTree = newNode(NULLOP,forTree,loopExpr);
3320 /* finally add the break label */
3321 forTree = newNode(NULLOP,forTree,
3322 createLabel(falseLabel,NULL));
3326 /*-----------------------------------------------------------------*/
3327 /* createWhile - creates parse tree for while statement */
3328 /* the while statement will be created as follows */
3330 /* _while_continue_n: */
3331 /* condition_expression +-> trueLabel -> _while_boby_n */
3333 /* +-> falseLabel -> _while_break_n*/
3334 /* _while_body_n: */
3336 /* goto _while_continue_n */
3337 /* _while_break_n: */
3338 /*-----------------------------------------------------------------*/
3339 ast *createWhile (symbol *trueLabel, symbol *continueLabel,
3340 symbol *falseLabel,ast *condExpr, ast *whileBody )
3344 /* put the continue label */
3345 condExpr = backPatchLabels (condExpr,trueLabel,falseLabel);
3346 condExpr = createLabel(continueLabel,condExpr);
3347 condExpr->lineno = 0;
3349 /* put the body label in front of the body */
3350 whileBody = createLabel(trueLabel,whileBody);
3351 whileBody->lineno = 0;
3352 /* put a jump to continue at the end of the body */
3353 /* and put break label at the end of the body */
3354 whileBody = newNode(NULLOP,
3357 newAst_VALUE(symbolVal(continueLabel)),
3358 createLabel(falseLabel,NULL)));
3360 /* put it all together */
3361 if ( IS_IFX(condExpr) )
3362 whileTree = condExpr ;
3364 whileTree = newNode (IFX, condExpr,NULL );
3365 /* put the true & false labels in place */
3366 whileTree->trueLabel = trueLabel ;
3367 whileTree->falseLabel= falseLabel;
3370 return newNode(NULLOP,whileTree,whileBody );
3373 /*-----------------------------------------------------------------*/
3374 /* optimizeGetHbit - get highest order bit of the expression */
3375 /*-----------------------------------------------------------------*/
3376 ast *optimizeGetHbit (ast *tree)
3379 /* if this is not a bit and */
3380 if (!IS_BITAND(tree))
3383 /* will look for tree of the form
3384 ( expr >> ((sizeof expr) -1) ) & 1 */
3385 if (!IS_AST_LIT_VALUE(tree->right))
3388 if (AST_LIT_VALUE(tree->right) != 1)
3391 if (!IS_RIGHT_OP(tree->left))
3394 if (!IS_AST_LIT_VALUE(tree->left->right))
3397 if ((i = AST_LIT_VALUE(tree->left->right)) !=
3398 ( j = (getSize(TTYPE(tree->left->left))*8 - 1)))
3401 return decorateType(newNode(GETHBIT,tree->left->left,NULL));
3405 /*-----------------------------------------------------------------*/
3406 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3407 /*-----------------------------------------------------------------*/
3408 ast *optimizeRRCRLC ( ast *root )
3410 /* will look for trees of the form
3411 (?expr << 1) | (?expr >> 7) or
3412 (?expr >> 7) | (?expr << 1) will make that
3413 into a RLC : operation ..
3415 (?expr >> 1) | (?expr << 7) or
3416 (?expr << 7) | (?expr >> 1) will make that
3417 into a RRC operation
3418 note : by 7 I mean (number of bits required to hold the
3420 /* if the root operations is not a | operation the not */
3421 if (!IS_BITOR(root))
3424 /* I have to think of a better way to match patterns this sucks */
3425 /* that aside let start looking for the first case : I use a the
3426 negative check a lot to improve the efficiency */
3427 /* (?expr << 1) | (?expr >> 7) */
3428 if (IS_LEFT_OP(root->left) &&
3429 IS_RIGHT_OP(root->right) ) {
3431 if (!SPEC_USIGN(TETYPE(root->left->left)))
3434 if (!IS_AST_LIT_VALUE(root->left->right) ||
3435 !IS_AST_LIT_VALUE(root->right->right))
3438 /* make sure it is the same expression */
3439 if (!isAstEqual(root->left->left,
3443 if (AST_LIT_VALUE(root->left->right) != 1 )
3446 if (AST_LIT_VALUE(root->right->right) !=
3447 (getSize(TTYPE(root->left->left))*8 - 1))
3450 /* whew got the first case : create the AST */
3451 return newNode(RLC,root->left->left,NULL);
3455 /* check for second case */
3456 /* (?expr >> 7) | (?expr << 1) */
3457 if (IS_LEFT_OP(root->right) &&
3458 IS_RIGHT_OP(root->left) ) {
3460 if (!SPEC_USIGN(TETYPE(root->left->left)))
3463 if (!IS_AST_LIT_VALUE(root->left->right) ||
3464 !IS_AST_LIT_VALUE(root->right->right))
3467 /* make sure it is the same symbol */
3468 if (!isAstEqual(root->left->left,
3472 if (AST_LIT_VALUE(root->right->right) != 1 )
3475 if (AST_LIT_VALUE(root->left->right) !=
3476 (getSize(TTYPE(root->left->left))*8 - 1))
3479 /* whew got the first case : create the AST */
3480 return newNode(RLC,root->left->left,NULL);
3485 /* third case for RRC */
3486 /* (?symbol >> 1) | (?symbol << 7) */
3487 if (IS_LEFT_OP(root->right) &&
3488 IS_RIGHT_OP(root->left) ) {
3490 if (!SPEC_USIGN(TETYPE(root->left->left)))
3493 if (!IS_AST_LIT_VALUE(root->left->right) ||
3494 !IS_AST_LIT_VALUE(root->right->right))
3497 /* make sure it is the same symbol */
3498 if (!isAstEqual(root->left->left,
3502 if (AST_LIT_VALUE(root->left->right) != 1 )
3505 if (AST_LIT_VALUE(root->right->right) !=
3506 (getSize(TTYPE(root->left->left))*8 - 1))
3509 /* whew got the first case : create the AST */
3510 return newNode(RRC,root->left->left,NULL);
3514 /* fourth and last case for now */
3515 /* (?symbol << 7) | (?symbol >> 1) */
3516 if (IS_RIGHT_OP(root->right) &&
3517 IS_LEFT_OP(root->left) ) {
3519 if (!SPEC_USIGN(TETYPE(root->left->left)))
3522 if (!IS_AST_LIT_VALUE(root->left->right) ||
3523 !IS_AST_LIT_VALUE(root->right->right))
3526 /* make sure it is the same symbol */
3527 if (!isAstEqual(root->left->left,
3531 if (AST_LIT_VALUE(root->right->right) != 1 )
3534 if (AST_LIT_VALUE(root->left->right) !=
3535 (getSize(TTYPE(root->left->left))*8 - 1))
3538 /* whew got the first case : create the AST */
3539 return newNode(RRC,root->left->left,NULL);
3543 /* not found return root */
3547 /*-----------------------------------------------------------------*/
3548 /* optimizeCompare - otimizes compares for bit variables */
3549 /*-----------------------------------------------------------------*/
3550 ast *optimizeCompare ( ast *root )
3552 ast *optExpr = NULL;
3555 unsigned int litValue ;
3557 /* if nothing then return nothing */
3561 /* if not a compare op then do leaves */
3562 if (!IS_COMPARE_OP(root)) {
3563 root->left = optimizeCompare (root->left);
3564 root->right= optimizeCompare (root->right);
3568 /* if left & right are the same then depending
3569 of the operation do */
3570 if (isAstEqual(root->left,root->right)) {
3571 switch (root->opval.op) {
3575 optExpr = newAst_VALUE(constVal("0"));
3580 optExpr = newAst_VALUE(constVal("1"));
3584 return decorateType(optExpr);
3587 vleft = (root->left->type == EX_VALUE ?
3588 root->left->opval.val : NULL );
3590 vright = (root->right->type == EX_VALUE ?
3591 root->right->opval.val : NULL);
3593 /* if left is a BITVAR in BITSPACE */
3594 /* and right is a LITERAL then opt-*/
3595 /* imize else do nothing */
3596 if (vleft && vright &&
3597 IS_BITVAR(vleft->etype) &&
3598 IN_BITSPACE(SPEC_OCLS(vleft->etype)) &&
3599 IS_LITERAL(vright->etype)) {
3601 /* if right side > 1 then comparison may never succeed */
3602 if ( (litValue = (int) floatFromVal(vright)) > 1 ) {
3603 werror(W_BAD_COMPARE);
3608 switch (root->opval.op) {
3609 case '>' : /* bit value greater than 1 cannot be */
3610 werror(W_BAD_COMPARE);
3614 case '<' : /* bit value < 1 means 0 */
3616 optExpr = newNode('!',newAst_VALUE(vleft),NULL);
3619 case LE_OP : /* bit value <= 1 means no check */
3620 optExpr = newAst_VALUE(vright);
3623 case GE_OP : /* bit value >= 1 means only check for = */
3625 optExpr = newAst_VALUE(vleft);
3628 } else { /* literal is zero */
3629 switch (root->opval.op) {
3630 case '<' : /* bit value < 0 cannot be */
3631 werror(W_BAD_COMPARE);
3635 case '>' : /* bit value > 0 means 1 */
3637 optExpr = newAst_VALUE(vleft);
3640 case LE_OP : /* bit value <= 0 means no check */
3641 case GE_OP : /* bit value >= 0 means no check */
3642 werror(W_BAD_COMPARE);
3646 case EQ_OP : /* bit == 0 means ! of bit */
3647 optExpr = newNode('!',newAst_VALUE(vleft),NULL);
3651 return decorateType(resolveSymbols(optExpr));
3652 } /* end-of-if of BITVAR */
3657 /*-----------------------------------------------------------------*/
3658 /* addSymToBlock : adds the symbol to the first block we find */
3659 /*-----------------------------------------------------------------*/
3660 void addSymToBlock (symbol *sym, ast *tree)
3662 /* reached end of tree or a leaf */
3663 if (!tree || IS_AST_LINK(tree) || IS_AST_VALUE(tree))
3667 if (IS_AST_OP(tree) &&
3668 tree->opval.op == BLOCK ) {
3670 symbol *lsym = copySymbol(sym);
3672 lsym->next = AST_VALUES(tree,sym);
3673 AST_VALUES(tree,sym) = lsym ;
3677 addSymToBlock(sym,tree->left);
3678 addSymToBlock(sym,tree->right);
3681 /*-----------------------------------------------------------------*/
3682 /* processRegParms - do processing for register parameters */
3683 /*-----------------------------------------------------------------*/
3684 static void processRegParms (value *args, ast *body)
3687 if (IS_REGPARM(args->etype))
3688 addSymToBlock(args->sym,body);
3693 /*-----------------------------------------------------------------*/
3694 /* resetParmKey - resets the operandkeys for the symbols */
3695 /*-----------------------------------------------------------------*/
3696 DEFSETFUNC(resetParmKey)
3707 /*-----------------------------------------------------------------*/
3708 /* createFunction - This is the key node that calls the iCode for */
3709 /* generating the code for a function. Note code */
3710 /* is generated function by function, later when */
3711 /* add inter-procedural analysis this will change */
3712 /*-----------------------------------------------------------------*/
3713 ast *createFunction (symbol *name, ast *body )
3719 iCode *piCode = NULL;
3721 /* if check function return 0 then some problem */
3722 if (checkFunction (name) == 0)
3725 /* create a dummy block if none exists */
3727 body = newNode(BLOCK,NULL,NULL);
3731 /* check if the function name already in the symbol table */
3732 if ((csym = findSym (SymbolTab,NULL,name->name))) {
3734 /* special case for compiler defined functions
3735 we need to add the name to the publics list : this
3736 actually means we are now compiling the compiler
3739 addSet(&publics,name);
3744 allocVariables(name);
3746 name->lastLine = yylineno;
3748 processFuncArgs(currFunc,0);
3750 /* set the stack pointer */
3751 /* PENDING: check this for the mcs51 */
3752 stackPtr = -port->stack.direction * port->stack.call_overhead;
3753 if (IS_ISR(name->etype))
3754 stackPtr -= port->stack.direction * port->stack.isr_overhead;
3755 if (IS_RENT(name->etype) || options.stackAuto)
3756 stackPtr -= port->stack.direction * port->stack.reent_overhead;
3758 xstackPtr = -port->stack.direction * port->stack.call_overhead;
3760 fetype = getSpec(name->type); /* get the specifier for the function */
3761 /* if this is a reentrant function then */
3762 if (IS_RENT(fetype))
3765 allocParms (name->args); /* allocate the parameters */
3767 /* do processing for parameters that are passed in registers */
3768 processRegParms (name->args,body);
3770 /* set the stack pointer */
3774 /* allocate & autoinit the block variables */
3775 processBlockVars (body, &stack,ALLOCATE);
3777 /* save the stack information */
3778 if (options.useXstack)
3779 name->xstack = SPEC_STAK(fetype) = stack;
3781 name->stack = SPEC_STAK(fetype) = stack;
3783 /* name needs to be mangled */
3784 sprintf (name->rname,"%s%s", port->fun_prefix, name->name);
3786 body = resolveSymbols(body); /* resolve the symbols */
3787 body = decorateType (body); /* propagateType & do semantic checks */
3789 ex = newAst_VALUE(symbolVal(name)); /* create name */
3790 ex = newNode (FUNCTION,ex,body);
3791 ex->values.args = name->args ;
3794 werror(E_FUNC_NO_CODE,name->name);
3798 /* create the node & generate intermediate code */
3799 codeOutFile = code->oFile;
3800 piCode = iCodeFromAst(ex);
3803 werror(E_FUNC_NO_CODE,name->name);
3807 eBBlockFromiCode(piCode);
3809 /* if there are any statics then do them */
3811 codeOutFile = statsg->oFile;
3812 eBBlockFromiCode (iCodeFromAst (decorateType(resolveSymbols(staticAutos))));
3818 /* dealloc the block variables */
3819 processBlockVars(body, &stack,DEALLOCATE);
3820 /* deallocate paramaters */
3821 deallocParms(name->args);
3823 if (IS_RENT(fetype))
3826 /* we are done freeup memory & cleanup */
3831 addSet(&operKeyReset,name);
3832 applyToSet(operKeyReset,resetParmKey);
3834 if (options.debug && !options.nodebug)
3835 cdbStructBlock(1,cdbFile);
3837 cleanUpLevel(LabelTab,0);
3838 cleanUpBlock(StructTab,1);
3839 cleanUpBlock(TypedefTab,1);
3841 xstack->syms = NULL;
3842 istack->syms = NULL;