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 TTYPE (tree) = computeType (LTYPE (tree),
2601 TETYPE (tree) = getSpec (TTYPE (tree));
2606 /*------------------------------------------------------------------*/
2607 /*----------------------------*/
2609 /*----------------------------*/
2610 p = newLink (DECLARATOR);
2611 /* if bit field then error */
2612 if (IS_BITVAR (tree->left->etype))
2614 werror (E_ILLEGAL_ADDR, "address of bit variable");
2615 goto errorTreeReturn;
2618 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2620 werror (E_ILLEGAL_ADDR, "address of register variable");
2621 goto errorTreeReturn;
2624 if (IS_FUNC (LTYPE (tree)))
2626 // this ought to be ignored
2627 return (tree->left);
2630 if (IS_LITERAL(LTYPE(tree)))
2632 werror (E_ILLEGAL_ADDR, "address of literal");
2633 goto errorTreeReturn;
2638 werror (E_LVALUE_REQUIRED, "address of");
2639 goto errorTreeReturn;
2642 DCL_TYPE (p) = POINTER;
2643 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2644 DCL_TYPE (p) = CPOINTER;
2645 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2646 DCL_TYPE (p) = FPOINTER;
2647 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2648 DCL_TYPE (p) = PPOINTER;
2649 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2650 DCL_TYPE (p) = IPOINTER;
2651 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2652 DCL_TYPE (p) = EEPPOINTER;
2653 else if (SPEC_OCLS(tree->left->etype))
2654 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2656 DCL_TYPE (p) = POINTER;
2658 if (IS_AST_SYM_VALUE (tree->left))
2660 AST_SYMBOL (tree->left)->addrtaken = 1;
2661 AST_SYMBOL (tree->left)->allocreq = 1;
2664 p->next = LTYPE (tree);
2666 TETYPE (tree) = getSpec (TTYPE (tree));
2671 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2672 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2674 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2675 AST_SYMBOL(tree->left->right));
2676 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2677 valueFromLit(element->offset));
2680 tree->type = EX_VALUE;
2681 tree->values.literalFromCast = 1;
2687 /*------------------------------------------------------------------*/
2688 /*----------------------------*/
2690 /*----------------------------*/
2692 /* if the rewrite succeeds then don't go any furthur */
2694 ast *wtree = optimizeRRCRLC (tree);
2696 return decorateType (wtree, RESULT_CHECK);
2698 wtree = optimizeSWAP (tree);
2700 return decorateType (wtree, RESULT_CHECK);
2703 /* if left is a literal exchange left & right */
2704 if (IS_LITERAL (LTYPE (tree)))
2706 ast *tTree = tree->left;
2707 tree->left = tree->right;
2708 tree->right = tTree;
2711 /* if right is a literal and */
2712 /* we can find a 2nd literal in an or-tree then */
2713 /* rearrange the tree */
2714 if (IS_LITERAL (RTYPE (tree)))
2717 ast *litTree = searchLitOp (tree, &parent, "|");
2721 ast *tTree = litTree->left;
2722 litTree->left = tree->right;
2723 tree->right = tTree;
2724 /* both operands in tTree are literal now */
2725 decorateType (parent, resultType);
2730 /*------------------------------------------------------------------*/
2731 /*----------------------------*/
2733 /*----------------------------*/
2735 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2737 werror (E_BITWISE_OP);
2738 werror (W_CONTINUE, "left & right types are ");
2739 printTypeChain (LTYPE (tree), stderr);
2740 fprintf (stderr, ",");
2741 printTypeChain (RTYPE (tree), stderr);
2742 fprintf (stderr, "\n");
2743 goto errorTreeReturn;
2746 /* if they are both literal then rewrite the tree */
2747 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2749 tree->type = EX_VALUE;
2750 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2751 valFromType (RETYPE (tree)),
2753 tree->right = tree->left = NULL;
2754 TETYPE (tree) = tree->opval.val->etype;
2755 TTYPE (tree) = tree->opval.val->type;
2759 /* if left is a literal exchange left & right */
2760 if (IS_LITERAL (LTYPE (tree)))
2762 ast *tTree = tree->left;
2763 tree->left = tree->right;
2764 tree->right = tTree;
2767 /* if right is a literal and */
2768 /* we can find a 2nd literal in a xor-tree then */
2769 /* rearrange the tree */
2770 if (IS_LITERAL (RTYPE (tree)) &&
2771 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2774 ast *litTree = searchLitOp (tree, &parent, "^");
2778 ast *tTree = litTree->left;
2779 litTree->left = tree->right;
2780 tree->right = tTree;
2781 /* both operands in litTree are literal now */
2782 decorateType (parent, resultType);
2786 LRVAL (tree) = RRVAL (tree) = 1;
2788 TTYPE (tree) = computeType (LTYPE (tree),
2792 TETYPE (tree) = getSpec (TTYPE (tree));
2796 /*------------------------------------------------------------------*/
2797 /*----------------------------*/
2799 /*----------------------------*/
2801 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2803 werror (E_INVALID_OP, "divide");
2804 goto errorTreeReturn;
2806 /* if they are both literal then */
2807 /* rewrite the tree */
2808 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2810 tree->type = EX_VALUE;
2811 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2812 valFromType (RETYPE (tree)));
2813 tree->right = tree->left = NULL;
2814 TETYPE (tree) = getSpec (TTYPE (tree) =
2815 tree->opval.val->type);
2819 LRVAL (tree) = RRVAL (tree) = 1;
2821 TETYPE (tree) = getSpec (TTYPE (tree) =
2822 computeType (LTYPE (tree),
2827 /* if right is a literal and */
2828 /* left is also a division by a literal then */
2829 /* rearrange the tree */
2830 if (IS_LITERAL (RTYPE (tree))
2831 /* avoid infinite loop */
2832 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2835 ast *litTree = searchLitOp (tree, &parent, "/");
2838 if (IS_LITERAL (RTYPE (litTree)))
2842 litTree->right = newNode ('*',
2844 copyAst (tree->right));
2845 litTree->right->lineno = tree->lineno;
2847 tree->right->opval.val = constVal ("1");
2848 decorateType (parent, resultType);
2852 /* litTree->left is literal: no gcse possible.
2853 We can't call decorateType(parent, RESULT_CHECK), because
2854 this would cause an infinit loop. */
2855 parent->decorated = 1;
2856 decorateType (litTree, resultType);
2863 /*------------------------------------------------------------------*/
2864 /*----------------------------*/
2866 /*----------------------------*/
2868 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2870 werror (E_BITWISE_OP);
2871 werror (W_CONTINUE, "left & right types are ");
2872 printTypeChain (LTYPE (tree), stderr);
2873 fprintf (stderr, ",");
2874 printTypeChain (RTYPE (tree), stderr);
2875 fprintf (stderr, "\n");
2876 goto errorTreeReturn;
2878 /* if they are both literal then */
2879 /* rewrite the tree */
2880 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2882 tree->type = EX_VALUE;
2883 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2884 valFromType (RETYPE (tree)));
2885 tree->right = tree->left = NULL;
2886 TETYPE (tree) = getSpec (TTYPE (tree) =
2887 tree->opval.val->type);
2890 LRVAL (tree) = RRVAL (tree) = 1;
2891 TETYPE (tree) = getSpec (TTYPE (tree) =
2892 computeType (LTYPE (tree),
2898 /*------------------------------------------------------------------*/
2899 /*----------------------------*/
2900 /* address dereference */
2901 /*----------------------------*/
2902 case '*': /* can be unary : if right is null then unary operation */
2905 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2907 werror (E_PTR_REQD);
2908 goto errorTreeReturn;
2913 werror (E_LVALUE_REQUIRED, "pointer deref");
2914 goto errorTreeReturn;
2916 if (IS_ADDRESS_OF_OP(tree->left))
2918 /* replace *&obj with obj */
2919 return tree->left->left;
2921 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2922 TETYPE (tree) = getSpec (TTYPE (tree));
2923 /* adjust the storage class */
2924 switch (DCL_TYPE(tree->left->ftype)) {
2926 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2929 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2932 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2935 SPEC_SCLS (TETYPE (tree)) = 0;
2938 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2941 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2944 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2947 SPEC_SCLS (TETYPE (tree)) = 0;
2956 /*------------------------------------------------------------------*/
2957 /*----------------------------*/
2958 /* multiplication */
2959 /*----------------------------*/
2960 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2962 werror (E_INVALID_OP, "multiplication");
2963 goto errorTreeReturn;
2966 /* if they are both literal then */
2967 /* rewrite the tree */
2968 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2970 tree->type = EX_VALUE;
2971 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2972 valFromType (RETYPE (tree)));
2973 tree->right = tree->left = NULL;
2974 TETYPE (tree) = getSpec (TTYPE (tree) =
2975 tree->opval.val->type);
2979 /* if left is a literal exchange left & right */
2980 if (IS_LITERAL (LTYPE (tree)))
2982 ast *tTree = tree->left;
2983 tree->left = tree->right;
2984 tree->right = tTree;
2987 /* if right is a literal and */
2988 /* we can find a 2nd literal in a mul-tree then */
2989 /* rearrange the tree */
2990 if (IS_LITERAL (RTYPE (tree)))
2993 ast *litTree = searchLitOp (tree, &parent, "*");
2997 ast *tTree = litTree->left;
2998 litTree->left = tree->right;
2999 tree->right = tTree;
3000 /* both operands in litTree are literal now */
3001 decorateType (parent, resultType);
3005 LRVAL (tree) = RRVAL (tree) = 1;
3006 tree->left = addCast (tree->left, resultType, FALSE);
3007 tree->right = addCast (tree->right, resultType, FALSE);
3008 TETYPE (tree) = getSpec (TTYPE (tree) =
3009 computeType (LTYPE (tree),
3016 /*------------------------------------------------------------------*/
3017 /*----------------------------*/
3018 /* unary '+' operator */
3019 /*----------------------------*/
3024 if (!IS_ARITHMETIC (LTYPE (tree)))
3026 werror (E_UNARY_OP, '+');
3027 goto errorTreeReturn;
3030 /* if left is a literal then do it */
3031 if (IS_LITERAL (LTYPE (tree)))
3033 tree->type = EX_VALUE;
3034 tree->opval.val = valFromType (LETYPE (tree));
3036 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3040 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3044 /*------------------------------------------------------------------*/
3045 /*----------------------------*/
3047 /*----------------------------*/
3049 /* this is not a unary operation */
3050 /* if both pointers then problem */
3051 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3052 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3054 werror (E_PTR_PLUS_PTR);
3055 goto errorTreeReturn;
3058 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3059 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3061 werror (E_PLUS_INVALID, "+");
3062 goto errorTreeReturn;
3065 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3066 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3068 werror (E_PLUS_INVALID, "+");
3069 goto errorTreeReturn;
3071 /* if they are both literal then */
3072 /* rewrite the tree */
3073 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3075 tree->type = EX_VALUE;
3076 tree->left = addCast (tree->left, resultType, TRUE);
3077 tree->right = addCast (tree->right, resultType, TRUE);
3078 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3079 valFromType (RETYPE (tree)));
3080 tree->right = tree->left = NULL;
3081 TETYPE (tree) = getSpec (TTYPE (tree) =
3082 tree->opval.val->type);
3086 /* if the right is a pointer or left is a literal
3087 xchange left & right */
3088 if (IS_ARRAY (RTYPE (tree)) ||
3089 IS_PTR (RTYPE (tree)) ||
3090 IS_LITERAL (LTYPE (tree)))
3092 ast *tTree = tree->left;
3093 tree->left = tree->right;
3094 tree->right = tTree;
3097 /* if right is a literal and */
3098 /* left is also an addition/subtraction with a literal then */
3099 /* rearrange the tree */
3100 if (IS_LITERAL (RTYPE (tree)))
3102 ast *litTree, *parent;
3103 litTree = searchLitOp (tree, &parent, "+-");
3106 if (litTree->opval.op == '+')
3110 ast *tTree = litTree->left;
3111 litTree->left = tree->right;
3112 tree->right = tree->left;
3115 else if (litTree->opval.op == '-')
3117 if (IS_LITERAL (RTYPE (litTree)))
3121 ast *tTree = litTree->left;
3122 litTree->left = tree->right;
3123 tree->right = tTree;
3129 ast *tTree = litTree->right;
3130 litTree->right = tree->right;
3131 tree->right = tTree;
3132 litTree->opval.op = '+';
3133 tree->opval.op = '-';
3136 decorateType (parent, resultType);
3140 LRVAL (tree) = RRVAL (tree) = 1;
3141 /* if the left is a pointer */
3142 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3143 TETYPE (tree) = getSpec (TTYPE (tree) =
3147 tree->left = addCast (tree->left, resultType, TRUE);
3148 tree->right = addCast (tree->right, resultType, TRUE);
3149 TETYPE (tree) = getSpec (TTYPE (tree) =
3150 computeType (LTYPE (tree),
3158 /*------------------------------------------------------------------*/
3159 /*----------------------------*/
3161 /*----------------------------*/
3162 case '-': /* can be unary */
3163 /* if right is null then unary */
3167 if (!IS_ARITHMETIC (LTYPE (tree)))
3169 werror (E_UNARY_OP, tree->opval.op);
3170 goto errorTreeReturn;
3173 /* if left is a literal then do it */
3174 if (IS_LITERAL (LTYPE (tree)))
3176 tree->type = EX_VALUE;
3177 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3179 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3180 SPEC_USIGN(TETYPE(tree)) = 0;
3184 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3188 /*------------------------------------------------------------------*/
3189 /*----------------------------*/
3191 /*----------------------------*/
3193 if (!(IS_PTR (LTYPE (tree)) ||
3194 IS_ARRAY (LTYPE (tree)) ||
3195 IS_ARITHMETIC (LTYPE (tree))))
3197 werror (E_PLUS_INVALID, "-");
3198 goto errorTreeReturn;
3201 if (!(IS_PTR (RTYPE (tree)) ||
3202 IS_ARRAY (RTYPE (tree)) ||
3203 IS_ARITHMETIC (RTYPE (tree))))
3205 werror (E_PLUS_INVALID, "-");
3206 goto errorTreeReturn;
3209 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3210 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3211 IS_INTEGRAL (RTYPE (tree))))
3213 werror (E_PLUS_INVALID, "-");
3214 goto errorTreeReturn;
3217 /* if they are both literal then */
3218 /* rewrite the tree */
3219 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3221 tree->type = EX_VALUE;
3222 tree->left = addCast (tree->left, resultType, TRUE);
3223 tree->right = addCast (tree->right, resultType, TRUE);
3224 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3225 valFromType (RETYPE (tree)));
3226 tree->right = tree->left = NULL;
3227 TETYPE (tree) = getSpec (TTYPE (tree) =
3228 tree->opval.val->type);
3232 /* if the left & right are equal then zero */
3233 if (isAstEqual (tree->left, tree->right))
3235 tree->type = EX_VALUE;
3236 tree->left = tree->right = NULL;
3237 tree->opval.val = constVal ("0");
3238 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3242 /* if both of them are pointers or arrays then */
3243 /* the result is going to be an integer */
3244 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3245 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3246 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3248 /* if only the left is a pointer */
3249 /* then result is a pointer */
3250 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3251 TETYPE (tree) = getSpec (TTYPE (tree) =
3255 tree->left = addCast (tree->left, resultType, TRUE);
3256 tree->right = addCast (tree->right, resultType, TRUE);
3258 TETYPE (tree) = getSpec (TTYPE (tree) =
3259 computeType (LTYPE (tree),
3265 LRVAL (tree) = RRVAL (tree) = 1;
3267 /* if right is a literal and */
3268 /* left is also an addition/subtraction with a literal then */
3269 /* rearrange the tree */
3270 if (IS_LITERAL (RTYPE (tree))
3271 /* avoid infinite loop */
3272 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3274 ast *litTree, *litParent;
3275 litTree = searchLitOp (tree, &litParent, "+-");
3278 if (litTree->opval.op == '+')
3282 ast *tTree = litTree->left;
3283 litTree->left = litTree->right;
3284 litTree->right = tree->right;
3285 tree->right = tTree;
3286 tree->opval.op = '+';
3287 litTree->opval.op = '-';
3289 else if (litTree->opval.op == '-')
3291 if (IS_LITERAL (RTYPE (litTree)))
3295 ast *tTree = litTree->left;
3296 litTree->left = tree->right;
3297 tree->right = litParent->left;
3298 litParent->left = tTree;
3299 litTree->opval.op = '+';
3301 tree->decorated = 0;
3302 decorateType (tree, resultType);
3308 ast *tTree = litTree->right;
3309 litTree->right = tree->right;
3310 tree->right = tTree;
3313 decorateType (litParent, resultType);
3318 /*------------------------------------------------------------------*/
3319 /*----------------------------*/
3321 /*----------------------------*/
3323 /* can be only integral type */
3324 if (!IS_INTEGRAL (LTYPE (tree)))
3326 werror (E_UNARY_OP, tree->opval.op);
3327 goto errorTreeReturn;
3330 /* if left is a literal then do it */
3331 if (IS_LITERAL (LTYPE (tree)))
3333 tree->type = EX_VALUE;
3334 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3336 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3337 return addCast (tree, resultType, TRUE);
3339 tree->left = addCast (tree->left, resultType, TRUE);
3341 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3344 /*------------------------------------------------------------------*/
3345 /*----------------------------*/
3347 /*----------------------------*/
3349 /* can be pointer */
3350 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3351 !IS_PTR (LTYPE (tree)) &&
3352 !IS_ARRAY (LTYPE (tree)))
3354 werror (E_UNARY_OP, tree->opval.op);
3355 goto errorTreeReturn;
3358 /* if left is a literal then do it */
3359 if (IS_LITERAL (LTYPE (tree)))
3361 tree->type = EX_VALUE;
3362 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3364 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3368 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3371 /*------------------------------------------------------------------*/
3372 /*----------------------------*/
3374 /*----------------------------*/
3378 TTYPE (tree) = LTYPE (tree);
3379 TETYPE (tree) = LETYPE (tree);
3383 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3388 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3390 werror (E_SHIFT_OP_INVALID);
3391 werror (W_CONTINUE, "left & right types are ");
3392 printTypeChain (LTYPE (tree), stderr);
3393 fprintf (stderr, ",");
3394 printTypeChain (RTYPE (tree), stderr);
3395 fprintf (stderr, "\n");
3396 goto errorTreeReturn;
3399 /* make smaller type only if it's a LEFT_OP */
3400 if (tree->opval.op == LEFT_OP)
3401 tree->left = addCast (tree->left, resultType, TRUE);
3403 /* if they are both literal then */
3404 /* rewrite the tree */
3405 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3407 tree->type = EX_VALUE;
3408 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3409 valFromType (RETYPE (tree)),
3410 (tree->opval.op == LEFT_OP ? 1 : 0));
3411 tree->right = tree->left = NULL;
3412 TETYPE (tree) = getSpec (TTYPE (tree) =
3413 tree->opval.val->type);
3417 LRVAL (tree) = RRVAL (tree) = 1;
3418 if (tree->opval.op == LEFT_OP)
3420 TETYPE (tree) = getSpec (TTYPE (tree) =
3421 computeType (LTYPE (tree),
3428 /* no promotion necessary */
3429 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3430 if (IS_LITERAL (TTYPE (tree)))
3431 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3434 /* if only the right side is a literal & we are
3435 shifting more than size of the left operand then zero */
3436 if (IS_LITERAL (RTYPE (tree)) &&
3437 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3438 (getSize (TETYPE (tree)) * 8))
3440 if (tree->opval.op==LEFT_OP ||
3441 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3443 lineno=tree->lineno;
3444 werror (W_SHIFT_CHANGED,
3445 (tree->opval.op == LEFT_OP ? "left" : "right"));
3446 tree->type = EX_VALUE;
3447 tree->left = tree->right = NULL;
3448 tree->opval.val = constVal ("0");
3449 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3456 /*------------------------------------------------------------------*/
3457 /*----------------------------*/
3459 /*----------------------------*/
3460 case CAST: /* change the type */
3461 /* cannot cast to an aggregate type */
3462 if (IS_AGGREGATE (LTYPE (tree)))
3464 werror (E_CAST_ILLEGAL);
3465 goto errorTreeReturn;
3468 /* make sure the type is complete and sane */
3469 changePointer(LTYPE(tree));
3470 checkTypeSanity(LETYPE(tree), "(cast)");
3472 /* If code memory is read only, then pointers to code memory */
3473 /* implicitly point to constants -- make this explicit */
3475 sym_link *t = LTYPE(tree);
3476 while (t && t->next)
3478 if (IS_CODEPTR(t) && port->mem.code_ro)
3480 if (IS_SPEC(t->next))
3481 SPEC_CONST (t->next) = 1;
3483 DCL_PTR_CONST (t->next) = 1;
3490 /* if the right is a literal replace the tree */
3491 if (IS_LITERAL (RETYPE (tree))) {
3492 if (!IS_PTR (LTYPE (tree))) {
3493 tree->type = EX_VALUE;
3495 valCastLiteral (LTYPE (tree),
3496 floatFromVal (valFromType (RETYPE (tree))));
3499 TTYPE (tree) = tree->opval.val->type;
3500 tree->values.literalFromCast = 1;
3501 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3502 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3503 sym_link *rest = LTYPE(tree)->next;
3504 werror(W_LITERAL_GENERIC);
3505 TTYPE(tree) = newLink(DECLARATOR);
3506 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3507 TTYPE(tree)->next = rest;
3508 tree->left->opval.lnk = TTYPE(tree);
3511 TTYPE (tree) = LTYPE (tree);
3515 TTYPE (tree) = LTYPE (tree);
3519 #if 0 // this is already checked, now this could be explicit
3520 /* if pointer to struct then check names */
3521 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3522 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3523 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3525 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3526 SPEC_STRUCT(LETYPE(tree))->tag);
3529 if (IS_ADDRESS_OF_OP(tree->right)
3530 && IS_AST_SYM_VALUE (tree->right->left)
3531 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3533 tree->type = EX_VALUE;
3535 valCastLiteral (LTYPE (tree),
3536 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3537 TTYPE (tree) = tree->opval.val->type;
3538 TETYPE (tree) = getSpec (TTYPE (tree));
3541 tree->values.literalFromCast = 1;
3545 /* handle offsetof macro: */
3546 /* #define offsetof(TYPE, MEMBER) \ */
3547 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3548 if (IS_ADDRESS_OF_OP(tree->right)
3549 && IS_AST_OP (tree->right->left)
3550 && tree->right->left->opval.op == PTR_OP
3551 && IS_AST_OP (tree->right->left->left)
3552 && tree->right->left->left->opval.op == CAST
3553 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3555 symbol *element = getStructElement (
3556 SPEC_STRUCT (LETYPE(tree->right->left)),
3557 AST_SYMBOL(tree->right->left->right)
3561 tree->type = EX_VALUE;
3562 tree->opval.val = valCastLiteral (
3565 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3568 TTYPE (tree) = tree->opval.val->type;
3569 TETYPE (tree) = getSpec (TTYPE (tree));
3576 /* if the right is a literal replace the tree */
3577 if (IS_LITERAL (RETYPE (tree))) {
3579 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3580 /* rewrite (type *)litaddr
3582 and define type at litaddr temp
3583 (but only if type's storage class is not generic)
3585 ast *newTree = newNode ('&', NULL, NULL);
3588 TTYPE (newTree) = LTYPE (tree);
3589 TETYPE (newTree) = getSpec(LTYPE (tree));
3591 /* define a global symbol at the casted address*/
3592 sym = newSymbol(genSymName (0), 0);
3593 sym->type = LTYPE (tree)->next;
3595 sym->type = newLink (V_VOID);
3596 sym->etype = getSpec(sym->type);
3597 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3598 sym->lineDef = tree->lineno;
3601 SPEC_STAT (sym->etype) = 1;
3602 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3603 SPEC_ABSA(sym->etype) = 1;
3604 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3607 newTree->left = newAst_VALUE(symbolVal(sym));
3608 newTree->left->lineno = tree->lineno;
3609 LTYPE (newTree) = sym->type;
3610 LETYPE (newTree) = sym->etype;
3611 LLVAL (newTree) = 1;
3612 LRVAL (newTree) = 0;
3613 TLVAL (newTree) = 1;
3617 if (!IS_PTR (LTYPE (tree))) {
3618 tree->type = EX_VALUE;
3620 valCastLiteral (LTYPE (tree),
3621 floatFromVal (valFromType (RTYPE (tree))));
3622 TTYPE (tree) = tree->opval.val->type;
3625 tree->values.literalFromCast = 1;
3626 TETYPE (tree) = getSpec (TTYPE (tree));
3630 TTYPE (tree) = LTYPE (tree);
3634 TETYPE (tree) = getSpec (TTYPE (tree));
3638 /*------------------------------------------------------------------*/
3639 /*----------------------------*/
3640 /* logical &&, || */
3641 /*----------------------------*/
3644 /* each must be arithmetic type or be a pointer */
3645 if (!IS_PTR (LTYPE (tree)) &&
3646 !IS_ARRAY (LTYPE (tree)) &&
3647 !IS_INTEGRAL (LTYPE (tree)))
3649 werror (E_COMPARE_OP);
3650 goto errorTreeReturn;
3653 if (!IS_PTR (RTYPE (tree)) &&
3654 !IS_ARRAY (RTYPE (tree)) &&
3655 !IS_INTEGRAL (RTYPE (tree)))
3657 werror (E_COMPARE_OP);
3658 goto errorTreeReturn;
3660 /* if they are both literal then */
3661 /* rewrite the tree */
3662 if (IS_LITERAL (RTYPE (tree)) &&
3663 IS_LITERAL (LTYPE (tree)))
3665 tree->type = EX_VALUE;
3666 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3667 valFromType (RTYPE (tree)),
3669 tree->right = tree->left = NULL;
3670 TETYPE (tree) = getSpec (TTYPE (tree) =
3671 tree->opval.val->type);
3674 LRVAL (tree) = RRVAL (tree) = 1;
3675 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3678 /*------------------------------------------------------------------*/
3679 /*----------------------------*/
3680 /* comparison operators */
3681 /*----------------------------*/
3689 ast *lt = optimizeCompare (tree);
3695 /* if they are pointers they must be castable */
3696 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3698 if (tree->opval.op==EQ_OP &&
3699 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3700 // we cannot cast a gptr to a !gptr: switch the leaves
3701 struct ast *s=tree->left;
3702 tree->left=tree->right;
3705 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3707 werror (E_COMPARE_OP);
3708 fprintf (stderr, "comparing type ");
3709 printTypeChain (LTYPE (tree), stderr);
3710 fprintf (stderr, "to type ");
3711 printTypeChain (RTYPE (tree), stderr);
3712 fprintf (stderr, "\n");
3713 goto errorTreeReturn;
3716 /* else they should be promotable to one another */
3719 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3720 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
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 /* if unsigned value < 0 then always false */
3734 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3735 if (SPEC_USIGN(LETYPE(tree)) &&
3736 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3737 IS_LITERAL(RTYPE(tree)) &&
3738 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3740 if (tree->opval.op == '<')
3744 if (tree->opval.op == '>')
3746 if (resultType == RESULT_TYPE_IFX)
3748 /* the parent is an ifx: */
3749 /* if (unsigned value) */
3753 /* (unsigned value) ? 1 : 0 */
3754 tree->opval.op = '?';
3755 tree->right = newNode (':',
3756 newAst_VALUE (constVal ("1")),
3757 tree->right); /* val 0 */
3758 tree->right->lineno = tree->lineno;
3759 tree->right->left->lineno = tree->lineno;
3760 decorateType (tree->right, RESULT_CHECK);
3763 /* if they are both literal then */
3764 /* rewrite the tree */
3765 if (IS_LITERAL (RTYPE (tree)) &&
3766 IS_LITERAL (LTYPE (tree)))
3768 tree->type = EX_VALUE;
3769 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3770 valFromType (RETYPE (tree)),
3772 tree->right = tree->left = NULL;
3773 TETYPE (tree) = getSpec (TTYPE (tree) =
3774 tree->opval.val->type);
3777 LRVAL (tree) = RRVAL (tree) = 1;
3778 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3781 /*------------------------------------------------------------------*/
3782 /*----------------------------*/
3784 /*----------------------------*/
3785 case SIZEOF: /* evaluate wihout code generation */
3786 /* change the type to a integer */
3788 int size = getSize (tree->right->ftype);
3789 SNPRINTF(buffer, sizeof(buffer), "%d", size);
3790 if (!size && !IS_VOID(tree->right->ftype))
3791 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
3793 tree->type = EX_VALUE;
3794 tree->opval.val = constVal (buffer);
3795 tree->right = tree->left = NULL;
3796 TETYPE (tree) = getSpec (TTYPE (tree) =
3797 tree->opval.val->type);
3800 /*------------------------------------------------------------------*/
3801 /*----------------------------*/
3803 /*----------------------------*/
3805 /* return typeof enum value */
3806 tree->type = EX_VALUE;
3809 if (IS_SPEC(tree->right->ftype)) {
3810 switch (SPEC_NOUN(tree->right->ftype)) {
3812 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3813 else typeofv = TYPEOF_INT;
3816 typeofv = TYPEOF_FLOAT;
3819 typeofv = TYPEOF_CHAR;
3822 typeofv = TYPEOF_VOID;
3825 typeofv = TYPEOF_STRUCT;
3828 typeofv = TYPEOF_BITFIELD;
3831 typeofv = TYPEOF_BIT;
3834 typeofv = TYPEOF_SBIT;
3840 switch (DCL_TYPE(tree->right->ftype)) {
3842 typeofv = TYPEOF_POINTER;
3845 typeofv = TYPEOF_FPOINTER;
3848 typeofv = TYPEOF_CPOINTER;
3851 typeofv = TYPEOF_GPOINTER;
3854 typeofv = TYPEOF_PPOINTER;
3857 typeofv = TYPEOF_IPOINTER;
3860 typeofv = TYPEOF_ARRAY;
3863 typeofv = TYPEOF_FUNCTION;
3869 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3870 tree->opval.val = constVal (buffer);
3871 tree->right = tree->left = NULL;
3872 TETYPE (tree) = getSpec (TTYPE (tree) =
3873 tree->opval.val->type);
3876 /*------------------------------------------------------------------*/
3877 /*----------------------------*/
3878 /* conditional operator '?' */
3879 /*----------------------------*/
3881 /* the type is value of the colon operator (on the right) */
3882 assert (IS_COLON_OP (tree->right));
3883 /* if already known then replace the tree : optimizer will do it
3884 but faster to do it here */
3885 if (IS_LITERAL (LTYPE (tree)))
3887 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
3888 return decorateType (tree->right->left, resultTypeProp);
3890 return decorateType (tree->right->right, resultTypeProp);
3894 tree->right = decorateType (tree->right, resultTypeProp);
3895 TTYPE (tree) = RTYPE (tree);
3896 TETYPE (tree) = getSpec (TTYPE (tree));
3901 /* if they don't match we have a problem */
3902 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3904 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3905 goto errorTreeReturn;
3908 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
3909 resultType, tree->opval.op);
3910 TETYPE (tree) = getSpec (TTYPE (tree));
3914 #if 0 // assignment operators are converted by the parser
3915 /*------------------------------------------------------------------*/
3916 /*----------------------------*/
3917 /* assignment operators */
3918 /*----------------------------*/
3921 /* for these it must be both must be integral */
3922 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3923 !IS_ARITHMETIC (RTYPE (tree)))
3925 werror (E_OPS_INTEGRAL);
3926 goto errorTreeReturn;
3929 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3931 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3932 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3936 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3937 goto errorTreeReturn;
3948 /* for these it must be both must be integral */
3949 if (!IS_INTEGRAL (LTYPE (tree)) ||
3950 !IS_INTEGRAL (RTYPE (tree)))
3952 werror (E_OPS_INTEGRAL);
3953 goto errorTreeReturn;
3956 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3958 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3959 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3963 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3964 goto errorTreeReturn;
3970 /*------------------------------------------------------------------*/
3971 /*----------------------------*/
3973 /*----------------------------*/
3975 if (!(IS_PTR (LTYPE (tree)) ||
3976 IS_ARITHMETIC (LTYPE (tree))))
3978 werror (E_PLUS_INVALID, "-=");
3979 goto errorTreeReturn;
3982 if (!(IS_PTR (RTYPE (tree)) ||
3983 IS_ARITHMETIC (RTYPE (tree))))
3985 werror (E_PLUS_INVALID, "-=");
3986 goto errorTreeReturn;
3989 TETYPE (tree) = getSpec (TTYPE (tree) =
3990 computeType (LTYPE (tree),
3995 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3996 werror (E_CODE_WRITE, "-=");
4000 werror (E_LVALUE_REQUIRED, "-=");
4001 goto errorTreeReturn;
4007 /*------------------------------------------------------------------*/
4008 /*----------------------------*/
4010 /*----------------------------*/
4012 /* this is not a unary operation */
4013 /* if both pointers then problem */
4014 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4016 werror (E_PTR_PLUS_PTR);
4017 goto errorTreeReturn;
4020 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4022 werror (E_PLUS_INVALID, "+=");
4023 goto errorTreeReturn;
4026 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4028 werror (E_PLUS_INVALID, "+=");
4029 goto errorTreeReturn;
4032 TETYPE (tree) = getSpec (TTYPE (tree) =
4033 computeType (LTYPE (tree),
4038 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4039 werror (E_CODE_WRITE, "+=");
4043 werror (E_LVALUE_REQUIRED, "+=");
4044 goto errorTreeReturn;
4047 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_CHECK);
4048 tree->opval.op = '=';
4053 /*------------------------------------------------------------------*/
4054 /*----------------------------*/
4055 /* straight assignemnt */
4056 /*----------------------------*/
4058 /* cannot be an aggregate */
4059 if (IS_AGGREGATE (LTYPE (tree)))
4061 werror (E_AGGR_ASSIGN);
4062 goto errorTreeReturn;
4065 /* they should either match or be castable */
4066 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4068 werror (E_TYPE_MISMATCH, "assignment", " ");
4069 printFromToType(RTYPE(tree),LTYPE(tree));
4072 /* if the left side of the tree is of type void
4073 then report error */
4074 if (IS_VOID (LTYPE (tree)))
4076 werror (E_CAST_ZERO);
4077 printFromToType(RTYPE(tree), LTYPE(tree));
4080 TETYPE (tree) = getSpec (TTYPE (tree) =
4084 if (!tree->initMode ) {
4085 if (IS_CONSTANT(LTYPE(tree)))
4086 werror (E_CODE_WRITE, "=");
4090 werror (E_LVALUE_REQUIRED, "=");
4091 goto errorTreeReturn;
4096 /*------------------------------------------------------------------*/
4097 /*----------------------------*/
4098 /* comma operator */
4099 /*----------------------------*/
4101 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4104 /*------------------------------------------------------------------*/
4105 /*----------------------------*/
4107 /*----------------------------*/
4110 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4111 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4113 if (tree->left->opval.op == '*' && !tree->left->right)
4114 tree->left = tree->left->left;
4117 /* require a function or pointer to function */
4118 if (!IS_FUNC (LTYPE (tree))
4119 && !(IS_CODEPTR (LTYPE (tree)) && IS_FUNC (LTYPE (tree)->next)))
4121 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4122 goto errorTreeReturn;
4125 /* if there are parms, make sure that
4126 parms are decorate / process / reverse only once */
4128 !tree->right->decorated)
4133 if (IS_CODEPTR(LTYPE(tree)))
4134 functype = LTYPE (tree)->next;
4136 functype = LTYPE (tree);
4138 if (processParms (tree->left, FUNC_ARGS(functype),
4139 &tree->right, &parmNumber, TRUE))
4141 goto errorTreeReturn;
4144 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4145 !IFFUNC_ISBUILTIN(functype))
4147 reverseParms (tree->right);
4150 TTYPE (tree) = functype->next;
4151 TETYPE (tree) = getSpec (TTYPE (tree));
4155 /*------------------------------------------------------------------*/
4156 /*----------------------------*/
4157 /* return statement */
4158 /*----------------------------*/
4163 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4165 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4166 printFromToType (RTYPE(tree), currFunc->type->next);
4167 goto errorTreeReturn;
4170 if (IS_VOID (currFunc->type->next)
4172 !IS_VOID (RTYPE (tree)))
4174 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4175 goto errorTreeReturn;
4178 /* if there is going to be a casting required then add it */
4179 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4182 decorateType (newNode (CAST,
4183 newAst_LINK (copyLinkChain (currFunc->type->next)),
4193 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4195 werror (W_VOID_FUNC, currFunc->name);
4196 goto errorTreeReturn;
4199 TTYPE (tree) = TETYPE (tree) = NULL;
4202 /*------------------------------------------------------------------*/
4203 /*----------------------------*/
4204 /* switch statement */
4205 /*----------------------------*/
4207 /* the switch value must be an integer */
4208 if (!IS_INTEGRAL (LTYPE (tree)))
4210 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4211 goto errorTreeReturn;
4214 TTYPE (tree) = TETYPE (tree) = NULL;
4217 /*------------------------------------------------------------------*/
4218 /*----------------------------*/
4220 /*----------------------------*/
4222 tree->left = backPatchLabels (tree->left,
4225 TTYPE (tree) = TETYPE (tree) = NULL;
4228 /*------------------------------------------------------------------*/
4229 /*----------------------------*/
4231 /*----------------------------*/
4234 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_CHECK);
4235 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_CHECK);
4236 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_CHECK);
4238 /* if the for loop is reversible then
4239 reverse it otherwise do what we normally
4245 if (isLoopReversible (tree, &sym, &init, &end))
4246 return reverseLoop (tree, sym, init, end);
4248 return decorateType (createFor (AST_FOR (tree, trueLabel),
4249 AST_FOR (tree, continueLabel),
4250 AST_FOR (tree, falseLabel),
4251 AST_FOR (tree, condLabel),
4252 AST_FOR (tree, initExpr),
4253 AST_FOR (tree, condExpr),
4254 AST_FOR (tree, loopExpr),
4255 tree->left), RESULT_CHECK);
4258 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4259 "node PARAM shouldn't be processed here");
4260 /* but in processParams() */
4263 TTYPE (tree) = TETYPE (tree) = NULL;
4267 /* some error found this tree will be killed */
4269 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4270 tree->opval.op = NULLOP;
4276 /*-----------------------------------------------------------------*/
4277 /* sizeofOp - processes size of operation */
4278 /*-----------------------------------------------------------------*/
4280 sizeofOp (sym_link * type)
4285 /* make sure the type is complete and sane */
4286 checkTypeSanity(type, "(sizeof)");
4288 /* get the size and convert it to character */
4289 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4290 if (!size && !IS_VOID(type))
4291 werror (E_SIZEOF_INCOMPLETE_TYPE);
4293 /* now convert into value */
4294 return constVal (buff);
4298 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4299 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4300 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4301 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4302 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4303 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4304 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4306 /*-----------------------------------------------------------------*/
4307 /* backPatchLabels - change and or not operators to flow control */
4308 /*-----------------------------------------------------------------*/
4310 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4316 if (!(IS_ANDORNOT (tree)))
4319 /* if this an and */
4322 static int localLbl = 0;
4325 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4326 localLabel = newSymbol (buffer, NestLevel);
4328 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4330 /* if left is already a IFX then just change the if true label in that */
4331 if (!IS_IFX (tree->left))
4332 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4334 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4335 /* right is a IFX then just join */
4336 if (IS_IFX (tree->right))
4337 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4339 tree->right = createLabel (localLabel, tree->right);
4340 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4342 return newNode (NULLOP, tree->left, tree->right);
4345 /* if this is an or operation */
4348 static int localLbl = 0;
4351 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4352 localLabel = newSymbol (buffer, NestLevel);
4354 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4356 /* if left is already a IFX then just change the if true label in that */
4357 if (!IS_IFX (tree->left))
4358 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4360 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4361 /* right is a IFX then just join */
4362 if (IS_IFX (tree->right))
4363 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4365 tree->right = createLabel (localLabel, tree->right);
4366 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4368 return newNode (NULLOP, tree->left, tree->right);
4374 int wasnot = IS_NOT (tree->left);
4375 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4377 /* if the left is already a IFX */
4378 if (!IS_IFX (tree->left))
4379 tree->left = newNode (IFX, tree->left, NULL);
4383 tree->left->trueLabel = trueLabel;
4384 tree->left->falseLabel = falseLabel;
4388 tree->left->trueLabel = falseLabel;
4389 tree->left->falseLabel = trueLabel;
4396 tree->trueLabel = trueLabel;
4397 tree->falseLabel = falseLabel;
4404 /*-----------------------------------------------------------------*/
4405 /* createBlock - create expression tree for block */
4406 /*-----------------------------------------------------------------*/
4408 createBlock (symbol * decl, ast * body)
4412 /* if the block has nothing */
4416 ex = newNode (BLOCK, NULL, body);
4417 ex->values.sym = decl;
4419 ex->right = ex->right;
4425 /*-----------------------------------------------------------------*/
4426 /* createLabel - creates the expression tree for labels */
4427 /*-----------------------------------------------------------------*/
4429 createLabel (symbol * label, ast * stmnt)
4432 char name[SDCC_NAME_MAX + 1];
4435 /* must create fresh symbol if the symbol name */
4436 /* exists in the symbol table, since there can */
4437 /* be a variable with the same name as the labl */
4438 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4439 (csym->level == label->level))
4440 label = newSymbol (label->name, label->level);
4442 /* change the name before putting it in add _ */
4443 SNPRINTF(name, sizeof(name), "%s", label->name);
4445 /* put the label in the LabelSymbol table */
4446 /* but first check if a label of the same */
4448 if ((csym = findSym (LabelTab, NULL, name)))
4449 werror (E_DUPLICATE_LABEL, label->name);
4451 addSym (LabelTab, label, name, label->level, 0, 0);
4455 label->key = labelKey++;
4456 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4462 /*-----------------------------------------------------------------*/
4463 /* createCase - generates the parsetree for a case statement */
4464 /*-----------------------------------------------------------------*/
4466 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4468 char caseLbl[SDCC_NAME_MAX + 1];
4472 /* if the switch statement does not exist */
4473 /* then case is out of context */
4476 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4480 caseVal = decorateType (resolveSymbols (caseVal), RESULT_CHECK);
4481 /* if not a constant then error */
4482 if (!IS_LITERAL (caseVal->ftype))
4484 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4488 /* if not a integer than error */
4489 if (!IS_INTEGRAL (caseVal->ftype))
4491 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4495 /* find the end of the switch values chain */
4496 if (!(val = swStat->values.switchVals.swVals))
4497 swStat->values.switchVals.swVals = caseVal->opval.val;
4500 /* also order the cases according to value */
4502 int cVal = (int) floatFromVal (caseVal->opval.val);
4503 while (val && (int) floatFromVal (val) < cVal)
4509 /* if we reached the end then */
4512 pval->next = caseVal->opval.val;
4514 else if ((int) floatFromVal (val) == cVal)
4516 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4522 /* we found a value greater than */
4523 /* the current value we must add this */
4524 /* before the value */
4525 caseVal->opval.val->next = val;
4527 /* if this was the first in chain */
4528 if (swStat->values.switchVals.swVals == val)
4529 swStat->values.switchVals.swVals =
4532 pval->next = caseVal->opval.val;
4537 /* create the case label */
4538 SNPRINTF(caseLbl, sizeof(caseLbl),
4540 swStat->values.switchVals.swNum,
4541 (int) floatFromVal (caseVal->opval.val));
4543 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4548 /*-----------------------------------------------------------------*/
4549 /* createDefault - creates the parse tree for the default statement */
4550 /*-----------------------------------------------------------------*/
4552 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4554 char defLbl[SDCC_NAME_MAX + 1];
4556 /* if the switch statement does not exist */
4557 /* then case is out of context */
4560 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4564 if (swStat->values.switchVals.swDefault)
4566 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4571 /* turn on the default flag */
4572 swStat->values.switchVals.swDefault = 1;
4574 /* create the label */
4575 SNPRINTF (defLbl, sizeof(defLbl),
4576 "_default_%d", swStat->values.switchVals.swNum);
4577 return createLabel (newSymbol (defLbl, 0), stmnt);
4580 /*-----------------------------------------------------------------*/
4581 /* createIf - creates the parsetree for the if statement */
4582 /*-----------------------------------------------------------------*/
4584 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4586 static int Lblnum = 0;
4588 symbol *ifTrue, *ifFalse, *ifEnd;
4590 /* if neither exists */
4591 if (!elseBody && !ifBody) {
4592 // if there are no side effects (i++, j() etc)
4593 if (!hasSEFcalls(condAst)) {
4598 /* create the labels */
4599 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4600 ifFalse = newSymbol (buffer, NestLevel);
4601 /* if no else body then end == false */
4606 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4607 ifEnd = newSymbol (buffer, NestLevel);
4610 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4611 ifTrue = newSymbol (buffer, NestLevel);
4615 /* attach the ifTrue label to the top of it body */
4616 ifBody = createLabel (ifTrue, ifBody);
4617 /* attach a goto end to the ifBody if else is present */
4620 ifBody = newNode (NULLOP, ifBody,
4622 newAst_VALUE (symbolVal (ifEnd)),
4624 /* put the elseLabel on the else body */
4625 elseBody = createLabel (ifFalse, elseBody);
4626 /* out the end at the end of the body */
4627 elseBody = newNode (NULLOP,
4629 createLabel (ifEnd, NULL));
4633 ifBody = newNode (NULLOP, ifBody,
4634 createLabel (ifFalse, NULL));
4636 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4637 if (IS_IFX (condAst))
4640 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4642 return newNode (NULLOP, ifTree,
4643 newNode (NULLOP, ifBody, elseBody));
4647 /*-----------------------------------------------------------------*/
4648 /* createDo - creates parse tree for do */
4651 /* _docontinue_n: */
4652 /* condition_expression +-> trueLabel -> _dobody_n */
4654 /* +-> falseLabel-> _dobreak_n */
4656 /*-----------------------------------------------------------------*/
4658 createDo (symbol * trueLabel, symbol * continueLabel,
4659 symbol * falseLabel, ast * condAst, ast * doBody)
4664 /* if the body does not exist then it is simple */
4667 condAst = backPatchLabels (condAst, continueLabel, NULL);
4668 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4669 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4670 doTree->trueLabel = continueLabel;
4671 doTree->falseLabel = NULL;
4675 /* otherwise we have a body */
4676 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4678 /* attach the body label to the top */
4679 doBody = createLabel (trueLabel, doBody);
4680 /* attach the continue label to end of body */
4681 doBody = newNode (NULLOP, doBody,
4682 createLabel (continueLabel, NULL));
4684 /* now put the break label at the end */
4685 if (IS_IFX (condAst))
4688 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4690 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4692 /* putting it together */
4693 return newNode (NULLOP, doBody, doTree);
4696 /*-----------------------------------------------------------------*/
4697 /* createFor - creates parse tree for 'for' statement */
4700 /* condExpr +-> trueLabel -> _forbody_n */
4702 /* +-> falseLabel-> _forbreak_n */
4705 /* _forcontinue_n: */
4707 /* goto _forcond_n ; */
4709 /*-----------------------------------------------------------------*/
4711 createFor (symbol * trueLabel, symbol * continueLabel,
4712 symbol * falseLabel, symbol * condLabel,
4713 ast * initExpr, ast * condExpr, ast * loopExpr,
4718 /* if loopexpression not present then we can generate it */
4719 /* the same way as a while */
4721 return newNode (NULLOP, initExpr,
4722 createWhile (trueLabel, continueLabel,
4723 falseLabel, condExpr, forBody));
4724 /* vanilla for statement */
4725 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4727 if (condExpr && !IS_IFX (condExpr))
4728 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4731 /* attach condition label to condition */
4732 condExpr = createLabel (condLabel, condExpr);
4734 /* attach body label to body */
4735 forBody = createLabel (trueLabel, forBody);
4737 /* attach continue to forLoop expression & attach */
4738 /* goto the forcond @ and of loopExpression */
4739 loopExpr = createLabel (continueLabel,
4743 newAst_VALUE (symbolVal (condLabel)),
4745 /* now start putting them together */
4746 forTree = newNode (NULLOP, initExpr, condExpr);
4747 forTree = newNode (NULLOP, forTree, forBody);
4748 forTree = newNode (NULLOP, forTree, loopExpr);
4749 /* finally add the break label */
4750 forTree = newNode (NULLOP, forTree,
4751 createLabel (falseLabel, NULL));
4755 /*-----------------------------------------------------------------*/
4756 /* createWhile - creates parse tree for while statement */
4757 /* the while statement will be created as follows */
4759 /* _while_continue_n: */
4760 /* condition_expression +-> trueLabel -> _while_boby_n */
4762 /* +-> falseLabel -> _while_break_n */
4763 /* _while_body_n: */
4765 /* goto _while_continue_n */
4766 /* _while_break_n: */
4767 /*-----------------------------------------------------------------*/
4769 createWhile (symbol * trueLabel, symbol * continueLabel,
4770 symbol * falseLabel, ast * condExpr, ast * whileBody)
4774 /* put the continue label */
4775 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4776 condExpr = createLabel (continueLabel, condExpr);
4777 condExpr->lineno = 0;
4779 /* put the body label in front of the body */
4780 whileBody = createLabel (trueLabel, whileBody);
4781 whileBody->lineno = 0;
4782 /* put a jump to continue at the end of the body */
4783 /* and put break label at the end of the body */
4784 whileBody = newNode (NULLOP,
4787 newAst_VALUE (symbolVal (continueLabel)),
4788 createLabel (falseLabel, NULL)));
4790 /* put it all together */
4791 if (IS_IFX (condExpr))
4792 whileTree = condExpr;
4795 whileTree = newNode (IFX, condExpr, NULL);
4796 /* put the true & false labels in place */
4797 whileTree->trueLabel = trueLabel;
4798 whileTree->falseLabel = falseLabel;
4801 return newNode (NULLOP, whileTree, whileBody);
4804 /*-----------------------------------------------------------------*/
4805 /* optimizeGetHbit - get highest order bit of the expression */
4806 /*-----------------------------------------------------------------*/
4808 optimizeGetHbit (ast * tree)
4811 /* if this is not a bit and */
4812 if (!IS_BITAND (tree))
4815 /* will look for tree of the form
4816 ( expr >> ((sizeof expr) -1) ) & 1 */
4817 if (!IS_AST_LIT_VALUE (tree->right))
4820 if (AST_LIT_VALUE (tree->right) != 1)
4823 if (!IS_RIGHT_OP (tree->left))
4826 if (!IS_AST_LIT_VALUE (tree->left->right))
4829 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4830 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4833 /* make sure the port supports GETHBIT */
4834 if (port->hasExtBitOp
4835 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4838 return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_CHECK);
4842 /*-----------------------------------------------------------------*/
4843 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4844 /*-----------------------------------------------------------------*/
4846 optimizeRRCRLC (ast * root)
4848 /* will look for trees of the form
4849 (?expr << 1) | (?expr >> 7) or
4850 (?expr >> 7) | (?expr << 1) will make that
4851 into a RLC : operation ..
4853 (?expr >> 1) | (?expr << 7) or
4854 (?expr << 7) | (?expr >> 1) will make that
4855 into a RRC operation
4856 note : by 7 I mean (number of bits required to hold the
4858 /* if the root operations is not a | operation the not */
4859 if (!IS_BITOR (root))
4862 /* I have to think of a better way to match patterns this sucks */
4863 /* that aside let start looking for the first case : I use a the
4864 negative check a lot to improve the efficiency */
4865 /* (?expr << 1) | (?expr >> 7) */
4866 if (IS_LEFT_OP (root->left) &&
4867 IS_RIGHT_OP (root->right))
4870 if (!SPEC_USIGN (TETYPE (root->left->left)))
4873 if (!IS_AST_LIT_VALUE (root->left->right) ||
4874 !IS_AST_LIT_VALUE (root->right->right))
4877 /* make sure it is the same expression */
4878 if (!isAstEqual (root->left->left,
4882 if (AST_LIT_VALUE (root->left->right) != 1)
4885 if (AST_LIT_VALUE (root->right->right) !=
4886 (getSize (TTYPE (root->left->left)) * 8 - 1))
4889 /* make sure the port supports RLC */
4890 if (port->hasExtBitOp
4891 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4894 /* whew got the first case : create the AST */
4895 return newNode (RLC, root->left->left, NULL);
4899 /* check for second case */
4900 /* (?expr >> 7) | (?expr << 1) */
4901 if (IS_LEFT_OP (root->right) &&
4902 IS_RIGHT_OP (root->left))
4905 if (!SPEC_USIGN (TETYPE (root->left->left)))
4908 if (!IS_AST_LIT_VALUE (root->left->right) ||
4909 !IS_AST_LIT_VALUE (root->right->right))
4912 /* make sure it is the same symbol */
4913 if (!isAstEqual (root->left->left,
4917 if (AST_LIT_VALUE (root->right->right) != 1)
4920 if (AST_LIT_VALUE (root->left->right) !=
4921 (getSize (TTYPE (root->left->left)) * 8 - 1))
4924 /* make sure the port supports RLC */
4925 if (port->hasExtBitOp
4926 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4929 /* whew got the first case : create the AST */
4930 return newNode (RLC, root->left->left, NULL);
4935 /* third case for RRC */
4936 /* (?symbol >> 1) | (?symbol << 7) */
4937 if (IS_LEFT_OP (root->right) &&
4938 IS_RIGHT_OP (root->left))
4941 if (!SPEC_USIGN (TETYPE (root->left->left)))
4944 if (!IS_AST_LIT_VALUE (root->left->right) ||
4945 !IS_AST_LIT_VALUE (root->right->right))
4948 /* make sure it is the same symbol */
4949 if (!isAstEqual (root->left->left,
4953 if (AST_LIT_VALUE (root->left->right) != 1)
4956 if (AST_LIT_VALUE (root->right->right) !=
4957 (getSize (TTYPE (root->left->left)) * 8 - 1))
4960 /* make sure the port supports RRC */
4961 if (port->hasExtBitOp
4962 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4965 /* whew got the first case : create the AST */
4966 return newNode (RRC, root->left->left, NULL);
4970 /* fourth and last case for now */
4971 /* (?symbol << 7) | (?symbol >> 1) */
4972 if (IS_RIGHT_OP (root->right) &&
4973 IS_LEFT_OP (root->left))
4976 if (!SPEC_USIGN (TETYPE (root->left->left)))
4979 if (!IS_AST_LIT_VALUE (root->left->right) ||
4980 !IS_AST_LIT_VALUE (root->right->right))
4983 /* make sure it is the same symbol */
4984 if (!isAstEqual (root->left->left,
4988 if (AST_LIT_VALUE (root->right->right) != 1)
4991 if (AST_LIT_VALUE (root->left->right) !=
4992 (getSize (TTYPE (root->left->left)) * 8 - 1))
4995 /* make sure the port supports RRC */
4996 if (port->hasExtBitOp
4997 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5000 /* whew got the first case : create the AST */
5001 return newNode (RRC, root->left->left, NULL);
5005 /* not found return root */
5009 /*-----------------------------------------------------------------*/
5010 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
5011 /*-----------------------------------------------------------------*/
5013 optimizeSWAP (ast * root)
5015 /* will look for trees of the form
5016 (?expr << 4) | (?expr >> 4) or
5017 (?expr >> 4) | (?expr << 4) will make that
5018 into a SWAP : operation ..
5019 note : by 4 I mean (number of bits required to hold the
5021 /* if the root operations is not a | operation the not */
5022 if (!IS_BITOR (root))
5025 /* (?expr << 4) | (?expr >> 4) */
5026 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5027 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5030 if (!SPEC_USIGN (TETYPE (root->left->left)))
5033 if (!IS_AST_LIT_VALUE (root->left->right) ||
5034 !IS_AST_LIT_VALUE (root->right->right))
5037 /* make sure it is the same expression */
5038 if (!isAstEqual (root->left->left,
5042 if (AST_LIT_VALUE (root->left->right) !=
5043 (getSize (TTYPE (root->left->left)) * 4))
5046 if (AST_LIT_VALUE (root->right->right) !=
5047 (getSize (TTYPE (root->left->left)) * 4))
5050 /* make sure the port supports SWAP */
5051 if (port->hasExtBitOp
5052 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5055 /* found it : create the AST */
5056 return newNode (SWAP, root->left->left, NULL);
5060 /* not found return root */
5064 /*-----------------------------------------------------------------*/
5065 /* optimizeCompare - otimizes compares for bit variables */
5066 /*-----------------------------------------------------------------*/
5068 optimizeCompare (ast * root)
5070 ast *optExpr = NULL;
5073 unsigned int litValue;
5075 /* if nothing then return nothing */
5079 /* if not a compare op then do leaves */
5080 if (!IS_COMPARE_OP (root))
5082 root->left = optimizeCompare (root->left);
5083 root->right = optimizeCompare (root->right);
5087 /* if left & right are the same then depending
5088 of the operation do */
5089 if (isAstEqual (root->left, root->right))
5091 switch (root->opval.op)
5096 optExpr = newAst_VALUE (constVal ("0"));
5101 optExpr = newAst_VALUE (constVal ("1"));
5105 return decorateType (optExpr, RESULT_CHECK);
5108 vleft = (root->left->type == EX_VALUE ?
5109 root->left->opval.val : NULL);
5111 vright = (root->right->type == EX_VALUE ?
5112 root->right->opval.val : NULL);
5114 /* if left is a BITVAR in BITSPACE */
5115 /* and right is a LITERAL then opt- */
5116 /* imize else do nothing */
5117 if (vleft && vright &&
5118 IS_BITVAR (vleft->etype) &&
5119 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5120 IS_LITERAL (vright->etype))
5123 /* if right side > 1 then comparison may never succeed */
5124 if ((litValue = (int) floatFromVal (vright)) > 1)
5126 werror (W_BAD_COMPARE);
5132 switch (root->opval.op)
5134 case '>': /* bit value greater than 1 cannot be */
5135 werror (W_BAD_COMPARE);
5139 case '<': /* bit value < 1 means 0 */
5141 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5144 case LE_OP: /* bit value <= 1 means no check */
5145 optExpr = newAst_VALUE (vright);
5148 case GE_OP: /* bit value >= 1 means only check for = */
5150 optExpr = newAst_VALUE (vleft);
5155 { /* literal is zero */
5156 switch (root->opval.op)
5158 case '<': /* bit value < 0 cannot be */
5159 werror (W_BAD_COMPARE);
5163 case '>': /* bit value > 0 means 1 */
5165 optExpr = newAst_VALUE (vleft);
5168 case LE_OP: /* bit value <= 0 means no check */
5169 case GE_OP: /* bit value >= 0 means no check */
5170 werror (W_BAD_COMPARE);
5174 case EQ_OP: /* bit == 0 means ! of bit */
5175 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5179 return decorateType (resolveSymbols (optExpr), RESULT_CHECK);
5180 } /* end-of-if of BITVAR */
5185 /*-----------------------------------------------------------------*/
5186 /* addSymToBlock : adds the symbol to the first block we find */
5187 /*-----------------------------------------------------------------*/
5189 addSymToBlock (symbol * sym, ast * tree)
5191 /* reached end of tree or a leaf */
5192 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5196 if (IS_AST_OP (tree) &&
5197 tree->opval.op == BLOCK)
5200 symbol *lsym = copySymbol (sym);
5202 lsym->next = AST_VALUES (tree, sym);
5203 AST_VALUES (tree, sym) = lsym;
5207 addSymToBlock (sym, tree->left);
5208 addSymToBlock (sym, tree->right);
5211 /*-----------------------------------------------------------------*/
5212 /* processRegParms - do processing for register parameters */
5213 /*-----------------------------------------------------------------*/
5215 processRegParms (value * args, ast * body)
5219 if (IS_REGPARM (args->etype))
5220 addSymToBlock (args->sym, body);
5225 /*-----------------------------------------------------------------*/
5226 /* resetParmKey - resets the operandkeys for the symbols */
5227 /*-----------------------------------------------------------------*/
5228 DEFSETFUNC (resetParmKey)
5239 /*-----------------------------------------------------------------*/
5240 /* createFunction - This is the key node that calls the iCode for */
5241 /* generating the code for a function. Note code */
5242 /* is generated function by function, later when */
5243 /* add inter-procedural analysis this will change */
5244 /*-----------------------------------------------------------------*/
5246 createFunction (symbol * name, ast * body)
5252 iCode *piCode = NULL;
5254 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5255 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5257 /* if check function return 0 then some problem */
5258 if (checkFunction (name, NULL) == 0)
5261 /* create a dummy block if none exists */
5263 body = newNode (BLOCK, NULL, NULL);
5267 /* check if the function name already in the symbol table */
5268 if ((csym = findSym (SymbolTab, NULL, name->name)))
5271 /* special case for compiler defined functions
5272 we need to add the name to the publics list : this
5273 actually means we are now compiling the compiler
5277 addSet (&publics, name);
5283 allocVariables (name);
5285 name->lastLine = mylineno;
5288 /* set the stack pointer */
5289 /* PENDING: check this for the mcs51 */
5290 stackPtr = -port->stack.direction * port->stack.call_overhead;
5291 if (IFFUNC_ISISR (name->type))
5292 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5293 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5294 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5296 xstackPtr = -port->stack.direction * port->stack.call_overhead;
5298 fetype = getSpec (name->type); /* get the specifier for the function */
5299 /* if this is a reentrant function then */
5300 if (IFFUNC_ISREENT (name->type))
5303 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5305 /* do processing for parameters that are passed in registers */
5306 processRegParms (FUNC_ARGS(name->type), body);
5308 /* set the stack pointer */
5312 /* allocate & autoinit the block variables */
5313 processBlockVars (body, &stack, ALLOCATE);
5315 /* save the stack information */
5316 if (options.useXstack)
5317 name->xstack = SPEC_STAK (fetype) = stack;
5319 name->stack = SPEC_STAK (fetype) = stack;
5321 /* name needs to be mangled */
5322 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5324 body = resolveSymbols (body); /* resolve the symbols */
5325 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5328 ex = newAst_VALUE (symbolVal (name)); /* create name */
5329 ex = newNode (FUNCTION, ex, body);
5330 ex->values.args = FUNC_ARGS(name->type);
5332 if (options.dump_tree) PA(ex);
5335 werror (E_FUNC_NO_CODE, name->name);
5339 /* create the node & generate intermediate code */
5341 codeOutFile = code->oFile;
5342 piCode = iCodeFromAst (ex);
5346 werror (E_FUNC_NO_CODE, name->name);
5350 eBBlockFromiCode (piCode);
5352 /* if there are any statics then do them */
5355 GcurMemmap = statsg;
5356 codeOutFile = statsg->oFile;
5357 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_CHECK)));
5363 /* dealloc the block variables */
5364 processBlockVars (body, &stack, DEALLOCATE);
5365 outputDebugStackSymbols();
5366 /* deallocate paramaters */
5367 deallocParms (FUNC_ARGS(name->type));
5369 if (IFFUNC_ISREENT (name->type))
5372 /* we are done freeup memory & cleanup */
5374 if (port->reset_labelKey) labelKey = 1;
5376 FUNC_HASBODY(name->type) = 1;
5377 addSet (&operKeyReset, name);
5378 applyToSet (operKeyReset, resetParmKey);
5383 cleanUpLevel (LabelTab, 0);
5384 cleanUpBlock (StructTab, 1);
5385 cleanUpBlock (TypedefTab, 1);
5387 xstack->syms = NULL;
5388 istack->syms = NULL;
5393 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5394 /*-----------------------------------------------------------------*/
5395 /* ast_print : prints the ast (for debugging purposes) */
5396 /*-----------------------------------------------------------------*/
5398 void ast_print (ast * tree, FILE *outfile, int indent)
5403 /* can print only decorated trees */
5404 if (!tree->decorated) return;
5406 /* if any child is an error | this one is an error do nothing */
5407 if (tree->isError ||
5408 (tree->left && tree->left->isError) ||
5409 (tree->right && tree->right->isError)) {
5410 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5414 /* print the line */
5415 /* if not block & function */
5416 if (tree->type == EX_OP &&
5417 (tree->opval.op != FUNCTION &&
5418 tree->opval.op != BLOCK &&
5419 tree->opval.op != NULLOP)) {
5422 if (tree->opval.op == FUNCTION) {
5424 value *args=FUNC_ARGS(tree->left->opval.val->type);
5425 fprintf(outfile,"FUNCTION (%s=%p) type (",
5426 tree->left->opval.val->name, tree);
5427 printTypeChain (tree->left->opval.val->type->next,outfile);
5428 fprintf(outfile,") args (");
5431 fprintf (outfile, ", ");
5433 printTypeChain (args ? args->type : NULL, outfile);
5435 args= args ? args->next : NULL;
5437 fprintf(outfile,")\n");
5438 ast_print(tree->left,outfile,indent);
5439 ast_print(tree->right,outfile,indent);
5442 if (tree->opval.op == BLOCK) {
5443 symbol *decls = tree->values.sym;
5444 INDENT(indent,outfile);
5445 fprintf(outfile,"{\n");
5447 INDENT(indent+2,outfile);
5448 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5449 decls->name, decls);
5450 printTypeChain(decls->type,outfile);
5451 fprintf(outfile,")\n");
5453 decls = decls->next;
5455 ast_print(tree->right,outfile,indent+2);
5456 INDENT(indent,outfile);
5457 fprintf(outfile,"}\n");
5460 if (tree->opval.op == NULLOP) {
5461 ast_print(tree->left,outfile,indent);
5462 ast_print(tree->right,outfile,indent);
5465 INDENT(indent,outfile);
5467 /*------------------------------------------------------------------*/
5468 /*----------------------------*/
5469 /* leaf has been reached */
5470 /*----------------------------*/
5471 /* if this is of type value */
5472 /* just get the type */
5473 if (tree->type == EX_VALUE) {
5475 if (IS_LITERAL (tree->opval.val->etype)) {
5476 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5477 if (SPEC_USIGN (tree->opval.val->etype))
5478 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5480 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5481 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5482 floatFromVal(tree->opval.val));
5483 } else if (tree->opval.val->sym) {
5484 /* if the undefined flag is set then give error message */
5485 if (tree->opval.val->sym->undefined) {
5486 fprintf(outfile,"UNDEFINED SYMBOL ");
5488 fprintf(outfile,"SYMBOL ");
5490 fprintf(outfile,"(%s=%p)",
5491 tree->opval.val->sym->name,tree);
5494 fprintf(outfile," type (");
5495 printTypeChain(tree->ftype,outfile);
5496 fprintf(outfile,")\n");
5498 fprintf(outfile,"\n");
5503 /* if type link for the case of cast */
5504 if (tree->type == EX_LINK) {
5505 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5506 printTypeChain(tree->opval.lnk,outfile);
5507 fprintf(outfile,")\n");
5512 /* depending on type of operator do */
5514 switch (tree->opval.op) {
5515 /*------------------------------------------------------------------*/
5516 /*----------------------------*/
5518 /*----------------------------*/
5520 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5521 printTypeChain(tree->ftype,outfile);
5522 fprintf(outfile,")\n");
5523 ast_print(tree->left,outfile,indent+2);
5524 ast_print(tree->right,outfile,indent+2);
5527 /*------------------------------------------------------------------*/
5528 /*----------------------------*/
5530 /*----------------------------*/
5532 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5533 printTypeChain(tree->ftype,outfile);
5534 fprintf(outfile,")\n");
5535 ast_print(tree->left,outfile,indent+2);
5536 ast_print(tree->right,outfile,indent+2);
5539 /*------------------------------------------------------------------*/
5540 /*----------------------------*/
5541 /* struct/union pointer */
5542 /*----------------------------*/
5544 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5545 printTypeChain(tree->ftype,outfile);
5546 fprintf(outfile,")\n");
5547 ast_print(tree->left,outfile,indent+2);
5548 ast_print(tree->right,outfile,indent+2);
5551 /*------------------------------------------------------------------*/
5552 /*----------------------------*/
5553 /* ++/-- operation */
5554 /*----------------------------*/
5557 fprintf(outfile,"post-");
5559 fprintf(outfile,"pre-");
5560 fprintf(outfile,"INC_OP (%p) type (",tree);
5561 printTypeChain(tree->ftype,outfile);
5562 fprintf(outfile,")\n");
5563 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5564 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5569 fprintf(outfile,"post-");
5571 fprintf(outfile,"pre-");
5572 fprintf(outfile,"DEC_OP (%p) type (",tree);
5573 printTypeChain(tree->ftype,outfile);
5574 fprintf(outfile,")\n");
5575 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5576 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5579 /*------------------------------------------------------------------*/
5580 /*----------------------------*/
5582 /*----------------------------*/
5585 fprintf(outfile,"& (%p) type (",tree);
5586 printTypeChain(tree->ftype,outfile);
5587 fprintf(outfile,")\n");
5588 ast_print(tree->left,outfile,indent+2);
5589 ast_print(tree->right,outfile,indent+2);
5591 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5592 printTypeChain(tree->ftype,outfile);
5593 fprintf(outfile,")\n");
5594 ast_print(tree->left,outfile,indent+2);
5595 ast_print(tree->right,outfile,indent+2);
5598 /*----------------------------*/
5600 /*----------------------------*/
5602 fprintf(outfile,"OR (%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 /*------------------------------------------------------------------*/
5609 /*----------------------------*/
5611 /*----------------------------*/
5613 fprintf(outfile,"XOR (%p) type (",tree);
5614 printTypeChain(tree->ftype,outfile);
5615 fprintf(outfile,")\n");
5616 ast_print(tree->left,outfile,indent+2);
5617 ast_print(tree->right,outfile,indent+2);
5620 /*------------------------------------------------------------------*/
5621 /*----------------------------*/
5623 /*----------------------------*/
5625 fprintf(outfile,"DIV (%p) type (",tree);
5626 printTypeChain(tree->ftype,outfile);
5627 fprintf(outfile,")\n");
5628 ast_print(tree->left,outfile,indent+2);
5629 ast_print(tree->right,outfile,indent+2);
5631 /*------------------------------------------------------------------*/
5632 /*----------------------------*/
5634 /*----------------------------*/
5636 fprintf(outfile,"MOD (%p) type (",tree);
5637 printTypeChain(tree->ftype,outfile);
5638 fprintf(outfile,")\n");
5639 ast_print(tree->left,outfile,indent+2);
5640 ast_print(tree->right,outfile,indent+2);
5643 /*------------------------------------------------------------------*/
5644 /*----------------------------*/
5645 /* address dereference */
5646 /*----------------------------*/
5647 case '*': /* can be unary : if right is null then unary operation */
5649 fprintf(outfile,"DEREF (%p) type (",tree);
5650 printTypeChain(tree->ftype,outfile);
5651 fprintf(outfile,")\n");
5652 ast_print(tree->left,outfile,indent+2);
5655 /*------------------------------------------------------------------*/
5656 /*----------------------------*/
5657 /* multiplication */
5658 /*----------------------------*/
5659 fprintf(outfile,"MULT (%p) type (",tree);
5660 printTypeChain(tree->ftype,outfile);
5661 fprintf(outfile,")\n");
5662 ast_print(tree->left,outfile,indent+2);
5663 ast_print(tree->right,outfile,indent+2);
5667 /*------------------------------------------------------------------*/
5668 /*----------------------------*/
5669 /* unary '+' operator */
5670 /*----------------------------*/
5674 fprintf(outfile,"UPLUS (%p) type (",tree);
5675 printTypeChain(tree->ftype,outfile);
5676 fprintf(outfile,")\n");
5677 ast_print(tree->left,outfile,indent+2);
5679 /*------------------------------------------------------------------*/
5680 /*----------------------------*/
5682 /*----------------------------*/
5683 fprintf(outfile,"ADD (%p) type (",tree);
5684 printTypeChain(tree->ftype,outfile);
5685 fprintf(outfile,")\n");
5686 ast_print(tree->left,outfile,indent+2);
5687 ast_print(tree->right,outfile,indent+2);
5690 /*------------------------------------------------------------------*/
5691 /*----------------------------*/
5693 /*----------------------------*/
5694 case '-': /* can be unary */
5696 fprintf(outfile,"UMINUS (%p) type (",tree);
5697 printTypeChain(tree->ftype,outfile);
5698 fprintf(outfile,")\n");
5699 ast_print(tree->left,outfile,indent+2);
5701 /*------------------------------------------------------------------*/
5702 /*----------------------------*/
5704 /*----------------------------*/
5705 fprintf(outfile,"SUB (%p) type (",tree);
5706 printTypeChain(tree->ftype,outfile);
5707 fprintf(outfile,")\n");
5708 ast_print(tree->left,outfile,indent+2);
5709 ast_print(tree->right,outfile,indent+2);
5712 /*------------------------------------------------------------------*/
5713 /*----------------------------*/
5715 /*----------------------------*/
5717 fprintf(outfile,"COMPL (%p) type (",tree);
5718 printTypeChain(tree->ftype,outfile);
5719 fprintf(outfile,")\n");
5720 ast_print(tree->left,outfile,indent+2);
5722 /*------------------------------------------------------------------*/
5723 /*----------------------------*/
5725 /*----------------------------*/
5727 fprintf(outfile,"NOT (%p) type (",tree);
5728 printTypeChain(tree->ftype,outfile);
5729 fprintf(outfile,")\n");
5730 ast_print(tree->left,outfile,indent+2);
5732 /*------------------------------------------------------------------*/
5733 /*----------------------------*/
5735 /*----------------------------*/
5737 fprintf(outfile,"RRC (%p) type (",tree);
5738 printTypeChain(tree->ftype,outfile);
5739 fprintf(outfile,")\n");
5740 ast_print(tree->left,outfile,indent+2);
5744 fprintf(outfile,"RLC (%p) type (",tree);
5745 printTypeChain(tree->ftype,outfile);
5746 fprintf(outfile,")\n");
5747 ast_print(tree->left,outfile,indent+2);
5750 fprintf(outfile,"SWAP (%p) type (",tree);
5751 printTypeChain(tree->ftype,outfile);
5752 fprintf(outfile,")\n");
5753 ast_print(tree->left,outfile,indent+2);
5756 fprintf(outfile,"GETHBIT (%p) type (",tree);
5757 printTypeChain(tree->ftype,outfile);
5758 fprintf(outfile,")\n");
5759 ast_print(tree->left,outfile,indent+2);
5762 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5763 printTypeChain(tree->ftype,outfile);
5764 fprintf(outfile,")\n");
5765 ast_print(tree->left,outfile,indent+2);
5766 ast_print(tree->right,outfile,indent+2);
5769 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5770 printTypeChain(tree->ftype,outfile);
5771 fprintf(outfile,")\n");
5772 ast_print(tree->left,outfile,indent+2);
5773 ast_print(tree->right,outfile,indent+2);
5775 /*------------------------------------------------------------------*/
5776 /*----------------------------*/
5778 /*----------------------------*/
5779 case CAST: /* change the type */
5780 fprintf(outfile,"CAST (%p) from type (",tree);
5781 printTypeChain(tree->right->ftype,outfile);
5782 fprintf(outfile,") to type (");
5783 printTypeChain(tree->ftype,outfile);
5784 fprintf(outfile,")\n");
5785 ast_print(tree->right,outfile,indent+2);
5789 fprintf(outfile,"ANDAND (%p) type (",tree);
5790 printTypeChain(tree->ftype,outfile);
5791 fprintf(outfile,")\n");
5792 ast_print(tree->left,outfile,indent+2);
5793 ast_print(tree->right,outfile,indent+2);
5796 fprintf(outfile,"OROR (%p) type (",tree);
5797 printTypeChain(tree->ftype,outfile);
5798 fprintf(outfile,")\n");
5799 ast_print(tree->left,outfile,indent+2);
5800 ast_print(tree->right,outfile,indent+2);
5803 /*------------------------------------------------------------------*/
5804 /*----------------------------*/
5805 /* comparison operators */
5806 /*----------------------------*/
5808 fprintf(outfile,"GT(>) (%p) type (",tree);
5809 printTypeChain(tree->ftype,outfile);
5810 fprintf(outfile,")\n");
5811 ast_print(tree->left,outfile,indent+2);
5812 ast_print(tree->right,outfile,indent+2);
5815 fprintf(outfile,"LT(<) (%p) type (",tree);
5816 printTypeChain(tree->ftype,outfile);
5817 fprintf(outfile,")\n");
5818 ast_print(tree->left,outfile,indent+2);
5819 ast_print(tree->right,outfile,indent+2);
5822 fprintf(outfile,"LE(<=) (%p) type (",tree);
5823 printTypeChain(tree->ftype,outfile);
5824 fprintf(outfile,")\n");
5825 ast_print(tree->left,outfile,indent+2);
5826 ast_print(tree->right,outfile,indent+2);
5829 fprintf(outfile,"GE(>=) (%p) type (",tree);
5830 printTypeChain(tree->ftype,outfile);
5831 fprintf(outfile,")\n");
5832 ast_print(tree->left,outfile,indent+2);
5833 ast_print(tree->right,outfile,indent+2);
5836 fprintf(outfile,"EQ(==) (%p) type (",tree);
5837 printTypeChain(tree->ftype,outfile);
5838 fprintf(outfile,")\n");
5839 ast_print(tree->left,outfile,indent+2);
5840 ast_print(tree->right,outfile,indent+2);
5843 fprintf(outfile,"NE(!=) (%p) type (",tree);
5844 printTypeChain(tree->ftype,outfile);
5845 fprintf(outfile,")\n");
5846 ast_print(tree->left,outfile,indent+2);
5847 ast_print(tree->right,outfile,indent+2);
5848 /*------------------------------------------------------------------*/
5849 /*----------------------------*/
5851 /*----------------------------*/
5852 case SIZEOF: /* evaluate wihout code generation */
5853 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5856 /*------------------------------------------------------------------*/
5857 /*----------------------------*/
5858 /* conditional operator '?' */
5859 /*----------------------------*/
5861 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5862 printTypeChain(tree->ftype,outfile);
5863 fprintf(outfile,")\n");
5864 ast_print(tree->left,outfile,indent+2);
5865 ast_print(tree->right,outfile,indent+2);
5869 fprintf(outfile,"COLON(:) (%p) type (",tree);
5870 printTypeChain(tree->ftype,outfile);
5871 fprintf(outfile,")\n");
5872 ast_print(tree->left,outfile,indent+2);
5873 ast_print(tree->right,outfile,indent+2);
5876 /*------------------------------------------------------------------*/
5877 /*----------------------------*/
5878 /* assignment operators */
5879 /*----------------------------*/
5881 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5882 printTypeChain(tree->ftype,outfile);
5883 fprintf(outfile,")\n");
5884 ast_print(tree->left,outfile,indent+2);
5885 ast_print(tree->right,outfile,indent+2);
5888 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5889 printTypeChain(tree->ftype,outfile);
5890 fprintf(outfile,")\n");
5891 ast_print(tree->left,outfile,indent+2);
5892 ast_print(tree->right,outfile,indent+2);
5895 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5896 printTypeChain(tree->ftype,outfile);
5897 fprintf(outfile,")\n");
5898 ast_print(tree->left,outfile,indent+2);
5899 ast_print(tree->right,outfile,indent+2);
5902 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5903 printTypeChain(tree->ftype,outfile);
5904 fprintf(outfile,")\n");
5905 ast_print(tree->left,outfile,indent+2);
5906 ast_print(tree->right,outfile,indent+2);
5909 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5910 printTypeChain(tree->ftype,outfile);
5911 fprintf(outfile,")\n");
5912 ast_print(tree->left,outfile,indent+2);
5913 ast_print(tree->right,outfile,indent+2);
5916 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5917 printTypeChain(tree->ftype,outfile);
5918 fprintf(outfile,")\n");
5919 ast_print(tree->left,outfile,indent+2);
5920 ast_print(tree->right,outfile,indent+2);
5923 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5924 printTypeChain(tree->ftype,outfile);
5925 fprintf(outfile,")\n");
5926 ast_print(tree->left,outfile,indent+2);
5927 ast_print(tree->right,outfile,indent+2);
5929 /*------------------------------------------------------------------*/
5930 /*----------------------------*/
5932 /*----------------------------*/
5934 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5935 printTypeChain(tree->ftype,outfile);
5936 fprintf(outfile,")\n");
5937 ast_print(tree->left,outfile,indent+2);
5938 ast_print(tree->right,outfile,indent+2);
5940 /*------------------------------------------------------------------*/
5941 /*----------------------------*/
5943 /*----------------------------*/
5945 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5946 printTypeChain(tree->ftype,outfile);
5947 fprintf(outfile,")\n");
5948 ast_print(tree->left,outfile,indent+2);
5949 ast_print(tree->right,outfile,indent+2);
5951 /*------------------------------------------------------------------*/
5952 /*----------------------------*/
5953 /* straight assignemnt */
5954 /*----------------------------*/
5956 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5957 printTypeChain(tree->ftype,outfile);
5958 fprintf(outfile,")\n");
5959 ast_print(tree->left,outfile,indent+2);
5960 ast_print(tree->right,outfile,indent+2);
5962 /*------------------------------------------------------------------*/
5963 /*----------------------------*/
5964 /* comma operator */
5965 /*----------------------------*/
5967 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5968 printTypeChain(tree->ftype,outfile);
5969 fprintf(outfile,")\n");
5970 ast_print(tree->left,outfile,indent+2);
5971 ast_print(tree->right,outfile,indent+2);
5973 /*------------------------------------------------------------------*/
5974 /*----------------------------*/
5976 /*----------------------------*/
5979 fprintf(outfile,"CALL (%p) type (",tree);
5980 printTypeChain(tree->ftype,outfile);
5981 fprintf(outfile,")\n");
5982 ast_print(tree->left,outfile,indent+2);
5983 ast_print(tree->right,outfile,indent+2);
5986 fprintf(outfile,"PARMS\n");
5987 ast_print(tree->left,outfile,indent+2);
5988 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5989 ast_print(tree->right,outfile,indent+2);
5992 /*------------------------------------------------------------------*/
5993 /*----------------------------*/
5994 /* return statement */
5995 /*----------------------------*/
5997 fprintf(outfile,"RETURN (%p) type (",tree);
5999 printTypeChain(tree->right->ftype,outfile);
6001 fprintf(outfile,")\n");
6002 ast_print(tree->right,outfile,indent+2);
6004 /*------------------------------------------------------------------*/
6005 /*----------------------------*/
6006 /* label statement */
6007 /*----------------------------*/
6009 fprintf(outfile,"LABEL (%p)\n",tree);
6010 ast_print(tree->left,outfile,indent+2);
6011 ast_print(tree->right,outfile,indent);
6013 /*------------------------------------------------------------------*/
6014 /*----------------------------*/
6015 /* switch statement */
6016 /*----------------------------*/
6020 fprintf(outfile,"SWITCH (%p) ",tree);
6021 ast_print(tree->left,outfile,0);
6022 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
6023 INDENT(indent+2,outfile);
6024 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
6025 (int) floatFromVal(val),
6026 tree->values.switchVals.swNum,
6027 (int) floatFromVal(val));
6029 ast_print(tree->right,outfile,indent);
6032 /*------------------------------------------------------------------*/
6033 /*----------------------------*/
6035 /*----------------------------*/
6037 fprintf(outfile,"IF (%p) \n",tree);
6038 ast_print(tree->left,outfile,indent+2);
6039 if (tree->trueLabel) {
6040 INDENT(indent+2,outfile);
6041 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
6043 if (tree->falseLabel) {
6044 INDENT(indent+2,outfile);
6045 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
6047 ast_print(tree->right,outfile,indent+2);
6049 /*----------------------------*/
6050 /* goto Statement */
6051 /*----------------------------*/
6053 fprintf(outfile,"GOTO (%p) \n",tree);
6054 ast_print(tree->left,outfile,indent+2);
6055 fprintf(outfile,"\n");
6057 /*------------------------------------------------------------------*/
6058 /*----------------------------*/
6060 /*----------------------------*/
6062 fprintf(outfile,"FOR (%p) \n",tree);
6063 if (AST_FOR( tree, initExpr)) {
6064 INDENT(indent+2,outfile);
6065 fprintf(outfile,"INIT EXPR ");
6066 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6068 if (AST_FOR( tree, condExpr)) {
6069 INDENT(indent+2,outfile);
6070 fprintf(outfile,"COND EXPR ");
6071 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6073 if (AST_FOR( tree, loopExpr)) {
6074 INDENT(indent+2,outfile);
6075 fprintf(outfile,"LOOP EXPR ");
6076 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6078 fprintf(outfile,"FOR LOOP BODY \n");
6079 ast_print(tree->left,outfile,indent+2);
6082 fprintf(outfile,"CRITICAL (%p) \n",tree);
6083 ast_print(tree->left,outfile,indent+2);
6091 ast_print(t,stdout,0);
6096 /*-----------------------------------------------------------------*/
6097 /* astErrors : returns non-zero if errors present in tree */
6098 /*-----------------------------------------------------------------*/
6099 int astErrors(ast *t)
6108 if (t->type == EX_VALUE
6109 && t->opval.val->sym
6110 && t->opval.val->sym->undefined)
6113 errors += astErrors(t->left);
6114 errors += astErrors(t->right);