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)
2036 case RESULT_TYPE_CHAR:
2037 if (getSize ((*tree)->etype) <= 1)
2039 newLink = newCharLink();
2041 case RESULT_TYPE_INT:
2043 if (getSize ((*tree)->etype) > INTSIZE)
2045 /* warn ("Loosing significant digits"); */
2049 /* char: promote to int */
2051 getSize ((*tree)->etype) >= INTSIZE)
2053 newLink = newIntLink();
2055 case RESULT_TYPE_OTHER:
2058 /* long, float: promote to int */
2059 if (getSize ((*tree)->etype) >= INTSIZE)
2061 newLink = newIntLink();
2066 (*tree)->decorated = 0;
2067 *tree = newNode (CAST, newAst_LINK (newLink), *tree);
2068 /* keep unsigned type */
2069 SPEC_USIGN ((*tree)->left->opval.lnk) = IS_UNSIGNED ((*tree)->right->etype) ? 1 : 0;
2070 *tree = decorateType (*tree, resultType);
2073 /*-----------------------------------------------------------------*/
2074 /* resultTypePropagate - decides if resultType can be propagated */
2075 /*-----------------------------------------------------------------*/
2077 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2079 switch (tree->opval.op)
2090 return RESULT_TYPE_NONE;
2094 return RESULT_TYPE_NONE;
2098 /*-----------------------------------------------------------------*/
2099 /* getLeftResultType - gets type from left branch for propagation */
2100 /*-----------------------------------------------------------------*/
2102 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2104 switch (tree->opval.op)
2108 if (IS_PTR (tree->left->ftype))
2109 return RESULT_TYPE_NONE;
2111 return getResultTypeFromType (tree->left->etype);
2113 if (IS_PTR (currFunc->type->next))
2114 return RESULT_TYPE_NONE;
2116 return getResultTypeFromType (currFunc->type->next);
2122 /*--------------------------------------------------------------------*/
2123 /* decorateType - compute type for this tree, also does type checking.*/
2124 /* This is done bottom up, since type has to flow upwards. */
2125 /* resultType flows top-down and forces e.g. char-arithmetik, if the */
2126 /* result is a char and the operand(s) are int's. */
2127 /* It also does constant folding, and parameter checking. */
2128 /*--------------------------------------------------------------------*/
2130 decorateType (ast * tree, RESULT_TYPE resultType)
2134 RESULT_TYPE resultTypeProp;
2139 /* if already has type then do nothing */
2140 if (tree->decorated)
2143 tree->decorated = 1;
2146 /* print the line */
2147 /* if not block & function */
2148 if (tree->type == EX_OP &&
2149 (tree->opval.op != FUNCTION &&
2150 tree->opval.op != BLOCK &&
2151 tree->opval.op != NULLOP))
2153 filename = tree->filename;
2154 lineno = tree->lineno;
2158 /* if any child is an error | this one is an error do nothing */
2159 if (tree->isError ||
2160 (tree->left && tree->left->isError) ||
2161 (tree->right && tree->right->isError))
2164 /*------------------------------------------------------------------*/
2165 /*----------------------------*/
2166 /* leaf has been reached */
2167 /*----------------------------*/
2168 lineno=tree->lineno;
2169 /* if this is of type value */
2170 /* just get the type */
2171 if (tree->type == EX_VALUE)
2174 if (IS_LITERAL (tree->opval.val->etype))
2177 /* if this is a character array then declare it */
2178 if (IS_ARRAY (tree->opval.val->type))
2179 tree->opval.val = stringToSymbol (tree->opval.val);
2181 /* otherwise just copy the type information */
2182 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2186 if (tree->opval.val->sym)
2188 /* if the undefined flag is set then give error message */
2189 if (tree->opval.val->sym->undefined)
2191 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2193 TTYPE (tree) = TETYPE (tree) =
2194 tree->opval.val->type = tree->opval.val->sym->type =
2195 tree->opval.val->etype = tree->opval.val->sym->etype =
2196 copyLinkChain (INTTYPE);
2201 /* if impilicit i.e. struct/union member then no type */
2202 if (tree->opval.val->sym->implicit)
2203 TTYPE (tree) = TETYPE (tree) = NULL;
2208 /* else copy the type */
2209 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2211 /* and mark it as referenced */
2212 tree->opval.val->sym->isref = 1;
2220 /* if type link for the case of cast */
2221 if (tree->type == EX_LINK)
2223 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2231 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2233 if (tree->left && tree->left->type == EX_OPERAND
2234 && (tree->left->opval.op == INC_OP
2235 || tree->left->opval.op == DEC_OP)
2236 && tree->left->left)
2238 tree->left->right = tree->left->left;
2239 tree->left->left = NULL;
2241 if (tree->right && tree->right->type == EX_OPERAND
2242 && (tree->right->opval.op == INC_OP
2243 || tree->right->opval.op == DEC_OP)
2244 && tree->right->left)
2246 tree->right->right = tree->right->left;
2247 tree->right->left = NULL;
2252 /* Before decorating the left branch we've to decide in dependence
2253 upon tree->opval.op, if resultType can be propagated */
2254 if (getenv ("SDCC_NEWTYPEFLOW"))
2255 resultTypeProp = resultTypePropagate (tree, resultType);
2257 resultTypeProp = RESULT_TYPE_NONE; /* provide initialization */
2259 dtl = decorateType (tree->left, resultTypeProp);
2261 /* After decorating the left branch there's type information available
2262 in tree->left->?type. If the op is e.g. '=' we extract the type
2263 information from there and propagate it to the right branch. */
2264 if (getenv ("SDCC_NEWTYPEFLOW"))
2265 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2267 /* delay right side for '?' operator since conditional macro expansions
2268 might rely on this */
2269 dtr = tree->opval.op == '?' ? tree->right :
2270 decorateType (tree->right, resultTypeProp);
2272 /* this is to take care of situations
2273 when the tree gets rewritten */
2274 if (dtl != tree->left)
2276 if (dtr != tree->right)
2278 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2281 if (!getenv ("SDCC_NEWTYPEFLOW"))
2283 if (IS_AST_OP(tree) &&
2284 (tree->opval.op == CAST || tree->opval.op == '=') &&
2285 (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) &&
2286 (getSize(RTYPE(tree)) < (unsigned) INTSIZE)) {
2287 /* this is a cast/assign to a bigger type */
2288 if (IS_AST_OP(tree->right) &&
2289 IS_INTEGRAL(tree->right->ftype) &&
2290 (tree->right->opval.op == LEFT_OP ||
2291 tree->right->opval.op == '*' ||
2292 tree->right->opval.op == '+' ||
2293 tree->right->opval.op == '-') &&
2294 tree->right->right) {
2295 /* we should cast an operand instead of the result */
2296 tree->right->decorated = 0;
2297 tree->right->left = newNode( CAST, newAst_LINK(newIntLink()),
2299 tree->right = decorateType(tree->right, RESULT_CHECK);
2305 /* depending on type of operator do */
2307 switch (tree->opval.op)
2309 /*------------------------------------------------------------------*/
2310 /*----------------------------*/
2312 /*----------------------------*/
2315 /* determine which is the array & which the index */
2316 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2319 ast *tempTree = tree->left;
2320 tree->left = tree->right;
2321 tree->right = tempTree;
2324 /* first check if this is a array or a pointer */
2325 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2327 werror (E_NEED_ARRAY_PTR, "[]");
2328 goto errorTreeReturn;
2331 /* check if the type of the idx */
2332 if (!IS_INTEGRAL (RTYPE (tree)))
2334 werror (E_IDX_NOT_INT);
2335 goto errorTreeReturn;
2338 /* if the left is an rvalue then error */
2341 werror (E_LVALUE_REQUIRED, "array access");
2342 goto errorTreeReturn;
2345 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2348 /*------------------------------------------------------------------*/
2349 /*----------------------------*/
2351 /*----------------------------*/
2353 /* if this is not a structure */
2354 if (!IS_STRUCT (LTYPE (tree)))
2356 werror (E_STRUCT_UNION, ".");
2357 goto errorTreeReturn;
2359 TTYPE (tree) = structElemType (LTYPE (tree),
2360 (tree->right->type == EX_VALUE ?
2361 tree->right->opval.val : NULL));
2362 TETYPE (tree) = getSpec (TTYPE (tree));
2365 /*------------------------------------------------------------------*/
2366 /*----------------------------*/
2367 /* struct/union pointer */
2368 /*----------------------------*/
2370 /* if not pointer to a structure */
2371 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2373 werror (E_PTR_REQD);
2374 goto errorTreeReturn;
2377 if (!IS_STRUCT (LTYPE (tree)->next))
2379 werror (E_STRUCT_UNION, "->");
2380 goto errorTreeReturn;
2383 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2384 (tree->right->type == EX_VALUE ?
2385 tree->right->opval.val : NULL));
2386 TETYPE (tree) = getSpec (TTYPE (tree));
2388 /* adjust the storage class */
2389 switch (DCL_TYPE(tree->left->ftype)) {
2391 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2394 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2397 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2400 SPEC_SCLS (TETYPE (tree)) = 0;
2403 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2406 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2409 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2412 SPEC_SCLS (TETYPE (tree)) = 0;
2419 /* This breaks with extern declarations, bitfields, and perhaps other */
2420 /* cases (gcse). Let's leave this optimization disabled for now and */
2421 /* ponder if there's a safe way to do this. -- EEP */
2423 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2424 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2426 /* If defined struct type at addr var
2427 then rewrite (&struct var)->member
2429 and define membertype at (addr+offsetof(struct var,member)) temp
2432 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2433 AST_SYMBOL(tree->right));
2435 sym = newSymbol(genSymName (0), 0);
2436 sym->type = TTYPE (tree);
2437 sym->etype = getSpec(sym->type);
2438 sym->lineDef = tree->lineno;
2441 SPEC_STAT (sym->etype) = 1;
2442 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2444 SPEC_ABSA(sym->etype) = 1;
2445 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2448 AST_VALUE (tree) = symbolVal(sym);
2451 tree->type = EX_VALUE;
2459 /*------------------------------------------------------------------*/
2460 /*----------------------------*/
2461 /* ++/-- operation */
2462 /*----------------------------*/
2466 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2467 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2468 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2469 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2478 /*------------------------------------------------------------------*/
2479 /*----------------------------*/
2481 /*----------------------------*/
2482 case '&': /* can be unary */
2483 /* if right is NULL then unary operation */
2484 if (tree->right) /* not an unary operation */
2487 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2489 werror (E_BITWISE_OP);
2490 werror (W_CONTINUE, "left & right types are ");
2491 printTypeChain (LTYPE (tree), stderr);
2492 fprintf (stderr, ",");
2493 printTypeChain (RTYPE (tree), stderr);
2494 fprintf (stderr, "\n");
2495 goto errorTreeReturn;
2498 /* if they are both literal */
2499 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2501 tree->type = EX_VALUE;
2502 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2503 valFromType (RETYPE (tree)), '&');
2505 tree->right = tree->left = NULL;
2506 TETYPE (tree) = tree->opval.val->etype;
2507 TTYPE (tree) = tree->opval.val->type;
2511 /* see if this is a GETHBIT operation if yes
2514 ast *otree = optimizeGetHbit (tree);
2517 return decorateType (otree, RESULT_CHECK);
2520 if (getenv ("SDCC_NEWTYPEFLOW"))
2522 addCast (&tree->left, resultType, FALSE);
2523 addCast (&tree->right, resultType, FALSE);
2525 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
2526 TETYPE (tree) = getSpec (TTYPE (tree));
2528 /* if left is a literal exchange left & right */
2529 if (IS_LITERAL (LTYPE (tree)))
2531 ast *tTree = tree->left;
2532 tree->left = tree->right;
2533 tree->right = tTree;
2536 /* if right is a literal and */
2537 /* we can find a 2nd literal in a and-tree then */
2538 /* rearrange the tree */
2539 if (IS_LITERAL (RTYPE (tree)))
2542 ast *litTree = searchLitOp (tree, &parent, "&");
2545 ast *tTree = litTree->left;
2546 litTree->left = tree->right;
2547 tree->right = tTree;
2548 /* both operands in tTree are literal now */
2549 decorateType (parent, RESULT_CHECK);
2553 LRVAL (tree) = RRVAL (tree) = 1;
2558 /*------------------------------------------------------------------*/
2559 /*----------------------------*/
2561 /*----------------------------*/
2562 p = newLink (DECLARATOR);
2563 /* if bit field then error */
2564 if (IS_BITVAR (tree->left->etype))
2566 werror (E_ILLEGAL_ADDR, "address of bit variable");
2567 goto errorTreeReturn;
2570 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2572 werror (E_ILLEGAL_ADDR, "address of register variable");
2573 goto errorTreeReturn;
2576 if (IS_FUNC (LTYPE (tree)))
2578 // this ought to be ignored
2579 return (tree->left);
2582 if (IS_LITERAL(LTYPE(tree)))
2584 werror (E_ILLEGAL_ADDR, "address of literal");
2585 goto errorTreeReturn;
2590 werror (E_LVALUE_REQUIRED, "address of");
2591 goto errorTreeReturn;
2594 DCL_TYPE (p) = POINTER;
2595 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2596 DCL_TYPE (p) = CPOINTER;
2597 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2598 DCL_TYPE (p) = FPOINTER;
2599 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2600 DCL_TYPE (p) = PPOINTER;
2601 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2602 DCL_TYPE (p) = IPOINTER;
2603 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2604 DCL_TYPE (p) = EEPPOINTER;
2605 else if (SPEC_OCLS(tree->left->etype))
2606 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2608 DCL_TYPE (p) = POINTER;
2610 if (IS_AST_SYM_VALUE (tree->left))
2612 AST_SYMBOL (tree->left)->addrtaken = 1;
2613 AST_SYMBOL (tree->left)->allocreq = 1;
2616 p->next = LTYPE (tree);
2618 TETYPE (tree) = getSpec (TTYPE (tree));
2623 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2624 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2626 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2627 AST_SYMBOL(tree->left->right));
2628 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2629 valueFromLit(element->offset));
2632 tree->type = EX_VALUE;
2633 tree->values.literalFromCast = 1;
2639 /*------------------------------------------------------------------*/
2640 /*----------------------------*/
2642 /*----------------------------*/
2644 /* if the rewrite succeeds then don't go any furthur */
2646 ast *wtree = optimizeRRCRLC (tree);
2648 return decorateType (wtree, RESULT_CHECK);
2650 wtree = optimizeSWAP (tree);
2652 return decorateType (wtree, RESULT_CHECK);
2655 /* if left is a literal exchange left & right */
2656 if (IS_LITERAL (LTYPE (tree)))
2658 ast *tTree = tree->left;
2659 tree->left = tree->right;
2660 tree->right = tTree;
2663 /* if right is a literal and */
2664 /* we can find a 2nd literal in a or-tree then */
2665 /* rearrange the tree */
2666 if (IS_LITERAL (RTYPE (tree)))
2669 ast *litTree = searchLitOp (tree, &parent, "|");
2672 ast *tTree = litTree->left;
2673 litTree->left = tree->right;
2674 tree->right = tTree;
2675 /* both operands in tTree are literal now */
2676 decorateType (parent, RESULT_CHECK);
2681 /*------------------------------------------------------------------*/
2682 /*----------------------------*/
2684 /*----------------------------*/
2686 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2688 werror (E_BITWISE_OP);
2689 werror (W_CONTINUE, "left & right types are ");
2690 printTypeChain (LTYPE (tree), stderr);
2691 fprintf (stderr, ",");
2692 printTypeChain (RTYPE (tree), stderr);
2693 fprintf (stderr, "\n");
2694 goto errorTreeReturn;
2697 /* if they are both literal then */
2698 /* rewrite the tree */
2699 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2701 tree->type = EX_VALUE;
2702 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2703 valFromType (RETYPE (tree)),
2705 tree->right = tree->left = NULL;
2706 TETYPE (tree) = tree->opval.val->etype;
2707 TTYPE (tree) = tree->opval.val->type;
2711 /* if left is a literal exchange left & right */
2712 if (IS_LITERAL (LTYPE (tree)))
2714 ast *tTree = tree->left;
2715 tree->left = tree->right;
2716 tree->right = tTree;
2719 /* if right is a literal and */
2720 /* we can find a 2nd literal in a xor-tree then */
2721 /* rearrange the tree */
2722 if (IS_LITERAL (RTYPE (tree)) &&
2723 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2726 ast *litTree = searchLitOp (tree, &parent, "^");
2729 ast *tTree = litTree->left;
2730 litTree->left = tree->right;
2731 tree->right = tTree;
2732 /* both operands in litTree are literal now */
2733 decorateType (parent, RESULT_CHECK);
2737 LRVAL (tree) = RRVAL (tree) = 1;
2738 if (getenv ("SDCC_NEWTYPEFLOW"))
2740 addCast (&tree->left, resultType, FALSE);
2741 addCast (&tree->right, resultType, FALSE);
2743 TETYPE (tree) = getSpec (TTYPE (tree) =
2744 computeType (LTYPE (tree),
2750 /*------------------------------------------------------------------*/
2751 /*----------------------------*/
2753 /*----------------------------*/
2755 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2757 werror (E_INVALID_OP, "divide");
2758 goto errorTreeReturn;
2760 /* if they are both literal then */
2761 /* rewrite the tree */
2762 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2764 tree->type = EX_VALUE;
2765 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2766 valFromType (RETYPE (tree)));
2767 tree->right = tree->left = NULL;
2768 TETYPE (tree) = getSpec (TTYPE (tree) =
2769 tree->opval.val->type);
2773 LRVAL (tree) = RRVAL (tree) = 1;
2774 TETYPE (tree) = getSpec (TTYPE (tree) =
2775 computeType (LTYPE (tree),
2777 ! (IS_UNSIGNED (LTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)))));
2779 /* if right is a literal and */
2780 /* left is also a division by a literal then */
2781 /* rearrange the tree */
2782 if (IS_LITERAL (RTYPE (tree))
2783 /* avoid infinite loop */
2784 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2787 ast *litTree = searchLitOp (tree, &parent, "/");
2790 if (IS_LITERAL (RTYPE (litTree)))
2793 litTree->right = newNode ('*', litTree->right, tree->right);
2794 litTree->right->lineno = tree->lineno;
2796 tree->right->opval.val = constVal ("1");
2797 decorateType (parent, RESULT_CHECK);
2801 /* litTree->left is literal: no gcse possible.
2802 We can't call decorateType(parent, RESULT_CHECK), because
2803 this would cause an infinit loop. */
2804 parent->decorated = 1;
2805 decorateType (litTree, RESULT_CHECK);
2812 /*------------------------------------------------------------------*/
2813 /*----------------------------*/
2815 /*----------------------------*/
2817 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2819 werror (E_BITWISE_OP);
2820 werror (W_CONTINUE, "left & right types are ");
2821 printTypeChain (LTYPE (tree), stderr);
2822 fprintf (stderr, ",");
2823 printTypeChain (RTYPE (tree), stderr);
2824 fprintf (stderr, "\n");
2825 goto errorTreeReturn;
2827 /* if they are both literal then */
2828 /* rewrite the tree */
2829 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2831 tree->type = EX_VALUE;
2832 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2833 valFromType (RETYPE (tree)));
2834 tree->right = tree->left = NULL;
2835 TETYPE (tree) = getSpec (TTYPE (tree) =
2836 tree->opval.val->type);
2839 LRVAL (tree) = RRVAL (tree) = 1;
2840 TETYPE (tree) = getSpec (TTYPE (tree) =
2841 computeType (LTYPE (tree),
2843 ! (IS_UNSIGNED (LTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)))));
2846 /*------------------------------------------------------------------*/
2847 /*----------------------------*/
2848 /* address dereference */
2849 /*----------------------------*/
2850 case '*': /* can be unary : if right is null then unary operation */
2853 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2855 werror (E_PTR_REQD);
2856 goto errorTreeReturn;
2861 werror (E_LVALUE_REQUIRED, "pointer deref");
2862 goto errorTreeReturn;
2864 if (IS_ADDRESS_OF_OP(tree->left))
2866 /* replace *&obj with obj */
2867 return tree->left->left;
2869 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2870 TETYPE (tree) = getSpec (TTYPE (tree));
2871 /* adjust the storage class */
2872 switch (DCL_TYPE(tree->left->ftype)) {
2874 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2877 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2880 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2883 SPEC_SCLS (TETYPE (tree)) = 0;
2886 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2889 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2892 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2895 SPEC_SCLS (TETYPE (tree)) = 0;
2904 /*------------------------------------------------------------------*/
2905 /*----------------------------*/
2906 /* multiplication */
2907 /*----------------------------*/
2908 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2910 werror (E_INVALID_OP, "multiplication");
2911 goto errorTreeReturn;
2914 /* if they are both literal then */
2915 /* rewrite the tree */
2916 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2918 tree->type = EX_VALUE;
2919 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2920 valFromType (RETYPE (tree)));
2921 tree->right = tree->left = NULL;
2922 TETYPE (tree) = getSpec (TTYPE (tree) =
2923 tree->opval.val->type);
2927 /* if left is a literal exchange left & right */
2928 if (IS_LITERAL (LTYPE (tree)))
2930 ast *tTree = tree->left;
2931 tree->left = tree->right;
2932 tree->right = tTree;
2935 /* if right is a literal and */
2936 /* we can find a 2nd literal in a mul-tree then */
2937 /* rearrange the tree */
2938 if (IS_LITERAL (RTYPE (tree)))
2941 ast *litTree = searchLitOp (tree, &parent, "*");
2944 ast *tTree = litTree->left;
2945 litTree->left = tree->right;
2946 tree->right = tTree;
2947 /* both operands in litTree are literal now */
2948 decorateType (parent, RESULT_CHECK);
2952 LRVAL (tree) = RRVAL (tree) = 1;
2953 if (!getenv ("SDCC_NEWTYPEFLOW"))
2954 TETYPE (tree) = getSpec (TTYPE (tree) =
2955 computeType (LTYPE (tree),
2960 addCast (&tree->left, resultType, FALSE);
2961 addCast (&tree->right, resultType, FALSE);
2962 TETYPE (tree) = getSpec (TTYPE (tree) =
2963 computeType (LTYPE (tree),
2965 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
2970 /*------------------------------------------------------------------*/
2971 /*----------------------------*/
2972 /* unary '+' operator */
2973 /*----------------------------*/
2978 if (!IS_ARITHMETIC (LTYPE (tree)))
2980 werror (E_UNARY_OP, '+');
2981 goto errorTreeReturn;
2984 /* if left is a literal then do it */
2985 if (IS_LITERAL (LTYPE (tree)))
2987 tree->type = EX_VALUE;
2988 tree->opval.val = valFromType (LETYPE (tree));
2990 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2994 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2998 /*------------------------------------------------------------------*/
2999 /*----------------------------*/
3001 /*----------------------------*/
3003 /* this is not a unary operation */
3004 /* if both pointers then problem */
3005 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3006 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3008 werror (E_PTR_PLUS_PTR);
3009 goto errorTreeReturn;
3012 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3013 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3015 werror (E_PLUS_INVALID, "+");
3016 goto errorTreeReturn;
3019 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3020 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3022 werror (E_PLUS_INVALID, "+");
3023 goto errorTreeReturn;
3025 /* if they are both literal then */
3026 /* rewrite the tree */
3027 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3029 tree->type = EX_VALUE;
3030 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3031 valFromType (RETYPE (tree)));
3032 tree->right = tree->left = NULL;
3033 TETYPE (tree) = getSpec (TTYPE (tree) =
3034 tree->opval.val->type);
3038 /* if the right is a pointer or left is a literal
3039 xchange left & right */
3040 if (IS_ARRAY (RTYPE (tree)) ||
3041 IS_PTR (RTYPE (tree)) ||
3042 IS_LITERAL (LTYPE (tree)))
3044 ast *tTree = tree->left;
3045 tree->left = tree->right;
3046 tree->right = tTree;
3049 /* if right is a literal and */
3050 /* left is also an addition/subtraction with a literal then */
3051 /* rearrange the tree */
3052 if (IS_LITERAL (RTYPE (tree)))
3054 ast *litTree, *parent;
3055 litTree = searchLitOp (tree, &parent, "+-");
3058 if (litTree->opval.op == '+')
3061 ast *tTree = litTree->left;
3062 litTree->left = tree->right;
3063 tree->right = tree->left;
3066 else if (litTree->opval.op == '-')
3068 if (IS_LITERAL (RTYPE (litTree)))
3071 ast *tTree = litTree->left;
3072 litTree->left = tree->right;
3073 tree->right = tTree;
3078 ast *tTree = litTree->right;
3079 litTree->right = tree->right;
3080 tree->right = tTree;
3081 litTree->opval.op = '+';
3082 tree->opval.op = '-';
3085 decorateType (parent, RESULT_CHECK);
3089 LRVAL (tree) = RRVAL (tree) = 1;
3090 /* if the left is a pointer */
3091 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3092 TETYPE (tree) = getSpec (TTYPE (tree) =
3095 if (!getenv ("SDCC_NEWTYPEFLOW"))
3096 TETYPE (tree) = getSpec (TTYPE (tree) =
3097 computeType (LTYPE (tree),
3102 addCast (&tree->left, resultType, TRUE);
3103 addCast (&tree->right, resultType, TRUE);
3104 TETYPE (tree) = getSpec (TTYPE (tree) =
3105 computeType (LTYPE (tree),
3107 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
3112 /*------------------------------------------------------------------*/
3113 /*----------------------------*/
3115 /*----------------------------*/
3116 case '-': /* can be unary */
3117 /* if right is null then unary */
3121 if (!IS_ARITHMETIC (LTYPE (tree)))
3123 werror (E_UNARY_OP, tree->opval.op);
3124 goto errorTreeReturn;
3127 /* if left is a literal then do it */
3128 if (IS_LITERAL (LTYPE (tree)))
3130 tree->type = EX_VALUE;
3131 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3133 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3134 SPEC_USIGN(TETYPE(tree)) = 0;
3138 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3142 /*------------------------------------------------------------------*/
3143 /*----------------------------*/
3145 /*----------------------------*/
3147 if (!(IS_PTR (LTYPE (tree)) ||
3148 IS_ARRAY (LTYPE (tree)) ||
3149 IS_ARITHMETIC (LTYPE (tree))))
3151 werror (E_PLUS_INVALID, "-");
3152 goto errorTreeReturn;
3155 if (!(IS_PTR (RTYPE (tree)) ||
3156 IS_ARRAY (RTYPE (tree)) ||
3157 IS_ARITHMETIC (RTYPE (tree))))
3159 werror (E_PLUS_INVALID, "-");
3160 goto errorTreeReturn;
3163 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3164 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3165 IS_INTEGRAL (RTYPE (tree))))
3167 werror (E_PLUS_INVALID, "-");
3168 goto errorTreeReturn;
3171 /* if they are both literal then */
3172 /* rewrite the tree */
3173 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3175 tree->type = EX_VALUE;
3176 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3177 valFromType (RETYPE (tree)));
3178 tree->right = tree->left = NULL;
3179 TETYPE (tree) = getSpec (TTYPE (tree) =
3180 tree->opval.val->type);
3184 /* if the left & right are equal then zero */
3185 if (isAstEqual (tree->left, tree->right))
3187 tree->type = EX_VALUE;
3188 tree->left = tree->right = NULL;
3189 tree->opval.val = constVal ("0");
3190 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3194 /* if both of them are pointers or arrays then */
3195 /* the result is going to be an integer */
3196 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3197 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3198 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3200 /* if only the left is a pointer */
3201 /* then result is a pointer */
3202 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3203 TETYPE (tree) = getSpec (TTYPE (tree) =
3206 if (!getenv ("SDCC_NEWTYPEFLOW"))
3207 TETYPE (tree) = getSpec (TTYPE (tree) =
3208 computeType (LTYPE (tree),
3213 addCast (&tree->left, resultType, TRUE);
3214 addCast (&tree->right, resultType, TRUE);
3215 TETYPE (tree) = getSpec (TTYPE (tree) =
3216 computeType (LTYPE (tree),
3218 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
3221 LRVAL (tree) = RRVAL (tree) = 1;
3223 /* if right is a literal and */
3224 /* left is also an addition/subtraction with a literal then */
3225 /* rearrange the tree */
3226 if (IS_LITERAL (RTYPE (tree))
3227 /* avoid infinite loop */
3228 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3230 ast *litTree, *litParent;
3231 litTree = searchLitOp (tree, &litParent, "+-");
3234 if (litTree->opval.op == '+')
3237 litTree->right = newNode ('-', litTree->right, tree->right);
3238 litTree->right->lineno = tree->lineno;
3240 tree->right->opval.val = constVal ("0");
3242 else if (litTree->opval.op == '-')
3244 if (IS_LITERAL (RTYPE (litTree)))
3247 litTree->right = newNode ('+', tree->right, litTree->right);
3248 litTree->right->lineno = tree->lineno;
3250 tree->right->opval.val = constVal ("0");
3255 ast *tTree = litTree->right;
3256 litTree->right = tree->right;
3257 tree->right = tTree;
3260 decorateType (litParent, RESULT_CHECK);
3265 /*------------------------------------------------------------------*/
3266 /*----------------------------*/
3268 /*----------------------------*/
3270 /* can be only integral type */
3271 if (!IS_INTEGRAL (LTYPE (tree)))
3273 werror (E_UNARY_OP, tree->opval.op);
3274 goto errorTreeReturn;
3277 /* if left is a literal then do it */
3278 if (IS_LITERAL (LTYPE (tree)))
3280 tree->type = EX_VALUE;
3281 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3283 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3287 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3290 /*------------------------------------------------------------------*/
3291 /*----------------------------*/
3293 /*----------------------------*/
3295 /* can be pointer */
3296 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3297 !IS_PTR (LTYPE (tree)) &&
3298 !IS_ARRAY (LTYPE (tree)))
3300 werror (E_UNARY_OP, tree->opval.op);
3301 goto errorTreeReturn;
3304 /* if left is a literal then do it */
3305 if (IS_LITERAL (LTYPE (tree)))
3307 tree->type = EX_VALUE;
3308 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3310 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3314 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3317 /*------------------------------------------------------------------*/
3318 /*----------------------------*/
3320 /*----------------------------*/
3324 TTYPE (tree) = LTYPE (tree);
3325 TETYPE (tree) = LETYPE (tree);
3329 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3334 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3336 werror (E_SHIFT_OP_INVALID);
3337 werror (W_CONTINUE, "left & right types are ");
3338 printTypeChain (LTYPE (tree), stderr);
3339 fprintf (stderr, ",");
3340 printTypeChain (RTYPE (tree), stderr);
3341 fprintf (stderr, "\n");
3342 goto errorTreeReturn;
3345 /* if they are both literal then */
3346 /* rewrite the tree */
3347 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3349 tree->type = EX_VALUE;
3350 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3351 valFromType (RETYPE (tree)),
3352 (tree->opval.op == LEFT_OP ? 1 : 0));
3353 tree->right = tree->left = NULL;
3354 TETYPE (tree) = getSpec (TTYPE (tree) =
3355 tree->opval.val->type);
3359 LRVAL (tree) = RRVAL (tree) = 1;
3360 if (tree->opval.op == LEFT_OP)
3362 if (!getenv ("SDCC_NEWTYPEFLOW"))
3363 /* promote char to int */
3364 TETYPE (tree) = getSpec (TTYPE (tree) =
3365 computeType (LTYPE (tree),
3366 LTYPE (tree), /* no, not RTYPE! */
3370 addCast (&tree->left, resultType, TRUE);
3371 TETYPE (tree) = getSpec (TTYPE (tree) =
3372 computeType (LTYPE (tree),
3374 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
3379 /* no promotion necessary */
3380 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3381 if (IS_LITERAL (TTYPE (tree)))
3382 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3385 /* if only the right side is a literal & we are
3386 shifting more than size of the left operand then zero */
3387 if (IS_LITERAL (RTYPE (tree)) &&
3388 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3389 (getSize (TETYPE (tree)) * 8))
3391 if (tree->opval.op==LEFT_OP ||
3392 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3394 lineno=tree->lineno;
3395 werror (W_SHIFT_CHANGED,
3396 (tree->opval.op == LEFT_OP ? "left" : "right"));
3397 tree->type = EX_VALUE;
3398 tree->left = tree->right = NULL;
3399 tree->opval.val = constVal ("0");
3400 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3407 /*------------------------------------------------------------------*/
3408 /*----------------------------*/
3410 /*----------------------------*/
3411 case CAST: /* change the type */
3412 /* cannot cast to an aggregate type */
3413 if (IS_AGGREGATE (LTYPE (tree)))
3415 werror (E_CAST_ILLEGAL);
3416 goto errorTreeReturn;
3419 /* make sure the type is complete and sane */
3420 checkTypeSanity(LETYPE(tree), "(cast)");
3422 /* If code memory is read only, then pointers to code memory */
3423 /* implicitly point to constants -- make this explicit */
3425 sym_link *t = LTYPE(tree);
3426 while (t && t->next)
3428 if (IS_CODEPTR(t) && port->mem.code_ro)
3430 if (IS_SPEC(t->next))
3431 SPEC_CONST (t->next) = 1;
3433 DCL_PTR_CONST (t->next) = 1;
3440 /* if the right is a literal replace the tree */
3441 if (IS_LITERAL (RETYPE (tree))) {
3442 if (!IS_PTR (LTYPE (tree))) {
3443 tree->type = EX_VALUE;
3445 valCastLiteral (LTYPE (tree),
3446 floatFromVal (valFromType (RETYPE (tree))));
3449 TTYPE (tree) = tree->opval.val->type;
3450 tree->values.literalFromCast = 1;
3451 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3452 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3453 sym_link *rest = LTYPE(tree)->next;
3454 werror(W_LITERAL_GENERIC);
3455 TTYPE(tree) = newLink(DECLARATOR);
3456 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3457 TTYPE(tree)->next = rest;
3458 tree->left->opval.lnk = TTYPE(tree);
3461 TTYPE (tree) = LTYPE (tree);
3465 TTYPE (tree) = LTYPE (tree);
3469 #if 0 // this is already checked, now this could be explicit
3470 /* if pointer to struct then check names */
3471 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3472 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3473 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3475 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3476 SPEC_STRUCT(LETYPE(tree))->tag);
3479 if (IS_ADDRESS_OF_OP(tree->right)
3480 && IS_AST_SYM_VALUE (tree->right->left)
3481 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3483 tree->type = EX_VALUE;
3485 valCastLiteral (LTYPE (tree),
3486 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3487 TTYPE (tree) = tree->opval.val->type;
3488 TETYPE (tree) = getSpec (TTYPE (tree));
3491 tree->values.literalFromCast = 1;
3495 /* handle offsetof macro: */
3496 /* #define offsetof(TYPE, MEMBER) \ */
3497 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3498 if (IS_ADDRESS_OF_OP(tree->right)
3499 && IS_AST_OP (tree->right->left)
3500 && tree->right->left->opval.op == PTR_OP
3501 && IS_AST_OP (tree->right->left->left)
3502 && tree->right->left->left->opval.op == CAST
3503 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3505 symbol *element = getStructElement (
3506 SPEC_STRUCT (LETYPE(tree->right->left)),
3507 AST_SYMBOL(tree->right->left->right)
3511 tree->type = EX_VALUE;
3512 tree->opval.val = valCastLiteral (
3515 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3518 TTYPE (tree) = tree->opval.val->type;
3519 TETYPE (tree) = getSpec (TTYPE (tree));
3526 /* if the right is a literal replace the tree */
3527 if (IS_LITERAL (RETYPE (tree))) {
3529 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3530 /* rewrite (type *)litaddr
3532 and define type at litaddr temp
3533 (but only if type's storage class is not generic)
3535 ast *newTree = newNode ('&', NULL, NULL);
3538 TTYPE (newTree) = LTYPE (tree);
3539 TETYPE (newTree) = getSpec(LTYPE (tree));
3541 /* define a global symbol at the casted address*/
3542 sym = newSymbol(genSymName (0), 0);
3543 sym->type = LTYPE (tree)->next;
3545 sym->type = newLink (V_VOID);
3546 sym->etype = getSpec(sym->type);
3547 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3548 sym->lineDef = tree->lineno;
3551 SPEC_STAT (sym->etype) = 1;
3552 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3553 SPEC_ABSA(sym->etype) = 1;
3554 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3557 newTree->left = newAst_VALUE(symbolVal(sym));
3558 newTree->left->lineno = tree->lineno;
3559 LTYPE (newTree) = sym->type;
3560 LETYPE (newTree) = sym->etype;
3561 LLVAL (newTree) = 1;
3562 LRVAL (newTree) = 0;
3563 TLVAL (newTree) = 1;
3567 if (!IS_PTR (LTYPE (tree))) {
3568 tree->type = EX_VALUE;
3570 valCastLiteral (LTYPE (tree),
3571 floatFromVal (valFromType (RTYPE (tree))));
3572 TTYPE (tree) = tree->opval.val->type;
3575 tree->values.literalFromCast = 1;
3576 TETYPE (tree) = getSpec (TTYPE (tree));
3580 TTYPE (tree) = LTYPE (tree);
3584 TETYPE (tree) = getSpec (TTYPE (tree));
3588 /*------------------------------------------------------------------*/
3589 /*----------------------------*/
3590 /* logical &&, || */
3591 /*----------------------------*/
3594 /* each must me arithmetic type or be a pointer */
3595 if (!IS_PTR (LTYPE (tree)) &&
3596 !IS_ARRAY (LTYPE (tree)) &&
3597 !IS_INTEGRAL (LTYPE (tree)))
3599 werror (E_COMPARE_OP);
3600 goto errorTreeReturn;
3603 if (!IS_PTR (RTYPE (tree)) &&
3604 !IS_ARRAY (RTYPE (tree)) &&
3605 !IS_INTEGRAL (RTYPE (tree)))
3607 werror (E_COMPARE_OP);
3608 goto errorTreeReturn;
3610 /* if they are both literal then */
3611 /* rewrite the tree */
3612 if (IS_LITERAL (RTYPE (tree)) &&
3613 IS_LITERAL (LTYPE (tree)))
3615 tree->type = EX_VALUE;
3616 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3617 valFromType (RTYPE (tree)),
3619 tree->right = tree->left = NULL;
3620 TETYPE (tree) = getSpec (TTYPE (tree) =
3621 tree->opval.val->type);
3624 LRVAL (tree) = RRVAL (tree) = 1;
3625 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3628 /*------------------------------------------------------------------*/
3629 /*----------------------------*/
3630 /* comparison operators */
3631 /*----------------------------*/
3639 ast *lt = optimizeCompare (tree);
3645 /* if they are pointers they must be castable */
3646 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3648 if (tree->opval.op==EQ_OP &&
3649 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3650 // we cannot cast a gptr to a !gptr: switch the leaves
3651 struct ast *s=tree->left;
3652 tree->left=tree->right;
3655 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3657 werror (E_COMPARE_OP);
3658 fprintf (stderr, "comparing type ");
3659 printTypeChain (LTYPE (tree), stderr);
3660 fprintf (stderr, "to type ");
3661 printTypeChain (RTYPE (tree), stderr);
3662 fprintf (stderr, "\n");
3663 goto errorTreeReturn;
3666 /* else they should be promotable to one another */
3669 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3670 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3672 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3674 werror (E_COMPARE_OP);
3675 fprintf (stderr, "comparing type ");
3676 printTypeChain (LTYPE (tree), stderr);
3677 fprintf (stderr, "to type ");
3678 printTypeChain (RTYPE (tree), stderr);
3679 fprintf (stderr, "\n");
3680 goto errorTreeReturn;
3683 /* if unsigned value < 0 then always false */
3684 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3685 if (SPEC_USIGN(LETYPE(tree)) &&
3686 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3687 IS_LITERAL(RTYPE(tree)) &&
3688 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3690 if (tree->opval.op == '<')
3694 if (tree->opval.op == '>')
3696 /* if the parent is an ifx, then we could do */
3697 /* return tree->left; */
3698 tree->opval.op = '?';
3699 tree->right = newNode (':',
3700 newAst_VALUE (constVal ("1")),
3701 tree->right); /* val 0 */
3702 tree->right->lineno = tree->lineno;
3703 tree->right->left->lineno = tree->lineno;
3704 decorateType (tree->right, RESULT_CHECK);
3707 /* if they are both literal then */
3708 /* rewrite the tree */
3709 if (IS_LITERAL (RTYPE (tree)) &&
3710 IS_LITERAL (LTYPE (tree)))
3712 tree->type = EX_VALUE;
3713 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3714 valFromType (RETYPE (tree)),
3716 tree->right = tree->left = NULL;
3717 TETYPE (tree) = getSpec (TTYPE (tree) =
3718 tree->opval.val->type);
3721 LRVAL (tree) = RRVAL (tree) = 1;
3722 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3725 /*------------------------------------------------------------------*/
3726 /*----------------------------*/
3728 /*----------------------------*/
3729 case SIZEOF: /* evaluate wihout code generation */
3730 /* change the type to a integer */
3731 tree->type = EX_VALUE;
3732 SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
3733 tree->opval.val = constVal (buffer);
3734 tree->right = tree->left = NULL;
3735 TETYPE (tree) = getSpec (TTYPE (tree) =
3736 tree->opval.val->type);
3739 /*------------------------------------------------------------------*/
3740 /*----------------------------*/
3742 /*----------------------------*/
3744 /* return typeof enum value */
3745 tree->type = EX_VALUE;
3748 if (IS_SPEC(tree->right->ftype)) {
3749 switch (SPEC_NOUN(tree->right->ftype)) {
3751 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3752 else typeofv = TYPEOF_INT;
3755 typeofv = TYPEOF_FLOAT;
3758 typeofv = TYPEOF_CHAR;
3761 typeofv = TYPEOF_VOID;
3764 typeofv = TYPEOF_STRUCT;
3767 typeofv = TYPEOF_BITFIELD;
3770 typeofv = TYPEOF_BIT;
3773 typeofv = TYPEOF_SBIT;
3779 switch (DCL_TYPE(tree->right->ftype)) {
3781 typeofv = TYPEOF_POINTER;
3784 typeofv = TYPEOF_FPOINTER;
3787 typeofv = TYPEOF_CPOINTER;
3790 typeofv = TYPEOF_GPOINTER;
3793 typeofv = TYPEOF_PPOINTER;
3796 typeofv = TYPEOF_IPOINTER;
3799 typeofv = TYPEOF_ARRAY;
3802 typeofv = TYPEOF_FUNCTION;
3808 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3809 tree->opval.val = constVal (buffer);
3810 tree->right = tree->left = NULL;
3811 TETYPE (tree) = getSpec (TTYPE (tree) =
3812 tree->opval.val->type);
3815 /*------------------------------------------------------------------*/
3816 /*----------------------------*/
3817 /* conditional operator '?' */
3818 /*----------------------------*/
3820 /* the type is value of the colon operator (on the right) */
3821 assert (IS_COLON_OP (tree->right));
3822 /* if already known then replace the tree : optimizer will do it
3823 but faster to do it here */
3824 if (IS_LITERAL (LTYPE (tree)))
3826 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
3827 return decorateType (tree->right->left, resultTypeProp);
3829 return decorateType (tree->right->right, resultTypeProp);
3833 tree->right = decorateType (tree->right, resultTypeProp);
3834 TTYPE (tree) = RTYPE (tree);
3835 TETYPE (tree) = getSpec (TTYPE (tree));
3840 /* if they don't match we have a problem */
3841 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3843 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3844 goto errorTreeReturn;
3847 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
3848 TETYPE (tree) = getSpec (TTYPE (tree));
3852 #if 0 // assignment operators are converted by the parser
3853 /*------------------------------------------------------------------*/
3854 /*----------------------------*/
3855 /* assignment operators */
3856 /*----------------------------*/
3859 /* for these it must be both must be integral */
3860 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3861 !IS_ARITHMETIC (RTYPE (tree)))
3863 werror (E_OPS_INTEGRAL);
3864 goto errorTreeReturn;
3867 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3869 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3870 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3874 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3875 goto errorTreeReturn;
3886 /* for these it must be both must be integral */
3887 if (!IS_INTEGRAL (LTYPE (tree)) ||
3888 !IS_INTEGRAL (RTYPE (tree)))
3890 werror (E_OPS_INTEGRAL);
3891 goto errorTreeReturn;
3894 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3896 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3897 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3901 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3902 goto errorTreeReturn;
3908 /*------------------------------------------------------------------*/
3909 /*----------------------------*/
3911 /*----------------------------*/
3913 if (!(IS_PTR (LTYPE (tree)) ||
3914 IS_ARITHMETIC (LTYPE (tree))))
3916 werror (E_PLUS_INVALID, "-=");
3917 goto errorTreeReturn;
3920 if (!(IS_PTR (RTYPE (tree)) ||
3921 IS_ARITHMETIC (RTYPE (tree))))
3923 werror (E_PLUS_INVALID, "-=");
3924 goto errorTreeReturn;
3927 TETYPE (tree) = getSpec (TTYPE (tree) =
3928 computeType (LTYPE (tree),
3932 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3933 werror (E_CODE_WRITE, "-=");
3937 werror (E_LVALUE_REQUIRED, "-=");
3938 goto errorTreeReturn;
3944 /*------------------------------------------------------------------*/
3945 /*----------------------------*/
3947 /*----------------------------*/
3949 /* this is not a unary operation */
3950 /* if both pointers then problem */
3951 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3953 werror (E_PTR_PLUS_PTR);
3954 goto errorTreeReturn;
3957 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3959 werror (E_PLUS_INVALID, "+=");
3960 goto errorTreeReturn;
3963 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3965 werror (E_PLUS_INVALID, "+=");
3966 goto errorTreeReturn;
3969 TETYPE (tree) = getSpec (TTYPE (tree) =
3970 computeType (LTYPE (tree),
3974 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3975 werror (E_CODE_WRITE, "+=");
3979 werror (E_LVALUE_REQUIRED, "+=");
3980 goto errorTreeReturn;
3983 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_CHECK);
3984 tree->opval.op = '=';
3989 /*------------------------------------------------------------------*/
3990 /*----------------------------*/
3991 /* straight assignemnt */
3992 /*----------------------------*/
3994 /* cannot be an aggregate */
3995 if (IS_AGGREGATE (LTYPE (tree)))
3997 werror (E_AGGR_ASSIGN);
3998 goto errorTreeReturn;
4001 /* they should either match or be castable */
4002 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4004 werror (E_TYPE_MISMATCH, "assignment", " ");
4005 printFromToType(RTYPE(tree),LTYPE(tree));
4008 /* if the left side of the tree is of type void
4009 then report error */
4010 if (IS_VOID (LTYPE (tree)))
4012 werror (E_CAST_ZERO);
4013 printFromToType(RTYPE(tree), LTYPE(tree));
4016 TETYPE (tree) = getSpec (TTYPE (tree) =
4020 if (!tree->initMode ) {
4021 if (IS_CONSTANT(LTYPE(tree)))
4022 werror (E_CODE_WRITE, "=");
4026 werror (E_LVALUE_REQUIRED, "=");
4027 goto errorTreeReturn;
4032 /*------------------------------------------------------------------*/
4033 /*----------------------------*/
4034 /* comma operator */
4035 /*----------------------------*/
4037 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4040 /*------------------------------------------------------------------*/
4041 /*----------------------------*/
4043 /*----------------------------*/
4047 if (processParms (tree->left,
4048 FUNC_ARGS(tree->left->ftype),
4049 tree->right, &parmNumber, TRUE)) {
4050 goto errorTreeReturn;
4053 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
4054 !IFFUNC_ISBUILTIN(LTYPE(tree)))
4056 reverseParms (tree->right);
4059 if (IS_CODEPTR(LTYPE(tree))) {
4060 TTYPE(tree) = LTYPE(tree)->next->next;
4062 TTYPE(tree) = LTYPE(tree)->next;
4064 TETYPE (tree) = getSpec (TTYPE (tree));
4067 /*------------------------------------------------------------------*/
4068 /*----------------------------*/
4069 /* return statement */
4070 /*----------------------------*/
4075 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4077 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4078 printFromToType (RTYPE(tree), currFunc->type->next);
4079 goto errorTreeReturn;
4082 if (IS_VOID (currFunc->type->next)
4084 !IS_VOID (RTYPE (tree)))
4086 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4087 goto errorTreeReturn;
4090 /* if there is going to be a casting required then add it */
4091 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4094 decorateType (newNode (CAST,
4095 newAst_LINK (copyLinkChain (currFunc->type->next)),
4105 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4107 werror (W_VOID_FUNC, currFunc->name);
4108 goto errorTreeReturn;
4111 TTYPE (tree) = TETYPE (tree) = NULL;
4114 /*------------------------------------------------------------------*/
4115 /*----------------------------*/
4116 /* switch statement */
4117 /*----------------------------*/
4119 /* the switch value must be an integer */
4120 if (!IS_INTEGRAL (LTYPE (tree)))
4122 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4123 goto errorTreeReturn;
4126 TTYPE (tree) = TETYPE (tree) = NULL;
4129 /*------------------------------------------------------------------*/
4130 /*----------------------------*/
4132 /*----------------------------*/
4134 tree->left = backPatchLabels (tree->left,
4137 TTYPE (tree) = TETYPE (tree) = NULL;
4140 /*------------------------------------------------------------------*/
4141 /*----------------------------*/
4143 /*----------------------------*/
4146 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_CHECK);
4147 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_CHECK);
4148 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_CHECK);
4150 /* if the for loop is reversible then
4151 reverse it otherwise do what we normally
4157 if (isLoopReversible (tree, &sym, &init, &end))
4158 return reverseLoop (tree, sym, init, end);
4160 return decorateType (createFor (AST_FOR (tree, trueLabel),
4161 AST_FOR (tree, continueLabel),
4162 AST_FOR (tree, falseLabel),
4163 AST_FOR (tree, condLabel),
4164 AST_FOR (tree, initExpr),
4165 AST_FOR (tree, condExpr),
4166 AST_FOR (tree, loopExpr),
4167 tree->left), RESULT_CHECK);
4170 TTYPE (tree) = TETYPE (tree) = NULL;
4174 /* some error found this tree will be killed */
4176 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4177 tree->opval.op = NULLOP;
4183 /*-----------------------------------------------------------------*/
4184 /* sizeofOp - processes size of operation */
4185 /*-----------------------------------------------------------------*/
4187 sizeofOp (sym_link * type)
4191 /* make sure the type is complete and sane */
4192 checkTypeSanity(type, "(sizeof)");
4194 /* get the size and convert it to character */
4195 SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
4197 /* now convert into value */
4198 return constVal (buff);
4202 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4203 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4204 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4205 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4206 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4207 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4208 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4210 /*-----------------------------------------------------------------*/
4211 /* backPatchLabels - change and or not operators to flow control */
4212 /*-----------------------------------------------------------------*/
4214 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4220 if (!(IS_ANDORNOT (tree)))
4223 /* if this an and */
4226 static int localLbl = 0;
4229 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4230 localLabel = newSymbol (buffer, NestLevel);
4232 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4234 /* if left is already a IFX then just change the if true label in that */
4235 if (!IS_IFX (tree->left))
4236 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4238 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4239 /* right is a IFX then just join */
4240 if (IS_IFX (tree->right))
4241 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4243 tree->right = createLabel (localLabel, tree->right);
4244 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4246 return newNode (NULLOP, tree->left, tree->right);
4249 /* if this is an or operation */
4252 static int localLbl = 0;
4255 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4256 localLabel = newSymbol (buffer, NestLevel);
4258 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4260 /* if left is already a IFX then just change the if true label in that */
4261 if (!IS_IFX (tree->left))
4262 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4264 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4265 /* right is a IFX then just join */
4266 if (IS_IFX (tree->right))
4267 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4269 tree->right = createLabel (localLabel, tree->right);
4270 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4272 return newNode (NULLOP, tree->left, tree->right);
4278 int wasnot = IS_NOT (tree->left);
4279 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4281 /* if the left is already a IFX */
4282 if (!IS_IFX (tree->left))
4283 tree->left = newNode (IFX, tree->left, NULL);
4287 tree->left->trueLabel = trueLabel;
4288 tree->left->falseLabel = falseLabel;
4292 tree->left->trueLabel = falseLabel;
4293 tree->left->falseLabel = trueLabel;
4300 tree->trueLabel = trueLabel;
4301 tree->falseLabel = falseLabel;
4308 /*-----------------------------------------------------------------*/
4309 /* createBlock - create expression tree for block */
4310 /*-----------------------------------------------------------------*/
4312 createBlock (symbol * decl, ast * body)
4316 /* if the block has nothing */
4320 ex = newNode (BLOCK, NULL, body);
4321 ex->values.sym = decl;
4323 ex->right = ex->right;
4329 /*-----------------------------------------------------------------*/
4330 /* createLabel - creates the expression tree for labels */
4331 /*-----------------------------------------------------------------*/
4333 createLabel (symbol * label, ast * stmnt)
4336 char name[SDCC_NAME_MAX + 1];
4339 /* must create fresh symbol if the symbol name */
4340 /* exists in the symbol table, since there can */
4341 /* be a variable with the same name as the labl */
4342 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4343 (csym->level == label->level))
4344 label = newSymbol (label->name, label->level);
4346 /* change the name before putting it in add _ */
4347 SNPRINTF(name, sizeof(name), "%s", label->name);
4349 /* put the label in the LabelSymbol table */
4350 /* but first check if a label of the same */
4352 if ((csym = findSym (LabelTab, NULL, name)))
4353 werror (E_DUPLICATE_LABEL, label->name);
4355 addSym (LabelTab, label, name, label->level, 0, 0);
4358 label->key = labelKey++;
4359 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4365 /*-----------------------------------------------------------------*/
4366 /* createCase - generates the parsetree for a case statement */
4367 /*-----------------------------------------------------------------*/
4369 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4371 char caseLbl[SDCC_NAME_MAX + 1];
4375 /* if the switch statement does not exist */
4376 /* then case is out of context */
4379 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4383 caseVal = decorateType (resolveSymbols (caseVal), RESULT_CHECK);
4384 /* if not a constant then error */
4385 if (!IS_LITERAL (caseVal->ftype))
4387 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4391 /* if not a integer than error */
4392 if (!IS_INTEGRAL (caseVal->ftype))
4394 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4398 /* find the end of the switch values chain */
4399 if (!(val = swStat->values.switchVals.swVals))
4400 swStat->values.switchVals.swVals = caseVal->opval.val;
4403 /* also order the cases according to value */
4405 int cVal = (int) floatFromVal (caseVal->opval.val);
4406 while (val && (int) floatFromVal (val) < cVal)
4412 /* if we reached the end then */
4415 pval->next = caseVal->opval.val;
4417 else if ((int) floatFromVal (val) == cVal)
4419 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4425 /* we found a value greater than */
4426 /* the current value we must add this */
4427 /* before the value */
4428 caseVal->opval.val->next = val;
4430 /* if this was the first in chain */
4431 if (swStat->values.switchVals.swVals == val)
4432 swStat->values.switchVals.swVals =
4435 pval->next = caseVal->opval.val;
4440 /* create the case label */
4441 SNPRINTF(caseLbl, sizeof(caseLbl),
4443 swStat->values.switchVals.swNum,
4444 (int) floatFromVal (caseVal->opval.val));
4446 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4451 /*-----------------------------------------------------------------*/
4452 /* createDefault - creates the parse tree for the default statement */
4453 /*-----------------------------------------------------------------*/
4455 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4457 char defLbl[SDCC_NAME_MAX + 1];
4459 /* if the switch statement does not exist */
4460 /* then case is out of context */
4463 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4467 if (swStat->values.switchVals.swDefault)
4469 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4474 /* turn on the default flag */
4475 swStat->values.switchVals.swDefault = 1;
4477 /* create the label */
4478 SNPRINTF (defLbl, sizeof(defLbl),
4479 "_default_%d", swStat->values.switchVals.swNum);
4480 return createLabel (newSymbol (defLbl, 0), stmnt);
4483 /*-----------------------------------------------------------------*/
4484 /* createIf - creates the parsetree for the if statement */
4485 /*-----------------------------------------------------------------*/
4487 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4489 static int Lblnum = 0;
4491 symbol *ifTrue, *ifFalse, *ifEnd;
4493 /* if neither exists */
4494 if (!elseBody && !ifBody) {
4495 // if there are no side effects (i++, j() etc)
4496 if (!hasSEFcalls(condAst)) {
4501 /* create the labels */
4502 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4503 ifFalse = newSymbol (buffer, NestLevel);
4504 /* if no else body then end == false */
4509 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4510 ifEnd = newSymbol (buffer, NestLevel);
4513 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4514 ifTrue = newSymbol (buffer, NestLevel);
4518 /* attach the ifTrue label to the top of it body */
4519 ifBody = createLabel (ifTrue, ifBody);
4520 /* attach a goto end to the ifBody if else is present */
4523 ifBody = newNode (NULLOP, ifBody,
4525 newAst_VALUE (symbolVal (ifEnd)),
4527 /* put the elseLabel on the else body */
4528 elseBody = createLabel (ifFalse, elseBody);
4529 /* out the end at the end of the body */
4530 elseBody = newNode (NULLOP,
4532 createLabel (ifEnd, NULL));
4536 ifBody = newNode (NULLOP, ifBody,
4537 createLabel (ifFalse, NULL));
4539 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4540 if (IS_IFX (condAst))
4543 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4545 return newNode (NULLOP, ifTree,
4546 newNode (NULLOP, ifBody, elseBody));
4550 /*-----------------------------------------------------------------*/
4551 /* createDo - creates parse tree for do */
4554 /* _docontinue_n: */
4555 /* condition_expression +-> trueLabel -> _dobody_n */
4557 /* +-> falseLabel-> _dobreak_n */
4559 /*-----------------------------------------------------------------*/
4561 createDo (symbol * trueLabel, symbol * continueLabel,
4562 symbol * falseLabel, ast * condAst, ast * doBody)
4567 /* if the body does not exist then it is simple */
4570 condAst = backPatchLabels (condAst, continueLabel, NULL);
4571 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4572 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4573 doTree->trueLabel = continueLabel;
4574 doTree->falseLabel = NULL;
4578 /* otherwise we have a body */
4579 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4581 /* attach the body label to the top */
4582 doBody = createLabel (trueLabel, doBody);
4583 /* attach the continue label to end of body */
4584 doBody = newNode (NULLOP, doBody,
4585 createLabel (continueLabel, NULL));
4587 /* now put the break label at the end */
4588 if (IS_IFX (condAst))
4591 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4593 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4595 /* putting it together */
4596 return newNode (NULLOP, doBody, doTree);
4599 /*-----------------------------------------------------------------*/
4600 /* createFor - creates parse tree for 'for' statement */
4603 /* condExpr +-> trueLabel -> _forbody_n */
4605 /* +-> falseLabel-> _forbreak_n */
4608 /* _forcontinue_n: */
4610 /* goto _forcond_n ; */
4612 /*-----------------------------------------------------------------*/
4614 createFor (symbol * trueLabel, symbol * continueLabel,
4615 symbol * falseLabel, symbol * condLabel,
4616 ast * initExpr, ast * condExpr, ast * loopExpr,
4621 /* if loopexpression not present then we can generate it */
4622 /* the same way as a while */
4624 return newNode (NULLOP, initExpr,
4625 createWhile (trueLabel, continueLabel,
4626 falseLabel, condExpr, forBody));
4627 /* vanilla for statement */
4628 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4630 if (condExpr && !IS_IFX (condExpr))
4631 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4634 /* attach condition label to condition */
4635 condExpr = createLabel (condLabel, condExpr);
4637 /* attach body label to body */
4638 forBody = createLabel (trueLabel, forBody);
4640 /* attach continue to forLoop expression & attach */
4641 /* goto the forcond @ and of loopExpression */
4642 loopExpr = createLabel (continueLabel,
4646 newAst_VALUE (symbolVal (condLabel)),
4648 /* now start putting them together */
4649 forTree = newNode (NULLOP, initExpr, condExpr);
4650 forTree = newNode (NULLOP, forTree, forBody);
4651 forTree = newNode (NULLOP, forTree, loopExpr);
4652 /* finally add the break label */
4653 forTree = newNode (NULLOP, forTree,
4654 createLabel (falseLabel, NULL));
4658 /*-----------------------------------------------------------------*/
4659 /* createWhile - creates parse tree for while statement */
4660 /* the while statement will be created as follows */
4662 /* _while_continue_n: */
4663 /* condition_expression +-> trueLabel -> _while_boby_n */
4665 /* +-> falseLabel -> _while_break_n */
4666 /* _while_body_n: */
4668 /* goto _while_continue_n */
4669 /* _while_break_n: */
4670 /*-----------------------------------------------------------------*/
4672 createWhile (symbol * trueLabel, symbol * continueLabel,
4673 symbol * falseLabel, ast * condExpr, ast * whileBody)
4677 /* put the continue label */
4678 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4679 condExpr = createLabel (continueLabel, condExpr);
4680 condExpr->lineno = 0;
4682 /* put the body label in front of the body */
4683 whileBody = createLabel (trueLabel, whileBody);
4684 whileBody->lineno = 0;
4685 /* put a jump to continue at the end of the body */
4686 /* and put break label at the end of the body */
4687 whileBody = newNode (NULLOP,
4690 newAst_VALUE (symbolVal (continueLabel)),
4691 createLabel (falseLabel, NULL)));
4693 /* put it all together */
4694 if (IS_IFX (condExpr))
4695 whileTree = condExpr;
4698 whileTree = newNode (IFX, condExpr, NULL);
4699 /* put the true & false labels in place */
4700 whileTree->trueLabel = trueLabel;
4701 whileTree->falseLabel = falseLabel;
4704 return newNode (NULLOP, whileTree, whileBody);
4707 /*-----------------------------------------------------------------*/
4708 /* optimizeGetHbit - get highest order bit of the expression */
4709 /*-----------------------------------------------------------------*/
4711 optimizeGetHbit (ast * tree)
4714 /* if this is not a bit and */
4715 if (!IS_BITAND (tree))
4718 /* will look for tree of the form
4719 ( expr >> ((sizeof expr) -1) ) & 1 */
4720 if (!IS_AST_LIT_VALUE (tree->right))
4723 if (AST_LIT_VALUE (tree->right) != 1)
4726 if (!IS_RIGHT_OP (tree->left))
4729 if (!IS_AST_LIT_VALUE (tree->left->right))
4732 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4733 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4736 /* make sure the port supports GETHBIT */
4737 if (port->hasExtBitOp
4738 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4741 return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_CHECK);
4745 /*-----------------------------------------------------------------*/
4746 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4747 /*-----------------------------------------------------------------*/
4749 optimizeRRCRLC (ast * root)
4751 /* will look for trees of the form
4752 (?expr << 1) | (?expr >> 7) or
4753 (?expr >> 7) | (?expr << 1) will make that
4754 into a RLC : operation ..
4756 (?expr >> 1) | (?expr << 7) or
4757 (?expr << 7) | (?expr >> 1) will make that
4758 into a RRC operation
4759 note : by 7 I mean (number of bits required to hold the
4761 /* if the root operations is not a | operation the not */
4762 if (!IS_BITOR (root))
4765 /* I have to think of a better way to match patterns this sucks */
4766 /* that aside let start looking for the first case : I use a the
4767 negative check a lot to improve the efficiency */
4768 /* (?expr << 1) | (?expr >> 7) */
4769 if (IS_LEFT_OP (root->left) &&
4770 IS_RIGHT_OP (root->right))
4773 if (!SPEC_USIGN (TETYPE (root->left->left)))
4776 if (!IS_AST_LIT_VALUE (root->left->right) ||
4777 !IS_AST_LIT_VALUE (root->right->right))
4780 /* make sure it is the same expression */
4781 if (!isAstEqual (root->left->left,
4785 if (AST_LIT_VALUE (root->left->right) != 1)
4788 if (AST_LIT_VALUE (root->right->right) !=
4789 (getSize (TTYPE (root->left->left)) * 8 - 1))
4792 /* make sure the port supports RLC */
4793 if (port->hasExtBitOp
4794 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4797 /* whew got the first case : create the AST */
4798 return newNode (RLC, root->left->left, NULL);
4802 /* check for second case */
4803 /* (?expr >> 7) | (?expr << 1) */
4804 if (IS_LEFT_OP (root->right) &&
4805 IS_RIGHT_OP (root->left))
4808 if (!SPEC_USIGN (TETYPE (root->left->left)))
4811 if (!IS_AST_LIT_VALUE (root->left->right) ||
4812 !IS_AST_LIT_VALUE (root->right->right))
4815 /* make sure it is the same symbol */
4816 if (!isAstEqual (root->left->left,
4820 if (AST_LIT_VALUE (root->right->right) != 1)
4823 if (AST_LIT_VALUE (root->left->right) !=
4824 (getSize (TTYPE (root->left->left)) * 8 - 1))
4827 /* make sure the port supports RLC */
4828 if (port->hasExtBitOp
4829 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4832 /* whew got the first case : create the AST */
4833 return newNode (RLC, root->left->left, NULL);
4838 /* third case for RRC */
4839 /* (?symbol >> 1) | (?symbol << 7) */
4840 if (IS_LEFT_OP (root->right) &&
4841 IS_RIGHT_OP (root->left))
4844 if (!SPEC_USIGN (TETYPE (root->left->left)))
4847 if (!IS_AST_LIT_VALUE (root->left->right) ||
4848 !IS_AST_LIT_VALUE (root->right->right))
4851 /* make sure it is the same symbol */
4852 if (!isAstEqual (root->left->left,
4856 if (AST_LIT_VALUE (root->left->right) != 1)
4859 if (AST_LIT_VALUE (root->right->right) !=
4860 (getSize (TTYPE (root->left->left)) * 8 - 1))
4863 /* make sure the port supports RRC */
4864 if (port->hasExtBitOp
4865 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4868 /* whew got the first case : create the AST */
4869 return newNode (RRC, root->left->left, NULL);
4873 /* fourth and last case for now */
4874 /* (?symbol << 7) | (?symbol >> 1) */
4875 if (IS_RIGHT_OP (root->right) &&
4876 IS_LEFT_OP (root->left))
4879 if (!SPEC_USIGN (TETYPE (root->left->left)))
4882 if (!IS_AST_LIT_VALUE (root->left->right) ||
4883 !IS_AST_LIT_VALUE (root->right->right))
4886 /* make sure it is the same symbol */
4887 if (!isAstEqual (root->left->left,
4891 if (AST_LIT_VALUE (root->right->right) != 1)
4894 if (AST_LIT_VALUE (root->left->right) !=
4895 (getSize (TTYPE (root->left->left)) * 8 - 1))
4898 /* make sure the port supports RRC */
4899 if (port->hasExtBitOp
4900 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4903 /* whew got the first case : create the AST */
4904 return newNode (RRC, root->left->left, NULL);
4908 /* not found return root */
4912 /*-----------------------------------------------------------------*/
4913 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
4914 /*-----------------------------------------------------------------*/
4916 optimizeSWAP (ast * root)
4918 /* will look for trees of the form
4919 (?expr << 4) | (?expr >> 4) or
4920 (?expr >> 4) | (?expr << 4) will make that
4921 into a SWAP : operation ..
4922 note : by 4 I mean (number of bits required to hold the
4924 /* if the root operations is not a | operation the not */
4925 if (!IS_BITOR (root))
4928 /* (?expr << 4) | (?expr >> 4) */
4929 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
4930 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
4933 if (!SPEC_USIGN (TETYPE (root->left->left)))
4936 if (!IS_AST_LIT_VALUE (root->left->right) ||
4937 !IS_AST_LIT_VALUE (root->right->right))
4940 /* make sure it is the same expression */
4941 if (!isAstEqual (root->left->left,
4945 if (AST_LIT_VALUE (root->left->right) !=
4946 (getSize (TTYPE (root->left->left)) * 4))
4949 if (AST_LIT_VALUE (root->right->right) !=
4950 (getSize (TTYPE (root->left->left)) * 4))
4953 /* make sure the port supports SWAP */
4954 if (port->hasExtBitOp
4955 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
4958 /* found it : create the AST */
4959 return newNode (SWAP, root->left->left, NULL);
4963 /* not found return root */
4967 /*-----------------------------------------------------------------*/
4968 /* optimizeCompare - otimizes compares for bit variables */
4969 /*-----------------------------------------------------------------*/
4971 optimizeCompare (ast * root)
4973 ast *optExpr = NULL;
4976 unsigned int litValue;
4978 /* if nothing then return nothing */
4982 /* if not a compare op then do leaves */
4983 if (!IS_COMPARE_OP (root))
4985 root->left = optimizeCompare (root->left);
4986 root->right = optimizeCompare (root->right);
4990 /* if left & right are the same then depending
4991 of the operation do */
4992 if (isAstEqual (root->left, root->right))
4994 switch (root->opval.op)
4999 optExpr = newAst_VALUE (constVal ("0"));
5004 optExpr = newAst_VALUE (constVal ("1"));
5008 return decorateType (optExpr, RESULT_CHECK);
5011 vleft = (root->left->type == EX_VALUE ?
5012 root->left->opval.val : NULL);
5014 vright = (root->right->type == EX_VALUE ?
5015 root->right->opval.val : NULL);
5017 /* if left is a BITVAR in BITSPACE */
5018 /* and right is a LITERAL then opt- */
5019 /* imize else do nothing */
5020 if (vleft && vright &&
5021 IS_BITVAR (vleft->etype) &&
5022 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5023 IS_LITERAL (vright->etype))
5026 /* if right side > 1 then comparison may never succeed */
5027 if ((litValue = (int) floatFromVal (vright)) > 1)
5029 werror (W_BAD_COMPARE);
5035 switch (root->opval.op)
5037 case '>': /* bit value greater than 1 cannot be */
5038 werror (W_BAD_COMPARE);
5042 case '<': /* bit value < 1 means 0 */
5044 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5047 case LE_OP: /* bit value <= 1 means no check */
5048 optExpr = newAst_VALUE (vright);
5051 case GE_OP: /* bit value >= 1 means only check for = */
5053 optExpr = newAst_VALUE (vleft);
5058 { /* literal is zero */
5059 switch (root->opval.op)
5061 case '<': /* bit value < 0 cannot be */
5062 werror (W_BAD_COMPARE);
5066 case '>': /* bit value > 0 means 1 */
5068 optExpr = newAst_VALUE (vleft);
5071 case LE_OP: /* bit value <= 0 means no check */
5072 case GE_OP: /* bit value >= 0 means no check */
5073 werror (W_BAD_COMPARE);
5077 case EQ_OP: /* bit == 0 means ! of bit */
5078 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5082 return decorateType (resolveSymbols (optExpr), RESULT_CHECK);
5083 } /* end-of-if of BITVAR */
5088 /*-----------------------------------------------------------------*/
5089 /* addSymToBlock : adds the symbol to the first block we find */
5090 /*-----------------------------------------------------------------*/
5092 addSymToBlock (symbol * sym, ast * tree)
5094 /* reached end of tree or a leaf */
5095 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5099 if (IS_AST_OP (tree) &&
5100 tree->opval.op == BLOCK)
5103 symbol *lsym = copySymbol (sym);
5105 lsym->next = AST_VALUES (tree, sym);
5106 AST_VALUES (tree, sym) = lsym;
5110 addSymToBlock (sym, tree->left);
5111 addSymToBlock (sym, tree->right);
5114 /*-----------------------------------------------------------------*/
5115 /* processRegParms - do processing for register parameters */
5116 /*-----------------------------------------------------------------*/
5118 processRegParms (value * args, ast * body)
5122 if (IS_REGPARM (args->etype))
5123 addSymToBlock (args->sym, body);
5128 /*-----------------------------------------------------------------*/
5129 /* resetParmKey - resets the operandkeys for the symbols */
5130 /*-----------------------------------------------------------------*/
5131 DEFSETFUNC (resetParmKey)
5142 /*-----------------------------------------------------------------*/
5143 /* createFunction - This is the key node that calls the iCode for */
5144 /* generating the code for a function. Note code */
5145 /* is generated function by function, later when */
5146 /* add inter-procedural analysis this will change */
5147 /*-----------------------------------------------------------------*/
5149 createFunction (symbol * name, ast * body)
5155 iCode *piCode = NULL;
5157 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5158 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5160 /* if check function return 0 then some problem */
5161 if (checkFunction (name, NULL) == 0)
5164 /* create a dummy block if none exists */
5166 body = newNode (BLOCK, NULL, NULL);
5170 /* check if the function name already in the symbol table */
5171 if ((csym = findSym (SymbolTab, NULL, name->name)))
5174 /* special case for compiler defined functions
5175 we need to add the name to the publics list : this
5176 actually means we are now compiling the compiler
5180 addSet (&publics, name);
5186 allocVariables (name);
5188 name->lastLine = mylineno;
5191 /* set the stack pointer */
5192 /* PENDING: check this for the mcs51 */
5193 stackPtr = -port->stack.direction * port->stack.call_overhead;
5194 if (IFFUNC_ISISR (name->type))
5195 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5196 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5197 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5199 xstackPtr = -port->stack.direction * port->stack.call_overhead;
5201 fetype = getSpec (name->type); /* get the specifier for the function */
5202 /* if this is a reentrant function then */
5203 if (IFFUNC_ISREENT (name->type))
5206 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5208 /* do processing for parameters that are passed in registers */
5209 processRegParms (FUNC_ARGS(name->type), body);
5211 /* set the stack pointer */
5215 /* allocate & autoinit the block variables */
5216 processBlockVars (body, &stack, ALLOCATE);
5218 /* save the stack information */
5219 if (options.useXstack)
5220 name->xstack = SPEC_STAK (fetype) = stack;
5222 name->stack = SPEC_STAK (fetype) = stack;
5224 /* name needs to be mangled */
5225 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5227 body = resolveSymbols (body); /* resolve the symbols */
5228 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5231 ex = newAst_VALUE (symbolVal (name)); /* create name */
5232 ex = newNode (FUNCTION, ex, body);
5233 ex->values.args = FUNC_ARGS(name->type);
5235 if (options.dump_tree) PA(ex);
5238 werror (E_FUNC_NO_CODE, name->name);
5242 /* create the node & generate intermediate code */
5244 codeOutFile = code->oFile;
5245 piCode = iCodeFromAst (ex);
5249 werror (E_FUNC_NO_CODE, name->name);
5253 eBBlockFromiCode (piCode);
5255 /* if there are any statics then do them */
5258 GcurMemmap = statsg;
5259 codeOutFile = statsg->oFile;
5260 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_CHECK)));
5266 /* dealloc the block variables */
5267 processBlockVars (body, &stack, DEALLOCATE);
5268 outputDebugStackSymbols();
5269 /* deallocate paramaters */
5270 deallocParms (FUNC_ARGS(name->type));
5272 if (IFFUNC_ISREENT (name->type))
5275 /* we are done freeup memory & cleanup */
5277 if (port->reset_labelKey) labelKey = 1;
5279 FUNC_HASBODY(name->type) = 1;
5280 addSet (&operKeyReset, name);
5281 applyToSet (operKeyReset, resetParmKey);
5286 cleanUpLevel (LabelTab, 0);
5287 cleanUpBlock (StructTab, 1);
5288 cleanUpBlock (TypedefTab, 1);
5290 xstack->syms = NULL;
5291 istack->syms = NULL;
5296 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5297 /*-----------------------------------------------------------------*/
5298 /* ast_print : prints the ast (for debugging purposes) */
5299 /*-----------------------------------------------------------------*/
5301 void ast_print (ast * tree, FILE *outfile, int indent)
5306 /* can print only decorated trees */
5307 if (!tree->decorated) return;
5309 /* if any child is an error | this one is an error do nothing */
5310 if (tree->isError ||
5311 (tree->left && tree->left->isError) ||
5312 (tree->right && tree->right->isError)) {
5313 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5317 /* print the line */
5318 /* if not block & function */
5319 if (tree->type == EX_OP &&
5320 (tree->opval.op != FUNCTION &&
5321 tree->opval.op != BLOCK &&
5322 tree->opval.op != NULLOP)) {
5325 if (tree->opval.op == FUNCTION) {
5327 value *args=FUNC_ARGS(tree->left->opval.val->type);
5328 fprintf(outfile,"FUNCTION (%s=%p) type (",
5329 tree->left->opval.val->name, tree);
5330 printTypeChain (tree->left->opval.val->type->next,outfile);
5331 fprintf(outfile,") args (");
5334 fprintf (outfile, ", ");
5336 printTypeChain (args ? args->type : NULL, outfile);
5338 args= args ? args->next : NULL;
5340 fprintf(outfile,")\n");
5341 ast_print(tree->left,outfile,indent);
5342 ast_print(tree->right,outfile,indent);
5345 if (tree->opval.op == BLOCK) {
5346 symbol *decls = tree->values.sym;
5347 INDENT(indent,outfile);
5348 fprintf(outfile,"{\n");
5350 INDENT(indent+2,outfile);
5351 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5352 decls->name, decls);
5353 printTypeChain(decls->type,outfile);
5354 fprintf(outfile,")\n");
5356 decls = decls->next;
5358 ast_print(tree->right,outfile,indent+2);
5359 INDENT(indent,outfile);
5360 fprintf(outfile,"}\n");
5363 if (tree->opval.op == NULLOP) {
5364 ast_print(tree->left,outfile,indent);
5365 ast_print(tree->right,outfile,indent);
5368 INDENT(indent,outfile);
5370 /*------------------------------------------------------------------*/
5371 /*----------------------------*/
5372 /* leaf has been reached */
5373 /*----------------------------*/
5374 /* if this is of type value */
5375 /* just get the type */
5376 if (tree->type == EX_VALUE) {
5378 if (IS_LITERAL (tree->opval.val->etype)) {
5379 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5380 if (SPEC_USIGN (tree->opval.val->etype))
5381 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5383 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5384 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5385 floatFromVal(tree->opval.val));
5386 } else if (tree->opval.val->sym) {
5387 /* if the undefined flag is set then give error message */
5388 if (tree->opval.val->sym->undefined) {
5389 fprintf(outfile,"UNDEFINED SYMBOL ");
5391 fprintf(outfile,"SYMBOL ");
5393 fprintf(outfile,"(%s=%p)",
5394 tree->opval.val->sym->name,tree);
5397 fprintf(outfile," type (");
5398 printTypeChain(tree->ftype,outfile);
5399 fprintf(outfile,")\n");
5401 fprintf(outfile,"\n");
5406 /* if type link for the case of cast */
5407 if (tree->type == EX_LINK) {
5408 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5409 printTypeChain(tree->opval.lnk,outfile);
5410 fprintf(outfile,")\n");
5415 /* depending on type of operator do */
5417 switch (tree->opval.op) {
5418 /*------------------------------------------------------------------*/
5419 /*----------------------------*/
5421 /*----------------------------*/
5423 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5424 printTypeChain(tree->ftype,outfile);
5425 fprintf(outfile,")\n");
5426 ast_print(tree->left,outfile,indent+2);
5427 ast_print(tree->right,outfile,indent+2);
5430 /*------------------------------------------------------------------*/
5431 /*----------------------------*/
5433 /*----------------------------*/
5435 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5436 printTypeChain(tree->ftype,outfile);
5437 fprintf(outfile,")\n");
5438 ast_print(tree->left,outfile,indent+2);
5439 ast_print(tree->right,outfile,indent+2);
5442 /*------------------------------------------------------------------*/
5443 /*----------------------------*/
5444 /* struct/union pointer */
5445 /*----------------------------*/
5447 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5448 printTypeChain(tree->ftype,outfile);
5449 fprintf(outfile,")\n");
5450 ast_print(tree->left,outfile,indent+2);
5451 ast_print(tree->right,outfile,indent+2);
5454 /*------------------------------------------------------------------*/
5455 /*----------------------------*/
5456 /* ++/-- operation */
5457 /*----------------------------*/
5460 fprintf(outfile,"post-");
5462 fprintf(outfile,"pre-");
5463 fprintf(outfile,"INC_OP (%p) type (",tree);
5464 printTypeChain(tree->ftype,outfile);
5465 fprintf(outfile,")\n");
5466 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5467 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5472 fprintf(outfile,"post-");
5474 fprintf(outfile,"pre-");
5475 fprintf(outfile,"DEC_OP (%p) type (",tree);
5476 printTypeChain(tree->ftype,outfile);
5477 fprintf(outfile,")\n");
5478 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5479 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5482 /*------------------------------------------------------------------*/
5483 /*----------------------------*/
5485 /*----------------------------*/
5488 fprintf(outfile,"& (%p) type (",tree);
5489 printTypeChain(tree->ftype,outfile);
5490 fprintf(outfile,")\n");
5491 ast_print(tree->left,outfile,indent+2);
5492 ast_print(tree->right,outfile,indent+2);
5494 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5495 printTypeChain(tree->ftype,outfile);
5496 fprintf(outfile,")\n");
5497 ast_print(tree->left,outfile,indent+2);
5498 ast_print(tree->right,outfile,indent+2);
5501 /*----------------------------*/
5503 /*----------------------------*/
5505 fprintf(outfile,"OR (%p) type (",tree);
5506 printTypeChain(tree->ftype,outfile);
5507 fprintf(outfile,")\n");
5508 ast_print(tree->left,outfile,indent+2);
5509 ast_print(tree->right,outfile,indent+2);
5511 /*------------------------------------------------------------------*/
5512 /*----------------------------*/
5514 /*----------------------------*/
5516 fprintf(outfile,"XOR (%p) type (",tree);
5517 printTypeChain(tree->ftype,outfile);
5518 fprintf(outfile,")\n");
5519 ast_print(tree->left,outfile,indent+2);
5520 ast_print(tree->right,outfile,indent+2);
5523 /*------------------------------------------------------------------*/
5524 /*----------------------------*/
5526 /*----------------------------*/
5528 fprintf(outfile,"DIV (%p) type (",tree);
5529 printTypeChain(tree->ftype,outfile);
5530 fprintf(outfile,")\n");
5531 ast_print(tree->left,outfile,indent+2);
5532 ast_print(tree->right,outfile,indent+2);
5534 /*------------------------------------------------------------------*/
5535 /*----------------------------*/
5537 /*----------------------------*/
5539 fprintf(outfile,"MOD (%p) type (",tree);
5540 printTypeChain(tree->ftype,outfile);
5541 fprintf(outfile,")\n");
5542 ast_print(tree->left,outfile,indent+2);
5543 ast_print(tree->right,outfile,indent+2);
5546 /*------------------------------------------------------------------*/
5547 /*----------------------------*/
5548 /* address dereference */
5549 /*----------------------------*/
5550 case '*': /* can be unary : if right is null then unary operation */
5552 fprintf(outfile,"DEREF (%p) type (",tree);
5553 printTypeChain(tree->ftype,outfile);
5554 fprintf(outfile,")\n");
5555 ast_print(tree->left,outfile,indent+2);
5558 /*------------------------------------------------------------------*/
5559 /*----------------------------*/
5560 /* multiplication */
5561 /*----------------------------*/
5562 fprintf(outfile,"MULT (%p) type (",tree);
5563 printTypeChain(tree->ftype,outfile);
5564 fprintf(outfile,")\n");
5565 ast_print(tree->left,outfile,indent+2);
5566 ast_print(tree->right,outfile,indent+2);
5570 /*------------------------------------------------------------------*/
5571 /*----------------------------*/
5572 /* unary '+' operator */
5573 /*----------------------------*/
5577 fprintf(outfile,"UPLUS (%p) type (",tree);
5578 printTypeChain(tree->ftype,outfile);
5579 fprintf(outfile,")\n");
5580 ast_print(tree->left,outfile,indent+2);
5582 /*------------------------------------------------------------------*/
5583 /*----------------------------*/
5585 /*----------------------------*/
5586 fprintf(outfile,"ADD (%p) type (",tree);
5587 printTypeChain(tree->ftype,outfile);
5588 fprintf(outfile,")\n");
5589 ast_print(tree->left,outfile,indent+2);
5590 ast_print(tree->right,outfile,indent+2);
5593 /*------------------------------------------------------------------*/
5594 /*----------------------------*/
5596 /*----------------------------*/
5597 case '-': /* can be unary */
5599 fprintf(outfile,"UMINUS (%p) type (",tree);
5600 printTypeChain(tree->ftype,outfile);
5601 fprintf(outfile,")\n");
5602 ast_print(tree->left,outfile,indent+2);
5604 /*------------------------------------------------------------------*/
5605 /*----------------------------*/
5607 /*----------------------------*/
5608 fprintf(outfile,"SUB (%p) type (",tree);
5609 printTypeChain(tree->ftype,outfile);
5610 fprintf(outfile,")\n");
5611 ast_print(tree->left,outfile,indent+2);
5612 ast_print(tree->right,outfile,indent+2);
5615 /*------------------------------------------------------------------*/
5616 /*----------------------------*/
5618 /*----------------------------*/
5620 fprintf(outfile,"COMPL (%p) type (",tree);
5621 printTypeChain(tree->ftype,outfile);
5622 fprintf(outfile,")\n");
5623 ast_print(tree->left,outfile,indent+2);
5625 /*------------------------------------------------------------------*/
5626 /*----------------------------*/
5628 /*----------------------------*/
5630 fprintf(outfile,"NOT (%p) type (",tree);
5631 printTypeChain(tree->ftype,outfile);
5632 fprintf(outfile,")\n");
5633 ast_print(tree->left,outfile,indent+2);
5635 /*------------------------------------------------------------------*/
5636 /*----------------------------*/
5638 /*----------------------------*/
5640 fprintf(outfile,"RRC (%p) type (",tree);
5641 printTypeChain(tree->ftype,outfile);
5642 fprintf(outfile,")\n");
5643 ast_print(tree->left,outfile,indent+2);
5647 fprintf(outfile,"RLC (%p) type (",tree);
5648 printTypeChain(tree->ftype,outfile);
5649 fprintf(outfile,")\n");
5650 ast_print(tree->left,outfile,indent+2);
5653 fprintf(outfile,"SWAP (%p) type (",tree);
5654 printTypeChain(tree->ftype,outfile);
5655 fprintf(outfile,")\n");
5656 ast_print(tree->left,outfile,indent+2);
5659 fprintf(outfile,"GETHBIT (%p) type (",tree);
5660 printTypeChain(tree->ftype,outfile);
5661 fprintf(outfile,")\n");
5662 ast_print(tree->left,outfile,indent+2);
5665 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5666 printTypeChain(tree->ftype,outfile);
5667 fprintf(outfile,")\n");
5668 ast_print(tree->left,outfile,indent+2);
5669 ast_print(tree->right,outfile,indent+2);
5672 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5673 printTypeChain(tree->ftype,outfile);
5674 fprintf(outfile,")\n");
5675 ast_print(tree->left,outfile,indent+2);
5676 ast_print(tree->right,outfile,indent+2);
5678 /*------------------------------------------------------------------*/
5679 /*----------------------------*/
5681 /*----------------------------*/
5682 case CAST: /* change the type */
5683 fprintf(outfile,"CAST (%p) from type (",tree);
5684 printTypeChain(tree->right->ftype,outfile);
5685 fprintf(outfile,") to type (");
5686 printTypeChain(tree->ftype,outfile);
5687 fprintf(outfile,")\n");
5688 ast_print(tree->right,outfile,indent+2);
5692 fprintf(outfile,"ANDAND (%p) type (",tree);
5693 printTypeChain(tree->ftype,outfile);
5694 fprintf(outfile,")\n");
5695 ast_print(tree->left,outfile,indent+2);
5696 ast_print(tree->right,outfile,indent+2);
5699 fprintf(outfile,"OROR (%p) type (",tree);
5700 printTypeChain(tree->ftype,outfile);
5701 fprintf(outfile,")\n");
5702 ast_print(tree->left,outfile,indent+2);
5703 ast_print(tree->right,outfile,indent+2);
5706 /*------------------------------------------------------------------*/
5707 /*----------------------------*/
5708 /* comparison operators */
5709 /*----------------------------*/
5711 fprintf(outfile,"GT(>) (%p) type (",tree);
5712 printTypeChain(tree->ftype,outfile);
5713 fprintf(outfile,")\n");
5714 ast_print(tree->left,outfile,indent+2);
5715 ast_print(tree->right,outfile,indent+2);
5718 fprintf(outfile,"LT(<) (%p) type (",tree);
5719 printTypeChain(tree->ftype,outfile);
5720 fprintf(outfile,")\n");
5721 ast_print(tree->left,outfile,indent+2);
5722 ast_print(tree->right,outfile,indent+2);
5725 fprintf(outfile,"LE(<=) (%p) type (",tree);
5726 printTypeChain(tree->ftype,outfile);
5727 fprintf(outfile,")\n");
5728 ast_print(tree->left,outfile,indent+2);
5729 ast_print(tree->right,outfile,indent+2);
5732 fprintf(outfile,"GE(>=) (%p) type (",tree);
5733 printTypeChain(tree->ftype,outfile);
5734 fprintf(outfile,")\n");
5735 ast_print(tree->left,outfile,indent+2);
5736 ast_print(tree->right,outfile,indent+2);
5739 fprintf(outfile,"EQ(==) (%p) type (",tree);
5740 printTypeChain(tree->ftype,outfile);
5741 fprintf(outfile,")\n");
5742 ast_print(tree->left,outfile,indent+2);
5743 ast_print(tree->right,outfile,indent+2);
5746 fprintf(outfile,"NE(!=) (%p) type (",tree);
5747 printTypeChain(tree->ftype,outfile);
5748 fprintf(outfile,")\n");
5749 ast_print(tree->left,outfile,indent+2);
5750 ast_print(tree->right,outfile,indent+2);
5751 /*------------------------------------------------------------------*/
5752 /*----------------------------*/
5754 /*----------------------------*/
5755 case SIZEOF: /* evaluate wihout code generation */
5756 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5759 /*------------------------------------------------------------------*/
5760 /*----------------------------*/
5761 /* conditional operator '?' */
5762 /*----------------------------*/
5764 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5765 printTypeChain(tree->ftype,outfile);
5766 fprintf(outfile,")\n");
5767 ast_print(tree->left,outfile,indent+2);
5768 ast_print(tree->right,outfile,indent+2);
5772 fprintf(outfile,"COLON(:) (%p) type (",tree);
5773 printTypeChain(tree->ftype,outfile);
5774 fprintf(outfile,")\n");
5775 ast_print(tree->left,outfile,indent+2);
5776 ast_print(tree->right,outfile,indent+2);
5779 /*------------------------------------------------------------------*/
5780 /*----------------------------*/
5781 /* assignment operators */
5782 /*----------------------------*/
5784 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5785 printTypeChain(tree->ftype,outfile);
5786 fprintf(outfile,")\n");
5787 ast_print(tree->left,outfile,indent+2);
5788 ast_print(tree->right,outfile,indent+2);
5791 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5792 printTypeChain(tree->ftype,outfile);
5793 fprintf(outfile,")\n");
5794 ast_print(tree->left,outfile,indent+2);
5795 ast_print(tree->right,outfile,indent+2);
5798 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5799 printTypeChain(tree->ftype,outfile);
5800 fprintf(outfile,")\n");
5801 ast_print(tree->left,outfile,indent+2);
5802 ast_print(tree->right,outfile,indent+2);
5805 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5806 printTypeChain(tree->ftype,outfile);
5807 fprintf(outfile,")\n");
5808 ast_print(tree->left,outfile,indent+2);
5809 ast_print(tree->right,outfile,indent+2);
5812 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5813 printTypeChain(tree->ftype,outfile);
5814 fprintf(outfile,")\n");
5815 ast_print(tree->left,outfile,indent+2);
5816 ast_print(tree->right,outfile,indent+2);
5819 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5820 printTypeChain(tree->ftype,outfile);
5821 fprintf(outfile,")\n");
5822 ast_print(tree->left,outfile,indent+2);
5823 ast_print(tree->right,outfile,indent+2);
5826 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5827 printTypeChain(tree->ftype,outfile);
5828 fprintf(outfile,")\n");
5829 ast_print(tree->left,outfile,indent+2);
5830 ast_print(tree->right,outfile,indent+2);
5832 /*------------------------------------------------------------------*/
5833 /*----------------------------*/
5835 /*----------------------------*/
5837 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5838 printTypeChain(tree->ftype,outfile);
5839 fprintf(outfile,")\n");
5840 ast_print(tree->left,outfile,indent+2);
5841 ast_print(tree->right,outfile,indent+2);
5843 /*------------------------------------------------------------------*/
5844 /*----------------------------*/
5846 /*----------------------------*/
5848 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5849 printTypeChain(tree->ftype,outfile);
5850 fprintf(outfile,")\n");
5851 ast_print(tree->left,outfile,indent+2);
5852 ast_print(tree->right,outfile,indent+2);
5854 /*------------------------------------------------------------------*/
5855 /*----------------------------*/
5856 /* straight assignemnt */
5857 /*----------------------------*/
5859 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5860 printTypeChain(tree->ftype,outfile);
5861 fprintf(outfile,")\n");
5862 ast_print(tree->left,outfile,indent+2);
5863 ast_print(tree->right,outfile,indent+2);
5865 /*------------------------------------------------------------------*/
5866 /*----------------------------*/
5867 /* comma operator */
5868 /*----------------------------*/
5870 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5871 printTypeChain(tree->ftype,outfile);
5872 fprintf(outfile,")\n");
5873 ast_print(tree->left,outfile,indent+2);
5874 ast_print(tree->right,outfile,indent+2);
5876 /*------------------------------------------------------------------*/
5877 /*----------------------------*/
5879 /*----------------------------*/
5882 fprintf(outfile,"CALL (%p) type (",tree);
5883 printTypeChain(tree->ftype,outfile);
5884 fprintf(outfile,")\n");
5885 ast_print(tree->left,outfile,indent+2);
5886 ast_print(tree->right,outfile,indent+2);
5889 fprintf(outfile,"PARMS\n");
5890 ast_print(tree->left,outfile,indent+2);
5891 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5892 ast_print(tree->right,outfile,indent+2);
5895 /*------------------------------------------------------------------*/
5896 /*----------------------------*/
5897 /* return statement */
5898 /*----------------------------*/
5900 fprintf(outfile,"RETURN (%p) type (",tree);
5902 printTypeChain(tree->right->ftype,outfile);
5904 fprintf(outfile,")\n");
5905 ast_print(tree->right,outfile,indent+2);
5907 /*------------------------------------------------------------------*/
5908 /*----------------------------*/
5909 /* label statement */
5910 /*----------------------------*/
5912 fprintf(outfile,"LABEL (%p)\n",tree);
5913 ast_print(tree->left,outfile,indent+2);
5914 ast_print(tree->right,outfile,indent);
5916 /*------------------------------------------------------------------*/
5917 /*----------------------------*/
5918 /* switch statement */
5919 /*----------------------------*/
5923 fprintf(outfile,"SWITCH (%p) ",tree);
5924 ast_print(tree->left,outfile,0);
5925 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5926 INDENT(indent+2,outfile);
5927 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5928 (int) floatFromVal(val),
5929 tree->values.switchVals.swNum,
5930 (int) floatFromVal(val));
5932 ast_print(tree->right,outfile,indent);
5935 /*------------------------------------------------------------------*/
5936 /*----------------------------*/
5938 /*----------------------------*/
5940 fprintf(outfile,"IF (%p) \n",tree);
5941 ast_print(tree->left,outfile,indent+2);
5942 if (tree->trueLabel) {
5943 INDENT(indent+2,outfile);
5944 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5946 if (tree->falseLabel) {
5947 INDENT(indent+2,outfile);
5948 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5950 ast_print(tree->right,outfile,indent+2);
5952 /*----------------------------*/
5953 /* goto Statement */
5954 /*----------------------------*/
5956 fprintf(outfile,"GOTO (%p) \n",tree);
5957 ast_print(tree->left,outfile,indent+2);
5958 fprintf(outfile,"\n");
5960 /*------------------------------------------------------------------*/
5961 /*----------------------------*/
5963 /*----------------------------*/
5965 fprintf(outfile,"FOR (%p) \n",tree);
5966 if (AST_FOR( tree, initExpr)) {
5967 INDENT(indent+2,outfile);
5968 fprintf(outfile,"INIT EXPR ");
5969 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5971 if (AST_FOR( tree, condExpr)) {
5972 INDENT(indent+2,outfile);
5973 fprintf(outfile,"COND EXPR ");
5974 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5976 if (AST_FOR( tree, loopExpr)) {
5977 INDENT(indent+2,outfile);
5978 fprintf(outfile,"LOOP EXPR ");
5979 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5981 fprintf(outfile,"FOR LOOP BODY \n");
5982 ast_print(tree->left,outfile,indent+2);
5985 fprintf(outfile,"CRITICAL (%p) \n",tree);
5986 ast_print(tree->left,outfile,indent+2);
5994 ast_print(t,stdout,0);
5999 /*-----------------------------------------------------------------*/
6000 /* astErrors : returns non-zero if errors present in tree */
6001 /*-----------------------------------------------------------------*/
6002 int astErrors(ast *t)
6011 if (t->type == EX_VALUE
6012 && t->opval.val->sym
6013 && t->opval.val->sym->undefined)
6016 errors += astErrors(t->left);
6017 errors += astErrors(t->right);