1 /*-------------------------------------------------------------------------
2 SDCCast.c - source file for parser support & all ast related routines
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
29 set *operKeyReset = NULL;
30 ast *staticAutos = NULL;
33 #define LRVAL(x) x->left->rvalue
34 #define RRVAL(x) x->right->rvalue
35 #define TRVAL(x) x->rvalue
36 #define LLVAL(x) x->left->lvalue
37 #define RLVAL(x) x->right->lvalue
38 #define TLVAL(x) x->lvalue
39 #define RTYPE(x) x->right->ftype
40 #define RETYPE(x) x->right->etype
41 #define LTYPE(x) x->left->ftype
42 #define LETYPE(x) x->left->etype
43 #define TTYPE(x) x->ftype
44 #define TETYPE(x) x->etype
50 symbol *currFunc=NULL;
51 static ast *createIval (ast *, sym_link *, initList *, ast *);
52 static ast *createIvalCharPtr (ast *, sym_link *, ast *);
53 static ast *optimizeCompare (ast *);
54 ast *optimizeRRCRLC (ast *);
55 ast *optimizeSWAP (ast *);
56 ast *optimizeGetHbit (ast *);
57 ast *backPatchLabels (ast *, symbol *, symbol *);
60 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
65 printTypeChain (tree->ftype, stdout);
70 /*-----------------------------------------------------------------*/
71 /* newAst - creates a fresh node for an expression tree */
72 /*-----------------------------------------------------------------*/
74 newAst_ (unsigned type)
77 static int oldLineno = 0;
79 ex = Safe_alloc ( sizeof (ast));
82 ex->lineno = (noLineno ? oldLineno : mylineno);
83 ex->filename = currFname;
84 ex->level = NestLevel;
85 ex->block = currBlockno;
86 ex->initMode = inInitMode;
87 ex->seqPoint = seqPointNo;
92 newAst_VALUE (value * val)
94 ast *ex = newAst_ (EX_VALUE);
100 newAst_OP (unsigned op)
102 ast *ex = newAst_ (EX_OP);
108 newAst_LINK (sym_link * val)
110 ast *ex = newAst_ (EX_LINK);
115 /*-----------------------------------------------------------------*/
116 /* newNode - creates a new node */
117 /*-----------------------------------------------------------------*/
119 newNode (long op, ast * left, ast * right)
130 /*-----------------------------------------------------------------*/
131 /* newIfxNode - creates a new Ifx Node */
132 /*-----------------------------------------------------------------*/
134 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
138 /* if this is a literal then we already know the result */
139 if (condAst->etype && IS_LITERAL (condAst->etype))
141 /* then depending on the expression value */
142 if (floatFromVal (condAst->opval.val))
143 ifxNode = newNode (GOTO,
144 newAst_VALUE (symbolVal (trueLabel)),
147 ifxNode = newNode (GOTO,
148 newAst_VALUE (symbolVal (falseLabel)),
153 ifxNode = newNode (IFX, condAst, NULL);
154 ifxNode->trueLabel = trueLabel;
155 ifxNode->falseLabel = falseLabel;
161 /*-----------------------------------------------------------------*/
162 /* copyAstValues - copies value portion of ast if needed */
163 /*-----------------------------------------------------------------*/
165 copyAstValues (ast * dest, ast * src)
167 switch (src->opval.op)
170 dest->values.sym = copySymbolChain (src->values.sym);
174 dest->values.switchVals.swVals =
175 copyValue (src->values.switchVals.swVals);
176 dest->values.switchVals.swDefault =
177 src->values.switchVals.swDefault;
178 dest->values.switchVals.swNum =
179 src->values.switchVals.swNum;
183 dest->values.inlineasm = Safe_strdup(src->values.inlineasm);
187 dest->values.constlist = copyLiteralList(src->values.constlist);
191 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
192 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
193 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
194 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
195 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
196 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
197 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
202 /*-----------------------------------------------------------------*/
203 /* copyAst - makes a copy of a given astession */
204 /*-----------------------------------------------------------------*/
213 dest = Safe_alloc ( sizeof (ast));
215 dest->type = src->type;
216 dest->lineno = src->lineno;
217 dest->level = src->level;
218 dest->funcName = src->funcName;
221 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
223 /* if this is a leaf */
225 if (src->type == EX_VALUE)
227 dest->opval.val = copyValue (src->opval.val);
232 if (src->type == EX_LINK)
234 dest->opval.lnk = copyLinkChain (src->opval.lnk);
238 dest->opval.op = src->opval.op;
240 /* if this is a node that has special values */
241 copyAstValues (dest, src);
243 dest->trueLabel = copySymbol (src->trueLabel);
244 dest->falseLabel = copySymbol (src->falseLabel);
245 dest->left = copyAst (src->left);
246 dest->right = copyAst (src->right);
252 /*-----------------------------------------------------------------*/
253 /* removeIncDecOps: remove for side effects in *_ASSIGN's */
254 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
255 /*-----------------------------------------------------------------*/
256 ast *removeIncDecOps (ast * tree) {
258 // traverse the tree and remove inc/dec ops
263 if (tree->type == EX_OP &&
264 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
271 tree->left=removeIncDecOps(tree->left);
272 tree->right=removeIncDecOps(tree->right);
277 /*-----------------------------------------------------------------*/
278 /* removePreIncDecOps: remove for side effects in *_ASSIGN's */
279 /* "*++s += 3" -> "*++s = *++s + 3" */
280 /*-----------------------------------------------------------------*/
281 ast *removePreIncDecOps (ast * tree) {
283 // traverse the tree and remove pre-inc/dec ops
288 if (tree->type == EX_OP &&
289 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
294 tree->left=removePreIncDecOps(tree->left);
295 tree->right=removePreIncDecOps(tree->right);
300 /*-----------------------------------------------------------------*/
301 /* removePostIncDecOps: remove for side effects in *_ASSIGN's */
302 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
303 /*-----------------------------------------------------------------*/
304 ast *removePostIncDecOps (ast * tree) {
306 // traverse the tree and remove pre-inc/dec ops
311 if (tree->type == EX_OP &&
312 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
317 tree->left=removePostIncDecOps(tree->left);
318 tree->right=removePostIncDecOps(tree->right);
323 /*-----------------------------------------------------------------*/
324 /* hasSEFcalls - returns TRUE if tree has a function call */
325 /*-----------------------------------------------------------------*/
327 hasSEFcalls (ast * tree)
332 if (tree->type == EX_OP &&
333 (tree->opval.op == CALL ||
334 tree->opval.op == PCALL ||
335 tree->opval.op == '=' ||
336 tree->opval.op == INC_OP ||
337 tree->opval.op == DEC_OP))
340 return (hasSEFcalls (tree->left) |
341 hasSEFcalls (tree->right));
344 /*-----------------------------------------------------------------*/
345 /* isAstEqual - compares two asts & returns 1 if they are equal */
346 /*-----------------------------------------------------------------*/
348 isAstEqual (ast * t1, ast * t2)
357 if (t1->type != t2->type)
363 if (t1->opval.op != t2->opval.op)
365 return (isAstEqual (t1->left, t2->left) &&
366 isAstEqual (t1->right, t2->right));
370 if (t1->opval.val->sym)
372 if (!t2->opval.val->sym)
375 return isSymbolEqual (t1->opval.val->sym,
380 if (t2->opval.val->sym)
383 return (floatFromVal (t1->opval.val) ==
384 floatFromVal (t2->opval.val));
388 /* only compare these two types */
396 /*-----------------------------------------------------------------*/
397 /* resolveSymbols - resolve symbols from the symbol table */
398 /*-----------------------------------------------------------------*/
400 resolveSymbols (ast * tree)
402 /* walk the entire tree and check for values */
403 /* with symbols if we find one then replace */
404 /* symbol with that from the symbol table */
411 /* if not block & function */
412 if (tree->type == EX_OP &&
413 (tree->opval.op != FUNCTION &&
414 tree->opval.op != BLOCK &&
415 tree->opval.op != NULLOP))
417 filename = tree->filename;
418 lineno = tree->lineno;
422 /* make sure we resolve the true & false labels for ifx */
423 if (tree->type == EX_OP && tree->opval.op == IFX)
429 if ((csym = findSym (LabelTab, tree->trueLabel,
430 tree->trueLabel->name)))
431 tree->trueLabel = csym;
433 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
434 tree->trueLabel->name);
437 if (tree->falseLabel)
439 if ((csym = findSym (LabelTab,
441 tree->falseLabel->name)))
442 tree->falseLabel = csym;
444 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
445 tree->falseLabel->name);
450 /* if this is a label resolve it from the labelTab */
451 if (IS_AST_VALUE (tree) &&
452 tree->opval.val->sym &&
453 tree->opval.val->sym->islbl)
456 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
457 tree->opval.val->sym->name);
460 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
461 tree->opval.val->sym->name);
463 tree->opval.val->sym = csym;
465 goto resolveChildren;
468 /* do only for leafs */
469 if (IS_AST_VALUE (tree) &&
470 tree->opval.val->sym &&
471 !tree->opval.val->sym->implicit)
474 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
476 /* if found in the symbol table & they r not the same */
477 if (csym && tree->opval.val->sym != csym)
479 tree->opval.val->sym = csym;
480 tree->opval.val->type = csym->type;
481 tree->opval.val->etype = csym->etype;
484 /* if not found in the symbol table */
485 /* mark it as undefined assume it is */
486 /* an integer in data space */
487 if (!csym && !tree->opval.val->sym->implicit)
490 /* if this is a function name then */
491 /* mark it as returning an int */
494 tree->opval.val->sym->type = newLink (DECLARATOR);
495 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
496 tree->opval.val->sym->type->next =
497 tree->opval.val->sym->etype = newIntLink ();
498 tree->opval.val->etype = tree->opval.val->etype;
499 tree->opval.val->type = tree->opval.val->sym->type;
500 werrorfl (tree->filename, tree->lineno, W_IMPLICIT_FUNC,
501 tree->opval.val->sym->name);
502 //tree->opval.val->sym->undefined = 1;
503 allocVariables (tree->opval.val->sym);
507 tree->opval.val->sym->undefined = 1;
508 tree->opval.val->type =
509 tree->opval.val->etype = newIntLink ();
510 tree->opval.val->sym->type =
511 tree->opval.val->sym->etype = newIntLink ();
517 resolveSymbols (tree->left);
518 resolveSymbols (tree->right);
523 /*-----------------------------------------------------------------*/
524 /* setAstLineno - walks a ast tree & sets the line number */
525 /*-----------------------------------------------------------------*/
526 int setAstLineno (ast * tree, int lineno)
531 tree->lineno = lineno;
532 setAstLineno (tree->left, lineno);
533 setAstLineno (tree->right, lineno);
537 /*-----------------------------------------------------------------*/
538 /* funcOfType :- function of type with name */
539 /*-----------------------------------------------------------------*/
541 funcOfType (char *name, sym_link * type, sym_link * argType,
545 /* create the symbol */
546 sym = newSymbol (name, 0);
548 /* setup return value */
549 sym->type = newLink (DECLARATOR);
550 DCL_TYPE (sym->type) = FUNCTION;
551 sym->type->next = copyLinkChain (type);
552 sym->etype = getSpec (sym->type);
553 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
555 /* if arguments required */
559 args = FUNC_ARGS(sym->type) = newValue ();
563 args->type = copyLinkChain (argType);
564 args->etype = getSpec (args->type);
565 SPEC_EXTR(args->etype)=1;
568 args = args->next = newValue ();
575 allocVariables (sym);
580 /*-----------------------------------------------------------------*/
581 /* funcOfTypeVarg :- function of type with name and argtype */
582 /*-----------------------------------------------------------------*/
584 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
589 /* create the symbol */
590 sym = newSymbol (name, 0);
592 /* setup return value */
593 sym->type = newLink (DECLARATOR);
594 DCL_TYPE (sym->type) = FUNCTION;
595 sym->type->next = typeFromStr(rtype);
596 sym->etype = getSpec (sym->type);
598 /* if arguments required */
601 args = FUNC_ARGS(sym->type) = newValue ();
603 for ( i = 0 ; i < nArgs ; i++ ) {
604 args->type = typeFromStr(atypes[i]);
605 args->etype = getSpec (args->type);
606 SPEC_EXTR(args->etype)=1;
607 if ((i + 1) == nArgs) break;
608 args = args->next = newValue ();
615 allocVariables (sym);
620 /*-----------------------------------------------------------------*/
621 /* reverseParms - will reverse a parameter tree */
622 /*-----------------------------------------------------------------*/
624 reverseParms (ast * ptree)
630 /* top down if we find a nonParm tree then quit */
631 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
634 ptree->left = ptree->right;
635 ptree->right = ttree;
636 reverseParms (ptree->left);
637 reverseParms (ptree->right);
643 /*-----------------------------------------------------------------*/
644 /* processParms - makes sure the parameters are okay and do some */
645 /* processing with them */
646 /*-----------------------------------------------------------------*/
648 processParms (ast * func,
651 int *parmNumber, // unused, although updated
654 /* if none of them exist */
655 if (!defParm && !actParm)
659 if (getenv("DEBUG_SANITY")) {
660 fprintf (stderr, "processParms: %s ", defParm->name);
662 /* make sure the type is complete and sane */
663 checkTypeSanity(defParm->etype, defParm->name);
666 /* if the function is being called via a pointer & */
667 /* it has not been defined a reentrant then we cannot */
668 /* have parameters */
669 if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
671 werror (W_NONRENT_ARGS);
675 /* if defined parameters ended but actual parameters */
676 /* exist and this is not defined as a variable arg */
677 if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
679 //if (func->type==EX_VALUE && func->opval.val->sym->undefined)
680 // return 1; /* Already gave them an undefined function error */
681 werror (E_TOO_MANY_PARMS);
685 /* if defined parameters present but no actual parameters */
686 if (defParm && !actParm)
688 werror (E_TOO_FEW_PARMS);
692 if (IS_VOID(actParm->ftype)) {
693 werror (E_VOID_VALUE_USED);
697 /* If this is a varargs function... */
698 if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
703 if (IS_CAST_OP (actParm)
704 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
706 /* Parameter was explicitly typecast; don't touch it. */
710 ftype = actParm->ftype;
712 /* If it's a small integer, upcast to int. */
713 if (IS_INTEGRAL (ftype)
714 && (getSize (ftype) < (unsigned) INTSIZE))
716 if (IS_AST_OP(actParm) &&
717 (actParm->opval.op == LEFT_OP ||
718 actParm->opval.op == '*' ||
719 actParm->opval.op == '+' ||
720 actParm->opval.op == '-') &&
722 // we should cast an operand instead of the result
723 actParm->decorated = 0;
724 actParm->left = newNode( CAST, newAst_LINK(newIntLink()),
726 actParm = decorateType(actParm, RESULT_CHECK);
728 newType = newAst_LINK(INTTYPE);
732 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
734 newType = newAst_LINK (copyLinkChain(ftype));
735 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
738 if (IS_AGGREGATE (ftype))
740 newType = newAst_LINK (copyLinkChain (ftype));
741 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
745 /* cast required; change this op to a cast. */
746 ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)), RESULT_CHECK);
748 actParm->type = EX_OP;
749 actParm->opval.op = CAST;
750 actParm->left = newType;
751 actParm->right = parmCopy;
752 decorateType (actParm, RESULT_CHECK);
754 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
756 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
757 processParms (func, NULL, actParm->right, parmNumber, rightmost));
762 /* if defined parameters ended but actual has not & */
764 if (!defParm && actParm &&
765 (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
768 resolveSymbols (actParm);
769 /* if this is a PARAM node then match left & right */
770 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
772 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
773 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
777 /* If we have found a value node by following only right-hand links,
778 * then we know that there are no more values after us.
780 * Therefore, if there are more defined parameters, the caller didn't
783 if (rightmost && defParm->next)
785 werror (E_TOO_FEW_PARMS);
790 /* the parameter type must be at least castable */
791 if (compareType (defParm->type, actParm->ftype) == 0) {
792 werror (E_INCOMPAT_TYPES);
793 printFromToType (actParm->ftype, defParm->type);
797 /* if the parameter is castable then add the cast */
798 if (compareType (defParm->type, actParm->ftype) < 0)
800 ast *pTree = decorateType(resolveSymbols (copyAst (actParm)), RESULT_CHECK);
802 /* now change the current one to a cast */
803 actParm->type = EX_OP;
804 actParm->opval.op = CAST;
805 actParm->left = newAst_LINK (defParm->type);
806 actParm->right = pTree;
807 actParm->etype = defParm->etype;
808 actParm->ftype = defParm->type;
809 actParm->decorated=0; /* force typechecking */
810 decorateType (actParm, RESULT_CHECK);
813 /* make a copy and change the regparm type to the defined parm */
814 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
815 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
816 SPEC_ARGREG (actParm->etype) = SPEC_ARGREG (defParm->etype);
820 /*-----------------------------------------------------------------*/
821 /* createIvalType - generates ival for basic types */
822 /*-----------------------------------------------------------------*/
824 createIvalType (ast * sym, sym_link * type, initList * ilist)
828 /* if initList is deep */
829 if (ilist->type == INIT_DEEP)
830 ilist = ilist->init.deep;
832 iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK);
833 return decorateType (newNode ('=', sym, iExpr), RESULT_CHECK);
836 /*-----------------------------------------------------------------*/
837 /* createIvalStruct - generates initial value for structures */
838 /*-----------------------------------------------------------------*/
840 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
847 sflds = SPEC_STRUCT (type)->fields;
848 if (ilist->type != INIT_DEEP)
850 werror (E_INIT_STRUCT, "");
854 iloop = ilist->init.deep;
856 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
858 /* if we have come to end */
862 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
863 lAst = decorateType (resolveSymbols (lAst), RESULT_CHECK);
864 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)), RESULT_CHECK);
868 werrorfl (filename, sym->opval.val->sym->lineDef,
869 W_EXCESS_INITIALIZERS, "struct",
870 sym->opval.val->sym->name);
877 /*-----------------------------------------------------------------*/
878 /* createIvalArray - generates code for array initialization */
879 /*-----------------------------------------------------------------*/
881 createIvalArray (ast * sym, sym_link * type, initList * ilist)
885 int lcnt = 0, size = 0;
886 literalList *literalL;
888 /* take care of the special case */
889 /* array of characters can be init */
891 if (IS_CHAR (type->next))
892 if ((rast = createIvalCharPtr (sym,
894 decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK))))
896 return decorateType (resolveSymbols (rast), RESULT_CHECK);
898 /* not the special case */
899 if (ilist->type != INIT_DEEP)
901 werror (E_INIT_STRUCT, "");
905 iloop = ilist->init.deep;
906 lcnt = DCL_ELEM (type);
908 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
912 aSym = decorateType (resolveSymbols(sym), RESULT_CHECK);
914 rast = newNode(ARRAYINIT, aSym, NULL);
915 rast->values.constlist = literalL;
917 // Make sure size is set to length of initializer list.
924 if (lcnt && size > lcnt)
926 // Array size was specified, and we have more initializers than needed.
927 char *name=sym->opval.val->sym->name;
928 int lineno=sym->opval.val->sym->lineDef;
930 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
939 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
940 aSym = decorateType (resolveSymbols (aSym), RESULT_CHECK);
941 rast = createIval (aSym, type->next, iloop, rast);
942 iloop = (iloop ? iloop->next : NULL);
948 /* no of elements given and we */
949 /* have generated for all of them */
952 // there has to be a better way
953 char *name=sym->opval.val->sym->name;
954 int lineno=sym->opval.val->sym->lineDef;
955 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
962 /* if we have not been given a size */
963 if (!DCL_ELEM (type))
965 DCL_ELEM (type) = size;
968 return decorateType (resolveSymbols (rast), RESULT_CHECK);
972 /*-----------------------------------------------------------------*/
973 /* createIvalCharPtr - generates initial values for char pointers */
974 /*-----------------------------------------------------------------*/
976 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
980 /* if this is a pointer & right is a literal array then */
981 /* just assignment will do */
982 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
983 SPEC_SCLS (iexpr->etype) == S_CODE)
984 && IS_ARRAY (iexpr->ftype)))
985 return newNode ('=', sym, iexpr);
987 /* left side is an array so we have to assign each */
989 if ((IS_LITERAL (iexpr->etype) ||
990 SPEC_SCLS (iexpr->etype) == S_CODE)
991 && IS_ARRAY (iexpr->ftype))
993 /* for each character generate an assignment */
994 /* to the array element */
995 char *s = SPEC_CVAL (iexpr->etype).v_char;
997 int size = getSize (iexpr->ftype);
998 int symsize = getSize (type);
1002 if (size>(symsize+1))
1003 werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1004 "string", sym->opval.val->sym->name);
1008 for (i=0;i<size;i++)
1010 rast = newNode (NULLOP,
1014 newAst_VALUE (valueFromLit ((float) i))),
1015 newAst_VALUE (valueFromLit (*s))));
1019 // now WE don't need iexpr's symbol anymore
1020 freeStringSymbol(AST_SYMBOL(iexpr));
1022 return decorateType (resolveSymbols (rast), RESULT_CHECK);
1028 /*-----------------------------------------------------------------*/
1029 /* createIvalPtr - generates initial value for pointers */
1030 /*-----------------------------------------------------------------*/
1032 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
1038 if (ilist->type == INIT_DEEP)
1039 ilist = ilist->init.deep;
1041 iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK);
1043 /* if character pointer */
1044 if (IS_CHAR (type->next))
1045 if ((rast = createIvalCharPtr (sym, type, iexpr)))
1048 return newNode ('=', sym, iexpr);
1051 /*-----------------------------------------------------------------*/
1052 /* createIval - generates code for initial value */
1053 /*-----------------------------------------------------------------*/
1055 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1062 /* if structure then */
1063 if (IS_STRUCT (type))
1064 rast = createIvalStruct (sym, type, ilist);
1066 /* if this is a pointer */
1068 rast = createIvalPtr (sym, type, ilist);
1070 /* if this is an array */
1071 if (IS_ARRAY (type))
1072 rast = createIvalArray (sym, type, ilist);
1074 /* if type is SPECIFIER */
1076 rast = createIvalType (sym, type, ilist);
1079 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_CHECK);
1081 return decorateType (resolveSymbols (rast), RESULT_CHECK);
1084 /*-----------------------------------------------------------------*/
1085 /* initAggregates - initialises aggregate variables with initv */
1086 /*-----------------------------------------------------------------*/
1087 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1088 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1091 /*-----------------------------------------------------------------*/
1092 /* gatherAutoInit - creates assignment expressions for initial */
1094 /*-----------------------------------------------------------------*/
1096 gatherAutoInit (symbol * autoChain)
1103 for (sym = autoChain; sym; sym = sym->next)
1106 /* resolve the symbols in the ival */
1108 resolveIvalSym (sym->ival);
1110 /* if this is a static variable & has an */
1111 /* initial value the code needs to be lifted */
1112 /* here to the main portion since they can be */
1113 /* initialised only once at the start */
1114 if (IS_STATIC (sym->etype) && sym->ival &&
1115 SPEC_SCLS (sym->etype) != S_CODE)
1119 /* insert the symbol into the symbol table */
1120 /* with level = 0 & name = rname */
1121 newSym = copySymbol (sym);
1122 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1124 /* now lift the code to main */
1125 if (IS_AGGREGATE (sym->type)) {
1126 work = initAggregates (sym, sym->ival, NULL);
1128 if (getNelements(sym->type, sym->ival)>1) {
1129 werrorfl (filename, sym->lineDef,
1130 W_EXCESS_INITIALIZERS, "scalar",
1133 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1134 list2expr (sym->ival));
1137 setAstLineno (work, sym->lineDef);
1141 staticAutos = newNode (NULLOP, staticAutos, work);
1148 /* if there is an initial value */
1149 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1151 initList *ilist=sym->ival;
1153 while (ilist->type == INIT_DEEP) {
1154 ilist = ilist->init.deep;
1157 /* update lineno for error msg */
1158 lineno=sym->lineDef;
1159 setAstLineno (ilist->init.node, lineno);
1161 if (IS_AGGREGATE (sym->type)) {
1162 work = initAggregates (sym, sym->ival, NULL);
1164 if (getNelements(sym->type, sym->ival)>1) {
1165 werrorfl (filename, sym->lineDef,
1166 W_EXCESS_INITIALIZERS, "scalar",
1169 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1170 list2expr (sym->ival));
1174 setAstLineno (work, sym->lineDef);
1178 init = newNode (NULLOP, init, work);
1187 /*-----------------------------------------------------------------*/
1188 /* freeStringSymbol - delete a literal string if no more usage */
1189 /*-----------------------------------------------------------------*/
1190 void freeStringSymbol(symbol *sym) {
1191 /* make sure this is a literal string */
1192 assert (sym->isstrlit);
1193 if (--sym->isstrlit == 0) { // lower the usage count
1194 memmap *segment=SPEC_OCLS(sym->etype);
1196 deleteSetItem(&segment->syms, sym);
1201 /*-----------------------------------------------------------------*/
1202 /* stringToSymbol - creates a symbol from a literal string */
1203 /*-----------------------------------------------------------------*/
1205 stringToSymbol (value * val)
1207 char name[SDCC_NAME_MAX + 1];
1208 static int charLbl = 0;
1213 // have we heard this before?
1214 for (sp=statsg->syms; sp; sp=sp->next) {
1216 size = getSize (sym->type);
1217 if (sym->isstrlit && size == getSize (val->type) &&
1218 !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1219 // yes, this is old news. Don't publish it again.
1220 sym->isstrlit++; // but raise the usage count
1221 return symbolVal(sym);
1225 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1226 sym = newSymbol (name, 0); /* make it @ level 0 */
1227 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1229 /* copy the type from the value passed */
1230 sym->type = copyLinkChain (val->type);
1231 sym->etype = getSpec (sym->type);
1232 /* change to storage class & output class */
1233 SPEC_SCLS (sym->etype) = S_CODE;
1234 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1235 SPEC_STAT (sym->etype) = 1;
1236 /* make the level & block = 0 */
1237 sym->block = sym->level = 0;
1239 /* create an ival */
1240 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1245 allocVariables (sym);
1248 return symbolVal (sym);
1252 /*-----------------------------------------------------------------*/
1253 /* processBlockVars - will go thru the ast looking for block if */
1254 /* a block is found then will allocate the syms */
1255 /* will also gather the auto inits present */
1256 /*-----------------------------------------------------------------*/
1258 processBlockVars (ast * tree, int *stack, int action)
1263 /* if this is a block */
1264 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1268 if (action == ALLOCATE)
1270 *stack += allocVariables (tree->values.sym);
1271 autoInit = gatherAutoInit (tree->values.sym);
1273 /* if there are auto inits then do them */
1275 tree->left = newNode (NULLOP, autoInit, tree->left);
1277 else /* action is deallocate */
1278 deallocLocal (tree->values.sym);
1281 processBlockVars (tree->left, stack, action);
1282 processBlockVars (tree->right, stack, action);
1287 /*-------------------------------------------------------------*/
1288 /* constExprTree - returns TRUE if this tree is a constant */
1290 /*-------------------------------------------------------------*/
1291 bool constExprTree (ast *cexpr) {
1297 cexpr = decorateType (resolveSymbols (cexpr), RESULT_CHECK);
1299 switch (cexpr->type)
1302 if (IS_AST_LIT_VALUE(cexpr)) {
1303 // this is a literal
1306 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1307 // a function's address will never change
1310 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1311 // an array's address will never change
1314 if (IS_AST_SYM_VALUE(cexpr) &&
1315 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1316 // a symbol in code space will never change
1317 // This is only for the 'char *s="hallo"' case and will have to leave
1318 //printf(" code space symbol");
1323 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1324 "unexpected link in expression tree\n");
1327 if (cexpr->opval.op==ARRAYINIT) {
1328 // this is a list of literals
1331 if (cexpr->opval.op=='=') {
1332 return constExprTree(cexpr->right);
1334 if (cexpr->opval.op==CAST) {
1335 // cast ignored, maybe we should throw a warning here?
1336 return constExprTree(cexpr->right);
1338 if (cexpr->opval.op=='&') {
1341 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1344 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1349 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1354 /*-----------------------------------------------------------------*/
1355 /* constExprValue - returns the value of a constant expression */
1356 /* or NULL if it is not a constant expression */
1357 /*-----------------------------------------------------------------*/
1359 constExprValue (ast * cexpr, int check)
1361 cexpr = decorateType (resolveSymbols (cexpr), RESULT_CHECK);
1363 /* if this is not a constant then */
1364 if (!IS_LITERAL (cexpr->ftype))
1366 /* then check if this is a literal array
1368 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1369 SPEC_CVAL (cexpr->etype).v_char &&
1370 IS_ARRAY (cexpr->ftype))
1372 value *val = valFromType (cexpr->ftype);
1373 SPEC_SCLS (val->etype) = S_LITERAL;
1374 val->sym = cexpr->opval.val->sym;
1375 val->sym->type = copyLinkChain (cexpr->ftype);
1376 val->sym->etype = getSpec (val->sym->type);
1377 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1381 /* if we are casting a literal value then */
1382 if (IS_AST_OP (cexpr) &&
1383 cexpr->opval.op == CAST &&
1384 IS_LITERAL (cexpr->right->ftype))
1386 return valCastLiteral (cexpr->ftype,
1387 floatFromVal (cexpr->right->opval.val));
1390 if (IS_AST_VALUE (cexpr))
1392 return cexpr->opval.val;
1396 werror (E_CONST_EXPECTED, "found expression");
1401 /* return the value */
1402 return cexpr->opval.val;
1406 /*-----------------------------------------------------------------*/
1407 /* isLabelInAst - will return true if a given label is found */
1408 /*-----------------------------------------------------------------*/
1410 isLabelInAst (symbol * label, ast * tree)
1412 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1415 if (IS_AST_OP (tree) &&
1416 tree->opval.op == LABEL &&
1417 isSymbolEqual (AST_SYMBOL (tree->left), label))
1420 return isLabelInAst (label, tree->right) &&
1421 isLabelInAst (label, tree->left);
1425 /*-----------------------------------------------------------------*/
1426 /* isLoopCountable - return true if the loop count can be determi- */
1427 /* -ned at compile time . */
1428 /*-----------------------------------------------------------------*/
1430 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1431 symbol ** sym, ast ** init, ast ** end)
1434 /* the loop is considered countable if the following
1435 conditions are true :-
1437 a) initExpr :- <sym> = <const>
1438 b) condExpr :- <sym> < <const1>
1439 c) loopExpr :- <sym> ++
1442 /* first check the initExpr */
1443 if (IS_AST_OP (initExpr) &&
1444 initExpr->opval.op == '=' && /* is assignment */
1445 IS_AST_SYM_VALUE (initExpr->left))
1446 { /* left is a symbol */
1448 *sym = AST_SYMBOL (initExpr->left);
1449 *init = initExpr->right;
1454 /* for now the symbol has to be of
1456 if (!IS_INTEGRAL ((*sym)->type))
1459 /* now check condExpr */
1460 if (IS_AST_OP (condExpr))
1463 switch (condExpr->opval.op)
1466 if (IS_AST_SYM_VALUE (condExpr->left) &&
1467 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1468 IS_AST_LIT_VALUE (condExpr->right))
1470 *end = condExpr->right;
1476 if (IS_AST_OP (condExpr->left) &&
1477 condExpr->left->opval.op == '>' &&
1478 IS_AST_LIT_VALUE (condExpr->left->right) &&
1479 IS_AST_SYM_VALUE (condExpr->left->left) &&
1480 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1483 *end = newNode ('+', condExpr->left->right,
1484 newAst_VALUE (constVal ("1")));
1495 /* check loop expression is of the form <sym>++ */
1496 if (!IS_AST_OP (loopExpr))
1499 /* check if <sym> ++ */
1500 if (loopExpr->opval.op == INC_OP)
1506 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1507 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1514 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1515 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1523 if (loopExpr->opval.op == ADD_ASSIGN)
1526 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1527 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1528 IS_AST_LIT_VALUE (loopExpr->right) &&
1529 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1537 /*-----------------------------------------------------------------*/
1538 /* astHasVolatile - returns true if ast contains any volatile */
1539 /*-----------------------------------------------------------------*/
1541 astHasVolatile (ast * tree)
1546 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1549 if (IS_AST_OP (tree))
1550 return astHasVolatile (tree->left) ||
1551 astHasVolatile (tree->right);
1556 /*-----------------------------------------------------------------*/
1557 /* astHasPointer - return true if the ast contains any ptr variable */
1558 /*-----------------------------------------------------------------*/
1560 astHasPointer (ast * tree)
1565 if (IS_AST_LINK (tree))
1568 /* if we hit an array expression then check
1569 only the left side */
1570 if (IS_AST_OP (tree) && tree->opval.op == '[')
1571 return astHasPointer (tree->left);
1573 if (IS_AST_VALUE (tree))
1574 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1576 return astHasPointer (tree->left) ||
1577 astHasPointer (tree->right);
1581 /*-----------------------------------------------------------------*/
1582 /* astHasSymbol - return true if the ast has the given symbol */
1583 /*-----------------------------------------------------------------*/
1585 astHasSymbol (ast * tree, symbol * sym)
1587 if (!tree || IS_AST_LINK (tree))
1590 if (IS_AST_VALUE (tree))
1592 if (IS_AST_SYM_VALUE (tree))
1593 return isSymbolEqual (AST_SYMBOL (tree), sym);
1598 return astHasSymbol (tree->left, sym) ||
1599 astHasSymbol (tree->right, sym);
1602 /*-----------------------------------------------------------------*/
1603 /* astHasDeref - return true if the ast has an indirect access */
1604 /*-----------------------------------------------------------------*/
1606 astHasDeref (ast * tree)
1608 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1611 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1613 return astHasDeref (tree->left) || astHasDeref (tree->right);
1616 /*-----------------------------------------------------------------*/
1617 /* isConformingBody - the loop body has to conform to a set of rules */
1618 /* for the loop to be considered reversible read on for rules */
1619 /*-----------------------------------------------------------------*/
1621 isConformingBody (ast * pbody, symbol * sym, ast * body)
1624 /* we are going to do a pre-order traversal of the
1625 tree && check for the following conditions. (essentially
1626 a set of very shallow tests )
1627 a) the sym passed does not participate in
1628 any arithmetic operation
1629 b) There are no function calls
1630 c) all jumps are within the body
1631 d) address of loop control variable not taken
1632 e) if an assignment has a pointer on the
1633 left hand side make sure right does not have
1634 loop control variable */
1636 /* if we reach the end or a leaf then true */
1637 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1640 /* if anything else is "volatile" */
1641 if (IS_VOLATILE (TETYPE (pbody)))
1644 /* we will walk the body in a pre-order traversal for
1646 switch (pbody->opval.op)
1648 /*------------------------------------------------------------------*/
1650 // if the loopvar is used as an index
1651 if (astHasSymbol(pbody->right, sym)) {
1654 return isConformingBody (pbody->right, sym, body);
1656 /*------------------------------------------------------------------*/
1661 /*------------------------------------------------------------------*/
1665 /* sure we are not sym is not modified */
1667 IS_AST_SYM_VALUE (pbody->left) &&
1668 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1672 IS_AST_SYM_VALUE (pbody->right) &&
1673 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1678 /*------------------------------------------------------------------*/
1680 case '*': /* can be unary : if right is null then unary operation */
1685 /* if right is NULL then unary operation */
1686 /*------------------------------------------------------------------*/
1687 /*----------------------------*/
1689 /*----------------------------*/
1692 if (IS_AST_SYM_VALUE (pbody->left) &&
1693 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1696 return isConformingBody (pbody->left, sym, body);
1700 if (astHasSymbol (pbody->left, sym) ||
1701 astHasSymbol (pbody->right, sym))
1706 /*------------------------------------------------------------------*/
1714 if (IS_AST_SYM_VALUE (pbody->left) &&
1715 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1718 if (IS_AST_SYM_VALUE (pbody->right) &&
1719 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1722 return isConformingBody (pbody->left, sym, body) &&
1723 isConformingBody (pbody->right, sym, body);
1731 if (IS_AST_SYM_VALUE (pbody->left) &&
1732 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1734 return isConformingBody (pbody->left, sym, body);
1736 /*------------------------------------------------------------------*/
1748 case SIZEOF: /* evaluate wihout code generation */
1750 if (IS_AST_SYM_VALUE (pbody->left) &&
1751 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1754 if (IS_AST_SYM_VALUE (pbody->right) &&
1755 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1758 return isConformingBody (pbody->left, sym, body) &&
1759 isConformingBody (pbody->right, sym, body);
1761 /*------------------------------------------------------------------*/
1764 /* if left has a pointer & right has loop
1765 control variable then we cannot */
1766 if (astHasPointer (pbody->left) &&
1767 astHasSymbol (pbody->right, sym))
1769 if (astHasVolatile (pbody->left))
1772 if (IS_AST_SYM_VALUE (pbody->left)) {
1773 // if the loopvar has an assignment
1774 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1776 // if the loopvar is used in another (maybe conditional) block
1777 if (astHasSymbol (pbody->right, sym) &&
1778 (pbody->level >= body->level)) {
1783 if (astHasVolatile (pbody->left))
1786 if (astHasDeref(pbody->right)) return FALSE;
1788 return isConformingBody (pbody->left, sym, body) &&
1789 isConformingBody (pbody->right, sym, body);
1800 assert ("Parser should not have generated this\n");
1802 /*------------------------------------------------------------------*/
1803 /*----------------------------*/
1804 /* comma operator */
1805 /*----------------------------*/
1807 return isConformingBody (pbody->left, sym, body) &&
1808 isConformingBody (pbody->right, sym, body);
1810 /*------------------------------------------------------------------*/
1811 /*----------------------------*/
1813 /*----------------------------*/
1815 /* if local & not passed as paramater then ok */
1816 if (sym->level && !astHasSymbol(pbody->right,sym))
1820 /*------------------------------------------------------------------*/
1821 /*----------------------------*/
1822 /* return statement */
1823 /*----------------------------*/
1828 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1833 if (astHasSymbol (pbody->left, sym))
1840 return isConformingBody (pbody->left, sym, body) &&
1841 isConformingBody (pbody->right, sym, body);
1847 /*-----------------------------------------------------------------*/
1848 /* isLoopReversible - takes a for loop as input && returns true */
1849 /* if the for loop is reversible. If yes will set the value of */
1850 /* the loop control var & init value & termination value */
1851 /*-----------------------------------------------------------------*/
1853 isLoopReversible (ast * loop, symbol ** loopCntrl,
1854 ast ** init, ast ** end)
1856 /* if option says don't do it then don't */
1857 if (optimize.noLoopReverse)
1859 /* there are several tests to determine this */
1861 /* for loop has to be of the form
1862 for ( <sym> = <const1> ;
1863 [<sym> < <const2>] ;
1864 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1866 if (!isLoopCountable (AST_FOR (loop, initExpr),
1867 AST_FOR (loop, condExpr),
1868 AST_FOR (loop, loopExpr),
1869 loopCntrl, init, end))
1872 /* now do some serious checking on the body of the loop
1875 return isConformingBody (loop->left, *loopCntrl, loop->left);
1879 /*-----------------------------------------------------------------*/
1880 /* replLoopSym - replace the loop sym by loop sym -1 */
1881 /*-----------------------------------------------------------------*/
1883 replLoopSym (ast * body, symbol * sym)
1886 if (!body || IS_AST_LINK (body))
1889 if (IS_AST_SYM_VALUE (body))
1892 if (isSymbolEqual (AST_SYMBOL (body), sym))
1896 body->opval.op = '-';
1897 body->left = newAst_VALUE (symbolVal (sym));
1898 body->right = newAst_VALUE (constVal ("1"));
1906 replLoopSym (body->left, sym);
1907 replLoopSym (body->right, sym);
1911 /*-----------------------------------------------------------------*/
1912 /* reverseLoop - do the actual loop reversal */
1913 /*-----------------------------------------------------------------*/
1915 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1919 /* create the following tree
1924 if (sym) goto for_continue ;
1927 /* put it together piece by piece */
1928 rloop = newNode (NULLOP,
1929 createIf (newAst_VALUE (symbolVal (sym)),
1931 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1934 newAst_VALUE (symbolVal (sym)),
1937 replLoopSym (loop->left, sym);
1938 setAstLineno (rloop, init->lineno);
1940 rloop = newNode (NULLOP,
1942 newAst_VALUE (symbolVal (sym)),
1943 newNode ('-', end, init)),
1944 createLabel (AST_FOR (loop, continueLabel),
1948 newNode (SUB_ASSIGN,
1949 newAst_VALUE (symbolVal (sym)),
1950 newAst_VALUE (constVal ("1"))),
1953 rloop->lineno=init->lineno;
1954 return decorateType (rloop, RESULT_CHECK);
1958 /*-----------------------------------------------------------------*/
1959 /* searchLitOp - search tree (*ops only) for an ast with literal */
1960 /*-----------------------------------------------------------------*/
1962 searchLitOp (ast *tree, ast **parent, const char *ops)
1966 if (tree && optimize.global_cse)
1968 /* is there a literal operand? */
1970 IS_AST_OP(tree->right) &&
1971 tree->right->right &&
1972 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
1974 if (IS_LITERAL (RTYPE (tree->right)) ^
1975 IS_LITERAL (LTYPE (tree->right)))
1977 tree->right->decorated = 0;
1978 tree->decorated = 0;
1982 ret = searchLitOp (tree->right, parent, ops);
1987 IS_AST_OP(tree->left) &&
1988 tree->left->right &&
1989 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
1991 if (IS_LITERAL (RTYPE (tree->left)) ^
1992 IS_LITERAL (LTYPE (tree->left)))
1994 tree->left->decorated = 0;
1995 tree->decorated = 0;
1999 ret = searchLitOp (tree->left, parent, ops);
2007 /*-----------------------------------------------------------------*/
2008 /* getResultFromType */
2009 /*-----------------------------------------------------------------*/
2011 getResultTypeFromType (sym_link *type)
2013 /* type = getSpec (type); */
2014 if (IS_BITVAR (type))
2015 return RESULT_TYPE_BIT;
2016 if (IS_BITFIELD (type))
2017 return RESULT_TYPE_CHAR;
2019 return RESULT_TYPE_CHAR;
2022 return RESULT_TYPE_INT;
2023 return RESULT_TYPE_OTHER;
2026 /*-----------------------------------------------------------------*/
2027 /* addCast - adds casts to a type specified by RESULT_TYPE */
2028 /*-----------------------------------------------------------------*/
2030 addCast (ast **tree, RESULT_TYPE resultType, bool upcast)
2033 bool upCasted = FALSE;
2037 case RESULT_TYPE_NONE:
2038 /* char: promote to int */
2040 getSize ((*tree)->etype) >= INTSIZE)
2042 newLink = newIntLink();
2045 case RESULT_TYPE_CHAR:
2046 if (getSize ((*tree)->etype) <= 1)
2048 newLink = newCharLink();
2050 case RESULT_TYPE_INT:
2052 if (getSize ((*tree)->etype) > INTSIZE)
2054 /* warn ("Loosing significant digits"); */
2058 /* char: promote to int */
2060 getSize ((*tree)->etype) >= INTSIZE)
2062 newLink = newIntLink();
2065 case RESULT_TYPE_OTHER:
2068 /* return type is long, float: promote char to int */
2069 if (getSize ((*tree)->etype) >= INTSIZE)
2071 newLink = newIntLink();
2077 (*tree)->decorated = 0;
2078 *tree = newNode (CAST, newAst_LINK (newLink), *tree);
2079 /* keep unsigned type during cast to smaller type,
2080 but not when promoting from char to int */
2082 SPEC_USIGN ((*tree)->left->opval.lnk) = IS_UNSIGNED ((*tree)->right->etype) ? 1 : 0;
2083 *tree = decorateType (*tree, resultType);
2086 /*-----------------------------------------------------------------*/
2087 /* resultTypePropagate - decides if resultType can be propagated */
2088 /*-----------------------------------------------------------------*/
2090 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2092 switch (tree->opval.op)
2103 return RESULT_TYPE_NONE;
2107 return RESULT_TYPE_NONE;
2111 /*-----------------------------------------------------------------*/
2112 /* getLeftResultType - gets type from left branch for propagation */
2113 /*-----------------------------------------------------------------*/
2115 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2117 switch (tree->opval.op)
2121 if (IS_PTR (tree->left->ftype))
2122 return RESULT_TYPE_NONE;
2124 return getResultTypeFromType (tree->left->etype);
2126 if (IS_PTR (currFunc->type->next))
2127 return RESULT_TYPE_NONE;
2129 return getResultTypeFromType (currFunc->type->next);
2135 /*--------------------------------------------------------------------*/
2136 /* decorateType - compute type for this tree, also does type checking.*/
2137 /* This is done bottom up, since type has to flow upwards. */
2138 /* resultType flows top-down and forces e.g. char-arithmetik, if the */
2139 /* result is a char and the operand(s) are int's. */
2140 /* It also does constant folding, and parameter checking. */
2141 /*--------------------------------------------------------------------*/
2143 decorateType (ast * tree, RESULT_TYPE resultType)
2147 RESULT_TYPE resultTypeProp;
2152 /* if already has type then do nothing */
2153 if (tree->decorated)
2156 tree->decorated = 1;
2159 /* print the line */
2160 /* if not block & function */
2161 if (tree->type == EX_OP &&
2162 (tree->opval.op != FUNCTION &&
2163 tree->opval.op != BLOCK &&
2164 tree->opval.op != NULLOP))
2166 filename = tree->filename;
2167 lineno = tree->lineno;
2171 /* if any child is an error | this one is an error do nothing */
2172 if (tree->isError ||
2173 (tree->left && tree->left->isError) ||
2174 (tree->right && tree->right->isError))
2177 /*------------------------------------------------------------------*/
2178 /*----------------------------*/
2179 /* leaf has been reached */
2180 /*----------------------------*/
2181 lineno=tree->lineno;
2182 /* if this is of type value */
2183 /* just get the type */
2184 if (tree->type == EX_VALUE)
2187 if (IS_LITERAL (tree->opval.val->etype))
2190 /* if this is a character array then declare it */
2191 if (IS_ARRAY (tree->opval.val->type))
2192 tree->opval.val = stringToSymbol (tree->opval.val);
2194 /* otherwise just copy the type information */
2195 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2199 if (tree->opval.val->sym)
2201 /* if the undefined flag is set then give error message */
2202 if (tree->opval.val->sym->undefined)
2204 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2206 TTYPE (tree) = TETYPE (tree) =
2207 tree->opval.val->type = tree->opval.val->sym->type =
2208 tree->opval.val->etype = tree->opval.val->sym->etype =
2209 copyLinkChain (INTTYPE);
2214 /* if impilicit i.e. struct/union member then no type */
2215 if (tree->opval.val->sym->implicit)
2216 TTYPE (tree) = TETYPE (tree) = NULL;
2221 /* else copy the type */
2222 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2224 /* and mark it as referenced */
2225 tree->opval.val->sym->isref = 1;
2233 /* if type link for the case of cast */
2234 if (tree->type == EX_LINK)
2236 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2244 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2246 if (tree->left && tree->left->type == EX_OPERAND
2247 && (tree->left->opval.op == INC_OP
2248 || tree->left->opval.op == DEC_OP)
2249 && tree->left->left)
2251 tree->left->right = tree->left->left;
2252 tree->left->left = NULL;
2254 if (tree->right && tree->right->type == EX_OPERAND
2255 && (tree->right->opval.op == INC_OP
2256 || tree->right->opval.op == DEC_OP)
2257 && tree->right->left)
2259 tree->right->right = tree->right->left;
2260 tree->right->left = NULL;
2265 /* Before decorating the left branch we've to decide in dependence
2266 upon tree->opval.op, if resultType can be propagated */
2267 if (getenv ("SDCC_NEWTYPEFLOW"))
2268 resultTypeProp = resultTypePropagate (tree, resultType);
2270 resultTypeProp = RESULT_TYPE_NONE; /* provide initialization */
2272 dtl = decorateType (tree->left, resultTypeProp);
2274 /* After decorating the left branch there's type information available
2275 in tree->left->?type. If the op is e.g. '=' we extract the type
2276 information from there and propagate it to the right branch. */
2277 if (getenv ("SDCC_NEWTYPEFLOW"))
2278 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2280 /* delay right side for '?' operator since conditional macro expansions
2281 might rely on this */
2282 dtr = tree->opval.op == '?' ? tree->right :
2283 decorateType (tree->right, resultTypeProp);
2285 /* this is to take care of situations
2286 when the tree gets rewritten */
2287 if (dtl != tree->left)
2289 if (dtr != tree->right)
2291 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2294 if (!getenv ("SDCC_NEWTYPEFLOW"))
2296 if (IS_AST_OP(tree) &&
2297 (tree->opval.op == CAST || tree->opval.op == '=') &&
2298 (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) &&
2299 (getSize(RTYPE(tree)) < (unsigned) INTSIZE)) {
2300 /* this is a cast/assign to a bigger type */
2301 if (IS_AST_OP(tree->right) &&
2302 IS_INTEGRAL(tree->right->ftype) &&
2303 (tree->right->opval.op == LEFT_OP ||
2304 tree->right->opval.op == '*' ||
2305 tree->right->opval.op == '+' ||
2306 tree->right->opval.op == '-') &&
2307 tree->right->right) {
2308 /* we should cast an operand instead of the result */
2309 tree->right->decorated = 0;
2310 tree->right->left = newNode( CAST, newAst_LINK(newIntLink()),
2312 tree->right = decorateType(tree->right, RESULT_CHECK);
2318 /* depending on type of operator do */
2320 switch (tree->opval.op)
2322 /*------------------------------------------------------------------*/
2323 /*----------------------------*/
2325 /*----------------------------*/
2328 /* determine which is the array & which the index */
2329 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2332 ast *tempTree = tree->left;
2333 tree->left = tree->right;
2334 tree->right = tempTree;
2337 /* first check if this is a array or a pointer */
2338 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2340 werror (E_NEED_ARRAY_PTR, "[]");
2341 goto errorTreeReturn;
2344 /* check if the type of the idx */
2345 if (!IS_INTEGRAL (RTYPE (tree)))
2347 werror (E_IDX_NOT_INT);
2348 goto errorTreeReturn;
2351 /* if the left is an rvalue then error */
2354 werror (E_LVALUE_REQUIRED, "array access");
2355 goto errorTreeReturn;
2358 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2361 /*------------------------------------------------------------------*/
2362 /*----------------------------*/
2364 /*----------------------------*/
2366 /* if this is not a structure */
2367 if (!IS_STRUCT (LTYPE (tree)))
2369 werror (E_STRUCT_UNION, ".");
2370 goto errorTreeReturn;
2372 TTYPE (tree) = structElemType (LTYPE (tree),
2373 (tree->right->type == EX_VALUE ?
2374 tree->right->opval.val : NULL));
2375 TETYPE (tree) = getSpec (TTYPE (tree));
2378 /*------------------------------------------------------------------*/
2379 /*----------------------------*/
2380 /* struct/union pointer */
2381 /*----------------------------*/
2383 /* if not pointer to a structure */
2384 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2386 werror (E_PTR_REQD);
2387 goto errorTreeReturn;
2390 if (!IS_STRUCT (LTYPE (tree)->next))
2392 werror (E_STRUCT_UNION, "->");
2393 goto errorTreeReturn;
2396 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2397 (tree->right->type == EX_VALUE ?
2398 tree->right->opval.val : NULL));
2399 TETYPE (tree) = getSpec (TTYPE (tree));
2401 /* adjust the storage class */
2402 switch (DCL_TYPE(tree->left->ftype)) {
2404 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2407 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2410 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2413 SPEC_SCLS (TETYPE (tree)) = 0;
2416 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2419 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2422 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2425 SPEC_SCLS (TETYPE (tree)) = 0;
2432 /* This breaks with extern declarations, bitfields, and perhaps other */
2433 /* cases (gcse). Let's leave this optimization disabled for now and */
2434 /* ponder if there's a safe way to do this. -- EEP */
2436 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2437 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2439 /* If defined struct type at addr var
2440 then rewrite (&struct var)->member
2442 and define membertype at (addr+offsetof(struct var,member)) temp
2445 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2446 AST_SYMBOL(tree->right));
2448 sym = newSymbol(genSymName (0), 0);
2449 sym->type = TTYPE (tree);
2450 sym->etype = getSpec(sym->type);
2451 sym->lineDef = tree->lineno;
2454 SPEC_STAT (sym->etype) = 1;
2455 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2457 SPEC_ABSA(sym->etype) = 1;
2458 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2461 AST_VALUE (tree) = symbolVal(sym);
2464 tree->type = EX_VALUE;
2472 /*------------------------------------------------------------------*/
2473 /*----------------------------*/
2474 /* ++/-- operation */
2475 /*----------------------------*/
2479 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2480 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2481 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2482 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2491 /*------------------------------------------------------------------*/
2492 /*----------------------------*/
2494 /*----------------------------*/
2495 case '&': /* can be unary */
2496 /* if right is NULL then unary operation */
2497 if (tree->right) /* not an unary operation */
2500 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2502 werror (E_BITWISE_OP);
2503 werror (W_CONTINUE, "left & right types are ");
2504 printTypeChain (LTYPE (tree), stderr);
2505 fprintf (stderr, ",");
2506 printTypeChain (RTYPE (tree), stderr);
2507 fprintf (stderr, "\n");
2508 goto errorTreeReturn;
2511 /* if they are both literal */
2512 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2514 tree->type = EX_VALUE;
2515 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2516 valFromType (RETYPE (tree)), '&');
2518 tree->right = tree->left = NULL;
2519 TETYPE (tree) = tree->opval.val->etype;
2520 TTYPE (tree) = tree->opval.val->type;
2524 /* see if this is a GETHBIT operation if yes
2527 ast *otree = optimizeGetHbit (tree);
2530 return decorateType (otree, RESULT_CHECK);
2533 if (getenv ("SDCC_NEWTYPEFLOW"))
2535 addCast (&tree->left, resultType, FALSE);
2536 addCast (&tree->right, resultType, FALSE);
2538 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
2539 TETYPE (tree) = getSpec (TTYPE (tree));
2541 /* if left is a literal exchange left & right */
2542 if (IS_LITERAL (LTYPE (tree)))
2544 ast *tTree = tree->left;
2545 tree->left = tree->right;
2546 tree->right = tTree;
2549 /* if right is a literal and */
2550 /* we can find a 2nd literal in a and-tree then */
2551 /* rearrange the tree */
2552 if (IS_LITERAL (RTYPE (tree)))
2555 ast *litTree = searchLitOp (tree, &parent, "&");
2558 ast *tTree = litTree->left;
2559 litTree->left = tree->right;
2560 tree->right = tTree;
2561 /* both operands in tTree are literal now */
2562 decorateType (parent, RESULT_CHECK);
2566 LRVAL (tree) = RRVAL (tree) = 1;
2571 /*------------------------------------------------------------------*/
2572 /*----------------------------*/
2574 /*----------------------------*/
2575 p = newLink (DECLARATOR);
2576 /* if bit field then error */
2577 if (IS_BITVAR (tree->left->etype))
2579 werror (E_ILLEGAL_ADDR, "address of bit variable");
2580 goto errorTreeReturn;
2583 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2585 werror (E_ILLEGAL_ADDR, "address of register variable");
2586 goto errorTreeReturn;
2589 if (IS_FUNC (LTYPE (tree)))
2591 // this ought to be ignored
2592 return (tree->left);
2595 if (IS_LITERAL(LTYPE(tree)))
2597 werror (E_ILLEGAL_ADDR, "address of literal");
2598 goto errorTreeReturn;
2603 werror (E_LVALUE_REQUIRED, "address of");
2604 goto errorTreeReturn;
2607 DCL_TYPE (p) = POINTER;
2608 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2609 DCL_TYPE (p) = CPOINTER;
2610 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2611 DCL_TYPE (p) = FPOINTER;
2612 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2613 DCL_TYPE (p) = PPOINTER;
2614 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2615 DCL_TYPE (p) = IPOINTER;
2616 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2617 DCL_TYPE (p) = EEPPOINTER;
2618 else if (SPEC_OCLS(tree->left->etype))
2619 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2621 DCL_TYPE (p) = POINTER;
2623 if (IS_AST_SYM_VALUE (tree->left))
2625 AST_SYMBOL (tree->left)->addrtaken = 1;
2626 AST_SYMBOL (tree->left)->allocreq = 1;
2629 p->next = LTYPE (tree);
2631 TETYPE (tree) = getSpec (TTYPE (tree));
2636 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2637 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2639 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2640 AST_SYMBOL(tree->left->right));
2641 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2642 valueFromLit(element->offset));
2645 tree->type = EX_VALUE;
2646 tree->values.literalFromCast = 1;
2652 /*------------------------------------------------------------------*/
2653 /*----------------------------*/
2655 /*----------------------------*/
2657 /* if the rewrite succeeds then don't go any furthur */
2659 ast *wtree = optimizeRRCRLC (tree);
2661 return decorateType (wtree, RESULT_CHECK);
2663 wtree = optimizeSWAP (tree);
2665 return decorateType (wtree, RESULT_CHECK);
2668 /* if left is a literal exchange left & right */
2669 if (IS_LITERAL (LTYPE (tree)))
2671 ast *tTree = tree->left;
2672 tree->left = tree->right;
2673 tree->right = tTree;
2676 /* if right is a literal and */
2677 /* we can find a 2nd literal in a or-tree then */
2678 /* rearrange the tree */
2679 if (IS_LITERAL (RTYPE (tree)))
2682 ast *litTree = searchLitOp (tree, &parent, "|");
2685 ast *tTree = litTree->left;
2686 litTree->left = tree->right;
2687 tree->right = tTree;
2688 /* both operands in tTree are literal now */
2689 decorateType (parent, RESULT_CHECK);
2694 /*------------------------------------------------------------------*/
2695 /*----------------------------*/
2697 /*----------------------------*/
2699 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2701 werror (E_BITWISE_OP);
2702 werror (W_CONTINUE, "left & right types are ");
2703 printTypeChain (LTYPE (tree), stderr);
2704 fprintf (stderr, ",");
2705 printTypeChain (RTYPE (tree), stderr);
2706 fprintf (stderr, "\n");
2707 goto errorTreeReturn;
2710 /* if they are both literal then */
2711 /* rewrite the tree */
2712 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2714 tree->type = EX_VALUE;
2715 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2716 valFromType (RETYPE (tree)),
2718 tree->right = tree->left = NULL;
2719 TETYPE (tree) = tree->opval.val->etype;
2720 TTYPE (tree) = tree->opval.val->type;
2724 /* if left is a literal exchange left & right */
2725 if (IS_LITERAL (LTYPE (tree)))
2727 ast *tTree = tree->left;
2728 tree->left = tree->right;
2729 tree->right = tTree;
2732 /* if right is a literal and */
2733 /* we can find a 2nd literal in a xor-tree then */
2734 /* rearrange the tree */
2735 if (IS_LITERAL (RTYPE (tree)) &&
2736 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2739 ast *litTree = searchLitOp (tree, &parent, "^");
2742 ast *tTree = litTree->left;
2743 litTree->left = tree->right;
2744 tree->right = tTree;
2745 /* both operands in litTree are literal now */
2746 decorateType (parent, RESULT_CHECK);
2750 LRVAL (tree) = RRVAL (tree) = 1;
2751 if (getenv ("SDCC_NEWTYPEFLOW"))
2753 addCast (&tree->left, resultType, FALSE);
2754 addCast (&tree->right, resultType, FALSE);
2756 TETYPE (tree) = getSpec (TTYPE (tree) =
2757 computeType (LTYPE (tree),
2763 /*------------------------------------------------------------------*/
2764 /*----------------------------*/
2766 /*----------------------------*/
2768 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2770 werror (E_INVALID_OP, "divide");
2771 goto errorTreeReturn;
2773 /* if they are both literal then */
2774 /* rewrite the tree */
2775 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2777 tree->type = EX_VALUE;
2778 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2779 valFromType (RETYPE (tree)));
2780 tree->right = tree->left = NULL;
2781 TETYPE (tree) = getSpec (TTYPE (tree) =
2782 tree->opval.val->type);
2786 LRVAL (tree) = RRVAL (tree) = 1;
2787 TETYPE (tree) = getSpec (TTYPE (tree) =
2788 computeType (LTYPE (tree),
2790 ! (IS_UNSIGNED (LTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)))));
2792 /* if right is a literal and */
2793 /* left is also a division by a literal then */
2794 /* rearrange the tree */
2795 if (IS_LITERAL (RTYPE (tree))
2796 /* avoid infinite loop */
2797 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2800 ast *litTree = searchLitOp (tree, &parent, "/");
2803 if (IS_LITERAL (RTYPE (litTree)))
2806 litTree->right = newNode ('*', litTree->right, tree->right);
2807 litTree->right->lineno = tree->lineno;
2809 tree->right->opval.val = constVal ("1");
2810 decorateType (parent, RESULT_CHECK);
2814 /* litTree->left is literal: no gcse possible.
2815 We can't call decorateType(parent, RESULT_CHECK), because
2816 this would cause an infinit loop. */
2817 parent->decorated = 1;
2818 decorateType (litTree, RESULT_CHECK);
2825 /*------------------------------------------------------------------*/
2826 /*----------------------------*/
2828 /*----------------------------*/
2830 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2832 werror (E_BITWISE_OP);
2833 werror (W_CONTINUE, "left & right types are ");
2834 printTypeChain (LTYPE (tree), stderr);
2835 fprintf (stderr, ",");
2836 printTypeChain (RTYPE (tree), stderr);
2837 fprintf (stderr, "\n");
2838 goto errorTreeReturn;
2840 /* if they are both literal then */
2841 /* rewrite the tree */
2842 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2844 tree->type = EX_VALUE;
2845 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2846 valFromType (RETYPE (tree)));
2847 tree->right = tree->left = NULL;
2848 TETYPE (tree) = getSpec (TTYPE (tree) =
2849 tree->opval.val->type);
2852 LRVAL (tree) = RRVAL (tree) = 1;
2853 TETYPE (tree) = getSpec (TTYPE (tree) =
2854 computeType (LTYPE (tree),
2856 ! (IS_UNSIGNED (LTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)))));
2859 /*------------------------------------------------------------------*/
2860 /*----------------------------*/
2861 /* address dereference */
2862 /*----------------------------*/
2863 case '*': /* can be unary : if right is null then unary operation */
2866 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2868 werror (E_PTR_REQD);
2869 goto errorTreeReturn;
2874 werror (E_LVALUE_REQUIRED, "pointer deref");
2875 goto errorTreeReturn;
2877 if (IS_ADDRESS_OF_OP(tree->left))
2879 /* replace *&obj with obj */
2880 return tree->left->left;
2882 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2883 TETYPE (tree) = getSpec (TTYPE (tree));
2884 /* adjust the storage class */
2885 switch (DCL_TYPE(tree->left->ftype)) {
2887 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2890 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2893 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2896 SPEC_SCLS (TETYPE (tree)) = 0;
2899 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2902 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2905 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2908 SPEC_SCLS (TETYPE (tree)) = 0;
2917 /*------------------------------------------------------------------*/
2918 /*----------------------------*/
2919 /* multiplication */
2920 /*----------------------------*/
2921 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2923 werror (E_INVALID_OP, "multiplication");
2924 goto errorTreeReturn;
2927 /* if they are both literal then */
2928 /* rewrite the tree */
2929 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2931 tree->type = EX_VALUE;
2932 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2933 valFromType (RETYPE (tree)));
2934 tree->right = tree->left = NULL;
2935 TETYPE (tree) = getSpec (TTYPE (tree) =
2936 tree->opval.val->type);
2940 /* if left is a literal exchange left & right */
2941 if (IS_LITERAL (LTYPE (tree)))
2943 ast *tTree = tree->left;
2944 tree->left = tree->right;
2945 tree->right = tTree;
2948 /* if right is a literal and */
2949 /* we can find a 2nd literal in a mul-tree then */
2950 /* rearrange the tree */
2951 if (IS_LITERAL (RTYPE (tree)))
2954 ast *litTree = searchLitOp (tree, &parent, "*");
2957 ast *tTree = litTree->left;
2958 litTree->left = tree->right;
2959 tree->right = tTree;
2960 /* both operands in litTree are literal now */
2961 decorateType (parent, RESULT_CHECK);
2965 LRVAL (tree) = RRVAL (tree) = 1;
2966 if (!getenv ("SDCC_NEWTYPEFLOW"))
2967 TETYPE (tree) = getSpec (TTYPE (tree) =
2968 computeType (LTYPE (tree),
2973 addCast (&tree->left, resultType, FALSE);
2974 addCast (&tree->right, resultType, FALSE);
2975 TETYPE (tree) = getSpec (TTYPE (tree) =
2976 computeType (LTYPE (tree),
2978 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
2983 /*------------------------------------------------------------------*/
2984 /*----------------------------*/
2985 /* unary '+' operator */
2986 /*----------------------------*/
2991 if (!IS_ARITHMETIC (LTYPE (tree)))
2993 werror (E_UNARY_OP, '+');
2994 goto errorTreeReturn;
2997 /* if left is a literal then do it */
2998 if (IS_LITERAL (LTYPE (tree)))
3000 tree->type = EX_VALUE;
3001 tree->opval.val = valFromType (LETYPE (tree));
3003 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3007 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3011 /*------------------------------------------------------------------*/
3012 /*----------------------------*/
3014 /*----------------------------*/
3016 /* this is not a unary operation */
3017 /* if both pointers then problem */
3018 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3019 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3021 werror (E_PTR_PLUS_PTR);
3022 goto errorTreeReturn;
3025 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3026 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3028 werror (E_PLUS_INVALID, "+");
3029 goto errorTreeReturn;
3032 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3033 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3035 werror (E_PLUS_INVALID, "+");
3036 goto errorTreeReturn;
3038 /* if they are both literal then */
3039 /* rewrite the tree */
3040 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3042 tree->type = EX_VALUE;
3043 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3044 valFromType (RETYPE (tree)));
3045 tree->right = tree->left = NULL;
3046 TETYPE (tree) = getSpec (TTYPE (tree) =
3047 tree->opval.val->type);
3051 /* if the right is a pointer or left is a literal
3052 xchange left & right */
3053 if (IS_ARRAY (RTYPE (tree)) ||
3054 IS_PTR (RTYPE (tree)) ||
3055 IS_LITERAL (LTYPE (tree)))
3057 ast *tTree = tree->left;
3058 tree->left = tree->right;
3059 tree->right = tTree;
3062 /* if right is a literal and */
3063 /* left is also an addition/subtraction with a literal then */
3064 /* rearrange the tree */
3065 if (IS_LITERAL (RTYPE (tree)))
3067 ast *litTree, *parent;
3068 litTree = searchLitOp (tree, &parent, "+-");
3071 if (litTree->opval.op == '+')
3074 ast *tTree = litTree->left;
3075 litTree->left = tree->right;
3076 tree->right = tree->left;
3079 else if (litTree->opval.op == '-')
3081 if (IS_LITERAL (RTYPE (litTree)))
3084 ast *tTree = litTree->left;
3085 litTree->left = tree->right;
3086 tree->right = tTree;
3091 ast *tTree = litTree->right;
3092 litTree->right = tree->right;
3093 tree->right = tTree;
3094 litTree->opval.op = '+';
3095 tree->opval.op = '-';
3098 decorateType (parent, RESULT_CHECK);
3102 LRVAL (tree) = RRVAL (tree) = 1;
3103 /* if the left is a pointer */
3104 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3105 TETYPE (tree) = getSpec (TTYPE (tree) =
3108 if (!getenv ("SDCC_NEWTYPEFLOW"))
3109 TETYPE (tree) = getSpec (TTYPE (tree) =
3110 computeType (LTYPE (tree),
3115 addCast (&tree->left, resultType, TRUE);
3116 addCast (&tree->right, resultType, TRUE);
3117 TETYPE (tree) = getSpec (TTYPE (tree) =
3118 computeType (LTYPE (tree),
3120 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
3125 /*------------------------------------------------------------------*/
3126 /*----------------------------*/
3128 /*----------------------------*/
3129 case '-': /* can be unary */
3130 /* if right is null then unary */
3134 if (!IS_ARITHMETIC (LTYPE (tree)))
3136 werror (E_UNARY_OP, tree->opval.op);
3137 goto errorTreeReturn;
3140 /* if left is a literal then do it */
3141 if (IS_LITERAL (LTYPE (tree)))
3143 tree->type = EX_VALUE;
3144 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3146 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3147 SPEC_USIGN(TETYPE(tree)) = 0;
3151 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3155 /*------------------------------------------------------------------*/
3156 /*----------------------------*/
3158 /*----------------------------*/
3160 if (!(IS_PTR (LTYPE (tree)) ||
3161 IS_ARRAY (LTYPE (tree)) ||
3162 IS_ARITHMETIC (LTYPE (tree))))
3164 werror (E_PLUS_INVALID, "-");
3165 goto errorTreeReturn;
3168 if (!(IS_PTR (RTYPE (tree)) ||
3169 IS_ARRAY (RTYPE (tree)) ||
3170 IS_ARITHMETIC (RTYPE (tree))))
3172 werror (E_PLUS_INVALID, "-");
3173 goto errorTreeReturn;
3176 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3177 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3178 IS_INTEGRAL (RTYPE (tree))))
3180 werror (E_PLUS_INVALID, "-");
3181 goto errorTreeReturn;
3184 /* if they are both literal then */
3185 /* rewrite the tree */
3186 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3188 tree->type = EX_VALUE;
3189 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3190 valFromType (RETYPE (tree)));
3191 tree->right = tree->left = NULL;
3192 TETYPE (tree) = getSpec (TTYPE (tree) =
3193 tree->opval.val->type);
3197 /* if the left & right are equal then zero */
3198 if (isAstEqual (tree->left, tree->right))
3200 tree->type = EX_VALUE;
3201 tree->left = tree->right = NULL;
3202 tree->opval.val = constVal ("0");
3203 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3207 /* if both of them are pointers or arrays then */
3208 /* the result is going to be an integer */
3209 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3210 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3211 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3213 /* if only the left is a pointer */
3214 /* then result is a pointer */
3215 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3216 TETYPE (tree) = getSpec (TTYPE (tree) =
3219 if (!getenv ("SDCC_NEWTYPEFLOW"))
3220 TETYPE (tree) = getSpec (TTYPE (tree) =
3221 computeType (LTYPE (tree),
3226 addCast (&tree->left, resultType, TRUE);
3227 addCast (&tree->right, resultType, TRUE);
3228 TETYPE (tree) = getSpec (TTYPE (tree) =
3229 computeType (LTYPE (tree),
3231 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
3234 LRVAL (tree) = RRVAL (tree) = 1;
3236 /* if right is a literal and */
3237 /* left is also an addition/subtraction with a literal then */
3238 /* rearrange the tree */
3239 if (IS_LITERAL (RTYPE (tree))
3240 /* avoid infinite loop */
3241 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3243 ast *litTree, *litParent;
3244 litTree = searchLitOp (tree, &litParent, "+-");
3247 if (litTree->opval.op == '+')
3250 litTree->right = newNode ('-', litTree->right, tree->right);
3251 litTree->right->lineno = tree->lineno;
3253 tree->right->opval.val = constVal ("0");
3255 else if (litTree->opval.op == '-')
3257 if (IS_LITERAL (RTYPE (litTree)))
3260 litTree->right = newNode ('+', tree->right, litTree->right);
3261 litTree->right->lineno = tree->lineno;
3263 tree->right->opval.val = constVal ("0");
3268 ast *tTree = litTree->right;
3269 litTree->right = tree->right;
3270 tree->right = tTree;
3273 decorateType (litParent, RESULT_CHECK);
3278 /*------------------------------------------------------------------*/
3279 /*----------------------------*/
3281 /*----------------------------*/
3283 /* can be only integral type */
3284 if (!IS_INTEGRAL (LTYPE (tree)))
3286 werror (E_UNARY_OP, tree->opval.op);
3287 goto errorTreeReturn;
3290 /* if left is a literal then do it */
3291 if (IS_LITERAL (LTYPE (tree)))
3293 tree->type = EX_VALUE;
3294 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3296 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3300 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3303 /*------------------------------------------------------------------*/
3304 /*----------------------------*/
3306 /*----------------------------*/
3308 /* can be pointer */
3309 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3310 !IS_PTR (LTYPE (tree)) &&
3311 !IS_ARRAY (LTYPE (tree)))
3313 werror (E_UNARY_OP, tree->opval.op);
3314 goto errorTreeReturn;
3317 /* if left is a literal then do it */
3318 if (IS_LITERAL (LTYPE (tree)))
3320 tree->type = EX_VALUE;
3321 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3323 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3327 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3330 /*------------------------------------------------------------------*/
3331 /*----------------------------*/
3333 /*----------------------------*/
3337 TTYPE (tree) = LTYPE (tree);
3338 TETYPE (tree) = LETYPE (tree);
3342 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3347 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3349 werror (E_SHIFT_OP_INVALID);
3350 werror (W_CONTINUE, "left & right types are ");
3351 printTypeChain (LTYPE (tree), stderr);
3352 fprintf (stderr, ",");
3353 printTypeChain (RTYPE (tree), stderr);
3354 fprintf (stderr, "\n");
3355 goto errorTreeReturn;
3358 /* if they are both literal then */
3359 /* rewrite the tree */
3360 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3362 tree->type = EX_VALUE;
3363 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3364 valFromType (RETYPE (tree)),
3365 (tree->opval.op == LEFT_OP ? 1 : 0));
3366 tree->right = tree->left = NULL;
3367 TETYPE (tree) = getSpec (TTYPE (tree) =
3368 tree->opval.val->type);
3372 LRVAL (tree) = RRVAL (tree) = 1;
3373 if (tree->opval.op == LEFT_OP)
3375 if (!getenv ("SDCC_NEWTYPEFLOW"))
3376 /* promote char to int */
3377 TETYPE (tree) = getSpec (TTYPE (tree) =
3378 computeType (LTYPE (tree),
3379 LTYPE (tree), /* no, not RTYPE! */
3383 addCast (&tree->left, resultType, TRUE);
3384 TETYPE (tree) = getSpec (TTYPE (tree) =
3385 computeType (LTYPE (tree),
3387 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
3392 /* no promotion necessary */
3393 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3394 if (IS_LITERAL (TTYPE (tree)))
3395 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3398 /* if only the right side is a literal & we are
3399 shifting more than size of the left operand then zero */
3400 if (IS_LITERAL (RTYPE (tree)) &&
3401 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3402 (getSize (TETYPE (tree)) * 8))
3404 if (tree->opval.op==LEFT_OP ||
3405 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3407 lineno=tree->lineno;
3408 werror (W_SHIFT_CHANGED,
3409 (tree->opval.op == LEFT_OP ? "left" : "right"));
3410 tree->type = EX_VALUE;
3411 tree->left = tree->right = NULL;
3412 tree->opval.val = constVal ("0");
3413 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3420 /*------------------------------------------------------------------*/
3421 /*----------------------------*/
3423 /*----------------------------*/
3424 case CAST: /* change the type */
3425 /* cannot cast to an aggregate type */
3426 if (IS_AGGREGATE (LTYPE (tree)))
3428 werror (E_CAST_ILLEGAL);
3429 goto errorTreeReturn;
3432 /* make sure the type is complete and sane */
3433 checkTypeSanity(LETYPE(tree), "(cast)");
3435 /* If code memory is read only, then pointers to code memory */
3436 /* implicitly point to constants -- make this explicit */
3438 sym_link *t = LTYPE(tree);
3439 while (t && t->next)
3441 if (IS_CODEPTR(t) && port->mem.code_ro)
3443 if (IS_SPEC(t->next))
3444 SPEC_CONST (t->next) = 1;
3446 DCL_PTR_CONST (t->next) = 1;
3453 /* if the right is a literal replace the tree */
3454 if (IS_LITERAL (RETYPE (tree))) {
3455 if (!IS_PTR (LTYPE (tree))) {
3456 tree->type = EX_VALUE;
3458 valCastLiteral (LTYPE (tree),
3459 floatFromVal (valFromType (RETYPE (tree))));
3462 TTYPE (tree) = tree->opval.val->type;
3463 tree->values.literalFromCast = 1;
3464 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3465 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3466 sym_link *rest = LTYPE(tree)->next;
3467 werror(W_LITERAL_GENERIC);
3468 TTYPE(tree) = newLink(DECLARATOR);
3469 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3470 TTYPE(tree)->next = rest;
3471 tree->left->opval.lnk = TTYPE(tree);
3474 TTYPE (tree) = LTYPE (tree);
3478 TTYPE (tree) = LTYPE (tree);
3482 #if 0 // this is already checked, now this could be explicit
3483 /* if pointer to struct then check names */
3484 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3485 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3486 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3488 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3489 SPEC_STRUCT(LETYPE(tree))->tag);
3492 if (IS_ADDRESS_OF_OP(tree->right)
3493 && IS_AST_SYM_VALUE (tree->right->left)
3494 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3496 tree->type = EX_VALUE;
3498 valCastLiteral (LTYPE (tree),
3499 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3500 TTYPE (tree) = tree->opval.val->type;
3501 TETYPE (tree) = getSpec (TTYPE (tree));
3504 tree->values.literalFromCast = 1;
3508 /* handle offsetof macro: */
3509 /* #define offsetof(TYPE, MEMBER) \ */
3510 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3511 if (IS_ADDRESS_OF_OP(tree->right)
3512 && IS_AST_OP (tree->right->left)
3513 && tree->right->left->opval.op == PTR_OP
3514 && IS_AST_OP (tree->right->left->left)
3515 && tree->right->left->left->opval.op == CAST
3516 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3518 symbol *element = getStructElement (
3519 SPEC_STRUCT (LETYPE(tree->right->left)),
3520 AST_SYMBOL(tree->right->left->right)
3524 tree->type = EX_VALUE;
3525 tree->opval.val = valCastLiteral (
3528 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3531 TTYPE (tree) = tree->opval.val->type;
3532 TETYPE (tree) = getSpec (TTYPE (tree));
3539 /* if the right is a literal replace the tree */
3540 if (IS_LITERAL (RETYPE (tree))) {
3542 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3543 /* rewrite (type *)litaddr
3545 and define type at litaddr temp
3546 (but only if type's storage class is not generic)
3548 ast *newTree = newNode ('&', NULL, NULL);
3551 TTYPE (newTree) = LTYPE (tree);
3552 TETYPE (newTree) = getSpec(LTYPE (tree));
3554 /* define a global symbol at the casted address*/
3555 sym = newSymbol(genSymName (0), 0);
3556 sym->type = LTYPE (tree)->next;
3558 sym->type = newLink (V_VOID);
3559 sym->etype = getSpec(sym->type);
3560 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3561 sym->lineDef = tree->lineno;
3564 SPEC_STAT (sym->etype) = 1;
3565 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3566 SPEC_ABSA(sym->etype) = 1;
3567 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3570 newTree->left = newAst_VALUE(symbolVal(sym));
3571 newTree->left->lineno = tree->lineno;
3572 LTYPE (newTree) = sym->type;
3573 LETYPE (newTree) = sym->etype;
3574 LLVAL (newTree) = 1;
3575 LRVAL (newTree) = 0;
3576 TLVAL (newTree) = 1;
3580 if (!IS_PTR (LTYPE (tree))) {
3581 tree->type = EX_VALUE;
3583 valCastLiteral (LTYPE (tree),
3584 floatFromVal (valFromType (RTYPE (tree))));
3585 TTYPE (tree) = tree->opval.val->type;
3588 tree->values.literalFromCast = 1;
3589 TETYPE (tree) = getSpec (TTYPE (tree));
3593 TTYPE (tree) = LTYPE (tree);
3597 TETYPE (tree) = getSpec (TTYPE (tree));
3601 /*------------------------------------------------------------------*/
3602 /*----------------------------*/
3603 /* logical &&, || */
3604 /*----------------------------*/
3607 /* each must me arithmetic type or be a pointer */
3608 if (!IS_PTR (LTYPE (tree)) &&
3609 !IS_ARRAY (LTYPE (tree)) &&
3610 !IS_INTEGRAL (LTYPE (tree)))
3612 werror (E_COMPARE_OP);
3613 goto errorTreeReturn;
3616 if (!IS_PTR (RTYPE (tree)) &&
3617 !IS_ARRAY (RTYPE (tree)) &&
3618 !IS_INTEGRAL (RTYPE (tree)))
3620 werror (E_COMPARE_OP);
3621 goto errorTreeReturn;
3623 /* if they are both literal then */
3624 /* rewrite the tree */
3625 if (IS_LITERAL (RTYPE (tree)) &&
3626 IS_LITERAL (LTYPE (tree)))
3628 tree->type = EX_VALUE;
3629 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3630 valFromType (RTYPE (tree)),
3632 tree->right = tree->left = NULL;
3633 TETYPE (tree) = getSpec (TTYPE (tree) =
3634 tree->opval.val->type);
3637 LRVAL (tree) = RRVAL (tree) = 1;
3638 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3641 /*------------------------------------------------------------------*/
3642 /*----------------------------*/
3643 /* comparison operators */
3644 /*----------------------------*/
3652 ast *lt = optimizeCompare (tree);
3658 /* if they are pointers they must be castable */
3659 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3661 if (tree->opval.op==EQ_OP &&
3662 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3663 // we cannot cast a gptr to a !gptr: switch the leaves
3664 struct ast *s=tree->left;
3665 tree->left=tree->right;
3668 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3670 werror (E_COMPARE_OP);
3671 fprintf (stderr, "comparing type ");
3672 printTypeChain (LTYPE (tree), stderr);
3673 fprintf (stderr, "to type ");
3674 printTypeChain (RTYPE (tree), stderr);
3675 fprintf (stderr, "\n");
3676 goto errorTreeReturn;
3679 /* else they should be promotable to one another */
3682 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3683 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3685 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3687 werror (E_COMPARE_OP);
3688 fprintf (stderr, "comparing type ");
3689 printTypeChain (LTYPE (tree), stderr);
3690 fprintf (stderr, "to type ");
3691 printTypeChain (RTYPE (tree), stderr);
3692 fprintf (stderr, "\n");
3693 goto errorTreeReturn;
3696 /* if unsigned value < 0 then always false */
3697 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3698 if (SPEC_USIGN(LETYPE(tree)) &&
3699 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3700 IS_LITERAL(RTYPE(tree)) &&
3701 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3703 if (tree->opval.op == '<')
3707 if (tree->opval.op == '>')
3709 /* if the parent is an ifx, then we could do */
3710 /* return tree->left; */
3711 tree->opval.op = '?';
3712 tree->right = newNode (':',
3713 newAst_VALUE (constVal ("1")),
3714 tree->right); /* val 0 */
3715 tree->right->lineno = tree->lineno;
3716 tree->right->left->lineno = tree->lineno;
3717 decorateType (tree->right, RESULT_CHECK);
3720 /* if they are both literal then */
3721 /* rewrite the tree */
3722 if (IS_LITERAL (RTYPE (tree)) &&
3723 IS_LITERAL (LTYPE (tree)))
3725 tree->type = EX_VALUE;
3726 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3727 valFromType (RETYPE (tree)),
3729 tree->right = tree->left = NULL;
3730 TETYPE (tree) = getSpec (TTYPE (tree) =
3731 tree->opval.val->type);
3734 LRVAL (tree) = RRVAL (tree) = 1;
3735 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3738 /*------------------------------------------------------------------*/
3739 /*----------------------------*/
3741 /*----------------------------*/
3742 case SIZEOF: /* evaluate wihout code generation */
3743 /* change the type to a integer */
3744 tree->type = EX_VALUE;
3745 SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
3746 tree->opval.val = constVal (buffer);
3747 tree->right = tree->left = NULL;
3748 TETYPE (tree) = getSpec (TTYPE (tree) =
3749 tree->opval.val->type);
3752 /*------------------------------------------------------------------*/
3753 /*----------------------------*/
3755 /*----------------------------*/
3757 /* return typeof enum value */
3758 tree->type = EX_VALUE;
3761 if (IS_SPEC(tree->right->ftype)) {
3762 switch (SPEC_NOUN(tree->right->ftype)) {
3764 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3765 else typeofv = TYPEOF_INT;
3768 typeofv = TYPEOF_FLOAT;
3771 typeofv = TYPEOF_CHAR;
3774 typeofv = TYPEOF_VOID;
3777 typeofv = TYPEOF_STRUCT;
3780 typeofv = TYPEOF_BITFIELD;
3783 typeofv = TYPEOF_BIT;
3786 typeofv = TYPEOF_SBIT;
3792 switch (DCL_TYPE(tree->right->ftype)) {
3794 typeofv = TYPEOF_POINTER;
3797 typeofv = TYPEOF_FPOINTER;
3800 typeofv = TYPEOF_CPOINTER;
3803 typeofv = TYPEOF_GPOINTER;
3806 typeofv = TYPEOF_PPOINTER;
3809 typeofv = TYPEOF_IPOINTER;
3812 typeofv = TYPEOF_ARRAY;
3815 typeofv = TYPEOF_FUNCTION;
3821 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3822 tree->opval.val = constVal (buffer);
3823 tree->right = tree->left = NULL;
3824 TETYPE (tree) = getSpec (TTYPE (tree) =
3825 tree->opval.val->type);
3828 /*------------------------------------------------------------------*/
3829 /*----------------------------*/
3830 /* conditional operator '?' */
3831 /*----------------------------*/
3833 /* the type is value of the colon operator (on the right) */
3834 assert (IS_COLON_OP (tree->right));
3835 /* if already known then replace the tree : optimizer will do it
3836 but faster to do it here */
3837 if (IS_LITERAL (LTYPE (tree)))
3839 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
3840 return decorateType (tree->right->left, resultTypeProp);
3842 return decorateType (tree->right->right, resultTypeProp);
3846 tree->right = decorateType (tree->right, resultTypeProp);
3847 TTYPE (tree) = RTYPE (tree);
3848 TETYPE (tree) = getSpec (TTYPE (tree));
3853 /* if they don't match we have a problem */
3854 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3856 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3857 goto errorTreeReturn;
3860 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
3861 TETYPE (tree) = getSpec (TTYPE (tree));
3865 #if 0 // assignment operators are converted by the parser
3866 /*------------------------------------------------------------------*/
3867 /*----------------------------*/
3868 /* assignment operators */
3869 /*----------------------------*/
3872 /* for these it must be both must be integral */
3873 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3874 !IS_ARITHMETIC (RTYPE (tree)))
3876 werror (E_OPS_INTEGRAL);
3877 goto errorTreeReturn;
3880 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3882 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3883 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3887 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3888 goto errorTreeReturn;
3899 /* for these it must be both must be integral */
3900 if (!IS_INTEGRAL (LTYPE (tree)) ||
3901 !IS_INTEGRAL (RTYPE (tree)))
3903 werror (E_OPS_INTEGRAL);
3904 goto errorTreeReturn;
3907 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3909 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3910 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3914 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3915 goto errorTreeReturn;
3921 /*------------------------------------------------------------------*/
3922 /*----------------------------*/
3924 /*----------------------------*/
3926 if (!(IS_PTR (LTYPE (tree)) ||
3927 IS_ARITHMETIC (LTYPE (tree))))
3929 werror (E_PLUS_INVALID, "-=");
3930 goto errorTreeReturn;
3933 if (!(IS_PTR (RTYPE (tree)) ||
3934 IS_ARITHMETIC (RTYPE (tree))))
3936 werror (E_PLUS_INVALID, "-=");
3937 goto errorTreeReturn;
3940 TETYPE (tree) = getSpec (TTYPE (tree) =
3941 computeType (LTYPE (tree),
3945 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3946 werror (E_CODE_WRITE, "-=");
3950 werror (E_LVALUE_REQUIRED, "-=");
3951 goto errorTreeReturn;
3957 /*------------------------------------------------------------------*/
3958 /*----------------------------*/
3960 /*----------------------------*/
3962 /* this is not a unary operation */
3963 /* if both pointers then problem */
3964 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3966 werror (E_PTR_PLUS_PTR);
3967 goto errorTreeReturn;
3970 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3972 werror (E_PLUS_INVALID, "+=");
3973 goto errorTreeReturn;
3976 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3978 werror (E_PLUS_INVALID, "+=");
3979 goto errorTreeReturn;
3982 TETYPE (tree) = getSpec (TTYPE (tree) =
3983 computeType (LTYPE (tree),
3987 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3988 werror (E_CODE_WRITE, "+=");
3992 werror (E_LVALUE_REQUIRED, "+=");
3993 goto errorTreeReturn;
3996 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_CHECK);
3997 tree->opval.op = '=';
4002 /*------------------------------------------------------------------*/
4003 /*----------------------------*/
4004 /* straight assignemnt */
4005 /*----------------------------*/
4007 /* cannot be an aggregate */
4008 if (IS_AGGREGATE (LTYPE (tree)))
4010 werror (E_AGGR_ASSIGN);
4011 goto errorTreeReturn;
4014 /* they should either match or be castable */
4015 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4017 werror (E_TYPE_MISMATCH, "assignment", " ");
4018 printFromToType(RTYPE(tree),LTYPE(tree));
4021 /* if the left side of the tree is of type void
4022 then report error */
4023 if (IS_VOID (LTYPE (tree)))
4025 werror (E_CAST_ZERO);
4026 printFromToType(RTYPE(tree), LTYPE(tree));
4029 TETYPE (tree) = getSpec (TTYPE (tree) =
4033 if (!tree->initMode ) {
4034 if (IS_CONSTANT(LTYPE(tree)))
4035 werror (E_CODE_WRITE, "=");
4039 werror (E_LVALUE_REQUIRED, "=");
4040 goto errorTreeReturn;
4045 /*------------------------------------------------------------------*/
4046 /*----------------------------*/
4047 /* comma operator */
4048 /*----------------------------*/
4050 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4053 /*------------------------------------------------------------------*/
4054 /*----------------------------*/
4056 /*----------------------------*/
4060 if (processParms (tree->left,
4061 FUNC_ARGS(tree->left->ftype),
4062 tree->right, &parmNumber, TRUE)) {
4063 goto errorTreeReturn;
4066 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
4067 !IFFUNC_ISBUILTIN(LTYPE(tree)))
4069 reverseParms (tree->right);
4072 if (IS_CODEPTR(LTYPE(tree))) {
4073 TTYPE(tree) = LTYPE(tree)->next->next;
4075 TTYPE(tree) = LTYPE(tree)->next;
4077 TETYPE (tree) = getSpec (TTYPE (tree));
4080 /*------------------------------------------------------------------*/
4081 /*----------------------------*/
4082 /* return statement */
4083 /*----------------------------*/
4088 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4090 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4091 printFromToType (RTYPE(tree), currFunc->type->next);
4092 goto errorTreeReturn;
4095 if (IS_VOID (currFunc->type->next)
4097 !IS_VOID (RTYPE (tree)))
4099 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4100 goto errorTreeReturn;
4103 /* if there is going to be a casting required then add it */
4104 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4107 decorateType (newNode (CAST,
4108 newAst_LINK (copyLinkChain (currFunc->type->next)),
4118 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4120 werror (W_VOID_FUNC, currFunc->name);
4121 goto errorTreeReturn;
4124 TTYPE (tree) = TETYPE (tree) = NULL;
4127 /*------------------------------------------------------------------*/
4128 /*----------------------------*/
4129 /* switch statement */
4130 /*----------------------------*/
4132 /* the switch value must be an integer */
4133 if (!IS_INTEGRAL (LTYPE (tree)))
4135 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4136 goto errorTreeReturn;
4139 TTYPE (tree) = TETYPE (tree) = NULL;
4142 /*------------------------------------------------------------------*/
4143 /*----------------------------*/
4145 /*----------------------------*/
4147 tree->left = backPatchLabels (tree->left,
4150 TTYPE (tree) = TETYPE (tree) = NULL;
4153 /*------------------------------------------------------------------*/
4154 /*----------------------------*/
4156 /*----------------------------*/
4159 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_CHECK);
4160 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_CHECK);
4161 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_CHECK);
4163 /* if the for loop is reversible then
4164 reverse it otherwise do what we normally
4170 if (isLoopReversible (tree, &sym, &init, &end))
4171 return reverseLoop (tree, sym, init, end);
4173 return decorateType (createFor (AST_FOR (tree, trueLabel),
4174 AST_FOR (tree, continueLabel),
4175 AST_FOR (tree, falseLabel),
4176 AST_FOR (tree, condLabel),
4177 AST_FOR (tree, initExpr),
4178 AST_FOR (tree, condExpr),
4179 AST_FOR (tree, loopExpr),
4180 tree->left), RESULT_CHECK);
4183 TTYPE (tree) = TETYPE (tree) = NULL;
4187 /* some error found this tree will be killed */
4189 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4190 tree->opval.op = NULLOP;
4196 /*-----------------------------------------------------------------*/
4197 /* sizeofOp - processes size of operation */
4198 /*-----------------------------------------------------------------*/
4200 sizeofOp (sym_link * type)
4204 /* make sure the type is complete and sane */
4205 checkTypeSanity(type, "(sizeof)");
4207 /* get the size and convert it to character */
4208 SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
4210 /* now convert into value */
4211 return constVal (buff);
4215 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4216 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4217 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4218 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4219 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4220 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4221 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4223 /*-----------------------------------------------------------------*/
4224 /* backPatchLabels - change and or not operators to flow control */
4225 /*-----------------------------------------------------------------*/
4227 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4233 if (!(IS_ANDORNOT (tree)))
4236 /* if this an and */
4239 static int localLbl = 0;
4242 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4243 localLabel = newSymbol (buffer, NestLevel);
4245 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4247 /* if left is already a IFX then just change the if true label in that */
4248 if (!IS_IFX (tree->left))
4249 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4251 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4252 /* right is a IFX then just join */
4253 if (IS_IFX (tree->right))
4254 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4256 tree->right = createLabel (localLabel, tree->right);
4257 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4259 return newNode (NULLOP, tree->left, tree->right);
4262 /* if this is an or operation */
4265 static int localLbl = 0;
4268 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4269 localLabel = newSymbol (buffer, NestLevel);
4271 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4273 /* if left is already a IFX then just change the if true label in that */
4274 if (!IS_IFX (tree->left))
4275 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4277 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4278 /* right is a IFX then just join */
4279 if (IS_IFX (tree->right))
4280 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4282 tree->right = createLabel (localLabel, tree->right);
4283 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4285 return newNode (NULLOP, tree->left, tree->right);
4291 int wasnot = IS_NOT (tree->left);
4292 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4294 /* if the left is already a IFX */
4295 if (!IS_IFX (tree->left))
4296 tree->left = newNode (IFX, tree->left, NULL);
4300 tree->left->trueLabel = trueLabel;
4301 tree->left->falseLabel = falseLabel;
4305 tree->left->trueLabel = falseLabel;
4306 tree->left->falseLabel = trueLabel;
4313 tree->trueLabel = trueLabel;
4314 tree->falseLabel = falseLabel;
4321 /*-----------------------------------------------------------------*/
4322 /* createBlock - create expression tree for block */
4323 /*-----------------------------------------------------------------*/
4325 createBlock (symbol * decl, ast * body)
4329 /* if the block has nothing */
4333 ex = newNode (BLOCK, NULL, body);
4334 ex->values.sym = decl;
4336 ex->right = ex->right;
4342 /*-----------------------------------------------------------------*/
4343 /* createLabel - creates the expression tree for labels */
4344 /*-----------------------------------------------------------------*/
4346 createLabel (symbol * label, ast * stmnt)
4349 char name[SDCC_NAME_MAX + 1];
4352 /* must create fresh symbol if the symbol name */
4353 /* exists in the symbol table, since there can */
4354 /* be a variable with the same name as the labl */
4355 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4356 (csym->level == label->level))
4357 label = newSymbol (label->name, label->level);
4359 /* change the name before putting it in add _ */
4360 SNPRINTF(name, sizeof(name), "%s", label->name);
4362 /* put the label in the LabelSymbol table */
4363 /* but first check if a label of the same */
4365 if ((csym = findSym (LabelTab, NULL, name)))
4366 werror (E_DUPLICATE_LABEL, label->name);
4368 addSym (LabelTab, label, name, label->level, 0, 0);
4371 label->key = labelKey++;
4372 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4378 /*-----------------------------------------------------------------*/
4379 /* createCase - generates the parsetree for a case statement */
4380 /*-----------------------------------------------------------------*/
4382 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4384 char caseLbl[SDCC_NAME_MAX + 1];
4388 /* if the switch statement does not exist */
4389 /* then case is out of context */
4392 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4396 caseVal = decorateType (resolveSymbols (caseVal), RESULT_CHECK);
4397 /* if not a constant then error */
4398 if (!IS_LITERAL (caseVal->ftype))
4400 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4404 /* if not a integer than error */
4405 if (!IS_INTEGRAL (caseVal->ftype))
4407 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4411 /* find the end of the switch values chain */
4412 if (!(val = swStat->values.switchVals.swVals))
4413 swStat->values.switchVals.swVals = caseVal->opval.val;
4416 /* also order the cases according to value */
4418 int cVal = (int) floatFromVal (caseVal->opval.val);
4419 while (val && (int) floatFromVal (val) < cVal)
4425 /* if we reached the end then */
4428 pval->next = caseVal->opval.val;
4430 else if ((int) floatFromVal (val) == cVal)
4432 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4438 /* we found a value greater than */
4439 /* the current value we must add this */
4440 /* before the value */
4441 caseVal->opval.val->next = val;
4443 /* if this was the first in chain */
4444 if (swStat->values.switchVals.swVals == val)
4445 swStat->values.switchVals.swVals =
4448 pval->next = caseVal->opval.val;
4453 /* create the case label */
4454 SNPRINTF(caseLbl, sizeof(caseLbl),
4456 swStat->values.switchVals.swNum,
4457 (int) floatFromVal (caseVal->opval.val));
4459 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4464 /*-----------------------------------------------------------------*/
4465 /* createDefault - creates the parse tree for the default statement */
4466 /*-----------------------------------------------------------------*/
4468 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4470 char defLbl[SDCC_NAME_MAX + 1];
4472 /* if the switch statement does not exist */
4473 /* then case is out of context */
4476 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4480 if (swStat->values.switchVals.swDefault)
4482 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4487 /* turn on the default flag */
4488 swStat->values.switchVals.swDefault = 1;
4490 /* create the label */
4491 SNPRINTF (defLbl, sizeof(defLbl),
4492 "_default_%d", swStat->values.switchVals.swNum);
4493 return createLabel (newSymbol (defLbl, 0), stmnt);
4496 /*-----------------------------------------------------------------*/
4497 /* createIf - creates the parsetree for the if statement */
4498 /*-----------------------------------------------------------------*/
4500 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4502 static int Lblnum = 0;
4504 symbol *ifTrue, *ifFalse, *ifEnd;
4506 /* if neither exists */
4507 if (!elseBody && !ifBody) {
4508 // if there are no side effects (i++, j() etc)
4509 if (!hasSEFcalls(condAst)) {
4514 /* create the labels */
4515 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4516 ifFalse = newSymbol (buffer, NestLevel);
4517 /* if no else body then end == false */
4522 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4523 ifEnd = newSymbol (buffer, NestLevel);
4526 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4527 ifTrue = newSymbol (buffer, NestLevel);
4531 /* attach the ifTrue label to the top of it body */
4532 ifBody = createLabel (ifTrue, ifBody);
4533 /* attach a goto end to the ifBody if else is present */
4536 ifBody = newNode (NULLOP, ifBody,
4538 newAst_VALUE (symbolVal (ifEnd)),
4540 /* put the elseLabel on the else body */
4541 elseBody = createLabel (ifFalse, elseBody);
4542 /* out the end at the end of the body */
4543 elseBody = newNode (NULLOP,
4545 createLabel (ifEnd, NULL));
4549 ifBody = newNode (NULLOP, ifBody,
4550 createLabel (ifFalse, NULL));
4552 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4553 if (IS_IFX (condAst))
4556 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4558 return newNode (NULLOP, ifTree,
4559 newNode (NULLOP, ifBody, elseBody));
4563 /*-----------------------------------------------------------------*/
4564 /* createDo - creates parse tree for do */
4567 /* _docontinue_n: */
4568 /* condition_expression +-> trueLabel -> _dobody_n */
4570 /* +-> falseLabel-> _dobreak_n */
4572 /*-----------------------------------------------------------------*/
4574 createDo (symbol * trueLabel, symbol * continueLabel,
4575 symbol * falseLabel, ast * condAst, ast * doBody)
4580 /* if the body does not exist then it is simple */
4583 condAst = backPatchLabels (condAst, continueLabel, NULL);
4584 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4585 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4586 doTree->trueLabel = continueLabel;
4587 doTree->falseLabel = NULL;
4591 /* otherwise we have a body */
4592 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4594 /* attach the body label to the top */
4595 doBody = createLabel (trueLabel, doBody);
4596 /* attach the continue label to end of body */
4597 doBody = newNode (NULLOP, doBody,
4598 createLabel (continueLabel, NULL));
4600 /* now put the break label at the end */
4601 if (IS_IFX (condAst))
4604 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4606 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4608 /* putting it together */
4609 return newNode (NULLOP, doBody, doTree);
4612 /*-----------------------------------------------------------------*/
4613 /* createFor - creates parse tree for 'for' statement */
4616 /* condExpr +-> trueLabel -> _forbody_n */
4618 /* +-> falseLabel-> _forbreak_n */
4621 /* _forcontinue_n: */
4623 /* goto _forcond_n ; */
4625 /*-----------------------------------------------------------------*/
4627 createFor (symbol * trueLabel, symbol * continueLabel,
4628 symbol * falseLabel, symbol * condLabel,
4629 ast * initExpr, ast * condExpr, ast * loopExpr,
4634 /* if loopexpression not present then we can generate it */
4635 /* the same way as a while */
4637 return newNode (NULLOP, initExpr,
4638 createWhile (trueLabel, continueLabel,
4639 falseLabel, condExpr, forBody));
4640 /* vanilla for statement */
4641 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4643 if (condExpr && !IS_IFX (condExpr))
4644 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4647 /* attach condition label to condition */
4648 condExpr = createLabel (condLabel, condExpr);
4650 /* attach body label to body */
4651 forBody = createLabel (trueLabel, forBody);
4653 /* attach continue to forLoop expression & attach */
4654 /* goto the forcond @ and of loopExpression */
4655 loopExpr = createLabel (continueLabel,
4659 newAst_VALUE (symbolVal (condLabel)),
4661 /* now start putting them together */
4662 forTree = newNode (NULLOP, initExpr, condExpr);
4663 forTree = newNode (NULLOP, forTree, forBody);
4664 forTree = newNode (NULLOP, forTree, loopExpr);
4665 /* finally add the break label */
4666 forTree = newNode (NULLOP, forTree,
4667 createLabel (falseLabel, NULL));
4671 /*-----------------------------------------------------------------*/
4672 /* createWhile - creates parse tree for while statement */
4673 /* the while statement will be created as follows */
4675 /* _while_continue_n: */
4676 /* condition_expression +-> trueLabel -> _while_boby_n */
4678 /* +-> falseLabel -> _while_break_n */
4679 /* _while_body_n: */
4681 /* goto _while_continue_n */
4682 /* _while_break_n: */
4683 /*-----------------------------------------------------------------*/
4685 createWhile (symbol * trueLabel, symbol * continueLabel,
4686 symbol * falseLabel, ast * condExpr, ast * whileBody)
4690 /* put the continue label */
4691 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4692 condExpr = createLabel (continueLabel, condExpr);
4693 condExpr->lineno = 0;
4695 /* put the body label in front of the body */
4696 whileBody = createLabel (trueLabel, whileBody);
4697 whileBody->lineno = 0;
4698 /* put a jump to continue at the end of the body */
4699 /* and put break label at the end of the body */
4700 whileBody = newNode (NULLOP,
4703 newAst_VALUE (symbolVal (continueLabel)),
4704 createLabel (falseLabel, NULL)));
4706 /* put it all together */
4707 if (IS_IFX (condExpr))
4708 whileTree = condExpr;
4711 whileTree = newNode (IFX, condExpr, NULL);
4712 /* put the true & false labels in place */
4713 whileTree->trueLabel = trueLabel;
4714 whileTree->falseLabel = falseLabel;
4717 return newNode (NULLOP, whileTree, whileBody);
4720 /*-----------------------------------------------------------------*/
4721 /* optimizeGetHbit - get highest order bit of the expression */
4722 /*-----------------------------------------------------------------*/
4724 optimizeGetHbit (ast * tree)
4727 /* if this is not a bit and */
4728 if (!IS_BITAND (tree))
4731 /* will look for tree of the form
4732 ( expr >> ((sizeof expr) -1) ) & 1 */
4733 if (!IS_AST_LIT_VALUE (tree->right))
4736 if (AST_LIT_VALUE (tree->right) != 1)
4739 if (!IS_RIGHT_OP (tree->left))
4742 if (!IS_AST_LIT_VALUE (tree->left->right))
4745 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4746 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4749 /* make sure the port supports GETHBIT */
4750 if (port->hasExtBitOp
4751 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4754 return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_CHECK);
4758 /*-----------------------------------------------------------------*/
4759 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4760 /*-----------------------------------------------------------------*/
4762 optimizeRRCRLC (ast * root)
4764 /* will look for trees of the form
4765 (?expr << 1) | (?expr >> 7) or
4766 (?expr >> 7) | (?expr << 1) will make that
4767 into a RLC : operation ..
4769 (?expr >> 1) | (?expr << 7) or
4770 (?expr << 7) | (?expr >> 1) will make that
4771 into a RRC operation
4772 note : by 7 I mean (number of bits required to hold the
4774 /* if the root operations is not a | operation the not */
4775 if (!IS_BITOR (root))
4778 /* I have to think of a better way to match patterns this sucks */
4779 /* that aside let start looking for the first case : I use a the
4780 negative check a lot to improve the efficiency */
4781 /* (?expr << 1) | (?expr >> 7) */
4782 if (IS_LEFT_OP (root->left) &&
4783 IS_RIGHT_OP (root->right))
4786 if (!SPEC_USIGN (TETYPE (root->left->left)))
4789 if (!IS_AST_LIT_VALUE (root->left->right) ||
4790 !IS_AST_LIT_VALUE (root->right->right))
4793 /* make sure it is the same expression */
4794 if (!isAstEqual (root->left->left,
4798 if (AST_LIT_VALUE (root->left->right) != 1)
4801 if (AST_LIT_VALUE (root->right->right) !=
4802 (getSize (TTYPE (root->left->left)) * 8 - 1))
4805 /* make sure the port supports RLC */
4806 if (port->hasExtBitOp
4807 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4810 /* whew got the first case : create the AST */
4811 return newNode (RLC, root->left->left, NULL);
4815 /* check for second case */
4816 /* (?expr >> 7) | (?expr << 1) */
4817 if (IS_LEFT_OP (root->right) &&
4818 IS_RIGHT_OP (root->left))
4821 if (!SPEC_USIGN (TETYPE (root->left->left)))
4824 if (!IS_AST_LIT_VALUE (root->left->right) ||
4825 !IS_AST_LIT_VALUE (root->right->right))
4828 /* make sure it is the same symbol */
4829 if (!isAstEqual (root->left->left,
4833 if (AST_LIT_VALUE (root->right->right) != 1)
4836 if (AST_LIT_VALUE (root->left->right) !=
4837 (getSize (TTYPE (root->left->left)) * 8 - 1))
4840 /* make sure the port supports RLC */
4841 if (port->hasExtBitOp
4842 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4845 /* whew got the first case : create the AST */
4846 return newNode (RLC, root->left->left, NULL);
4851 /* third case for RRC */
4852 /* (?symbol >> 1) | (?symbol << 7) */
4853 if (IS_LEFT_OP (root->right) &&
4854 IS_RIGHT_OP (root->left))
4857 if (!SPEC_USIGN (TETYPE (root->left->left)))
4860 if (!IS_AST_LIT_VALUE (root->left->right) ||
4861 !IS_AST_LIT_VALUE (root->right->right))
4864 /* make sure it is the same symbol */
4865 if (!isAstEqual (root->left->left,
4869 if (AST_LIT_VALUE (root->left->right) != 1)
4872 if (AST_LIT_VALUE (root->right->right) !=
4873 (getSize (TTYPE (root->left->left)) * 8 - 1))
4876 /* make sure the port supports RRC */
4877 if (port->hasExtBitOp
4878 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4881 /* whew got the first case : create the AST */
4882 return newNode (RRC, root->left->left, NULL);
4886 /* fourth and last case for now */
4887 /* (?symbol << 7) | (?symbol >> 1) */
4888 if (IS_RIGHT_OP (root->right) &&
4889 IS_LEFT_OP (root->left))
4892 if (!SPEC_USIGN (TETYPE (root->left->left)))
4895 if (!IS_AST_LIT_VALUE (root->left->right) ||
4896 !IS_AST_LIT_VALUE (root->right->right))
4899 /* make sure it is the same symbol */
4900 if (!isAstEqual (root->left->left,
4904 if (AST_LIT_VALUE (root->right->right) != 1)
4907 if (AST_LIT_VALUE (root->left->right) !=
4908 (getSize (TTYPE (root->left->left)) * 8 - 1))
4911 /* make sure the port supports RRC */
4912 if (port->hasExtBitOp
4913 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4916 /* whew got the first case : create the AST */
4917 return newNode (RRC, root->left->left, NULL);
4921 /* not found return root */
4925 /*-----------------------------------------------------------------*/
4926 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
4927 /*-----------------------------------------------------------------*/
4929 optimizeSWAP (ast * root)
4931 /* will look for trees of the form
4932 (?expr << 4) | (?expr >> 4) or
4933 (?expr >> 4) | (?expr << 4) will make that
4934 into a SWAP : operation ..
4935 note : by 4 I mean (number of bits required to hold the
4937 /* if the root operations is not a | operation the not */
4938 if (!IS_BITOR (root))
4941 /* (?expr << 4) | (?expr >> 4) */
4942 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
4943 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
4946 if (!SPEC_USIGN (TETYPE (root->left->left)))
4949 if (!IS_AST_LIT_VALUE (root->left->right) ||
4950 !IS_AST_LIT_VALUE (root->right->right))
4953 /* make sure it is the same expression */
4954 if (!isAstEqual (root->left->left,
4958 if (AST_LIT_VALUE (root->left->right) !=
4959 (getSize (TTYPE (root->left->left)) * 4))
4962 if (AST_LIT_VALUE (root->right->right) !=
4963 (getSize (TTYPE (root->left->left)) * 4))
4966 /* make sure the port supports SWAP */
4967 if (port->hasExtBitOp
4968 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
4971 /* found it : create the AST */
4972 return newNode (SWAP, root->left->left, NULL);
4976 /* not found return root */
4980 /*-----------------------------------------------------------------*/
4981 /* optimizeCompare - otimizes compares for bit variables */
4982 /*-----------------------------------------------------------------*/
4984 optimizeCompare (ast * root)
4986 ast *optExpr = NULL;
4989 unsigned int litValue;
4991 /* if nothing then return nothing */
4995 /* if not a compare op then do leaves */
4996 if (!IS_COMPARE_OP (root))
4998 root->left = optimizeCompare (root->left);
4999 root->right = optimizeCompare (root->right);
5003 /* if left & right are the same then depending
5004 of the operation do */
5005 if (isAstEqual (root->left, root->right))
5007 switch (root->opval.op)
5012 optExpr = newAst_VALUE (constVal ("0"));
5017 optExpr = newAst_VALUE (constVal ("1"));
5021 return decorateType (optExpr, RESULT_CHECK);
5024 vleft = (root->left->type == EX_VALUE ?
5025 root->left->opval.val : NULL);
5027 vright = (root->right->type == EX_VALUE ?
5028 root->right->opval.val : NULL);
5030 /* if left is a BITVAR in BITSPACE */
5031 /* and right is a LITERAL then opt- */
5032 /* imize else do nothing */
5033 if (vleft && vright &&
5034 IS_BITVAR (vleft->etype) &&
5035 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5036 IS_LITERAL (vright->etype))
5039 /* if right side > 1 then comparison may never succeed */
5040 if ((litValue = (int) floatFromVal (vright)) > 1)
5042 werror (W_BAD_COMPARE);
5048 switch (root->opval.op)
5050 case '>': /* bit value greater than 1 cannot be */
5051 werror (W_BAD_COMPARE);
5055 case '<': /* bit value < 1 means 0 */
5057 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5060 case LE_OP: /* bit value <= 1 means no check */
5061 optExpr = newAst_VALUE (vright);
5064 case GE_OP: /* bit value >= 1 means only check for = */
5066 optExpr = newAst_VALUE (vleft);
5071 { /* literal is zero */
5072 switch (root->opval.op)
5074 case '<': /* bit value < 0 cannot be */
5075 werror (W_BAD_COMPARE);
5079 case '>': /* bit value > 0 means 1 */
5081 optExpr = newAst_VALUE (vleft);
5084 case LE_OP: /* bit value <= 0 means no check */
5085 case GE_OP: /* bit value >= 0 means no check */
5086 werror (W_BAD_COMPARE);
5090 case EQ_OP: /* bit == 0 means ! of bit */
5091 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5095 return decorateType (resolveSymbols (optExpr), RESULT_CHECK);
5096 } /* end-of-if of BITVAR */
5101 /*-----------------------------------------------------------------*/
5102 /* addSymToBlock : adds the symbol to the first block we find */
5103 /*-----------------------------------------------------------------*/
5105 addSymToBlock (symbol * sym, ast * tree)
5107 /* reached end of tree or a leaf */
5108 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5112 if (IS_AST_OP (tree) &&
5113 tree->opval.op == BLOCK)
5116 symbol *lsym = copySymbol (sym);
5118 lsym->next = AST_VALUES (tree, sym);
5119 AST_VALUES (tree, sym) = lsym;
5123 addSymToBlock (sym, tree->left);
5124 addSymToBlock (sym, tree->right);
5127 /*-----------------------------------------------------------------*/
5128 /* processRegParms - do processing for register parameters */
5129 /*-----------------------------------------------------------------*/
5131 processRegParms (value * args, ast * body)
5135 if (IS_REGPARM (args->etype))
5136 addSymToBlock (args->sym, body);
5141 /*-----------------------------------------------------------------*/
5142 /* resetParmKey - resets the operandkeys for the symbols */
5143 /*-----------------------------------------------------------------*/
5144 DEFSETFUNC (resetParmKey)
5155 /*-----------------------------------------------------------------*/
5156 /* createFunction - This is the key node that calls the iCode for */
5157 /* generating the code for a function. Note code */
5158 /* is generated function by function, later when */
5159 /* add inter-procedural analysis this will change */
5160 /*-----------------------------------------------------------------*/
5162 createFunction (symbol * name, ast * body)
5168 iCode *piCode = NULL;
5170 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5171 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5173 /* if check function return 0 then some problem */
5174 if (checkFunction (name, NULL) == 0)
5177 /* create a dummy block if none exists */
5179 body = newNode (BLOCK, NULL, NULL);
5183 /* check if the function name already in the symbol table */
5184 if ((csym = findSym (SymbolTab, NULL, name->name)))
5187 /* special case for compiler defined functions
5188 we need to add the name to the publics list : this
5189 actually means we are now compiling the compiler
5193 addSet (&publics, name);
5199 allocVariables (name);
5201 name->lastLine = mylineno;
5204 /* set the stack pointer */
5205 /* PENDING: check this for the mcs51 */
5206 stackPtr = -port->stack.direction * port->stack.call_overhead;
5207 if (IFFUNC_ISISR (name->type))
5208 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5209 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5210 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5212 xstackPtr = -port->stack.direction * port->stack.call_overhead;
5214 fetype = getSpec (name->type); /* get the specifier for the function */
5215 /* if this is a reentrant function then */
5216 if (IFFUNC_ISREENT (name->type))
5219 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5221 /* do processing for parameters that are passed in registers */
5222 processRegParms (FUNC_ARGS(name->type), body);
5224 /* set the stack pointer */
5228 /* allocate & autoinit the block variables */
5229 processBlockVars (body, &stack, ALLOCATE);
5231 /* save the stack information */
5232 if (options.useXstack)
5233 name->xstack = SPEC_STAK (fetype) = stack;
5235 name->stack = SPEC_STAK (fetype) = stack;
5237 /* name needs to be mangled */
5238 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5240 body = resolveSymbols (body); /* resolve the symbols */
5241 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5244 ex = newAst_VALUE (symbolVal (name)); /* create name */
5245 ex = newNode (FUNCTION, ex, body);
5246 ex->values.args = FUNC_ARGS(name->type);
5248 if (options.dump_tree) PA(ex);
5251 werror (E_FUNC_NO_CODE, name->name);
5255 /* create the node & generate intermediate code */
5257 codeOutFile = code->oFile;
5258 piCode = iCodeFromAst (ex);
5262 werror (E_FUNC_NO_CODE, name->name);
5266 eBBlockFromiCode (piCode);
5268 /* if there are any statics then do them */
5271 GcurMemmap = statsg;
5272 codeOutFile = statsg->oFile;
5273 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_CHECK)));
5279 /* dealloc the block variables */
5280 processBlockVars (body, &stack, DEALLOCATE);
5281 outputDebugStackSymbols();
5282 /* deallocate paramaters */
5283 deallocParms (FUNC_ARGS(name->type));
5285 if (IFFUNC_ISREENT (name->type))
5288 /* we are done freeup memory & cleanup */
5290 if (port->reset_labelKey) labelKey = 1;
5292 FUNC_HASBODY(name->type) = 1;
5293 addSet (&operKeyReset, name);
5294 applyToSet (operKeyReset, resetParmKey);
5299 cleanUpLevel (LabelTab, 0);
5300 cleanUpBlock (StructTab, 1);
5301 cleanUpBlock (TypedefTab, 1);
5303 xstack->syms = NULL;
5304 istack->syms = NULL;
5309 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5310 /*-----------------------------------------------------------------*/
5311 /* ast_print : prints the ast (for debugging purposes) */
5312 /*-----------------------------------------------------------------*/
5314 void ast_print (ast * tree, FILE *outfile, int indent)
5319 /* can print only decorated trees */
5320 if (!tree->decorated) return;
5322 /* if any child is an error | this one is an error do nothing */
5323 if (tree->isError ||
5324 (tree->left && tree->left->isError) ||
5325 (tree->right && tree->right->isError)) {
5326 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5330 /* print the line */
5331 /* if not block & function */
5332 if (tree->type == EX_OP &&
5333 (tree->opval.op != FUNCTION &&
5334 tree->opval.op != BLOCK &&
5335 tree->opval.op != NULLOP)) {
5338 if (tree->opval.op == FUNCTION) {
5340 value *args=FUNC_ARGS(tree->left->opval.val->type);
5341 fprintf(outfile,"FUNCTION (%s=%p) type (",
5342 tree->left->opval.val->name, tree);
5343 printTypeChain (tree->left->opval.val->type->next,outfile);
5344 fprintf(outfile,") args (");
5347 fprintf (outfile, ", ");
5349 printTypeChain (args ? args->type : NULL, outfile);
5351 args= args ? args->next : NULL;
5353 fprintf(outfile,")\n");
5354 ast_print(tree->left,outfile,indent);
5355 ast_print(tree->right,outfile,indent);
5358 if (tree->opval.op == BLOCK) {
5359 symbol *decls = tree->values.sym;
5360 INDENT(indent,outfile);
5361 fprintf(outfile,"{\n");
5363 INDENT(indent+2,outfile);
5364 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5365 decls->name, decls);
5366 printTypeChain(decls->type,outfile);
5367 fprintf(outfile,")\n");
5369 decls = decls->next;
5371 ast_print(tree->right,outfile,indent+2);
5372 INDENT(indent,outfile);
5373 fprintf(outfile,"}\n");
5376 if (tree->opval.op == NULLOP) {
5377 ast_print(tree->left,outfile,indent);
5378 ast_print(tree->right,outfile,indent);
5381 INDENT(indent,outfile);
5383 /*------------------------------------------------------------------*/
5384 /*----------------------------*/
5385 /* leaf has been reached */
5386 /*----------------------------*/
5387 /* if this is of type value */
5388 /* just get the type */
5389 if (tree->type == EX_VALUE) {
5391 if (IS_LITERAL (tree->opval.val->etype)) {
5392 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5393 if (SPEC_USIGN (tree->opval.val->etype))
5394 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5396 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5397 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5398 floatFromVal(tree->opval.val));
5399 } else if (tree->opval.val->sym) {
5400 /* if the undefined flag is set then give error message */
5401 if (tree->opval.val->sym->undefined) {
5402 fprintf(outfile,"UNDEFINED SYMBOL ");
5404 fprintf(outfile,"SYMBOL ");
5406 fprintf(outfile,"(%s=%p)",
5407 tree->opval.val->sym->name,tree);
5410 fprintf(outfile," type (");
5411 printTypeChain(tree->ftype,outfile);
5412 fprintf(outfile,")\n");
5414 fprintf(outfile,"\n");
5419 /* if type link for the case of cast */
5420 if (tree->type == EX_LINK) {
5421 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5422 printTypeChain(tree->opval.lnk,outfile);
5423 fprintf(outfile,")\n");
5428 /* depending on type of operator do */
5430 switch (tree->opval.op) {
5431 /*------------------------------------------------------------------*/
5432 /*----------------------------*/
5434 /*----------------------------*/
5436 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5437 printTypeChain(tree->ftype,outfile);
5438 fprintf(outfile,")\n");
5439 ast_print(tree->left,outfile,indent+2);
5440 ast_print(tree->right,outfile,indent+2);
5443 /*------------------------------------------------------------------*/
5444 /*----------------------------*/
5446 /*----------------------------*/
5448 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5449 printTypeChain(tree->ftype,outfile);
5450 fprintf(outfile,")\n");
5451 ast_print(tree->left,outfile,indent+2);
5452 ast_print(tree->right,outfile,indent+2);
5455 /*------------------------------------------------------------------*/
5456 /*----------------------------*/
5457 /* struct/union pointer */
5458 /*----------------------------*/
5460 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5461 printTypeChain(tree->ftype,outfile);
5462 fprintf(outfile,")\n");
5463 ast_print(tree->left,outfile,indent+2);
5464 ast_print(tree->right,outfile,indent+2);
5467 /*------------------------------------------------------------------*/
5468 /*----------------------------*/
5469 /* ++/-- operation */
5470 /*----------------------------*/
5473 fprintf(outfile,"post-");
5475 fprintf(outfile,"pre-");
5476 fprintf(outfile,"INC_OP (%p) type (",tree);
5477 printTypeChain(tree->ftype,outfile);
5478 fprintf(outfile,")\n");
5479 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5480 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5485 fprintf(outfile,"post-");
5487 fprintf(outfile,"pre-");
5488 fprintf(outfile,"DEC_OP (%p) type (",tree);
5489 printTypeChain(tree->ftype,outfile);
5490 fprintf(outfile,")\n");
5491 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5492 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5495 /*------------------------------------------------------------------*/
5496 /*----------------------------*/
5498 /*----------------------------*/
5501 fprintf(outfile,"& (%p) type (",tree);
5502 printTypeChain(tree->ftype,outfile);
5503 fprintf(outfile,")\n");
5504 ast_print(tree->left,outfile,indent+2);
5505 ast_print(tree->right,outfile,indent+2);
5507 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5508 printTypeChain(tree->ftype,outfile);
5509 fprintf(outfile,")\n");
5510 ast_print(tree->left,outfile,indent+2);
5511 ast_print(tree->right,outfile,indent+2);
5514 /*----------------------------*/
5516 /*----------------------------*/
5518 fprintf(outfile,"OR (%p) type (",tree);
5519 printTypeChain(tree->ftype,outfile);
5520 fprintf(outfile,")\n");
5521 ast_print(tree->left,outfile,indent+2);
5522 ast_print(tree->right,outfile,indent+2);
5524 /*------------------------------------------------------------------*/
5525 /*----------------------------*/
5527 /*----------------------------*/
5529 fprintf(outfile,"XOR (%p) type (",tree);
5530 printTypeChain(tree->ftype,outfile);
5531 fprintf(outfile,")\n");
5532 ast_print(tree->left,outfile,indent+2);
5533 ast_print(tree->right,outfile,indent+2);
5536 /*------------------------------------------------------------------*/
5537 /*----------------------------*/
5539 /*----------------------------*/
5541 fprintf(outfile,"DIV (%p) type (",tree);
5542 printTypeChain(tree->ftype,outfile);
5543 fprintf(outfile,")\n");
5544 ast_print(tree->left,outfile,indent+2);
5545 ast_print(tree->right,outfile,indent+2);
5547 /*------------------------------------------------------------------*/
5548 /*----------------------------*/
5550 /*----------------------------*/
5552 fprintf(outfile,"MOD (%p) type (",tree);
5553 printTypeChain(tree->ftype,outfile);
5554 fprintf(outfile,")\n");
5555 ast_print(tree->left,outfile,indent+2);
5556 ast_print(tree->right,outfile,indent+2);
5559 /*------------------------------------------------------------------*/
5560 /*----------------------------*/
5561 /* address dereference */
5562 /*----------------------------*/
5563 case '*': /* can be unary : if right is null then unary operation */
5565 fprintf(outfile,"DEREF (%p) type (",tree);
5566 printTypeChain(tree->ftype,outfile);
5567 fprintf(outfile,")\n");
5568 ast_print(tree->left,outfile,indent+2);
5571 /*------------------------------------------------------------------*/
5572 /*----------------------------*/
5573 /* multiplication */
5574 /*----------------------------*/
5575 fprintf(outfile,"MULT (%p) type (",tree);
5576 printTypeChain(tree->ftype,outfile);
5577 fprintf(outfile,")\n");
5578 ast_print(tree->left,outfile,indent+2);
5579 ast_print(tree->right,outfile,indent+2);
5583 /*------------------------------------------------------------------*/
5584 /*----------------------------*/
5585 /* unary '+' operator */
5586 /*----------------------------*/
5590 fprintf(outfile,"UPLUS (%p) type (",tree);
5591 printTypeChain(tree->ftype,outfile);
5592 fprintf(outfile,")\n");
5593 ast_print(tree->left,outfile,indent+2);
5595 /*------------------------------------------------------------------*/
5596 /*----------------------------*/
5598 /*----------------------------*/
5599 fprintf(outfile,"ADD (%p) type (",tree);
5600 printTypeChain(tree->ftype,outfile);
5601 fprintf(outfile,")\n");
5602 ast_print(tree->left,outfile,indent+2);
5603 ast_print(tree->right,outfile,indent+2);
5606 /*------------------------------------------------------------------*/
5607 /*----------------------------*/
5609 /*----------------------------*/
5610 case '-': /* can be unary */
5612 fprintf(outfile,"UMINUS (%p) type (",tree);
5613 printTypeChain(tree->ftype,outfile);
5614 fprintf(outfile,")\n");
5615 ast_print(tree->left,outfile,indent+2);
5617 /*------------------------------------------------------------------*/
5618 /*----------------------------*/
5620 /*----------------------------*/
5621 fprintf(outfile,"SUB (%p) type (",tree);
5622 printTypeChain(tree->ftype,outfile);
5623 fprintf(outfile,")\n");
5624 ast_print(tree->left,outfile,indent+2);
5625 ast_print(tree->right,outfile,indent+2);
5628 /*------------------------------------------------------------------*/
5629 /*----------------------------*/
5631 /*----------------------------*/
5633 fprintf(outfile,"COMPL (%p) type (",tree);
5634 printTypeChain(tree->ftype,outfile);
5635 fprintf(outfile,")\n");
5636 ast_print(tree->left,outfile,indent+2);
5638 /*------------------------------------------------------------------*/
5639 /*----------------------------*/
5641 /*----------------------------*/
5643 fprintf(outfile,"NOT (%p) type (",tree);
5644 printTypeChain(tree->ftype,outfile);
5645 fprintf(outfile,")\n");
5646 ast_print(tree->left,outfile,indent+2);
5648 /*------------------------------------------------------------------*/
5649 /*----------------------------*/
5651 /*----------------------------*/
5653 fprintf(outfile,"RRC (%p) type (",tree);
5654 printTypeChain(tree->ftype,outfile);
5655 fprintf(outfile,")\n");
5656 ast_print(tree->left,outfile,indent+2);
5660 fprintf(outfile,"RLC (%p) type (",tree);
5661 printTypeChain(tree->ftype,outfile);
5662 fprintf(outfile,")\n");
5663 ast_print(tree->left,outfile,indent+2);
5666 fprintf(outfile,"SWAP (%p) type (",tree);
5667 printTypeChain(tree->ftype,outfile);
5668 fprintf(outfile,")\n");
5669 ast_print(tree->left,outfile,indent+2);
5672 fprintf(outfile,"GETHBIT (%p) type (",tree);
5673 printTypeChain(tree->ftype,outfile);
5674 fprintf(outfile,")\n");
5675 ast_print(tree->left,outfile,indent+2);
5678 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5679 printTypeChain(tree->ftype,outfile);
5680 fprintf(outfile,")\n");
5681 ast_print(tree->left,outfile,indent+2);
5682 ast_print(tree->right,outfile,indent+2);
5685 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5686 printTypeChain(tree->ftype,outfile);
5687 fprintf(outfile,")\n");
5688 ast_print(tree->left,outfile,indent+2);
5689 ast_print(tree->right,outfile,indent+2);
5691 /*------------------------------------------------------------------*/
5692 /*----------------------------*/
5694 /*----------------------------*/
5695 case CAST: /* change the type */
5696 fprintf(outfile,"CAST (%p) from type (",tree);
5697 printTypeChain(tree->right->ftype,outfile);
5698 fprintf(outfile,") to type (");
5699 printTypeChain(tree->ftype,outfile);
5700 fprintf(outfile,")\n");
5701 ast_print(tree->right,outfile,indent+2);
5705 fprintf(outfile,"ANDAND (%p) type (",tree);
5706 printTypeChain(tree->ftype,outfile);
5707 fprintf(outfile,")\n");
5708 ast_print(tree->left,outfile,indent+2);
5709 ast_print(tree->right,outfile,indent+2);
5712 fprintf(outfile,"OROR (%p) type (",tree);
5713 printTypeChain(tree->ftype,outfile);
5714 fprintf(outfile,")\n");
5715 ast_print(tree->left,outfile,indent+2);
5716 ast_print(tree->right,outfile,indent+2);
5719 /*------------------------------------------------------------------*/
5720 /*----------------------------*/
5721 /* comparison operators */
5722 /*----------------------------*/
5724 fprintf(outfile,"GT(>) (%p) type (",tree);
5725 printTypeChain(tree->ftype,outfile);
5726 fprintf(outfile,")\n");
5727 ast_print(tree->left,outfile,indent+2);
5728 ast_print(tree->right,outfile,indent+2);
5731 fprintf(outfile,"LT(<) (%p) type (",tree);
5732 printTypeChain(tree->ftype,outfile);
5733 fprintf(outfile,")\n");
5734 ast_print(tree->left,outfile,indent+2);
5735 ast_print(tree->right,outfile,indent+2);
5738 fprintf(outfile,"LE(<=) (%p) type (",tree);
5739 printTypeChain(tree->ftype,outfile);
5740 fprintf(outfile,")\n");
5741 ast_print(tree->left,outfile,indent+2);
5742 ast_print(tree->right,outfile,indent+2);
5745 fprintf(outfile,"GE(>=) (%p) type (",tree);
5746 printTypeChain(tree->ftype,outfile);
5747 fprintf(outfile,")\n");
5748 ast_print(tree->left,outfile,indent+2);
5749 ast_print(tree->right,outfile,indent+2);
5752 fprintf(outfile,"EQ(==) (%p) type (",tree);
5753 printTypeChain(tree->ftype,outfile);
5754 fprintf(outfile,")\n");
5755 ast_print(tree->left,outfile,indent+2);
5756 ast_print(tree->right,outfile,indent+2);
5759 fprintf(outfile,"NE(!=) (%p) type (",tree);
5760 printTypeChain(tree->ftype,outfile);
5761 fprintf(outfile,")\n");
5762 ast_print(tree->left,outfile,indent+2);
5763 ast_print(tree->right,outfile,indent+2);
5764 /*------------------------------------------------------------------*/
5765 /*----------------------------*/
5767 /*----------------------------*/
5768 case SIZEOF: /* evaluate wihout code generation */
5769 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5772 /*------------------------------------------------------------------*/
5773 /*----------------------------*/
5774 /* conditional operator '?' */
5775 /*----------------------------*/
5777 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5778 printTypeChain(tree->ftype,outfile);
5779 fprintf(outfile,")\n");
5780 ast_print(tree->left,outfile,indent+2);
5781 ast_print(tree->right,outfile,indent+2);
5785 fprintf(outfile,"COLON(:) (%p) type (",tree);
5786 printTypeChain(tree->ftype,outfile);
5787 fprintf(outfile,")\n");
5788 ast_print(tree->left,outfile,indent+2);
5789 ast_print(tree->right,outfile,indent+2);
5792 /*------------------------------------------------------------------*/
5793 /*----------------------------*/
5794 /* assignment operators */
5795 /*----------------------------*/
5797 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5798 printTypeChain(tree->ftype,outfile);
5799 fprintf(outfile,")\n");
5800 ast_print(tree->left,outfile,indent+2);
5801 ast_print(tree->right,outfile,indent+2);
5804 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5805 printTypeChain(tree->ftype,outfile);
5806 fprintf(outfile,")\n");
5807 ast_print(tree->left,outfile,indent+2);
5808 ast_print(tree->right,outfile,indent+2);
5811 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5812 printTypeChain(tree->ftype,outfile);
5813 fprintf(outfile,")\n");
5814 ast_print(tree->left,outfile,indent+2);
5815 ast_print(tree->right,outfile,indent+2);
5818 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5819 printTypeChain(tree->ftype,outfile);
5820 fprintf(outfile,")\n");
5821 ast_print(tree->left,outfile,indent+2);
5822 ast_print(tree->right,outfile,indent+2);
5825 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5826 printTypeChain(tree->ftype,outfile);
5827 fprintf(outfile,")\n");
5828 ast_print(tree->left,outfile,indent+2);
5829 ast_print(tree->right,outfile,indent+2);
5832 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5833 printTypeChain(tree->ftype,outfile);
5834 fprintf(outfile,")\n");
5835 ast_print(tree->left,outfile,indent+2);
5836 ast_print(tree->right,outfile,indent+2);
5839 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5840 printTypeChain(tree->ftype,outfile);
5841 fprintf(outfile,")\n");
5842 ast_print(tree->left,outfile,indent+2);
5843 ast_print(tree->right,outfile,indent+2);
5845 /*------------------------------------------------------------------*/
5846 /*----------------------------*/
5848 /*----------------------------*/
5850 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5851 printTypeChain(tree->ftype,outfile);
5852 fprintf(outfile,")\n");
5853 ast_print(tree->left,outfile,indent+2);
5854 ast_print(tree->right,outfile,indent+2);
5856 /*------------------------------------------------------------------*/
5857 /*----------------------------*/
5859 /*----------------------------*/
5861 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5862 printTypeChain(tree->ftype,outfile);
5863 fprintf(outfile,")\n");
5864 ast_print(tree->left,outfile,indent+2);
5865 ast_print(tree->right,outfile,indent+2);
5867 /*------------------------------------------------------------------*/
5868 /*----------------------------*/
5869 /* straight assignemnt */
5870 /*----------------------------*/
5872 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5873 printTypeChain(tree->ftype,outfile);
5874 fprintf(outfile,")\n");
5875 ast_print(tree->left,outfile,indent+2);
5876 ast_print(tree->right,outfile,indent+2);
5878 /*------------------------------------------------------------------*/
5879 /*----------------------------*/
5880 /* comma operator */
5881 /*----------------------------*/
5883 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5884 printTypeChain(tree->ftype,outfile);
5885 fprintf(outfile,")\n");
5886 ast_print(tree->left,outfile,indent+2);
5887 ast_print(tree->right,outfile,indent+2);
5889 /*------------------------------------------------------------------*/
5890 /*----------------------------*/
5892 /*----------------------------*/
5895 fprintf(outfile,"CALL (%p) type (",tree);
5896 printTypeChain(tree->ftype,outfile);
5897 fprintf(outfile,")\n");
5898 ast_print(tree->left,outfile,indent+2);
5899 ast_print(tree->right,outfile,indent+2);
5902 fprintf(outfile,"PARMS\n");
5903 ast_print(tree->left,outfile,indent+2);
5904 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5905 ast_print(tree->right,outfile,indent+2);
5908 /*------------------------------------------------------------------*/
5909 /*----------------------------*/
5910 /* return statement */
5911 /*----------------------------*/
5913 fprintf(outfile,"RETURN (%p) type (",tree);
5915 printTypeChain(tree->right->ftype,outfile);
5917 fprintf(outfile,")\n");
5918 ast_print(tree->right,outfile,indent+2);
5920 /*------------------------------------------------------------------*/
5921 /*----------------------------*/
5922 /* label statement */
5923 /*----------------------------*/
5925 fprintf(outfile,"LABEL (%p)\n",tree);
5926 ast_print(tree->left,outfile,indent+2);
5927 ast_print(tree->right,outfile,indent);
5929 /*------------------------------------------------------------------*/
5930 /*----------------------------*/
5931 /* switch statement */
5932 /*----------------------------*/
5936 fprintf(outfile,"SWITCH (%p) ",tree);
5937 ast_print(tree->left,outfile,0);
5938 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5939 INDENT(indent+2,outfile);
5940 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5941 (int) floatFromVal(val),
5942 tree->values.switchVals.swNum,
5943 (int) floatFromVal(val));
5945 ast_print(tree->right,outfile,indent);
5948 /*------------------------------------------------------------------*/
5949 /*----------------------------*/
5951 /*----------------------------*/
5953 fprintf(outfile,"IF (%p) \n",tree);
5954 ast_print(tree->left,outfile,indent+2);
5955 if (tree->trueLabel) {
5956 INDENT(indent+2,outfile);
5957 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5959 if (tree->falseLabel) {
5960 INDENT(indent+2,outfile);
5961 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5963 ast_print(tree->right,outfile,indent+2);
5965 /*----------------------------*/
5966 /* goto Statement */
5967 /*----------------------------*/
5969 fprintf(outfile,"GOTO (%p) \n",tree);
5970 ast_print(tree->left,outfile,indent+2);
5971 fprintf(outfile,"\n");
5973 /*------------------------------------------------------------------*/
5974 /*----------------------------*/
5976 /*----------------------------*/
5978 fprintf(outfile,"FOR (%p) \n",tree);
5979 if (AST_FOR( tree, initExpr)) {
5980 INDENT(indent+2,outfile);
5981 fprintf(outfile,"INIT EXPR ");
5982 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5984 if (AST_FOR( tree, condExpr)) {
5985 INDENT(indent+2,outfile);
5986 fprintf(outfile,"COND EXPR ");
5987 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5989 if (AST_FOR( tree, loopExpr)) {
5990 INDENT(indent+2,outfile);
5991 fprintf(outfile,"LOOP EXPR ");
5992 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5994 fprintf(outfile,"FOR LOOP BODY \n");
5995 ast_print(tree->left,outfile,indent+2);
5998 fprintf(outfile,"CRITICAL (%p) \n",tree);
5999 ast_print(tree->left,outfile,indent+2);
6007 ast_print(t,stdout,0);
6012 /*-----------------------------------------------------------------*/
6013 /* astErrors : returns non-zero if errors present in tree */
6014 /*-----------------------------------------------------------------*/
6015 int astErrors(ast *t)
6024 if (t->type == EX_VALUE
6025 && t->opval.val->sym
6026 && t->opval.val->sym->undefined)
6029 errors += astErrors(t->left);
6030 errors += astErrors(t->right);