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)
2036 case RESULT_TYPE_CHAR:
2037 if (getSize ((*tree)->etype) <= 1)
2039 newLink = newCharLink();
2041 case RESULT_TYPE_INT:
2043 /* casting from long to int costs additional 4 bytes dram! */
2044 if (getSize ((*tree)->etype) <= INTSIZE)
2046 newLink = newIntLink();
2049 /* warn ("Loosing significant digits"); */
2055 (*tree)->decorated = 0;
2056 *tree = newNode (CAST, newAst_LINK (newLink), *tree);
2057 /* keep unsigned type */
2058 SPEC_USIGN ((*tree)->left->opval.lnk) = IS_UNSIGNED ((*tree)->right->etype) ? 1 : 0;
2059 *tree = decorateType (*tree, resultType);
2062 /*-----------------------------------------------------------------*/
2063 /* resultTypePropagate - decides if resultType can be propagated */
2064 /*-----------------------------------------------------------------*/
2066 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2068 switch (tree->opval.op)
2079 return RESULT_TYPE_NONE;
2083 return RESULT_TYPE_NONE;
2087 /*-----------------------------------------------------------------*/
2088 /* getLeftResultType - gets type from left branch for propagation */
2089 /*-----------------------------------------------------------------*/
2091 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2093 switch (tree->opval.op)
2097 if (IS_PTR (tree->left->ftype))
2098 return RESULT_TYPE_NONE;
2100 return getResultTypeFromType (tree->left->etype);
2102 if (IS_PTR (currFunc->type->next))
2103 return RESULT_TYPE_NONE;
2105 return getResultTypeFromType (currFunc->type->next);
2111 /*--------------------------------------------------------------------*/
2112 /* decorateType - compute type for this tree, also does type checking.*/
2113 /* This is done bottom up, since type has to flow upwards. */
2114 /* resultType flows top-down and forces e.g. char-arithmetik, if the */
2115 /* result is a char and the operand(s) are int's. */
2116 /* It also does constant folding, and parameter checking. */
2117 /*--------------------------------------------------------------------*/
2119 decorateType (ast * tree, RESULT_TYPE resultType)
2123 RESULT_TYPE resultTypeProp;
2128 /* if already has type then do nothing */
2129 if (tree->decorated)
2132 tree->decorated = 1;
2135 /* print the line */
2136 /* if not block & function */
2137 if (tree->type == EX_OP &&
2138 (tree->opval.op != FUNCTION &&
2139 tree->opval.op != BLOCK &&
2140 tree->opval.op != NULLOP))
2142 filename = tree->filename;
2143 lineno = tree->lineno;
2147 /* if any child is an error | this one is an error do nothing */
2148 if (tree->isError ||
2149 (tree->left && tree->left->isError) ||
2150 (tree->right && tree->right->isError))
2153 /*------------------------------------------------------------------*/
2154 /*----------------------------*/
2155 /* leaf has been reached */
2156 /*----------------------------*/
2157 lineno=tree->lineno;
2158 /* if this is of type value */
2159 /* just get the type */
2160 if (tree->type == EX_VALUE)
2163 if (IS_LITERAL (tree->opval.val->etype))
2166 /* if this is a character array then declare it */
2167 if (IS_ARRAY (tree->opval.val->type))
2168 tree->opval.val = stringToSymbol (tree->opval.val);
2170 /* otherwise just copy the type information */
2171 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2175 if (tree->opval.val->sym)
2177 /* if the undefined flag is set then give error message */
2178 if (tree->opval.val->sym->undefined)
2180 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2182 TTYPE (tree) = TETYPE (tree) =
2183 tree->opval.val->type = tree->opval.val->sym->type =
2184 tree->opval.val->etype = tree->opval.val->sym->etype =
2185 copyLinkChain (INTTYPE);
2190 /* if impilicit i.e. struct/union member then no type */
2191 if (tree->opval.val->sym->implicit)
2192 TTYPE (tree) = TETYPE (tree) = NULL;
2197 /* else copy the type */
2198 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2200 /* and mark it as referenced */
2201 tree->opval.val->sym->isref = 1;
2209 /* if type link for the case of cast */
2210 if (tree->type == EX_LINK)
2212 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2220 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2222 if (tree->left && tree->left->type == EX_OPERAND
2223 && (tree->left->opval.op == INC_OP
2224 || tree->left->opval.op == DEC_OP)
2225 && tree->left->left)
2227 tree->left->right = tree->left->left;
2228 tree->left->left = NULL;
2230 if (tree->right && tree->right->type == EX_OPERAND
2231 && (tree->right->opval.op == INC_OP
2232 || tree->right->opval.op == DEC_OP)
2233 && tree->right->left)
2235 tree->right->right = tree->right->left;
2236 tree->right->left = NULL;
2241 /* Before decorating the left branch we've to decide in dependence
2242 upon tree->opval.op, if resultType can be propagated */
2243 if (getenv ("SDCC_NEWTYPEFLOW"))
2244 resultTypeProp = resultTypePropagate (tree, resultType);
2246 resultTypeProp = RESULT_TYPE_NONE; /* provide initialization */
2248 dtl = decorateType (tree->left, resultTypeProp);
2250 /* After decorating the left branch there's type information available
2251 in tree->left->?type. If the op is e.g. '=' we extract the type
2252 information from there and propagate it to the right branch. */
2253 if (getenv ("SDCC_NEWTYPEFLOW"))
2254 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2256 /* delay right side for '?' operator since conditional macro expansions
2257 might rely on this */
2258 dtr = tree->opval.op == '?' ? tree->right :
2259 decorateType (tree->right, resultTypeProp);
2261 /* this is to take care of situations
2262 when the tree gets rewritten */
2263 if (dtl != tree->left)
2265 if (dtr != tree->right)
2267 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2270 if (!getenv ("SDCC_NEWTYPEFLOW"))
2272 if (IS_AST_OP(tree) &&
2273 (tree->opval.op == CAST || tree->opval.op == '=') &&
2274 (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) &&
2275 (getSize(RTYPE(tree)) < (unsigned) INTSIZE)) {
2276 /* this is a cast/assign to a bigger type */
2277 if (IS_AST_OP(tree->right) &&
2278 IS_INTEGRAL(tree->right->ftype) &&
2279 (tree->right->opval.op == LEFT_OP ||
2280 tree->right->opval.op == '*' ||
2281 tree->right->opval.op == '+' ||
2282 tree->right->opval.op == '-') &&
2283 tree->right->right) {
2284 /* we should cast an operand instead of the result */
2285 tree->right->decorated = 0;
2286 tree->right->left = newNode( CAST, newAst_LINK(newIntLink()),
2288 tree->right = decorateType(tree->right, RESULT_CHECK);
2294 /* depending on type of operator do */
2296 switch (tree->opval.op)
2298 /*------------------------------------------------------------------*/
2299 /*----------------------------*/
2301 /*----------------------------*/
2304 /* determine which is the array & which the index */
2305 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2308 ast *tempTree = tree->left;
2309 tree->left = tree->right;
2310 tree->right = tempTree;
2313 /* first check if this is a array or a pointer */
2314 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2316 werror (E_NEED_ARRAY_PTR, "[]");
2317 goto errorTreeReturn;
2320 /* check if the type of the idx */
2321 if (!IS_INTEGRAL (RTYPE (tree)))
2323 werror (E_IDX_NOT_INT);
2324 goto errorTreeReturn;
2327 /* if the left is an rvalue then error */
2330 werror (E_LVALUE_REQUIRED, "array access");
2331 goto errorTreeReturn;
2334 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2337 /*------------------------------------------------------------------*/
2338 /*----------------------------*/
2340 /*----------------------------*/
2342 /* if this is not a structure */
2343 if (!IS_STRUCT (LTYPE (tree)))
2345 werror (E_STRUCT_UNION, ".");
2346 goto errorTreeReturn;
2348 TTYPE (tree) = structElemType (LTYPE (tree),
2349 (tree->right->type == EX_VALUE ?
2350 tree->right->opval.val : NULL));
2351 TETYPE (tree) = getSpec (TTYPE (tree));
2354 /*------------------------------------------------------------------*/
2355 /*----------------------------*/
2356 /* struct/union pointer */
2357 /*----------------------------*/
2359 /* if not pointer to a structure */
2360 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2362 werror (E_PTR_REQD);
2363 goto errorTreeReturn;
2366 if (!IS_STRUCT (LTYPE (tree)->next))
2368 werror (E_STRUCT_UNION, "->");
2369 goto errorTreeReturn;
2372 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2373 (tree->right->type == EX_VALUE ?
2374 tree->right->opval.val : NULL));
2375 TETYPE (tree) = getSpec (TTYPE (tree));
2377 /* adjust the storage class */
2378 switch (DCL_TYPE(tree->left->ftype)) {
2380 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2383 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2386 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2389 SPEC_SCLS (TETYPE (tree)) = 0;
2392 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2395 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2398 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2401 SPEC_SCLS (TETYPE (tree)) = 0;
2408 /* This breaks with extern declarations, bitfields, and perhaps other */
2409 /* cases (gcse). Let's leave this optimization disabled for now and */
2410 /* ponder if there's a safe way to do this. -- EEP */
2412 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2413 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2415 /* If defined struct type at addr var
2416 then rewrite (&struct var)->member
2418 and define membertype at (addr+offsetof(struct var,member)) temp
2421 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2422 AST_SYMBOL(tree->right));
2424 sym = newSymbol(genSymName (0), 0);
2425 sym->type = TTYPE (tree);
2426 sym->etype = getSpec(sym->type);
2427 sym->lineDef = tree->lineno;
2430 SPEC_STAT (sym->etype) = 1;
2431 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2433 SPEC_ABSA(sym->etype) = 1;
2434 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2437 AST_VALUE (tree) = symbolVal(sym);
2440 tree->type = EX_VALUE;
2448 /*------------------------------------------------------------------*/
2449 /*----------------------------*/
2450 /* ++/-- operation */
2451 /*----------------------------*/
2455 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2456 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2457 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2458 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2467 /*------------------------------------------------------------------*/
2468 /*----------------------------*/
2470 /*----------------------------*/
2471 case '&': /* can be unary */
2472 /* if right is NULL then unary operation */
2473 if (tree->right) /* not an unary operation */
2476 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2478 werror (E_BITWISE_OP);
2479 werror (W_CONTINUE, "left & right types are ");
2480 printTypeChain (LTYPE (tree), stderr);
2481 fprintf (stderr, ",");
2482 printTypeChain (RTYPE (tree), stderr);
2483 fprintf (stderr, "\n");
2484 goto errorTreeReturn;
2487 /* if they are both literal */
2488 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2490 tree->type = EX_VALUE;
2491 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2492 valFromType (RETYPE (tree)), '&');
2494 tree->right = tree->left = NULL;
2495 TETYPE (tree) = tree->opval.val->etype;
2496 TTYPE (tree) = tree->opval.val->type;
2500 /* see if this is a GETHBIT operation if yes
2503 ast *otree = optimizeGetHbit (tree);
2506 return decorateType (otree, RESULT_CHECK);
2509 if (getenv ("SDCC_NEWTYPEFLOW"))
2511 addCast (&tree->left, resultType);
2512 addCast (&tree->right, resultType);
2514 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
2515 TETYPE (tree) = getSpec (TTYPE (tree));
2517 /* if left is a literal exchange left & right */
2518 if (IS_LITERAL (LTYPE (tree)))
2520 ast *tTree = tree->left;
2521 tree->left = tree->right;
2522 tree->right = tTree;
2525 /* if right is a literal and */
2526 /* we can find a 2nd literal in a and-tree then */
2527 /* rearrange the tree */
2528 if (IS_LITERAL (RTYPE (tree)))
2531 ast *litTree = searchLitOp (tree, &parent, "&");
2534 ast *tTree = litTree->left;
2535 litTree->left = tree->right;
2536 tree->right = tTree;
2537 /* both operands in tTree are literal now */
2538 decorateType (parent, RESULT_CHECK);
2542 LRVAL (tree) = RRVAL (tree) = 1;
2547 /*------------------------------------------------------------------*/
2548 /*----------------------------*/
2550 /*----------------------------*/
2551 p = newLink (DECLARATOR);
2552 /* if bit field then error */
2553 if (IS_BITVAR (tree->left->etype))
2555 werror (E_ILLEGAL_ADDR, "address of bit variable");
2556 goto errorTreeReturn;
2559 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2561 werror (E_ILLEGAL_ADDR, "address of register variable");
2562 goto errorTreeReturn;
2565 if (IS_FUNC (LTYPE (tree)))
2567 // this ought to be ignored
2568 return (tree->left);
2571 if (IS_LITERAL(LTYPE(tree)))
2573 werror (E_ILLEGAL_ADDR, "address of literal");
2574 goto errorTreeReturn;
2579 werror (E_LVALUE_REQUIRED, "address of");
2580 goto errorTreeReturn;
2583 DCL_TYPE (p) = POINTER;
2584 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2585 DCL_TYPE (p) = CPOINTER;
2586 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2587 DCL_TYPE (p) = FPOINTER;
2588 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2589 DCL_TYPE (p) = PPOINTER;
2590 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2591 DCL_TYPE (p) = IPOINTER;
2592 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2593 DCL_TYPE (p) = EEPPOINTER;
2594 else if (SPEC_OCLS(tree->left->etype))
2595 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2597 DCL_TYPE (p) = POINTER;
2599 if (IS_AST_SYM_VALUE (tree->left))
2601 AST_SYMBOL (tree->left)->addrtaken = 1;
2602 AST_SYMBOL (tree->left)->allocreq = 1;
2605 p->next = LTYPE (tree);
2607 TETYPE (tree) = getSpec (TTYPE (tree));
2612 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2613 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2615 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2616 AST_SYMBOL(tree->left->right));
2617 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2618 valueFromLit(element->offset));
2621 tree->type = EX_VALUE;
2622 tree->values.literalFromCast = 1;
2628 /*------------------------------------------------------------------*/
2629 /*----------------------------*/
2631 /*----------------------------*/
2633 /* if the rewrite succeeds then don't go any furthur */
2635 ast *wtree = optimizeRRCRLC (tree);
2637 return decorateType (wtree, RESULT_CHECK);
2639 wtree = optimizeSWAP (tree);
2641 return decorateType (wtree, RESULT_CHECK);
2644 /* if left is a literal exchange left & right */
2645 if (IS_LITERAL (LTYPE (tree)))
2647 ast *tTree = tree->left;
2648 tree->left = tree->right;
2649 tree->right = tTree;
2652 /* if right is a literal and */
2653 /* we can find a 2nd literal in a or-tree then */
2654 /* rearrange the tree */
2655 if (IS_LITERAL (RTYPE (tree)))
2658 ast *litTree = searchLitOp (tree, &parent, "|");
2661 ast *tTree = litTree->left;
2662 litTree->left = tree->right;
2663 tree->right = tTree;
2664 /* both operands in tTree are literal now */
2665 decorateType (parent, RESULT_CHECK);
2670 /*------------------------------------------------------------------*/
2671 /*----------------------------*/
2673 /*----------------------------*/
2675 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2677 werror (E_BITWISE_OP);
2678 werror (W_CONTINUE, "left & right types are ");
2679 printTypeChain (LTYPE (tree), stderr);
2680 fprintf (stderr, ",");
2681 printTypeChain (RTYPE (tree), stderr);
2682 fprintf (stderr, "\n");
2683 goto errorTreeReturn;
2686 /* if they are both literal then */
2687 /* rewrite the tree */
2688 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2690 tree->type = EX_VALUE;
2691 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2692 valFromType (RETYPE (tree)),
2694 tree->right = tree->left = NULL;
2695 TETYPE (tree) = tree->opval.val->etype;
2696 TTYPE (tree) = tree->opval.val->type;
2700 /* if left is a literal exchange left & right */
2701 if (IS_LITERAL (LTYPE (tree)))
2703 ast *tTree = tree->left;
2704 tree->left = tree->right;
2705 tree->right = tTree;
2708 /* if right is a literal and */
2709 /* we can find a 2nd literal in a xor-tree then */
2710 /* rearrange the tree */
2711 if (IS_LITERAL (RTYPE (tree)) &&
2712 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2715 ast *litTree = searchLitOp (tree, &parent, "^");
2718 ast *tTree = litTree->left;
2719 litTree->left = tree->right;
2720 tree->right = tTree;
2721 /* both operands in litTree are literal now */
2722 decorateType (parent, RESULT_CHECK);
2726 LRVAL (tree) = RRVAL (tree) = 1;
2727 if (getenv ("SDCC_NEWTYPEFLOW"))
2729 addCast (&tree->left, resultType);
2730 addCast (&tree->right, resultType);
2732 TETYPE (tree) = getSpec (TTYPE (tree) =
2733 computeType (LTYPE (tree),
2739 /*------------------------------------------------------------------*/
2740 /*----------------------------*/
2742 /*----------------------------*/
2744 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2746 werror (E_INVALID_OP, "divide");
2747 goto errorTreeReturn;
2749 /* if they are both literal then */
2750 /* rewrite the tree */
2751 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2753 tree->type = EX_VALUE;
2754 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2755 valFromType (RETYPE (tree)));
2756 tree->right = tree->left = NULL;
2757 TETYPE (tree) = getSpec (TTYPE (tree) =
2758 tree->opval.val->type);
2762 LRVAL (tree) = RRVAL (tree) = 1;
2763 TETYPE (tree) = getSpec (TTYPE (tree) =
2764 computeType (LTYPE (tree),
2766 ! (IS_UNSIGNED (LTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)))));
2768 /* if right is a literal and */
2769 /* left is also a division by a literal then */
2770 /* rearrange the tree */
2771 if (IS_LITERAL (RTYPE (tree))
2772 /* avoid infinite loop */
2773 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2776 ast *litTree = searchLitOp (tree, &parent, "/");
2779 if (IS_LITERAL (RTYPE (litTree)))
2782 litTree->right = newNode ('*', litTree->right, tree->right);
2783 litTree->right->lineno = tree->lineno;
2785 tree->right->opval.val = constVal ("1");
2786 decorateType (parent, RESULT_CHECK);
2790 /* litTree->left is literal: no gcse possible.
2791 We can't call decorateType(parent, RESULT_CHECK), because
2792 this would cause an infinit loop. */
2793 parent->decorated = 1;
2794 decorateType (litTree, RESULT_CHECK);
2801 /*------------------------------------------------------------------*/
2802 /*----------------------------*/
2804 /*----------------------------*/
2806 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2808 werror (E_BITWISE_OP);
2809 werror (W_CONTINUE, "left & right types are ");
2810 printTypeChain (LTYPE (tree), stderr);
2811 fprintf (stderr, ",");
2812 printTypeChain (RTYPE (tree), stderr);
2813 fprintf (stderr, "\n");
2814 goto errorTreeReturn;
2816 /* if they are both literal then */
2817 /* rewrite the tree */
2818 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2820 tree->type = EX_VALUE;
2821 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2822 valFromType (RETYPE (tree)));
2823 tree->right = tree->left = NULL;
2824 TETYPE (tree) = getSpec (TTYPE (tree) =
2825 tree->opval.val->type);
2828 LRVAL (tree) = RRVAL (tree) = 1;
2829 TETYPE (tree) = getSpec (TTYPE (tree) =
2830 computeType (LTYPE (tree),
2832 ! (IS_UNSIGNED (LTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)))));
2835 /*------------------------------------------------------------------*/
2836 /*----------------------------*/
2837 /* address dereference */
2838 /*----------------------------*/
2839 case '*': /* can be unary : if right is null then unary operation */
2842 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2844 werror (E_PTR_REQD);
2845 goto errorTreeReturn;
2850 werror (E_LVALUE_REQUIRED, "pointer deref");
2851 goto errorTreeReturn;
2853 if (IS_ADDRESS_OF_OP(tree->left))
2855 /* replace *&obj with obj */
2856 return tree->left->left;
2858 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2859 TETYPE (tree) = getSpec (TTYPE (tree));
2860 /* adjust the storage class */
2861 switch (DCL_TYPE(tree->left->ftype)) {
2863 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2866 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2869 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2872 SPEC_SCLS (TETYPE (tree)) = 0;
2875 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2878 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2881 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2884 SPEC_SCLS (TETYPE (tree)) = 0;
2893 /*------------------------------------------------------------------*/
2894 /*----------------------------*/
2895 /* multiplication */
2896 /*----------------------------*/
2897 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2899 werror (E_INVALID_OP, "multiplication");
2900 goto errorTreeReturn;
2903 /* if they are both literal then */
2904 /* rewrite the tree */
2905 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2907 tree->type = EX_VALUE;
2908 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2909 valFromType (RETYPE (tree)));
2910 tree->right = tree->left = NULL;
2911 TETYPE (tree) = getSpec (TTYPE (tree) =
2912 tree->opval.val->type);
2916 /* if left is a literal exchange left & right */
2917 if (IS_LITERAL (LTYPE (tree)))
2919 ast *tTree = tree->left;
2920 tree->left = tree->right;
2921 tree->right = tTree;
2924 /* if right is a literal and */
2925 /* we can find a 2nd literal in a mul-tree then */
2926 /* rearrange the tree */
2927 if (IS_LITERAL (RTYPE (tree)))
2930 ast *litTree = searchLitOp (tree, &parent, "*");
2933 ast *tTree = litTree->left;
2934 litTree->left = tree->right;
2935 tree->right = tTree;
2936 /* both operands in litTree are literal now */
2937 decorateType (parent, RESULT_CHECK);
2941 LRVAL (tree) = RRVAL (tree) = 1;
2942 if (!getenv ("SDCC_NEWTYPEFLOW"))
2943 TETYPE (tree) = getSpec (TTYPE (tree) =
2944 computeType (LTYPE (tree),
2949 addCast (&tree->left, resultType);
2950 addCast (&tree->right, resultType);
2951 TETYPE (tree) = getSpec (TTYPE (tree) =
2952 computeType (LTYPE (tree),
2954 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
2959 /*------------------------------------------------------------------*/
2960 /*----------------------------*/
2961 /* unary '+' operator */
2962 /*----------------------------*/
2967 if (!IS_ARITHMETIC (LTYPE (tree)))
2969 werror (E_UNARY_OP, '+');
2970 goto errorTreeReturn;
2973 /* if left is a literal then do it */
2974 if (IS_LITERAL (LTYPE (tree)))
2976 tree->type = EX_VALUE;
2977 tree->opval.val = valFromType (LETYPE (tree));
2979 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2983 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2987 /*------------------------------------------------------------------*/
2988 /*----------------------------*/
2990 /*----------------------------*/
2992 /* this is not a unary operation */
2993 /* if both pointers then problem */
2994 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2995 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2997 werror (E_PTR_PLUS_PTR);
2998 goto errorTreeReturn;
3001 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3002 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3004 werror (E_PLUS_INVALID, "+");
3005 goto errorTreeReturn;
3008 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3009 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3011 werror (E_PLUS_INVALID, "+");
3012 goto errorTreeReturn;
3014 /* if they are both literal then */
3015 /* rewrite the tree */
3016 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3018 tree->type = EX_VALUE;
3019 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3020 valFromType (RETYPE (tree)));
3021 tree->right = tree->left = NULL;
3022 TETYPE (tree) = getSpec (TTYPE (tree) =
3023 tree->opval.val->type);
3027 /* if the right is a pointer or left is a literal
3028 xchange left & right */
3029 if (IS_ARRAY (RTYPE (tree)) ||
3030 IS_PTR (RTYPE (tree)) ||
3031 IS_LITERAL (LTYPE (tree)))
3033 ast *tTree = tree->left;
3034 tree->left = tree->right;
3035 tree->right = tTree;
3038 /* if right is a literal and */
3039 /* left is also an addition/subtraction with a literal then */
3040 /* rearrange the tree */
3041 if (IS_LITERAL (RTYPE (tree)))
3043 ast *litTree, *parent;
3044 litTree = searchLitOp (tree, &parent, "+-");
3047 if (litTree->opval.op == '+')
3050 ast *tTree = litTree->left;
3051 litTree->left = tree->right;
3052 tree->right = tree->left;
3055 else if (litTree->opval.op == '-')
3057 if (IS_LITERAL (RTYPE (litTree)))
3060 ast *tTree = litTree->left;
3061 litTree->left = tree->right;
3062 tree->right = tTree;
3067 ast *tTree = litTree->right;
3068 litTree->right = tree->right;
3069 tree->right = tTree;
3070 litTree->opval.op = '+';
3071 tree->opval.op = '-';
3074 decorateType (parent, RESULT_CHECK);
3078 LRVAL (tree) = RRVAL (tree) = 1;
3079 /* if the left is a pointer */
3080 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3081 TETYPE (tree) = getSpec (TTYPE (tree) =
3084 if (!getenv ("SDCC_NEWTYPEFLOW"))
3085 TETYPE (tree) = getSpec (TTYPE (tree) =
3086 computeType (LTYPE (tree),
3091 addCast (&tree->left, resultType);
3092 addCast (&tree->right, resultType);
3093 TETYPE (tree) = getSpec (TTYPE (tree) =
3094 computeType (LTYPE (tree),
3096 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
3101 /*------------------------------------------------------------------*/
3102 /*----------------------------*/
3104 /*----------------------------*/
3105 case '-': /* can be unary */
3106 /* if right is null then unary */
3110 if (!IS_ARITHMETIC (LTYPE (tree)))
3112 werror (E_UNARY_OP, tree->opval.op);
3113 goto errorTreeReturn;
3116 /* if left is a literal then do it */
3117 if (IS_LITERAL (LTYPE (tree)))
3119 tree->type = EX_VALUE;
3120 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3122 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3123 SPEC_USIGN(TETYPE(tree)) = 0;
3127 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3131 /*------------------------------------------------------------------*/
3132 /*----------------------------*/
3134 /*----------------------------*/
3136 if (!(IS_PTR (LTYPE (tree)) ||
3137 IS_ARRAY (LTYPE (tree)) ||
3138 IS_ARITHMETIC (LTYPE (tree))))
3140 werror (E_PLUS_INVALID, "-");
3141 goto errorTreeReturn;
3144 if (!(IS_PTR (RTYPE (tree)) ||
3145 IS_ARRAY (RTYPE (tree)) ||
3146 IS_ARITHMETIC (RTYPE (tree))))
3148 werror (E_PLUS_INVALID, "-");
3149 goto errorTreeReturn;
3152 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3153 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3154 IS_INTEGRAL (RTYPE (tree))))
3156 werror (E_PLUS_INVALID, "-");
3157 goto errorTreeReturn;
3160 /* if they are both literal then */
3161 /* rewrite the tree */
3162 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3164 tree->type = EX_VALUE;
3165 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3166 valFromType (RETYPE (tree)));
3167 tree->right = tree->left = NULL;
3168 TETYPE (tree) = getSpec (TTYPE (tree) =
3169 tree->opval.val->type);
3173 /* if the left & right are equal then zero */
3174 if (isAstEqual (tree->left, tree->right))
3176 tree->type = EX_VALUE;
3177 tree->left = tree->right = NULL;
3178 tree->opval.val = constVal ("0");
3179 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3183 /* if both of them are pointers or arrays then */
3184 /* the result is going to be an integer */
3185 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3186 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3187 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3189 /* if only the left is a pointer */
3190 /* then result is a pointer */
3191 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3192 TETYPE (tree) = getSpec (TTYPE (tree) =
3195 if (!getenv ("SDCC_NEWTYPEFLOW"))
3196 TETYPE (tree) = getSpec (TTYPE (tree) =
3197 computeType (LTYPE (tree),
3202 addCast (&tree->left, resultType);
3203 addCast (&tree->right, resultType);
3204 TETYPE (tree) = getSpec (TTYPE (tree) =
3205 computeType (LTYPE (tree),
3207 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
3210 LRVAL (tree) = RRVAL (tree) = 1;
3212 /* if right is a literal and */
3213 /* left is also an addition/subtraction with a literal then */
3214 /* rearrange the tree */
3215 if (IS_LITERAL (RTYPE (tree))
3216 /* avoid infinite loop */
3217 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3219 ast *litTree, *litParent;
3220 litTree = searchLitOp (tree, &litParent, "+-");
3223 if (litTree->opval.op == '+')
3226 litTree->right = newNode ('-', litTree->right, tree->right);
3227 litTree->right->lineno = tree->lineno;
3229 tree->right->opval.val = constVal ("0");
3231 else if (litTree->opval.op == '-')
3233 if (IS_LITERAL (RTYPE (litTree)))
3236 litTree->right = newNode ('+', tree->right, litTree->right);
3237 litTree->right->lineno = tree->lineno;
3239 tree->right->opval.val = constVal ("0");
3244 ast *tTree = litTree->right;
3245 litTree->right = tree->right;
3246 tree->right = tTree;
3249 decorateType (litParent, RESULT_CHECK);
3254 /*------------------------------------------------------------------*/
3255 /*----------------------------*/
3257 /*----------------------------*/
3259 /* can be only integral type */
3260 if (!IS_INTEGRAL (LTYPE (tree)))
3262 werror (E_UNARY_OP, tree->opval.op);
3263 goto errorTreeReturn;
3266 /* if left is a literal then do it */
3267 if (IS_LITERAL (LTYPE (tree)))
3269 tree->type = EX_VALUE;
3270 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3272 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3276 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3279 /*------------------------------------------------------------------*/
3280 /*----------------------------*/
3282 /*----------------------------*/
3284 /* can be pointer */
3285 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3286 !IS_PTR (LTYPE (tree)) &&
3287 !IS_ARRAY (LTYPE (tree)))
3289 werror (E_UNARY_OP, tree->opval.op);
3290 goto errorTreeReturn;
3293 /* if left is a literal then do it */
3294 if (IS_LITERAL (LTYPE (tree)))
3296 tree->type = EX_VALUE;
3297 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3299 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3303 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3306 /*------------------------------------------------------------------*/
3307 /*----------------------------*/
3309 /*----------------------------*/
3313 TTYPE (tree) = LTYPE (tree);
3314 TETYPE (tree) = LETYPE (tree);
3318 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3323 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3325 werror (E_SHIFT_OP_INVALID);
3326 werror (W_CONTINUE, "left & right types are ");
3327 printTypeChain (LTYPE (tree), stderr);
3328 fprintf (stderr, ",");
3329 printTypeChain (RTYPE (tree), stderr);
3330 fprintf (stderr, "\n");
3331 goto errorTreeReturn;
3334 /* if they are both literal then */
3335 /* rewrite the tree */
3336 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3338 tree->type = EX_VALUE;
3339 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3340 valFromType (RETYPE (tree)),
3341 (tree->opval.op == LEFT_OP ? 1 : 0));
3342 tree->right = tree->left = NULL;
3343 TETYPE (tree) = getSpec (TTYPE (tree) =
3344 tree->opval.val->type);
3348 LRVAL (tree) = RRVAL (tree) = 1;
3349 if (tree->opval.op == LEFT_OP)
3351 if (!getenv ("SDCC_NEWTYPEFLOW"))
3352 /* promote char to int */
3353 TETYPE (tree) = getSpec (TTYPE (tree) =
3354 computeType (LTYPE (tree),
3355 LTYPE (tree), /* no, not RTYPE! */
3359 addCast (&tree->left, resultType);
3360 TETYPE (tree) = getSpec (TTYPE (tree) =
3361 computeType (LTYPE (tree),
3363 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
3368 /* no promotion necessary */
3369 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3370 if (IS_LITERAL (TTYPE (tree)))
3371 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3374 /* if only the right side is a literal & we are
3375 shifting more than size of the left operand then zero */
3376 if (IS_LITERAL (RTYPE (tree)) &&
3377 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3378 (getSize (TETYPE (tree)) * 8))
3380 if (tree->opval.op==LEFT_OP ||
3381 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3383 lineno=tree->lineno;
3384 werror (W_SHIFT_CHANGED,
3385 (tree->opval.op == LEFT_OP ? "left" : "right"));
3386 tree->type = EX_VALUE;
3387 tree->left = tree->right = NULL;
3388 tree->opval.val = constVal ("0");
3389 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3396 /*------------------------------------------------------------------*/
3397 /*----------------------------*/
3399 /*----------------------------*/
3400 case CAST: /* change the type */
3401 /* cannot cast to an aggregate type */
3402 if (IS_AGGREGATE (LTYPE (tree)))
3404 werror (E_CAST_ILLEGAL);
3405 goto errorTreeReturn;
3408 /* make sure the type is complete and sane */
3409 checkTypeSanity(LETYPE(tree), "(cast)");
3411 /* If code memory is read only, then pointers to code memory */
3412 /* implicitly point to constants -- make this explicit */
3414 sym_link *t = LTYPE(tree);
3415 while (t && t->next)
3417 if (IS_CODEPTR(t) && port->mem.code_ro)
3419 if (IS_SPEC(t->next))
3420 SPEC_CONST (t->next) = 1;
3422 DCL_PTR_CONST (t->next) = 1;
3429 /* if the right is a literal replace the tree */
3430 if (IS_LITERAL (RETYPE (tree))) {
3431 if (!IS_PTR (LTYPE (tree))) {
3432 tree->type = EX_VALUE;
3434 valCastLiteral (LTYPE (tree),
3435 floatFromVal (valFromType (RETYPE (tree))));
3438 TTYPE (tree) = tree->opval.val->type;
3439 tree->values.literalFromCast = 1;
3440 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3441 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3442 sym_link *rest = LTYPE(tree)->next;
3443 werror(W_LITERAL_GENERIC);
3444 TTYPE(tree) = newLink(DECLARATOR);
3445 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3446 TTYPE(tree)->next = rest;
3447 tree->left->opval.lnk = TTYPE(tree);
3450 TTYPE (tree) = LTYPE (tree);
3454 TTYPE (tree) = LTYPE (tree);
3458 #if 0 // this is already checked, now this could be explicit
3459 /* if pointer to struct then check names */
3460 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3461 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3462 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3464 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3465 SPEC_STRUCT(LETYPE(tree))->tag);
3468 if (IS_ADDRESS_OF_OP(tree->right)
3469 && IS_AST_SYM_VALUE (tree->right->left)
3470 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3472 tree->type = EX_VALUE;
3474 valCastLiteral (LTYPE (tree),
3475 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3476 TTYPE (tree) = tree->opval.val->type;
3477 TETYPE (tree) = getSpec (TTYPE (tree));
3480 tree->values.literalFromCast = 1;
3484 /* handle offsetof macro: */
3485 /* #define offsetof(TYPE, MEMBER) \ */
3486 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3487 if (IS_ADDRESS_OF_OP(tree->right)
3488 && IS_AST_OP (tree->right->left)
3489 && tree->right->left->opval.op == PTR_OP
3490 && IS_AST_OP (tree->right->left->left)
3491 && tree->right->left->left->opval.op == CAST
3492 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3494 symbol *element = getStructElement (
3495 SPEC_STRUCT (LETYPE(tree->right->left)),
3496 AST_SYMBOL(tree->right->left->right)
3500 tree->type = EX_VALUE;
3501 tree->opval.val = valCastLiteral (
3504 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3507 TTYPE (tree) = tree->opval.val->type;
3508 TETYPE (tree) = getSpec (TTYPE (tree));
3515 /* if the right is a literal replace the tree */
3516 if (IS_LITERAL (RETYPE (tree))) {
3518 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3519 /* rewrite (type *)litaddr
3521 and define type at litaddr temp
3522 (but only if type's storage class is not generic)
3524 ast *newTree = newNode ('&', NULL, NULL);
3527 TTYPE (newTree) = LTYPE (tree);
3528 TETYPE (newTree) = getSpec(LTYPE (tree));
3530 /* define a global symbol at the casted address*/
3531 sym = newSymbol(genSymName (0), 0);
3532 sym->type = LTYPE (tree)->next;
3534 sym->type = newLink (V_VOID);
3535 sym->etype = getSpec(sym->type);
3536 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3537 sym->lineDef = tree->lineno;
3540 SPEC_STAT (sym->etype) = 1;
3541 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3542 SPEC_ABSA(sym->etype) = 1;
3543 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3546 newTree->left = newAst_VALUE(symbolVal(sym));
3547 newTree->left->lineno = tree->lineno;
3548 LTYPE (newTree) = sym->type;
3549 LETYPE (newTree) = sym->etype;
3550 LLVAL (newTree) = 1;
3551 LRVAL (newTree) = 0;
3552 TLVAL (newTree) = 1;
3556 if (!IS_PTR (LTYPE (tree))) {
3557 tree->type = EX_VALUE;
3559 valCastLiteral (LTYPE (tree),
3560 floatFromVal (valFromType (RTYPE (tree))));
3561 TTYPE (tree) = tree->opval.val->type;
3564 tree->values.literalFromCast = 1;
3565 TETYPE (tree) = getSpec (TTYPE (tree));
3569 TTYPE (tree) = LTYPE (tree);
3573 TETYPE (tree) = getSpec (TTYPE (tree));
3577 /*------------------------------------------------------------------*/
3578 /*----------------------------*/
3579 /* logical &&, || */
3580 /*----------------------------*/
3583 /* each must me arithmetic type or be a pointer */
3584 if (!IS_PTR (LTYPE (tree)) &&
3585 !IS_ARRAY (LTYPE (tree)) &&
3586 !IS_INTEGRAL (LTYPE (tree)))
3588 werror (E_COMPARE_OP);
3589 goto errorTreeReturn;
3592 if (!IS_PTR (RTYPE (tree)) &&
3593 !IS_ARRAY (RTYPE (tree)) &&
3594 !IS_INTEGRAL (RTYPE (tree)))
3596 werror (E_COMPARE_OP);
3597 goto errorTreeReturn;
3599 /* if they are both literal then */
3600 /* rewrite the tree */
3601 if (IS_LITERAL (RTYPE (tree)) &&
3602 IS_LITERAL (LTYPE (tree)))
3604 tree->type = EX_VALUE;
3605 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3606 valFromType (RTYPE (tree)),
3608 tree->right = tree->left = NULL;
3609 TETYPE (tree) = getSpec (TTYPE (tree) =
3610 tree->opval.val->type);
3613 LRVAL (tree) = RRVAL (tree) = 1;
3614 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3617 /*------------------------------------------------------------------*/
3618 /*----------------------------*/
3619 /* comparison operators */
3620 /*----------------------------*/
3628 ast *lt = optimizeCompare (tree);
3634 /* if they are pointers they must be castable */
3635 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3637 if (tree->opval.op==EQ_OP &&
3638 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3639 // we cannot cast a gptr to a !gptr: switch the leaves
3640 struct ast *s=tree->left;
3641 tree->left=tree->right;
3644 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3646 werror (E_COMPARE_OP);
3647 fprintf (stderr, "comparing type ");
3648 printTypeChain (LTYPE (tree), stderr);
3649 fprintf (stderr, "to type ");
3650 printTypeChain (RTYPE (tree), stderr);
3651 fprintf (stderr, "\n");
3652 goto errorTreeReturn;
3655 /* else they should be promotable to one another */
3658 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3659 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3661 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3663 werror (E_COMPARE_OP);
3664 fprintf (stderr, "comparing type ");
3665 printTypeChain (LTYPE (tree), stderr);
3666 fprintf (stderr, "to type ");
3667 printTypeChain (RTYPE (tree), stderr);
3668 fprintf (stderr, "\n");
3669 goto errorTreeReturn;
3672 /* if unsigned value < 0 then always false */
3673 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3674 if (SPEC_USIGN(LETYPE(tree)) &&
3675 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3676 IS_LITERAL(RTYPE(tree)) &&
3677 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3679 if (tree->opval.op == '<')
3683 if (tree->opval.op == '>')
3685 /* if the parent is an ifx, then we could do */
3686 /* return tree->left; */
3687 tree->opval.op = '?';
3688 tree->right = newNode (':',
3689 newAst_VALUE (constVal ("1")),
3690 tree->right); /* val 0 */
3691 tree->right->lineno = tree->lineno;
3692 tree->right->left->lineno = tree->lineno;
3693 decorateType (tree->right, RESULT_CHECK);
3696 /* if they are both literal then */
3697 /* rewrite the tree */
3698 if (IS_LITERAL (RTYPE (tree)) &&
3699 IS_LITERAL (LTYPE (tree)))
3701 tree->type = EX_VALUE;
3702 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3703 valFromType (RETYPE (tree)),
3705 tree->right = tree->left = NULL;
3706 TETYPE (tree) = getSpec (TTYPE (tree) =
3707 tree->opval.val->type);
3710 LRVAL (tree) = RRVAL (tree) = 1;
3711 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3714 /*------------------------------------------------------------------*/
3715 /*----------------------------*/
3717 /*----------------------------*/
3718 case SIZEOF: /* evaluate wihout code generation */
3719 /* change the type to a integer */
3720 tree->type = EX_VALUE;
3721 SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
3722 tree->opval.val = constVal (buffer);
3723 tree->right = tree->left = NULL;
3724 TETYPE (tree) = getSpec (TTYPE (tree) =
3725 tree->opval.val->type);
3728 /*------------------------------------------------------------------*/
3729 /*----------------------------*/
3731 /*----------------------------*/
3733 /* return typeof enum value */
3734 tree->type = EX_VALUE;
3737 if (IS_SPEC(tree->right->ftype)) {
3738 switch (SPEC_NOUN(tree->right->ftype)) {
3740 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3741 else typeofv = TYPEOF_INT;
3744 typeofv = TYPEOF_FLOAT;
3747 typeofv = TYPEOF_CHAR;
3750 typeofv = TYPEOF_VOID;
3753 typeofv = TYPEOF_STRUCT;
3756 typeofv = TYPEOF_BITFIELD;
3759 typeofv = TYPEOF_BIT;
3762 typeofv = TYPEOF_SBIT;
3768 switch (DCL_TYPE(tree->right->ftype)) {
3770 typeofv = TYPEOF_POINTER;
3773 typeofv = TYPEOF_FPOINTER;
3776 typeofv = TYPEOF_CPOINTER;
3779 typeofv = TYPEOF_GPOINTER;
3782 typeofv = TYPEOF_PPOINTER;
3785 typeofv = TYPEOF_IPOINTER;
3788 typeofv = TYPEOF_ARRAY;
3791 typeofv = TYPEOF_FUNCTION;
3797 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3798 tree->opval.val = constVal (buffer);
3799 tree->right = tree->left = NULL;
3800 TETYPE (tree) = getSpec (TTYPE (tree) =
3801 tree->opval.val->type);
3804 /*------------------------------------------------------------------*/
3805 /*----------------------------*/
3806 /* conditional operator '?' */
3807 /*----------------------------*/
3809 /* the type is value of the colon operator (on the right) */
3810 assert (IS_COLON_OP (tree->right));
3811 /* if already known then replace the tree : optimizer will do it
3812 but faster to do it here */
3813 if (IS_LITERAL (LTYPE (tree)))
3815 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
3816 return decorateType (tree->right->left, resultTypeProp);
3818 return decorateType (tree->right->right, resultTypeProp);
3822 tree->right = decorateType (tree->right, resultTypeProp);
3823 TTYPE (tree) = RTYPE (tree);
3824 TETYPE (tree) = getSpec (TTYPE (tree));
3829 /* if they don't match we have a problem */
3830 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3832 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3833 goto errorTreeReturn;
3836 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
3837 TETYPE (tree) = getSpec (TTYPE (tree));
3841 #if 0 // assignment operators are converted by the parser
3842 /*------------------------------------------------------------------*/
3843 /*----------------------------*/
3844 /* assignment operators */
3845 /*----------------------------*/
3848 /* for these it must be both must be integral */
3849 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3850 !IS_ARITHMETIC (RTYPE (tree)))
3852 werror (E_OPS_INTEGRAL);
3853 goto errorTreeReturn;
3856 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3858 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3859 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3863 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3864 goto errorTreeReturn;
3875 /* for these it must be both must be integral */
3876 if (!IS_INTEGRAL (LTYPE (tree)) ||
3877 !IS_INTEGRAL (RTYPE (tree)))
3879 werror (E_OPS_INTEGRAL);
3880 goto errorTreeReturn;
3883 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3885 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3886 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3890 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3891 goto errorTreeReturn;
3897 /*------------------------------------------------------------------*/
3898 /*----------------------------*/
3900 /*----------------------------*/
3902 if (!(IS_PTR (LTYPE (tree)) ||
3903 IS_ARITHMETIC (LTYPE (tree))))
3905 werror (E_PLUS_INVALID, "-=");
3906 goto errorTreeReturn;
3909 if (!(IS_PTR (RTYPE (tree)) ||
3910 IS_ARITHMETIC (RTYPE (tree))))
3912 werror (E_PLUS_INVALID, "-=");
3913 goto errorTreeReturn;
3916 TETYPE (tree) = getSpec (TTYPE (tree) =
3917 computeType (LTYPE (tree),
3921 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3922 werror (E_CODE_WRITE, "-=");
3926 werror (E_LVALUE_REQUIRED, "-=");
3927 goto errorTreeReturn;
3933 /*------------------------------------------------------------------*/
3934 /*----------------------------*/
3936 /*----------------------------*/
3938 /* this is not a unary operation */
3939 /* if both pointers then problem */
3940 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3942 werror (E_PTR_PLUS_PTR);
3943 goto errorTreeReturn;
3946 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3948 werror (E_PLUS_INVALID, "+=");
3949 goto errorTreeReturn;
3952 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3954 werror (E_PLUS_INVALID, "+=");
3955 goto errorTreeReturn;
3958 TETYPE (tree) = getSpec (TTYPE (tree) =
3959 computeType (LTYPE (tree),
3963 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3964 werror (E_CODE_WRITE, "+=");
3968 werror (E_LVALUE_REQUIRED, "+=");
3969 goto errorTreeReturn;
3972 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_CHECK);
3973 tree->opval.op = '=';
3978 /*------------------------------------------------------------------*/
3979 /*----------------------------*/
3980 /* straight assignemnt */
3981 /*----------------------------*/
3983 /* cannot be an aggregate */
3984 if (IS_AGGREGATE (LTYPE (tree)))
3986 werror (E_AGGR_ASSIGN);
3987 goto errorTreeReturn;
3990 /* they should either match or be castable */
3991 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3993 werror (E_TYPE_MISMATCH, "assignment", " ");
3994 printFromToType(RTYPE(tree),LTYPE(tree));
3997 /* if the left side of the tree is of type void
3998 then report error */
3999 if (IS_VOID (LTYPE (tree)))
4001 werror (E_CAST_ZERO);
4002 printFromToType(RTYPE(tree), LTYPE(tree));
4005 TETYPE (tree) = getSpec (TTYPE (tree) =
4009 if (!tree->initMode ) {
4010 if (IS_CONSTANT(LTYPE(tree)))
4011 werror (E_CODE_WRITE, "=");
4015 werror (E_LVALUE_REQUIRED, "=");
4016 goto errorTreeReturn;
4021 /*------------------------------------------------------------------*/
4022 /*----------------------------*/
4023 /* comma operator */
4024 /*----------------------------*/
4026 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4029 /*------------------------------------------------------------------*/
4030 /*----------------------------*/
4032 /*----------------------------*/
4036 if (processParms (tree->left,
4037 FUNC_ARGS(tree->left->ftype),
4038 tree->right, &parmNumber, TRUE)) {
4039 goto errorTreeReturn;
4042 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
4043 !IFFUNC_ISBUILTIN(LTYPE(tree)))
4045 reverseParms (tree->right);
4048 if (IS_CODEPTR(LTYPE(tree))) {
4049 TTYPE(tree) = LTYPE(tree)->next->next;
4051 TTYPE(tree) = LTYPE(tree)->next;
4053 TETYPE (tree) = getSpec (TTYPE (tree));
4056 /*------------------------------------------------------------------*/
4057 /*----------------------------*/
4058 /* return statement */
4059 /*----------------------------*/
4064 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4066 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4067 printFromToType (RTYPE(tree), currFunc->type->next);
4068 goto errorTreeReturn;
4071 if (IS_VOID (currFunc->type->next)
4073 !IS_VOID (RTYPE (tree)))
4075 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4076 goto errorTreeReturn;
4079 /* if there is going to be a casting required then add it */
4080 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4083 decorateType (newNode (CAST,
4084 newAst_LINK (copyLinkChain (currFunc->type->next)),
4094 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4096 werror (W_VOID_FUNC, currFunc->name);
4097 goto errorTreeReturn;
4100 TTYPE (tree) = TETYPE (tree) = NULL;
4103 /*------------------------------------------------------------------*/
4104 /*----------------------------*/
4105 /* switch statement */
4106 /*----------------------------*/
4108 /* the switch value must be an integer */
4109 if (!IS_INTEGRAL (LTYPE (tree)))
4111 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4112 goto errorTreeReturn;
4115 TTYPE (tree) = TETYPE (tree) = NULL;
4118 /*------------------------------------------------------------------*/
4119 /*----------------------------*/
4121 /*----------------------------*/
4123 tree->left = backPatchLabels (tree->left,
4126 TTYPE (tree) = TETYPE (tree) = NULL;
4129 /*------------------------------------------------------------------*/
4130 /*----------------------------*/
4132 /*----------------------------*/
4135 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_CHECK);
4136 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_CHECK);
4137 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_CHECK);
4139 /* if the for loop is reversible then
4140 reverse it otherwise do what we normally
4146 if (isLoopReversible (tree, &sym, &init, &end))
4147 return reverseLoop (tree, sym, init, end);
4149 return decorateType (createFor (AST_FOR (tree, trueLabel),
4150 AST_FOR (tree, continueLabel),
4151 AST_FOR (tree, falseLabel),
4152 AST_FOR (tree, condLabel),
4153 AST_FOR (tree, initExpr),
4154 AST_FOR (tree, condExpr),
4155 AST_FOR (tree, loopExpr),
4156 tree->left), RESULT_CHECK);
4159 TTYPE (tree) = TETYPE (tree) = NULL;
4163 /* some error found this tree will be killed */
4165 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4166 tree->opval.op = NULLOP;
4172 /*-----------------------------------------------------------------*/
4173 /* sizeofOp - processes size of operation */
4174 /*-----------------------------------------------------------------*/
4176 sizeofOp (sym_link * type)
4180 /* make sure the type is complete and sane */
4181 checkTypeSanity(type, "(sizeof)");
4183 /* get the size and convert it to character */
4184 SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
4186 /* now convert into value */
4187 return constVal (buff);
4191 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4192 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4193 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4194 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4195 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4196 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4197 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4199 /*-----------------------------------------------------------------*/
4200 /* backPatchLabels - change and or not operators to flow control */
4201 /*-----------------------------------------------------------------*/
4203 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4209 if (!(IS_ANDORNOT (tree)))
4212 /* if this an and */
4215 static int localLbl = 0;
4218 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4219 localLabel = newSymbol (buffer, NestLevel);
4221 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4223 /* if left is already a IFX then just change the if true label in that */
4224 if (!IS_IFX (tree->left))
4225 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4227 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4228 /* right is a IFX then just join */
4229 if (IS_IFX (tree->right))
4230 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4232 tree->right = createLabel (localLabel, tree->right);
4233 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4235 return newNode (NULLOP, tree->left, tree->right);
4238 /* if this is an or operation */
4241 static int localLbl = 0;
4244 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4245 localLabel = newSymbol (buffer, NestLevel);
4247 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4249 /* if left is already a IFX then just change the if true label in that */
4250 if (!IS_IFX (tree->left))
4251 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4253 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4254 /* right is a IFX then just join */
4255 if (IS_IFX (tree->right))
4256 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4258 tree->right = createLabel (localLabel, tree->right);
4259 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4261 return newNode (NULLOP, tree->left, tree->right);
4267 int wasnot = IS_NOT (tree->left);
4268 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4270 /* if the left is already a IFX */
4271 if (!IS_IFX (tree->left))
4272 tree->left = newNode (IFX, tree->left, NULL);
4276 tree->left->trueLabel = trueLabel;
4277 tree->left->falseLabel = falseLabel;
4281 tree->left->trueLabel = falseLabel;
4282 tree->left->falseLabel = trueLabel;
4289 tree->trueLabel = trueLabel;
4290 tree->falseLabel = falseLabel;
4297 /*-----------------------------------------------------------------*/
4298 /* createBlock - create expression tree for block */
4299 /*-----------------------------------------------------------------*/
4301 createBlock (symbol * decl, ast * body)
4305 /* if the block has nothing */
4309 ex = newNode (BLOCK, NULL, body);
4310 ex->values.sym = decl;
4312 ex->right = ex->right;
4318 /*-----------------------------------------------------------------*/
4319 /* createLabel - creates the expression tree for labels */
4320 /*-----------------------------------------------------------------*/
4322 createLabel (symbol * label, ast * stmnt)
4325 char name[SDCC_NAME_MAX + 1];
4328 /* must create fresh symbol if the symbol name */
4329 /* exists in the symbol table, since there can */
4330 /* be a variable with the same name as the labl */
4331 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4332 (csym->level == label->level))
4333 label = newSymbol (label->name, label->level);
4335 /* change the name before putting it in add _ */
4336 SNPRINTF(name, sizeof(name), "%s", label->name);
4338 /* put the label in the LabelSymbol table */
4339 /* but first check if a label of the same */
4341 if ((csym = findSym (LabelTab, NULL, name)))
4342 werror (E_DUPLICATE_LABEL, label->name);
4344 addSym (LabelTab, label, name, label->level, 0, 0);
4347 label->key = labelKey++;
4348 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4354 /*-----------------------------------------------------------------*/
4355 /* createCase - generates the parsetree for a case statement */
4356 /*-----------------------------------------------------------------*/
4358 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4360 char caseLbl[SDCC_NAME_MAX + 1];
4364 /* if the switch statement does not exist */
4365 /* then case is out of context */
4368 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4372 caseVal = decorateType (resolveSymbols (caseVal), RESULT_CHECK);
4373 /* if not a constant then error */
4374 if (!IS_LITERAL (caseVal->ftype))
4376 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4380 /* if not a integer than error */
4381 if (!IS_INTEGRAL (caseVal->ftype))
4383 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4387 /* find the end of the switch values chain */
4388 if (!(val = swStat->values.switchVals.swVals))
4389 swStat->values.switchVals.swVals = caseVal->opval.val;
4392 /* also order the cases according to value */
4394 int cVal = (int) floatFromVal (caseVal->opval.val);
4395 while (val && (int) floatFromVal (val) < cVal)
4401 /* if we reached the end then */
4404 pval->next = caseVal->opval.val;
4406 else if ((int) floatFromVal (val) == cVal)
4408 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4414 /* we found a value greater than */
4415 /* the current value we must add this */
4416 /* before the value */
4417 caseVal->opval.val->next = val;
4419 /* if this was the first in chain */
4420 if (swStat->values.switchVals.swVals == val)
4421 swStat->values.switchVals.swVals =
4424 pval->next = caseVal->opval.val;
4429 /* create the case label */
4430 SNPRINTF(caseLbl, sizeof(caseLbl),
4432 swStat->values.switchVals.swNum,
4433 (int) floatFromVal (caseVal->opval.val));
4435 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4440 /*-----------------------------------------------------------------*/
4441 /* createDefault - creates the parse tree for the default statement */
4442 /*-----------------------------------------------------------------*/
4444 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4446 char defLbl[SDCC_NAME_MAX + 1];
4448 /* if the switch statement does not exist */
4449 /* then case is out of context */
4452 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4456 if (swStat->values.switchVals.swDefault)
4458 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4463 /* turn on the default flag */
4464 swStat->values.switchVals.swDefault = 1;
4466 /* create the label */
4467 SNPRINTF (defLbl, sizeof(defLbl),
4468 "_default_%d", swStat->values.switchVals.swNum);
4469 return createLabel (newSymbol (defLbl, 0), stmnt);
4472 /*-----------------------------------------------------------------*/
4473 /* createIf - creates the parsetree for the if statement */
4474 /*-----------------------------------------------------------------*/
4476 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4478 static int Lblnum = 0;
4480 symbol *ifTrue, *ifFalse, *ifEnd;
4482 /* if neither exists */
4483 if (!elseBody && !ifBody) {
4484 // if there are no side effects (i++, j() etc)
4485 if (!hasSEFcalls(condAst)) {
4490 /* create the labels */
4491 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4492 ifFalse = newSymbol (buffer, NestLevel);
4493 /* if no else body then end == false */
4498 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4499 ifEnd = newSymbol (buffer, NestLevel);
4502 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4503 ifTrue = newSymbol (buffer, NestLevel);
4507 /* attach the ifTrue label to the top of it body */
4508 ifBody = createLabel (ifTrue, ifBody);
4509 /* attach a goto end to the ifBody if else is present */
4512 ifBody = newNode (NULLOP, ifBody,
4514 newAst_VALUE (symbolVal (ifEnd)),
4516 /* put the elseLabel on the else body */
4517 elseBody = createLabel (ifFalse, elseBody);
4518 /* out the end at the end of the body */
4519 elseBody = newNode (NULLOP,
4521 createLabel (ifEnd, NULL));
4525 ifBody = newNode (NULLOP, ifBody,
4526 createLabel (ifFalse, NULL));
4528 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4529 if (IS_IFX (condAst))
4532 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4534 return newNode (NULLOP, ifTree,
4535 newNode (NULLOP, ifBody, elseBody));
4539 /*-----------------------------------------------------------------*/
4540 /* createDo - creates parse tree for do */
4543 /* _docontinue_n: */
4544 /* condition_expression +-> trueLabel -> _dobody_n */
4546 /* +-> falseLabel-> _dobreak_n */
4548 /*-----------------------------------------------------------------*/
4550 createDo (symbol * trueLabel, symbol * continueLabel,
4551 symbol * falseLabel, ast * condAst, ast * doBody)
4556 /* if the body does not exist then it is simple */
4559 condAst = backPatchLabels (condAst, continueLabel, NULL);
4560 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4561 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4562 doTree->trueLabel = continueLabel;
4563 doTree->falseLabel = NULL;
4567 /* otherwise we have a body */
4568 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4570 /* attach the body label to the top */
4571 doBody = createLabel (trueLabel, doBody);
4572 /* attach the continue label to end of body */
4573 doBody = newNode (NULLOP, doBody,
4574 createLabel (continueLabel, NULL));
4576 /* now put the break label at the end */
4577 if (IS_IFX (condAst))
4580 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4582 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4584 /* putting it together */
4585 return newNode (NULLOP, doBody, doTree);
4588 /*-----------------------------------------------------------------*/
4589 /* createFor - creates parse tree for 'for' statement */
4592 /* condExpr +-> trueLabel -> _forbody_n */
4594 /* +-> falseLabel-> _forbreak_n */
4597 /* _forcontinue_n: */
4599 /* goto _forcond_n ; */
4601 /*-----------------------------------------------------------------*/
4603 createFor (symbol * trueLabel, symbol * continueLabel,
4604 symbol * falseLabel, symbol * condLabel,
4605 ast * initExpr, ast * condExpr, ast * loopExpr,
4610 /* if loopexpression not present then we can generate it */
4611 /* the same way as a while */
4613 return newNode (NULLOP, initExpr,
4614 createWhile (trueLabel, continueLabel,
4615 falseLabel, condExpr, forBody));
4616 /* vanilla for statement */
4617 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4619 if (condExpr && !IS_IFX (condExpr))
4620 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4623 /* attach condition label to condition */
4624 condExpr = createLabel (condLabel, condExpr);
4626 /* attach body label to body */
4627 forBody = createLabel (trueLabel, forBody);
4629 /* attach continue to forLoop expression & attach */
4630 /* goto the forcond @ and of loopExpression */
4631 loopExpr = createLabel (continueLabel,
4635 newAst_VALUE (symbolVal (condLabel)),
4637 /* now start putting them together */
4638 forTree = newNode (NULLOP, initExpr, condExpr);
4639 forTree = newNode (NULLOP, forTree, forBody);
4640 forTree = newNode (NULLOP, forTree, loopExpr);
4641 /* finally add the break label */
4642 forTree = newNode (NULLOP, forTree,
4643 createLabel (falseLabel, NULL));
4647 /*-----------------------------------------------------------------*/
4648 /* createWhile - creates parse tree for while statement */
4649 /* the while statement will be created as follows */
4651 /* _while_continue_n: */
4652 /* condition_expression +-> trueLabel -> _while_boby_n */
4654 /* +-> falseLabel -> _while_break_n */
4655 /* _while_body_n: */
4657 /* goto _while_continue_n */
4658 /* _while_break_n: */
4659 /*-----------------------------------------------------------------*/
4661 createWhile (symbol * trueLabel, symbol * continueLabel,
4662 symbol * falseLabel, ast * condExpr, ast * whileBody)
4666 /* put the continue label */
4667 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4668 condExpr = createLabel (continueLabel, condExpr);
4669 condExpr->lineno = 0;
4671 /* put the body label in front of the body */
4672 whileBody = createLabel (trueLabel, whileBody);
4673 whileBody->lineno = 0;
4674 /* put a jump to continue at the end of the body */
4675 /* and put break label at the end of the body */
4676 whileBody = newNode (NULLOP,
4679 newAst_VALUE (symbolVal (continueLabel)),
4680 createLabel (falseLabel, NULL)));
4682 /* put it all together */
4683 if (IS_IFX (condExpr))
4684 whileTree = condExpr;
4687 whileTree = newNode (IFX, condExpr, NULL);
4688 /* put the true & false labels in place */
4689 whileTree->trueLabel = trueLabel;
4690 whileTree->falseLabel = falseLabel;
4693 return newNode (NULLOP, whileTree, whileBody);
4696 /*-----------------------------------------------------------------*/
4697 /* optimizeGetHbit - get highest order bit of the expression */
4698 /*-----------------------------------------------------------------*/
4700 optimizeGetHbit (ast * tree)
4703 /* if this is not a bit and */
4704 if (!IS_BITAND (tree))
4707 /* will look for tree of the form
4708 ( expr >> ((sizeof expr) -1) ) & 1 */
4709 if (!IS_AST_LIT_VALUE (tree->right))
4712 if (AST_LIT_VALUE (tree->right) != 1)
4715 if (!IS_RIGHT_OP (tree->left))
4718 if (!IS_AST_LIT_VALUE (tree->left->right))
4721 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4722 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4725 /* make sure the port supports GETHBIT */
4726 if (port->hasExtBitOp
4727 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4730 return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_CHECK);
4734 /*-----------------------------------------------------------------*/
4735 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4736 /*-----------------------------------------------------------------*/
4738 optimizeRRCRLC (ast * root)
4740 /* will look for trees of the form
4741 (?expr << 1) | (?expr >> 7) or
4742 (?expr >> 7) | (?expr << 1) will make that
4743 into a RLC : operation ..
4745 (?expr >> 1) | (?expr << 7) or
4746 (?expr << 7) | (?expr >> 1) will make that
4747 into a RRC operation
4748 note : by 7 I mean (number of bits required to hold the
4750 /* if the root operations is not a | operation the not */
4751 if (!IS_BITOR (root))
4754 /* I have to think of a better way to match patterns this sucks */
4755 /* that aside let start looking for the first case : I use a the
4756 negative check a lot to improve the efficiency */
4757 /* (?expr << 1) | (?expr >> 7) */
4758 if (IS_LEFT_OP (root->left) &&
4759 IS_RIGHT_OP (root->right))
4762 if (!SPEC_USIGN (TETYPE (root->left->left)))
4765 if (!IS_AST_LIT_VALUE (root->left->right) ||
4766 !IS_AST_LIT_VALUE (root->right->right))
4769 /* make sure it is the same expression */
4770 if (!isAstEqual (root->left->left,
4774 if (AST_LIT_VALUE (root->left->right) != 1)
4777 if (AST_LIT_VALUE (root->right->right) !=
4778 (getSize (TTYPE (root->left->left)) * 8 - 1))
4781 /* make sure the port supports RLC */
4782 if (port->hasExtBitOp
4783 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4786 /* whew got the first case : create the AST */
4787 return newNode (RLC, root->left->left, NULL);
4791 /* check for second case */
4792 /* (?expr >> 7) | (?expr << 1) */
4793 if (IS_LEFT_OP (root->right) &&
4794 IS_RIGHT_OP (root->left))
4797 if (!SPEC_USIGN (TETYPE (root->left->left)))
4800 if (!IS_AST_LIT_VALUE (root->left->right) ||
4801 !IS_AST_LIT_VALUE (root->right->right))
4804 /* make sure it is the same symbol */
4805 if (!isAstEqual (root->left->left,
4809 if (AST_LIT_VALUE (root->right->right) != 1)
4812 if (AST_LIT_VALUE (root->left->right) !=
4813 (getSize (TTYPE (root->left->left)) * 8 - 1))
4816 /* make sure the port supports RLC */
4817 if (port->hasExtBitOp
4818 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4821 /* whew got the first case : create the AST */
4822 return newNode (RLC, root->left->left, NULL);
4827 /* third case for RRC */
4828 /* (?symbol >> 1) | (?symbol << 7) */
4829 if (IS_LEFT_OP (root->right) &&
4830 IS_RIGHT_OP (root->left))
4833 if (!SPEC_USIGN (TETYPE (root->left->left)))
4836 if (!IS_AST_LIT_VALUE (root->left->right) ||
4837 !IS_AST_LIT_VALUE (root->right->right))
4840 /* make sure it is the same symbol */
4841 if (!isAstEqual (root->left->left,
4845 if (AST_LIT_VALUE (root->left->right) != 1)
4848 if (AST_LIT_VALUE (root->right->right) !=
4849 (getSize (TTYPE (root->left->left)) * 8 - 1))
4852 /* make sure the port supports RRC */
4853 if (port->hasExtBitOp
4854 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4857 /* whew got the first case : create the AST */
4858 return newNode (RRC, root->left->left, NULL);
4862 /* fourth and last case for now */
4863 /* (?symbol << 7) | (?symbol >> 1) */
4864 if (IS_RIGHT_OP (root->right) &&
4865 IS_LEFT_OP (root->left))
4868 if (!SPEC_USIGN (TETYPE (root->left->left)))
4871 if (!IS_AST_LIT_VALUE (root->left->right) ||
4872 !IS_AST_LIT_VALUE (root->right->right))
4875 /* make sure it is the same symbol */
4876 if (!isAstEqual (root->left->left,
4880 if (AST_LIT_VALUE (root->right->right) != 1)
4883 if (AST_LIT_VALUE (root->left->right) !=
4884 (getSize (TTYPE (root->left->left)) * 8 - 1))
4887 /* make sure the port supports RRC */
4888 if (port->hasExtBitOp
4889 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4892 /* whew got the first case : create the AST */
4893 return newNode (RRC, root->left->left, NULL);
4897 /* not found return root */
4901 /*-----------------------------------------------------------------*/
4902 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
4903 /*-----------------------------------------------------------------*/
4905 optimizeSWAP (ast * root)
4907 /* will look for trees of the form
4908 (?expr << 4) | (?expr >> 4) or
4909 (?expr >> 4) | (?expr << 4) will make that
4910 into a SWAP : operation ..
4911 note : by 4 I mean (number of bits required to hold the
4913 /* if the root operations is not a | operation the not */
4914 if (!IS_BITOR (root))
4917 /* (?expr << 4) | (?expr >> 4) */
4918 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
4919 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
4922 if (!SPEC_USIGN (TETYPE (root->left->left)))
4925 if (!IS_AST_LIT_VALUE (root->left->right) ||
4926 !IS_AST_LIT_VALUE (root->right->right))
4929 /* make sure it is the same expression */
4930 if (!isAstEqual (root->left->left,
4934 if (AST_LIT_VALUE (root->left->right) !=
4935 (getSize (TTYPE (root->left->left)) * 4))
4938 if (AST_LIT_VALUE (root->right->right) !=
4939 (getSize (TTYPE (root->left->left)) * 4))
4942 /* make sure the port supports SWAP */
4943 if (port->hasExtBitOp
4944 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
4947 /* found it : create the AST */
4948 return newNode (SWAP, root->left->left, NULL);
4952 /* not found return root */
4956 /*-----------------------------------------------------------------*/
4957 /* optimizeCompare - otimizes compares for bit variables */
4958 /*-----------------------------------------------------------------*/
4960 optimizeCompare (ast * root)
4962 ast *optExpr = NULL;
4965 unsigned int litValue;
4967 /* if nothing then return nothing */
4971 /* if not a compare op then do leaves */
4972 if (!IS_COMPARE_OP (root))
4974 root->left = optimizeCompare (root->left);
4975 root->right = optimizeCompare (root->right);
4979 /* if left & right are the same then depending
4980 of the operation do */
4981 if (isAstEqual (root->left, root->right))
4983 switch (root->opval.op)
4988 optExpr = newAst_VALUE (constVal ("0"));
4993 optExpr = newAst_VALUE (constVal ("1"));
4997 return decorateType (optExpr, RESULT_CHECK);
5000 vleft = (root->left->type == EX_VALUE ?
5001 root->left->opval.val : NULL);
5003 vright = (root->right->type == EX_VALUE ?
5004 root->right->opval.val : NULL);
5006 /* if left is a BITVAR in BITSPACE */
5007 /* and right is a LITERAL then opt- */
5008 /* imize else do nothing */
5009 if (vleft && vright &&
5010 IS_BITVAR (vleft->etype) &&
5011 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5012 IS_LITERAL (vright->etype))
5015 /* if right side > 1 then comparison may never succeed */
5016 if ((litValue = (int) floatFromVal (vright)) > 1)
5018 werror (W_BAD_COMPARE);
5024 switch (root->opval.op)
5026 case '>': /* bit value greater than 1 cannot be */
5027 werror (W_BAD_COMPARE);
5031 case '<': /* bit value < 1 means 0 */
5033 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5036 case LE_OP: /* bit value <= 1 means no check */
5037 optExpr = newAst_VALUE (vright);
5040 case GE_OP: /* bit value >= 1 means only check for = */
5042 optExpr = newAst_VALUE (vleft);
5047 { /* literal is zero */
5048 switch (root->opval.op)
5050 case '<': /* bit value < 0 cannot be */
5051 werror (W_BAD_COMPARE);
5055 case '>': /* bit value > 0 means 1 */
5057 optExpr = newAst_VALUE (vleft);
5060 case LE_OP: /* bit value <= 0 means no check */
5061 case GE_OP: /* bit value >= 0 means no check */
5062 werror (W_BAD_COMPARE);
5066 case EQ_OP: /* bit == 0 means ! of bit */
5067 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5071 return decorateType (resolveSymbols (optExpr), RESULT_CHECK);
5072 } /* end-of-if of BITVAR */
5077 /*-----------------------------------------------------------------*/
5078 /* addSymToBlock : adds the symbol to the first block we find */
5079 /*-----------------------------------------------------------------*/
5081 addSymToBlock (symbol * sym, ast * tree)
5083 /* reached end of tree or a leaf */
5084 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5088 if (IS_AST_OP (tree) &&
5089 tree->opval.op == BLOCK)
5092 symbol *lsym = copySymbol (sym);
5094 lsym->next = AST_VALUES (tree, sym);
5095 AST_VALUES (tree, sym) = lsym;
5099 addSymToBlock (sym, tree->left);
5100 addSymToBlock (sym, tree->right);
5103 /*-----------------------------------------------------------------*/
5104 /* processRegParms - do processing for register parameters */
5105 /*-----------------------------------------------------------------*/
5107 processRegParms (value * args, ast * body)
5111 if (IS_REGPARM (args->etype))
5112 addSymToBlock (args->sym, body);
5117 /*-----------------------------------------------------------------*/
5118 /* resetParmKey - resets the operandkeys for the symbols */
5119 /*-----------------------------------------------------------------*/
5120 DEFSETFUNC (resetParmKey)
5131 /*-----------------------------------------------------------------*/
5132 /* createFunction - This is the key node that calls the iCode for */
5133 /* generating the code for a function. Note code */
5134 /* is generated function by function, later when */
5135 /* add inter-procedural analysis this will change */
5136 /*-----------------------------------------------------------------*/
5138 createFunction (symbol * name, ast * body)
5144 iCode *piCode = NULL;
5146 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5147 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5149 /* if check function return 0 then some problem */
5150 if (checkFunction (name, NULL) == 0)
5153 /* create a dummy block if none exists */
5155 body = newNode (BLOCK, NULL, NULL);
5159 /* check if the function name already in the symbol table */
5160 if ((csym = findSym (SymbolTab, NULL, name->name)))
5163 /* special case for compiler defined functions
5164 we need to add the name to the publics list : this
5165 actually means we are now compiling the compiler
5169 addSet (&publics, name);
5175 allocVariables (name);
5177 name->lastLine = mylineno;
5180 /* set the stack pointer */
5181 /* PENDING: check this for the mcs51 */
5182 stackPtr = -port->stack.direction * port->stack.call_overhead;
5183 if (IFFUNC_ISISR (name->type))
5184 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5185 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5186 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5188 xstackPtr = -port->stack.direction * port->stack.call_overhead;
5190 fetype = getSpec (name->type); /* get the specifier for the function */
5191 /* if this is a reentrant function then */
5192 if (IFFUNC_ISREENT (name->type))
5195 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5197 /* do processing for parameters that are passed in registers */
5198 processRegParms (FUNC_ARGS(name->type), body);
5200 /* set the stack pointer */
5204 /* allocate & autoinit the block variables */
5205 processBlockVars (body, &stack, ALLOCATE);
5207 /* save the stack information */
5208 if (options.useXstack)
5209 name->xstack = SPEC_STAK (fetype) = stack;
5211 name->stack = SPEC_STAK (fetype) = stack;
5213 /* name needs to be mangled */
5214 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5216 body = resolveSymbols (body); /* resolve the symbols */
5217 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5220 ex = newAst_VALUE (symbolVal (name)); /* create name */
5221 ex = newNode (FUNCTION, ex, body);
5222 ex->values.args = FUNC_ARGS(name->type);
5224 if (options.dump_tree) PA(ex);
5227 werror (E_FUNC_NO_CODE, name->name);
5231 /* create the node & generate intermediate code */
5233 codeOutFile = code->oFile;
5234 piCode = iCodeFromAst (ex);
5238 werror (E_FUNC_NO_CODE, name->name);
5242 eBBlockFromiCode (piCode);
5244 /* if there are any statics then do them */
5247 GcurMemmap = statsg;
5248 codeOutFile = statsg->oFile;
5249 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_CHECK)));
5255 /* dealloc the block variables */
5256 processBlockVars (body, &stack, DEALLOCATE);
5257 outputDebugStackSymbols();
5258 /* deallocate paramaters */
5259 deallocParms (FUNC_ARGS(name->type));
5261 if (IFFUNC_ISREENT (name->type))
5264 /* we are done freeup memory & cleanup */
5266 if (port->reset_labelKey) labelKey = 1;
5268 FUNC_HASBODY(name->type) = 1;
5269 addSet (&operKeyReset, name);
5270 applyToSet (operKeyReset, resetParmKey);
5275 cleanUpLevel (LabelTab, 0);
5276 cleanUpBlock (StructTab, 1);
5277 cleanUpBlock (TypedefTab, 1);
5279 xstack->syms = NULL;
5280 istack->syms = NULL;
5285 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5286 /*-----------------------------------------------------------------*/
5287 /* ast_print : prints the ast (for debugging purposes) */
5288 /*-----------------------------------------------------------------*/
5290 void ast_print (ast * tree, FILE *outfile, int indent)
5295 /* can print only decorated trees */
5296 if (!tree->decorated) return;
5298 /* if any child is an error | this one is an error do nothing */
5299 if (tree->isError ||
5300 (tree->left && tree->left->isError) ||
5301 (tree->right && tree->right->isError)) {
5302 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5306 /* print the line */
5307 /* if not block & function */
5308 if (tree->type == EX_OP &&
5309 (tree->opval.op != FUNCTION &&
5310 tree->opval.op != BLOCK &&
5311 tree->opval.op != NULLOP)) {
5314 if (tree->opval.op == FUNCTION) {
5316 value *args=FUNC_ARGS(tree->left->opval.val->type);
5317 fprintf(outfile,"FUNCTION (%s=%p) type (",
5318 tree->left->opval.val->name, tree);
5319 printTypeChain (tree->left->opval.val->type->next,outfile);
5320 fprintf(outfile,") args (");
5323 fprintf (outfile, ", ");
5325 printTypeChain (args ? args->type : NULL, outfile);
5327 args= args ? args->next : NULL;
5329 fprintf(outfile,")\n");
5330 ast_print(tree->left,outfile,indent);
5331 ast_print(tree->right,outfile,indent);
5334 if (tree->opval.op == BLOCK) {
5335 symbol *decls = tree->values.sym;
5336 INDENT(indent,outfile);
5337 fprintf(outfile,"{\n");
5339 INDENT(indent+2,outfile);
5340 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5341 decls->name, decls);
5342 printTypeChain(decls->type,outfile);
5343 fprintf(outfile,")\n");
5345 decls = decls->next;
5347 ast_print(tree->right,outfile,indent+2);
5348 INDENT(indent,outfile);
5349 fprintf(outfile,"}\n");
5352 if (tree->opval.op == NULLOP) {
5353 ast_print(tree->left,outfile,indent);
5354 ast_print(tree->right,outfile,indent);
5357 INDENT(indent,outfile);
5359 /*------------------------------------------------------------------*/
5360 /*----------------------------*/
5361 /* leaf has been reached */
5362 /*----------------------------*/
5363 /* if this is of type value */
5364 /* just get the type */
5365 if (tree->type == EX_VALUE) {
5367 if (IS_LITERAL (tree->opval.val->etype)) {
5368 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5369 if (SPEC_USIGN (tree->opval.val->etype))
5370 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5372 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5373 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5374 floatFromVal(tree->opval.val));
5375 } else if (tree->opval.val->sym) {
5376 /* if the undefined flag is set then give error message */
5377 if (tree->opval.val->sym->undefined) {
5378 fprintf(outfile,"UNDEFINED SYMBOL ");
5380 fprintf(outfile,"SYMBOL ");
5382 fprintf(outfile,"(%s=%p)",
5383 tree->opval.val->sym->name,tree);
5386 fprintf(outfile," type (");
5387 printTypeChain(tree->ftype,outfile);
5388 fprintf(outfile,")\n");
5390 fprintf(outfile,"\n");
5395 /* if type link for the case of cast */
5396 if (tree->type == EX_LINK) {
5397 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5398 printTypeChain(tree->opval.lnk,outfile);
5399 fprintf(outfile,")\n");
5404 /* depending on type of operator do */
5406 switch (tree->opval.op) {
5407 /*------------------------------------------------------------------*/
5408 /*----------------------------*/
5410 /*----------------------------*/
5412 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5413 printTypeChain(tree->ftype,outfile);
5414 fprintf(outfile,")\n");
5415 ast_print(tree->left,outfile,indent+2);
5416 ast_print(tree->right,outfile,indent+2);
5419 /*------------------------------------------------------------------*/
5420 /*----------------------------*/
5422 /*----------------------------*/
5424 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5425 printTypeChain(tree->ftype,outfile);
5426 fprintf(outfile,")\n");
5427 ast_print(tree->left,outfile,indent+2);
5428 ast_print(tree->right,outfile,indent+2);
5431 /*------------------------------------------------------------------*/
5432 /*----------------------------*/
5433 /* struct/union pointer */
5434 /*----------------------------*/
5436 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5437 printTypeChain(tree->ftype,outfile);
5438 fprintf(outfile,")\n");
5439 ast_print(tree->left,outfile,indent+2);
5440 ast_print(tree->right,outfile,indent+2);
5443 /*------------------------------------------------------------------*/
5444 /*----------------------------*/
5445 /* ++/-- operation */
5446 /*----------------------------*/
5449 fprintf(outfile,"post-");
5451 fprintf(outfile,"pre-");
5452 fprintf(outfile,"INC_OP (%p) type (",tree);
5453 printTypeChain(tree->ftype,outfile);
5454 fprintf(outfile,")\n");
5455 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5456 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5461 fprintf(outfile,"post-");
5463 fprintf(outfile,"pre-");
5464 fprintf(outfile,"DEC_OP (%p) type (",tree);
5465 printTypeChain(tree->ftype,outfile);
5466 fprintf(outfile,")\n");
5467 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5468 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5471 /*------------------------------------------------------------------*/
5472 /*----------------------------*/
5474 /*----------------------------*/
5477 fprintf(outfile,"& (%p) type (",tree);
5478 printTypeChain(tree->ftype,outfile);
5479 fprintf(outfile,")\n");
5480 ast_print(tree->left,outfile,indent+2);
5481 ast_print(tree->right,outfile,indent+2);
5483 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5484 printTypeChain(tree->ftype,outfile);
5485 fprintf(outfile,")\n");
5486 ast_print(tree->left,outfile,indent+2);
5487 ast_print(tree->right,outfile,indent+2);
5490 /*----------------------------*/
5492 /*----------------------------*/
5494 fprintf(outfile,"OR (%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);
5500 /*------------------------------------------------------------------*/
5501 /*----------------------------*/
5503 /*----------------------------*/
5505 fprintf(outfile,"XOR (%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);
5512 /*------------------------------------------------------------------*/
5513 /*----------------------------*/
5515 /*----------------------------*/
5517 fprintf(outfile,"DIV (%p) type (",tree);
5518 printTypeChain(tree->ftype,outfile);
5519 fprintf(outfile,")\n");
5520 ast_print(tree->left,outfile,indent+2);
5521 ast_print(tree->right,outfile,indent+2);
5523 /*------------------------------------------------------------------*/
5524 /*----------------------------*/
5526 /*----------------------------*/
5528 fprintf(outfile,"MOD (%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);
5535 /*------------------------------------------------------------------*/
5536 /*----------------------------*/
5537 /* address dereference */
5538 /*----------------------------*/
5539 case '*': /* can be unary : if right is null then unary operation */
5541 fprintf(outfile,"DEREF (%p) type (",tree);
5542 printTypeChain(tree->ftype,outfile);
5543 fprintf(outfile,")\n");
5544 ast_print(tree->left,outfile,indent+2);
5547 /*------------------------------------------------------------------*/
5548 /*----------------------------*/
5549 /* multiplication */
5550 /*----------------------------*/
5551 fprintf(outfile,"MULT (%p) type (",tree);
5552 printTypeChain(tree->ftype,outfile);
5553 fprintf(outfile,")\n");
5554 ast_print(tree->left,outfile,indent+2);
5555 ast_print(tree->right,outfile,indent+2);
5559 /*------------------------------------------------------------------*/
5560 /*----------------------------*/
5561 /* unary '+' operator */
5562 /*----------------------------*/
5566 fprintf(outfile,"UPLUS (%p) type (",tree);
5567 printTypeChain(tree->ftype,outfile);
5568 fprintf(outfile,")\n");
5569 ast_print(tree->left,outfile,indent+2);
5571 /*------------------------------------------------------------------*/
5572 /*----------------------------*/
5574 /*----------------------------*/
5575 fprintf(outfile,"ADD (%p) type (",tree);
5576 printTypeChain(tree->ftype,outfile);
5577 fprintf(outfile,")\n");
5578 ast_print(tree->left,outfile,indent+2);
5579 ast_print(tree->right,outfile,indent+2);
5582 /*------------------------------------------------------------------*/
5583 /*----------------------------*/
5585 /*----------------------------*/
5586 case '-': /* can be unary */
5588 fprintf(outfile,"UMINUS (%p) type (",tree);
5589 printTypeChain(tree->ftype,outfile);
5590 fprintf(outfile,")\n");
5591 ast_print(tree->left,outfile,indent+2);
5593 /*------------------------------------------------------------------*/
5594 /*----------------------------*/
5596 /*----------------------------*/
5597 fprintf(outfile,"SUB (%p) type (",tree);
5598 printTypeChain(tree->ftype,outfile);
5599 fprintf(outfile,")\n");
5600 ast_print(tree->left,outfile,indent+2);
5601 ast_print(tree->right,outfile,indent+2);
5604 /*------------------------------------------------------------------*/
5605 /*----------------------------*/
5607 /*----------------------------*/
5609 fprintf(outfile,"COMPL (%p) type (",tree);
5610 printTypeChain(tree->ftype,outfile);
5611 fprintf(outfile,")\n");
5612 ast_print(tree->left,outfile,indent+2);
5614 /*------------------------------------------------------------------*/
5615 /*----------------------------*/
5617 /*----------------------------*/
5619 fprintf(outfile,"NOT (%p) type (",tree);
5620 printTypeChain(tree->ftype,outfile);
5621 fprintf(outfile,")\n");
5622 ast_print(tree->left,outfile,indent+2);
5624 /*------------------------------------------------------------------*/
5625 /*----------------------------*/
5627 /*----------------------------*/
5629 fprintf(outfile,"RRC (%p) type (",tree);
5630 printTypeChain(tree->ftype,outfile);
5631 fprintf(outfile,")\n");
5632 ast_print(tree->left,outfile,indent+2);
5636 fprintf(outfile,"RLC (%p) type (",tree);
5637 printTypeChain(tree->ftype,outfile);
5638 fprintf(outfile,")\n");
5639 ast_print(tree->left,outfile,indent+2);
5642 fprintf(outfile,"SWAP (%p) type (",tree);
5643 printTypeChain(tree->ftype,outfile);
5644 fprintf(outfile,")\n");
5645 ast_print(tree->left,outfile,indent+2);
5648 fprintf(outfile,"GETHBIT (%p) type (",tree);
5649 printTypeChain(tree->ftype,outfile);
5650 fprintf(outfile,")\n");
5651 ast_print(tree->left,outfile,indent+2);
5654 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5655 printTypeChain(tree->ftype,outfile);
5656 fprintf(outfile,")\n");
5657 ast_print(tree->left,outfile,indent+2);
5658 ast_print(tree->right,outfile,indent+2);
5661 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5662 printTypeChain(tree->ftype,outfile);
5663 fprintf(outfile,")\n");
5664 ast_print(tree->left,outfile,indent+2);
5665 ast_print(tree->right,outfile,indent+2);
5667 /*------------------------------------------------------------------*/
5668 /*----------------------------*/
5670 /*----------------------------*/
5671 case CAST: /* change the type */
5672 fprintf(outfile,"CAST (%p) from type (",tree);
5673 printTypeChain(tree->right->ftype,outfile);
5674 fprintf(outfile,") to type (");
5675 printTypeChain(tree->ftype,outfile);
5676 fprintf(outfile,")\n");
5677 ast_print(tree->right,outfile,indent+2);
5681 fprintf(outfile,"ANDAND (%p) type (",tree);
5682 printTypeChain(tree->ftype,outfile);
5683 fprintf(outfile,")\n");
5684 ast_print(tree->left,outfile,indent+2);
5685 ast_print(tree->right,outfile,indent+2);
5688 fprintf(outfile,"OROR (%p) type (",tree);
5689 printTypeChain(tree->ftype,outfile);
5690 fprintf(outfile,")\n");
5691 ast_print(tree->left,outfile,indent+2);
5692 ast_print(tree->right,outfile,indent+2);
5695 /*------------------------------------------------------------------*/
5696 /*----------------------------*/
5697 /* comparison operators */
5698 /*----------------------------*/
5700 fprintf(outfile,"GT(>) (%p) type (",tree);
5701 printTypeChain(tree->ftype,outfile);
5702 fprintf(outfile,")\n");
5703 ast_print(tree->left,outfile,indent+2);
5704 ast_print(tree->right,outfile,indent+2);
5707 fprintf(outfile,"LT(<) (%p) type (",tree);
5708 printTypeChain(tree->ftype,outfile);
5709 fprintf(outfile,")\n");
5710 ast_print(tree->left,outfile,indent+2);
5711 ast_print(tree->right,outfile,indent+2);
5714 fprintf(outfile,"LE(<=) (%p) type (",tree);
5715 printTypeChain(tree->ftype,outfile);
5716 fprintf(outfile,")\n");
5717 ast_print(tree->left,outfile,indent+2);
5718 ast_print(tree->right,outfile,indent+2);
5721 fprintf(outfile,"GE(>=) (%p) type (",tree);
5722 printTypeChain(tree->ftype,outfile);
5723 fprintf(outfile,")\n");
5724 ast_print(tree->left,outfile,indent+2);
5725 ast_print(tree->right,outfile,indent+2);
5728 fprintf(outfile,"EQ(==) (%p) type (",tree);
5729 printTypeChain(tree->ftype,outfile);
5730 fprintf(outfile,")\n");
5731 ast_print(tree->left,outfile,indent+2);
5732 ast_print(tree->right,outfile,indent+2);
5735 fprintf(outfile,"NE(!=) (%p) type (",tree);
5736 printTypeChain(tree->ftype,outfile);
5737 fprintf(outfile,")\n");
5738 ast_print(tree->left,outfile,indent+2);
5739 ast_print(tree->right,outfile,indent+2);
5740 /*------------------------------------------------------------------*/
5741 /*----------------------------*/
5743 /*----------------------------*/
5744 case SIZEOF: /* evaluate wihout code generation */
5745 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5748 /*------------------------------------------------------------------*/
5749 /*----------------------------*/
5750 /* conditional operator '?' */
5751 /*----------------------------*/
5753 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5754 printTypeChain(tree->ftype,outfile);
5755 fprintf(outfile,")\n");
5756 ast_print(tree->left,outfile,indent+2);
5757 ast_print(tree->right,outfile,indent+2);
5761 fprintf(outfile,"COLON(:) (%p) type (",tree);
5762 printTypeChain(tree->ftype,outfile);
5763 fprintf(outfile,")\n");
5764 ast_print(tree->left,outfile,indent+2);
5765 ast_print(tree->right,outfile,indent+2);
5768 /*------------------------------------------------------------------*/
5769 /*----------------------------*/
5770 /* assignment operators */
5771 /*----------------------------*/
5773 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5774 printTypeChain(tree->ftype,outfile);
5775 fprintf(outfile,")\n");
5776 ast_print(tree->left,outfile,indent+2);
5777 ast_print(tree->right,outfile,indent+2);
5780 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5781 printTypeChain(tree->ftype,outfile);
5782 fprintf(outfile,")\n");
5783 ast_print(tree->left,outfile,indent+2);
5784 ast_print(tree->right,outfile,indent+2);
5787 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5788 printTypeChain(tree->ftype,outfile);
5789 fprintf(outfile,")\n");
5790 ast_print(tree->left,outfile,indent+2);
5791 ast_print(tree->right,outfile,indent+2);
5794 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5795 printTypeChain(tree->ftype,outfile);
5796 fprintf(outfile,")\n");
5797 ast_print(tree->left,outfile,indent+2);
5798 ast_print(tree->right,outfile,indent+2);
5801 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5802 printTypeChain(tree->ftype,outfile);
5803 fprintf(outfile,")\n");
5804 ast_print(tree->left,outfile,indent+2);
5805 ast_print(tree->right,outfile,indent+2);
5808 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5809 printTypeChain(tree->ftype,outfile);
5810 fprintf(outfile,")\n");
5811 ast_print(tree->left,outfile,indent+2);
5812 ast_print(tree->right,outfile,indent+2);
5815 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5816 printTypeChain(tree->ftype,outfile);
5817 fprintf(outfile,")\n");
5818 ast_print(tree->left,outfile,indent+2);
5819 ast_print(tree->right,outfile,indent+2);
5821 /*------------------------------------------------------------------*/
5822 /*----------------------------*/
5824 /*----------------------------*/
5826 fprintf(outfile,"SUBASS(-=) (%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,"ADDASS(+=) (%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 /*----------------------------*/
5845 /* straight assignemnt */
5846 /*----------------------------*/
5848 fprintf(outfile,"ASSIGN(=) (%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 /* comma operator */
5857 /*----------------------------*/
5859 fprintf(outfile,"COMMA(,) (%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 /*----------------------------*/
5868 /*----------------------------*/
5871 fprintf(outfile,"CALL (%p) type (",tree);
5872 printTypeChain(tree->ftype,outfile);
5873 fprintf(outfile,")\n");
5874 ast_print(tree->left,outfile,indent+2);
5875 ast_print(tree->right,outfile,indent+2);
5878 fprintf(outfile,"PARMS\n");
5879 ast_print(tree->left,outfile,indent+2);
5880 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5881 ast_print(tree->right,outfile,indent+2);
5884 /*------------------------------------------------------------------*/
5885 /*----------------------------*/
5886 /* return statement */
5887 /*----------------------------*/
5889 fprintf(outfile,"RETURN (%p) type (",tree);
5891 printTypeChain(tree->right->ftype,outfile);
5893 fprintf(outfile,")\n");
5894 ast_print(tree->right,outfile,indent+2);
5896 /*------------------------------------------------------------------*/
5897 /*----------------------------*/
5898 /* label statement */
5899 /*----------------------------*/
5901 fprintf(outfile,"LABEL (%p)\n",tree);
5902 ast_print(tree->left,outfile,indent+2);
5903 ast_print(tree->right,outfile,indent);
5905 /*------------------------------------------------------------------*/
5906 /*----------------------------*/
5907 /* switch statement */
5908 /*----------------------------*/
5912 fprintf(outfile,"SWITCH (%p) ",tree);
5913 ast_print(tree->left,outfile,0);
5914 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5915 INDENT(indent+2,outfile);
5916 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5917 (int) floatFromVal(val),
5918 tree->values.switchVals.swNum,
5919 (int) floatFromVal(val));
5921 ast_print(tree->right,outfile,indent);
5924 /*------------------------------------------------------------------*/
5925 /*----------------------------*/
5927 /*----------------------------*/
5929 fprintf(outfile,"IF (%p) \n",tree);
5930 ast_print(tree->left,outfile,indent+2);
5931 if (tree->trueLabel) {
5932 INDENT(indent+2,outfile);
5933 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5935 if (tree->falseLabel) {
5936 INDENT(indent+2,outfile);
5937 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5939 ast_print(tree->right,outfile,indent+2);
5941 /*----------------------------*/
5942 /* goto Statement */
5943 /*----------------------------*/
5945 fprintf(outfile,"GOTO (%p) \n",tree);
5946 ast_print(tree->left,outfile,indent+2);
5947 fprintf(outfile,"\n");
5949 /*------------------------------------------------------------------*/
5950 /*----------------------------*/
5952 /*----------------------------*/
5954 fprintf(outfile,"FOR (%p) \n",tree);
5955 if (AST_FOR( tree, initExpr)) {
5956 INDENT(indent+2,outfile);
5957 fprintf(outfile,"INIT EXPR ");
5958 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5960 if (AST_FOR( tree, condExpr)) {
5961 INDENT(indent+2,outfile);
5962 fprintf(outfile,"COND EXPR ");
5963 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5965 if (AST_FOR( tree, loopExpr)) {
5966 INDENT(indent+2,outfile);
5967 fprintf(outfile,"LOOP EXPR ");
5968 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5970 fprintf(outfile,"FOR LOOP BODY \n");
5971 ast_print(tree->left,outfile,indent+2);
5974 fprintf(outfile,"CRITICAL (%p) \n",tree);
5975 ast_print(tree->left,outfile,indent+2);
5983 ast_print(t,stdout,0);
5988 /*-----------------------------------------------------------------*/
5989 /* astErrors : returns non-zero if errors present in tree */
5990 /*-----------------------------------------------------------------*/
5991 int astErrors(ast *t)
6000 if (t->type == EX_VALUE
6001 && t->opval.val->sym
6002 && t->opval.val->sym->undefined)
6005 errors += astErrors(t->left);
6006 errors += astErrors(t->right);