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 // there has to be a better way
959 char *name=sym->opval.val->sym->name;
960 int lineno=sym->opval.val->sym->lineDef;
961 char *filename=sym->opval.val->sym->fileDef;
962 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
969 /* if we have not been given a size */
970 if (!DCL_ELEM (type))
972 DCL_ELEM (type) = size;
975 return decorateType (resolveSymbols (rast), RESULT_CHECK);
979 /*-----------------------------------------------------------------*/
980 /* createIvalCharPtr - generates initial values for char pointers */
981 /*-----------------------------------------------------------------*/
983 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
987 /* if this is a pointer & right is a literal array then */
988 /* just assignment will do */
989 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
990 SPEC_SCLS (iexpr->etype) == S_CODE)
991 && IS_ARRAY (iexpr->ftype)))
992 return newNode ('=', sym, iexpr);
994 /* left side is an array so we have to assign each */
996 if ((IS_LITERAL (iexpr->etype) ||
997 SPEC_SCLS (iexpr->etype) == S_CODE)
998 && IS_ARRAY (iexpr->ftype))
1000 /* for each character generate an assignment */
1001 /* to the array element */
1002 char *s = SPEC_CVAL (iexpr->etype).v_char;
1004 int size = getSize (iexpr->ftype);
1005 int symsize = getSize (type);
1009 if (size>(symsize+1))
1010 werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1011 "string", sym->opval.val->sym->name);
1015 for (i=0;i<size;i++)
1017 rast = newNode (NULLOP,
1021 newAst_VALUE (valueFromLit ((float) i))),
1022 newAst_VALUE (valueFromLit (*s))));
1026 // now WE don't need iexpr's symbol anymore
1027 freeStringSymbol(AST_SYMBOL(iexpr));
1029 return decorateType (resolveSymbols (rast), RESULT_CHECK);
1035 /*-----------------------------------------------------------------*/
1036 /* createIvalPtr - generates initial value for pointers */
1037 /*-----------------------------------------------------------------*/
1039 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
1045 if (ilist->type == INIT_DEEP)
1046 ilist = ilist->init.deep;
1048 iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK);
1050 /* if character pointer */
1051 if (IS_CHAR (type->next))
1052 if ((rast = createIvalCharPtr (sym, type, iexpr)))
1055 return newNode ('=', sym, iexpr);
1058 /*-----------------------------------------------------------------*/
1059 /* createIval - generates code for initial value */
1060 /*-----------------------------------------------------------------*/
1062 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1069 /* if structure then */
1070 if (IS_STRUCT (type))
1071 rast = createIvalStruct (sym, type, ilist);
1073 /* if this is a pointer */
1075 rast = createIvalPtr (sym, type, ilist);
1077 /* if this is an array */
1078 if (IS_ARRAY (type))
1079 rast = createIvalArray (sym, type, ilist);
1081 /* if type is SPECIFIER */
1083 rast = createIvalType (sym, type, ilist);
1086 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_CHECK);
1088 return decorateType (resolveSymbols (rast), RESULT_CHECK);
1091 /*-----------------------------------------------------------------*/
1092 /* initAggregates - initialises aggregate variables with initv */
1093 /*-----------------------------------------------------------------*/
1094 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1095 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1098 /*-----------------------------------------------------------------*/
1099 /* gatherAutoInit - creates assignment expressions for initial */
1101 /*-----------------------------------------------------------------*/
1103 gatherAutoInit (symbol * autoChain)
1110 for (sym = autoChain; sym; sym = sym->next)
1113 /* resolve the symbols in the ival */
1115 resolveIvalSym (sym->ival, sym->type);
1117 /* if this is a static variable & has an */
1118 /* initial value the code needs to be lifted */
1119 /* here to the main portion since they can be */
1120 /* initialised only once at the start */
1121 if (IS_STATIC (sym->etype) && sym->ival &&
1122 SPEC_SCLS (sym->etype) != S_CODE)
1126 /* insert the symbol into the symbol table */
1127 /* with level = 0 & name = rname */
1128 newSym = copySymbol (sym);
1129 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1131 /* now lift the code to main */
1132 if (IS_AGGREGATE (sym->type)) {
1133 work = initAggregates (sym, sym->ival, NULL);
1135 if (getNelements(sym->type, sym->ival)>1) {
1136 werrorfl (sym->fileDef, sym->lineDef,
1137 W_EXCESS_INITIALIZERS, "scalar",
1140 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1141 list2expr (sym->ival));
1144 setAstLineno (work, sym->lineDef);
1148 staticAutos = newNode (NULLOP, staticAutos, work);
1155 /* if there is an initial value */
1156 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1158 initList *ilist=sym->ival;
1160 while (ilist->type == INIT_DEEP) {
1161 ilist = ilist->init.deep;
1164 /* update lineno for error msg */
1165 lineno=sym->lineDef;
1166 setAstLineno (ilist->init.node, lineno);
1168 if (IS_AGGREGATE (sym->type)) {
1169 work = initAggregates (sym, sym->ival, NULL);
1171 if (getNelements(sym->type, sym->ival)>1) {
1172 werrorfl (sym->fileDef, sym->lineDef,
1173 W_EXCESS_INITIALIZERS, "scalar",
1176 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1177 list2expr (sym->ival));
1181 setAstLineno (work, sym->lineDef);
1185 init = newNode (NULLOP, init, work);
1194 /*-----------------------------------------------------------------*/
1195 /* freeStringSymbol - delete a literal string if no more usage */
1196 /*-----------------------------------------------------------------*/
1197 void freeStringSymbol(symbol *sym) {
1198 /* make sure this is a literal string */
1199 assert (sym->isstrlit);
1200 if (--sym->isstrlit == 0) { // lower the usage count
1201 memmap *segment=SPEC_OCLS(sym->etype);
1203 deleteSetItem(&segment->syms, sym);
1208 /*-----------------------------------------------------------------*/
1209 /* stringToSymbol - creates a symbol from a literal string */
1210 /*-----------------------------------------------------------------*/
1212 stringToSymbol (value * val)
1214 char name[SDCC_NAME_MAX + 1];
1215 static int charLbl = 0;
1220 // have we heard this before?
1221 for (sp=statsg->syms; sp; sp=sp->next) {
1223 size = getSize (sym->type);
1224 if (sym->isstrlit && size == getSize (val->type) &&
1225 !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1226 // yes, this is old news. Don't publish it again.
1227 sym->isstrlit++; // but raise the usage count
1228 return symbolVal(sym);
1232 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1233 sym = newSymbol (name, 0); /* make it @ level 0 */
1234 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1236 /* copy the type from the value passed */
1237 sym->type = copyLinkChain (val->type);
1238 sym->etype = getSpec (sym->type);
1239 /* change to storage class & output class */
1240 SPEC_SCLS (sym->etype) = S_CODE;
1241 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1242 SPEC_STAT (sym->etype) = 1;
1243 /* make the level & block = 0 */
1244 sym->block = sym->level = 0;
1246 /* create an ival */
1247 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1252 allocVariables (sym);
1255 return symbolVal (sym);
1259 /*-----------------------------------------------------------------*/
1260 /* processBlockVars - will go thru the ast looking for block if */
1261 /* a block is found then will allocate the syms */
1262 /* will also gather the auto inits present */
1263 /*-----------------------------------------------------------------*/
1265 processBlockVars (ast * tree, int *stack, int action)
1270 /* if this is a block */
1271 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1275 if (action == ALLOCATE)
1277 *stack += allocVariables (tree->values.sym);
1278 autoInit = gatherAutoInit (tree->values.sym);
1280 /* if there are auto inits then do them */
1282 tree->left = newNode (NULLOP, autoInit, tree->left);
1284 else /* action is deallocate */
1285 deallocLocal (tree->values.sym);
1288 processBlockVars (tree->left, stack, action);
1289 processBlockVars (tree->right, stack, action);
1294 /*-------------------------------------------------------------*/
1295 /* constExprTree - returns TRUE if this tree is a constant */
1297 /*-------------------------------------------------------------*/
1298 bool constExprTree (ast *cexpr) {
1304 cexpr = decorateType (resolveSymbols (cexpr), RESULT_CHECK);
1306 switch (cexpr->type)
1309 if (IS_AST_LIT_VALUE(cexpr)) {
1310 // this is a literal
1313 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1314 // a function's address will never change
1317 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1318 // an array's address will never change
1321 if (IS_AST_SYM_VALUE(cexpr) &&
1322 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1323 // a symbol in code space will never change
1324 // This is only for the 'char *s="hallo"' case and will have to leave
1325 //printf(" code space symbol");
1330 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1331 "unexpected link in expression tree\n");
1334 if (cexpr->opval.op==ARRAYINIT) {
1335 // this is a list of literals
1338 if (cexpr->opval.op=='=') {
1339 return constExprTree(cexpr->right);
1341 if (cexpr->opval.op==CAST) {
1342 // cast ignored, maybe we should throw a warning here?
1343 return constExprTree(cexpr->right);
1345 if (cexpr->opval.op=='&') {
1348 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1351 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1356 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1361 /*-----------------------------------------------------------------*/
1362 /* constExprValue - returns the value of a constant expression */
1363 /* or NULL if it is not a constant expression */
1364 /*-----------------------------------------------------------------*/
1366 constExprValue (ast * cexpr, int check)
1368 cexpr = decorateType (resolveSymbols (cexpr), RESULT_CHECK);
1370 /* if this is not a constant then */
1371 if (!IS_LITERAL (cexpr->ftype))
1373 /* then check if this is a literal array
1375 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1376 SPEC_CVAL (cexpr->etype).v_char &&
1377 IS_ARRAY (cexpr->ftype))
1379 value *val = valFromType (cexpr->ftype);
1380 SPEC_SCLS (val->etype) = S_LITERAL;
1381 val->sym = cexpr->opval.val->sym;
1382 val->sym->type = copyLinkChain (cexpr->ftype);
1383 val->sym->etype = getSpec (val->sym->type);
1384 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1388 /* if we are casting a literal value then */
1389 if (IS_AST_OP (cexpr) &&
1390 cexpr->opval.op == CAST &&
1391 IS_LITERAL (cexpr->right->ftype))
1393 return valCastLiteral (cexpr->ftype,
1394 floatFromVal (cexpr->right->opval.val));
1397 if (IS_AST_VALUE (cexpr))
1399 return cexpr->opval.val;
1403 werror (E_CONST_EXPECTED, "found expression");
1408 /* return the value */
1409 return cexpr->opval.val;
1413 /*-----------------------------------------------------------------*/
1414 /* isLabelInAst - will return true if a given label is found */
1415 /*-----------------------------------------------------------------*/
1417 isLabelInAst (symbol * label, ast * tree)
1419 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1422 if (IS_AST_OP (tree) &&
1423 tree->opval.op == LABEL &&
1424 isSymbolEqual (AST_SYMBOL (tree->left), label))
1427 return isLabelInAst (label, tree->right) &&
1428 isLabelInAst (label, tree->left);
1432 /*-----------------------------------------------------------------*/
1433 /* isLoopCountable - return true if the loop count can be determi- */
1434 /* -ned at compile time . */
1435 /*-----------------------------------------------------------------*/
1437 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1438 symbol ** sym, ast ** init, ast ** end)
1441 /* the loop is considered countable if the following
1442 conditions are true :-
1444 a) initExpr :- <sym> = <const>
1445 b) condExpr :- <sym> < <const1>
1446 c) loopExpr :- <sym> ++
1449 /* first check the initExpr */
1450 if (IS_AST_OP (initExpr) &&
1451 initExpr->opval.op == '=' && /* is assignment */
1452 IS_AST_SYM_VALUE (initExpr->left))
1453 { /* left is a symbol */
1455 *sym = AST_SYMBOL (initExpr->left);
1456 *init = initExpr->right;
1461 /* for now the symbol has to be of
1463 if (!IS_INTEGRAL ((*sym)->type))
1466 /* now check condExpr */
1467 if (IS_AST_OP (condExpr))
1470 switch (condExpr->opval.op)
1473 if (IS_AST_SYM_VALUE (condExpr->left) &&
1474 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1475 IS_AST_LIT_VALUE (condExpr->right))
1477 *end = condExpr->right;
1483 if (IS_AST_OP (condExpr->left) &&
1484 condExpr->left->opval.op == '>' &&
1485 IS_AST_LIT_VALUE (condExpr->left->right) &&
1486 IS_AST_SYM_VALUE (condExpr->left->left) &&
1487 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1490 *end = newNode ('+', condExpr->left->right,
1491 newAst_VALUE (constVal ("1")));
1502 /* check loop expression is of the form <sym>++ */
1503 if (!IS_AST_OP (loopExpr))
1506 /* check if <sym> ++ */
1507 if (loopExpr->opval.op == INC_OP)
1513 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1514 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1521 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1522 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1530 if (loopExpr->opval.op == ADD_ASSIGN)
1533 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1534 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1535 IS_AST_LIT_VALUE (loopExpr->right) &&
1536 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1544 /*-----------------------------------------------------------------*/
1545 /* astHasVolatile - returns true if ast contains any volatile */
1546 /*-----------------------------------------------------------------*/
1548 astHasVolatile (ast * tree)
1553 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1556 if (IS_AST_OP (tree))
1557 return astHasVolatile (tree->left) ||
1558 astHasVolatile (tree->right);
1563 /*-----------------------------------------------------------------*/
1564 /* astHasPointer - return true if the ast contains any ptr variable */
1565 /*-----------------------------------------------------------------*/
1567 astHasPointer (ast * tree)
1572 if (IS_AST_LINK (tree))
1575 /* if we hit an array expression then check
1576 only the left side */
1577 if (IS_AST_OP (tree) && tree->opval.op == '[')
1578 return astHasPointer (tree->left);
1580 if (IS_AST_VALUE (tree))
1581 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1583 return astHasPointer (tree->left) ||
1584 astHasPointer (tree->right);
1588 /*-----------------------------------------------------------------*/
1589 /* astHasSymbol - return true if the ast has the given symbol */
1590 /*-----------------------------------------------------------------*/
1592 astHasSymbol (ast * tree, symbol * sym)
1594 if (!tree || IS_AST_LINK (tree))
1597 if (IS_AST_VALUE (tree))
1599 if (IS_AST_SYM_VALUE (tree))
1600 return isSymbolEqual (AST_SYMBOL (tree), sym);
1605 return astHasSymbol (tree->left, sym) ||
1606 astHasSymbol (tree->right, sym);
1609 /*-----------------------------------------------------------------*/
1610 /* astHasDeref - return true if the ast has an indirect access */
1611 /*-----------------------------------------------------------------*/
1613 astHasDeref (ast * tree)
1615 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1618 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1620 return astHasDeref (tree->left) || astHasDeref (tree->right);
1623 /*-----------------------------------------------------------------*/
1624 /* isConformingBody - the loop body has to conform to a set of rules */
1625 /* for the loop to be considered reversible read on for rules */
1626 /*-----------------------------------------------------------------*/
1628 isConformingBody (ast * pbody, symbol * sym, ast * body)
1631 /* we are going to do a pre-order traversal of the
1632 tree && check for the following conditions. (essentially
1633 a set of very shallow tests )
1634 a) the sym passed does not participate in
1635 any arithmetic operation
1636 b) There are no function calls
1637 c) all jumps are within the body
1638 d) address of loop control variable not taken
1639 e) if an assignment has a pointer on the
1640 left hand side make sure right does not have
1641 loop control variable */
1643 /* if we reach the end or a leaf then true */
1644 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1647 /* if anything else is "volatile" */
1648 if (IS_VOLATILE (TETYPE (pbody)))
1651 /* we will walk the body in a pre-order traversal for
1653 switch (pbody->opval.op)
1655 /*------------------------------------------------------------------*/
1657 // if the loopvar is used as an index
1658 /* array op is commutative -- must check both left & right */
1659 if (astHasSymbol(pbody->right, sym) || astHasSymbol(pbody->left, sym)) {
1662 return isConformingBody (pbody->right, sym, body)
1663 && isConformingBody (pbody->left, sym, body);
1665 /*------------------------------------------------------------------*/
1670 /*------------------------------------------------------------------*/
1674 /* sure we are not sym is not modified */
1676 IS_AST_SYM_VALUE (pbody->left) &&
1677 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1681 IS_AST_SYM_VALUE (pbody->right) &&
1682 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1687 /*------------------------------------------------------------------*/
1689 case '*': /* can be unary : if right is null then unary operation */
1694 /* if right is NULL then unary operation */
1695 /*------------------------------------------------------------------*/
1696 /*----------------------------*/
1698 /*----------------------------*/
1701 if (IS_AST_SYM_VALUE (pbody->left) &&
1702 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1705 return isConformingBody (pbody->left, sym, body);
1709 if (astHasSymbol (pbody->left, sym) ||
1710 astHasSymbol (pbody->right, sym))
1715 /*------------------------------------------------------------------*/
1723 if (IS_AST_SYM_VALUE (pbody->left) &&
1724 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1727 if (IS_AST_SYM_VALUE (pbody->right) &&
1728 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1731 return isConformingBody (pbody->left, sym, body) &&
1732 isConformingBody (pbody->right, sym, body);
1740 if (IS_AST_SYM_VALUE (pbody->left) &&
1741 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1743 return isConformingBody (pbody->left, sym, body);
1745 /*------------------------------------------------------------------*/
1757 case SIZEOF: /* evaluate wihout code generation */
1759 if (IS_AST_SYM_VALUE (pbody->left) &&
1760 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1763 if (IS_AST_SYM_VALUE (pbody->right) &&
1764 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1767 return isConformingBody (pbody->left, sym, body) &&
1768 isConformingBody (pbody->right, sym, body);
1770 /*------------------------------------------------------------------*/
1773 /* if left has a pointer & right has loop
1774 control variable then we cannot */
1775 if (astHasPointer (pbody->left) &&
1776 astHasSymbol (pbody->right, sym))
1778 if (astHasVolatile (pbody->left))
1781 if (IS_AST_SYM_VALUE (pbody->left)) {
1782 // if the loopvar has an assignment
1783 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1785 // if the loopvar is used in another (maybe conditional) block
1786 if (astHasSymbol (pbody->right, sym) &&
1787 (pbody->level >= body->level)) {
1792 if (astHasVolatile (pbody->left))
1795 if (astHasDeref(pbody->right)) return FALSE;
1797 return isConformingBody (pbody->left, sym, body) &&
1798 isConformingBody (pbody->right, sym, body);
1809 assert ("Parser should not have generated this\n");
1811 /*------------------------------------------------------------------*/
1812 /*----------------------------*/
1813 /* comma operator */
1814 /*----------------------------*/
1816 return isConformingBody (pbody->left, sym, body) &&
1817 isConformingBody (pbody->right, sym, body);
1819 /*------------------------------------------------------------------*/
1820 /*----------------------------*/
1822 /*----------------------------*/
1824 /* if local & not passed as paramater then ok */
1825 if (sym->level && !astHasSymbol(pbody->right,sym))
1829 /*------------------------------------------------------------------*/
1830 /*----------------------------*/
1831 /* return statement */
1832 /*----------------------------*/
1837 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1842 if (astHasSymbol (pbody->left, sym))
1849 return isConformingBody (pbody->left, sym, body) &&
1850 isConformingBody (pbody->right, sym, body);
1856 /*-----------------------------------------------------------------*/
1857 /* isLoopReversible - takes a for loop as input && returns true */
1858 /* if the for loop is reversible. If yes will set the value of */
1859 /* the loop control var & init value & termination value */
1860 /*-----------------------------------------------------------------*/
1862 isLoopReversible (ast * loop, symbol ** loopCntrl,
1863 ast ** init, ast ** end)
1865 /* if option says don't do it then don't */
1866 if (optimize.noLoopReverse)
1868 /* there are several tests to determine this */
1870 /* for loop has to be of the form
1871 for ( <sym> = <const1> ;
1872 [<sym> < <const2>] ;
1873 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1875 if (!isLoopCountable (AST_FOR (loop, initExpr),
1876 AST_FOR (loop, condExpr),
1877 AST_FOR (loop, loopExpr),
1878 loopCntrl, init, end))
1881 /* now do some serious checking on the body of the loop
1884 return isConformingBody (loop->left, *loopCntrl, loop->left);
1888 /*-----------------------------------------------------------------*/
1889 /* replLoopSym - replace the loop sym by loop sym -1 */
1890 /*-----------------------------------------------------------------*/
1892 replLoopSym (ast * body, symbol * sym)
1895 if (!body || IS_AST_LINK (body))
1898 if (IS_AST_SYM_VALUE (body))
1901 if (isSymbolEqual (AST_SYMBOL (body), sym))
1905 body->opval.op = '-';
1906 body->left = newAst_VALUE (symbolVal (sym));
1907 body->right = newAst_VALUE (constVal ("1"));
1915 replLoopSym (body->left, sym);
1916 replLoopSym (body->right, sym);
1920 /*-----------------------------------------------------------------*/
1921 /* reverseLoop - do the actual loop reversal */
1922 /*-----------------------------------------------------------------*/
1924 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1928 /* create the following tree
1933 if (sym) goto for_continue ;
1936 /* put it together piece by piece */
1937 rloop = newNode (NULLOP,
1938 createIf (newAst_VALUE (symbolVal (sym)),
1940 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1943 newAst_VALUE (symbolVal (sym)),
1946 replLoopSym (loop->left, sym);
1947 setAstLineno (rloop, init->lineno);
1949 rloop = newNode (NULLOP,
1951 newAst_VALUE (symbolVal (sym)),
1952 newNode ('-', end, init)),
1953 createLabel (AST_FOR (loop, continueLabel),
1957 newNode (SUB_ASSIGN,
1958 newAst_VALUE (symbolVal (sym)),
1959 newAst_VALUE (constVal ("1"))),
1962 rloop->lineno=init->lineno;
1963 return decorateType (rloop, RESULT_CHECK);
1967 /*-----------------------------------------------------------------*/
1968 /* searchLitOp - search tree (*ops only) for an ast with literal */
1969 /*-----------------------------------------------------------------*/
1971 searchLitOp (ast *tree, ast **parent, const char *ops)
1975 if (tree && optimize.global_cse)
1977 /* is there a literal operand? */
1979 IS_AST_OP(tree->right) &&
1980 tree->right->right &&
1981 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
1983 if (IS_LITERAL (RTYPE (tree->right)) !=
1984 IS_LITERAL (LTYPE (tree->right)))
1986 tree->right->decorated = 0;
1987 tree->decorated = 0;
1991 ret = searchLitOp (tree->right, parent, ops);
1996 IS_AST_OP(tree->left) &&
1997 tree->left->right &&
1998 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
2000 if (IS_LITERAL (RTYPE (tree->left)) !=
2001 IS_LITERAL (LTYPE (tree->left)))
2003 tree->left->decorated = 0;
2004 tree->decorated = 0;
2008 ret = searchLitOp (tree->left, parent, ops);
2016 /*-----------------------------------------------------------------*/
2017 /* getResultFromType */
2018 /*-----------------------------------------------------------------*/
2020 getResultTypeFromType (sym_link *type)
2022 /* type = getSpec (type); */
2024 return RESULT_TYPE_BIT;
2025 if (IS_BITFIELD (type))
2027 int blen = SPEC_BLEN (type);
2030 return RESULT_TYPE_BIT;
2032 return RESULT_TYPE_CHAR;
2033 return RESULT_TYPE_INT;
2036 return RESULT_TYPE_CHAR;
2039 return RESULT_TYPE_INT;
2040 return RESULT_TYPE_OTHER;
2043 /*-----------------------------------------------------------------*/
2044 /* addCast - adds casts to a type specified by RESULT_TYPE */
2045 /*-----------------------------------------------------------------*/
2047 addCast (ast *tree, RESULT_TYPE resultType, bool upcast)
2050 bool upCasted = FALSE;
2054 case RESULT_TYPE_NONE:
2055 /* char: promote to int */
2057 getSize (tree->etype) >= INTSIZE)
2059 newLink = newIntLink();
2062 case RESULT_TYPE_CHAR:
2063 if (IS_CHAR (tree->etype) ||
2064 IS_FLOAT(tree->etype))
2066 newLink = newCharLink();
2068 case RESULT_TYPE_INT:
2070 if (getSize (tree->etype) > INTSIZE)
2072 /* warn ("Loosing significant digits"); */
2076 /* char: promote to int */
2078 getSize (tree->etype) >= INTSIZE)
2080 newLink = newIntLink();
2083 case RESULT_TYPE_OTHER:
2086 /* return type is long, float: promote char to int */
2087 if (getSize (tree->etype) >= INTSIZE)
2089 newLink = newIntLink();
2095 tree->decorated = 0;
2096 tree = newNode (CAST, newAst_LINK (newLink), tree);
2097 tree->lineno = tree->right->lineno;
2098 /* keep unsigned type during cast to smaller type,
2099 but not when promoting from char to int */
2101 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2102 return decorateType (tree, resultType);
2105 /*-----------------------------------------------------------------*/
2106 /* resultTypePropagate - decides if resultType can be propagated */
2107 /*-----------------------------------------------------------------*/
2109 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2111 switch (tree->opval.op)
2127 return RESULT_TYPE_NONE;
2131 return RESULT_TYPE_IFX;
2133 return RESULT_TYPE_NONE;
2137 /*-----------------------------------------------------------------*/
2138 /* getLeftResultType - gets type from left branch for propagation */
2139 /*-----------------------------------------------------------------*/
2141 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2143 switch (tree->opval.op)
2147 if (IS_PTR (LTYPE (tree)))
2148 return RESULT_TYPE_NONE;
2150 return getResultTypeFromType (LETYPE (tree));
2152 if (IS_PTR (currFunc->type->next))
2153 return RESULT_TYPE_NONE;
2155 return getResultTypeFromType (currFunc->type->next);
2157 if (!IS_ARRAY (LTYPE (tree)))
2159 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256)
2160 return RESULT_TYPE_CHAR;
2167 /*--------------------------------------------------------------------*/
2168 /* decorateType - compute type for this tree, also does type checking.*/
2169 /* This is done bottom up, since type has to flow upwards. */
2170 /* resultType flows top-down and forces e.g. char-arithmetik, if the */
2171 /* result is a char and the operand(s) are int's. */
2172 /* It also does constant folding, and parameter checking. */
2173 /*--------------------------------------------------------------------*/
2175 decorateType (ast * tree, RESULT_TYPE resultType)
2179 RESULT_TYPE resultTypeProp;
2184 /* if already has type then do nothing */
2185 if (tree->decorated)
2188 tree->decorated = 1;
2191 /* print the line */
2192 /* if not block & function */
2193 if (tree->type == EX_OP &&
2194 (tree->opval.op != FUNCTION &&
2195 tree->opval.op != BLOCK &&
2196 tree->opval.op != NULLOP))
2198 filename = tree->filename;
2199 lineno = tree->lineno;
2203 /* if any child is an error | this one is an error do nothing */
2204 if (tree->isError ||
2205 (tree->left && tree->left->isError) ||
2206 (tree->right && tree->right->isError))
2209 /*------------------------------------------------------------------*/
2210 /*----------------------------*/
2211 /* leaf has been reached */
2212 /*----------------------------*/
2213 lineno=tree->lineno;
2214 /* if this is of type value */
2215 /* just get the type */
2216 if (tree->type == EX_VALUE)
2219 if (IS_LITERAL (tree->opval.val->etype))
2222 /* if this is a character array then declare it */
2223 if (IS_ARRAY (tree->opval.val->type))
2224 tree->opval.val = stringToSymbol (tree->opval.val);
2226 /* otherwise just copy the type information */
2227 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2231 if (tree->opval.val->sym)
2233 /* if the undefined flag is set then give error message */
2234 if (tree->opval.val->sym->undefined)
2236 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2238 TTYPE (tree) = TETYPE (tree) =
2239 tree->opval.val->type = tree->opval.val->sym->type =
2240 tree->opval.val->etype = tree->opval.val->sym->etype =
2241 copyLinkChain (INTTYPE);
2246 /* if impilicit i.e. struct/union member then no type */
2247 if (tree->opval.val->sym->implicit)
2248 TTYPE (tree) = TETYPE (tree) = NULL;
2253 /* else copy the type */
2254 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2256 /* and mark it as referenced */
2257 tree->opval.val->sym->isref = 1;
2265 /* if type link for the case of cast */
2266 if (tree->type == EX_LINK)
2268 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2276 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2278 if (tree->left && tree->left->type == EX_OPERAND
2279 && (tree->left->opval.op == INC_OP
2280 || tree->left->opval.op == DEC_OP)
2281 && tree->left->left)
2283 tree->left->right = tree->left->left;
2284 tree->left->left = NULL;
2286 if (tree->right && tree->right->type == EX_OPERAND
2287 && (tree->right->opval.op == INC_OP
2288 || tree->right->opval.op == DEC_OP)
2289 && tree->right->left)
2291 tree->right->right = tree->right->left;
2292 tree->right->left = NULL;
2297 /* Before decorating the left branch we've to decide in dependence
2298 upon tree->opval.op, if resultType can be propagated */
2299 resultTypeProp = resultTypePropagate (tree, resultType);
2301 if (tree->opval.op == '?')
2302 dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2304 dtl = decorateType (tree->left, resultTypeProp);
2306 /* if an array node, we may need to swap branches */
2307 if (tree->opval.op == '[')
2309 /* determine which is the array & which the index */
2310 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2311 IS_INTEGRAL (LTYPE (tree)))
2313 ast *tempTree = tree->left;
2314 tree->left = tree->right;
2315 tree->right = tempTree;
2319 /* After decorating the left branch there's type information available
2320 in tree->left->?type. If the op is e.g. '=' we extract the type
2321 information from there and propagate it to the right branch. */
2322 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2324 switch (tree->opval.op)
2327 /* delay right side for '?' operator since conditional macro
2328 expansions might rely on this */
2332 /* decorate right side for CALL (parameter list) in processParms();
2333 there is resultType available */
2337 dtr = decorateType (tree->right, resultTypeProp);
2341 /* this is to take care of situations
2342 when the tree gets rewritten */
2343 if (dtl != tree->left)
2345 if (dtr != tree->right)
2347 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2351 /* depending on type of operator do */
2353 switch (tree->opval.op)
2355 /*------------------------------------------------------------------*/
2356 /*----------------------------*/
2358 /*----------------------------*/
2361 /* first check if this is a array or a pointer */
2362 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2364 werror (E_NEED_ARRAY_PTR, "[]");
2365 goto errorTreeReturn;
2368 /* check if the type of the idx */
2369 if (!IS_INTEGRAL (RTYPE (tree)))
2371 werror (E_IDX_NOT_INT);
2372 goto errorTreeReturn;
2375 /* if the left is an rvalue then error */
2378 werror (E_LVALUE_REQUIRED, "array access");
2379 goto errorTreeReturn;
2382 if (IS_LITERAL (RTYPE (tree)))
2384 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2385 int arraySize = DCL_ELEM (LTYPE (tree));
2386 if (arraySize && arrayIndex >= arraySize)
2388 werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2393 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2396 /*------------------------------------------------------------------*/
2397 /*----------------------------*/
2399 /*----------------------------*/
2401 /* if this is not a structure */
2402 if (!IS_STRUCT (LTYPE (tree)))
2404 werror (E_STRUCT_UNION, ".");
2405 goto errorTreeReturn;
2407 TTYPE (tree) = structElemType (LTYPE (tree),
2408 (tree->right->type == EX_VALUE ?
2409 tree->right->opval.val : NULL));
2410 TETYPE (tree) = getSpec (TTYPE (tree));
2413 /*------------------------------------------------------------------*/
2414 /*----------------------------*/
2415 /* struct/union pointer */
2416 /*----------------------------*/
2418 /* if not pointer to a structure */
2419 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2421 werror (E_PTR_REQD);
2422 goto errorTreeReturn;
2425 if (!IS_STRUCT (LTYPE (tree)->next))
2427 werror (E_STRUCT_UNION, "->");
2428 goto errorTreeReturn;
2431 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2432 (tree->right->type == EX_VALUE ?
2433 tree->right->opval.val : NULL));
2434 TETYPE (tree) = getSpec (TTYPE (tree));
2436 /* adjust the storage class */
2437 switch (DCL_TYPE(tree->left->ftype)) {
2439 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2442 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2445 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2448 SPEC_SCLS (TETYPE (tree)) = 0;
2451 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2454 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2457 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2460 SPEC_SCLS (TETYPE (tree)) = 0;
2467 /* This breaks with extern declarations, bitfields, and perhaps other */
2468 /* cases (gcse). Let's leave this optimization disabled for now and */
2469 /* ponder if there's a safe way to do this. -- EEP */
2471 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2472 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2474 /* If defined struct type at addr var
2475 then rewrite (&struct var)->member
2477 and define membertype at (addr+offsetof(struct var,member)) temp
2480 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2481 AST_SYMBOL(tree->right));
2483 sym = newSymbol(genSymName (0), 0);
2484 sym->type = TTYPE (tree);
2485 sym->etype = getSpec(sym->type);
2486 sym->lineDef = tree->lineno;
2489 SPEC_STAT (sym->etype) = 1;
2490 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2492 SPEC_ABSA(sym->etype) = 1;
2493 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2496 AST_VALUE (tree) = symbolVal(sym);
2499 tree->type = EX_VALUE;
2507 /*------------------------------------------------------------------*/
2508 /*----------------------------*/
2509 /* ++/-- operation */
2510 /*----------------------------*/
2514 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2515 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2516 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2517 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2526 /*------------------------------------------------------------------*/
2527 /*----------------------------*/
2529 /*----------------------------*/
2530 case '&': /* can be unary */
2531 /* if right is NULL then unary operation */
2532 if (tree->right) /* not an unary operation */
2535 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2537 werror (E_BITWISE_OP);
2538 werror (W_CONTINUE, "left & right types are ");
2539 printTypeChain (LTYPE (tree), stderr);
2540 fprintf (stderr, ",");
2541 printTypeChain (RTYPE (tree), stderr);
2542 fprintf (stderr, "\n");
2543 goto errorTreeReturn;
2546 /* if they are both literal */
2547 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2549 tree->type = EX_VALUE;
2550 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2551 valFromType (RETYPE (tree)), '&');
2553 tree->right = tree->left = NULL;
2554 TETYPE (tree) = tree->opval.val->etype;
2555 TTYPE (tree) = tree->opval.val->type;
2559 /* see if this is a GETHBIT operation if yes
2562 ast *otree = optimizeGetHbit (tree);
2565 return decorateType (otree, RESULT_CHECK);
2568 TTYPE (tree) = computeType (LTYPE (tree),
2572 TETYPE (tree) = getSpec (TTYPE (tree));
2574 /* if left is a literal exchange left & right */
2575 if (IS_LITERAL (LTYPE (tree)))
2577 ast *tTree = tree->left;
2578 tree->left = tree->right;
2579 tree->right = tTree;
2582 /* if right is a literal and */
2583 /* we can find a 2nd literal in a and-tree then */
2584 /* rearrange the tree */
2585 if (IS_LITERAL (RTYPE (tree)))
2588 ast *litTree = searchLitOp (tree, &parent, "&");
2592 ast *tTree = litTree->left;
2593 litTree->left = tree->right;
2594 tree->right = tTree;
2595 /* both operands in tTree are literal now */
2596 decorateType (parent, resultType);
2600 LRVAL (tree) = RRVAL (tree) = 1;
2605 /*------------------------------------------------------------------*/
2606 /*----------------------------*/
2608 /*----------------------------*/
2609 p = newLink (DECLARATOR);
2610 /* if bit field then error */
2611 if (IS_BITVAR (tree->left->etype))
2613 werror (E_ILLEGAL_ADDR, "address of bit variable");
2614 goto errorTreeReturn;
2617 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2619 werror (E_ILLEGAL_ADDR, "address of register variable");
2620 goto errorTreeReturn;
2623 if (IS_FUNC (LTYPE (tree)))
2625 // this ought to be ignored
2626 return (tree->left);
2629 if (IS_LITERAL(LTYPE(tree)))
2631 werror (E_ILLEGAL_ADDR, "address of literal");
2632 goto errorTreeReturn;
2637 werror (E_LVALUE_REQUIRED, "address of");
2638 goto errorTreeReturn;
2641 DCL_TYPE (p) = POINTER;
2642 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2643 DCL_TYPE (p) = CPOINTER;
2644 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2645 DCL_TYPE (p) = FPOINTER;
2646 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2647 DCL_TYPE (p) = PPOINTER;
2648 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2649 DCL_TYPE (p) = IPOINTER;
2650 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2651 DCL_TYPE (p) = EEPPOINTER;
2652 else if (SPEC_OCLS(tree->left->etype))
2653 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2655 DCL_TYPE (p) = POINTER;
2657 if (IS_AST_SYM_VALUE (tree->left))
2659 AST_SYMBOL (tree->left)->addrtaken = 1;
2660 AST_SYMBOL (tree->left)->allocreq = 1;
2663 p->next = LTYPE (tree);
2665 TETYPE (tree) = getSpec (TTYPE (tree));
2670 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2671 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2673 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2674 AST_SYMBOL(tree->left->right));
2675 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2676 valueFromLit(element->offset));
2679 tree->type = EX_VALUE;
2680 tree->values.literalFromCast = 1;
2686 /*------------------------------------------------------------------*/
2687 /*----------------------------*/
2689 /*----------------------------*/
2691 /* if the rewrite succeeds then don't go any furthur */
2693 ast *wtree = optimizeRRCRLC (tree);
2695 return decorateType (wtree, RESULT_CHECK);
2697 wtree = optimizeSWAP (tree);
2699 return decorateType (wtree, RESULT_CHECK);
2702 /* if left is a literal exchange left & right */
2703 if (IS_LITERAL (LTYPE (tree)))
2705 ast *tTree = tree->left;
2706 tree->left = tree->right;
2707 tree->right = tTree;
2710 /* if right is a literal and */
2711 /* we can find a 2nd literal in a or-tree then */
2712 /* rearrange the tree */
2713 if (IS_LITERAL (RTYPE (tree)))
2716 ast *litTree = searchLitOp (tree, &parent, "|");
2720 ast *tTree = litTree->left;
2721 litTree->left = tree->right;
2722 tree->right = tTree;
2723 /* both operands in tTree are literal now */
2724 decorateType (parent, resultType);
2729 /*------------------------------------------------------------------*/
2730 /*----------------------------*/
2732 /*----------------------------*/
2734 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2736 werror (E_BITWISE_OP);
2737 werror (W_CONTINUE, "left & right types are ");
2738 printTypeChain (LTYPE (tree), stderr);
2739 fprintf (stderr, ",");
2740 printTypeChain (RTYPE (tree), stderr);
2741 fprintf (stderr, "\n");
2742 goto errorTreeReturn;
2745 /* if they are both literal then */
2746 /* 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;
2787 TETYPE (tree) = getSpec (TTYPE (tree) =
2788 computeType (LTYPE (tree),
2795 /*------------------------------------------------------------------*/
2796 /*----------------------------*/
2798 /*----------------------------*/
2800 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2802 werror (E_INVALID_OP, "divide");
2803 goto errorTreeReturn;
2805 /* if they are both literal then */
2806 /* rewrite the tree */
2807 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2809 tree->type = EX_VALUE;
2810 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2811 valFromType (RETYPE (tree)));
2812 tree->right = tree->left = NULL;
2813 TETYPE (tree) = getSpec (TTYPE (tree) =
2814 tree->opval.val->type);
2818 LRVAL (tree) = RRVAL (tree) = 1;
2820 TETYPE (tree) = getSpec (TTYPE (tree) =
2821 computeType (LTYPE (tree),
2826 /* if right is a literal and */
2827 /* left is also a division by a literal then */
2828 /* rearrange the tree */
2829 if (IS_LITERAL (RTYPE (tree))
2830 /* avoid infinite loop */
2831 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2834 ast *litTree = searchLitOp (tree, &parent, "/");
2837 if (IS_LITERAL (RTYPE (litTree)))
2841 litTree->right = newNode ('*',
2843 copyAst (tree->right));
2844 litTree->right->lineno = tree->lineno;
2846 tree->right->opval.val = constVal ("1");
2847 decorateType (parent, resultType);
2851 /* litTree->left is literal: no gcse possible.
2852 We can't call decorateType(parent, RESULT_CHECK), because
2853 this would cause an infinit loop. */
2854 parent->decorated = 1;
2855 decorateType (litTree, resultType);
2862 /*------------------------------------------------------------------*/
2863 /*----------------------------*/
2865 /*----------------------------*/
2867 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2869 werror (E_BITWISE_OP);
2870 werror (W_CONTINUE, "left & right types are ");
2871 printTypeChain (LTYPE (tree), stderr);
2872 fprintf (stderr, ",");
2873 printTypeChain (RTYPE (tree), stderr);
2874 fprintf (stderr, "\n");
2875 goto errorTreeReturn;
2877 /* if they are both literal then */
2878 /* rewrite the tree */
2879 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2881 tree->type = EX_VALUE;
2882 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2883 valFromType (RETYPE (tree)));
2884 tree->right = tree->left = NULL;
2885 TETYPE (tree) = getSpec (TTYPE (tree) =
2886 tree->opval.val->type);
2889 LRVAL (tree) = RRVAL (tree) = 1;
2890 TETYPE (tree) = getSpec (TTYPE (tree) =
2891 computeType (LTYPE (tree),
2897 /*------------------------------------------------------------------*/
2898 /*----------------------------*/
2899 /* address dereference */
2900 /*----------------------------*/
2901 case '*': /* can be unary : if right is null then unary operation */
2904 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2906 werror (E_PTR_REQD);
2907 goto errorTreeReturn;
2912 werror (E_LVALUE_REQUIRED, "pointer deref");
2913 goto errorTreeReturn;
2915 if (IS_ADDRESS_OF_OP(tree->left))
2917 /* replace *&obj with obj */
2918 return tree->left->left;
2920 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2921 TETYPE (tree) = getSpec (TTYPE (tree));
2922 /* adjust the storage class */
2923 switch (DCL_TYPE(tree->left->ftype)) {
2925 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2928 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2931 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2934 SPEC_SCLS (TETYPE (tree)) = 0;
2937 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2940 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2943 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2946 SPEC_SCLS (TETYPE (tree)) = 0;
2955 /*------------------------------------------------------------------*/
2956 /*----------------------------*/
2957 /* multiplication */
2958 /*----------------------------*/
2959 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2961 werror (E_INVALID_OP, "multiplication");
2962 goto errorTreeReturn;
2965 /* if they are both literal then */
2966 /* rewrite the tree */
2967 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2969 tree->type = EX_VALUE;
2970 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2971 valFromType (RETYPE (tree)));
2972 tree->right = tree->left = NULL;
2973 TETYPE (tree) = getSpec (TTYPE (tree) =
2974 tree->opval.val->type);
2978 /* if left is a literal exchange left & right */
2979 if (IS_LITERAL (LTYPE (tree)))
2981 ast *tTree = tree->left;
2982 tree->left = tree->right;
2983 tree->right = tTree;
2986 /* if right is a literal and */
2987 /* we can find a 2nd literal in a mul-tree then */
2988 /* rearrange the tree */
2989 if (IS_LITERAL (RTYPE (tree)))
2992 ast *litTree = searchLitOp (tree, &parent, "*");
2996 ast *tTree = litTree->left;
2997 litTree->left = tree->right;
2998 tree->right = tTree;
2999 /* both operands in litTree are literal now */
3000 decorateType (parent, resultType);
3004 LRVAL (tree) = RRVAL (tree) = 1;
3005 tree->left = addCast (tree->left, resultType, FALSE);
3006 tree->right = addCast (tree->right, resultType, FALSE);
3007 TETYPE (tree) = getSpec (TTYPE (tree) =
3008 computeType (LTYPE (tree),
3015 /*------------------------------------------------------------------*/
3016 /*----------------------------*/
3017 /* unary '+' operator */
3018 /*----------------------------*/
3023 if (!IS_ARITHMETIC (LTYPE (tree)))
3025 werror (E_UNARY_OP, '+');
3026 goto errorTreeReturn;
3029 /* if left is a literal then do it */
3030 if (IS_LITERAL (LTYPE (tree)))
3032 tree->type = EX_VALUE;
3033 tree->opval.val = valFromType (LETYPE (tree));
3035 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3039 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3043 /*------------------------------------------------------------------*/
3044 /*----------------------------*/
3046 /*----------------------------*/
3048 /* this is not a unary operation */
3049 /* if both pointers then problem */
3050 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3051 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3053 werror (E_PTR_PLUS_PTR);
3054 goto errorTreeReturn;
3057 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3058 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3060 werror (E_PLUS_INVALID, "+");
3061 goto errorTreeReturn;
3064 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3065 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3067 werror (E_PLUS_INVALID, "+");
3068 goto errorTreeReturn;
3070 /* if they are both literal then */
3071 /* rewrite the tree */
3072 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3074 tree->type = EX_VALUE;
3075 tree->left = addCast (tree->left, resultType, TRUE);
3076 tree->right = addCast (tree->right, resultType, TRUE);
3077 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3078 valFromType (RETYPE (tree)));
3079 tree->right = tree->left = NULL;
3080 TETYPE (tree) = getSpec (TTYPE (tree) =
3081 tree->opval.val->type);
3085 /* if the right is a pointer or left is a literal
3086 xchange left & right */
3087 if (IS_ARRAY (RTYPE (tree)) ||
3088 IS_PTR (RTYPE (tree)) ||
3089 IS_LITERAL (LTYPE (tree)))
3091 ast *tTree = tree->left;
3092 tree->left = tree->right;
3093 tree->right = tTree;
3096 /* if right is a literal and */
3097 /* left is also an addition/subtraction with a literal then */
3098 /* rearrange the tree */
3099 if (IS_LITERAL (RTYPE (tree)))
3101 ast *litTree, *parent;
3102 litTree = searchLitOp (tree, &parent, "+-");
3105 if (litTree->opval.op == '+')
3109 ast *tTree = litTree->left;
3110 litTree->left = tree->right;
3111 tree->right = tree->left;
3114 else if (litTree->opval.op == '-')
3116 if (IS_LITERAL (RTYPE (litTree)))
3120 ast *tTree = litTree->left;
3121 litTree->left = tree->right;
3122 tree->right = tTree;
3128 ast *tTree = litTree->right;
3129 litTree->right = tree->right;
3130 tree->right = tTree;
3131 litTree->opval.op = '+';
3132 tree->opval.op = '-';
3135 decorateType (parent, resultType);
3139 LRVAL (tree) = RRVAL (tree) = 1;
3140 /* if the left is a pointer */
3141 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3142 TETYPE (tree) = getSpec (TTYPE (tree) =
3146 tree->left = addCast (tree->left, resultType, TRUE);
3147 tree->right = addCast (tree->right, resultType, TRUE);
3148 TETYPE (tree) = getSpec (TTYPE (tree) =
3149 computeType (LTYPE (tree),
3157 /*------------------------------------------------------------------*/
3158 /*----------------------------*/
3160 /*----------------------------*/
3161 case '-': /* can be unary */
3162 /* if right is null then unary */
3166 if (!IS_ARITHMETIC (LTYPE (tree)))
3168 werror (E_UNARY_OP, tree->opval.op);
3169 goto errorTreeReturn;
3172 /* if left is a literal then do it */
3173 if (IS_LITERAL (LTYPE (tree)))
3175 tree->type = EX_VALUE;
3176 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3178 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3179 SPEC_USIGN(TETYPE(tree)) = 0;
3183 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3187 /*------------------------------------------------------------------*/
3188 /*----------------------------*/
3190 /*----------------------------*/
3192 if (!(IS_PTR (LTYPE (tree)) ||
3193 IS_ARRAY (LTYPE (tree)) ||
3194 IS_ARITHMETIC (LTYPE (tree))))
3196 werror (E_PLUS_INVALID, "-");
3197 goto errorTreeReturn;
3200 if (!(IS_PTR (RTYPE (tree)) ||
3201 IS_ARRAY (RTYPE (tree)) ||
3202 IS_ARITHMETIC (RTYPE (tree))))
3204 werror (E_PLUS_INVALID, "-");
3205 goto errorTreeReturn;
3208 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3209 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3210 IS_INTEGRAL (RTYPE (tree))))
3212 werror (E_PLUS_INVALID, "-");
3213 goto errorTreeReturn;
3216 /* if they are both literal then */
3217 /* rewrite the tree */
3218 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3220 tree->type = EX_VALUE;
3221 tree->left = addCast (tree->left, resultType, TRUE);
3222 tree->right = addCast (tree->right, resultType, TRUE);
3223 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3224 valFromType (RETYPE (tree)));
3225 tree->right = tree->left = NULL;
3226 TETYPE (tree) = getSpec (TTYPE (tree) =
3227 tree->opval.val->type);
3231 /* if the left & right are equal then zero */
3232 if (isAstEqual (tree->left, tree->right))
3234 tree->type = EX_VALUE;
3235 tree->left = tree->right = NULL;
3236 tree->opval.val = constVal ("0");
3237 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3241 /* if both of them are pointers or arrays then */
3242 /* the result is going to be an integer */
3243 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3244 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3245 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3247 /* if only the left is a pointer */
3248 /* then result is a pointer */
3249 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3250 TETYPE (tree) = getSpec (TTYPE (tree) =
3254 tree->left = addCast (tree->left, resultType, TRUE);
3255 tree->right = addCast (tree->right, resultType, TRUE);
3257 TETYPE (tree) = getSpec (TTYPE (tree) =
3258 computeType (LTYPE (tree),
3264 LRVAL (tree) = RRVAL (tree) = 1;
3266 /* if right is a literal and */
3267 /* left is also an addition/subtraction with a literal then */
3268 /* rearrange the tree */
3269 if (IS_LITERAL (RTYPE (tree))
3270 /* avoid infinite loop */
3271 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3273 ast *litTree, *litParent;
3274 litTree = searchLitOp (tree, &litParent, "+-");
3277 if (litTree->opval.op == '+')
3281 ast *tTree = litTree->left;
3282 litTree->left = litTree->right;
3283 litTree->right = tree->right;
3284 tree->right = tTree;
3285 tree->opval.op = '+';
3286 litTree->opval.op = '-';
3288 else if (litTree->opval.op == '-')
3290 if (IS_LITERAL (RTYPE (litTree)))
3294 ast *tTree = litTree->left;
3295 litTree->left = tree->right;
3296 tree->right = litParent->left;
3297 litParent->left = tTree;
3298 litTree->opval.op = '+';
3300 tree->decorated = 0;
3301 decorateType (tree, resultType);
3307 ast *tTree = litTree->right;
3308 litTree->right = tree->right;
3309 tree->right = tTree;
3312 decorateType (litParent, resultType);
3317 /*------------------------------------------------------------------*/
3318 /*----------------------------*/
3320 /*----------------------------*/
3322 /* can be only integral type */
3323 if (!IS_INTEGRAL (LTYPE (tree)))
3325 werror (E_UNARY_OP, tree->opval.op);
3326 goto errorTreeReturn;
3329 /* if left is a literal then do it */
3330 if (IS_LITERAL (LTYPE (tree)))
3332 tree->type = EX_VALUE;
3333 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3335 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3336 return addCast (tree, resultType, TRUE);
3338 tree->left = addCast (tree->left, resultType, TRUE);
3340 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3343 /*------------------------------------------------------------------*/
3344 /*----------------------------*/
3346 /*----------------------------*/
3348 /* can be pointer */
3349 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3350 !IS_PTR (LTYPE (tree)) &&
3351 !IS_ARRAY (LTYPE (tree)))
3353 werror (E_UNARY_OP, tree->opval.op);
3354 goto errorTreeReturn;
3357 /* if left is a literal then do it */
3358 if (IS_LITERAL (LTYPE (tree)))
3360 tree->type = EX_VALUE;
3361 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3363 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3367 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3370 /*------------------------------------------------------------------*/
3371 /*----------------------------*/
3373 /*----------------------------*/
3377 TTYPE (tree) = LTYPE (tree);
3378 TETYPE (tree) = LETYPE (tree);
3382 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3387 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3389 werror (E_SHIFT_OP_INVALID);
3390 werror (W_CONTINUE, "left & right types are ");
3391 printTypeChain (LTYPE (tree), stderr);
3392 fprintf (stderr, ",");
3393 printTypeChain (RTYPE (tree), stderr);
3394 fprintf (stderr, "\n");
3395 goto errorTreeReturn;
3398 /* make smaller type only if it's a LEFT_OP */
3399 if (tree->opval.op == LEFT_OP)
3400 tree->left = addCast (tree->left, resultType, TRUE);
3402 /* if they are both literal then */
3403 /* rewrite the tree */
3404 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3406 tree->type = EX_VALUE;
3407 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3408 valFromType (RETYPE (tree)),
3409 (tree->opval.op == LEFT_OP ? 1 : 0));
3410 tree->right = tree->left = NULL;
3411 TETYPE (tree) = getSpec (TTYPE (tree) =
3412 tree->opval.val->type);
3416 LRVAL (tree) = RRVAL (tree) = 1;
3417 if (tree->opval.op == LEFT_OP)
3419 TETYPE (tree) = getSpec (TTYPE (tree) =
3420 computeType (LTYPE (tree),
3427 /* no promotion necessary */
3428 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3429 if (IS_LITERAL (TTYPE (tree)))
3430 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3433 /* if only the right side is a literal & we are
3434 shifting more than size of the left operand then zero */
3435 if (IS_LITERAL (RTYPE (tree)) &&
3436 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3437 (getSize (TETYPE (tree)) * 8))
3439 if (tree->opval.op==LEFT_OP ||
3440 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3442 lineno=tree->lineno;
3443 werror (W_SHIFT_CHANGED,
3444 (tree->opval.op == LEFT_OP ? "left" : "right"));
3445 tree->type = EX_VALUE;
3446 tree->left = tree->right = NULL;
3447 tree->opval.val = constVal ("0");
3448 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3455 /*------------------------------------------------------------------*/
3456 /*----------------------------*/
3458 /*----------------------------*/
3459 case CAST: /* change the type */
3460 /* cannot cast to an aggregate type */
3461 if (IS_AGGREGATE (LTYPE (tree)))
3463 werror (E_CAST_ILLEGAL);
3464 goto errorTreeReturn;
3467 /* make sure the type is complete and sane */
3468 checkTypeSanity(LETYPE(tree), "(cast)");
3470 /* If code memory is read only, then pointers to code memory */
3471 /* implicitly point to constants -- make this explicit */
3473 sym_link *t = LTYPE(tree);
3474 while (t && t->next)
3476 if (IS_CODEPTR(t) && port->mem.code_ro)
3478 if (IS_SPEC(t->next))
3479 SPEC_CONST (t->next) = 1;
3481 DCL_PTR_CONST (t->next) = 1;
3488 /* if the right is a literal replace the tree */
3489 if (IS_LITERAL (RETYPE (tree))) {
3490 if (!IS_PTR (LTYPE (tree))) {
3491 tree->type = EX_VALUE;
3493 valCastLiteral (LTYPE (tree),
3494 floatFromVal (valFromType (RETYPE (tree))));
3497 TTYPE (tree) = tree->opval.val->type;
3498 tree->values.literalFromCast = 1;
3499 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3500 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3501 sym_link *rest = LTYPE(tree)->next;
3502 werror(W_LITERAL_GENERIC);
3503 TTYPE(tree) = newLink(DECLARATOR);
3504 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3505 TTYPE(tree)->next = rest;
3506 tree->left->opval.lnk = TTYPE(tree);
3509 TTYPE (tree) = LTYPE (tree);
3513 TTYPE (tree) = LTYPE (tree);
3517 #if 0 // this is already checked, now this could be explicit
3518 /* if pointer to struct then check names */
3519 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3520 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3521 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3523 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3524 SPEC_STRUCT(LETYPE(tree))->tag);
3527 if (IS_ADDRESS_OF_OP(tree->right)
3528 && IS_AST_SYM_VALUE (tree->right->left)
3529 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3531 tree->type = EX_VALUE;
3533 valCastLiteral (LTYPE (tree),
3534 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3535 TTYPE (tree) = tree->opval.val->type;
3536 TETYPE (tree) = getSpec (TTYPE (tree));
3539 tree->values.literalFromCast = 1;
3543 /* handle offsetof macro: */
3544 /* #define offsetof(TYPE, MEMBER) \ */
3545 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3546 if (IS_ADDRESS_OF_OP(tree->right)
3547 && IS_AST_OP (tree->right->left)
3548 && tree->right->left->opval.op == PTR_OP
3549 && IS_AST_OP (tree->right->left->left)
3550 && tree->right->left->left->opval.op == CAST
3551 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3553 symbol *element = getStructElement (
3554 SPEC_STRUCT (LETYPE(tree->right->left)),
3555 AST_SYMBOL(tree->right->left->right)
3559 tree->type = EX_VALUE;
3560 tree->opval.val = valCastLiteral (
3563 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3566 TTYPE (tree) = tree->opval.val->type;
3567 TETYPE (tree) = getSpec (TTYPE (tree));
3574 /* if the right is a literal replace the tree */
3575 if (IS_LITERAL (RETYPE (tree))) {
3577 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3578 /* rewrite (type *)litaddr
3580 and define type at litaddr temp
3581 (but only if type's storage class is not generic)
3583 ast *newTree = newNode ('&', NULL, NULL);
3586 TTYPE (newTree) = LTYPE (tree);
3587 TETYPE (newTree) = getSpec(LTYPE (tree));
3589 /* define a global symbol at the casted address*/
3590 sym = newSymbol(genSymName (0), 0);
3591 sym->type = LTYPE (tree)->next;
3593 sym->type = newLink (V_VOID);
3594 sym->etype = getSpec(sym->type);
3595 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3596 sym->lineDef = tree->lineno;
3599 SPEC_STAT (sym->etype) = 1;
3600 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3601 SPEC_ABSA(sym->etype) = 1;
3602 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3605 newTree->left = newAst_VALUE(symbolVal(sym));
3606 newTree->left->lineno = tree->lineno;
3607 LTYPE (newTree) = sym->type;
3608 LETYPE (newTree) = sym->etype;
3609 LLVAL (newTree) = 1;
3610 LRVAL (newTree) = 0;
3611 TLVAL (newTree) = 1;
3615 if (!IS_PTR (LTYPE (tree))) {
3616 tree->type = EX_VALUE;
3618 valCastLiteral (LTYPE (tree),
3619 floatFromVal (valFromType (RTYPE (tree))));
3620 TTYPE (tree) = tree->opval.val->type;
3623 tree->values.literalFromCast = 1;
3624 TETYPE (tree) = getSpec (TTYPE (tree));
3628 TTYPE (tree) = LTYPE (tree);
3632 TETYPE (tree) = getSpec (TTYPE (tree));
3636 /*------------------------------------------------------------------*/
3637 /*----------------------------*/
3638 /* logical &&, || */
3639 /*----------------------------*/
3642 /* each must be arithmetic type or be a pointer */
3643 if (!IS_PTR (LTYPE (tree)) &&
3644 !IS_ARRAY (LTYPE (tree)) &&
3645 !IS_INTEGRAL (LTYPE (tree)))
3647 werror (E_COMPARE_OP);
3648 goto errorTreeReturn;
3651 if (!IS_PTR (RTYPE (tree)) &&
3652 !IS_ARRAY (RTYPE (tree)) &&
3653 !IS_INTEGRAL (RTYPE (tree)))
3655 werror (E_COMPARE_OP);
3656 goto errorTreeReturn;
3658 /* if they are both literal then */
3659 /* rewrite the tree */
3660 if (IS_LITERAL (RTYPE (tree)) &&
3661 IS_LITERAL (LTYPE (tree)))
3663 tree->type = EX_VALUE;
3664 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3665 valFromType (RTYPE (tree)),
3667 tree->right = tree->left = NULL;
3668 TETYPE (tree) = getSpec (TTYPE (tree) =
3669 tree->opval.val->type);
3672 LRVAL (tree) = RRVAL (tree) = 1;
3673 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3676 /*------------------------------------------------------------------*/
3677 /*----------------------------*/
3678 /* comparison operators */
3679 /*----------------------------*/
3687 ast *lt = optimizeCompare (tree);
3693 /* if they are pointers they must be castable */
3694 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3696 if (tree->opval.op==EQ_OP &&
3697 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3698 // we cannot cast a gptr to a !gptr: switch the leaves
3699 struct ast *s=tree->left;
3700 tree->left=tree->right;
3703 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3705 werror (E_COMPARE_OP);
3706 fprintf (stderr, "comparing type ");
3707 printTypeChain (LTYPE (tree), stderr);
3708 fprintf (stderr, "to type ");
3709 printTypeChain (RTYPE (tree), stderr);
3710 fprintf (stderr, "\n");
3711 goto errorTreeReturn;
3714 /* else they should be promotable to one another */
3717 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3718 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3720 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3722 werror (E_COMPARE_OP);
3723 fprintf (stderr, "comparing type ");
3724 printTypeChain (LTYPE (tree), stderr);
3725 fprintf (stderr, "to type ");
3726 printTypeChain (RTYPE (tree), stderr);
3727 fprintf (stderr, "\n");
3728 goto errorTreeReturn;
3731 /* if unsigned value < 0 then always false */
3732 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3733 if (SPEC_USIGN(LETYPE(tree)) &&
3734 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3735 IS_LITERAL(RTYPE(tree)) &&
3736 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3738 if (tree->opval.op == '<')
3742 if (tree->opval.op == '>')
3744 if (resultType == RESULT_TYPE_IFX)
3746 /* the parent is an ifx: */
3747 /* if (unsigned value) */
3751 /* (unsigned value) ? 1 : 0 */
3752 tree->opval.op = '?';
3753 tree->right = newNode (':',
3754 newAst_VALUE (constVal ("1")),
3755 tree->right); /* val 0 */
3756 tree->right->lineno = tree->lineno;
3757 tree->right->left->lineno = tree->lineno;
3758 decorateType (tree->right, RESULT_CHECK);
3761 /* if they are both literal then */
3762 /* rewrite the tree */
3763 if (IS_LITERAL (RTYPE (tree)) &&
3764 IS_LITERAL (LTYPE (tree)))
3766 tree->type = EX_VALUE;
3767 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3768 valFromType (RETYPE (tree)),
3770 tree->right = tree->left = NULL;
3771 TETYPE (tree) = getSpec (TTYPE (tree) =
3772 tree->opval.val->type);
3775 LRVAL (tree) = RRVAL (tree) = 1;
3776 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3779 /*------------------------------------------------------------------*/
3780 /*----------------------------*/
3782 /*----------------------------*/
3783 case SIZEOF: /* evaluate wihout code generation */
3784 /* change the type to a integer */
3786 int size = getSize (tree->right->ftype);
3787 SNPRINTF(buffer, sizeof(buffer), "%d", size);
3788 if (!size && !IS_VOID(tree->right->ftype))
3789 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
3791 tree->type = EX_VALUE;
3792 tree->opval.val = constVal (buffer);
3793 tree->right = tree->left = NULL;
3794 TETYPE (tree) = getSpec (TTYPE (tree) =
3795 tree->opval.val->type);
3798 /*------------------------------------------------------------------*/
3799 /*----------------------------*/
3801 /*----------------------------*/
3803 /* return typeof enum value */
3804 tree->type = EX_VALUE;
3807 if (IS_SPEC(tree->right->ftype)) {
3808 switch (SPEC_NOUN(tree->right->ftype)) {
3810 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3811 else typeofv = TYPEOF_INT;
3814 typeofv = TYPEOF_FLOAT;
3817 typeofv = TYPEOF_CHAR;
3820 typeofv = TYPEOF_VOID;
3823 typeofv = TYPEOF_STRUCT;
3826 typeofv = TYPEOF_BITFIELD;
3829 typeofv = TYPEOF_BIT;
3832 typeofv = TYPEOF_SBIT;
3838 switch (DCL_TYPE(tree->right->ftype)) {
3840 typeofv = TYPEOF_POINTER;
3843 typeofv = TYPEOF_FPOINTER;
3846 typeofv = TYPEOF_CPOINTER;
3849 typeofv = TYPEOF_GPOINTER;
3852 typeofv = TYPEOF_PPOINTER;
3855 typeofv = TYPEOF_IPOINTER;
3858 typeofv = TYPEOF_ARRAY;
3861 typeofv = TYPEOF_FUNCTION;
3867 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3868 tree->opval.val = constVal (buffer);
3869 tree->right = tree->left = NULL;
3870 TETYPE (tree) = getSpec (TTYPE (tree) =
3871 tree->opval.val->type);
3874 /*------------------------------------------------------------------*/
3875 /*----------------------------*/
3876 /* conditional operator '?' */
3877 /*----------------------------*/
3879 /* the type is value of the colon operator (on the right) */
3880 assert (IS_COLON_OP (tree->right));
3881 /* if already known then replace the tree : optimizer will do it
3882 but faster to do it here */
3883 if (IS_LITERAL (LTYPE (tree)))
3885 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
3886 return decorateType (tree->right->left, resultTypeProp);
3888 return decorateType (tree->right->right, resultTypeProp);
3892 tree->right = decorateType (tree->right, resultTypeProp);
3893 TTYPE (tree) = RTYPE (tree);
3894 TETYPE (tree) = getSpec (TTYPE (tree));
3899 /* if they don't match we have a problem */
3900 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3902 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3903 goto errorTreeReturn;
3906 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
3907 resultType, tree->opval.op);
3908 TETYPE (tree) = getSpec (TTYPE (tree));
3912 #if 0 // assignment operators are converted by the parser
3913 /*------------------------------------------------------------------*/
3914 /*----------------------------*/
3915 /* assignment operators */
3916 /*----------------------------*/
3919 /* for these it must be both must be integral */
3920 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3921 !IS_ARITHMETIC (RTYPE (tree)))
3923 werror (E_OPS_INTEGRAL);
3924 goto errorTreeReturn;
3927 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3929 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3930 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3934 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3935 goto errorTreeReturn;
3946 /* for these it must be both must be integral */
3947 if (!IS_INTEGRAL (LTYPE (tree)) ||
3948 !IS_INTEGRAL (RTYPE (tree)))
3950 werror (E_OPS_INTEGRAL);
3951 goto errorTreeReturn;
3954 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3956 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3957 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3961 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3962 goto errorTreeReturn;
3968 /*------------------------------------------------------------------*/
3969 /*----------------------------*/
3971 /*----------------------------*/
3973 if (!(IS_PTR (LTYPE (tree)) ||
3974 IS_ARITHMETIC (LTYPE (tree))))
3976 werror (E_PLUS_INVALID, "-=");
3977 goto errorTreeReturn;
3980 if (!(IS_PTR (RTYPE (tree)) ||
3981 IS_ARITHMETIC (RTYPE (tree))))
3983 werror (E_PLUS_INVALID, "-=");
3984 goto errorTreeReturn;
3987 TETYPE (tree) = getSpec (TTYPE (tree) =
3988 computeType (LTYPE (tree),
3993 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3994 werror (E_CODE_WRITE, "-=");
3998 werror (E_LVALUE_REQUIRED, "-=");
3999 goto errorTreeReturn;
4005 /*------------------------------------------------------------------*/
4006 /*----------------------------*/
4008 /*----------------------------*/
4010 /* this is not a unary operation */
4011 /* if both pointers then problem */
4012 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4014 werror (E_PTR_PLUS_PTR);
4015 goto errorTreeReturn;
4018 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4020 werror (E_PLUS_INVALID, "+=");
4021 goto errorTreeReturn;
4024 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4026 werror (E_PLUS_INVALID, "+=");
4027 goto errorTreeReturn;
4030 TETYPE (tree) = getSpec (TTYPE (tree) =
4031 computeType (LTYPE (tree),
4036 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4037 werror (E_CODE_WRITE, "+=");
4041 werror (E_LVALUE_REQUIRED, "+=");
4042 goto errorTreeReturn;
4045 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_CHECK);
4046 tree->opval.op = '=';
4051 /*------------------------------------------------------------------*/
4052 /*----------------------------*/
4053 /* straight assignemnt */
4054 /*----------------------------*/
4056 /* cannot be an aggregate */
4057 if (IS_AGGREGATE (LTYPE (tree)))
4059 werror (E_AGGR_ASSIGN);
4060 goto errorTreeReturn;
4063 /* they should either match or be castable */
4064 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4066 werror (E_TYPE_MISMATCH, "assignment", " ");
4067 printFromToType(RTYPE(tree),LTYPE(tree));
4070 /* if the left side of the tree is of type void
4071 then report error */
4072 if (IS_VOID (LTYPE (tree)))
4074 werror (E_CAST_ZERO);
4075 printFromToType(RTYPE(tree), LTYPE(tree));
4078 TETYPE (tree) = getSpec (TTYPE (tree) =
4082 if (!tree->initMode ) {
4083 if (IS_CONSTANT(LTYPE(tree)))
4084 werror (E_CODE_WRITE, "=");
4088 werror (E_LVALUE_REQUIRED, "=");
4089 goto errorTreeReturn;
4094 /*------------------------------------------------------------------*/
4095 /*----------------------------*/
4096 /* comma operator */
4097 /*----------------------------*/
4099 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4102 /*------------------------------------------------------------------*/
4103 /*----------------------------*/
4105 /*----------------------------*/
4108 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4109 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4111 if (tree->left->opval.op == '*' && !tree->left->right)
4112 tree->left = tree->left->left;
4115 /* require a function or pointer to function */
4116 if (!IS_FUNC (LTYPE (tree))
4117 && !(IS_CODEPTR (LTYPE (tree)) && IS_FUNC (LTYPE (tree)->next)))
4119 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4120 goto errorTreeReturn;
4123 /* if there are parms, make sure that
4124 parms are decorate / process / reverse only once */
4126 !tree->right->decorated)
4131 if (IS_CODEPTR(LTYPE(tree)))
4132 functype = LTYPE (tree)->next;
4134 functype = LTYPE (tree);
4136 if (processParms (tree->left, FUNC_ARGS(functype),
4137 &tree->right, &parmNumber, TRUE))
4139 goto errorTreeReturn;
4142 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4143 !IFFUNC_ISBUILTIN(functype))
4145 reverseParms (tree->right);
4148 TTYPE (tree) = functype->next;
4149 TETYPE (tree) = getSpec (TTYPE (tree));
4153 /*------------------------------------------------------------------*/
4154 /*----------------------------*/
4155 /* return statement */
4156 /*----------------------------*/
4161 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4163 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4164 printFromToType (RTYPE(tree), currFunc->type->next);
4165 goto errorTreeReturn;
4168 if (IS_VOID (currFunc->type->next)
4170 !IS_VOID (RTYPE (tree)))
4172 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4173 goto errorTreeReturn;
4176 /* if there is going to be a casting required then add it */
4177 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4180 decorateType (newNode (CAST,
4181 newAst_LINK (copyLinkChain (currFunc->type->next)),
4191 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4193 werror (W_VOID_FUNC, currFunc->name);
4194 goto errorTreeReturn;
4197 TTYPE (tree) = TETYPE (tree) = NULL;
4200 /*------------------------------------------------------------------*/
4201 /*----------------------------*/
4202 /* switch statement */
4203 /*----------------------------*/
4205 /* the switch value must be an integer */
4206 if (!IS_INTEGRAL (LTYPE (tree)))
4208 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4209 goto errorTreeReturn;
4212 TTYPE (tree) = TETYPE (tree) = NULL;
4215 /*------------------------------------------------------------------*/
4216 /*----------------------------*/
4218 /*----------------------------*/
4220 tree->left = backPatchLabels (tree->left,
4223 TTYPE (tree) = TETYPE (tree) = NULL;
4226 /*------------------------------------------------------------------*/
4227 /*----------------------------*/
4229 /*----------------------------*/
4232 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_CHECK);
4233 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_CHECK);
4234 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_CHECK);
4236 /* if the for loop is reversible then
4237 reverse it otherwise do what we normally
4243 if (isLoopReversible (tree, &sym, &init, &end))
4244 return reverseLoop (tree, sym, init, end);
4246 return decorateType (createFor (AST_FOR (tree, trueLabel),
4247 AST_FOR (tree, continueLabel),
4248 AST_FOR (tree, falseLabel),
4249 AST_FOR (tree, condLabel),
4250 AST_FOR (tree, initExpr),
4251 AST_FOR (tree, condExpr),
4252 AST_FOR (tree, loopExpr),
4253 tree->left), RESULT_CHECK);
4256 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4257 "node PARAM shouldn't be processed here");
4258 /* but in processParams() */
4261 TTYPE (tree) = TETYPE (tree) = NULL;
4265 /* some error found this tree will be killed */
4267 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4268 tree->opval.op = NULLOP;
4274 /*-----------------------------------------------------------------*/
4275 /* sizeofOp - processes size of operation */
4276 /*-----------------------------------------------------------------*/
4278 sizeofOp (sym_link * type)
4283 /* make sure the type is complete and sane */
4284 checkTypeSanity(type, "(sizeof)");
4286 /* get the size and convert it to character */
4287 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4288 if (!size && !IS_VOID(type))
4289 werror (E_SIZEOF_INCOMPLETE_TYPE);
4291 /* now convert into value */
4292 return constVal (buff);
4296 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4297 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4298 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4299 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4300 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4301 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4302 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4304 /*-----------------------------------------------------------------*/
4305 /* backPatchLabels - change and or not operators to flow control */
4306 /*-----------------------------------------------------------------*/
4308 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4314 if (!(IS_ANDORNOT (tree)))
4317 /* if this an and */
4320 static int localLbl = 0;
4323 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4324 localLabel = newSymbol (buffer, NestLevel);
4326 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4328 /* if left is already a IFX then just change the if true label in that */
4329 if (!IS_IFX (tree->left))
4330 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4332 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4333 /* right is a IFX then just join */
4334 if (IS_IFX (tree->right))
4335 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4337 tree->right = createLabel (localLabel, tree->right);
4338 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4340 return newNode (NULLOP, tree->left, tree->right);
4343 /* if this is an or operation */
4346 static int localLbl = 0;
4349 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4350 localLabel = newSymbol (buffer, NestLevel);
4352 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4354 /* if left is already a IFX then just change the if true label in that */
4355 if (!IS_IFX (tree->left))
4356 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4358 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4359 /* right is a IFX then just join */
4360 if (IS_IFX (tree->right))
4361 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4363 tree->right = createLabel (localLabel, tree->right);
4364 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4366 return newNode (NULLOP, tree->left, tree->right);
4372 int wasnot = IS_NOT (tree->left);
4373 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4375 /* if the left is already a IFX */
4376 if (!IS_IFX (tree->left))
4377 tree->left = newNode (IFX, tree->left, NULL);
4381 tree->left->trueLabel = trueLabel;
4382 tree->left->falseLabel = falseLabel;
4386 tree->left->trueLabel = falseLabel;
4387 tree->left->falseLabel = trueLabel;
4394 tree->trueLabel = trueLabel;
4395 tree->falseLabel = falseLabel;
4402 /*-----------------------------------------------------------------*/
4403 /* createBlock - create expression tree for block */
4404 /*-----------------------------------------------------------------*/
4406 createBlock (symbol * decl, ast * body)
4410 /* if the block has nothing */
4414 ex = newNode (BLOCK, NULL, body);
4415 ex->values.sym = decl;
4417 ex->right = ex->right;
4423 /*-----------------------------------------------------------------*/
4424 /* createLabel - creates the expression tree for labels */
4425 /*-----------------------------------------------------------------*/
4427 createLabel (symbol * label, ast * stmnt)
4430 char name[SDCC_NAME_MAX + 1];
4433 /* must create fresh symbol if the symbol name */
4434 /* exists in the symbol table, since there can */
4435 /* be a variable with the same name as the labl */
4436 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4437 (csym->level == label->level))
4438 label = newSymbol (label->name, label->level);
4440 /* change the name before putting it in add _ */
4441 SNPRINTF(name, sizeof(name), "%s", label->name);
4443 /* put the label in the LabelSymbol table */
4444 /* but first check if a label of the same */
4446 if ((csym = findSym (LabelTab, NULL, name)))
4447 werror (E_DUPLICATE_LABEL, label->name);
4449 addSym (LabelTab, label, name, label->level, 0, 0);
4453 label->key = labelKey++;
4454 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4460 /*-----------------------------------------------------------------*/
4461 /* createCase - generates the parsetree for a case statement */
4462 /*-----------------------------------------------------------------*/
4464 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4466 char caseLbl[SDCC_NAME_MAX + 1];
4470 /* if the switch statement does not exist */
4471 /* then case is out of context */
4474 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4478 caseVal = decorateType (resolveSymbols (caseVal), RESULT_CHECK);
4479 /* if not a constant then error */
4480 if (!IS_LITERAL (caseVal->ftype))
4482 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4486 /* if not a integer than error */
4487 if (!IS_INTEGRAL (caseVal->ftype))
4489 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4493 /* find the end of the switch values chain */
4494 if (!(val = swStat->values.switchVals.swVals))
4495 swStat->values.switchVals.swVals = caseVal->opval.val;
4498 /* also order the cases according to value */
4500 int cVal = (int) floatFromVal (caseVal->opval.val);
4501 while (val && (int) floatFromVal (val) < cVal)
4507 /* if we reached the end then */
4510 pval->next = caseVal->opval.val;
4512 else if ((int) floatFromVal (val) == cVal)
4514 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4520 /* we found a value greater than */
4521 /* the current value we must add this */
4522 /* before the value */
4523 caseVal->opval.val->next = val;
4525 /* if this was the first in chain */
4526 if (swStat->values.switchVals.swVals == val)
4527 swStat->values.switchVals.swVals =
4530 pval->next = caseVal->opval.val;
4535 /* create the case label */
4536 SNPRINTF(caseLbl, sizeof(caseLbl),
4538 swStat->values.switchVals.swNum,
4539 (int) floatFromVal (caseVal->opval.val));
4541 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4546 /*-----------------------------------------------------------------*/
4547 /* createDefault - creates the parse tree for the default statement */
4548 /*-----------------------------------------------------------------*/
4550 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4552 char defLbl[SDCC_NAME_MAX + 1];
4554 /* if the switch statement does not exist */
4555 /* then case is out of context */
4558 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4562 if (swStat->values.switchVals.swDefault)
4564 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4569 /* turn on the default flag */
4570 swStat->values.switchVals.swDefault = 1;
4572 /* create the label */
4573 SNPRINTF (defLbl, sizeof(defLbl),
4574 "_default_%d", swStat->values.switchVals.swNum);
4575 return createLabel (newSymbol (defLbl, 0), stmnt);
4578 /*-----------------------------------------------------------------*/
4579 /* createIf - creates the parsetree for the if statement */
4580 /*-----------------------------------------------------------------*/
4582 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4584 static int Lblnum = 0;
4586 symbol *ifTrue, *ifFalse, *ifEnd;
4588 /* if neither exists */
4589 if (!elseBody && !ifBody) {
4590 // if there are no side effects (i++, j() etc)
4591 if (!hasSEFcalls(condAst)) {
4596 /* create the labels */
4597 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4598 ifFalse = newSymbol (buffer, NestLevel);
4599 /* if no else body then end == false */
4604 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4605 ifEnd = newSymbol (buffer, NestLevel);
4608 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4609 ifTrue = newSymbol (buffer, NestLevel);
4613 /* attach the ifTrue label to the top of it body */
4614 ifBody = createLabel (ifTrue, ifBody);
4615 /* attach a goto end to the ifBody if else is present */
4618 ifBody = newNode (NULLOP, ifBody,
4620 newAst_VALUE (symbolVal (ifEnd)),
4622 /* put the elseLabel on the else body */
4623 elseBody = createLabel (ifFalse, elseBody);
4624 /* out the end at the end of the body */
4625 elseBody = newNode (NULLOP,
4627 createLabel (ifEnd, NULL));
4631 ifBody = newNode (NULLOP, ifBody,
4632 createLabel (ifFalse, NULL));
4634 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4635 if (IS_IFX (condAst))
4638 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4640 return newNode (NULLOP, ifTree,
4641 newNode (NULLOP, ifBody, elseBody));
4645 /*-----------------------------------------------------------------*/
4646 /* createDo - creates parse tree for do */
4649 /* _docontinue_n: */
4650 /* condition_expression +-> trueLabel -> _dobody_n */
4652 /* +-> falseLabel-> _dobreak_n */
4654 /*-----------------------------------------------------------------*/
4656 createDo (symbol * trueLabel, symbol * continueLabel,
4657 symbol * falseLabel, ast * condAst, ast * doBody)
4662 /* if the body does not exist then it is simple */
4665 condAst = backPatchLabels (condAst, continueLabel, NULL);
4666 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4667 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4668 doTree->trueLabel = continueLabel;
4669 doTree->falseLabel = NULL;
4673 /* otherwise we have a body */
4674 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4676 /* attach the body label to the top */
4677 doBody = createLabel (trueLabel, doBody);
4678 /* attach the continue label to end of body */
4679 doBody = newNode (NULLOP, doBody,
4680 createLabel (continueLabel, NULL));
4682 /* now put the break label at the end */
4683 if (IS_IFX (condAst))
4686 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4688 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4690 /* putting it together */
4691 return newNode (NULLOP, doBody, doTree);
4694 /*-----------------------------------------------------------------*/
4695 /* createFor - creates parse tree for 'for' statement */
4698 /* condExpr +-> trueLabel -> _forbody_n */
4700 /* +-> falseLabel-> _forbreak_n */
4703 /* _forcontinue_n: */
4705 /* goto _forcond_n ; */
4707 /*-----------------------------------------------------------------*/
4709 createFor (symbol * trueLabel, symbol * continueLabel,
4710 symbol * falseLabel, symbol * condLabel,
4711 ast * initExpr, ast * condExpr, ast * loopExpr,
4716 /* if loopexpression not present then we can generate it */
4717 /* the same way as a while */
4719 return newNode (NULLOP, initExpr,
4720 createWhile (trueLabel, continueLabel,
4721 falseLabel, condExpr, forBody));
4722 /* vanilla for statement */
4723 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4725 if (condExpr && !IS_IFX (condExpr))
4726 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4729 /* attach condition label to condition */
4730 condExpr = createLabel (condLabel, condExpr);
4732 /* attach body label to body */
4733 forBody = createLabel (trueLabel, forBody);
4735 /* attach continue to forLoop expression & attach */
4736 /* goto the forcond @ and of loopExpression */
4737 loopExpr = createLabel (continueLabel,
4741 newAst_VALUE (symbolVal (condLabel)),
4743 /* now start putting them together */
4744 forTree = newNode (NULLOP, initExpr, condExpr);
4745 forTree = newNode (NULLOP, forTree, forBody);
4746 forTree = newNode (NULLOP, forTree, loopExpr);
4747 /* finally add the break label */
4748 forTree = newNode (NULLOP, forTree,
4749 createLabel (falseLabel, NULL));
4753 /*-----------------------------------------------------------------*/
4754 /* createWhile - creates parse tree for while statement */
4755 /* the while statement will be created as follows */
4757 /* _while_continue_n: */
4758 /* condition_expression +-> trueLabel -> _while_boby_n */
4760 /* +-> falseLabel -> _while_break_n */
4761 /* _while_body_n: */
4763 /* goto _while_continue_n */
4764 /* _while_break_n: */
4765 /*-----------------------------------------------------------------*/
4767 createWhile (symbol * trueLabel, symbol * continueLabel,
4768 symbol * falseLabel, ast * condExpr, ast * whileBody)
4772 /* put the continue label */
4773 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4774 condExpr = createLabel (continueLabel, condExpr);
4775 condExpr->lineno = 0;
4777 /* put the body label in front of the body */
4778 whileBody = createLabel (trueLabel, whileBody);
4779 whileBody->lineno = 0;
4780 /* put a jump to continue at the end of the body */
4781 /* and put break label at the end of the body */
4782 whileBody = newNode (NULLOP,
4785 newAst_VALUE (symbolVal (continueLabel)),
4786 createLabel (falseLabel, NULL)));
4788 /* put it all together */
4789 if (IS_IFX (condExpr))
4790 whileTree = condExpr;
4793 whileTree = newNode (IFX, condExpr, NULL);
4794 /* put the true & false labels in place */
4795 whileTree->trueLabel = trueLabel;
4796 whileTree->falseLabel = falseLabel;
4799 return newNode (NULLOP, whileTree, whileBody);
4802 /*-----------------------------------------------------------------*/
4803 /* optimizeGetHbit - get highest order bit of the expression */
4804 /*-----------------------------------------------------------------*/
4806 optimizeGetHbit (ast * tree)
4809 /* if this is not a bit and */
4810 if (!IS_BITAND (tree))
4813 /* will look for tree of the form
4814 ( expr >> ((sizeof expr) -1) ) & 1 */
4815 if (!IS_AST_LIT_VALUE (tree->right))
4818 if (AST_LIT_VALUE (tree->right) != 1)
4821 if (!IS_RIGHT_OP (tree->left))
4824 if (!IS_AST_LIT_VALUE (tree->left->right))
4827 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4828 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4831 /* make sure the port supports GETHBIT */
4832 if (port->hasExtBitOp
4833 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4836 return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_CHECK);
4840 /*-----------------------------------------------------------------*/
4841 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4842 /*-----------------------------------------------------------------*/
4844 optimizeRRCRLC (ast * root)
4846 /* will look for trees of the form
4847 (?expr << 1) | (?expr >> 7) or
4848 (?expr >> 7) | (?expr << 1) will make that
4849 into a RLC : operation ..
4851 (?expr >> 1) | (?expr << 7) or
4852 (?expr << 7) | (?expr >> 1) will make that
4853 into a RRC operation
4854 note : by 7 I mean (number of bits required to hold the
4856 /* if the root operations is not a | operation the not */
4857 if (!IS_BITOR (root))
4860 /* I have to think of a better way to match patterns this sucks */
4861 /* that aside let start looking for the first case : I use a the
4862 negative check a lot to improve the efficiency */
4863 /* (?expr << 1) | (?expr >> 7) */
4864 if (IS_LEFT_OP (root->left) &&
4865 IS_RIGHT_OP (root->right))
4868 if (!SPEC_USIGN (TETYPE (root->left->left)))
4871 if (!IS_AST_LIT_VALUE (root->left->right) ||
4872 !IS_AST_LIT_VALUE (root->right->right))
4875 /* make sure it is the same expression */
4876 if (!isAstEqual (root->left->left,
4880 if (AST_LIT_VALUE (root->left->right) != 1)
4883 if (AST_LIT_VALUE (root->right->right) !=
4884 (getSize (TTYPE (root->left->left)) * 8 - 1))
4887 /* make sure the port supports RLC */
4888 if (port->hasExtBitOp
4889 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4892 /* whew got the first case : create the AST */
4893 return newNode (RLC, root->left->left, NULL);
4897 /* check for second case */
4898 /* (?expr >> 7) | (?expr << 1) */
4899 if (IS_LEFT_OP (root->right) &&
4900 IS_RIGHT_OP (root->left))
4903 if (!SPEC_USIGN (TETYPE (root->left->left)))
4906 if (!IS_AST_LIT_VALUE (root->left->right) ||
4907 !IS_AST_LIT_VALUE (root->right->right))
4910 /* make sure it is the same symbol */
4911 if (!isAstEqual (root->left->left,
4915 if (AST_LIT_VALUE (root->right->right) != 1)
4918 if (AST_LIT_VALUE (root->left->right) !=
4919 (getSize (TTYPE (root->left->left)) * 8 - 1))
4922 /* make sure the port supports RLC */
4923 if (port->hasExtBitOp
4924 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4927 /* whew got the first case : create the AST */
4928 return newNode (RLC, root->left->left, NULL);
4933 /* third case for RRC */
4934 /* (?symbol >> 1) | (?symbol << 7) */
4935 if (IS_LEFT_OP (root->right) &&
4936 IS_RIGHT_OP (root->left))
4939 if (!SPEC_USIGN (TETYPE (root->left->left)))
4942 if (!IS_AST_LIT_VALUE (root->left->right) ||
4943 !IS_AST_LIT_VALUE (root->right->right))
4946 /* make sure it is the same symbol */
4947 if (!isAstEqual (root->left->left,
4951 if (AST_LIT_VALUE (root->left->right) != 1)
4954 if (AST_LIT_VALUE (root->right->right) !=
4955 (getSize (TTYPE (root->left->left)) * 8 - 1))
4958 /* make sure the port supports RRC */
4959 if (port->hasExtBitOp
4960 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4963 /* whew got the first case : create the AST */
4964 return newNode (RRC, root->left->left, NULL);
4968 /* fourth and last case for now */
4969 /* (?symbol << 7) | (?symbol >> 1) */
4970 if (IS_RIGHT_OP (root->right) &&
4971 IS_LEFT_OP (root->left))
4974 if (!SPEC_USIGN (TETYPE (root->left->left)))
4977 if (!IS_AST_LIT_VALUE (root->left->right) ||
4978 !IS_AST_LIT_VALUE (root->right->right))
4981 /* make sure it is the same symbol */
4982 if (!isAstEqual (root->left->left,
4986 if (AST_LIT_VALUE (root->right->right) != 1)
4989 if (AST_LIT_VALUE (root->left->right) !=
4990 (getSize (TTYPE (root->left->left)) * 8 - 1))
4993 /* make sure the port supports RRC */
4994 if (port->hasExtBitOp
4995 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4998 /* whew got the first case : create the AST */
4999 return newNode (RRC, root->left->left, NULL);
5003 /* not found return root */
5007 /*-----------------------------------------------------------------*/
5008 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
5009 /*-----------------------------------------------------------------*/
5011 optimizeSWAP (ast * root)
5013 /* will look for trees of the form
5014 (?expr << 4) | (?expr >> 4) or
5015 (?expr >> 4) | (?expr << 4) will make that
5016 into a SWAP : operation ..
5017 note : by 4 I mean (number of bits required to hold the
5019 /* if the root operations is not a | operation the not */
5020 if (!IS_BITOR (root))
5023 /* (?expr << 4) | (?expr >> 4) */
5024 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5025 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5028 if (!SPEC_USIGN (TETYPE (root->left->left)))
5031 if (!IS_AST_LIT_VALUE (root->left->right) ||
5032 !IS_AST_LIT_VALUE (root->right->right))
5035 /* make sure it is the same expression */
5036 if (!isAstEqual (root->left->left,
5040 if (AST_LIT_VALUE (root->left->right) !=
5041 (getSize (TTYPE (root->left->left)) * 4))
5044 if (AST_LIT_VALUE (root->right->right) !=
5045 (getSize (TTYPE (root->left->left)) * 4))
5048 /* make sure the port supports SWAP */
5049 if (port->hasExtBitOp
5050 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5053 /* found it : create the AST */
5054 return newNode (SWAP, root->left->left, NULL);
5058 /* not found return root */
5062 /*-----------------------------------------------------------------*/
5063 /* optimizeCompare - otimizes compares for bit variables */
5064 /*-----------------------------------------------------------------*/
5066 optimizeCompare (ast * root)
5068 ast *optExpr = NULL;
5071 unsigned int litValue;
5073 /* if nothing then return nothing */
5077 /* if not a compare op then do leaves */
5078 if (!IS_COMPARE_OP (root))
5080 root->left = optimizeCompare (root->left);
5081 root->right = optimizeCompare (root->right);
5085 /* if left & right are the same then depending
5086 of the operation do */
5087 if (isAstEqual (root->left, root->right))
5089 switch (root->opval.op)
5094 optExpr = newAst_VALUE (constVal ("0"));
5099 optExpr = newAst_VALUE (constVal ("1"));
5103 return decorateType (optExpr, RESULT_CHECK);
5106 vleft = (root->left->type == EX_VALUE ?
5107 root->left->opval.val : NULL);
5109 vright = (root->right->type == EX_VALUE ?
5110 root->right->opval.val : NULL);
5112 /* if left is a BITVAR in BITSPACE */
5113 /* and right is a LITERAL then opt- */
5114 /* imize else do nothing */
5115 if (vleft && vright &&
5116 IS_BITVAR (vleft->etype) &&
5117 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5118 IS_LITERAL (vright->etype))
5121 /* if right side > 1 then comparison may never succeed */
5122 if ((litValue = (int) floatFromVal (vright)) > 1)
5124 werror (W_BAD_COMPARE);
5130 switch (root->opval.op)
5132 case '>': /* bit value greater than 1 cannot be */
5133 werror (W_BAD_COMPARE);
5137 case '<': /* bit value < 1 means 0 */
5139 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5142 case LE_OP: /* bit value <= 1 means no check */
5143 optExpr = newAst_VALUE (vright);
5146 case GE_OP: /* bit value >= 1 means only check for = */
5148 optExpr = newAst_VALUE (vleft);
5153 { /* literal is zero */
5154 switch (root->opval.op)
5156 case '<': /* bit value < 0 cannot be */
5157 werror (W_BAD_COMPARE);
5161 case '>': /* bit value > 0 means 1 */
5163 optExpr = newAst_VALUE (vleft);
5166 case LE_OP: /* bit value <= 0 means no check */
5167 case GE_OP: /* bit value >= 0 means no check */
5168 werror (W_BAD_COMPARE);
5172 case EQ_OP: /* bit == 0 means ! of bit */
5173 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5177 return decorateType (resolveSymbols (optExpr), RESULT_CHECK);
5178 } /* end-of-if of BITVAR */
5183 /*-----------------------------------------------------------------*/
5184 /* addSymToBlock : adds the symbol to the first block we find */
5185 /*-----------------------------------------------------------------*/
5187 addSymToBlock (symbol * sym, ast * tree)
5189 /* reached end of tree or a leaf */
5190 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5194 if (IS_AST_OP (tree) &&
5195 tree->opval.op == BLOCK)
5198 symbol *lsym = copySymbol (sym);
5200 lsym->next = AST_VALUES (tree, sym);
5201 AST_VALUES (tree, sym) = lsym;
5205 addSymToBlock (sym, tree->left);
5206 addSymToBlock (sym, tree->right);
5209 /*-----------------------------------------------------------------*/
5210 /* processRegParms - do processing for register parameters */
5211 /*-----------------------------------------------------------------*/
5213 processRegParms (value * args, ast * body)
5217 if (IS_REGPARM (args->etype))
5218 addSymToBlock (args->sym, body);
5223 /*-----------------------------------------------------------------*/
5224 /* resetParmKey - resets the operandkeys for the symbols */
5225 /*-----------------------------------------------------------------*/
5226 DEFSETFUNC (resetParmKey)
5237 /*-----------------------------------------------------------------*/
5238 /* createFunction - This is the key node that calls the iCode for */
5239 /* generating the code for a function. Note code */
5240 /* is generated function by function, later when */
5241 /* add inter-procedural analysis this will change */
5242 /*-----------------------------------------------------------------*/
5244 createFunction (symbol * name, ast * body)
5250 iCode *piCode = NULL;
5252 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5253 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5255 /* if check function return 0 then some problem */
5256 if (checkFunction (name, NULL) == 0)
5259 /* create a dummy block if none exists */
5261 body = newNode (BLOCK, NULL, NULL);
5265 /* check if the function name already in the symbol table */
5266 if ((csym = findSym (SymbolTab, NULL, name->name)))
5269 /* special case for compiler defined functions
5270 we need to add the name to the publics list : this
5271 actually means we are now compiling the compiler
5275 addSet (&publics, name);
5281 allocVariables (name);
5283 name->lastLine = mylineno;
5286 /* set the stack pointer */
5287 /* PENDING: check this for the mcs51 */
5288 stackPtr = -port->stack.direction * port->stack.call_overhead;
5289 if (IFFUNC_ISISR (name->type))
5290 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5291 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5292 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5294 xstackPtr = -port->stack.direction * port->stack.call_overhead;
5296 fetype = getSpec (name->type); /* get the specifier for the function */
5297 /* if this is a reentrant function then */
5298 if (IFFUNC_ISREENT (name->type))
5301 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5303 /* do processing for parameters that are passed in registers */
5304 processRegParms (FUNC_ARGS(name->type), body);
5306 /* set the stack pointer */
5310 /* allocate & autoinit the block variables */
5311 processBlockVars (body, &stack, ALLOCATE);
5313 /* save the stack information */
5314 if (options.useXstack)
5315 name->xstack = SPEC_STAK (fetype) = stack;
5317 name->stack = SPEC_STAK (fetype) = stack;
5319 /* name needs to be mangled */
5320 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5322 body = resolveSymbols (body); /* resolve the symbols */
5323 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5326 ex = newAst_VALUE (symbolVal (name)); /* create name */
5327 ex = newNode (FUNCTION, ex, body);
5328 ex->values.args = FUNC_ARGS(name->type);
5330 if (options.dump_tree) PA(ex);
5333 werror (E_FUNC_NO_CODE, name->name);
5337 /* create the node & generate intermediate code */
5339 codeOutFile = code->oFile;
5340 piCode = iCodeFromAst (ex);
5344 werror (E_FUNC_NO_CODE, name->name);
5348 eBBlockFromiCode (piCode);
5350 /* if there are any statics then do them */
5353 GcurMemmap = statsg;
5354 codeOutFile = statsg->oFile;
5355 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_CHECK)));
5361 /* dealloc the block variables */
5362 processBlockVars (body, &stack, DEALLOCATE);
5363 outputDebugStackSymbols();
5364 /* deallocate paramaters */
5365 deallocParms (FUNC_ARGS(name->type));
5367 if (IFFUNC_ISREENT (name->type))
5370 /* we are done freeup memory & cleanup */
5372 if (port->reset_labelKey) labelKey = 1;
5374 FUNC_HASBODY(name->type) = 1;
5375 addSet (&operKeyReset, name);
5376 applyToSet (operKeyReset, resetParmKey);
5381 cleanUpLevel (LabelTab, 0);
5382 cleanUpBlock (StructTab, 1);
5383 cleanUpBlock (TypedefTab, 1);
5385 xstack->syms = NULL;
5386 istack->syms = NULL;
5391 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5392 /*-----------------------------------------------------------------*/
5393 /* ast_print : prints the ast (for debugging purposes) */
5394 /*-----------------------------------------------------------------*/
5396 void ast_print (ast * tree, FILE *outfile, int indent)
5401 /* can print only decorated trees */
5402 if (!tree->decorated) return;
5404 /* if any child is an error | this one is an error do nothing */
5405 if (tree->isError ||
5406 (tree->left && tree->left->isError) ||
5407 (tree->right && tree->right->isError)) {
5408 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5412 /* print the line */
5413 /* if not block & function */
5414 if (tree->type == EX_OP &&
5415 (tree->opval.op != FUNCTION &&
5416 tree->opval.op != BLOCK &&
5417 tree->opval.op != NULLOP)) {
5420 if (tree->opval.op == FUNCTION) {
5422 value *args=FUNC_ARGS(tree->left->opval.val->type);
5423 fprintf(outfile,"FUNCTION (%s=%p) type (",
5424 tree->left->opval.val->name, tree);
5425 printTypeChain (tree->left->opval.val->type->next,outfile);
5426 fprintf(outfile,") args (");
5429 fprintf (outfile, ", ");
5431 printTypeChain (args ? args->type : NULL, outfile);
5433 args= args ? args->next : NULL;
5435 fprintf(outfile,")\n");
5436 ast_print(tree->left,outfile,indent);
5437 ast_print(tree->right,outfile,indent);
5440 if (tree->opval.op == BLOCK) {
5441 symbol *decls = tree->values.sym;
5442 INDENT(indent,outfile);
5443 fprintf(outfile,"{\n");
5445 INDENT(indent+2,outfile);
5446 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5447 decls->name, decls);
5448 printTypeChain(decls->type,outfile);
5449 fprintf(outfile,")\n");
5451 decls = decls->next;
5453 ast_print(tree->right,outfile,indent+2);
5454 INDENT(indent,outfile);
5455 fprintf(outfile,"}\n");
5458 if (tree->opval.op == NULLOP) {
5459 ast_print(tree->left,outfile,indent);
5460 ast_print(tree->right,outfile,indent);
5463 INDENT(indent,outfile);
5465 /*------------------------------------------------------------------*/
5466 /*----------------------------*/
5467 /* leaf has been reached */
5468 /*----------------------------*/
5469 /* if this is of type value */
5470 /* just get the type */
5471 if (tree->type == EX_VALUE) {
5473 if (IS_LITERAL (tree->opval.val->etype)) {
5474 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5475 if (SPEC_USIGN (tree->opval.val->etype))
5476 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5478 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5479 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5480 floatFromVal(tree->opval.val));
5481 } else if (tree->opval.val->sym) {
5482 /* if the undefined flag is set then give error message */
5483 if (tree->opval.val->sym->undefined) {
5484 fprintf(outfile,"UNDEFINED SYMBOL ");
5486 fprintf(outfile,"SYMBOL ");
5488 fprintf(outfile,"(%s=%p)",
5489 tree->opval.val->sym->name,tree);
5492 fprintf(outfile," type (");
5493 printTypeChain(tree->ftype,outfile);
5494 fprintf(outfile,")\n");
5496 fprintf(outfile,"\n");
5501 /* if type link for the case of cast */
5502 if (tree->type == EX_LINK) {
5503 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5504 printTypeChain(tree->opval.lnk,outfile);
5505 fprintf(outfile,")\n");
5510 /* depending on type of operator do */
5512 switch (tree->opval.op) {
5513 /*------------------------------------------------------------------*/
5514 /*----------------------------*/
5516 /*----------------------------*/
5518 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5519 printTypeChain(tree->ftype,outfile);
5520 fprintf(outfile,")\n");
5521 ast_print(tree->left,outfile,indent+2);
5522 ast_print(tree->right,outfile,indent+2);
5525 /*------------------------------------------------------------------*/
5526 /*----------------------------*/
5528 /*----------------------------*/
5530 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5531 printTypeChain(tree->ftype,outfile);
5532 fprintf(outfile,")\n");
5533 ast_print(tree->left,outfile,indent+2);
5534 ast_print(tree->right,outfile,indent+2);
5537 /*------------------------------------------------------------------*/
5538 /*----------------------------*/
5539 /* struct/union pointer */
5540 /*----------------------------*/
5542 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5543 printTypeChain(tree->ftype,outfile);
5544 fprintf(outfile,")\n");
5545 ast_print(tree->left,outfile,indent+2);
5546 ast_print(tree->right,outfile,indent+2);
5549 /*------------------------------------------------------------------*/
5550 /*----------------------------*/
5551 /* ++/-- operation */
5552 /*----------------------------*/
5555 fprintf(outfile,"post-");
5557 fprintf(outfile,"pre-");
5558 fprintf(outfile,"INC_OP (%p) type (",tree);
5559 printTypeChain(tree->ftype,outfile);
5560 fprintf(outfile,")\n");
5561 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5562 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5567 fprintf(outfile,"post-");
5569 fprintf(outfile,"pre-");
5570 fprintf(outfile,"DEC_OP (%p) type (",tree);
5571 printTypeChain(tree->ftype,outfile);
5572 fprintf(outfile,")\n");
5573 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5574 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5577 /*------------------------------------------------------------------*/
5578 /*----------------------------*/
5580 /*----------------------------*/
5583 fprintf(outfile,"& (%p) type (",tree);
5584 printTypeChain(tree->ftype,outfile);
5585 fprintf(outfile,")\n");
5586 ast_print(tree->left,outfile,indent+2);
5587 ast_print(tree->right,outfile,indent+2);
5589 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5590 printTypeChain(tree->ftype,outfile);
5591 fprintf(outfile,")\n");
5592 ast_print(tree->left,outfile,indent+2);
5593 ast_print(tree->right,outfile,indent+2);
5596 /*----------------------------*/
5598 /*----------------------------*/
5600 fprintf(outfile,"OR (%p) type (",tree);
5601 printTypeChain(tree->ftype,outfile);
5602 fprintf(outfile,")\n");
5603 ast_print(tree->left,outfile,indent+2);
5604 ast_print(tree->right,outfile,indent+2);
5606 /*------------------------------------------------------------------*/
5607 /*----------------------------*/
5609 /*----------------------------*/
5611 fprintf(outfile,"XOR (%p) type (",tree);
5612 printTypeChain(tree->ftype,outfile);
5613 fprintf(outfile,")\n");
5614 ast_print(tree->left,outfile,indent+2);
5615 ast_print(tree->right,outfile,indent+2);
5618 /*------------------------------------------------------------------*/
5619 /*----------------------------*/
5621 /*----------------------------*/
5623 fprintf(outfile,"DIV (%p) type (",tree);
5624 printTypeChain(tree->ftype,outfile);
5625 fprintf(outfile,")\n");
5626 ast_print(tree->left,outfile,indent+2);
5627 ast_print(tree->right,outfile,indent+2);
5629 /*------------------------------------------------------------------*/
5630 /*----------------------------*/
5632 /*----------------------------*/
5634 fprintf(outfile,"MOD (%p) type (",tree);
5635 printTypeChain(tree->ftype,outfile);
5636 fprintf(outfile,")\n");
5637 ast_print(tree->left,outfile,indent+2);
5638 ast_print(tree->right,outfile,indent+2);
5641 /*------------------------------------------------------------------*/
5642 /*----------------------------*/
5643 /* address dereference */
5644 /*----------------------------*/
5645 case '*': /* can be unary : if right is null then unary operation */
5647 fprintf(outfile,"DEREF (%p) type (",tree);
5648 printTypeChain(tree->ftype,outfile);
5649 fprintf(outfile,")\n");
5650 ast_print(tree->left,outfile,indent+2);
5653 /*------------------------------------------------------------------*/
5654 /*----------------------------*/
5655 /* multiplication */
5656 /*----------------------------*/
5657 fprintf(outfile,"MULT (%p) type (",tree);
5658 printTypeChain(tree->ftype,outfile);
5659 fprintf(outfile,")\n");
5660 ast_print(tree->left,outfile,indent+2);
5661 ast_print(tree->right,outfile,indent+2);
5665 /*------------------------------------------------------------------*/
5666 /*----------------------------*/
5667 /* unary '+' operator */
5668 /*----------------------------*/
5672 fprintf(outfile,"UPLUS (%p) type (",tree);
5673 printTypeChain(tree->ftype,outfile);
5674 fprintf(outfile,")\n");
5675 ast_print(tree->left,outfile,indent+2);
5677 /*------------------------------------------------------------------*/
5678 /*----------------------------*/
5680 /*----------------------------*/
5681 fprintf(outfile,"ADD (%p) type (",tree);
5682 printTypeChain(tree->ftype,outfile);
5683 fprintf(outfile,")\n");
5684 ast_print(tree->left,outfile,indent+2);
5685 ast_print(tree->right,outfile,indent+2);
5688 /*------------------------------------------------------------------*/
5689 /*----------------------------*/
5691 /*----------------------------*/
5692 case '-': /* can be unary */
5694 fprintf(outfile,"UMINUS (%p) type (",tree);
5695 printTypeChain(tree->ftype,outfile);
5696 fprintf(outfile,")\n");
5697 ast_print(tree->left,outfile,indent+2);
5699 /*------------------------------------------------------------------*/
5700 /*----------------------------*/
5702 /*----------------------------*/
5703 fprintf(outfile,"SUB (%p) type (",tree);
5704 printTypeChain(tree->ftype,outfile);
5705 fprintf(outfile,")\n");
5706 ast_print(tree->left,outfile,indent+2);
5707 ast_print(tree->right,outfile,indent+2);
5710 /*------------------------------------------------------------------*/
5711 /*----------------------------*/
5713 /*----------------------------*/
5715 fprintf(outfile,"COMPL (%p) type (",tree);
5716 printTypeChain(tree->ftype,outfile);
5717 fprintf(outfile,")\n");
5718 ast_print(tree->left,outfile,indent+2);
5720 /*------------------------------------------------------------------*/
5721 /*----------------------------*/
5723 /*----------------------------*/
5725 fprintf(outfile,"NOT (%p) type (",tree);
5726 printTypeChain(tree->ftype,outfile);
5727 fprintf(outfile,")\n");
5728 ast_print(tree->left,outfile,indent+2);
5730 /*------------------------------------------------------------------*/
5731 /*----------------------------*/
5733 /*----------------------------*/
5735 fprintf(outfile,"RRC (%p) type (",tree);
5736 printTypeChain(tree->ftype,outfile);
5737 fprintf(outfile,")\n");
5738 ast_print(tree->left,outfile,indent+2);
5742 fprintf(outfile,"RLC (%p) type (",tree);
5743 printTypeChain(tree->ftype,outfile);
5744 fprintf(outfile,")\n");
5745 ast_print(tree->left,outfile,indent+2);
5748 fprintf(outfile,"SWAP (%p) type (",tree);
5749 printTypeChain(tree->ftype,outfile);
5750 fprintf(outfile,")\n");
5751 ast_print(tree->left,outfile,indent+2);
5754 fprintf(outfile,"GETHBIT (%p) type (",tree);
5755 printTypeChain(tree->ftype,outfile);
5756 fprintf(outfile,")\n");
5757 ast_print(tree->left,outfile,indent+2);
5760 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5761 printTypeChain(tree->ftype,outfile);
5762 fprintf(outfile,")\n");
5763 ast_print(tree->left,outfile,indent+2);
5764 ast_print(tree->right,outfile,indent+2);
5767 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5768 printTypeChain(tree->ftype,outfile);
5769 fprintf(outfile,")\n");
5770 ast_print(tree->left,outfile,indent+2);
5771 ast_print(tree->right,outfile,indent+2);
5773 /*------------------------------------------------------------------*/
5774 /*----------------------------*/
5776 /*----------------------------*/
5777 case CAST: /* change the type */
5778 fprintf(outfile,"CAST (%p) from type (",tree);
5779 printTypeChain(tree->right->ftype,outfile);
5780 fprintf(outfile,") to type (");
5781 printTypeChain(tree->ftype,outfile);
5782 fprintf(outfile,")\n");
5783 ast_print(tree->right,outfile,indent+2);
5787 fprintf(outfile,"ANDAND (%p) type (",tree);
5788 printTypeChain(tree->ftype,outfile);
5789 fprintf(outfile,")\n");
5790 ast_print(tree->left,outfile,indent+2);
5791 ast_print(tree->right,outfile,indent+2);
5794 fprintf(outfile,"OROR (%p) type (",tree);
5795 printTypeChain(tree->ftype,outfile);
5796 fprintf(outfile,")\n");
5797 ast_print(tree->left,outfile,indent+2);
5798 ast_print(tree->right,outfile,indent+2);
5801 /*------------------------------------------------------------------*/
5802 /*----------------------------*/
5803 /* comparison operators */
5804 /*----------------------------*/
5806 fprintf(outfile,"GT(>) (%p) type (",tree);
5807 printTypeChain(tree->ftype,outfile);
5808 fprintf(outfile,")\n");
5809 ast_print(tree->left,outfile,indent+2);
5810 ast_print(tree->right,outfile,indent+2);
5813 fprintf(outfile,"LT(<) (%p) type (",tree);
5814 printTypeChain(tree->ftype,outfile);
5815 fprintf(outfile,")\n");
5816 ast_print(tree->left,outfile,indent+2);
5817 ast_print(tree->right,outfile,indent+2);
5820 fprintf(outfile,"LE(<=) (%p) type (",tree);
5821 printTypeChain(tree->ftype,outfile);
5822 fprintf(outfile,")\n");
5823 ast_print(tree->left,outfile,indent+2);
5824 ast_print(tree->right,outfile,indent+2);
5827 fprintf(outfile,"GE(>=) (%p) type (",tree);
5828 printTypeChain(tree->ftype,outfile);
5829 fprintf(outfile,")\n");
5830 ast_print(tree->left,outfile,indent+2);
5831 ast_print(tree->right,outfile,indent+2);
5834 fprintf(outfile,"EQ(==) (%p) type (",tree);
5835 printTypeChain(tree->ftype,outfile);
5836 fprintf(outfile,")\n");
5837 ast_print(tree->left,outfile,indent+2);
5838 ast_print(tree->right,outfile,indent+2);
5841 fprintf(outfile,"NE(!=) (%p) type (",tree);
5842 printTypeChain(tree->ftype,outfile);
5843 fprintf(outfile,")\n");
5844 ast_print(tree->left,outfile,indent+2);
5845 ast_print(tree->right,outfile,indent+2);
5846 /*------------------------------------------------------------------*/
5847 /*----------------------------*/
5849 /*----------------------------*/
5850 case SIZEOF: /* evaluate wihout code generation */
5851 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5854 /*------------------------------------------------------------------*/
5855 /*----------------------------*/
5856 /* conditional operator '?' */
5857 /*----------------------------*/
5859 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5860 printTypeChain(tree->ftype,outfile);
5861 fprintf(outfile,")\n");
5862 ast_print(tree->left,outfile,indent+2);
5863 ast_print(tree->right,outfile,indent+2);
5867 fprintf(outfile,"COLON(:) (%p) type (",tree);
5868 printTypeChain(tree->ftype,outfile);
5869 fprintf(outfile,")\n");
5870 ast_print(tree->left,outfile,indent+2);
5871 ast_print(tree->right,outfile,indent+2);
5874 /*------------------------------------------------------------------*/
5875 /*----------------------------*/
5876 /* assignment operators */
5877 /*----------------------------*/
5879 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5880 printTypeChain(tree->ftype,outfile);
5881 fprintf(outfile,")\n");
5882 ast_print(tree->left,outfile,indent+2);
5883 ast_print(tree->right,outfile,indent+2);
5886 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5887 printTypeChain(tree->ftype,outfile);
5888 fprintf(outfile,")\n");
5889 ast_print(tree->left,outfile,indent+2);
5890 ast_print(tree->right,outfile,indent+2);
5893 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5894 printTypeChain(tree->ftype,outfile);
5895 fprintf(outfile,")\n");
5896 ast_print(tree->left,outfile,indent+2);
5897 ast_print(tree->right,outfile,indent+2);
5900 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5901 printTypeChain(tree->ftype,outfile);
5902 fprintf(outfile,")\n");
5903 ast_print(tree->left,outfile,indent+2);
5904 ast_print(tree->right,outfile,indent+2);
5907 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5908 printTypeChain(tree->ftype,outfile);
5909 fprintf(outfile,")\n");
5910 ast_print(tree->left,outfile,indent+2);
5911 ast_print(tree->right,outfile,indent+2);
5914 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5915 printTypeChain(tree->ftype,outfile);
5916 fprintf(outfile,")\n");
5917 ast_print(tree->left,outfile,indent+2);
5918 ast_print(tree->right,outfile,indent+2);
5921 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5922 printTypeChain(tree->ftype,outfile);
5923 fprintf(outfile,")\n");
5924 ast_print(tree->left,outfile,indent+2);
5925 ast_print(tree->right,outfile,indent+2);
5927 /*------------------------------------------------------------------*/
5928 /*----------------------------*/
5930 /*----------------------------*/
5932 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5933 printTypeChain(tree->ftype,outfile);
5934 fprintf(outfile,")\n");
5935 ast_print(tree->left,outfile,indent+2);
5936 ast_print(tree->right,outfile,indent+2);
5938 /*------------------------------------------------------------------*/
5939 /*----------------------------*/
5941 /*----------------------------*/
5943 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5944 printTypeChain(tree->ftype,outfile);
5945 fprintf(outfile,")\n");
5946 ast_print(tree->left,outfile,indent+2);
5947 ast_print(tree->right,outfile,indent+2);
5949 /*------------------------------------------------------------------*/
5950 /*----------------------------*/
5951 /* straight assignemnt */
5952 /*----------------------------*/
5954 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5955 printTypeChain(tree->ftype,outfile);
5956 fprintf(outfile,")\n");
5957 ast_print(tree->left,outfile,indent+2);
5958 ast_print(tree->right,outfile,indent+2);
5960 /*------------------------------------------------------------------*/
5961 /*----------------------------*/
5962 /* comma operator */
5963 /*----------------------------*/
5965 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5966 printTypeChain(tree->ftype,outfile);
5967 fprintf(outfile,")\n");
5968 ast_print(tree->left,outfile,indent+2);
5969 ast_print(tree->right,outfile,indent+2);
5971 /*------------------------------------------------------------------*/
5972 /*----------------------------*/
5974 /*----------------------------*/
5977 fprintf(outfile,"CALL (%p) type (",tree);
5978 printTypeChain(tree->ftype,outfile);
5979 fprintf(outfile,")\n");
5980 ast_print(tree->left,outfile,indent+2);
5981 ast_print(tree->right,outfile,indent+2);
5984 fprintf(outfile,"PARMS\n");
5985 ast_print(tree->left,outfile,indent+2);
5986 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5987 ast_print(tree->right,outfile,indent+2);
5990 /*------------------------------------------------------------------*/
5991 /*----------------------------*/
5992 /* return statement */
5993 /*----------------------------*/
5995 fprintf(outfile,"RETURN (%p) type (",tree);
5997 printTypeChain(tree->right->ftype,outfile);
5999 fprintf(outfile,")\n");
6000 ast_print(tree->right,outfile,indent+2);
6002 /*------------------------------------------------------------------*/
6003 /*----------------------------*/
6004 /* label statement */
6005 /*----------------------------*/
6007 fprintf(outfile,"LABEL (%p)\n",tree);
6008 ast_print(tree->left,outfile,indent+2);
6009 ast_print(tree->right,outfile,indent);
6011 /*------------------------------------------------------------------*/
6012 /*----------------------------*/
6013 /* switch statement */
6014 /*----------------------------*/
6018 fprintf(outfile,"SWITCH (%p) ",tree);
6019 ast_print(tree->left,outfile,0);
6020 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
6021 INDENT(indent+2,outfile);
6022 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
6023 (int) floatFromVal(val),
6024 tree->values.switchVals.swNum,
6025 (int) floatFromVal(val));
6027 ast_print(tree->right,outfile,indent);
6030 /*------------------------------------------------------------------*/
6031 /*----------------------------*/
6033 /*----------------------------*/
6035 fprintf(outfile,"IF (%p) \n",tree);
6036 ast_print(tree->left,outfile,indent+2);
6037 if (tree->trueLabel) {
6038 INDENT(indent+2,outfile);
6039 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
6041 if (tree->falseLabel) {
6042 INDENT(indent+2,outfile);
6043 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
6045 ast_print(tree->right,outfile,indent+2);
6047 /*----------------------------*/
6048 /* goto Statement */
6049 /*----------------------------*/
6051 fprintf(outfile,"GOTO (%p) \n",tree);
6052 ast_print(tree->left,outfile,indent+2);
6053 fprintf(outfile,"\n");
6055 /*------------------------------------------------------------------*/
6056 /*----------------------------*/
6058 /*----------------------------*/
6060 fprintf(outfile,"FOR (%p) \n",tree);
6061 if (AST_FOR( tree, initExpr)) {
6062 INDENT(indent+2,outfile);
6063 fprintf(outfile,"INIT EXPR ");
6064 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6066 if (AST_FOR( tree, condExpr)) {
6067 INDENT(indent+2,outfile);
6068 fprintf(outfile,"COND EXPR ");
6069 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6071 if (AST_FOR( tree, loopExpr)) {
6072 INDENT(indent+2,outfile);
6073 fprintf(outfile,"LOOP EXPR ");
6074 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6076 fprintf(outfile,"FOR LOOP BODY \n");
6077 ast_print(tree->left,outfile,indent+2);
6080 fprintf(outfile,"CRITICAL (%p) \n",tree);
6081 ast_print(tree->left,outfile,indent+2);
6089 ast_print(t,stdout,0);
6094 /*-----------------------------------------------------------------*/
6095 /* astErrors : returns non-zero if errors present in tree */
6096 /*-----------------------------------------------------------------*/
6097 int astErrors(ast *t)
6106 if (t->type == EX_VALUE
6107 && t->opval.val->sym
6108 && t->opval.val->sym->undefined)
6111 errors += astErrors(t->left);
6112 errors += astErrors(t->right);