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 -------------------------------------------------------------------------*/
25 #define DEBUG_CF(x) /* puts(x); */
31 set *operKeyReset = NULL;
32 ast *staticAutos = NULL;
35 #define LRVAL(x) x->left->rvalue
36 #define RRVAL(x) x->right->rvalue
37 #define TRVAL(x) x->rvalue
38 #define LLVAL(x) x->left->lvalue
39 #define RLVAL(x) x->right->lvalue
40 #define TLVAL(x) x->lvalue
41 #define RTYPE(x) x->right->ftype
42 #define RETYPE(x) x->right->etype
43 #define LTYPE(x) x->left->ftype
44 #define LETYPE(x) x->left->etype
45 #define TTYPE(x) x->ftype
46 #define TETYPE(x) x->etype
52 symbol *currFunc=NULL;
53 static ast *createIval (ast *, sym_link *, initList *, ast *);
54 static ast *createIvalCharPtr (ast *, sym_link *, ast *);
55 static ast *optimizeCompare (ast *);
56 ast *optimizeRRCRLC (ast *);
57 ast *optimizeSWAP (ast *);
58 ast *optimizeGetHbit (ast *);
59 ast *backPatchLabels (ast *, symbol *, symbol *);
62 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
67 printTypeChain (tree->ftype, stdout);
72 /*-----------------------------------------------------------------*/
73 /* newAst - creates a fresh node for an expression tree */
74 /*-----------------------------------------------------------------*/
76 newAst_ (unsigned type)
79 static int oldLineno = 0;
81 ex = Safe_alloc ( sizeof (ast));
84 ex->lineno = (noLineno ? oldLineno : mylineno);
85 ex->filename = currFname;
86 ex->level = NestLevel;
87 ex->block = currBlockno;
88 ex->initMode = inInitMode;
89 ex->seqPoint = seqPointNo;
94 newAst_VALUE (value * val)
96 ast *ex = newAst_ (EX_VALUE);
102 newAst_OP (unsigned op)
104 ast *ex = newAst_ (EX_OP);
110 newAst_LINK (sym_link * val)
112 ast *ex = newAst_ (EX_LINK);
117 /*-----------------------------------------------------------------*/
118 /* newNode - creates a new node */
119 /*-----------------------------------------------------------------*/
121 newNode (long op, ast * left, ast * right)
132 /*-----------------------------------------------------------------*/
133 /* newIfxNode - creates a new Ifx Node */
134 /*-----------------------------------------------------------------*/
136 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
140 /* if this is a literal then we already know the result */
141 if (condAst->etype && IS_LITERAL (condAst->etype))
143 /* then depending on the expression value */
144 if (floatFromVal (condAst->opval.val))
145 ifxNode = newNode (GOTO,
146 newAst_VALUE (symbolVal (trueLabel)),
149 ifxNode = newNode (GOTO,
150 newAst_VALUE (symbolVal (falseLabel)),
155 ifxNode = newNode (IFX, condAst, NULL);
156 ifxNode->trueLabel = trueLabel;
157 ifxNode->falseLabel = falseLabel;
163 /*-----------------------------------------------------------------*/
164 /* copyAstValues - copies value portion of ast if needed */
165 /*-----------------------------------------------------------------*/
167 copyAstValues (ast * dest, ast * src)
169 switch (src->opval.op)
172 dest->values.sym = copySymbolChain (src->values.sym);
176 dest->values.switchVals.swVals =
177 copyValue (src->values.switchVals.swVals);
178 dest->values.switchVals.swDefault =
179 src->values.switchVals.swDefault;
180 dest->values.switchVals.swNum =
181 src->values.switchVals.swNum;
185 dest->values.inlineasm = Safe_strdup(src->values.inlineasm);
189 dest->values.constlist = copyLiteralList(src->values.constlist);
193 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
194 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
195 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
196 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
197 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
198 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
199 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
204 /*-----------------------------------------------------------------*/
205 /* copyAst - makes a copy of a given astession */
206 /*-----------------------------------------------------------------*/
215 dest = Safe_alloc ( sizeof (ast));
217 dest->type = src->type;
218 dest->lineno = src->lineno;
219 dest->level = src->level;
220 dest->funcName = src->funcName;
223 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
225 /* if this is a leaf */
227 if (src->type == EX_VALUE)
229 dest->opval.val = copyValue (src->opval.val);
234 if (src->type == EX_LINK)
236 dest->opval.lnk = copyLinkChain (src->opval.lnk);
240 dest->opval.op = src->opval.op;
242 /* if this is a node that has special values */
243 copyAstValues (dest, src);
245 dest->trueLabel = copySymbol (src->trueLabel);
246 dest->falseLabel = copySymbol (src->falseLabel);
247 dest->left = copyAst (src->left);
248 dest->right = copyAst (src->right);
254 /*-----------------------------------------------------------------*/
255 /* removeIncDecOps: remove for side effects in *_ASSIGN's */
256 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
257 /*-----------------------------------------------------------------*/
258 ast *removeIncDecOps (ast * tree) {
260 // traverse the tree and remove inc/dec ops
265 if (tree->type == EX_OP &&
266 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
273 tree->left=removeIncDecOps(tree->left);
274 tree->right=removeIncDecOps(tree->right);
279 /*-----------------------------------------------------------------*/
280 /* removePreIncDecOps: remove for side effects in *_ASSIGN's */
281 /* "*++s += 3" -> "*++s = *++s + 3" */
282 /*-----------------------------------------------------------------*/
283 ast *removePreIncDecOps (ast * tree) {
285 // traverse the tree and remove pre-inc/dec ops
290 if (tree->type == EX_OP &&
291 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
296 tree->left=removePreIncDecOps(tree->left);
297 tree->right=removePreIncDecOps(tree->right);
302 /*-----------------------------------------------------------------*/
303 /* removePostIncDecOps: remove for side effects in *_ASSIGN's */
304 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
305 /*-----------------------------------------------------------------*/
306 ast *removePostIncDecOps (ast * tree) {
308 // traverse the tree and remove pre-inc/dec ops
313 if (tree->type == EX_OP &&
314 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
319 tree->left=removePostIncDecOps(tree->left);
320 tree->right=removePostIncDecOps(tree->right);
325 /*-----------------------------------------------------------------*/
326 /* hasSEFcalls - returns TRUE if tree has a function call */
327 /*-----------------------------------------------------------------*/
329 hasSEFcalls (ast * tree)
334 if (tree->type == EX_OP &&
335 (tree->opval.op == CALL ||
336 tree->opval.op == PCALL ||
337 tree->opval.op == '=' ||
338 tree->opval.op == INC_OP ||
339 tree->opval.op == DEC_OP))
342 return (hasSEFcalls (tree->left) |
343 hasSEFcalls (tree->right));
346 /*-----------------------------------------------------------------*/
347 /* isAstEqual - compares two asts & returns 1 if they are equal */
348 /*-----------------------------------------------------------------*/
350 isAstEqual (ast * t1, ast * t2)
359 if (t1->type != t2->type)
365 if (t1->opval.op != t2->opval.op)
367 return (isAstEqual (t1->left, t2->left) &&
368 isAstEqual (t1->right, t2->right));
372 if (t1->opval.val->sym)
374 if (!t2->opval.val->sym)
377 return isSymbolEqual (t1->opval.val->sym,
382 if (t2->opval.val->sym)
385 return (floatFromVal (t1->opval.val) ==
386 floatFromVal (t2->opval.val));
390 /* only compare these two types */
398 /*-----------------------------------------------------------------*/
399 /* resolveSymbols - resolve symbols from the symbol table */
400 /*-----------------------------------------------------------------*/
402 resolveSymbols (ast * tree)
404 /* walk the entire tree and check for values */
405 /* with symbols if we find one then replace */
406 /* symbol with that from the symbol table */
413 /* if not block & function */
414 if (tree->type == EX_OP &&
415 (tree->opval.op != FUNCTION &&
416 tree->opval.op != BLOCK &&
417 tree->opval.op != NULLOP))
419 filename = tree->filename;
420 lineno = tree->lineno;
424 /* make sure we resolve the true & false labels for ifx */
425 if (tree->type == EX_OP && tree->opval.op == IFX)
431 if ((csym = findSym (LabelTab, tree->trueLabel,
432 tree->trueLabel->name)))
433 tree->trueLabel = csym;
435 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
436 tree->trueLabel->name);
439 if (tree->falseLabel)
441 if ((csym = findSym (LabelTab,
443 tree->falseLabel->name)))
444 tree->falseLabel = csym;
446 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
447 tree->falseLabel->name);
452 /* if this is a label resolve it from the labelTab */
453 if (IS_AST_VALUE (tree) &&
454 tree->opval.val->sym &&
455 tree->opval.val->sym->islbl)
458 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
459 tree->opval.val->sym->name);
462 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
463 tree->opval.val->sym->name);
465 tree->opval.val->sym = csym;
467 goto resolveChildren;
470 /* do only for leafs */
471 if (IS_AST_VALUE (tree) &&
472 tree->opval.val->sym &&
473 !tree->opval.val->sym->implicit)
476 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
478 /* if found in the symbol table & they r not the same */
479 if (csym && tree->opval.val->sym != csym)
481 tree->opval.val->sym = csym;
482 tree->opval.val->type = csym->type;
483 tree->opval.val->etype = csym->etype;
486 /* if not found in the symbol table */
487 /* mark it as undefined assume it is */
488 /* an integer in data space */
489 if (!csym && !tree->opval.val->sym->implicit)
492 /* if this is a function name then */
493 /* mark it as returning an int */
496 tree->opval.val->sym->type = newLink (DECLARATOR);
497 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
498 tree->opval.val->sym->type->next =
499 tree->opval.val->sym->etype = newIntLink ();
500 tree->opval.val->etype = tree->opval.val->etype;
501 tree->opval.val->type = tree->opval.val->sym->type;
502 werrorfl (tree->filename, tree->lineno, W_IMPLICIT_FUNC,
503 tree->opval.val->sym->name);
504 //tree->opval.val->sym->undefined = 1;
505 allocVariables (tree->opval.val->sym);
509 tree->opval.val->sym->undefined = 1;
510 tree->opval.val->type =
511 tree->opval.val->etype = newIntLink ();
512 tree->opval.val->sym->type =
513 tree->opval.val->sym->etype = newIntLink ();
519 resolveSymbols (tree->left);
520 resolveSymbols (tree->right);
525 /*-----------------------------------------------------------------*/
526 /* setAstLineno - walks a ast tree & sets the line number */
527 /*-----------------------------------------------------------------*/
528 int setAstLineno (ast * tree, int lineno)
533 tree->lineno = lineno;
534 setAstLineno (tree->left, lineno);
535 setAstLineno (tree->right, lineno);
539 /*-----------------------------------------------------------------*/
540 /* funcOfType :- function of type with name */
541 /*-----------------------------------------------------------------*/
543 funcOfType (char *name, sym_link * type, sym_link * argType,
547 /* create the symbol */
548 sym = newSymbol (name, 0);
550 /* setup return value */
551 sym->type = newLink (DECLARATOR);
552 DCL_TYPE (sym->type) = FUNCTION;
553 sym->type->next = copyLinkChain (type);
554 sym->etype = getSpec (sym->type);
555 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
557 /* if arguments required */
561 args = FUNC_ARGS(sym->type) = newValue ();
565 args->type = copyLinkChain (argType);
566 args->etype = getSpec (args->type);
567 SPEC_EXTR(args->etype)=1;
570 args = args->next = newValue ();
577 allocVariables (sym);
582 /*-----------------------------------------------------------------*/
583 /* funcOfTypeVarg :- function of type with name and argtype */
584 /*-----------------------------------------------------------------*/
586 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
591 /* create the symbol */
592 sym = newSymbol (name, 0);
594 /* setup return value */
595 sym->type = newLink (DECLARATOR);
596 DCL_TYPE (sym->type) = FUNCTION;
597 sym->type->next = typeFromStr(rtype);
598 sym->etype = getSpec (sym->type);
600 /* if arguments required */
603 args = FUNC_ARGS(sym->type) = newValue ();
605 for ( i = 0 ; i < nArgs ; i++ ) {
606 args->type = typeFromStr(atypes[i]);
607 args->etype = getSpec (args->type);
608 SPEC_EXTR(args->etype)=1;
609 if ((i + 1) == nArgs) break;
610 args = args->next = newValue ();
617 allocVariables (sym);
622 /*-----------------------------------------------------------------*/
623 /* reverseParms - will reverse a parameter tree */
624 /*-----------------------------------------------------------------*/
626 reverseParms (ast * ptree)
632 /* top down if we find a nonParm tree then quit */
633 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
636 ptree->left = ptree->right;
637 ptree->right = ttree;
638 reverseParms (ptree->left);
639 reverseParms (ptree->right);
645 /*-----------------------------------------------------------------*/
646 /* processParms - makes sure the parameters are okay and do some */
647 /* processing with them */
648 /*-----------------------------------------------------------------*/
650 processParms (ast *func,
653 int *parmNumber, /* unused, although updated */
656 RESULT_TYPE resultType;
659 /* if none of them exist */
660 if (!defParm && !*actParm)
665 if (getenv("DEBUG_SANITY"))
667 fprintf (stderr, "processParms: %s ", defParm->name);
669 /* make sure the type is complete and sane */
670 checkTypeSanity(defParm->etype, defParm->name);
673 if (IS_CODEPTR (func->ftype))
674 functype = func->ftype->next;
676 functype = func->ftype;
678 /* if the function is being called via a pointer & */
679 /* it has not been defined a reentrant then we cannot */
680 /* have parameters */
681 if (func->type != EX_VALUE && !IFFUNC_ISREENT (functype) && !options.stackAuto)
683 werror (W_NONRENT_ARGS);
688 /* if defined parameters ended but actual parameters */
689 /* exist and this is not defined as a variable arg */
690 if (!defParm && *actParm && !IFFUNC_HASVARARGS(functype))
692 werror (E_TOO_MANY_PARMS);
696 /* if defined parameters present but no actual parameters */
697 if (defParm && !*actParm)
699 werror (E_TOO_FEW_PARMS);
703 /* if this is a PARAM node then match left & right */
704 if ((*actParm)->type == EX_OP && (*actParm)->opval.op == PARAM)
706 (*actParm)->decorated = 1;
707 return (processParms (func, defParm,
708 &(*actParm)->left, parmNumber, FALSE) ||
709 processParms (func, defParm ? defParm->next : NULL,
710 &(*actParm)->right, parmNumber, rightmost));
712 else if (defParm) /* not vararg */
714 /* If we have found a value node by following only right-hand links,
715 * then we know that there are no more values after us.
717 * Therefore, if there are more defined parameters, the caller didn't
720 if (rightmost && defParm->next)
722 werror (E_TOO_FEW_PARMS);
727 /* decorate parameter */
728 resultType = defParm ? getResultTypeFromType (defParm->etype) :
730 *actParm = decorateType (*actParm, resultType);
732 if (IS_VOID((*actParm)->ftype))
734 werror (E_VOID_VALUE_USED);
738 /* If this is a varargs function... */
739 if (!defParm && *actParm && IFFUNC_HASVARARGS(functype))
744 if (IS_CAST_OP (*actParm)
745 || (IS_AST_LIT_VALUE (*actParm) && (*actParm)->values.literalFromCast))
747 /* Parameter was explicitly typecast; don't touch it. */
751 ftype = (*actParm)->ftype;
753 /* If it's a char, upcast to int. */
754 if (IS_INTEGRAL (ftype)
755 && (getSize (ftype) < (unsigned) INTSIZE))
757 newType = newAst_LINK(INTTYPE);
760 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
762 newType = newAst_LINK (copyLinkChain(ftype));
763 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
766 if (IS_AGGREGATE (ftype))
768 newType = newAst_LINK (copyLinkChain (ftype));
769 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
774 /* cast required; change this op to a cast. */
775 (*actParm)->decorated = 0;
776 *actParm = newNode (CAST, newType, *actParm);
777 (*actParm)->lineno = (*actParm)->right->lineno;
779 decorateType (*actParm, RESULT_TYPE_NONE);
784 /* if defined parameters ended but actual has not & */
786 if (!defParm && *actParm &&
787 (options.stackAuto || IFFUNC_ISREENT (functype)))
790 resolveSymbols (*actParm);
792 /* the parameter type must be at least castable */
793 if (compareType (defParm->type, (*actParm)->ftype) == 0)
795 werror (E_INCOMPAT_TYPES);
796 printFromToType ((*actParm)->ftype, defParm->type);
800 /* if the parameter is castable then add the cast */
801 if (compareType (defParm->type, (*actParm)->ftype) < 0)
805 resultType = getResultTypeFromType (defParm->etype);
806 pTree = resolveSymbols (copyAst (*actParm));
808 /* now change the current one to a cast */
809 (*actParm)->type = EX_OP;
810 (*actParm)->opval.op = CAST;
811 (*actParm)->left = newAst_LINK (defParm->type);
812 (*actParm)->right = pTree;
813 (*actParm)->decorated = 0; /* force typechecking */
814 decorateType (*actParm, resultType);
817 /* make a copy and change the regparm type to the defined parm */
818 (*actParm)->etype = getSpec ((*actParm)->ftype = copyLinkChain ((*actParm)->ftype));
819 SPEC_REGPARM ((*actParm)->etype) = SPEC_REGPARM (defParm->etype);
820 SPEC_ARGREG ((*actParm)->etype) = SPEC_ARGREG (defParm->etype);
825 /*-----------------------------------------------------------------*/
826 /* createIvalType - generates ival for basic types */
827 /*-----------------------------------------------------------------*/
829 createIvalType (ast * sym, sym_link * type, initList * ilist)
833 /* if initList is deep */
834 if (ilist->type == INIT_DEEP)
835 ilist = ilist->init.deep;
837 iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK);
838 return decorateType (newNode ('=', sym, iExpr), RESULT_CHECK);
841 /*-----------------------------------------------------------------*/
842 /* createIvalStruct - generates initial value for structures */
843 /*-----------------------------------------------------------------*/
845 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
852 sflds = SPEC_STRUCT (type)->fields;
853 if (ilist->type != INIT_DEEP)
855 werror (E_INIT_STRUCT, "");
859 iloop = ilist->init.deep;
861 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
863 /* if we have come to end */
867 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
868 lAst = decorateType (resolveSymbols (lAst), RESULT_CHECK);
869 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)), RESULT_CHECK);
873 werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
874 W_EXCESS_INITIALIZERS, "struct",
875 sym->opval.val->sym->name);
882 /*-----------------------------------------------------------------*/
883 /* createIvalArray - generates code for array initialization */
884 /*-----------------------------------------------------------------*/
886 createIvalArray (ast * sym, sym_link * type, initList * ilist)
890 int lcnt = 0, size = 0;
891 literalList *literalL;
893 /* take care of the special case */
894 /* array of characters can be init */
896 if (IS_CHAR (type->next))
897 if ((rast = createIvalCharPtr (sym,
899 decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK))))
901 return decorateType (resolveSymbols (rast), RESULT_CHECK);
903 /* not the special case */
904 if (ilist->type != INIT_DEEP)
906 werror (E_INIT_STRUCT, "");
910 iloop = ilist->init.deep;
911 lcnt = DCL_ELEM (type);
913 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
917 aSym = decorateType (resolveSymbols(sym), RESULT_CHECK);
919 rast = newNode(ARRAYINIT, aSym, NULL);
920 rast->values.constlist = literalL;
922 // Make sure size is set to length of initializer list.
929 if (lcnt && size > lcnt)
931 // Array size was specified, and we have more initializers than needed.
932 char *name=sym->opval.val->sym->name;
933 int lineno=sym->opval.val->sym->lineDef;
934 char *filename=sym->opval.val->sym->fileDef;
936 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
945 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
946 aSym = decorateType (resolveSymbols (aSym), RESULT_CHECK);
947 rast = createIval (aSym, type->next, iloop, rast);
948 iloop = (iloop ? iloop->next : NULL);
954 /* no of elements given and we */
955 /* have generated for all of them */
958 // is this a better way? at least it won't crash
959 char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
960 int lineno = iloop->lineno;
961 char *filename = iloop->filename;
962 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
969 /* if we have not been given a size */
970 if (!DCL_ELEM (type))
972 /* but this still updates the typedef instead of the instance ! see bug 770487 */
973 DCL_ELEM (type) = size;
976 return decorateType (resolveSymbols (rast), RESULT_CHECK);
980 /*-----------------------------------------------------------------*/
981 /* createIvalCharPtr - generates initial values for char pointers */
982 /*-----------------------------------------------------------------*/
984 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
988 /* if this is a pointer & right is a literal array then */
989 /* just assignment will do */
990 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
991 SPEC_SCLS (iexpr->etype) == S_CODE)
992 && IS_ARRAY (iexpr->ftype)))
993 return newNode ('=', sym, iexpr);
995 /* left side is an array so we have to assign each */
997 if ((IS_LITERAL (iexpr->etype) ||
998 SPEC_SCLS (iexpr->etype) == S_CODE)
999 && IS_ARRAY (iexpr->ftype))
1001 /* for each character generate an assignment */
1002 /* to the array element */
1003 char *s = SPEC_CVAL (iexpr->etype).v_char;
1005 int size = getSize (iexpr->ftype);
1006 int symsize = getSize (type);
1010 if (size>(symsize+1))
1011 werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1012 "string", sym->opval.val->sym->name);
1016 for (i=0;i<size;i++)
1018 rast = newNode (NULLOP,
1022 newAst_VALUE (valueFromLit ((float) i))),
1023 newAst_VALUE (valueFromLit (*s))));
1027 // now WE don't need iexpr's symbol anymore
1028 freeStringSymbol(AST_SYMBOL(iexpr));
1030 return decorateType (resolveSymbols (rast), RESULT_CHECK);
1036 /*-----------------------------------------------------------------*/
1037 /* createIvalPtr - generates initial value for pointers */
1038 /*-----------------------------------------------------------------*/
1040 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
1046 if (ilist->type == INIT_DEEP)
1047 ilist = ilist->init.deep;
1049 iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK);
1051 /* if character pointer */
1052 if (IS_CHAR (type->next))
1053 if ((rast = createIvalCharPtr (sym, type, iexpr)))
1056 return newNode ('=', sym, iexpr);
1059 /*-----------------------------------------------------------------*/
1060 /* createIval - generates code for initial value */
1061 /*-----------------------------------------------------------------*/
1063 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1070 /* if structure then */
1071 if (IS_STRUCT (type))
1072 rast = createIvalStruct (sym, type, ilist);
1074 /* if this is a pointer */
1076 rast = createIvalPtr (sym, type, ilist);
1078 /* if this is an array */
1079 if (IS_ARRAY (type))
1080 rast = createIvalArray (sym, type, ilist);
1082 /* if type is SPECIFIER */
1084 rast = createIvalType (sym, type, ilist);
1087 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_CHECK);
1089 return decorateType (resolveSymbols (rast), RESULT_CHECK);
1092 /*-----------------------------------------------------------------*/
1093 /* initAggregates - initialises aggregate variables with initv */
1094 /*-----------------------------------------------------------------*/
1095 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1096 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1099 /*-----------------------------------------------------------------*/
1100 /* gatherAutoInit - creates assignment expressions for initial */
1102 /*-----------------------------------------------------------------*/
1104 gatherAutoInit (symbol * autoChain)
1111 for (sym = autoChain; sym; sym = sym->next)
1114 /* resolve the symbols in the ival */
1116 resolveIvalSym (sym->ival, sym->type);
1118 /* if this is a static variable & has an */
1119 /* initial value the code needs to be lifted */
1120 /* here to the main portion since they can be */
1121 /* initialised only once at the start */
1122 if (IS_STATIC (sym->etype) && sym->ival &&
1123 SPEC_SCLS (sym->etype) != S_CODE)
1127 /* insert the symbol into the symbol table */
1128 /* with level = 0 & name = rname */
1129 newSym = copySymbol (sym);
1130 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1132 /* now lift the code to main */
1133 if (IS_AGGREGATE (sym->type)) {
1134 work = initAggregates (sym, sym->ival, NULL);
1136 if (getNelements(sym->type, sym->ival)>1) {
1137 werrorfl (sym->fileDef, sym->lineDef,
1138 W_EXCESS_INITIALIZERS, "scalar",
1141 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1142 list2expr (sym->ival));
1145 setAstLineno (work, sym->lineDef);
1149 staticAutos = newNode (NULLOP, staticAutos, work);
1156 /* if there is an initial value */
1157 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1159 initList *ilist=sym->ival;
1161 while (ilist->type == INIT_DEEP) {
1162 ilist = ilist->init.deep;
1165 /* update lineno for error msg */
1166 lineno=sym->lineDef;
1167 setAstLineno (ilist->init.node, lineno);
1169 if (IS_AGGREGATE (sym->type)) {
1170 work = initAggregates (sym, sym->ival, NULL);
1172 if (getNelements(sym->type, sym->ival)>1) {
1173 werrorfl (sym->fileDef, sym->lineDef,
1174 W_EXCESS_INITIALIZERS, "scalar",
1177 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1178 list2expr (sym->ival));
1182 setAstLineno (work, sym->lineDef);
1186 init = newNode (NULLOP, init, work);
1195 /*-----------------------------------------------------------------*/
1196 /* freeStringSymbol - delete a literal string if no more usage */
1197 /*-----------------------------------------------------------------*/
1198 void freeStringSymbol(symbol *sym) {
1199 /* make sure this is a literal string */
1200 assert (sym->isstrlit);
1201 if (--sym->isstrlit == 0) { // lower the usage count
1202 memmap *segment=SPEC_OCLS(sym->etype);
1204 deleteSetItem(&segment->syms, sym);
1209 /*-----------------------------------------------------------------*/
1210 /* stringToSymbol - creates a symbol from a literal string */
1211 /*-----------------------------------------------------------------*/
1213 stringToSymbol (value * val)
1215 char name[SDCC_NAME_MAX + 1];
1216 static int charLbl = 0;
1221 // have we heard this before?
1222 for (sp=statsg->syms; sp; sp=sp->next) {
1224 size = getSize (sym->type);
1225 if (sym->isstrlit && size == getSize (val->type) &&
1226 !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1227 // yes, this is old news. Don't publish it again.
1228 sym->isstrlit++; // but raise the usage count
1229 return symbolVal(sym);
1233 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1234 sym = newSymbol (name, 0); /* make it @ level 0 */
1235 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1237 /* copy the type from the value passed */
1238 sym->type = copyLinkChain (val->type);
1239 sym->etype = getSpec (sym->type);
1240 /* change to storage class & output class */
1241 SPEC_SCLS (sym->etype) = S_CODE;
1242 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1243 SPEC_STAT (sym->etype) = 1;
1244 /* make the level & block = 0 */
1245 sym->block = sym->level = 0;
1247 /* create an ival */
1248 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1253 allocVariables (sym);
1256 return symbolVal (sym);
1260 /*-----------------------------------------------------------------*/
1261 /* processBlockVars - will go thru the ast looking for block if */
1262 /* a block is found then will allocate the syms */
1263 /* will also gather the auto inits present */
1264 /*-----------------------------------------------------------------*/
1266 processBlockVars (ast * tree, int *stack, int action)
1271 /* if this is a block */
1272 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1276 if (action == ALLOCATE)
1278 *stack += allocVariables (tree->values.sym);
1279 autoInit = gatherAutoInit (tree->values.sym);
1281 /* if there are auto inits then do them */
1283 tree->left = newNode (NULLOP, autoInit, tree->left);
1285 else /* action is deallocate */
1286 deallocLocal (tree->values.sym);
1289 processBlockVars (tree->left, stack, action);
1290 processBlockVars (tree->right, stack, action);
1295 /*-------------------------------------------------------------*/
1296 /* constExprTree - returns TRUE if this tree is a constant */
1298 /*-------------------------------------------------------------*/
1299 bool constExprTree (ast *cexpr) {
1305 cexpr = decorateType (resolveSymbols (cexpr), RESULT_CHECK);
1307 switch (cexpr->type)
1310 if (IS_AST_LIT_VALUE(cexpr)) {
1311 // this is a literal
1314 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1315 // a function's address will never change
1318 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1319 // an array's address will never change
1322 if (IS_AST_SYM_VALUE(cexpr) &&
1323 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1324 // a symbol in code space will never change
1325 // This is only for the 'char *s="hallo"' case and will have to leave
1326 //printf(" code space symbol");
1331 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1332 "unexpected link in expression tree\n");
1335 if (cexpr->opval.op==ARRAYINIT) {
1336 // this is a list of literals
1339 if (cexpr->opval.op=='=') {
1340 return constExprTree(cexpr->right);
1342 if (cexpr->opval.op==CAST) {
1343 // cast ignored, maybe we should throw a warning here?
1344 return constExprTree(cexpr->right);
1346 if (cexpr->opval.op=='&') {
1349 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1352 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1357 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1362 /*-----------------------------------------------------------------*/
1363 /* constExprValue - returns the value of a constant expression */
1364 /* or NULL if it is not a constant expression */
1365 /*-----------------------------------------------------------------*/
1367 constExprValue (ast * cexpr, int check)
1369 cexpr = decorateType (resolveSymbols (cexpr), RESULT_CHECK);
1371 /* if this is not a constant then */
1372 if (!IS_LITERAL (cexpr->ftype))
1374 /* then check if this is a literal array
1376 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1377 SPEC_CVAL (cexpr->etype).v_char &&
1378 IS_ARRAY (cexpr->ftype))
1380 value *val = valFromType (cexpr->ftype);
1381 SPEC_SCLS (val->etype) = S_LITERAL;
1382 val->sym = cexpr->opval.val->sym;
1383 val->sym->type = copyLinkChain (cexpr->ftype);
1384 val->sym->etype = getSpec (val->sym->type);
1385 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1389 /* if we are casting a literal value then */
1390 if (IS_AST_OP (cexpr) &&
1391 cexpr->opval.op == CAST &&
1392 IS_LITERAL (cexpr->right->ftype))
1394 return valCastLiteral (cexpr->ftype,
1395 floatFromVal (cexpr->right->opval.val));
1398 if (IS_AST_VALUE (cexpr))
1400 return cexpr->opval.val;
1404 werror (E_CONST_EXPECTED, "found expression");
1409 /* return the value */
1410 return cexpr->opval.val;
1414 /*-----------------------------------------------------------------*/
1415 /* isLabelInAst - will return true if a given label is found */
1416 /*-----------------------------------------------------------------*/
1418 isLabelInAst (symbol * label, ast * tree)
1420 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1423 if (IS_AST_OP (tree) &&
1424 tree->opval.op == LABEL &&
1425 isSymbolEqual (AST_SYMBOL (tree->left), label))
1428 return isLabelInAst (label, tree->right) &&
1429 isLabelInAst (label, tree->left);
1433 /*-----------------------------------------------------------------*/
1434 /* isLoopCountable - return true if the loop count can be determi- */
1435 /* -ned at compile time . */
1436 /*-----------------------------------------------------------------*/
1438 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1439 symbol ** sym, ast ** init, ast ** end)
1442 /* the loop is considered countable if the following
1443 conditions are true :-
1445 a) initExpr :- <sym> = <const>
1446 b) condExpr :- <sym> < <const1>
1447 c) loopExpr :- <sym> ++
1450 /* first check the initExpr */
1451 if (IS_AST_OP (initExpr) &&
1452 initExpr->opval.op == '=' && /* is assignment */
1453 IS_AST_SYM_VALUE (initExpr->left))
1454 { /* left is a symbol */
1456 *sym = AST_SYMBOL (initExpr->left);
1457 *init = initExpr->right;
1462 /* for now the symbol has to be of
1464 if (!IS_INTEGRAL ((*sym)->type))
1467 /* now check condExpr */
1468 if (IS_AST_OP (condExpr))
1471 switch (condExpr->opval.op)
1474 if (IS_AST_SYM_VALUE (condExpr->left) &&
1475 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1476 IS_AST_LIT_VALUE (condExpr->right))
1478 *end = condExpr->right;
1484 if (IS_AST_OP (condExpr->left) &&
1485 condExpr->left->opval.op == '>' &&
1486 IS_AST_LIT_VALUE (condExpr->left->right) &&
1487 IS_AST_SYM_VALUE (condExpr->left->left) &&
1488 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1491 *end = newNode ('+', condExpr->left->right,
1492 newAst_VALUE (constVal ("1")));
1503 /* check loop expression is of the form <sym>++ */
1504 if (!IS_AST_OP (loopExpr))
1507 /* check if <sym> ++ */
1508 if (loopExpr->opval.op == INC_OP)
1514 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1515 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1522 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1523 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1531 if (loopExpr->opval.op == ADD_ASSIGN)
1534 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1535 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1536 IS_AST_LIT_VALUE (loopExpr->right) &&
1537 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1545 /*-----------------------------------------------------------------*/
1546 /* astHasVolatile - returns true if ast contains any volatile */
1547 /*-----------------------------------------------------------------*/
1549 astHasVolatile (ast * tree)
1554 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1557 if (IS_AST_OP (tree))
1558 return astHasVolatile (tree->left) ||
1559 astHasVolatile (tree->right);
1564 /*-----------------------------------------------------------------*/
1565 /* astHasPointer - return true if the ast contains any ptr variable */
1566 /*-----------------------------------------------------------------*/
1568 astHasPointer (ast * tree)
1573 if (IS_AST_LINK (tree))
1576 /* if we hit an array expression then check
1577 only the left side */
1578 if (IS_AST_OP (tree) && tree->opval.op == '[')
1579 return astHasPointer (tree->left);
1581 if (IS_AST_VALUE (tree))
1582 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1584 return astHasPointer (tree->left) ||
1585 astHasPointer (tree->right);
1589 /*-----------------------------------------------------------------*/
1590 /* astHasSymbol - return true if the ast has the given symbol */
1591 /*-----------------------------------------------------------------*/
1593 astHasSymbol (ast * tree, symbol * sym)
1595 if (!tree || IS_AST_LINK (tree))
1598 if (IS_AST_VALUE (tree))
1600 if (IS_AST_SYM_VALUE (tree))
1601 return isSymbolEqual (AST_SYMBOL (tree), sym);
1606 return astHasSymbol (tree->left, sym) ||
1607 astHasSymbol (tree->right, sym);
1610 /*-----------------------------------------------------------------*/
1611 /* astHasDeref - return true if the ast has an indirect access */
1612 /*-----------------------------------------------------------------*/
1614 astHasDeref (ast * tree)
1616 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1619 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1621 return astHasDeref (tree->left) || astHasDeref (tree->right);
1624 /*-----------------------------------------------------------------*/
1625 /* isConformingBody - the loop body has to conform to a set of rules */
1626 /* for the loop to be considered reversible read on for rules */
1627 /*-----------------------------------------------------------------*/
1629 isConformingBody (ast * pbody, symbol * sym, ast * body)
1632 /* we are going to do a pre-order traversal of the
1633 tree && check for the following conditions. (essentially
1634 a set of very shallow tests )
1635 a) the sym passed does not participate in
1636 any arithmetic operation
1637 b) There are no function calls
1638 c) all jumps are within the body
1639 d) address of loop control variable not taken
1640 e) if an assignment has a pointer on the
1641 left hand side make sure right does not have
1642 loop control variable */
1644 /* if we reach the end or a leaf then true */
1645 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1648 /* if anything else is "volatile" */
1649 if (IS_VOLATILE (TETYPE (pbody)))
1652 /* we will walk the body in a pre-order traversal for
1654 switch (pbody->opval.op)
1656 /*------------------------------------------------------------------*/
1658 // if the loopvar is used as an index
1659 /* array op is commutative -- must check both left & right */
1660 if (astHasSymbol(pbody->right, sym) || astHasSymbol(pbody->left, sym)) {
1663 return isConformingBody (pbody->right, sym, body)
1664 && isConformingBody (pbody->left, sym, body);
1666 /*------------------------------------------------------------------*/
1671 /*------------------------------------------------------------------*/
1675 /* sure we are not sym is not modified */
1677 IS_AST_SYM_VALUE (pbody->left) &&
1678 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1682 IS_AST_SYM_VALUE (pbody->right) &&
1683 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1688 /*------------------------------------------------------------------*/
1690 case '*': /* can be unary : if right is null then unary operation */
1695 /* if right is NULL then unary operation */
1696 /*------------------------------------------------------------------*/
1697 /*----------------------------*/
1699 /*----------------------------*/
1702 if (IS_AST_SYM_VALUE (pbody->left) &&
1703 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1706 return isConformingBody (pbody->left, sym, body);
1710 if (astHasSymbol (pbody->left, sym) ||
1711 astHasSymbol (pbody->right, sym))
1716 /*------------------------------------------------------------------*/
1724 if (IS_AST_SYM_VALUE (pbody->left) &&
1725 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1728 if (IS_AST_SYM_VALUE (pbody->right) &&
1729 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1732 return isConformingBody (pbody->left, sym, body) &&
1733 isConformingBody (pbody->right, sym, body);
1741 if (IS_AST_SYM_VALUE (pbody->left) &&
1742 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1744 return isConformingBody (pbody->left, sym, body);
1746 /*------------------------------------------------------------------*/
1758 case SIZEOF: /* evaluate wihout code generation */
1760 if (IS_AST_SYM_VALUE (pbody->left) &&
1761 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1764 if (IS_AST_SYM_VALUE (pbody->right) &&
1765 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1768 return isConformingBody (pbody->left, sym, body) &&
1769 isConformingBody (pbody->right, sym, body);
1771 /*------------------------------------------------------------------*/
1774 /* if left has a pointer & right has loop
1775 control variable then we cannot */
1776 if (astHasPointer (pbody->left) &&
1777 astHasSymbol (pbody->right, sym))
1779 if (astHasVolatile (pbody->left))
1782 if (IS_AST_SYM_VALUE (pbody->left)) {
1783 // if the loopvar has an assignment
1784 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1786 // if the loopvar is used in another (maybe conditional) block
1787 if (astHasSymbol (pbody->right, sym) &&
1788 (pbody->level >= body->level)) {
1793 if (astHasVolatile (pbody->left))
1796 if (astHasDeref(pbody->right)) return FALSE;
1798 return isConformingBody (pbody->left, sym, body) &&
1799 isConformingBody (pbody->right, sym, body);
1810 assert ("Parser should not have generated this\n");
1812 /*------------------------------------------------------------------*/
1813 /*----------------------------*/
1814 /* comma operator */
1815 /*----------------------------*/
1817 return isConformingBody (pbody->left, sym, body) &&
1818 isConformingBody (pbody->right, sym, body);
1820 /*------------------------------------------------------------------*/
1821 /*----------------------------*/
1823 /*----------------------------*/
1825 /* if local & not passed as paramater then ok */
1826 if (sym->level && !astHasSymbol(pbody->right,sym))
1830 /*------------------------------------------------------------------*/
1831 /*----------------------------*/
1832 /* return statement */
1833 /*----------------------------*/
1838 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1843 if (astHasSymbol (pbody->left, sym))
1850 return isConformingBody (pbody->left, sym, body) &&
1851 isConformingBody (pbody->right, sym, body);
1857 /*-----------------------------------------------------------------*/
1858 /* isLoopReversible - takes a for loop as input && returns true */
1859 /* if the for loop is reversible. If yes will set the value of */
1860 /* the loop control var & init value & termination value */
1861 /*-----------------------------------------------------------------*/
1863 isLoopReversible (ast * loop, symbol ** loopCntrl,
1864 ast ** init, ast ** end)
1866 /* if option says don't do it then don't */
1867 if (optimize.noLoopReverse)
1869 /* there are several tests to determine this */
1871 /* for loop has to be of the form
1872 for ( <sym> = <const1> ;
1873 [<sym> < <const2>] ;
1874 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1876 if (!isLoopCountable (AST_FOR (loop, initExpr),
1877 AST_FOR (loop, condExpr),
1878 AST_FOR (loop, loopExpr),
1879 loopCntrl, init, end))
1882 /* now do some serious checking on the body of the loop
1885 return isConformingBody (loop->left, *loopCntrl, loop->left);
1889 /*-----------------------------------------------------------------*/
1890 /* replLoopSym - replace the loop sym by loop sym -1 */
1891 /*-----------------------------------------------------------------*/
1893 replLoopSym (ast * body, symbol * sym)
1896 if (!body || IS_AST_LINK (body))
1899 if (IS_AST_SYM_VALUE (body))
1902 if (isSymbolEqual (AST_SYMBOL (body), sym))
1906 body->opval.op = '-';
1907 body->left = newAst_VALUE (symbolVal (sym));
1908 body->right = newAst_VALUE (constVal ("1"));
1916 replLoopSym (body->left, sym);
1917 replLoopSym (body->right, sym);
1921 /*-----------------------------------------------------------------*/
1922 /* reverseLoop - do the actual loop reversal */
1923 /*-----------------------------------------------------------------*/
1925 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1929 /* create the following tree
1934 if (sym) goto for_continue ;
1937 /* put it together piece by piece */
1938 rloop = newNode (NULLOP,
1939 createIf (newAst_VALUE (symbolVal (sym)),
1941 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1944 newAst_VALUE (symbolVal (sym)),
1947 replLoopSym (loop->left, sym);
1948 setAstLineno (rloop, init->lineno);
1950 rloop = newNode (NULLOP,
1952 newAst_VALUE (symbolVal (sym)),
1953 newNode ('-', end, init)),
1954 createLabel (AST_FOR (loop, continueLabel),
1958 newNode (SUB_ASSIGN,
1959 newAst_VALUE (symbolVal (sym)),
1960 newAst_VALUE (constVal ("1"))),
1963 rloop->lineno=init->lineno;
1964 return decorateType (rloop, RESULT_CHECK);
1968 /*-----------------------------------------------------------------*/
1969 /* searchLitOp - search tree (*ops only) for an ast with literal */
1970 /*-----------------------------------------------------------------*/
1972 searchLitOp (ast *tree, ast **parent, const char *ops)
1976 if (tree && optimize.global_cse)
1978 /* is there a literal operand? */
1980 IS_AST_OP(tree->right) &&
1981 tree->right->right &&
1982 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
1984 if (IS_LITERAL (RTYPE (tree->right)) !=
1985 IS_LITERAL (LTYPE (tree->right)))
1987 tree->right->decorated = 0;
1988 tree->decorated = 0;
1992 ret = searchLitOp (tree->right, parent, ops);
1997 IS_AST_OP(tree->left) &&
1998 tree->left->right &&
1999 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
2001 if (IS_LITERAL (RTYPE (tree->left)) !=
2002 IS_LITERAL (LTYPE (tree->left)))
2004 tree->left->decorated = 0;
2005 tree->decorated = 0;
2009 ret = searchLitOp (tree->left, parent, ops);
2017 /*-----------------------------------------------------------------*/
2018 /* getResultFromType */
2019 /*-----------------------------------------------------------------*/
2021 getResultTypeFromType (sym_link *type)
2023 /* type = getSpec (type); */
2025 return RESULT_TYPE_BIT;
2026 if (IS_BITFIELD (type))
2028 int blen = SPEC_BLEN (type);
2031 return RESULT_TYPE_BIT;
2033 return RESULT_TYPE_CHAR;
2034 return RESULT_TYPE_INT;
2037 return RESULT_TYPE_CHAR;
2040 return RESULT_TYPE_INT;
2041 return RESULT_TYPE_OTHER;
2044 /*-----------------------------------------------------------------*/
2045 /* addCast - adds casts to a type specified by RESULT_TYPE */
2046 /*-----------------------------------------------------------------*/
2048 addCast (ast *tree, RESULT_TYPE resultType, bool upcast)
2051 bool upCasted = FALSE;
2055 case RESULT_TYPE_NONE:
2056 /* char: promote to int */
2058 getSize (tree->etype) >= INTSIZE)
2060 newLink = newIntLink();
2063 case RESULT_TYPE_CHAR:
2064 if (IS_CHAR (tree->etype) ||
2065 IS_FLOAT(tree->etype))
2067 newLink = newCharLink();
2069 case RESULT_TYPE_INT:
2071 if (getSize (tree->etype) > INTSIZE)
2073 /* warn ("Loosing significant digits"); */
2077 /* char: promote to int */
2079 getSize (tree->etype) >= INTSIZE)
2081 newLink = newIntLink();
2084 case RESULT_TYPE_OTHER:
2087 /* return type is long, float: promote char to int */
2088 if (getSize (tree->etype) >= INTSIZE)
2090 newLink = newIntLink();
2096 tree->decorated = 0;
2097 tree = newNode (CAST, newAst_LINK (newLink), tree);
2098 tree->lineno = tree->right->lineno;
2099 /* keep unsigned type during cast to smaller type,
2100 but not when promoting from char to int */
2102 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2103 return decorateType (tree, resultType);
2106 /*-----------------------------------------------------------------*/
2107 /* resultTypePropagate - decides if resultType can be propagated */
2108 /*-----------------------------------------------------------------*/
2110 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2112 switch (tree->opval.op)
2128 return RESULT_TYPE_NONE;
2132 return RESULT_TYPE_IFX;
2134 return RESULT_TYPE_NONE;
2138 /*-----------------------------------------------------------------*/
2139 /* getLeftResultType - gets type from left branch for propagation */
2140 /*-----------------------------------------------------------------*/
2142 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2144 switch (tree->opval.op)
2148 if (IS_PTR (LTYPE (tree)))
2149 return RESULT_TYPE_NONE;
2151 return getResultTypeFromType (LETYPE (tree));
2153 if (IS_PTR (currFunc->type->next))
2154 return RESULT_TYPE_NONE;
2156 return getResultTypeFromType (currFunc->type->next);
2158 if (!IS_ARRAY (LTYPE (tree)))
2160 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256)
2161 return RESULT_TYPE_CHAR;
2168 /*--------------------------------------------------------------------*/
2169 /* decorateType - compute type for this tree, also does type checking.*/
2170 /* This is done bottom up, since type has to flow upwards. */
2171 /* resultType flows top-down and forces e.g. char-arithmetik, if the */
2172 /* result is a char and the operand(s) are int's. */
2173 /* It also does constant folding, and parameter checking. */
2174 /*--------------------------------------------------------------------*/
2176 decorateType (ast * tree, RESULT_TYPE resultType)
2180 RESULT_TYPE resultTypeProp;
2185 /* if already has type then do nothing */
2186 if (tree->decorated)
2189 tree->decorated = 1;
2192 /* print the line */
2193 /* if not block & function */
2194 if (tree->type == EX_OP &&
2195 (tree->opval.op != FUNCTION &&
2196 tree->opval.op != BLOCK &&
2197 tree->opval.op != NULLOP))
2199 filename = tree->filename;
2200 lineno = tree->lineno;
2204 /* if any child is an error | this one is an error do nothing */
2205 if (tree->isError ||
2206 (tree->left && tree->left->isError) ||
2207 (tree->right && tree->right->isError))
2210 /*------------------------------------------------------------------*/
2211 /*----------------------------*/
2212 /* leaf has been reached */
2213 /*----------------------------*/
2214 lineno=tree->lineno;
2215 /* if this is of type value */
2216 /* just get the type */
2217 if (tree->type == EX_VALUE)
2220 if (IS_LITERAL (tree->opval.val->etype))
2223 /* if this is a character array then declare it */
2224 if (IS_ARRAY (tree->opval.val->type))
2225 tree->opval.val = stringToSymbol (tree->opval.val);
2227 /* otherwise just copy the type information */
2228 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2232 if (tree->opval.val->sym)
2234 /* if the undefined flag is set then give error message */
2235 if (tree->opval.val->sym->undefined)
2237 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2239 TTYPE (tree) = TETYPE (tree) =
2240 tree->opval.val->type = tree->opval.val->sym->type =
2241 tree->opval.val->etype = tree->opval.val->sym->etype =
2242 copyLinkChain (INTTYPE);
2247 /* if impilicit i.e. struct/union member then no type */
2248 if (tree->opval.val->sym->implicit)
2249 TTYPE (tree) = TETYPE (tree) = NULL;
2254 /* else copy the type */
2255 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2257 /* and mark it as referenced */
2258 tree->opval.val->sym->isref = 1;
2266 /* if type link for the case of cast */
2267 if (tree->type == EX_LINK)
2269 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2277 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2279 if (tree->left && tree->left->type == EX_OPERAND
2280 && (tree->left->opval.op == INC_OP
2281 || tree->left->opval.op == DEC_OP)
2282 && tree->left->left)
2284 tree->left->right = tree->left->left;
2285 tree->left->left = NULL;
2287 if (tree->right && tree->right->type == EX_OPERAND
2288 && (tree->right->opval.op == INC_OP
2289 || tree->right->opval.op == DEC_OP)
2290 && tree->right->left)
2292 tree->right->right = tree->right->left;
2293 tree->right->left = NULL;
2298 /* Before decorating the left branch we've to decide in dependence
2299 upon tree->opval.op, if resultType can be propagated */
2300 resultTypeProp = resultTypePropagate (tree, resultType);
2302 if (tree->opval.op == '?')
2303 dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2305 dtl = decorateType (tree->left, resultTypeProp);
2307 /* if an array node, we may need to swap branches */
2308 if (tree->opval.op == '[')
2310 /* determine which is the array & which the index */
2311 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2312 IS_INTEGRAL (LTYPE (tree)))
2314 ast *tempTree = tree->left;
2315 tree->left = tree->right;
2316 tree->right = tempTree;
2320 /* After decorating the left branch there's type information available
2321 in tree->left->?type. If the op is e.g. '=' we extract the type
2322 information from there and propagate it to the right branch. */
2323 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2325 switch (tree->opval.op)
2328 /* delay right side for '?' operator since conditional macro
2329 expansions might rely on this */
2333 /* decorate right side for CALL (parameter list) in processParms();
2334 there is resultType available */
2338 dtr = decorateType (tree->right, resultTypeProp);
2342 /* this is to take care of situations
2343 when the tree gets rewritten */
2344 if (dtl != tree->left)
2346 if (dtr != tree->right)
2348 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2352 /* depending on type of operator do */
2354 switch (tree->opval.op)
2356 /*------------------------------------------------------------------*/
2357 /*----------------------------*/
2359 /*----------------------------*/
2362 /* first check if this is a array or a pointer */
2363 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2365 werror (E_NEED_ARRAY_PTR, "[]");
2366 goto errorTreeReturn;
2369 /* check if the type of the idx */
2370 if (!IS_INTEGRAL (RTYPE (tree)))
2372 werror (E_IDX_NOT_INT);
2373 goto errorTreeReturn;
2376 /* if the left is an rvalue then error */
2379 werror (E_LVALUE_REQUIRED, "array access");
2380 goto errorTreeReturn;
2383 if (IS_LITERAL (RTYPE (tree)))
2385 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2386 int arraySize = DCL_ELEM (LTYPE (tree));
2387 if (arraySize && arrayIndex >= arraySize)
2389 werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2394 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2397 /*------------------------------------------------------------------*/
2398 /*----------------------------*/
2400 /*----------------------------*/
2402 /* if this is not a structure */
2403 if (!IS_STRUCT (LTYPE (tree)))
2405 werror (E_STRUCT_UNION, ".");
2406 goto errorTreeReturn;
2408 TTYPE (tree) = structElemType (LTYPE (tree),
2409 (tree->right->type == EX_VALUE ?
2410 tree->right->opval.val : NULL));
2411 TETYPE (tree) = getSpec (TTYPE (tree));
2414 /*------------------------------------------------------------------*/
2415 /*----------------------------*/
2416 /* struct/union pointer */
2417 /*----------------------------*/
2419 /* if not pointer to a structure */
2420 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2422 werror (E_PTR_REQD);
2423 goto errorTreeReturn;
2426 if (!IS_STRUCT (LTYPE (tree)->next))
2428 werror (E_STRUCT_UNION, "->");
2429 goto errorTreeReturn;
2432 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2433 (tree->right->type == EX_VALUE ?
2434 tree->right->opval.val : NULL));
2435 TETYPE (tree) = getSpec (TTYPE (tree));
2437 /* adjust the storage class */
2438 switch (DCL_TYPE(tree->left->ftype)) {
2440 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2443 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2446 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2449 SPEC_SCLS (TETYPE (tree)) = 0;
2452 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2455 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2458 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2461 SPEC_SCLS (TETYPE (tree)) = 0;
2468 /* This breaks with extern declarations, bitfields, and perhaps other */
2469 /* cases (gcse). Let's leave this optimization disabled for now and */
2470 /* ponder if there's a safe way to do this. -- EEP */
2472 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2473 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2475 /* If defined struct type at addr var
2476 then rewrite (&struct var)->member
2478 and define membertype at (addr+offsetof(struct var,member)) temp
2481 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2482 AST_SYMBOL(tree->right));
2484 sym = newSymbol(genSymName (0), 0);
2485 sym->type = TTYPE (tree);
2486 sym->etype = getSpec(sym->type);
2487 sym->lineDef = tree->lineno;
2490 SPEC_STAT (sym->etype) = 1;
2491 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2493 SPEC_ABSA(sym->etype) = 1;
2494 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2497 AST_VALUE (tree) = symbolVal(sym);
2500 tree->type = EX_VALUE;
2508 /*------------------------------------------------------------------*/
2509 /*----------------------------*/
2510 /* ++/-- operation */
2511 /*----------------------------*/
2515 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2516 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2517 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2518 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2527 /*------------------------------------------------------------------*/
2528 /*----------------------------*/
2530 /*----------------------------*/
2531 case '&': /* can be unary */
2532 /* if right is NULL then unary operation */
2533 if (tree->right) /* not an unary operation */
2536 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2538 werror (E_BITWISE_OP);
2539 werror (W_CONTINUE, "left & right types are ");
2540 printTypeChain (LTYPE (tree), stderr);
2541 fprintf (stderr, ",");
2542 printTypeChain (RTYPE (tree), stderr);
2543 fprintf (stderr, "\n");
2544 goto errorTreeReturn;
2547 /* if they are both literal */
2548 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2550 tree->type = EX_VALUE;
2551 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2552 valFromType (RETYPE (tree)), '&');
2554 tree->right = tree->left = NULL;
2555 TETYPE (tree) = tree->opval.val->etype;
2556 TTYPE (tree) = tree->opval.val->type;
2560 /* see if this is a GETHBIT operation if yes
2563 ast *otree = optimizeGetHbit (tree);
2566 return decorateType (otree, RESULT_CHECK);
2569 /* if left is a literal exchange left & right */
2570 if (IS_LITERAL (LTYPE (tree)))
2572 ast *tTree = tree->left;
2573 tree->left = tree->right;
2574 tree->right = tTree;
2577 /* if right is a literal and */
2578 /* we can find a 2nd literal in an and-tree then */
2579 /* rearrange the tree */
2580 if (IS_LITERAL (RTYPE (tree)))
2583 ast *litTree = searchLitOp (tree, &parent, "&");
2587 ast *tTree = litTree->left;
2588 litTree->left = tree->right;
2589 tree->right = tTree;
2590 /* both operands in litTree are literal now */
2591 decorateType (parent, resultType);
2595 LRVAL (tree) = RRVAL (tree) = 1;
2597 /* AND is signless so make signedness of literal equal */
2598 /* to signedness of left for better optimized code */
2599 if (IS_LITERAL (RTYPE (tree)) &&
2600 (getSize(LTYPE(tree)) == getSize(RTYPE(tree))) &&
2601 (SPEC_USIGN(LTYPE(tree)) != SPEC_USIGN(RTYPE(tree))) )
2603 SPEC_USIGN(RTYPE(tree)) = SPEC_USIGN(LTYPE(tree));
2606 TTYPE (tree) = computeType (LTYPE (tree),
2610 TETYPE (tree) = getSpec (TTYPE (tree));
2615 /*------------------------------------------------------------------*/
2616 /*----------------------------*/
2618 /*----------------------------*/
2619 p = newLink (DECLARATOR);
2620 /* if bit field then error */
2621 if (IS_BITVAR (tree->left->etype))
2623 werror (E_ILLEGAL_ADDR, "address of bit variable");
2624 goto errorTreeReturn;
2627 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2629 werror (E_ILLEGAL_ADDR, "address of register variable");
2630 goto errorTreeReturn;
2633 if (IS_FUNC (LTYPE (tree)))
2635 // this ought to be ignored
2636 return (tree->left);
2639 if (IS_LITERAL(LTYPE(tree)))
2641 werror (E_ILLEGAL_ADDR, "address of literal");
2642 goto errorTreeReturn;
2647 werror (E_LVALUE_REQUIRED, "address of");
2648 goto errorTreeReturn;
2651 DCL_TYPE (p) = POINTER;
2652 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2653 DCL_TYPE (p) = CPOINTER;
2654 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2655 DCL_TYPE (p) = FPOINTER;
2656 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2657 DCL_TYPE (p) = PPOINTER;
2658 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2659 DCL_TYPE (p) = IPOINTER;
2660 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2661 DCL_TYPE (p) = EEPPOINTER;
2662 else if (SPEC_OCLS(tree->left->etype))
2663 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2665 DCL_TYPE (p) = POINTER;
2667 if (IS_AST_SYM_VALUE (tree->left))
2669 AST_SYMBOL (tree->left)->addrtaken = 1;
2670 AST_SYMBOL (tree->left)->allocreq = 1;
2673 p->next = LTYPE (tree);
2675 TETYPE (tree) = getSpec (TTYPE (tree));
2680 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2681 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2683 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2684 AST_SYMBOL(tree->left->right));
2685 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2686 valueFromLit(element->offset));
2689 tree->type = EX_VALUE;
2690 tree->values.literalFromCast = 1;
2696 /*------------------------------------------------------------------*/
2697 /*----------------------------*/
2699 /*----------------------------*/
2701 /* if the rewrite succeeds then don't go any furthur */
2703 ast *wtree = optimizeRRCRLC (tree);
2705 return decorateType (wtree, RESULT_CHECK);
2707 wtree = optimizeSWAP (tree);
2709 return decorateType (wtree, RESULT_CHECK);
2712 /* if left is a literal exchange left & right */
2713 if (IS_LITERAL (LTYPE (tree)))
2715 ast *tTree = tree->left;
2716 tree->left = tree->right;
2717 tree->right = tTree;
2720 /* if right is a literal and */
2721 /* we can find a 2nd literal in an or-tree then */
2722 /* rearrange the tree */
2723 if (IS_LITERAL (RTYPE (tree)))
2726 ast *litTree = searchLitOp (tree, &parent, "|");
2730 ast *tTree = litTree->left;
2731 litTree->left = tree->right;
2732 tree->right = tTree;
2733 /* both operands in tTree are literal now */
2734 decorateType (parent, resultType);
2739 /*------------------------------------------------------------------*/
2740 /*----------------------------*/
2742 /*----------------------------*/
2744 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2746 werror (E_BITWISE_OP);
2747 werror (W_CONTINUE, "left & right types are ");
2748 printTypeChain (LTYPE (tree), stderr);
2749 fprintf (stderr, ",");
2750 printTypeChain (RTYPE (tree), stderr);
2751 fprintf (stderr, "\n");
2752 goto errorTreeReturn;
2755 /* if they are both literal then rewrite the tree */
2756 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2758 tree->type = EX_VALUE;
2759 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2760 valFromType (RETYPE (tree)),
2762 tree->right = tree->left = NULL;
2763 TETYPE (tree) = tree->opval.val->etype;
2764 TTYPE (tree) = tree->opval.val->type;
2768 /* if left is a literal exchange left & right */
2769 if (IS_LITERAL (LTYPE (tree)))
2771 ast *tTree = tree->left;
2772 tree->left = tree->right;
2773 tree->right = tTree;
2776 /* if right is a literal and */
2777 /* we can find a 2nd literal in a xor-tree then */
2778 /* rearrange the tree */
2779 if (IS_LITERAL (RTYPE (tree)) &&
2780 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2783 ast *litTree = searchLitOp (tree, &parent, "^");
2787 ast *tTree = litTree->left;
2788 litTree->left = tree->right;
2789 tree->right = tTree;
2790 /* both operands in litTree are literal now */
2791 decorateType (parent, resultType);
2795 /* OR/XOR are signless so make signedness of literal equal */
2796 /* to signedness of left for better optimized code */
2797 if (IS_LITERAL (RTYPE (tree)) &&
2798 (getSize(LTYPE(tree)) == getSize(RTYPE(tree))) &&
2799 (SPEC_USIGN(LTYPE(tree)) != SPEC_USIGN(RTYPE(tree))) )
2801 SPEC_USIGN(RTYPE(tree)) = SPEC_USIGN(LTYPE(tree));
2804 LRVAL (tree) = RRVAL (tree) = 1;
2806 TTYPE (tree) = computeType (LTYPE (tree),
2810 TETYPE (tree) = getSpec (TTYPE (tree));
2814 /*------------------------------------------------------------------*/
2815 /*----------------------------*/
2817 /*----------------------------*/
2819 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2821 werror (E_INVALID_OP, "divide");
2822 goto errorTreeReturn;
2824 /* if they are both literal then */
2825 /* rewrite the tree */
2826 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2828 tree->type = EX_VALUE;
2829 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2830 valFromType (RETYPE (tree)));
2831 tree->right = tree->left = NULL;
2832 TETYPE (tree) = getSpec (TTYPE (tree) =
2833 tree->opval.val->type);
2837 LRVAL (tree) = RRVAL (tree) = 1;
2839 TETYPE (tree) = getSpec (TTYPE (tree) =
2840 computeType (LTYPE (tree),
2845 /* if right is a literal and */
2846 /* left is also a division by a literal then */
2847 /* rearrange the tree */
2848 if (IS_LITERAL (RTYPE (tree))
2849 /* avoid infinite loop */
2850 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2853 ast *litTree = searchLitOp (tree, &parent, "/");
2856 if (IS_LITERAL (RTYPE (litTree)))
2860 litTree->right = newNode ('*',
2862 copyAst (tree->right));
2863 litTree->right->lineno = tree->lineno;
2865 tree->right->opval.val = constVal ("1");
2866 decorateType (parent, resultType);
2870 /* litTree->left is literal: no gcse possible.
2871 We can't call decorateType(parent, RESULT_CHECK), because
2872 this would cause an infinit loop. */
2873 parent->decorated = 1;
2874 decorateType (litTree, resultType);
2881 /*------------------------------------------------------------------*/
2882 /*----------------------------*/
2884 /*----------------------------*/
2886 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2888 werror (E_BITWISE_OP);
2889 werror (W_CONTINUE, "left & right types are ");
2890 printTypeChain (LTYPE (tree), stderr);
2891 fprintf (stderr, ",");
2892 printTypeChain (RTYPE (tree), stderr);
2893 fprintf (stderr, "\n");
2894 goto errorTreeReturn;
2896 /* if they are both literal then */
2897 /* rewrite the tree */
2898 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2900 tree->type = EX_VALUE;
2901 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2902 valFromType (RETYPE (tree)));
2903 tree->right = tree->left = NULL;
2904 TETYPE (tree) = getSpec (TTYPE (tree) =
2905 tree->opval.val->type);
2908 LRVAL (tree) = RRVAL (tree) = 1;
2909 TETYPE (tree) = getSpec (TTYPE (tree) =
2910 computeType (LTYPE (tree),
2916 /*------------------------------------------------------------------*/
2917 /*----------------------------*/
2918 /* address dereference */
2919 /*----------------------------*/
2920 case '*': /* can be unary : if right is null then unary operation */
2923 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2925 werror (E_PTR_REQD);
2926 goto errorTreeReturn;
2931 werror (E_LVALUE_REQUIRED, "pointer deref");
2932 goto errorTreeReturn;
2934 if (IS_ADDRESS_OF_OP(tree->left))
2936 /* replace *&obj with obj */
2937 return tree->left->left;
2939 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2940 TETYPE (tree) = getSpec (TTYPE (tree));
2941 /* adjust the storage class */
2942 switch (DCL_TYPE(tree->left->ftype)) {
2944 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2947 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2950 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2953 SPEC_SCLS (TETYPE (tree)) = 0;
2956 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2959 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2962 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2965 SPEC_SCLS (TETYPE (tree)) = 0;
2974 /*------------------------------------------------------------------*/
2975 /*----------------------------*/
2976 /* multiplication */
2977 /*----------------------------*/
2978 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2980 werror (E_INVALID_OP, "multiplication");
2981 goto errorTreeReturn;
2984 /* if they are both literal then */
2985 /* rewrite the tree */
2986 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2988 tree->type = EX_VALUE;
2989 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2990 valFromType (RETYPE (tree)));
2991 tree->right = tree->left = NULL;
2992 TETYPE (tree) = getSpec (TTYPE (tree) =
2993 tree->opval.val->type);
2997 /* if left is a literal exchange left & right */
2998 if (IS_LITERAL (LTYPE (tree)))
3000 ast *tTree = tree->left;
3001 tree->left = tree->right;
3002 tree->right = tTree;
3005 /* if right is a literal and */
3006 /* we can find a 2nd literal in a mul-tree then */
3007 /* rearrange the tree */
3008 if (IS_LITERAL (RTYPE (tree)))
3011 ast *litTree = searchLitOp (tree, &parent, "*");
3015 ast *tTree = litTree->left;
3016 litTree->left = tree->right;
3017 tree->right = tTree;
3018 /* both operands in litTree are literal now */
3019 decorateType (parent, resultType);
3023 LRVAL (tree) = RRVAL (tree) = 1;
3024 tree->left = addCast (tree->left, resultType, FALSE);
3025 tree->right = addCast (tree->right, resultType, FALSE);
3026 TETYPE (tree) = getSpec (TTYPE (tree) =
3027 computeType (LTYPE (tree),
3034 /*------------------------------------------------------------------*/
3035 /*----------------------------*/
3036 /* unary '+' operator */
3037 /*----------------------------*/
3042 if (!IS_ARITHMETIC (LTYPE (tree)))
3044 werror (E_UNARY_OP, '+');
3045 goto errorTreeReturn;
3048 /* if left is a literal then do it */
3049 if (IS_LITERAL (LTYPE (tree)))
3051 tree->type = EX_VALUE;
3052 tree->opval.val = valFromType (LETYPE (tree));
3054 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3058 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3062 /*------------------------------------------------------------------*/
3063 /*----------------------------*/
3065 /*----------------------------*/
3067 /* this is not a unary operation */
3068 /* if both pointers then problem */
3069 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3070 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3072 werror (E_PTR_PLUS_PTR);
3073 goto errorTreeReturn;
3076 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3077 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3079 werror (E_PLUS_INVALID, "+");
3080 goto errorTreeReturn;
3083 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3084 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3086 werror (E_PLUS_INVALID, "+");
3087 goto errorTreeReturn;
3089 /* if they are both literal then */
3090 /* rewrite the tree */
3091 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3093 tree->type = EX_VALUE;
3094 tree->left = addCast (tree->left, resultType, TRUE);
3095 tree->right = addCast (tree->right, resultType, TRUE);
3096 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3097 valFromType (RETYPE (tree)));
3098 tree->right = tree->left = NULL;
3099 TETYPE (tree) = getSpec (TTYPE (tree) =
3100 tree->opval.val->type);
3104 /* if the right is a pointer or left is a literal
3105 xchange left & right */
3106 if (IS_ARRAY (RTYPE (tree)) ||
3107 IS_PTR (RTYPE (tree)) ||
3108 IS_LITERAL (LTYPE (tree)))
3110 ast *tTree = tree->left;
3111 tree->left = tree->right;
3112 tree->right = tTree;
3115 /* if right is a literal and */
3116 /* left is also an addition/subtraction with a literal then */
3117 /* rearrange the tree */
3118 if (IS_LITERAL (RTYPE (tree)))
3120 ast *litTree, *parent;
3121 litTree = searchLitOp (tree, &parent, "+-");
3124 if (litTree->opval.op == '+')
3128 ast *tTree = litTree->left;
3129 litTree->left = tree->right;
3130 tree->right = tree->left;
3133 else if (litTree->opval.op == '-')
3135 if (IS_LITERAL (RTYPE (litTree)))
3139 ast *tTree = litTree->left;
3140 litTree->left = tree->right;
3141 tree->right = tTree;
3147 ast *tTree = litTree->right;
3148 litTree->right = tree->right;
3149 tree->right = tTree;
3150 litTree->opval.op = '+';
3151 tree->opval.op = '-';
3154 decorateType (parent, resultType);
3158 LRVAL (tree) = RRVAL (tree) = 1;
3159 /* if the left is a pointer */
3160 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3161 TETYPE (tree) = getSpec (TTYPE (tree) =
3165 tree->left = addCast (tree->left, resultType, TRUE);
3166 tree->right = addCast (tree->right, resultType, TRUE);
3167 TETYPE (tree) = getSpec (TTYPE (tree) =
3168 computeType (LTYPE (tree),
3176 /*------------------------------------------------------------------*/
3177 /*----------------------------*/
3179 /*----------------------------*/
3180 case '-': /* can be unary */
3181 /* if right is null then unary */
3185 if (!IS_ARITHMETIC (LTYPE (tree)))
3187 werror (E_UNARY_OP, tree->opval.op);
3188 goto errorTreeReturn;
3191 /* if left is a literal then do it */
3192 if (IS_LITERAL (LTYPE (tree)))
3194 tree->type = EX_VALUE;
3195 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3197 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3198 SPEC_USIGN(TETYPE(tree)) = 0;
3202 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3206 /*------------------------------------------------------------------*/
3207 /*----------------------------*/
3209 /*----------------------------*/
3211 if (!(IS_PTR (LTYPE (tree)) ||
3212 IS_ARRAY (LTYPE (tree)) ||
3213 IS_ARITHMETIC (LTYPE (tree))))
3215 werror (E_PLUS_INVALID, "-");
3216 goto errorTreeReturn;
3219 if (!(IS_PTR (RTYPE (tree)) ||
3220 IS_ARRAY (RTYPE (tree)) ||
3221 IS_ARITHMETIC (RTYPE (tree))))
3223 werror (E_PLUS_INVALID, "-");
3224 goto errorTreeReturn;
3227 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3228 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3229 IS_INTEGRAL (RTYPE (tree))))
3231 werror (E_PLUS_INVALID, "-");
3232 goto errorTreeReturn;
3235 /* if they are both literal then */
3236 /* rewrite the tree */
3237 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3239 tree->type = EX_VALUE;
3240 tree->left = addCast (tree->left, resultType, TRUE);
3241 tree->right = addCast (tree->right, resultType, TRUE);
3242 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3243 valFromType (RETYPE (tree)));
3244 tree->right = tree->left = NULL;
3245 TETYPE (tree) = getSpec (TTYPE (tree) =
3246 tree->opval.val->type);
3250 /* if the left & right are equal then zero */
3251 if (isAstEqual (tree->left, tree->right))
3253 tree->type = EX_VALUE;
3254 tree->left = tree->right = NULL;
3255 tree->opval.val = constVal ("0");
3256 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3260 /* if both of them are pointers or arrays then */
3261 /* the result is going to be an integer */
3262 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3263 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3264 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3266 /* if only the left is a pointer */
3267 /* then result is a pointer */
3268 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3269 TETYPE (tree) = getSpec (TTYPE (tree) =
3273 tree->left = addCast (tree->left, resultType, TRUE);
3274 tree->right = addCast (tree->right, resultType, TRUE);
3276 TETYPE (tree) = getSpec (TTYPE (tree) =
3277 computeType (LTYPE (tree),
3283 LRVAL (tree) = RRVAL (tree) = 1;
3285 /* if right is a literal and */
3286 /* left is also an addition/subtraction with a literal then */
3287 /* rearrange the tree */
3288 if (IS_LITERAL (RTYPE (tree))
3289 /* avoid infinite loop */
3290 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3292 ast *litTree, *litParent;
3293 litTree = searchLitOp (tree, &litParent, "+-");
3296 if (litTree->opval.op == '+')
3300 ast *tTree = litTree->left;
3301 litTree->left = litTree->right;
3302 litTree->right = tree->right;
3303 tree->right = tTree;
3304 tree->opval.op = '+';
3305 litTree->opval.op = '-';
3307 else if (litTree->opval.op == '-')
3309 if (IS_LITERAL (RTYPE (litTree)))
3313 ast *tTree = litTree->left;
3314 litTree->left = tree->right;
3315 tree->right = litParent->left;
3316 litParent->left = tTree;
3317 litTree->opval.op = '+';
3319 tree->decorated = 0;
3320 decorateType (tree, resultType);
3326 ast *tTree = litTree->right;
3327 litTree->right = tree->right;
3328 tree->right = tTree;
3331 decorateType (litParent, resultType);
3336 /*------------------------------------------------------------------*/
3337 /*----------------------------*/
3339 /*----------------------------*/
3341 /* can be only integral type */
3342 if (!IS_INTEGRAL (LTYPE (tree)))
3344 werror (E_UNARY_OP, tree->opval.op);
3345 goto errorTreeReturn;
3348 /* if left is a literal then do it */
3349 if (IS_LITERAL (LTYPE (tree)))
3351 tree->type = EX_VALUE;
3352 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3354 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3355 return addCast (tree, resultType, TRUE);
3357 tree->left = addCast (tree->left, resultType, TRUE);
3359 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3362 /*------------------------------------------------------------------*/
3363 /*----------------------------*/
3365 /*----------------------------*/
3367 /* can be pointer */
3368 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3369 !IS_PTR (LTYPE (tree)) &&
3370 !IS_ARRAY (LTYPE (tree)))
3372 werror (E_UNARY_OP, tree->opval.op);
3373 goto errorTreeReturn;
3376 /* if left is a literal then do it */
3377 if (IS_LITERAL (LTYPE (tree)))
3379 tree->type = EX_VALUE;
3380 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3382 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3386 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3389 /*------------------------------------------------------------------*/
3390 /*----------------------------*/
3392 /*----------------------------*/
3396 TTYPE (tree) = LTYPE (tree);
3397 TETYPE (tree) = LETYPE (tree);
3401 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3406 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3408 werror (E_SHIFT_OP_INVALID);
3409 werror (W_CONTINUE, "left & right types are ");
3410 printTypeChain (LTYPE (tree), stderr);
3411 fprintf (stderr, ",");
3412 printTypeChain (RTYPE (tree), stderr);
3413 fprintf (stderr, "\n");
3414 goto errorTreeReturn;
3417 /* make smaller type only if it's a LEFT_OP */
3418 if (tree->opval.op == LEFT_OP)
3419 tree->left = addCast (tree->left, resultType, TRUE);
3421 /* if they are both literal then */
3422 /* rewrite the tree */
3423 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3425 tree->type = EX_VALUE;
3426 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3427 valFromType (RETYPE (tree)),
3428 (tree->opval.op == LEFT_OP ? 1 : 0));
3429 tree->right = tree->left = NULL;
3430 TETYPE (tree) = getSpec (TTYPE (tree) =
3431 tree->opval.val->type);
3435 LRVAL (tree) = RRVAL (tree) = 1;
3436 if (tree->opval.op == LEFT_OP)
3438 TETYPE (tree) = getSpec (TTYPE (tree) =
3439 computeType (LTYPE (tree),
3446 /* no promotion necessary */
3447 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3448 if (IS_LITERAL (TTYPE (tree)))
3449 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3452 /* if only the right side is a literal & we are
3453 shifting more than size of the left operand then zero */
3454 if (IS_LITERAL (RTYPE (tree)) &&
3455 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3456 (getSize (TETYPE (tree)) * 8))
3458 if (tree->opval.op==LEFT_OP ||
3459 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3461 lineno=tree->lineno;
3462 werror (W_SHIFT_CHANGED,
3463 (tree->opval.op == LEFT_OP ? "left" : "right"));
3464 tree->type = EX_VALUE;
3465 tree->left = tree->right = NULL;
3466 tree->opval.val = constVal ("0");
3467 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3474 /*------------------------------------------------------------------*/
3475 /*----------------------------*/
3477 /*----------------------------*/
3478 case CAST: /* change the type */
3479 /* cannot cast to an aggregate type */
3480 if (IS_AGGREGATE (LTYPE (tree)))
3482 werror (E_CAST_ILLEGAL);
3483 goto errorTreeReturn;
3486 /* make sure the type is complete and sane */
3487 checkTypeSanity(LETYPE(tree), "(cast)");
3489 /* If code memory is read only, then pointers to code memory */
3490 /* implicitly point to constants -- make this explicit */
3492 sym_link *t = LTYPE(tree);
3493 while (t && t->next)
3495 if (IS_CODEPTR(t) && port->mem.code_ro)
3497 if (IS_SPEC(t->next))
3498 SPEC_CONST (t->next) = 1;
3500 DCL_PTR_CONST (t->next) = 1;
3507 /* if the right is a literal replace the tree */
3508 if (IS_LITERAL (RETYPE (tree))) {
3509 if (!IS_PTR (LTYPE (tree))) {
3510 tree->type = EX_VALUE;
3512 valCastLiteral (LTYPE (tree),
3513 floatFromVal (valFromType (RETYPE (tree))));
3516 TTYPE (tree) = tree->opval.val->type;
3517 tree->values.literalFromCast = 1;
3518 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3519 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3520 sym_link *rest = LTYPE(tree)->next;
3521 werror(W_LITERAL_GENERIC);
3522 TTYPE(tree) = newLink(DECLARATOR);
3523 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3524 TTYPE(tree)->next = rest;
3525 tree->left->opval.lnk = TTYPE(tree);
3528 TTYPE (tree) = LTYPE (tree);
3532 TTYPE (tree) = LTYPE (tree);
3536 #if 0 // this is already checked, now this could be explicit
3537 /* if pointer to struct then check names */
3538 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3539 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3540 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3542 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3543 SPEC_STRUCT(LETYPE(tree))->tag);
3546 if (IS_ADDRESS_OF_OP(tree->right)
3547 && IS_AST_SYM_VALUE (tree->right->left)
3548 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3550 tree->type = EX_VALUE;
3552 valCastLiteral (LTYPE (tree),
3553 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3554 TTYPE (tree) = tree->opval.val->type;
3555 TETYPE (tree) = getSpec (TTYPE (tree));
3558 tree->values.literalFromCast = 1;
3562 /* handle offsetof macro: */
3563 /* #define offsetof(TYPE, MEMBER) \ */
3564 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3565 if (IS_ADDRESS_OF_OP(tree->right)
3566 && IS_AST_OP (tree->right->left)
3567 && tree->right->left->opval.op == PTR_OP
3568 && IS_AST_OP (tree->right->left->left)
3569 && tree->right->left->left->opval.op == CAST
3570 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3572 symbol *element = getStructElement (
3573 SPEC_STRUCT (LETYPE(tree->right->left)),
3574 AST_SYMBOL(tree->right->left->right)
3578 tree->type = EX_VALUE;
3579 tree->opval.val = valCastLiteral (
3582 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3585 TTYPE (tree) = tree->opval.val->type;
3586 TETYPE (tree) = getSpec (TTYPE (tree));
3593 /* if the right is a literal replace the tree */
3594 if (IS_LITERAL (RETYPE (tree))) {
3596 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3597 /* rewrite (type *)litaddr
3599 and define type at litaddr temp
3600 (but only if type's storage class is not generic)
3602 ast *newTree = newNode ('&', NULL, NULL);
3605 TTYPE (newTree) = LTYPE (tree);
3606 TETYPE (newTree) = getSpec(LTYPE (tree));
3608 /* define a global symbol at the casted address*/
3609 sym = newSymbol(genSymName (0), 0);
3610 sym->type = LTYPE (tree)->next;
3612 sym->type = newLink (V_VOID);
3613 sym->etype = getSpec(sym->type);
3614 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3615 sym->lineDef = tree->lineno;
3618 SPEC_STAT (sym->etype) = 1;
3619 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3620 SPEC_ABSA(sym->etype) = 1;
3621 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3624 newTree->left = newAst_VALUE(symbolVal(sym));
3625 newTree->left->lineno = tree->lineno;
3626 LTYPE (newTree) = sym->type;
3627 LETYPE (newTree) = sym->etype;
3628 LLVAL (newTree) = 1;
3629 LRVAL (newTree) = 0;
3630 TLVAL (newTree) = 1;
3634 if (!IS_PTR (LTYPE (tree))) {
3635 tree->type = EX_VALUE;
3637 valCastLiteral (LTYPE (tree),
3638 floatFromVal (valFromType (RTYPE (tree))));
3639 TTYPE (tree) = tree->opval.val->type;
3642 tree->values.literalFromCast = 1;
3643 TETYPE (tree) = getSpec (TTYPE (tree));
3647 TTYPE (tree) = LTYPE (tree);
3651 TETYPE (tree) = getSpec (TTYPE (tree));
3655 /*------------------------------------------------------------------*/
3656 /*----------------------------*/
3657 /* logical &&, || */
3658 /*----------------------------*/
3661 /* each must be arithmetic type or be a pointer */
3662 if (!IS_PTR (LTYPE (tree)) &&
3663 !IS_ARRAY (LTYPE (tree)) &&
3664 !IS_INTEGRAL (LTYPE (tree)))
3666 werror (E_COMPARE_OP);
3667 goto errorTreeReturn;
3670 if (!IS_PTR (RTYPE (tree)) &&
3671 !IS_ARRAY (RTYPE (tree)) &&
3672 !IS_INTEGRAL (RTYPE (tree)))
3674 werror (E_COMPARE_OP);
3675 goto errorTreeReturn;
3677 /* if they are both literal then */
3678 /* rewrite the tree */
3679 if (IS_LITERAL (RTYPE (tree)) &&
3680 IS_LITERAL (LTYPE (tree)))
3682 tree->type = EX_VALUE;
3683 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3684 valFromType (RTYPE (tree)),
3686 tree->right = tree->left = NULL;
3687 TETYPE (tree) = getSpec (TTYPE (tree) =
3688 tree->opval.val->type);
3691 LRVAL (tree) = RRVAL (tree) = 1;
3692 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3695 /*------------------------------------------------------------------*/
3696 /*----------------------------*/
3697 /* comparison operators */
3698 /*----------------------------*/
3706 ast *lt = optimizeCompare (tree);
3712 /* if they are pointers they must be castable */
3713 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3715 if (tree->opval.op==EQ_OP &&
3716 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3717 // we cannot cast a gptr to a !gptr: switch the leaves
3718 struct ast *s=tree->left;
3719 tree->left=tree->right;
3722 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3724 werror (E_COMPARE_OP);
3725 fprintf (stderr, "comparing type ");
3726 printTypeChain (LTYPE (tree), stderr);
3727 fprintf (stderr, "to type ");
3728 printTypeChain (RTYPE (tree), stderr);
3729 fprintf (stderr, "\n");
3730 goto errorTreeReturn;
3733 /* else they should be promotable to one another */
3736 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3737 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3739 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3741 werror (E_COMPARE_OP);
3742 fprintf (stderr, "comparing type ");
3743 printTypeChain (LTYPE (tree), stderr);
3744 fprintf (stderr, "to type ");
3745 printTypeChain (RTYPE (tree), stderr);
3746 fprintf (stderr, "\n");
3747 goto errorTreeReturn;
3750 /* if unsigned value < 0 then always false */
3751 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3752 if (SPEC_USIGN(LETYPE(tree)) &&
3753 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3754 IS_LITERAL(RTYPE(tree)) &&
3755 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3757 if (tree->opval.op == '<')
3761 if (tree->opval.op == '>')
3763 if (resultType == RESULT_TYPE_IFX)
3765 /* the parent is an ifx: */
3766 /* if (unsigned value) */
3770 /* (unsigned value) ? 1 : 0 */
3771 tree->opval.op = '?';
3772 tree->right = newNode (':',
3773 newAst_VALUE (constVal ("1")),
3774 tree->right); /* val 0 */
3775 tree->right->lineno = tree->lineno;
3776 tree->right->left->lineno = tree->lineno;
3777 decorateType (tree->right, RESULT_CHECK);
3780 /* if they are both literal then */
3781 /* rewrite the tree */
3782 if (IS_LITERAL (RTYPE (tree)) &&
3783 IS_LITERAL (LTYPE (tree)))
3785 tree->type = EX_VALUE;
3786 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3787 valFromType (RETYPE (tree)),
3789 tree->right = tree->left = NULL;
3790 TETYPE (tree) = getSpec (TTYPE (tree) =
3791 tree->opval.val->type);
3794 LRVAL (tree) = RRVAL (tree) = 1;
3795 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3798 /*------------------------------------------------------------------*/
3799 /*----------------------------*/
3801 /*----------------------------*/
3802 case SIZEOF: /* evaluate wihout code generation */
3803 /* change the type to a integer */
3805 int size = getSize (tree->right->ftype);
3806 SNPRINTF(buffer, sizeof(buffer), "%d", size);
3807 if (!size && !IS_VOID(tree->right->ftype))
3808 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
3810 tree->type = EX_VALUE;
3811 tree->opval.val = constVal (buffer);
3812 tree->right = tree->left = NULL;
3813 TETYPE (tree) = getSpec (TTYPE (tree) =
3814 tree->opval.val->type);
3817 /*------------------------------------------------------------------*/
3818 /*----------------------------*/
3820 /*----------------------------*/
3822 /* return typeof enum value */
3823 tree->type = EX_VALUE;
3826 if (IS_SPEC(tree->right->ftype)) {
3827 switch (SPEC_NOUN(tree->right->ftype)) {
3829 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3830 else typeofv = TYPEOF_INT;
3833 typeofv = TYPEOF_FLOAT;
3836 typeofv = TYPEOF_CHAR;
3839 typeofv = TYPEOF_VOID;
3842 typeofv = TYPEOF_STRUCT;
3845 typeofv = TYPEOF_BITFIELD;
3848 typeofv = TYPEOF_BIT;
3851 typeofv = TYPEOF_SBIT;
3857 switch (DCL_TYPE(tree->right->ftype)) {
3859 typeofv = TYPEOF_POINTER;
3862 typeofv = TYPEOF_FPOINTER;
3865 typeofv = TYPEOF_CPOINTER;
3868 typeofv = TYPEOF_GPOINTER;
3871 typeofv = TYPEOF_PPOINTER;
3874 typeofv = TYPEOF_IPOINTER;
3877 typeofv = TYPEOF_ARRAY;
3880 typeofv = TYPEOF_FUNCTION;
3886 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3887 tree->opval.val = constVal (buffer);
3888 tree->right = tree->left = NULL;
3889 TETYPE (tree) = getSpec (TTYPE (tree) =
3890 tree->opval.val->type);
3893 /*------------------------------------------------------------------*/
3894 /*----------------------------*/
3895 /* conditional operator '?' */
3896 /*----------------------------*/
3898 /* the type is value of the colon operator (on the right) */
3899 assert (IS_COLON_OP (tree->right));
3900 /* if already known then replace the tree : optimizer will do it
3901 but faster to do it here */
3902 if (IS_LITERAL (LTYPE (tree)))
3904 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
3905 return decorateType (tree->right->left, resultTypeProp);
3907 return decorateType (tree->right->right, resultTypeProp);
3911 tree->right = decorateType (tree->right, resultTypeProp);
3912 TTYPE (tree) = RTYPE (tree);
3913 TETYPE (tree) = getSpec (TTYPE (tree));
3918 /* if they don't match we have a problem */
3919 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3921 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3922 goto errorTreeReturn;
3925 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
3926 resultType, tree->opval.op);
3927 TETYPE (tree) = getSpec (TTYPE (tree));
3931 #if 0 // assignment operators are converted by the parser
3932 /*------------------------------------------------------------------*/
3933 /*----------------------------*/
3934 /* assignment operators */
3935 /*----------------------------*/
3938 /* for these it must be both must be integral */
3939 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3940 !IS_ARITHMETIC (RTYPE (tree)))
3942 werror (E_OPS_INTEGRAL);
3943 goto errorTreeReturn;
3946 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3948 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3949 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3953 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3954 goto errorTreeReturn;
3965 /* for these it must be both must be integral */
3966 if (!IS_INTEGRAL (LTYPE (tree)) ||
3967 !IS_INTEGRAL (RTYPE (tree)))
3969 werror (E_OPS_INTEGRAL);
3970 goto errorTreeReturn;
3973 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3975 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3976 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3980 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3981 goto errorTreeReturn;
3987 /*------------------------------------------------------------------*/
3988 /*----------------------------*/
3990 /*----------------------------*/
3992 if (!(IS_PTR (LTYPE (tree)) ||
3993 IS_ARITHMETIC (LTYPE (tree))))
3995 werror (E_PLUS_INVALID, "-=");
3996 goto errorTreeReturn;
3999 if (!(IS_PTR (RTYPE (tree)) ||
4000 IS_ARITHMETIC (RTYPE (tree))))
4002 werror (E_PLUS_INVALID, "-=");
4003 goto errorTreeReturn;
4006 TETYPE (tree) = getSpec (TTYPE (tree) =
4007 computeType (LTYPE (tree),
4012 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4013 werror (E_CODE_WRITE, "-=");
4017 werror (E_LVALUE_REQUIRED, "-=");
4018 goto errorTreeReturn;
4024 /*------------------------------------------------------------------*/
4025 /*----------------------------*/
4027 /*----------------------------*/
4029 /* this is not a unary operation */
4030 /* if both pointers then problem */
4031 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4033 werror (E_PTR_PLUS_PTR);
4034 goto errorTreeReturn;
4037 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4039 werror (E_PLUS_INVALID, "+=");
4040 goto errorTreeReturn;
4043 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4045 werror (E_PLUS_INVALID, "+=");
4046 goto errorTreeReturn;
4049 TETYPE (tree) = getSpec (TTYPE (tree) =
4050 computeType (LTYPE (tree),
4055 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4056 werror (E_CODE_WRITE, "+=");
4060 werror (E_LVALUE_REQUIRED, "+=");
4061 goto errorTreeReturn;
4064 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_CHECK);
4065 tree->opval.op = '=';
4070 /*------------------------------------------------------------------*/
4071 /*----------------------------*/
4072 /* straight assignemnt */
4073 /*----------------------------*/
4075 /* cannot be an aggregate */
4076 if (IS_AGGREGATE (LTYPE (tree)))
4078 werror (E_AGGR_ASSIGN);
4079 goto errorTreeReturn;
4082 /* they should either match or be castable */
4083 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4085 werror (E_TYPE_MISMATCH, "assignment", " ");
4086 printFromToType(RTYPE(tree),LTYPE(tree));
4089 /* if the left side of the tree is of type void
4090 then report error */
4091 if (IS_VOID (LTYPE (tree)))
4093 werror (E_CAST_ZERO);
4094 printFromToType(RTYPE(tree), LTYPE(tree));
4097 TETYPE (tree) = getSpec (TTYPE (tree) =
4101 if (!tree->initMode ) {
4102 if (IS_CONSTANT(LTYPE(tree)))
4103 werror (E_CODE_WRITE, "=");
4107 werror (E_LVALUE_REQUIRED, "=");
4108 goto errorTreeReturn;
4113 /*------------------------------------------------------------------*/
4114 /*----------------------------*/
4115 /* comma operator */
4116 /*----------------------------*/
4118 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4121 /*------------------------------------------------------------------*/
4122 /*----------------------------*/
4124 /*----------------------------*/
4127 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4128 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4130 if (tree->left->opval.op == '*' && !tree->left->right)
4131 tree->left = tree->left->left;
4134 /* require a function or pointer to function */
4135 if (!IS_FUNC (LTYPE (tree))
4136 && !(IS_CODEPTR (LTYPE (tree)) && IS_FUNC (LTYPE (tree)->next)))
4138 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4139 goto errorTreeReturn;
4142 /* if there are parms, make sure that
4143 parms are decorate / process / reverse only once */
4145 !tree->right->decorated)
4150 if (IS_CODEPTR(LTYPE(tree)))
4151 functype = LTYPE (tree)->next;
4153 functype = LTYPE (tree);
4155 if (processParms (tree->left, FUNC_ARGS(functype),
4156 &tree->right, &parmNumber, TRUE))
4158 goto errorTreeReturn;
4161 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4162 !IFFUNC_ISBUILTIN(functype))
4164 reverseParms (tree->right);
4167 TTYPE (tree) = functype->next;
4168 TETYPE (tree) = getSpec (TTYPE (tree));
4172 /*------------------------------------------------------------------*/
4173 /*----------------------------*/
4174 /* return statement */
4175 /*----------------------------*/
4180 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4182 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4183 printFromToType (RTYPE(tree), currFunc->type->next);
4184 goto errorTreeReturn;
4187 if (IS_VOID (currFunc->type->next)
4189 !IS_VOID (RTYPE (tree)))
4191 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4192 goto errorTreeReturn;
4195 /* if there is going to be a casting required then add it */
4196 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4199 decorateType (newNode (CAST,
4200 newAst_LINK (copyLinkChain (currFunc->type->next)),
4210 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4212 werror (W_VOID_FUNC, currFunc->name);
4213 goto errorTreeReturn;
4216 TTYPE (tree) = TETYPE (tree) = NULL;
4219 /*------------------------------------------------------------------*/
4220 /*----------------------------*/
4221 /* switch statement */
4222 /*----------------------------*/
4224 /* the switch value must be an integer */
4225 if (!IS_INTEGRAL (LTYPE (tree)))
4227 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4228 goto errorTreeReturn;
4231 TTYPE (tree) = TETYPE (tree) = NULL;
4234 /*------------------------------------------------------------------*/
4235 /*----------------------------*/
4237 /*----------------------------*/
4239 tree->left = backPatchLabels (tree->left,
4242 TTYPE (tree) = TETYPE (tree) = NULL;
4245 /*------------------------------------------------------------------*/
4246 /*----------------------------*/
4248 /*----------------------------*/
4251 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_CHECK);
4252 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_CHECK);
4253 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_CHECK);
4255 /* if the for loop is reversible then
4256 reverse it otherwise do what we normally
4262 if (isLoopReversible (tree, &sym, &init, &end))
4263 return reverseLoop (tree, sym, init, end);
4265 return decorateType (createFor (AST_FOR (tree, trueLabel),
4266 AST_FOR (tree, continueLabel),
4267 AST_FOR (tree, falseLabel),
4268 AST_FOR (tree, condLabel),
4269 AST_FOR (tree, initExpr),
4270 AST_FOR (tree, condExpr),
4271 AST_FOR (tree, loopExpr),
4272 tree->left), RESULT_CHECK);
4275 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4276 "node PARAM shouldn't be processed here");
4277 /* but in processParams() */
4280 TTYPE (tree) = TETYPE (tree) = NULL;
4284 /* some error found this tree will be killed */
4286 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4287 tree->opval.op = NULLOP;
4293 /*-----------------------------------------------------------------*/
4294 /* sizeofOp - processes size of operation */
4295 /*-----------------------------------------------------------------*/
4297 sizeofOp (sym_link * type)
4302 /* make sure the type is complete and sane */
4303 checkTypeSanity(type, "(sizeof)");
4305 /* get the size and convert it to character */
4306 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4307 if (!size && !IS_VOID(type))
4308 werror (E_SIZEOF_INCOMPLETE_TYPE);
4310 /* now convert into value */
4311 return constVal (buff);
4315 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4316 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4317 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4318 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4319 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4320 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4321 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4323 /*-----------------------------------------------------------------*/
4324 /* backPatchLabels - change and or not operators to flow control */
4325 /*-----------------------------------------------------------------*/
4327 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4333 if (!(IS_ANDORNOT (tree)))
4336 /* if this an and */
4339 static int localLbl = 0;
4342 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4343 localLabel = newSymbol (buffer, NestLevel);
4345 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4347 /* if left is already a IFX then just change the if true label in that */
4348 if (!IS_IFX (tree->left))
4349 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4351 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4352 /* right is a IFX then just join */
4353 if (IS_IFX (tree->right))
4354 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4356 tree->right = createLabel (localLabel, tree->right);
4357 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4359 return newNode (NULLOP, tree->left, tree->right);
4362 /* if this is an or operation */
4365 static int localLbl = 0;
4368 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4369 localLabel = newSymbol (buffer, NestLevel);
4371 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4373 /* if left is already a IFX then just change the if true label in that */
4374 if (!IS_IFX (tree->left))
4375 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4377 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4378 /* right is a IFX then just join */
4379 if (IS_IFX (tree->right))
4380 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4382 tree->right = createLabel (localLabel, tree->right);
4383 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4385 return newNode (NULLOP, tree->left, tree->right);
4391 int wasnot = IS_NOT (tree->left);
4392 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4394 /* if the left is already a IFX */
4395 if (!IS_IFX (tree->left))
4396 tree->left = newNode (IFX, tree->left, NULL);
4400 tree->left->trueLabel = trueLabel;
4401 tree->left->falseLabel = falseLabel;
4405 tree->left->trueLabel = falseLabel;
4406 tree->left->falseLabel = trueLabel;
4413 tree->trueLabel = trueLabel;
4414 tree->falseLabel = falseLabel;
4421 /*-----------------------------------------------------------------*/
4422 /* createBlock - create expression tree for block */
4423 /*-----------------------------------------------------------------*/
4425 createBlock (symbol * decl, ast * body)
4429 /* if the block has nothing */
4433 ex = newNode (BLOCK, NULL, body);
4434 ex->values.sym = decl;
4436 ex->right = ex->right;
4442 /*-----------------------------------------------------------------*/
4443 /* createLabel - creates the expression tree for labels */
4444 /*-----------------------------------------------------------------*/
4446 createLabel (symbol * label, ast * stmnt)
4449 char name[SDCC_NAME_MAX + 1];
4452 /* must create fresh symbol if the symbol name */
4453 /* exists in the symbol table, since there can */
4454 /* be a variable with the same name as the labl */
4455 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4456 (csym->level == label->level))
4457 label = newSymbol (label->name, label->level);
4459 /* change the name before putting it in add _ */
4460 SNPRINTF(name, sizeof(name), "%s", label->name);
4462 /* put the label in the LabelSymbol table */
4463 /* but first check if a label of the same */
4465 if ((csym = findSym (LabelTab, NULL, name)))
4466 werror (E_DUPLICATE_LABEL, label->name);
4468 addSym (LabelTab, label, name, label->level, 0, 0);
4472 label->key = labelKey++;
4473 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4479 /*-----------------------------------------------------------------*/
4480 /* createCase - generates the parsetree for a case statement */
4481 /*-----------------------------------------------------------------*/
4483 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4485 char caseLbl[SDCC_NAME_MAX + 1];
4489 /* if the switch statement does not exist */
4490 /* then case is out of context */
4493 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4497 caseVal = decorateType (resolveSymbols (caseVal), RESULT_CHECK);
4498 /* if not a constant then error */
4499 if (!IS_LITERAL (caseVal->ftype))
4501 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4505 /* if not a integer than error */
4506 if (!IS_INTEGRAL (caseVal->ftype))
4508 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4512 /* find the end of the switch values chain */
4513 if (!(val = swStat->values.switchVals.swVals))
4514 swStat->values.switchVals.swVals = caseVal->opval.val;
4517 /* also order the cases according to value */
4519 int cVal = (int) floatFromVal (caseVal->opval.val);
4520 while (val && (int) floatFromVal (val) < cVal)
4526 /* if we reached the end then */
4529 pval->next = caseVal->opval.val;
4531 else if ((int) floatFromVal (val) == cVal)
4533 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4539 /* we found a value greater than */
4540 /* the current value we must add this */
4541 /* before the value */
4542 caseVal->opval.val->next = val;
4544 /* if this was the first in chain */
4545 if (swStat->values.switchVals.swVals == val)
4546 swStat->values.switchVals.swVals =
4549 pval->next = caseVal->opval.val;
4554 /* create the case label */
4555 SNPRINTF(caseLbl, sizeof(caseLbl),
4557 swStat->values.switchVals.swNum,
4558 (int) floatFromVal (caseVal->opval.val));
4560 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4565 /*-----------------------------------------------------------------*/
4566 /* createDefault - creates the parse tree for the default statement */
4567 /*-----------------------------------------------------------------*/
4569 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4571 char defLbl[SDCC_NAME_MAX + 1];
4573 /* if the switch statement does not exist */
4574 /* then case is out of context */
4577 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4581 if (swStat->values.switchVals.swDefault)
4583 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4588 /* turn on the default flag */
4589 swStat->values.switchVals.swDefault = 1;
4591 /* create the label */
4592 SNPRINTF (defLbl, sizeof(defLbl),
4593 "_default_%d", swStat->values.switchVals.swNum);
4594 return createLabel (newSymbol (defLbl, 0), stmnt);
4597 /*-----------------------------------------------------------------*/
4598 /* createIf - creates the parsetree for the if statement */
4599 /*-----------------------------------------------------------------*/
4601 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4603 static int Lblnum = 0;
4605 symbol *ifTrue, *ifFalse, *ifEnd;
4607 /* if neither exists */
4608 if (!elseBody && !ifBody) {
4609 // if there are no side effects (i++, j() etc)
4610 if (!hasSEFcalls(condAst)) {
4615 /* create the labels */
4616 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4617 ifFalse = newSymbol (buffer, NestLevel);
4618 /* if no else body then end == false */
4623 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4624 ifEnd = newSymbol (buffer, NestLevel);
4627 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4628 ifTrue = newSymbol (buffer, NestLevel);
4632 /* attach the ifTrue label to the top of it body */
4633 ifBody = createLabel (ifTrue, ifBody);
4634 /* attach a goto end to the ifBody if else is present */
4637 ifBody = newNode (NULLOP, ifBody,
4639 newAst_VALUE (symbolVal (ifEnd)),
4641 /* put the elseLabel on the else body */
4642 elseBody = createLabel (ifFalse, elseBody);
4643 /* out the end at the end of the body */
4644 elseBody = newNode (NULLOP,
4646 createLabel (ifEnd, NULL));
4650 ifBody = newNode (NULLOP, ifBody,
4651 createLabel (ifFalse, NULL));
4653 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4654 if (IS_IFX (condAst))
4657 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4659 return newNode (NULLOP, ifTree,
4660 newNode (NULLOP, ifBody, elseBody));
4664 /*-----------------------------------------------------------------*/
4665 /* createDo - creates parse tree for do */
4668 /* _docontinue_n: */
4669 /* condition_expression +-> trueLabel -> _dobody_n */
4671 /* +-> falseLabel-> _dobreak_n */
4673 /*-----------------------------------------------------------------*/
4675 createDo (symbol * trueLabel, symbol * continueLabel,
4676 symbol * falseLabel, ast * condAst, ast * doBody)
4681 /* if the body does not exist then it is simple */
4684 condAst = backPatchLabels (condAst, continueLabel, NULL);
4685 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4686 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4687 doTree->trueLabel = continueLabel;
4688 doTree->falseLabel = NULL;
4692 /* otherwise we have a body */
4693 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4695 /* attach the body label to the top */
4696 doBody = createLabel (trueLabel, doBody);
4697 /* attach the continue label to end of body */
4698 doBody = newNode (NULLOP, doBody,
4699 createLabel (continueLabel, NULL));
4701 /* now put the break label at the end */
4702 if (IS_IFX (condAst))
4705 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4707 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4709 /* putting it together */
4710 return newNode (NULLOP, doBody, doTree);
4713 /*-----------------------------------------------------------------*/
4714 /* createFor - creates parse tree for 'for' statement */
4717 /* condExpr +-> trueLabel -> _forbody_n */
4719 /* +-> falseLabel-> _forbreak_n */
4722 /* _forcontinue_n: */
4724 /* goto _forcond_n ; */
4726 /*-----------------------------------------------------------------*/
4728 createFor (symbol * trueLabel, symbol * continueLabel,
4729 symbol * falseLabel, symbol * condLabel,
4730 ast * initExpr, ast * condExpr, ast * loopExpr,
4735 /* if loopexpression not present then we can generate it */
4736 /* the same way as a while */
4738 return newNode (NULLOP, initExpr,
4739 createWhile (trueLabel, continueLabel,
4740 falseLabel, condExpr, forBody));
4741 /* vanilla for statement */
4742 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4744 if (condExpr && !IS_IFX (condExpr))
4745 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4748 /* attach condition label to condition */
4749 condExpr = createLabel (condLabel, condExpr);
4751 /* attach body label to body */
4752 forBody = createLabel (trueLabel, forBody);
4754 /* attach continue to forLoop expression & attach */
4755 /* goto the forcond @ and of loopExpression */
4756 loopExpr = createLabel (continueLabel,
4760 newAst_VALUE (symbolVal (condLabel)),
4762 /* now start putting them together */
4763 forTree = newNode (NULLOP, initExpr, condExpr);
4764 forTree = newNode (NULLOP, forTree, forBody);
4765 forTree = newNode (NULLOP, forTree, loopExpr);
4766 /* finally add the break label */
4767 forTree = newNode (NULLOP, forTree,
4768 createLabel (falseLabel, NULL));
4772 /*-----------------------------------------------------------------*/
4773 /* createWhile - creates parse tree for while statement */
4774 /* the while statement will be created as follows */
4776 /* _while_continue_n: */
4777 /* condition_expression +-> trueLabel -> _while_boby_n */
4779 /* +-> falseLabel -> _while_break_n */
4780 /* _while_body_n: */
4782 /* goto _while_continue_n */
4783 /* _while_break_n: */
4784 /*-----------------------------------------------------------------*/
4786 createWhile (symbol * trueLabel, symbol * continueLabel,
4787 symbol * falseLabel, ast * condExpr, ast * whileBody)
4791 /* put the continue label */
4792 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4793 condExpr = createLabel (continueLabel, condExpr);
4794 condExpr->lineno = 0;
4796 /* put the body label in front of the body */
4797 whileBody = createLabel (trueLabel, whileBody);
4798 whileBody->lineno = 0;
4799 /* put a jump to continue at the end of the body */
4800 /* and put break label at the end of the body */
4801 whileBody = newNode (NULLOP,
4804 newAst_VALUE (symbolVal (continueLabel)),
4805 createLabel (falseLabel, NULL)));
4807 /* put it all together */
4808 if (IS_IFX (condExpr))
4809 whileTree = condExpr;
4812 whileTree = newNode (IFX, condExpr, NULL);
4813 /* put the true & false labels in place */
4814 whileTree->trueLabel = trueLabel;
4815 whileTree->falseLabel = falseLabel;
4818 return newNode (NULLOP, whileTree, whileBody);
4821 /*-----------------------------------------------------------------*/
4822 /* optimizeGetHbit - get highest order bit of the expression */
4823 /*-----------------------------------------------------------------*/
4825 optimizeGetHbit (ast * tree)
4828 /* if this is not a bit and */
4829 if (!IS_BITAND (tree))
4832 /* will look for tree of the form
4833 ( expr >> ((sizeof expr) -1) ) & 1 */
4834 if (!IS_AST_LIT_VALUE (tree->right))
4837 if (AST_LIT_VALUE (tree->right) != 1)
4840 if (!IS_RIGHT_OP (tree->left))
4843 if (!IS_AST_LIT_VALUE (tree->left->right))
4846 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4847 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4850 /* make sure the port supports GETHBIT */
4851 if (port->hasExtBitOp
4852 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4855 return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_CHECK);
4859 /*-----------------------------------------------------------------*/
4860 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4861 /*-----------------------------------------------------------------*/
4863 optimizeRRCRLC (ast * root)
4865 /* will look for trees of the form
4866 (?expr << 1) | (?expr >> 7) or
4867 (?expr >> 7) | (?expr << 1) will make that
4868 into a RLC : operation ..
4870 (?expr >> 1) | (?expr << 7) or
4871 (?expr << 7) | (?expr >> 1) will make that
4872 into a RRC operation
4873 note : by 7 I mean (number of bits required to hold the
4875 /* if the root operations is not a | operation the not */
4876 if (!IS_BITOR (root))
4879 /* I have to think of a better way to match patterns this sucks */
4880 /* that aside let start looking for the first case : I use a the
4881 negative check a lot to improve the efficiency */
4882 /* (?expr << 1) | (?expr >> 7) */
4883 if (IS_LEFT_OP (root->left) &&
4884 IS_RIGHT_OP (root->right))
4887 if (!SPEC_USIGN (TETYPE (root->left->left)))
4890 if (!IS_AST_LIT_VALUE (root->left->right) ||
4891 !IS_AST_LIT_VALUE (root->right->right))
4894 /* make sure it is the same expression */
4895 if (!isAstEqual (root->left->left,
4899 if (AST_LIT_VALUE (root->left->right) != 1)
4902 if (AST_LIT_VALUE (root->right->right) !=
4903 (getSize (TTYPE (root->left->left)) * 8 - 1))
4906 /* make sure the port supports RLC */
4907 if (port->hasExtBitOp
4908 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4911 /* whew got the first case : create the AST */
4912 return newNode (RLC, root->left->left, NULL);
4916 /* check for second case */
4917 /* (?expr >> 7) | (?expr << 1) */
4918 if (IS_LEFT_OP (root->right) &&
4919 IS_RIGHT_OP (root->left))
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 symbol */
4930 if (!isAstEqual (root->left->left,
4934 if (AST_LIT_VALUE (root->right->right) != 1)
4937 if (AST_LIT_VALUE (root->left->right) !=
4938 (getSize (TTYPE (root->left->left)) * 8 - 1))
4941 /* make sure the port supports RLC */
4942 if (port->hasExtBitOp
4943 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4946 /* whew got the first case : create the AST */
4947 return newNode (RLC, root->left->left, NULL);
4952 /* third case for RRC */
4953 /* (?symbol >> 1) | (?symbol << 7) */
4954 if (IS_LEFT_OP (root->right) &&
4955 IS_RIGHT_OP (root->left))
4958 if (!SPEC_USIGN (TETYPE (root->left->left)))
4961 if (!IS_AST_LIT_VALUE (root->left->right) ||
4962 !IS_AST_LIT_VALUE (root->right->right))
4965 /* make sure it is the same symbol */
4966 if (!isAstEqual (root->left->left,
4970 if (AST_LIT_VALUE (root->left->right) != 1)
4973 if (AST_LIT_VALUE (root->right->right) !=
4974 (getSize (TTYPE (root->left->left)) * 8 - 1))
4977 /* make sure the port supports RRC */
4978 if (port->hasExtBitOp
4979 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4982 /* whew got the first case : create the AST */
4983 return newNode (RRC, root->left->left, NULL);
4987 /* fourth and last case for now */
4988 /* (?symbol << 7) | (?symbol >> 1) */
4989 if (IS_RIGHT_OP (root->right) &&
4990 IS_LEFT_OP (root->left))
4993 if (!SPEC_USIGN (TETYPE (root->left->left)))
4996 if (!IS_AST_LIT_VALUE (root->left->right) ||
4997 !IS_AST_LIT_VALUE (root->right->right))
5000 /* make sure it is the same symbol */
5001 if (!isAstEqual (root->left->left,
5005 if (AST_LIT_VALUE (root->right->right) != 1)
5008 if (AST_LIT_VALUE (root->left->right) !=
5009 (getSize (TTYPE (root->left->left)) * 8 - 1))
5012 /* make sure the port supports RRC */
5013 if (port->hasExtBitOp
5014 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5017 /* whew got the first case : create the AST */
5018 return newNode (RRC, root->left->left, NULL);
5022 /* not found return root */
5026 /*-----------------------------------------------------------------*/
5027 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
5028 /*-----------------------------------------------------------------*/
5030 optimizeSWAP (ast * root)
5032 /* will look for trees of the form
5033 (?expr << 4) | (?expr >> 4) or
5034 (?expr >> 4) | (?expr << 4) will make that
5035 into a SWAP : operation ..
5036 note : by 4 I mean (number of bits required to hold the
5038 /* if the root operations is not a | operation the not */
5039 if (!IS_BITOR (root))
5042 /* (?expr << 4) | (?expr >> 4) */
5043 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5044 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5047 if (!SPEC_USIGN (TETYPE (root->left->left)))
5050 if (!IS_AST_LIT_VALUE (root->left->right) ||
5051 !IS_AST_LIT_VALUE (root->right->right))
5054 /* make sure it is the same expression */
5055 if (!isAstEqual (root->left->left,
5059 if (AST_LIT_VALUE (root->left->right) !=
5060 (getSize (TTYPE (root->left->left)) * 4))
5063 if (AST_LIT_VALUE (root->right->right) !=
5064 (getSize (TTYPE (root->left->left)) * 4))
5067 /* make sure the port supports SWAP */
5068 if (port->hasExtBitOp
5069 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5072 /* found it : create the AST */
5073 return newNode (SWAP, root->left->left, NULL);
5077 /* not found return root */
5081 /*-----------------------------------------------------------------*/
5082 /* optimizeCompare - otimizes compares for bit variables */
5083 /*-----------------------------------------------------------------*/
5085 optimizeCompare (ast * root)
5087 ast *optExpr = NULL;
5090 unsigned int litValue;
5092 /* if nothing then return nothing */
5096 /* if not a compare op then do leaves */
5097 if (!IS_COMPARE_OP (root))
5099 root->left = optimizeCompare (root->left);
5100 root->right = optimizeCompare (root->right);
5104 /* if left & right are the same then depending
5105 of the operation do */
5106 if (isAstEqual (root->left, root->right))
5108 switch (root->opval.op)
5113 optExpr = newAst_VALUE (constVal ("0"));
5118 optExpr = newAst_VALUE (constVal ("1"));
5122 return decorateType (optExpr, RESULT_CHECK);
5125 vleft = (root->left->type == EX_VALUE ?
5126 root->left->opval.val : NULL);
5128 vright = (root->right->type == EX_VALUE ?
5129 root->right->opval.val : NULL);
5131 /* if left is a BITVAR in BITSPACE */
5132 /* and right is a LITERAL then opt- */
5133 /* imize else do nothing */
5134 if (vleft && vright &&
5135 IS_BITVAR (vleft->etype) &&
5136 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5137 IS_LITERAL (vright->etype))
5140 /* if right side > 1 then comparison may never succeed */
5141 if ((litValue = (int) floatFromVal (vright)) > 1)
5143 werror (W_BAD_COMPARE);
5149 switch (root->opval.op)
5151 case '>': /* bit value greater than 1 cannot be */
5152 werror (W_BAD_COMPARE);
5156 case '<': /* bit value < 1 means 0 */
5158 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5161 case LE_OP: /* bit value <= 1 means no check */
5162 optExpr = newAst_VALUE (vright);
5165 case GE_OP: /* bit value >= 1 means only check for = */
5167 optExpr = newAst_VALUE (vleft);
5172 { /* literal is zero */
5173 switch (root->opval.op)
5175 case '<': /* bit value < 0 cannot be */
5176 werror (W_BAD_COMPARE);
5180 case '>': /* bit value > 0 means 1 */
5182 optExpr = newAst_VALUE (vleft);
5185 case LE_OP: /* bit value <= 0 means no check */
5186 case GE_OP: /* bit value >= 0 means no check */
5187 werror (W_BAD_COMPARE);
5191 case EQ_OP: /* bit == 0 means ! of bit */
5192 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5196 return decorateType (resolveSymbols (optExpr), RESULT_CHECK);
5197 } /* end-of-if of BITVAR */
5202 /*-----------------------------------------------------------------*/
5203 /* addSymToBlock : adds the symbol to the first block we find */
5204 /*-----------------------------------------------------------------*/
5206 addSymToBlock (symbol * sym, ast * tree)
5208 /* reached end of tree or a leaf */
5209 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5213 if (IS_AST_OP (tree) &&
5214 tree->opval.op == BLOCK)
5217 symbol *lsym = copySymbol (sym);
5219 lsym->next = AST_VALUES (tree, sym);
5220 AST_VALUES (tree, sym) = lsym;
5224 addSymToBlock (sym, tree->left);
5225 addSymToBlock (sym, tree->right);
5228 /*-----------------------------------------------------------------*/
5229 /* processRegParms - do processing for register parameters */
5230 /*-----------------------------------------------------------------*/
5232 processRegParms (value * args, ast * body)
5236 if (IS_REGPARM (args->etype))
5237 addSymToBlock (args->sym, body);
5242 /*-----------------------------------------------------------------*/
5243 /* resetParmKey - resets the operandkeys for the symbols */
5244 /*-----------------------------------------------------------------*/
5245 DEFSETFUNC (resetParmKey)
5256 /*-----------------------------------------------------------------*/
5257 /* createFunction - This is the key node that calls the iCode for */
5258 /* generating the code for a function. Note code */
5259 /* is generated function by function, later when */
5260 /* add inter-procedural analysis this will change */
5261 /*-----------------------------------------------------------------*/
5263 createFunction (symbol * name, ast * body)
5269 iCode *piCode = NULL;
5271 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5272 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5274 /* if check function return 0 then some problem */
5275 if (checkFunction (name, NULL) == 0)
5278 /* create a dummy block if none exists */
5280 body = newNode (BLOCK, NULL, NULL);
5284 /* check if the function name already in the symbol table */
5285 if ((csym = findSym (SymbolTab, NULL, name->name)))
5288 /* special case for compiler defined functions
5289 we need to add the name to the publics list : this
5290 actually means we are now compiling the compiler
5294 addSet (&publics, name);
5300 allocVariables (name);
5302 name->lastLine = mylineno;
5305 /* set the stack pointer */
5306 /* PENDING: check this for the mcs51 */
5307 stackPtr = -port->stack.direction * port->stack.call_overhead;
5308 if (IFFUNC_ISISR (name->type))
5309 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5310 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5311 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5313 xstackPtr = -port->stack.direction * port->stack.call_overhead;
5315 fetype = getSpec (name->type); /* get the specifier for the function */
5316 /* if this is a reentrant function then */
5317 if (IFFUNC_ISREENT (name->type))
5320 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5322 /* do processing for parameters that are passed in registers */
5323 processRegParms (FUNC_ARGS(name->type), body);
5325 /* set the stack pointer */
5329 /* allocate & autoinit the block variables */
5330 processBlockVars (body, &stack, ALLOCATE);
5332 /* save the stack information */
5333 if (options.useXstack)
5334 name->xstack = SPEC_STAK (fetype) = stack;
5336 name->stack = SPEC_STAK (fetype) = stack;
5338 /* name needs to be mangled */
5339 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5341 body = resolveSymbols (body); /* resolve the symbols */
5342 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5345 ex = newAst_VALUE (symbolVal (name)); /* create name */
5346 ex = newNode (FUNCTION, ex, body);
5347 ex->values.args = FUNC_ARGS(name->type);
5349 if (options.dump_tree) PA(ex);
5352 werror (E_FUNC_NO_CODE, name->name);
5356 /* create the node & generate intermediate code */
5358 codeOutFile = code->oFile;
5359 piCode = iCodeFromAst (ex);
5363 werror (E_FUNC_NO_CODE, name->name);
5367 eBBlockFromiCode (piCode);
5369 /* if there are any statics then do them */
5372 GcurMemmap = statsg;
5373 codeOutFile = statsg->oFile;
5374 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_CHECK)));
5380 /* dealloc the block variables */
5381 processBlockVars (body, &stack, DEALLOCATE);
5382 outputDebugStackSymbols();
5383 /* deallocate paramaters */
5384 deallocParms (FUNC_ARGS(name->type));
5386 if (IFFUNC_ISREENT (name->type))
5389 /* we are done freeup memory & cleanup */
5391 if (port->reset_labelKey) labelKey = 1;
5393 FUNC_HASBODY(name->type) = 1;
5394 addSet (&operKeyReset, name);
5395 applyToSet (operKeyReset, resetParmKey);
5400 cleanUpLevel (LabelTab, 0);
5401 cleanUpBlock (StructTab, 1);
5402 cleanUpBlock (TypedefTab, 1);
5404 xstack->syms = NULL;
5405 istack->syms = NULL;
5410 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5411 /*-----------------------------------------------------------------*/
5412 /* ast_print : prints the ast (for debugging purposes) */
5413 /*-----------------------------------------------------------------*/
5415 void ast_print (ast * tree, FILE *outfile, int indent)
5420 /* can print only decorated trees */
5421 if (!tree->decorated) return;
5423 /* if any child is an error | this one is an error do nothing */
5424 if (tree->isError ||
5425 (tree->left && tree->left->isError) ||
5426 (tree->right && tree->right->isError)) {
5427 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5431 /* print the line */
5432 /* if not block & function */
5433 if (tree->type == EX_OP &&
5434 (tree->opval.op != FUNCTION &&
5435 tree->opval.op != BLOCK &&
5436 tree->opval.op != NULLOP)) {
5439 if (tree->opval.op == FUNCTION) {
5441 value *args=FUNC_ARGS(tree->left->opval.val->type);
5442 fprintf(outfile,"FUNCTION (%s=%p) type (",
5443 tree->left->opval.val->name, tree);
5444 printTypeChain (tree->left->opval.val->type->next,outfile);
5445 fprintf(outfile,") args (");
5448 fprintf (outfile, ", ");
5450 printTypeChain (args ? args->type : NULL, outfile);
5452 args= args ? args->next : NULL;
5454 fprintf(outfile,")\n");
5455 ast_print(tree->left,outfile,indent);
5456 ast_print(tree->right,outfile,indent);
5459 if (tree->opval.op == BLOCK) {
5460 symbol *decls = tree->values.sym;
5461 INDENT(indent,outfile);
5462 fprintf(outfile,"{\n");
5464 INDENT(indent+2,outfile);
5465 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5466 decls->name, decls);
5467 printTypeChain(decls->type,outfile);
5468 fprintf(outfile,")\n");
5470 decls = decls->next;
5472 ast_print(tree->right,outfile,indent+2);
5473 INDENT(indent,outfile);
5474 fprintf(outfile,"}\n");
5477 if (tree->opval.op == NULLOP) {
5478 ast_print(tree->left,outfile,indent);
5479 ast_print(tree->right,outfile,indent);
5482 INDENT(indent,outfile);
5484 /*------------------------------------------------------------------*/
5485 /*----------------------------*/
5486 /* leaf has been reached */
5487 /*----------------------------*/
5488 /* if this is of type value */
5489 /* just get the type */
5490 if (tree->type == EX_VALUE) {
5492 if (IS_LITERAL (tree->opval.val->etype)) {
5493 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5494 if (SPEC_USIGN (tree->opval.val->etype))
5495 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5497 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5498 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5499 floatFromVal(tree->opval.val));
5500 } else if (tree->opval.val->sym) {
5501 /* if the undefined flag is set then give error message */
5502 if (tree->opval.val->sym->undefined) {
5503 fprintf(outfile,"UNDEFINED SYMBOL ");
5505 fprintf(outfile,"SYMBOL ");
5507 fprintf(outfile,"(%s=%p)",
5508 tree->opval.val->sym->name,tree);
5511 fprintf(outfile," type (");
5512 printTypeChain(tree->ftype,outfile);
5513 fprintf(outfile,")\n");
5515 fprintf(outfile,"\n");
5520 /* if type link for the case of cast */
5521 if (tree->type == EX_LINK) {
5522 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5523 printTypeChain(tree->opval.lnk,outfile);
5524 fprintf(outfile,")\n");
5529 /* depending on type of operator do */
5531 switch (tree->opval.op) {
5532 /*------------------------------------------------------------------*/
5533 /*----------------------------*/
5535 /*----------------------------*/
5537 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5538 printTypeChain(tree->ftype,outfile);
5539 fprintf(outfile,")\n");
5540 ast_print(tree->left,outfile,indent+2);
5541 ast_print(tree->right,outfile,indent+2);
5544 /*------------------------------------------------------------------*/
5545 /*----------------------------*/
5547 /*----------------------------*/
5549 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5550 printTypeChain(tree->ftype,outfile);
5551 fprintf(outfile,")\n");
5552 ast_print(tree->left,outfile,indent+2);
5553 ast_print(tree->right,outfile,indent+2);
5556 /*------------------------------------------------------------------*/
5557 /*----------------------------*/
5558 /* struct/union pointer */
5559 /*----------------------------*/
5561 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5562 printTypeChain(tree->ftype,outfile);
5563 fprintf(outfile,")\n");
5564 ast_print(tree->left,outfile,indent+2);
5565 ast_print(tree->right,outfile,indent+2);
5568 /*------------------------------------------------------------------*/
5569 /*----------------------------*/
5570 /* ++/-- operation */
5571 /*----------------------------*/
5574 fprintf(outfile,"post-");
5576 fprintf(outfile,"pre-");
5577 fprintf(outfile,"INC_OP (%p) type (",tree);
5578 printTypeChain(tree->ftype,outfile);
5579 fprintf(outfile,")\n");
5580 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5581 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5586 fprintf(outfile,"post-");
5588 fprintf(outfile,"pre-");
5589 fprintf(outfile,"DEC_OP (%p) type (",tree);
5590 printTypeChain(tree->ftype,outfile);
5591 fprintf(outfile,")\n");
5592 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5593 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5596 /*------------------------------------------------------------------*/
5597 /*----------------------------*/
5599 /*----------------------------*/
5602 fprintf(outfile,"& (%p) type (",tree);
5603 printTypeChain(tree->ftype,outfile);
5604 fprintf(outfile,")\n");
5605 ast_print(tree->left,outfile,indent+2);
5606 ast_print(tree->right,outfile,indent+2);
5608 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5609 printTypeChain(tree->ftype,outfile);
5610 fprintf(outfile,")\n");
5611 ast_print(tree->left,outfile,indent+2);
5612 ast_print(tree->right,outfile,indent+2);
5615 /*----------------------------*/
5617 /*----------------------------*/
5619 fprintf(outfile,"OR (%p) type (",tree);
5620 printTypeChain(tree->ftype,outfile);
5621 fprintf(outfile,")\n");
5622 ast_print(tree->left,outfile,indent+2);
5623 ast_print(tree->right,outfile,indent+2);
5625 /*------------------------------------------------------------------*/
5626 /*----------------------------*/
5628 /*----------------------------*/
5630 fprintf(outfile,"XOR (%p) type (",tree);
5631 printTypeChain(tree->ftype,outfile);
5632 fprintf(outfile,")\n");
5633 ast_print(tree->left,outfile,indent+2);
5634 ast_print(tree->right,outfile,indent+2);
5637 /*------------------------------------------------------------------*/
5638 /*----------------------------*/
5640 /*----------------------------*/
5642 fprintf(outfile,"DIV (%p) type (",tree);
5643 printTypeChain(tree->ftype,outfile);
5644 fprintf(outfile,")\n");
5645 ast_print(tree->left,outfile,indent+2);
5646 ast_print(tree->right,outfile,indent+2);
5648 /*------------------------------------------------------------------*/
5649 /*----------------------------*/
5651 /*----------------------------*/
5653 fprintf(outfile,"MOD (%p) type (",tree);
5654 printTypeChain(tree->ftype,outfile);
5655 fprintf(outfile,")\n");
5656 ast_print(tree->left,outfile,indent+2);
5657 ast_print(tree->right,outfile,indent+2);
5660 /*------------------------------------------------------------------*/
5661 /*----------------------------*/
5662 /* address dereference */
5663 /*----------------------------*/
5664 case '*': /* can be unary : if right is null then unary operation */
5666 fprintf(outfile,"DEREF (%p) type (",tree);
5667 printTypeChain(tree->ftype,outfile);
5668 fprintf(outfile,")\n");
5669 ast_print(tree->left,outfile,indent+2);
5672 /*------------------------------------------------------------------*/
5673 /*----------------------------*/
5674 /* multiplication */
5675 /*----------------------------*/
5676 fprintf(outfile,"MULT (%p) type (",tree);
5677 printTypeChain(tree->ftype,outfile);
5678 fprintf(outfile,")\n");
5679 ast_print(tree->left,outfile,indent+2);
5680 ast_print(tree->right,outfile,indent+2);
5684 /*------------------------------------------------------------------*/
5685 /*----------------------------*/
5686 /* unary '+' operator */
5687 /*----------------------------*/
5691 fprintf(outfile,"UPLUS (%p) type (",tree);
5692 printTypeChain(tree->ftype,outfile);
5693 fprintf(outfile,")\n");
5694 ast_print(tree->left,outfile,indent+2);
5696 /*------------------------------------------------------------------*/
5697 /*----------------------------*/
5699 /*----------------------------*/
5700 fprintf(outfile,"ADD (%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 /*------------------------------------------------------------------*/
5708 /*----------------------------*/
5710 /*----------------------------*/
5711 case '-': /* can be unary */
5713 fprintf(outfile,"UMINUS (%p) type (",tree);
5714 printTypeChain(tree->ftype,outfile);
5715 fprintf(outfile,")\n");
5716 ast_print(tree->left,outfile,indent+2);
5718 /*------------------------------------------------------------------*/
5719 /*----------------------------*/
5721 /*----------------------------*/
5722 fprintf(outfile,"SUB (%p) type (",tree);
5723 printTypeChain(tree->ftype,outfile);
5724 fprintf(outfile,")\n");
5725 ast_print(tree->left,outfile,indent+2);
5726 ast_print(tree->right,outfile,indent+2);
5729 /*------------------------------------------------------------------*/
5730 /*----------------------------*/
5732 /*----------------------------*/
5734 fprintf(outfile,"COMPL (%p) type (",tree);
5735 printTypeChain(tree->ftype,outfile);
5736 fprintf(outfile,")\n");
5737 ast_print(tree->left,outfile,indent+2);
5739 /*------------------------------------------------------------------*/
5740 /*----------------------------*/
5742 /*----------------------------*/
5744 fprintf(outfile,"NOT (%p) type (",tree);
5745 printTypeChain(tree->ftype,outfile);
5746 fprintf(outfile,")\n");
5747 ast_print(tree->left,outfile,indent+2);
5749 /*------------------------------------------------------------------*/
5750 /*----------------------------*/
5752 /*----------------------------*/
5754 fprintf(outfile,"RRC (%p) type (",tree);
5755 printTypeChain(tree->ftype,outfile);
5756 fprintf(outfile,")\n");
5757 ast_print(tree->left,outfile,indent+2);
5761 fprintf(outfile,"RLC (%p) type (",tree);
5762 printTypeChain(tree->ftype,outfile);
5763 fprintf(outfile,")\n");
5764 ast_print(tree->left,outfile,indent+2);
5767 fprintf(outfile,"SWAP (%p) type (",tree);
5768 printTypeChain(tree->ftype,outfile);
5769 fprintf(outfile,")\n");
5770 ast_print(tree->left,outfile,indent+2);
5773 fprintf(outfile,"GETHBIT (%p) type (",tree);
5774 printTypeChain(tree->ftype,outfile);
5775 fprintf(outfile,")\n");
5776 ast_print(tree->left,outfile,indent+2);
5779 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5780 printTypeChain(tree->ftype,outfile);
5781 fprintf(outfile,")\n");
5782 ast_print(tree->left,outfile,indent+2);
5783 ast_print(tree->right,outfile,indent+2);
5786 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5787 printTypeChain(tree->ftype,outfile);
5788 fprintf(outfile,")\n");
5789 ast_print(tree->left,outfile,indent+2);
5790 ast_print(tree->right,outfile,indent+2);
5792 /*------------------------------------------------------------------*/
5793 /*----------------------------*/
5795 /*----------------------------*/
5796 case CAST: /* change the type */
5797 fprintf(outfile,"CAST (%p) from type (",tree);
5798 printTypeChain(tree->right->ftype,outfile);
5799 fprintf(outfile,") to type (");
5800 printTypeChain(tree->ftype,outfile);
5801 fprintf(outfile,")\n");
5802 ast_print(tree->right,outfile,indent+2);
5806 fprintf(outfile,"ANDAND (%p) type (",tree);
5807 printTypeChain(tree->ftype,outfile);
5808 fprintf(outfile,")\n");
5809 ast_print(tree->left,outfile,indent+2);
5810 ast_print(tree->right,outfile,indent+2);
5813 fprintf(outfile,"OROR (%p) type (",tree);
5814 printTypeChain(tree->ftype,outfile);
5815 fprintf(outfile,")\n");
5816 ast_print(tree->left,outfile,indent+2);
5817 ast_print(tree->right,outfile,indent+2);
5820 /*------------------------------------------------------------------*/
5821 /*----------------------------*/
5822 /* comparison operators */
5823 /*----------------------------*/
5825 fprintf(outfile,"GT(>) (%p) type (",tree);
5826 printTypeChain(tree->ftype,outfile);
5827 fprintf(outfile,")\n");
5828 ast_print(tree->left,outfile,indent+2);
5829 ast_print(tree->right,outfile,indent+2);
5832 fprintf(outfile,"LT(<) (%p) type (",tree);
5833 printTypeChain(tree->ftype,outfile);
5834 fprintf(outfile,")\n");
5835 ast_print(tree->left,outfile,indent+2);
5836 ast_print(tree->right,outfile,indent+2);
5839 fprintf(outfile,"LE(<=) (%p) type (",tree);
5840 printTypeChain(tree->ftype,outfile);
5841 fprintf(outfile,")\n");
5842 ast_print(tree->left,outfile,indent+2);
5843 ast_print(tree->right,outfile,indent+2);
5846 fprintf(outfile,"GE(>=) (%p) type (",tree);
5847 printTypeChain(tree->ftype,outfile);
5848 fprintf(outfile,")\n");
5849 ast_print(tree->left,outfile,indent+2);
5850 ast_print(tree->right,outfile,indent+2);
5853 fprintf(outfile,"EQ(==) (%p) type (",tree);
5854 printTypeChain(tree->ftype,outfile);
5855 fprintf(outfile,")\n");
5856 ast_print(tree->left,outfile,indent+2);
5857 ast_print(tree->right,outfile,indent+2);
5860 fprintf(outfile,"NE(!=) (%p) type (",tree);
5861 printTypeChain(tree->ftype,outfile);
5862 fprintf(outfile,")\n");
5863 ast_print(tree->left,outfile,indent+2);
5864 ast_print(tree->right,outfile,indent+2);
5865 /*------------------------------------------------------------------*/
5866 /*----------------------------*/
5868 /*----------------------------*/
5869 case SIZEOF: /* evaluate wihout code generation */
5870 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5873 /*------------------------------------------------------------------*/
5874 /*----------------------------*/
5875 /* conditional operator '?' */
5876 /*----------------------------*/
5878 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5879 printTypeChain(tree->ftype,outfile);
5880 fprintf(outfile,")\n");
5881 ast_print(tree->left,outfile,indent+2);
5882 ast_print(tree->right,outfile,indent+2);
5886 fprintf(outfile,"COLON(:) (%p) type (",tree);
5887 printTypeChain(tree->ftype,outfile);
5888 fprintf(outfile,")\n");
5889 ast_print(tree->left,outfile,indent+2);
5890 ast_print(tree->right,outfile,indent+2);
5893 /*------------------------------------------------------------------*/
5894 /*----------------------------*/
5895 /* assignment operators */
5896 /*----------------------------*/
5898 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5899 printTypeChain(tree->ftype,outfile);
5900 fprintf(outfile,")\n");
5901 ast_print(tree->left,outfile,indent+2);
5902 ast_print(tree->right,outfile,indent+2);
5905 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5906 printTypeChain(tree->ftype,outfile);
5907 fprintf(outfile,")\n");
5908 ast_print(tree->left,outfile,indent+2);
5909 ast_print(tree->right,outfile,indent+2);
5912 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5913 printTypeChain(tree->ftype,outfile);
5914 fprintf(outfile,")\n");
5915 ast_print(tree->left,outfile,indent+2);
5916 ast_print(tree->right,outfile,indent+2);
5919 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5920 printTypeChain(tree->ftype,outfile);
5921 fprintf(outfile,")\n");
5922 ast_print(tree->left,outfile,indent+2);
5923 ast_print(tree->right,outfile,indent+2);
5926 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5927 printTypeChain(tree->ftype,outfile);
5928 fprintf(outfile,")\n");
5929 ast_print(tree->left,outfile,indent+2);
5930 ast_print(tree->right,outfile,indent+2);
5933 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5934 printTypeChain(tree->ftype,outfile);
5935 fprintf(outfile,")\n");
5936 ast_print(tree->left,outfile,indent+2);
5937 ast_print(tree->right,outfile,indent+2);
5940 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5941 printTypeChain(tree->ftype,outfile);
5942 fprintf(outfile,")\n");
5943 ast_print(tree->left,outfile,indent+2);
5944 ast_print(tree->right,outfile,indent+2);
5946 /*------------------------------------------------------------------*/
5947 /*----------------------------*/
5949 /*----------------------------*/
5951 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5952 printTypeChain(tree->ftype,outfile);
5953 fprintf(outfile,")\n");
5954 ast_print(tree->left,outfile,indent+2);
5955 ast_print(tree->right,outfile,indent+2);
5957 /*------------------------------------------------------------------*/
5958 /*----------------------------*/
5960 /*----------------------------*/
5962 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5963 printTypeChain(tree->ftype,outfile);
5964 fprintf(outfile,")\n");
5965 ast_print(tree->left,outfile,indent+2);
5966 ast_print(tree->right,outfile,indent+2);
5968 /*------------------------------------------------------------------*/
5969 /*----------------------------*/
5970 /* straight assignemnt */
5971 /*----------------------------*/
5973 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5974 printTypeChain(tree->ftype,outfile);
5975 fprintf(outfile,")\n");
5976 ast_print(tree->left,outfile,indent+2);
5977 ast_print(tree->right,outfile,indent+2);
5979 /*------------------------------------------------------------------*/
5980 /*----------------------------*/
5981 /* comma operator */
5982 /*----------------------------*/
5984 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5985 printTypeChain(tree->ftype,outfile);
5986 fprintf(outfile,")\n");
5987 ast_print(tree->left,outfile,indent+2);
5988 ast_print(tree->right,outfile,indent+2);
5990 /*------------------------------------------------------------------*/
5991 /*----------------------------*/
5993 /*----------------------------*/
5996 fprintf(outfile,"CALL (%p) type (",tree);
5997 printTypeChain(tree->ftype,outfile);
5998 fprintf(outfile,")\n");
5999 ast_print(tree->left,outfile,indent+2);
6000 ast_print(tree->right,outfile,indent+2);
6003 fprintf(outfile,"PARMS\n");
6004 ast_print(tree->left,outfile,indent+2);
6005 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
6006 ast_print(tree->right,outfile,indent+2);
6009 /*------------------------------------------------------------------*/
6010 /*----------------------------*/
6011 /* return statement */
6012 /*----------------------------*/
6014 fprintf(outfile,"RETURN (%p) type (",tree);
6016 printTypeChain(tree->right->ftype,outfile);
6018 fprintf(outfile,")\n");
6019 ast_print(tree->right,outfile,indent+2);
6021 /*------------------------------------------------------------------*/
6022 /*----------------------------*/
6023 /* label statement */
6024 /*----------------------------*/
6026 fprintf(outfile,"LABEL (%p)\n",tree);
6027 ast_print(tree->left,outfile,indent+2);
6028 ast_print(tree->right,outfile,indent);
6030 /*------------------------------------------------------------------*/
6031 /*----------------------------*/
6032 /* switch statement */
6033 /*----------------------------*/
6037 fprintf(outfile,"SWITCH (%p) ",tree);
6038 ast_print(tree->left,outfile,0);
6039 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
6040 INDENT(indent+2,outfile);
6041 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
6042 (int) floatFromVal(val),
6043 tree->values.switchVals.swNum,
6044 (int) floatFromVal(val));
6046 ast_print(tree->right,outfile,indent);
6049 /*------------------------------------------------------------------*/
6050 /*----------------------------*/
6052 /*----------------------------*/
6054 fprintf(outfile,"IF (%p) \n",tree);
6055 ast_print(tree->left,outfile,indent+2);
6056 if (tree->trueLabel) {
6057 INDENT(indent+2,outfile);
6058 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
6060 if (tree->falseLabel) {
6061 INDENT(indent+2,outfile);
6062 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
6064 ast_print(tree->right,outfile,indent+2);
6066 /*----------------------------*/
6067 /* goto Statement */
6068 /*----------------------------*/
6070 fprintf(outfile,"GOTO (%p) \n",tree);
6071 ast_print(tree->left,outfile,indent+2);
6072 fprintf(outfile,"\n");
6074 /*------------------------------------------------------------------*/
6075 /*----------------------------*/
6077 /*----------------------------*/
6079 fprintf(outfile,"FOR (%p) \n",tree);
6080 if (AST_FOR( tree, initExpr)) {
6081 INDENT(indent+2,outfile);
6082 fprintf(outfile,"INIT EXPR ");
6083 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6085 if (AST_FOR( tree, condExpr)) {
6086 INDENT(indent+2,outfile);
6087 fprintf(outfile,"COND EXPR ");
6088 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6090 if (AST_FOR( tree, loopExpr)) {
6091 INDENT(indent+2,outfile);
6092 fprintf(outfile,"LOOP EXPR ");
6093 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6095 fprintf(outfile,"FOR LOOP BODY \n");
6096 ast_print(tree->left,outfile,indent+2);
6099 fprintf(outfile,"CRITICAL (%p) \n",tree);
6100 ast_print(tree->left,outfile,indent+2);
6108 ast_print(t,stdout,0);
6113 /*-----------------------------------------------------------------*/
6114 /* astErrors : returns non-zero if errors present in tree */
6115 /*-----------------------------------------------------------------*/
6116 int astErrors(ast *t)
6125 if (t->type == EX_VALUE
6126 && t->opval.val->sym
6127 && t->opval.val->sym->undefined)
6130 errors += astErrors(t->left);
6131 errors += astErrors(t->right);