1 /*-------------------------------------------------------------------------
2 SDCCast.c - source file for parser support & all ast related routines
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
29 set *operKeyReset = NULL;
30 ast *staticAutos = NULL;
33 #define LRVAL(x) x->left->rvalue
34 #define RRVAL(x) x->right->rvalue
35 #define TRVAL(x) x->rvalue
36 #define LLVAL(x) x->left->lvalue
37 #define RLVAL(x) x->right->lvalue
38 #define TLVAL(x) x->lvalue
39 #define RTYPE(x) x->right->ftype
40 #define RETYPE(x) x->right->etype
41 #define LTYPE(x) x->left->ftype
42 #define LETYPE(x) x->left->etype
43 #define TTYPE(x) x->ftype
44 #define TETYPE(x) x->etype
50 symbol *currFunc=NULL;
51 static ast *createIval (ast *, sym_link *, initList *, ast *);
52 static ast *createIvalCharPtr (ast *, sym_link *, ast *);
53 static ast *optimizeCompare (ast *);
54 ast *optimizeRRCRLC (ast *);
55 ast *optimizeSWAP (ast *);
56 ast *optimizeGetHbit (ast *);
57 ast *backPatchLabels (ast *, symbol *, symbol *);
60 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
65 printTypeChain (tree->ftype, stdout);
70 /*-----------------------------------------------------------------*/
71 /* newAst - creates a fresh node for an expression tree */
72 /*-----------------------------------------------------------------*/
74 newAst_ (unsigned type)
77 static int oldLineno = 0;
79 ex = Safe_alloc ( sizeof (ast));
82 ex->lineno = (noLineno ? oldLineno : mylineno);
83 ex->filename = currFname;
84 ex->level = NestLevel;
85 ex->block = currBlockno;
86 ex->initMode = inInitMode;
87 ex->seqPoint = seqPointNo;
92 newAst_VALUE (value * val)
94 ast *ex = newAst_ (EX_VALUE);
100 newAst_OP (unsigned op)
102 ast *ex = newAst_ (EX_OP);
108 newAst_LINK (sym_link * val)
110 ast *ex = newAst_ (EX_LINK);
115 /*-----------------------------------------------------------------*/
116 /* newNode - creates a new node */
117 /*-----------------------------------------------------------------*/
119 newNode (long op, ast * left, ast * right)
130 /*-----------------------------------------------------------------*/
131 /* newIfxNode - creates a new Ifx Node */
132 /*-----------------------------------------------------------------*/
134 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
138 /* if this is a literal then we already know the result */
139 if (condAst->etype && IS_LITERAL (condAst->etype))
141 /* then depending on the expression value */
142 if (floatFromVal (condAst->opval.val))
143 ifxNode = newNode (GOTO,
144 newAst_VALUE (symbolVal (trueLabel)),
147 ifxNode = newNode (GOTO,
148 newAst_VALUE (symbolVal (falseLabel)),
153 ifxNode = newNode (IFX, condAst, NULL);
154 ifxNode->trueLabel = trueLabel;
155 ifxNode->falseLabel = falseLabel;
161 /*-----------------------------------------------------------------*/
162 /* copyAstValues - copies value portion of ast if needed */
163 /*-----------------------------------------------------------------*/
165 copyAstValues (ast * dest, ast * src)
167 switch (src->opval.op)
170 dest->values.sym = copySymbolChain (src->values.sym);
174 dest->values.switchVals.swVals =
175 copyValue (src->values.switchVals.swVals);
176 dest->values.switchVals.swDefault =
177 src->values.switchVals.swDefault;
178 dest->values.switchVals.swNum =
179 src->values.switchVals.swNum;
183 dest->values.inlineasm = Safe_strdup(src->values.inlineasm);
187 dest->values.constlist = copyLiteralList(src->values.constlist);
191 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
192 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
193 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
194 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
195 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
196 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
197 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
202 /*-----------------------------------------------------------------*/
203 /* copyAst - makes a copy of a given astession */
204 /*-----------------------------------------------------------------*/
213 dest = Safe_alloc ( sizeof (ast));
215 dest->type = src->type;
216 dest->lineno = src->lineno;
217 dest->level = src->level;
218 dest->funcName = src->funcName;
221 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
223 /* if this is a leaf */
225 if (src->type == EX_VALUE)
227 dest->opval.val = copyValue (src->opval.val);
232 if (src->type == EX_LINK)
234 dest->opval.lnk = copyLinkChain (src->opval.lnk);
238 dest->opval.op = src->opval.op;
240 /* if this is a node that has special values */
241 copyAstValues (dest, src);
243 dest->trueLabel = copySymbol (src->trueLabel);
244 dest->falseLabel = copySymbol (src->falseLabel);
245 dest->left = copyAst (src->left);
246 dest->right = copyAst (src->right);
252 /*-----------------------------------------------------------------*/
253 /* removeIncDecOps: remove for side effects in *_ASSIGN's */
254 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
255 /*-----------------------------------------------------------------*/
256 ast *removeIncDecOps (ast * tree) {
258 // traverse the tree and remove inc/dec ops
263 if (tree->type == EX_OP &&
264 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
271 tree->left=removeIncDecOps(tree->left);
272 tree->right=removeIncDecOps(tree->right);
277 /*-----------------------------------------------------------------*/
278 /* removePreIncDecOps: remove for side effects in *_ASSIGN's */
279 /* "*++s += 3" -> "*++s = *++s + 3" */
280 /*-----------------------------------------------------------------*/
281 ast *removePreIncDecOps (ast * tree) {
283 // traverse the tree and remove pre-inc/dec ops
288 if (tree->type == EX_OP &&
289 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
294 tree->left=removePreIncDecOps(tree->left);
295 tree->right=removePreIncDecOps(tree->right);
300 /*-----------------------------------------------------------------*/
301 /* removePostIncDecOps: remove for side effects in *_ASSIGN's */
302 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
303 /*-----------------------------------------------------------------*/
304 ast *removePostIncDecOps (ast * tree) {
306 // traverse the tree and remove pre-inc/dec ops
311 if (tree->type == EX_OP &&
312 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
317 tree->left=removePostIncDecOps(tree->left);
318 tree->right=removePostIncDecOps(tree->right);
323 /*-----------------------------------------------------------------*/
324 /* hasSEFcalls - returns TRUE if tree has a function call */
325 /*-----------------------------------------------------------------*/
327 hasSEFcalls (ast * tree)
332 if (tree->type == EX_OP &&
333 (tree->opval.op == CALL ||
334 tree->opval.op == PCALL ||
335 tree->opval.op == '=' ||
336 tree->opval.op == INC_OP ||
337 tree->opval.op == DEC_OP))
340 return (hasSEFcalls (tree->left) |
341 hasSEFcalls (tree->right));
344 /*-----------------------------------------------------------------*/
345 /* isAstEqual - compares two asts & returns 1 if they are equal */
346 /*-----------------------------------------------------------------*/
348 isAstEqual (ast * t1, ast * t2)
357 if (t1->type != t2->type)
363 if (t1->opval.op != t2->opval.op)
365 return (isAstEqual (t1->left, t2->left) &&
366 isAstEqual (t1->right, t2->right));
370 if (t1->opval.val->sym)
372 if (!t2->opval.val->sym)
375 return isSymbolEqual (t1->opval.val->sym,
380 if (t2->opval.val->sym)
383 return (floatFromVal (t1->opval.val) ==
384 floatFromVal (t2->opval.val));
388 /* only compare these two types */
396 /*-----------------------------------------------------------------*/
397 /* resolveSymbols - resolve symbols from the symbol table */
398 /*-----------------------------------------------------------------*/
400 resolveSymbols (ast * tree)
402 /* walk the entire tree and check for values */
403 /* with symbols if we find one then replace */
404 /* symbol with that from the symbol table */
411 /* if not block & function */
412 if (tree->type == EX_OP &&
413 (tree->opval.op != FUNCTION &&
414 tree->opval.op != BLOCK &&
415 tree->opval.op != NULLOP))
417 filename = tree->filename;
418 lineno = tree->lineno;
422 /* make sure we resolve the true & false labels for ifx */
423 if (tree->type == EX_OP && tree->opval.op == IFX)
429 if ((csym = findSym (LabelTab, tree->trueLabel,
430 tree->trueLabel->name)))
431 tree->trueLabel = csym;
433 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
434 tree->trueLabel->name);
437 if (tree->falseLabel)
439 if ((csym = findSym (LabelTab,
441 tree->falseLabel->name)))
442 tree->falseLabel = csym;
444 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
445 tree->falseLabel->name);
450 /* if this is a label resolve it from the labelTab */
451 if (IS_AST_VALUE (tree) &&
452 tree->opval.val->sym &&
453 tree->opval.val->sym->islbl)
456 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
457 tree->opval.val->sym->name);
460 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
461 tree->opval.val->sym->name);
463 tree->opval.val->sym = csym;
465 goto resolveChildren;
468 /* do only for leafs */
469 if (IS_AST_VALUE (tree) &&
470 tree->opval.val->sym &&
471 !tree->opval.val->sym->implicit)
474 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
476 /* if found in the symbol table & they r not the same */
477 if (csym && tree->opval.val->sym != csym)
479 tree->opval.val->sym = csym;
480 tree->opval.val->type = csym->type;
481 tree->opval.val->etype = csym->etype;
484 /* if not found in the symbol table */
485 /* mark it as undefined assume it is */
486 /* an integer in data space */
487 if (!csym && !tree->opval.val->sym->implicit)
490 /* if this is a function name then */
491 /* mark it as returning an int */
494 tree->opval.val->sym->type = newLink (DECLARATOR);
495 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
496 tree->opval.val->sym->type->next =
497 tree->opval.val->sym->etype = newIntLink ();
498 tree->opval.val->etype = tree->opval.val->etype;
499 tree->opval.val->type = tree->opval.val->sym->type;
500 werrorfl (tree->filename, tree->lineno, W_IMPLICIT_FUNC,
501 tree->opval.val->sym->name);
502 //tree->opval.val->sym->undefined = 1;
503 allocVariables (tree->opval.val->sym);
507 tree->opval.val->sym->undefined = 1;
508 tree->opval.val->type =
509 tree->opval.val->etype = newIntLink ();
510 tree->opval.val->sym->type =
511 tree->opval.val->sym->etype = newIntLink ();
517 resolveSymbols (tree->left);
518 resolveSymbols (tree->right);
523 /*-----------------------------------------------------------------*/
524 /* setAstLineno - walks a ast tree & sets the line number */
525 /*-----------------------------------------------------------------*/
526 int setAstLineno (ast * tree, int lineno)
531 tree->lineno = lineno;
532 setAstLineno (tree->left, lineno);
533 setAstLineno (tree->right, lineno);
537 /*-----------------------------------------------------------------*/
538 /* funcOfType :- function of type with name */
539 /*-----------------------------------------------------------------*/
541 funcOfType (char *name, sym_link * type, sym_link * argType,
545 /* create the symbol */
546 sym = newSymbol (name, 0);
548 /* setup return value */
549 sym->type = newLink (DECLARATOR);
550 DCL_TYPE (sym->type) = FUNCTION;
551 sym->type->next = copyLinkChain (type);
552 sym->etype = getSpec (sym->type);
553 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
555 /* if arguments required */
559 args = FUNC_ARGS(sym->type) = newValue ();
563 args->type = copyLinkChain (argType);
564 args->etype = getSpec (args->type);
565 SPEC_EXTR(args->etype)=1;
568 args = args->next = newValue ();
575 allocVariables (sym);
580 /*-----------------------------------------------------------------*/
581 /* funcOfTypeVarg :- function of type with name and argtype */
582 /*-----------------------------------------------------------------*/
584 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
589 /* create the symbol */
590 sym = newSymbol (name, 0);
592 /* setup return value */
593 sym->type = newLink (DECLARATOR);
594 DCL_TYPE (sym->type) = FUNCTION;
595 sym->type->next = typeFromStr(rtype);
596 sym->etype = getSpec (sym->type);
598 /* if arguments required */
601 args = FUNC_ARGS(sym->type) = newValue ();
603 for ( i = 0 ; i < nArgs ; i++ ) {
604 args->type = typeFromStr(atypes[i]);
605 args->etype = getSpec (args->type);
606 SPEC_EXTR(args->etype)=1;
607 if ((i + 1) == nArgs) break;
608 args = args->next = newValue ();
615 allocVariables (sym);
620 /*-----------------------------------------------------------------*/
621 /* reverseParms - will reverse a parameter tree */
622 /*-----------------------------------------------------------------*/
624 reverseParms (ast * ptree)
630 /* top down if we find a nonParm tree then quit */
631 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
634 ptree->left = ptree->right;
635 ptree->right = ttree;
636 reverseParms (ptree->left);
637 reverseParms (ptree->right);
643 /*-----------------------------------------------------------------*/
644 /* processParms - makes sure the parameters are okay and do some */
645 /* processing with them */
646 /*-----------------------------------------------------------------*/
648 processParms (ast *func,
651 int *parmNumber, /* unused, although updated */
654 RESULT_TYPE resultType;
656 /* if none of them exist */
657 if (!defParm && !actParm)
662 if (getenv("DEBUG_SANITY"))
664 fprintf (stderr, "processParms: %s ", defParm->name);
666 /* make sure the type is complete and sane */
667 checkTypeSanity(defParm->etype, defParm->name);
670 /* if the function is being called via a pointer & */
671 /* it has not been defined a reentrant then we cannot */
672 /* have parameters */
673 if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
675 werror (W_NONRENT_ARGS);
679 /* if defined parameters ended but actual parameters */
680 /* exist and this is not defined as a variable arg */
681 if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
683 /* if (func->type==EX_VALUE && func->opval.val->sym->undefined) */
684 /* return 1; *//* Already gave them an undefined function error */
685 werror (E_TOO_MANY_PARMS);
689 /* if defined parameters present but no actual parameters */
690 if (defParm && !actParm)
692 werror (E_TOO_FEW_PARMS);
696 /* if this is a PARAM node then match left & right */
697 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
699 actParm->decorated = 1;
700 return (processParms (func, defParm,
701 actParm->left, parmNumber, FALSE) ||
702 processParms (func, defParm ? defParm->next : NULL,
703 actParm->right, parmNumber, rightmost));
705 else if (defParm) /* not vararg */
707 /* If we have found a value node by following only right-hand links,
708 * then we know that there are no more values after us.
710 * Therefore, if there are more defined parameters, the caller didn't
713 if (rightmost && defParm->next)
715 werror (E_TOO_FEW_PARMS);
720 /* decorate parameter */
721 resultType = defParm ? getResultTypeFromType (defParm->etype) :
723 actParm = decorateType (actParm, resultType);
725 if (IS_VOID(actParm->ftype))
727 werror (E_VOID_VALUE_USED);
731 /* If this is a varargs function... */
732 if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
737 if (IS_CAST_OP (actParm)
738 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
740 /* Parameter was explicitly typecast; don't touch it. */
744 ftype = actParm->ftype;
746 /* If it's a char, upcast to int. */
747 if (IS_INTEGRAL (ftype)
748 && (getSize (ftype) < (unsigned) INTSIZE))
750 newType = newAst_LINK(INTTYPE);
753 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
755 newType = newAst_LINK (copyLinkChain(ftype));
756 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
759 if (IS_AGGREGATE (ftype))
761 newType = newAst_LINK (copyLinkChain (ftype));
762 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
767 /* cast required; change this op to a cast. */
768 ast *parmCopy = resolveSymbols (copyAst (actParm));
770 actParm->type = EX_OP;
771 actParm->opval.op = CAST;
772 actParm->left = newType;
773 actParm->right = parmCopy;
774 actParm->decorated = 0; /* force typechecking */
775 decorateType (actParm, RESULT_TYPE_NONE);
780 /* if defined parameters ended but actual has not & */
782 if (!defParm && actParm &&
783 (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
786 resolveSymbols (actParm);
788 /* the parameter type must be at least castable */
789 if (compareType (defParm->type, actParm->ftype) == 0)
791 werror (E_INCOMPAT_TYPES);
792 printFromToType (actParm->ftype, defParm->type);
796 /* if the parameter is castable then add the cast */
797 if (compareType (defParm->type, actParm->ftype) < 0)
801 resultType = getResultTypeFromType (defParm->etype);
802 pTree = resolveSymbols (copyAst (actParm));
804 /* now change the current one to a cast */
805 actParm->type = EX_OP;
806 actParm->opval.op = CAST;
807 actParm->left = newAst_LINK (defParm->type);
808 actParm->right = pTree;
809 actParm->decorated = 0; /* force typechecking */
810 decorateType (actParm, resultType);
813 /* make a copy and change the regparm type to the defined parm */
814 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
815 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
816 SPEC_ARGREG (actParm->etype) = SPEC_ARGREG (defParm->etype);
821 /*-----------------------------------------------------------------*/
822 /* createIvalType - generates ival for basic types */
823 /*-----------------------------------------------------------------*/
825 createIvalType (ast * sym, sym_link * type, initList * ilist)
829 /* if initList is deep */
830 if (ilist->type == INIT_DEEP)
831 ilist = ilist->init.deep;
833 iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK);
834 return decorateType (newNode ('=', sym, iExpr), RESULT_CHECK);
837 /*-----------------------------------------------------------------*/
838 /* createIvalStruct - generates initial value for structures */
839 /*-----------------------------------------------------------------*/
841 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
848 sflds = SPEC_STRUCT (type)->fields;
849 if (ilist->type != INIT_DEEP)
851 werror (E_INIT_STRUCT, "");
855 iloop = ilist->init.deep;
857 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
859 /* if we have come to end */
863 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
864 lAst = decorateType (resolveSymbols (lAst), RESULT_CHECK);
865 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)), RESULT_CHECK);
869 werrorfl (filename, sym->opval.val->sym->lineDef,
870 W_EXCESS_INITIALIZERS, "struct",
871 sym->opval.val->sym->name);
878 /*-----------------------------------------------------------------*/
879 /* createIvalArray - generates code for array initialization */
880 /*-----------------------------------------------------------------*/
882 createIvalArray (ast * sym, sym_link * type, initList * ilist)
886 int lcnt = 0, size = 0;
887 literalList *literalL;
889 /* take care of the special case */
890 /* array of characters can be init */
892 if (IS_CHAR (type->next))
893 if ((rast = createIvalCharPtr (sym,
895 decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK))))
897 return decorateType (resolveSymbols (rast), RESULT_CHECK);
899 /* not the special case */
900 if (ilist->type != INIT_DEEP)
902 werror (E_INIT_STRUCT, "");
906 iloop = ilist->init.deep;
907 lcnt = DCL_ELEM (type);
909 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
913 aSym = decorateType (resolveSymbols(sym), RESULT_CHECK);
915 rast = newNode(ARRAYINIT, aSym, NULL);
916 rast->values.constlist = literalL;
918 // Make sure size is set to length of initializer list.
925 if (lcnt && size > lcnt)
927 // Array size was specified, and we have more initializers than needed.
928 char *name=sym->opval.val->sym->name;
929 int lineno=sym->opval.val->sym->lineDef;
931 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
940 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
941 aSym = decorateType (resolveSymbols (aSym), RESULT_CHECK);
942 rast = createIval (aSym, type->next, iloop, rast);
943 iloop = (iloop ? iloop->next : NULL);
949 /* no of elements given and we */
950 /* have generated for all of them */
953 // there has to be a better way
954 char *name=sym->opval.val->sym->name;
955 int lineno=sym->opval.val->sym->lineDef;
956 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
963 /* if we have not been given a size */
964 if (!DCL_ELEM (type))
966 DCL_ELEM (type) = size;
969 return decorateType (resolveSymbols (rast), RESULT_CHECK);
973 /*-----------------------------------------------------------------*/
974 /* createIvalCharPtr - generates initial values for char pointers */
975 /*-----------------------------------------------------------------*/
977 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
981 /* if this is a pointer & right is a literal array then */
982 /* just assignment will do */
983 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
984 SPEC_SCLS (iexpr->etype) == S_CODE)
985 && IS_ARRAY (iexpr->ftype)))
986 return newNode ('=', sym, iexpr);
988 /* left side is an array so we have to assign each */
990 if ((IS_LITERAL (iexpr->etype) ||
991 SPEC_SCLS (iexpr->etype) == S_CODE)
992 && IS_ARRAY (iexpr->ftype))
994 /* for each character generate an assignment */
995 /* to the array element */
996 char *s = SPEC_CVAL (iexpr->etype).v_char;
998 int size = getSize (iexpr->ftype);
999 int symsize = getSize (type);
1003 if (size>(symsize+1))
1004 werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1005 "string", sym->opval.val->sym->name);
1009 for (i=0;i<size;i++)
1011 rast = newNode (NULLOP,
1015 newAst_VALUE (valueFromLit ((float) i))),
1016 newAst_VALUE (valueFromLit (*s))));
1020 // now WE don't need iexpr's symbol anymore
1021 freeStringSymbol(AST_SYMBOL(iexpr));
1023 return decorateType (resolveSymbols (rast), RESULT_CHECK);
1029 /*-----------------------------------------------------------------*/
1030 /* createIvalPtr - generates initial value for pointers */
1031 /*-----------------------------------------------------------------*/
1033 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
1039 if (ilist->type == INIT_DEEP)
1040 ilist = ilist->init.deep;
1042 iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK);
1044 /* if character pointer */
1045 if (IS_CHAR (type->next))
1046 if ((rast = createIvalCharPtr (sym, type, iexpr)))
1049 return newNode ('=', sym, iexpr);
1052 /*-----------------------------------------------------------------*/
1053 /* createIval - generates code for initial value */
1054 /*-----------------------------------------------------------------*/
1056 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1063 /* if structure then */
1064 if (IS_STRUCT (type))
1065 rast = createIvalStruct (sym, type, ilist);
1067 /* if this is a pointer */
1069 rast = createIvalPtr (sym, type, ilist);
1071 /* if this is an array */
1072 if (IS_ARRAY (type))
1073 rast = createIvalArray (sym, type, ilist);
1075 /* if type is SPECIFIER */
1077 rast = createIvalType (sym, type, ilist);
1080 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_CHECK);
1082 return decorateType (resolveSymbols (rast), RESULT_CHECK);
1085 /*-----------------------------------------------------------------*/
1086 /* initAggregates - initialises aggregate variables with initv */
1087 /*-----------------------------------------------------------------*/
1088 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1089 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1092 /*-----------------------------------------------------------------*/
1093 /* gatherAutoInit - creates assignment expressions for initial */
1095 /*-----------------------------------------------------------------*/
1097 gatherAutoInit (symbol * autoChain)
1104 for (sym = autoChain; sym; sym = sym->next)
1107 /* resolve the symbols in the ival */
1109 resolveIvalSym (sym->ival, sym->type);
1111 /* if this is a static variable & has an */
1112 /* initial value the code needs to be lifted */
1113 /* here to the main portion since they can be */
1114 /* initialised only once at the start */
1115 if (IS_STATIC (sym->etype) && sym->ival &&
1116 SPEC_SCLS (sym->etype) != S_CODE)
1120 /* insert the symbol into the symbol table */
1121 /* with level = 0 & name = rname */
1122 newSym = copySymbol (sym);
1123 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1125 /* now lift the code to main */
1126 if (IS_AGGREGATE (sym->type)) {
1127 work = initAggregates (sym, sym->ival, NULL);
1129 if (getNelements(sym->type, sym->ival)>1) {
1130 werrorfl (filename, sym->lineDef,
1131 W_EXCESS_INITIALIZERS, "scalar",
1134 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1135 list2expr (sym->ival));
1138 setAstLineno (work, sym->lineDef);
1142 staticAutos = newNode (NULLOP, staticAutos, work);
1149 /* if there is an initial value */
1150 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1152 initList *ilist=sym->ival;
1154 while (ilist->type == INIT_DEEP) {
1155 ilist = ilist->init.deep;
1158 /* update lineno for error msg */
1159 lineno=sym->lineDef;
1160 setAstLineno (ilist->init.node, lineno);
1162 if (IS_AGGREGATE (sym->type)) {
1163 work = initAggregates (sym, sym->ival, NULL);
1165 if (getNelements(sym->type, sym->ival)>1) {
1166 werrorfl (filename, sym->lineDef,
1167 W_EXCESS_INITIALIZERS, "scalar",
1170 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1171 list2expr (sym->ival));
1175 setAstLineno (work, sym->lineDef);
1179 init = newNode (NULLOP, init, work);
1188 /*-----------------------------------------------------------------*/
1189 /* freeStringSymbol - delete a literal string if no more usage */
1190 /*-----------------------------------------------------------------*/
1191 void freeStringSymbol(symbol *sym) {
1192 /* make sure this is a literal string */
1193 assert (sym->isstrlit);
1194 if (--sym->isstrlit == 0) { // lower the usage count
1195 memmap *segment=SPEC_OCLS(sym->etype);
1197 deleteSetItem(&segment->syms, sym);
1202 /*-----------------------------------------------------------------*/
1203 /* stringToSymbol - creates a symbol from a literal string */
1204 /*-----------------------------------------------------------------*/
1206 stringToSymbol (value * val)
1208 char name[SDCC_NAME_MAX + 1];
1209 static int charLbl = 0;
1214 // have we heard this before?
1215 for (sp=statsg->syms; sp; sp=sp->next) {
1217 size = getSize (sym->type);
1218 if (sym->isstrlit && size == getSize (val->type) &&
1219 !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1220 // yes, this is old news. Don't publish it again.
1221 sym->isstrlit++; // but raise the usage count
1222 return symbolVal(sym);
1226 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1227 sym = newSymbol (name, 0); /* make it @ level 0 */
1228 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1230 /* copy the type from the value passed */
1231 sym->type = copyLinkChain (val->type);
1232 sym->etype = getSpec (sym->type);
1233 /* change to storage class & output class */
1234 SPEC_SCLS (sym->etype) = S_CODE;
1235 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1236 SPEC_STAT (sym->etype) = 1;
1237 /* make the level & block = 0 */
1238 sym->block = sym->level = 0;
1240 /* create an ival */
1241 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1246 allocVariables (sym);
1249 return symbolVal (sym);
1253 /*-----------------------------------------------------------------*/
1254 /* processBlockVars - will go thru the ast looking for block if */
1255 /* a block is found then will allocate the syms */
1256 /* will also gather the auto inits present */
1257 /*-----------------------------------------------------------------*/
1259 processBlockVars (ast * tree, int *stack, int action)
1264 /* if this is a block */
1265 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1269 if (action == ALLOCATE)
1271 *stack += allocVariables (tree->values.sym);
1272 autoInit = gatherAutoInit (tree->values.sym);
1274 /* if there are auto inits then do them */
1276 tree->left = newNode (NULLOP, autoInit, tree->left);
1278 else /* action is deallocate */
1279 deallocLocal (tree->values.sym);
1282 processBlockVars (tree->left, stack, action);
1283 processBlockVars (tree->right, stack, action);
1288 /*-------------------------------------------------------------*/
1289 /* constExprTree - returns TRUE if this tree is a constant */
1291 /*-------------------------------------------------------------*/
1292 bool constExprTree (ast *cexpr) {
1298 cexpr = decorateType (resolveSymbols (cexpr), RESULT_CHECK);
1300 switch (cexpr->type)
1303 if (IS_AST_LIT_VALUE(cexpr)) {
1304 // this is a literal
1307 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1308 // a function's address will never change
1311 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1312 // an array's address will never change
1315 if (IS_AST_SYM_VALUE(cexpr) &&
1316 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1317 // a symbol in code space will never change
1318 // This is only for the 'char *s="hallo"' case and will have to leave
1319 //printf(" code space symbol");
1324 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1325 "unexpected link in expression tree\n");
1328 if (cexpr->opval.op==ARRAYINIT) {
1329 // this is a list of literals
1332 if (cexpr->opval.op=='=') {
1333 return constExprTree(cexpr->right);
1335 if (cexpr->opval.op==CAST) {
1336 // cast ignored, maybe we should throw a warning here?
1337 return constExprTree(cexpr->right);
1339 if (cexpr->opval.op=='&') {
1342 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1345 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1350 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1355 /*-----------------------------------------------------------------*/
1356 /* constExprValue - returns the value of a constant expression */
1357 /* or NULL if it is not a constant expression */
1358 /*-----------------------------------------------------------------*/
1360 constExprValue (ast * cexpr, int check)
1362 cexpr = decorateType (resolveSymbols (cexpr), RESULT_CHECK);
1364 /* if this is not a constant then */
1365 if (!IS_LITERAL (cexpr->ftype))
1367 /* then check if this is a literal array
1369 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1370 SPEC_CVAL (cexpr->etype).v_char &&
1371 IS_ARRAY (cexpr->ftype))
1373 value *val = valFromType (cexpr->ftype);
1374 SPEC_SCLS (val->etype) = S_LITERAL;
1375 val->sym = cexpr->opval.val->sym;
1376 val->sym->type = copyLinkChain (cexpr->ftype);
1377 val->sym->etype = getSpec (val->sym->type);
1378 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1382 /* if we are casting a literal value then */
1383 if (IS_AST_OP (cexpr) &&
1384 cexpr->opval.op == CAST &&
1385 IS_LITERAL (cexpr->right->ftype))
1387 return valCastLiteral (cexpr->ftype,
1388 floatFromVal (cexpr->right->opval.val));
1391 if (IS_AST_VALUE (cexpr))
1393 return cexpr->opval.val;
1397 werror (E_CONST_EXPECTED, "found expression");
1402 /* return the value */
1403 return cexpr->opval.val;
1407 /*-----------------------------------------------------------------*/
1408 /* isLabelInAst - will return true if a given label is found */
1409 /*-----------------------------------------------------------------*/
1411 isLabelInAst (symbol * label, ast * tree)
1413 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1416 if (IS_AST_OP (tree) &&
1417 tree->opval.op == LABEL &&
1418 isSymbolEqual (AST_SYMBOL (tree->left), label))
1421 return isLabelInAst (label, tree->right) &&
1422 isLabelInAst (label, tree->left);
1426 /*-----------------------------------------------------------------*/
1427 /* isLoopCountable - return true if the loop count can be determi- */
1428 /* -ned at compile time . */
1429 /*-----------------------------------------------------------------*/
1431 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1432 symbol ** sym, ast ** init, ast ** end)
1435 /* the loop is considered countable if the following
1436 conditions are true :-
1438 a) initExpr :- <sym> = <const>
1439 b) condExpr :- <sym> < <const1>
1440 c) loopExpr :- <sym> ++
1443 /* first check the initExpr */
1444 if (IS_AST_OP (initExpr) &&
1445 initExpr->opval.op == '=' && /* is assignment */
1446 IS_AST_SYM_VALUE (initExpr->left))
1447 { /* left is a symbol */
1449 *sym = AST_SYMBOL (initExpr->left);
1450 *init = initExpr->right;
1455 /* for now the symbol has to be of
1457 if (!IS_INTEGRAL ((*sym)->type))
1460 /* now check condExpr */
1461 if (IS_AST_OP (condExpr))
1464 switch (condExpr->opval.op)
1467 if (IS_AST_SYM_VALUE (condExpr->left) &&
1468 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1469 IS_AST_LIT_VALUE (condExpr->right))
1471 *end = condExpr->right;
1477 if (IS_AST_OP (condExpr->left) &&
1478 condExpr->left->opval.op == '>' &&
1479 IS_AST_LIT_VALUE (condExpr->left->right) &&
1480 IS_AST_SYM_VALUE (condExpr->left->left) &&
1481 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1484 *end = newNode ('+', condExpr->left->right,
1485 newAst_VALUE (constVal ("1")));
1496 /* check loop expression is of the form <sym>++ */
1497 if (!IS_AST_OP (loopExpr))
1500 /* check if <sym> ++ */
1501 if (loopExpr->opval.op == INC_OP)
1507 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1508 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1515 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1516 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1524 if (loopExpr->opval.op == ADD_ASSIGN)
1527 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1528 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1529 IS_AST_LIT_VALUE (loopExpr->right) &&
1530 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1538 /*-----------------------------------------------------------------*/
1539 /* astHasVolatile - returns true if ast contains any volatile */
1540 /*-----------------------------------------------------------------*/
1542 astHasVolatile (ast * tree)
1547 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1550 if (IS_AST_OP (tree))
1551 return astHasVolatile (tree->left) ||
1552 astHasVolatile (tree->right);
1557 /*-----------------------------------------------------------------*/
1558 /* astHasPointer - return true if the ast contains any ptr variable */
1559 /*-----------------------------------------------------------------*/
1561 astHasPointer (ast * tree)
1566 if (IS_AST_LINK (tree))
1569 /* if we hit an array expression then check
1570 only the left side */
1571 if (IS_AST_OP (tree) && tree->opval.op == '[')
1572 return astHasPointer (tree->left);
1574 if (IS_AST_VALUE (tree))
1575 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1577 return astHasPointer (tree->left) ||
1578 astHasPointer (tree->right);
1582 /*-----------------------------------------------------------------*/
1583 /* astHasSymbol - return true if the ast has the given symbol */
1584 /*-----------------------------------------------------------------*/
1586 astHasSymbol (ast * tree, symbol * sym)
1588 if (!tree || IS_AST_LINK (tree))
1591 if (IS_AST_VALUE (tree))
1593 if (IS_AST_SYM_VALUE (tree))
1594 return isSymbolEqual (AST_SYMBOL (tree), sym);
1599 return astHasSymbol (tree->left, sym) ||
1600 astHasSymbol (tree->right, sym);
1603 /*-----------------------------------------------------------------*/
1604 /* astHasDeref - return true if the ast has an indirect access */
1605 /*-----------------------------------------------------------------*/
1607 astHasDeref (ast * tree)
1609 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1612 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1614 return astHasDeref (tree->left) || astHasDeref (tree->right);
1617 /*-----------------------------------------------------------------*/
1618 /* isConformingBody - the loop body has to conform to a set of rules */
1619 /* for the loop to be considered reversible read on for rules */
1620 /*-----------------------------------------------------------------*/
1622 isConformingBody (ast * pbody, symbol * sym, ast * body)
1625 /* we are going to do a pre-order traversal of the
1626 tree && check for the following conditions. (essentially
1627 a set of very shallow tests )
1628 a) the sym passed does not participate in
1629 any arithmetic operation
1630 b) There are no function calls
1631 c) all jumps are within the body
1632 d) address of loop control variable not taken
1633 e) if an assignment has a pointer on the
1634 left hand side make sure right does not have
1635 loop control variable */
1637 /* if we reach the end or a leaf then true */
1638 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1641 /* if anything else is "volatile" */
1642 if (IS_VOLATILE (TETYPE (pbody)))
1645 /* we will walk the body in a pre-order traversal for
1647 switch (pbody->opval.op)
1649 /*------------------------------------------------------------------*/
1651 // if the loopvar is used as an index
1652 if (astHasSymbol(pbody->right, sym)) {
1655 return isConformingBody (pbody->right, sym, body);
1657 /*------------------------------------------------------------------*/
1662 /*------------------------------------------------------------------*/
1666 /* sure we are not sym is not modified */
1668 IS_AST_SYM_VALUE (pbody->left) &&
1669 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1673 IS_AST_SYM_VALUE (pbody->right) &&
1674 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1679 /*------------------------------------------------------------------*/
1681 case '*': /* can be unary : if right is null then unary operation */
1686 /* if right is NULL then unary operation */
1687 /*------------------------------------------------------------------*/
1688 /*----------------------------*/
1690 /*----------------------------*/
1693 if (IS_AST_SYM_VALUE (pbody->left) &&
1694 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1697 return isConformingBody (pbody->left, sym, body);
1701 if (astHasSymbol (pbody->left, sym) ||
1702 astHasSymbol (pbody->right, sym))
1707 /*------------------------------------------------------------------*/
1715 if (IS_AST_SYM_VALUE (pbody->left) &&
1716 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1719 if (IS_AST_SYM_VALUE (pbody->right) &&
1720 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1723 return isConformingBody (pbody->left, sym, body) &&
1724 isConformingBody (pbody->right, sym, body);
1732 if (IS_AST_SYM_VALUE (pbody->left) &&
1733 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1735 return isConformingBody (pbody->left, sym, body);
1737 /*------------------------------------------------------------------*/
1749 case SIZEOF: /* evaluate wihout code generation */
1751 if (IS_AST_SYM_VALUE (pbody->left) &&
1752 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1755 if (IS_AST_SYM_VALUE (pbody->right) &&
1756 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1759 return isConformingBody (pbody->left, sym, body) &&
1760 isConformingBody (pbody->right, sym, body);
1762 /*------------------------------------------------------------------*/
1765 /* if left has a pointer & right has loop
1766 control variable then we cannot */
1767 if (astHasPointer (pbody->left) &&
1768 astHasSymbol (pbody->right, sym))
1770 if (astHasVolatile (pbody->left))
1773 if (IS_AST_SYM_VALUE (pbody->left)) {
1774 // if the loopvar has an assignment
1775 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1777 // if the loopvar is used in another (maybe conditional) block
1778 if (astHasSymbol (pbody->right, sym) &&
1779 (pbody->level >= body->level)) {
1784 if (astHasVolatile (pbody->left))
1787 if (astHasDeref(pbody->right)) return FALSE;
1789 return isConformingBody (pbody->left, sym, body) &&
1790 isConformingBody (pbody->right, sym, body);
1801 assert ("Parser should not have generated this\n");
1803 /*------------------------------------------------------------------*/
1804 /*----------------------------*/
1805 /* comma operator */
1806 /*----------------------------*/
1808 return isConformingBody (pbody->left, sym, body) &&
1809 isConformingBody (pbody->right, sym, body);
1811 /*------------------------------------------------------------------*/
1812 /*----------------------------*/
1814 /*----------------------------*/
1816 /* if local & not passed as paramater then ok */
1817 if (sym->level && !astHasSymbol(pbody->right,sym))
1821 /*------------------------------------------------------------------*/
1822 /*----------------------------*/
1823 /* return statement */
1824 /*----------------------------*/
1829 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1834 if (astHasSymbol (pbody->left, sym))
1841 return isConformingBody (pbody->left, sym, body) &&
1842 isConformingBody (pbody->right, sym, body);
1848 /*-----------------------------------------------------------------*/
1849 /* isLoopReversible - takes a for loop as input && returns true */
1850 /* if the for loop is reversible. If yes will set the value of */
1851 /* the loop control var & init value & termination value */
1852 /*-----------------------------------------------------------------*/
1854 isLoopReversible (ast * loop, symbol ** loopCntrl,
1855 ast ** init, ast ** end)
1857 /* if option says don't do it then don't */
1858 if (optimize.noLoopReverse)
1860 /* there are several tests to determine this */
1862 /* for loop has to be of the form
1863 for ( <sym> = <const1> ;
1864 [<sym> < <const2>] ;
1865 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1867 if (!isLoopCountable (AST_FOR (loop, initExpr),
1868 AST_FOR (loop, condExpr),
1869 AST_FOR (loop, loopExpr),
1870 loopCntrl, init, end))
1873 /* now do some serious checking on the body of the loop
1876 return isConformingBody (loop->left, *loopCntrl, loop->left);
1880 /*-----------------------------------------------------------------*/
1881 /* replLoopSym - replace the loop sym by loop sym -1 */
1882 /*-----------------------------------------------------------------*/
1884 replLoopSym (ast * body, symbol * sym)
1887 if (!body || IS_AST_LINK (body))
1890 if (IS_AST_SYM_VALUE (body))
1893 if (isSymbolEqual (AST_SYMBOL (body), sym))
1897 body->opval.op = '-';
1898 body->left = newAst_VALUE (symbolVal (sym));
1899 body->right = newAst_VALUE (constVal ("1"));
1907 replLoopSym (body->left, sym);
1908 replLoopSym (body->right, sym);
1912 /*-----------------------------------------------------------------*/
1913 /* reverseLoop - do the actual loop reversal */
1914 /*-----------------------------------------------------------------*/
1916 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1920 /* create the following tree
1925 if (sym) goto for_continue ;
1928 /* put it together piece by piece */
1929 rloop = newNode (NULLOP,
1930 createIf (newAst_VALUE (symbolVal (sym)),
1932 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1935 newAst_VALUE (symbolVal (sym)),
1938 replLoopSym (loop->left, sym);
1939 setAstLineno (rloop, init->lineno);
1941 rloop = newNode (NULLOP,
1943 newAst_VALUE (symbolVal (sym)),
1944 newNode ('-', end, init)),
1945 createLabel (AST_FOR (loop, continueLabel),
1949 newNode (SUB_ASSIGN,
1950 newAst_VALUE (symbolVal (sym)),
1951 newAst_VALUE (constVal ("1"))),
1954 rloop->lineno=init->lineno;
1955 return decorateType (rloop, RESULT_CHECK);
1959 /*-----------------------------------------------------------------*/
1960 /* searchLitOp - search tree (*ops only) for an ast with literal */
1961 /*-----------------------------------------------------------------*/
1963 searchLitOp (ast *tree, ast **parent, const char *ops)
1967 if (tree && optimize.global_cse)
1969 /* is there a literal operand? */
1971 IS_AST_OP(tree->right) &&
1972 tree->right->right &&
1973 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
1975 if (IS_LITERAL (RTYPE (tree->right)) ^
1976 IS_LITERAL (LTYPE (tree->right)))
1978 tree->right->decorated = 0;
1979 tree->decorated = 0;
1983 ret = searchLitOp (tree->right, parent, ops);
1988 IS_AST_OP(tree->left) &&
1989 tree->left->right &&
1990 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
1992 if (IS_LITERAL (RTYPE (tree->left)) ^
1993 IS_LITERAL (LTYPE (tree->left)))
1995 tree->left->decorated = 0;
1996 tree->decorated = 0;
2000 ret = searchLitOp (tree->left, parent, ops);
2008 /*-----------------------------------------------------------------*/
2009 /* getResultFromType */
2010 /*-----------------------------------------------------------------*/
2012 getResultTypeFromType (sym_link *type)
2014 /* type = getSpec (type); */
2015 if (IS_BITVAR (type))
2016 return RESULT_TYPE_BIT;
2017 if (IS_BITFIELD (type))
2018 return RESULT_TYPE_CHAR;
2020 return RESULT_TYPE_CHAR;
2023 return RESULT_TYPE_INT;
2024 return RESULT_TYPE_OTHER;
2027 /*-----------------------------------------------------------------*/
2028 /* addCast - adds casts to a type specified by RESULT_TYPE */
2029 /*-----------------------------------------------------------------*/
2031 addCast (ast *tree, RESULT_TYPE resultType, bool upcast)
2034 bool upCasted = FALSE;
2038 case RESULT_TYPE_NONE:
2039 /* char: promote to int */
2041 getSize (tree->etype) >= INTSIZE)
2043 newLink = newIntLink();
2046 case RESULT_TYPE_CHAR:
2047 if (getSize (tree->etype) <= 1)
2049 newLink = newCharLink();
2051 case RESULT_TYPE_INT:
2053 if (getSize (tree->etype) > INTSIZE)
2055 /* warn ("Loosing significant digits"); */
2059 /* char: promote to int */
2061 getSize (tree->etype) >= INTSIZE)
2063 newLink = newIntLink();
2066 case RESULT_TYPE_OTHER:
2069 /* return type is long, float: promote char to int */
2070 if (getSize (tree->etype) >= INTSIZE)
2072 newLink = newIntLink();
2078 tree->decorated = 0;
2079 tree = newNode (CAST, newAst_LINK (newLink), tree);
2080 /* keep unsigned type during cast to smaller type,
2081 but not when promoting from char to int */
2083 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2084 return decorateType (tree, resultType);
2087 /*-----------------------------------------------------------------*/
2088 /* resultTypePropagate - decides if resultType can be propagated */
2089 /*-----------------------------------------------------------------*/
2091 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2093 switch (tree->opval.op)
2104 return RESULT_TYPE_NONE;
2108 return RESULT_TYPE_NONE;
2112 /*-----------------------------------------------------------------*/
2113 /* getLeftResultType - gets type from left branch for propagation */
2114 /*-----------------------------------------------------------------*/
2116 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2118 switch (tree->opval.op)
2122 if (IS_PTR (LTYPE (tree)))
2123 return RESULT_TYPE_NONE;
2125 return getResultTypeFromType (LETYPE (tree));
2127 if (IS_PTR (currFunc->type->next))
2128 return RESULT_TYPE_NONE;
2130 return getResultTypeFromType (currFunc->type->next);
2132 if (!IS_ARRAY (LTYPE (tree)))
2134 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256)
2135 return RESULT_TYPE_CHAR;
2142 /*--------------------------------------------------------------------*/
2143 /* decorateType - compute type for this tree, also does type checking.*/
2144 /* This is done bottom up, since type has to flow upwards. */
2145 /* resultType flows top-down and forces e.g. char-arithmetik, if the */
2146 /* result is a char and the operand(s) are int's. */
2147 /* It also does constant folding, and parameter checking. */
2148 /*--------------------------------------------------------------------*/
2150 decorateType (ast * tree, RESULT_TYPE resultType)
2154 RESULT_TYPE resultTypeProp;
2159 /* if already has type then do nothing */
2160 if (tree->decorated)
2163 tree->decorated = 1;
2166 /* print the line */
2167 /* if not block & function */
2168 if (tree->type == EX_OP &&
2169 (tree->opval.op != FUNCTION &&
2170 tree->opval.op != BLOCK &&
2171 tree->opval.op != NULLOP))
2173 filename = tree->filename;
2174 lineno = tree->lineno;
2178 /* if any child is an error | this one is an error do nothing */
2179 if (tree->isError ||
2180 (tree->left && tree->left->isError) ||
2181 (tree->right && tree->right->isError))
2184 /*------------------------------------------------------------------*/
2185 /*----------------------------*/
2186 /* leaf has been reached */
2187 /*----------------------------*/
2188 lineno=tree->lineno;
2189 /* if this is of type value */
2190 /* just get the type */
2191 if (tree->type == EX_VALUE)
2194 if (IS_LITERAL (tree->opval.val->etype))
2197 /* if this is a character array then declare it */
2198 if (IS_ARRAY (tree->opval.val->type))
2199 tree->opval.val = stringToSymbol (tree->opval.val);
2201 /* otherwise just copy the type information */
2202 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2206 if (tree->opval.val->sym)
2208 /* if the undefined flag is set then give error message */
2209 if (tree->opval.val->sym->undefined)
2211 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2213 TTYPE (tree) = TETYPE (tree) =
2214 tree->opval.val->type = tree->opval.val->sym->type =
2215 tree->opval.val->etype = tree->opval.val->sym->etype =
2216 copyLinkChain (INTTYPE);
2221 /* if impilicit i.e. struct/union member then no type */
2222 if (tree->opval.val->sym->implicit)
2223 TTYPE (tree) = TETYPE (tree) = NULL;
2228 /* else copy the type */
2229 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2231 /* and mark it as referenced */
2232 tree->opval.val->sym->isref = 1;
2240 /* if type link for the case of cast */
2241 if (tree->type == EX_LINK)
2243 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2251 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2253 if (tree->left && tree->left->type == EX_OPERAND
2254 && (tree->left->opval.op == INC_OP
2255 || tree->left->opval.op == DEC_OP)
2256 && tree->left->left)
2258 tree->left->right = tree->left->left;
2259 tree->left->left = NULL;
2261 if (tree->right && tree->right->type == EX_OPERAND
2262 && (tree->right->opval.op == INC_OP
2263 || tree->right->opval.op == DEC_OP)
2264 && tree->right->left)
2266 tree->right->right = tree->right->left;
2267 tree->right->left = NULL;
2272 /* Before decorating the left branch we've to decide in dependence
2273 upon tree->opval.op, if resultType can be propagated */
2274 resultTypeProp = resultTypePropagate (tree, resultType);
2276 dtl = decorateType (tree->left, resultTypeProp);
2278 /* if an array node, we may need to swap branches */
2279 if (tree->opval.op == '[')
2281 /* determine which is the array & which the index */
2282 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2283 IS_INTEGRAL (LTYPE (tree)))
2285 ast *tempTree = tree->left;
2286 tree->left = tree->right;
2287 tree->right = tempTree;
2291 /* After decorating the left branch there's type information available
2292 in tree->left->?type. If the op is e.g. '=' we extract the type
2293 information from there and propagate it to the right branch. */
2294 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2296 switch (tree->opval.op)
2299 /* delay right side for '?' operator since conditional macro
2300 expansions might rely on this */
2304 /* decorate right side for CALL (parameter list) in processParms();
2305 there is resultType available */
2309 dtr = decorateType (tree->right, resultTypeProp);
2313 /* this is to take care of situations
2314 when the tree gets rewritten */
2315 if (dtl != tree->left)
2317 if (dtr != tree->right)
2319 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2323 /* depending on type of operator do */
2325 switch (tree->opval.op)
2327 /*------------------------------------------------------------------*/
2328 /*----------------------------*/
2330 /*----------------------------*/
2333 /* first check if this is a array or a pointer */
2334 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2336 werror (E_NEED_ARRAY_PTR, "[]");
2337 goto errorTreeReturn;
2340 /* check if the type of the idx */
2341 if (!IS_INTEGRAL (RTYPE (tree)))
2343 werror (E_IDX_NOT_INT);
2344 goto errorTreeReturn;
2347 /* if the left is an rvalue then error */
2350 werror (E_LVALUE_REQUIRED, "array access");
2351 goto errorTreeReturn;
2354 if (IS_LITERAL (RTYPE (tree)))
2356 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2357 int arraySize = DCL_ELEM (LTYPE (tree));
2358 if (arraySize && arrayIndex >= arraySize)
2360 werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2365 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2368 /*------------------------------------------------------------------*/
2369 /*----------------------------*/
2371 /*----------------------------*/
2373 /* if this is not a structure */
2374 if (!IS_STRUCT (LTYPE (tree)))
2376 werror (E_STRUCT_UNION, ".");
2377 goto errorTreeReturn;
2379 TTYPE (tree) = structElemType (LTYPE (tree),
2380 (tree->right->type == EX_VALUE ?
2381 tree->right->opval.val : NULL));
2382 TETYPE (tree) = getSpec (TTYPE (tree));
2385 /*------------------------------------------------------------------*/
2386 /*----------------------------*/
2387 /* struct/union pointer */
2388 /*----------------------------*/
2390 /* if not pointer to a structure */
2391 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2393 werror (E_PTR_REQD);
2394 goto errorTreeReturn;
2397 if (!IS_STRUCT (LTYPE (tree)->next))
2399 werror (E_STRUCT_UNION, "->");
2400 goto errorTreeReturn;
2403 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2404 (tree->right->type == EX_VALUE ?
2405 tree->right->opval.val : NULL));
2406 TETYPE (tree) = getSpec (TTYPE (tree));
2408 /* adjust the storage class */
2409 switch (DCL_TYPE(tree->left->ftype)) {
2411 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2414 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2417 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2420 SPEC_SCLS (TETYPE (tree)) = 0;
2423 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2426 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2429 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2432 SPEC_SCLS (TETYPE (tree)) = 0;
2439 /* This breaks with extern declarations, bitfields, and perhaps other */
2440 /* cases (gcse). Let's leave this optimization disabled for now and */
2441 /* ponder if there's a safe way to do this. -- EEP */
2443 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2444 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2446 /* If defined struct type at addr var
2447 then rewrite (&struct var)->member
2449 and define membertype at (addr+offsetof(struct var,member)) temp
2452 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2453 AST_SYMBOL(tree->right));
2455 sym = newSymbol(genSymName (0), 0);
2456 sym->type = TTYPE (tree);
2457 sym->etype = getSpec(sym->type);
2458 sym->lineDef = tree->lineno;
2461 SPEC_STAT (sym->etype) = 1;
2462 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2464 SPEC_ABSA(sym->etype) = 1;
2465 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2468 AST_VALUE (tree) = symbolVal(sym);
2471 tree->type = EX_VALUE;
2479 /*------------------------------------------------------------------*/
2480 /*----------------------------*/
2481 /* ++/-- operation */
2482 /*----------------------------*/
2486 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2487 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2488 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2489 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2498 /*------------------------------------------------------------------*/
2499 /*----------------------------*/
2501 /*----------------------------*/
2502 case '&': /* can be unary */
2503 /* if right is NULL then unary operation */
2504 if (tree->right) /* not an unary operation */
2507 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2509 werror (E_BITWISE_OP);
2510 werror (W_CONTINUE, "left & right types are ");
2511 printTypeChain (LTYPE (tree), stderr);
2512 fprintf (stderr, ",");
2513 printTypeChain (RTYPE (tree), stderr);
2514 fprintf (stderr, "\n");
2515 goto errorTreeReturn;
2518 /* if they are both literal */
2519 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2521 tree->type = EX_VALUE;
2522 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2523 valFromType (RETYPE (tree)), '&');
2525 tree->right = tree->left = NULL;
2526 TETYPE (tree) = tree->opval.val->etype;
2527 TTYPE (tree) = tree->opval.val->type;
2531 /* see if this is a GETHBIT operation if yes
2534 ast *otree = optimizeGetHbit (tree);
2537 return decorateType (otree, RESULT_CHECK);
2540 tree->left = addCast (tree->left, resultType, FALSE);
2541 tree->right = addCast (tree->right, resultType, FALSE);
2542 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
2543 TETYPE (tree) = getSpec (TTYPE (tree));
2545 /* if left is a literal exchange left & right */
2546 if (IS_LITERAL (LTYPE (tree)))
2548 ast *tTree = tree->left;
2549 tree->left = tree->right;
2550 tree->right = tTree;
2553 /* if right is a literal and */
2554 /* we can find a 2nd literal in a and-tree then */
2555 /* rearrange the tree */
2556 if (IS_LITERAL (RTYPE (tree)))
2559 ast *litTree = searchLitOp (tree, &parent, "&");
2562 ast *tTree = litTree->left;
2563 litTree->left = tree->right;
2564 tree->right = tTree;
2565 /* both operands in tTree are literal now */
2566 decorateType (parent, RESULT_CHECK);
2570 LRVAL (tree) = RRVAL (tree) = 1;
2575 /*------------------------------------------------------------------*/
2576 /*----------------------------*/
2578 /*----------------------------*/
2579 p = newLink (DECLARATOR);
2580 /* if bit field then error */
2581 if (IS_BITVAR (tree->left->etype))
2583 werror (E_ILLEGAL_ADDR, "address of bit variable");
2584 goto errorTreeReturn;
2587 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2589 werror (E_ILLEGAL_ADDR, "address of register variable");
2590 goto errorTreeReturn;
2593 if (IS_FUNC (LTYPE (tree)))
2595 // this ought to be ignored
2596 return (tree->left);
2599 if (IS_LITERAL(LTYPE(tree)))
2601 werror (E_ILLEGAL_ADDR, "address of literal");
2602 goto errorTreeReturn;
2607 werror (E_LVALUE_REQUIRED, "address of");
2608 goto errorTreeReturn;
2611 DCL_TYPE (p) = POINTER;
2612 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2613 DCL_TYPE (p) = CPOINTER;
2614 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2615 DCL_TYPE (p) = FPOINTER;
2616 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2617 DCL_TYPE (p) = PPOINTER;
2618 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2619 DCL_TYPE (p) = IPOINTER;
2620 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2621 DCL_TYPE (p) = EEPPOINTER;
2622 else if (SPEC_OCLS(tree->left->etype))
2623 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2625 DCL_TYPE (p) = POINTER;
2627 if (IS_AST_SYM_VALUE (tree->left))
2629 AST_SYMBOL (tree->left)->addrtaken = 1;
2630 AST_SYMBOL (tree->left)->allocreq = 1;
2633 p->next = LTYPE (tree);
2635 TETYPE (tree) = getSpec (TTYPE (tree));
2640 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2641 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2643 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2644 AST_SYMBOL(tree->left->right));
2645 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2646 valueFromLit(element->offset));
2649 tree->type = EX_VALUE;
2650 tree->values.literalFromCast = 1;
2656 /*------------------------------------------------------------------*/
2657 /*----------------------------*/
2659 /*----------------------------*/
2661 /* if the rewrite succeeds then don't go any furthur */
2663 ast *wtree = optimizeRRCRLC (tree);
2665 return decorateType (wtree, RESULT_CHECK);
2667 wtree = optimizeSWAP (tree);
2669 return decorateType (wtree, RESULT_CHECK);
2672 /* if left is a literal exchange left & right */
2673 if (IS_LITERAL (LTYPE (tree)))
2675 ast *tTree = tree->left;
2676 tree->left = tree->right;
2677 tree->right = tTree;
2680 /* if right is a literal and */
2681 /* we can find a 2nd literal in a or-tree then */
2682 /* rearrange the tree */
2683 if (IS_LITERAL (RTYPE (tree)))
2686 ast *litTree = searchLitOp (tree, &parent, "|");
2689 ast *tTree = litTree->left;
2690 litTree->left = tree->right;
2691 tree->right = tTree;
2692 /* both operands in tTree are literal now */
2693 decorateType (parent, RESULT_CHECK);
2698 /*------------------------------------------------------------------*/
2699 /*----------------------------*/
2701 /*----------------------------*/
2703 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2705 werror (E_BITWISE_OP);
2706 werror (W_CONTINUE, "left & right types are ");
2707 printTypeChain (LTYPE (tree), stderr);
2708 fprintf (stderr, ",");
2709 printTypeChain (RTYPE (tree), stderr);
2710 fprintf (stderr, "\n");
2711 goto errorTreeReturn;
2714 /* if they are both literal then */
2715 /* rewrite the tree */
2716 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2718 tree->type = EX_VALUE;
2719 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2720 valFromType (RETYPE (tree)),
2722 tree->right = tree->left = NULL;
2723 TETYPE (tree) = tree->opval.val->etype;
2724 TTYPE (tree) = tree->opval.val->type;
2728 /* if left is a literal exchange left & right */
2729 if (IS_LITERAL (LTYPE (tree)))
2731 ast *tTree = tree->left;
2732 tree->left = tree->right;
2733 tree->right = tTree;
2736 /* if right is a literal and */
2737 /* we can find a 2nd literal in a xor-tree then */
2738 /* rearrange the tree */
2739 if (IS_LITERAL (RTYPE (tree)) &&
2740 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2743 ast *litTree = searchLitOp (tree, &parent, "^");
2746 ast *tTree = litTree->left;
2747 litTree->left = tree->right;
2748 tree->right = tTree;
2749 /* both operands in litTree are literal now */
2750 decorateType (parent, RESULT_CHECK);
2754 LRVAL (tree) = RRVAL (tree) = 1;
2755 tree->left = addCast (tree->left, resultType, FALSE);
2756 tree->right = addCast (tree->right, resultType, FALSE);
2757 TETYPE (tree) = getSpec (TTYPE (tree) =
2758 computeType (LTYPE (tree),
2764 /*------------------------------------------------------------------*/
2765 /*----------------------------*/
2767 /*----------------------------*/
2769 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2771 werror (E_INVALID_OP, "divide");
2772 goto errorTreeReturn;
2774 /* if they are both literal then */
2775 /* rewrite the tree */
2776 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2778 tree->type = EX_VALUE;
2779 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2780 valFromType (RETYPE (tree)));
2781 tree->right = tree->left = NULL;
2782 TETYPE (tree) = getSpec (TTYPE (tree) =
2783 tree->opval.val->type);
2787 LRVAL (tree) = RRVAL (tree) = 1;
2788 TETYPE (tree) = getSpec (TTYPE (tree) =
2789 computeType (LTYPE (tree),
2791 ! (IS_UNSIGNED (LTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)))));
2793 /* if right is a literal and */
2794 /* left is also a division by a literal then */
2795 /* rearrange the tree */
2796 if (IS_LITERAL (RTYPE (tree))
2797 /* avoid infinite loop */
2798 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2801 ast *litTree = searchLitOp (tree, &parent, "/");
2804 if (IS_LITERAL (RTYPE (litTree)))
2807 litTree->right = newNode ('*', litTree->right, tree->right);
2808 litTree->right->lineno = tree->lineno;
2810 tree->right->opval.val = constVal ("1");
2811 decorateType (parent, RESULT_CHECK);
2815 /* litTree->left is literal: no gcse possible.
2816 We can't call decorateType(parent, RESULT_CHECK), because
2817 this would cause an infinit loop. */
2818 parent->decorated = 1;
2819 decorateType (litTree, RESULT_CHECK);
2826 /*------------------------------------------------------------------*/
2827 /*----------------------------*/
2829 /*----------------------------*/
2831 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2833 werror (E_BITWISE_OP);
2834 werror (W_CONTINUE, "left & right types are ");
2835 printTypeChain (LTYPE (tree), stderr);
2836 fprintf (stderr, ",");
2837 printTypeChain (RTYPE (tree), stderr);
2838 fprintf (stderr, "\n");
2839 goto errorTreeReturn;
2841 /* if they are both literal then */
2842 /* rewrite the tree */
2843 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2845 tree->type = EX_VALUE;
2846 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2847 valFromType (RETYPE (tree)));
2848 tree->right = tree->left = NULL;
2849 TETYPE (tree) = getSpec (TTYPE (tree) =
2850 tree->opval.val->type);
2853 LRVAL (tree) = RRVAL (tree) = 1;
2854 TETYPE (tree) = getSpec (TTYPE (tree) =
2855 computeType (LTYPE (tree),
2857 ! (IS_UNSIGNED (LTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)))));
2860 /*------------------------------------------------------------------*/
2861 /*----------------------------*/
2862 /* address dereference */
2863 /*----------------------------*/
2864 case '*': /* can be unary : if right is null then unary operation */
2867 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2869 werror (E_PTR_REQD);
2870 goto errorTreeReturn;
2875 werror (E_LVALUE_REQUIRED, "pointer deref");
2876 goto errorTreeReturn;
2878 if (IS_ADDRESS_OF_OP(tree->left))
2880 /* replace *&obj with obj */
2881 return tree->left->left;
2883 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2884 TETYPE (tree) = getSpec (TTYPE (tree));
2885 /* adjust the storage class */
2886 switch (DCL_TYPE(tree->left->ftype)) {
2888 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2891 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2894 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2897 SPEC_SCLS (TETYPE (tree)) = 0;
2900 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2903 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2906 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2909 SPEC_SCLS (TETYPE (tree)) = 0;
2918 /*------------------------------------------------------------------*/
2919 /*----------------------------*/
2920 /* multiplication */
2921 /*----------------------------*/
2922 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2924 werror (E_INVALID_OP, "multiplication");
2925 goto errorTreeReturn;
2928 /* if they are both literal then */
2929 /* rewrite the tree */
2930 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2932 tree->type = EX_VALUE;
2933 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2934 valFromType (RETYPE (tree)));
2935 tree->right = tree->left = NULL;
2936 TETYPE (tree) = getSpec (TTYPE (tree) =
2937 tree->opval.val->type);
2941 /* if left is a literal exchange left & right */
2942 if (IS_LITERAL (LTYPE (tree)))
2944 ast *tTree = tree->left;
2945 tree->left = tree->right;
2946 tree->right = tTree;
2949 /* if right is a literal and */
2950 /* we can find a 2nd literal in a mul-tree then */
2951 /* rearrange the tree */
2952 if (IS_LITERAL (RTYPE (tree)))
2955 ast *litTree = searchLitOp (tree, &parent, "*");
2958 ast *tTree = litTree->left;
2959 litTree->left = tree->right;
2960 tree->right = tTree;
2961 /* both operands in litTree are literal now */
2962 decorateType (parent, RESULT_CHECK);
2966 LRVAL (tree) = RRVAL (tree) = 1;
2967 tree->left = addCast (tree->left, resultType, FALSE);
2968 tree->right = addCast (tree->right, resultType, FALSE);
2969 TETYPE (tree) = getSpec (TTYPE (tree) =
2970 computeType (LTYPE (tree),
2972 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
2976 /*------------------------------------------------------------------*/
2977 /*----------------------------*/
2978 /* unary '+' operator */
2979 /*----------------------------*/
2984 if (!IS_ARITHMETIC (LTYPE (tree)))
2986 werror (E_UNARY_OP, '+');
2987 goto errorTreeReturn;
2990 /* if left is a literal then do it */
2991 if (IS_LITERAL (LTYPE (tree)))
2993 tree->type = EX_VALUE;
2994 tree->opval.val = valFromType (LETYPE (tree));
2996 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3000 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3004 /*------------------------------------------------------------------*/
3005 /*----------------------------*/
3007 /*----------------------------*/
3009 /* this is not a unary operation */
3010 /* if both pointers then problem */
3011 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3012 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3014 werror (E_PTR_PLUS_PTR);
3015 goto errorTreeReturn;
3018 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3019 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3021 werror (E_PLUS_INVALID, "+");
3022 goto errorTreeReturn;
3025 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3026 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3028 werror (E_PLUS_INVALID, "+");
3029 goto errorTreeReturn;
3031 /* if they are both literal then */
3032 /* rewrite the tree */
3033 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3035 tree->type = EX_VALUE;
3036 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3037 valFromType (RETYPE (tree)));
3038 tree->right = tree->left = NULL;
3039 TETYPE (tree) = getSpec (TTYPE (tree) =
3040 tree->opval.val->type);
3044 /* if the right is a pointer or left is a literal
3045 xchange left & right */
3046 if (IS_ARRAY (RTYPE (tree)) ||
3047 IS_PTR (RTYPE (tree)) ||
3048 IS_LITERAL (LTYPE (tree)))
3050 ast *tTree = tree->left;
3051 tree->left = tree->right;
3052 tree->right = tTree;
3055 /* if right is a literal and */
3056 /* left is also an addition/subtraction with a literal then */
3057 /* rearrange the tree */
3058 if (IS_LITERAL (RTYPE (tree)))
3060 ast *litTree, *parent;
3061 litTree = searchLitOp (tree, &parent, "+-");
3064 if (litTree->opval.op == '+')
3067 ast *tTree = litTree->left;
3068 litTree->left = tree->right;
3069 tree->right = tree->left;
3072 else if (litTree->opval.op == '-')
3074 if (IS_LITERAL (RTYPE (litTree)))
3077 ast *tTree = litTree->left;
3078 litTree->left = tree->right;
3079 tree->right = tTree;
3084 ast *tTree = litTree->right;
3085 litTree->right = tree->right;
3086 tree->right = tTree;
3087 litTree->opval.op = '+';
3088 tree->opval.op = '-';
3091 decorateType (parent, RESULT_CHECK);
3095 LRVAL (tree) = RRVAL (tree) = 1;
3096 /* if the left is a pointer */
3097 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3098 TETYPE (tree) = getSpec (TTYPE (tree) =
3102 tree->left = addCast (tree->left, resultType, TRUE);
3103 tree->right = addCast (tree->right, resultType, TRUE);
3104 TETYPE (tree) = getSpec (TTYPE (tree) =
3105 computeType (LTYPE (tree),
3107 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
3112 /*------------------------------------------------------------------*/
3113 /*----------------------------*/
3115 /*----------------------------*/
3116 case '-': /* can be unary */
3117 /* if right is null then unary */
3121 if (!IS_ARITHMETIC (LTYPE (tree)))
3123 werror (E_UNARY_OP, tree->opval.op);
3124 goto errorTreeReturn;
3127 /* if left is a literal then do it */
3128 if (IS_LITERAL (LTYPE (tree)))
3130 tree->type = EX_VALUE;
3131 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3133 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3134 SPEC_USIGN(TETYPE(tree)) = 0;
3138 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3142 /*------------------------------------------------------------------*/
3143 /*----------------------------*/
3145 /*----------------------------*/
3147 if (!(IS_PTR (LTYPE (tree)) ||
3148 IS_ARRAY (LTYPE (tree)) ||
3149 IS_ARITHMETIC (LTYPE (tree))))
3151 werror (E_PLUS_INVALID, "-");
3152 goto errorTreeReturn;
3155 if (!(IS_PTR (RTYPE (tree)) ||
3156 IS_ARRAY (RTYPE (tree)) ||
3157 IS_ARITHMETIC (RTYPE (tree))))
3159 werror (E_PLUS_INVALID, "-");
3160 goto errorTreeReturn;
3163 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3164 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3165 IS_INTEGRAL (RTYPE (tree))))
3167 werror (E_PLUS_INVALID, "-");
3168 goto errorTreeReturn;
3171 /* if they are both literal then */
3172 /* rewrite the tree */
3173 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3175 tree->type = EX_VALUE;
3176 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3177 valFromType (RETYPE (tree)));
3178 tree->right = tree->left = NULL;
3179 TETYPE (tree) = getSpec (TTYPE (tree) =
3180 tree->opval.val->type);
3184 /* if the left & right are equal then zero */
3185 if (isAstEqual (tree->left, tree->right))
3187 tree->type = EX_VALUE;
3188 tree->left = tree->right = NULL;
3189 tree->opval.val = constVal ("0");
3190 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3194 /* if both of them are pointers or arrays then */
3195 /* the result is going to be an integer */
3196 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3197 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3198 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3200 /* if only the left is a pointer */
3201 /* then result is a pointer */
3202 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3203 TETYPE (tree) = getSpec (TTYPE (tree) =
3207 tree->left = addCast (tree->left, resultType, TRUE);
3208 tree->right = addCast (tree->right, resultType, TRUE);
3209 TETYPE (tree) = getSpec (TTYPE (tree) =
3210 computeType (LTYPE (tree),
3212 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
3215 LRVAL (tree) = RRVAL (tree) = 1;
3217 /* if right is a literal and */
3218 /* left is also an addition/subtraction with a literal then */
3219 /* rearrange the tree */
3220 if (IS_LITERAL (RTYPE (tree))
3221 /* avoid infinite loop */
3222 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3224 ast *litTree, *litParent;
3225 litTree = searchLitOp (tree, &litParent, "+-");
3228 if (litTree->opval.op == '+')
3231 litTree->right = newNode ('-', litTree->right, tree->right);
3232 litTree->right->lineno = tree->lineno;
3234 tree->right->opval.val = constVal ("0");
3236 else if (litTree->opval.op == '-')
3238 if (IS_LITERAL (RTYPE (litTree)))
3241 litTree->right = newNode ('+', tree->right, litTree->right);
3242 litTree->right->lineno = tree->lineno;
3244 tree->right->opval.val = constVal ("0");
3249 ast *tTree = litTree->right;
3250 litTree->right = tree->right;
3251 tree->right = tTree;
3254 decorateType (litParent, RESULT_CHECK);
3259 /*------------------------------------------------------------------*/
3260 /*----------------------------*/
3262 /*----------------------------*/
3264 /* can be only integral type */
3265 if (!IS_INTEGRAL (LTYPE (tree)))
3267 werror (E_UNARY_OP, tree->opval.op);
3268 goto errorTreeReturn;
3271 /* if left is a literal then do it */
3272 if (IS_LITERAL (LTYPE (tree)))
3274 tree->type = EX_VALUE;
3275 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3277 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3281 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3284 /*------------------------------------------------------------------*/
3285 /*----------------------------*/
3287 /*----------------------------*/
3289 /* can be pointer */
3290 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3291 !IS_PTR (LTYPE (tree)) &&
3292 !IS_ARRAY (LTYPE (tree)))
3294 werror (E_UNARY_OP, tree->opval.op);
3295 goto errorTreeReturn;
3298 /* if left is a literal then do it */
3299 if (IS_LITERAL (LTYPE (tree)))
3301 tree->type = EX_VALUE;
3302 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3304 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3308 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3311 /*------------------------------------------------------------------*/
3312 /*----------------------------*/
3314 /*----------------------------*/
3318 TTYPE (tree) = LTYPE (tree);
3319 TETYPE (tree) = LETYPE (tree);
3323 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3328 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3330 werror (E_SHIFT_OP_INVALID);
3331 werror (W_CONTINUE, "left & right types are ");
3332 printTypeChain (LTYPE (tree), stderr);
3333 fprintf (stderr, ",");
3334 printTypeChain (RTYPE (tree), stderr);
3335 fprintf (stderr, "\n");
3336 goto errorTreeReturn;
3339 /* if they are both literal then */
3340 /* rewrite the tree */
3341 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3343 tree->type = EX_VALUE;
3344 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3345 valFromType (RETYPE (tree)),
3346 (tree->opval.op == LEFT_OP ? 1 : 0));
3347 tree->right = tree->left = NULL;
3348 TETYPE (tree) = getSpec (TTYPE (tree) =
3349 tree->opval.val->type);
3353 LRVAL (tree) = RRVAL (tree) = 1;
3354 if (tree->opval.op == LEFT_OP)
3356 tree->left = addCast (tree->left, resultType, TRUE);
3357 TETYPE (tree) = getSpec (TTYPE (tree) =
3358 computeType (LTYPE (tree),
3360 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
3364 /* no promotion necessary */
3365 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3366 if (IS_LITERAL (TTYPE (tree)))
3367 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3370 /* if only the right side is a literal & we are
3371 shifting more than size of the left operand then zero */
3372 if (IS_LITERAL (RTYPE (tree)) &&
3373 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3374 (getSize (TETYPE (tree)) * 8))
3376 if (tree->opval.op==LEFT_OP ||
3377 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3379 lineno=tree->lineno;
3380 werror (W_SHIFT_CHANGED,
3381 (tree->opval.op == LEFT_OP ? "left" : "right"));
3382 tree->type = EX_VALUE;
3383 tree->left = tree->right = NULL;
3384 tree->opval.val = constVal ("0");
3385 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3392 /*------------------------------------------------------------------*/
3393 /*----------------------------*/
3395 /*----------------------------*/
3396 case CAST: /* change the type */
3397 /* cannot cast to an aggregate type */
3398 if (IS_AGGREGATE (LTYPE (tree)))
3400 werror (E_CAST_ILLEGAL);
3401 goto errorTreeReturn;
3404 /* make sure the type is complete and sane */
3405 checkTypeSanity(LETYPE(tree), "(cast)");
3407 /* If code memory is read only, then pointers to code memory */
3408 /* implicitly point to constants -- make this explicit */
3410 sym_link *t = LTYPE(tree);
3411 while (t && t->next)
3413 if (IS_CODEPTR(t) && port->mem.code_ro)
3415 if (IS_SPEC(t->next))
3416 SPEC_CONST (t->next) = 1;
3418 DCL_PTR_CONST (t->next) = 1;
3425 /* if the right is a literal replace the tree */
3426 if (IS_LITERAL (RETYPE (tree))) {
3427 if (!IS_PTR (LTYPE (tree))) {
3428 tree->type = EX_VALUE;
3430 valCastLiteral (LTYPE (tree),
3431 floatFromVal (valFromType (RETYPE (tree))));
3434 TTYPE (tree) = tree->opval.val->type;
3435 tree->values.literalFromCast = 1;
3436 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3437 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3438 sym_link *rest = LTYPE(tree)->next;
3439 werror(W_LITERAL_GENERIC);
3440 TTYPE(tree) = newLink(DECLARATOR);
3441 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3442 TTYPE(tree)->next = rest;
3443 tree->left->opval.lnk = TTYPE(tree);
3446 TTYPE (tree) = LTYPE (tree);
3450 TTYPE (tree) = LTYPE (tree);
3454 #if 0 // this is already checked, now this could be explicit
3455 /* if pointer to struct then check names */
3456 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3457 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3458 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3460 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3461 SPEC_STRUCT(LETYPE(tree))->tag);
3464 if (IS_ADDRESS_OF_OP(tree->right)
3465 && IS_AST_SYM_VALUE (tree->right->left)
3466 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3468 tree->type = EX_VALUE;
3470 valCastLiteral (LTYPE (tree),
3471 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3472 TTYPE (tree) = tree->opval.val->type;
3473 TETYPE (tree) = getSpec (TTYPE (tree));
3476 tree->values.literalFromCast = 1;
3480 /* handle offsetof macro: */
3481 /* #define offsetof(TYPE, MEMBER) \ */
3482 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3483 if (IS_ADDRESS_OF_OP(tree->right)
3484 && IS_AST_OP (tree->right->left)
3485 && tree->right->left->opval.op == PTR_OP
3486 && IS_AST_OP (tree->right->left->left)
3487 && tree->right->left->left->opval.op == CAST
3488 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3490 symbol *element = getStructElement (
3491 SPEC_STRUCT (LETYPE(tree->right->left)),
3492 AST_SYMBOL(tree->right->left->right)
3496 tree->type = EX_VALUE;
3497 tree->opval.val = valCastLiteral (
3500 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3503 TTYPE (tree) = tree->opval.val->type;
3504 TETYPE (tree) = getSpec (TTYPE (tree));
3511 /* if the right is a literal replace the tree */
3512 if (IS_LITERAL (RETYPE (tree))) {
3514 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3515 /* rewrite (type *)litaddr
3517 and define type at litaddr temp
3518 (but only if type's storage class is not generic)
3520 ast *newTree = newNode ('&', NULL, NULL);
3523 TTYPE (newTree) = LTYPE (tree);
3524 TETYPE (newTree) = getSpec(LTYPE (tree));
3526 /* define a global symbol at the casted address*/
3527 sym = newSymbol(genSymName (0), 0);
3528 sym->type = LTYPE (tree)->next;
3530 sym->type = newLink (V_VOID);
3531 sym->etype = getSpec(sym->type);
3532 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3533 sym->lineDef = tree->lineno;
3536 SPEC_STAT (sym->etype) = 1;
3537 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3538 SPEC_ABSA(sym->etype) = 1;
3539 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3542 newTree->left = newAst_VALUE(symbolVal(sym));
3543 newTree->left->lineno = tree->lineno;
3544 LTYPE (newTree) = sym->type;
3545 LETYPE (newTree) = sym->etype;
3546 LLVAL (newTree) = 1;
3547 LRVAL (newTree) = 0;
3548 TLVAL (newTree) = 1;
3552 if (!IS_PTR (LTYPE (tree))) {
3553 tree->type = EX_VALUE;
3555 valCastLiteral (LTYPE (tree),
3556 floatFromVal (valFromType (RTYPE (tree))));
3557 TTYPE (tree) = tree->opval.val->type;
3560 tree->values.literalFromCast = 1;
3561 TETYPE (tree) = getSpec (TTYPE (tree));
3565 TTYPE (tree) = LTYPE (tree);
3569 TETYPE (tree) = getSpec (TTYPE (tree));
3573 /*------------------------------------------------------------------*/
3574 /*----------------------------*/
3575 /* logical &&, || */
3576 /*----------------------------*/
3579 /* each must me arithmetic type or be a pointer */
3580 if (!IS_PTR (LTYPE (tree)) &&
3581 !IS_ARRAY (LTYPE (tree)) &&
3582 !IS_INTEGRAL (LTYPE (tree)))
3584 werror (E_COMPARE_OP);
3585 goto errorTreeReturn;
3588 if (!IS_PTR (RTYPE (tree)) &&
3589 !IS_ARRAY (RTYPE (tree)) &&
3590 !IS_INTEGRAL (RTYPE (tree)))
3592 werror (E_COMPARE_OP);
3593 goto errorTreeReturn;
3595 /* if they are both literal then */
3596 /* rewrite the tree */
3597 if (IS_LITERAL (RTYPE (tree)) &&
3598 IS_LITERAL (LTYPE (tree)))
3600 tree->type = EX_VALUE;
3601 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3602 valFromType (RTYPE (tree)),
3604 tree->right = tree->left = NULL;
3605 TETYPE (tree) = getSpec (TTYPE (tree) =
3606 tree->opval.val->type);
3609 LRVAL (tree) = RRVAL (tree) = 1;
3610 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3613 /*------------------------------------------------------------------*/
3614 /*----------------------------*/
3615 /* comparison operators */
3616 /*----------------------------*/
3624 ast *lt = optimizeCompare (tree);
3630 /* if they are pointers they must be castable */
3631 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3633 if (tree->opval.op==EQ_OP &&
3634 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3635 // we cannot cast a gptr to a !gptr: switch the leaves
3636 struct ast *s=tree->left;
3637 tree->left=tree->right;
3640 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3642 werror (E_COMPARE_OP);
3643 fprintf (stderr, "comparing type ");
3644 printTypeChain (LTYPE (tree), stderr);
3645 fprintf (stderr, "to type ");
3646 printTypeChain (RTYPE (tree), stderr);
3647 fprintf (stderr, "\n");
3648 goto errorTreeReturn;
3651 /* else they should be promotable to one another */
3654 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3655 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3657 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3659 werror (E_COMPARE_OP);
3660 fprintf (stderr, "comparing type ");
3661 printTypeChain (LTYPE (tree), stderr);
3662 fprintf (stderr, "to type ");
3663 printTypeChain (RTYPE (tree), stderr);
3664 fprintf (stderr, "\n");
3665 goto errorTreeReturn;
3668 /* if unsigned value < 0 then always false */
3669 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3670 if (SPEC_USIGN(LETYPE(tree)) &&
3671 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3672 IS_LITERAL(RTYPE(tree)) &&
3673 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3675 if (tree->opval.op == '<')
3679 if (tree->opval.op == '>')
3681 /* if the parent is an ifx, then we could do */
3682 /* return tree->left; */
3683 tree->opval.op = '?';
3684 tree->right = newNode (':',
3685 newAst_VALUE (constVal ("1")),
3686 tree->right); /* val 0 */
3687 tree->right->lineno = tree->lineno;
3688 tree->right->left->lineno = tree->lineno;
3689 decorateType (tree->right, RESULT_CHECK);
3692 /* if they are both literal then */
3693 /* rewrite the tree */
3694 if (IS_LITERAL (RTYPE (tree)) &&
3695 IS_LITERAL (LTYPE (tree)))
3697 tree->type = EX_VALUE;
3698 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3699 valFromType (RETYPE (tree)),
3701 tree->right = tree->left = NULL;
3702 TETYPE (tree) = getSpec (TTYPE (tree) =
3703 tree->opval.val->type);
3706 LRVAL (tree) = RRVAL (tree) = 1;
3707 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3710 /*------------------------------------------------------------------*/
3711 /*----------------------------*/
3713 /*----------------------------*/
3714 case SIZEOF: /* evaluate wihout code generation */
3715 /* change the type to a integer */
3716 tree->type = EX_VALUE;
3717 SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
3718 tree->opval.val = constVal (buffer);
3719 tree->right = tree->left = NULL;
3720 TETYPE (tree) = getSpec (TTYPE (tree) =
3721 tree->opval.val->type);
3724 /*------------------------------------------------------------------*/
3725 /*----------------------------*/
3727 /*----------------------------*/
3729 /* return typeof enum value */
3730 tree->type = EX_VALUE;
3733 if (IS_SPEC(tree->right->ftype)) {
3734 switch (SPEC_NOUN(tree->right->ftype)) {
3736 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3737 else typeofv = TYPEOF_INT;
3740 typeofv = TYPEOF_FLOAT;
3743 typeofv = TYPEOF_CHAR;
3746 typeofv = TYPEOF_VOID;
3749 typeofv = TYPEOF_STRUCT;
3752 typeofv = TYPEOF_BITFIELD;
3755 typeofv = TYPEOF_BIT;
3758 typeofv = TYPEOF_SBIT;
3764 switch (DCL_TYPE(tree->right->ftype)) {
3766 typeofv = TYPEOF_POINTER;
3769 typeofv = TYPEOF_FPOINTER;
3772 typeofv = TYPEOF_CPOINTER;
3775 typeofv = TYPEOF_GPOINTER;
3778 typeofv = TYPEOF_PPOINTER;
3781 typeofv = TYPEOF_IPOINTER;
3784 typeofv = TYPEOF_ARRAY;
3787 typeofv = TYPEOF_FUNCTION;
3793 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3794 tree->opval.val = constVal (buffer);
3795 tree->right = tree->left = NULL;
3796 TETYPE (tree) = getSpec (TTYPE (tree) =
3797 tree->opval.val->type);
3800 /*------------------------------------------------------------------*/
3801 /*----------------------------*/
3802 /* conditional operator '?' */
3803 /*----------------------------*/
3805 /* the type is value of the colon operator (on the right) */
3806 assert (IS_COLON_OP (tree->right));
3807 /* if already known then replace the tree : optimizer will do it
3808 but faster to do it here */
3809 if (IS_LITERAL (LTYPE (tree)))
3811 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
3812 return decorateType (tree->right->left, resultTypeProp);
3814 return decorateType (tree->right->right, resultTypeProp);
3818 tree->right = decorateType (tree->right, resultTypeProp);
3819 TTYPE (tree) = RTYPE (tree);
3820 TETYPE (tree) = getSpec (TTYPE (tree));
3825 /* if they don't match we have a problem */
3826 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3828 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3829 goto errorTreeReturn;
3832 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
3833 TETYPE (tree) = getSpec (TTYPE (tree));
3837 #if 0 // assignment operators are converted by the parser
3838 /*------------------------------------------------------------------*/
3839 /*----------------------------*/
3840 /* assignment operators */
3841 /*----------------------------*/
3844 /* for these it must be both must be integral */
3845 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3846 !IS_ARITHMETIC (RTYPE (tree)))
3848 werror (E_OPS_INTEGRAL);
3849 goto errorTreeReturn;
3852 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3854 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3855 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3859 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3860 goto errorTreeReturn;
3871 /* for these it must be both must be integral */
3872 if (!IS_INTEGRAL (LTYPE (tree)) ||
3873 !IS_INTEGRAL (RTYPE (tree)))
3875 werror (E_OPS_INTEGRAL);
3876 goto errorTreeReturn;
3879 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3881 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3882 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3886 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3887 goto errorTreeReturn;
3893 /*------------------------------------------------------------------*/
3894 /*----------------------------*/
3896 /*----------------------------*/
3898 if (!(IS_PTR (LTYPE (tree)) ||
3899 IS_ARITHMETIC (LTYPE (tree))))
3901 werror (E_PLUS_INVALID, "-=");
3902 goto errorTreeReturn;
3905 if (!(IS_PTR (RTYPE (tree)) ||
3906 IS_ARITHMETIC (RTYPE (tree))))
3908 werror (E_PLUS_INVALID, "-=");
3909 goto errorTreeReturn;
3912 TETYPE (tree) = getSpec (TTYPE (tree) =
3913 computeType (LTYPE (tree),
3917 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3918 werror (E_CODE_WRITE, "-=");
3922 werror (E_LVALUE_REQUIRED, "-=");
3923 goto errorTreeReturn;
3929 /*------------------------------------------------------------------*/
3930 /*----------------------------*/
3932 /*----------------------------*/
3934 /* this is not a unary operation */
3935 /* if both pointers then problem */
3936 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3938 werror (E_PTR_PLUS_PTR);
3939 goto errorTreeReturn;
3942 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3944 werror (E_PLUS_INVALID, "+=");
3945 goto errorTreeReturn;
3948 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3950 werror (E_PLUS_INVALID, "+=");
3951 goto errorTreeReturn;
3954 TETYPE (tree) = getSpec (TTYPE (tree) =
3955 computeType (LTYPE (tree),
3959 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3960 werror (E_CODE_WRITE, "+=");
3964 werror (E_LVALUE_REQUIRED, "+=");
3965 goto errorTreeReturn;
3968 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_CHECK);
3969 tree->opval.op = '=';
3974 /*------------------------------------------------------------------*/
3975 /*----------------------------*/
3976 /* straight assignemnt */
3977 /*----------------------------*/
3979 /* cannot be an aggregate */
3980 if (IS_AGGREGATE (LTYPE (tree)))
3982 werror (E_AGGR_ASSIGN);
3983 goto errorTreeReturn;
3986 /* they should either match or be castable */
3987 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3989 werror (E_TYPE_MISMATCH, "assignment", " ");
3990 printFromToType(RTYPE(tree),LTYPE(tree));
3993 /* if the left side of the tree is of type void
3994 then report error */
3995 if (IS_VOID (LTYPE (tree)))
3997 werror (E_CAST_ZERO);
3998 printFromToType(RTYPE(tree), LTYPE(tree));
4001 TETYPE (tree) = getSpec (TTYPE (tree) =
4005 if (!tree->initMode ) {
4006 if (IS_CONSTANT(LTYPE(tree)))
4007 werror (E_CODE_WRITE, "=");
4011 werror (E_LVALUE_REQUIRED, "=");
4012 goto errorTreeReturn;
4017 /*------------------------------------------------------------------*/
4018 /*----------------------------*/
4019 /* comma operator */
4020 /*----------------------------*/
4022 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4025 /*------------------------------------------------------------------*/
4026 /*----------------------------*/
4028 /*----------------------------*/
4032 if (processParms (tree->left,
4033 FUNC_ARGS(tree->left->ftype),
4034 tree->right, &parmNumber, TRUE)) {
4035 goto errorTreeReturn;
4038 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
4039 !IFFUNC_ISBUILTIN(LTYPE(tree)))
4041 reverseParms (tree->right);
4044 if (IS_CODEPTR(LTYPE(tree))) {
4045 TTYPE(tree) = LTYPE(tree)->next->next;
4047 TTYPE(tree) = LTYPE(tree)->next;
4049 TETYPE (tree) = getSpec (TTYPE (tree));
4052 /*------------------------------------------------------------------*/
4053 /*----------------------------*/
4054 /* return statement */
4055 /*----------------------------*/
4060 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4062 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4063 printFromToType (RTYPE(tree), currFunc->type->next);
4064 goto errorTreeReturn;
4067 if (IS_VOID (currFunc->type->next)
4069 !IS_VOID (RTYPE (tree)))
4071 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4072 goto errorTreeReturn;
4075 /* if there is going to be a casting required then add it */
4076 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4079 decorateType (newNode (CAST,
4080 newAst_LINK (copyLinkChain (currFunc->type->next)),
4090 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4092 werror (W_VOID_FUNC, currFunc->name);
4093 goto errorTreeReturn;
4096 TTYPE (tree) = TETYPE (tree) = NULL;
4099 /*------------------------------------------------------------------*/
4100 /*----------------------------*/
4101 /* switch statement */
4102 /*----------------------------*/
4104 /* the switch value must be an integer */
4105 if (!IS_INTEGRAL (LTYPE (tree)))
4107 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4108 goto errorTreeReturn;
4111 TTYPE (tree) = TETYPE (tree) = NULL;
4114 /*------------------------------------------------------------------*/
4115 /*----------------------------*/
4117 /*----------------------------*/
4119 tree->left = backPatchLabels (tree->left,
4122 TTYPE (tree) = TETYPE (tree) = NULL;
4125 /*------------------------------------------------------------------*/
4126 /*----------------------------*/
4128 /*----------------------------*/
4131 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_CHECK);
4132 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_CHECK);
4133 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_CHECK);
4135 /* if the for loop is reversible then
4136 reverse it otherwise do what we normally
4142 if (isLoopReversible (tree, &sym, &init, &end))
4143 return reverseLoop (tree, sym, init, end);
4145 return decorateType (createFor (AST_FOR (tree, trueLabel),
4146 AST_FOR (tree, continueLabel),
4147 AST_FOR (tree, falseLabel),
4148 AST_FOR (tree, condLabel),
4149 AST_FOR (tree, initExpr),
4150 AST_FOR (tree, condExpr),
4151 AST_FOR (tree, loopExpr),
4152 tree->left), RESULT_CHECK);
4155 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4156 "node PARAM shouldn't be processed here");
4157 /* but in processParams() */
4160 TTYPE (tree) = TETYPE (tree) = NULL;
4164 /* some error found this tree will be killed */
4166 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4167 tree->opval.op = NULLOP;
4173 /*-----------------------------------------------------------------*/
4174 /* sizeofOp - processes size of operation */
4175 /*-----------------------------------------------------------------*/
4177 sizeofOp (sym_link * type)
4181 /* make sure the type is complete and sane */
4182 checkTypeSanity(type, "(sizeof)");
4184 /* get the size and convert it to character */
4185 SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
4187 /* now convert into value */
4188 return constVal (buff);
4192 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4193 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4194 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4195 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4196 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4197 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4198 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4200 /*-----------------------------------------------------------------*/
4201 /* backPatchLabels - change and or not operators to flow control */
4202 /*-----------------------------------------------------------------*/
4204 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4210 if (!(IS_ANDORNOT (tree)))
4213 /* if this an and */
4216 static int localLbl = 0;
4219 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4220 localLabel = newSymbol (buffer, NestLevel);
4222 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4224 /* if left is already a IFX then just change the if true label in that */
4225 if (!IS_IFX (tree->left))
4226 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4228 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4229 /* right is a IFX then just join */
4230 if (IS_IFX (tree->right))
4231 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4233 tree->right = createLabel (localLabel, tree->right);
4234 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4236 return newNode (NULLOP, tree->left, tree->right);
4239 /* if this is an or operation */
4242 static int localLbl = 0;
4245 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4246 localLabel = newSymbol (buffer, NestLevel);
4248 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4250 /* if left is already a IFX then just change the if true label in that */
4251 if (!IS_IFX (tree->left))
4252 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4254 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4255 /* right is a IFX then just join */
4256 if (IS_IFX (tree->right))
4257 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4259 tree->right = createLabel (localLabel, tree->right);
4260 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4262 return newNode (NULLOP, tree->left, tree->right);
4268 int wasnot = IS_NOT (tree->left);
4269 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4271 /* if the left is already a IFX */
4272 if (!IS_IFX (tree->left))
4273 tree->left = newNode (IFX, tree->left, NULL);
4277 tree->left->trueLabel = trueLabel;
4278 tree->left->falseLabel = falseLabel;
4282 tree->left->trueLabel = falseLabel;
4283 tree->left->falseLabel = trueLabel;
4290 tree->trueLabel = trueLabel;
4291 tree->falseLabel = falseLabel;
4298 /*-----------------------------------------------------------------*/
4299 /* createBlock - create expression tree for block */
4300 /*-----------------------------------------------------------------*/
4302 createBlock (symbol * decl, ast * body)
4306 /* if the block has nothing */
4310 ex = newNode (BLOCK, NULL, body);
4311 ex->values.sym = decl;
4313 ex->right = ex->right;
4319 /*-----------------------------------------------------------------*/
4320 /* createLabel - creates the expression tree for labels */
4321 /*-----------------------------------------------------------------*/
4323 createLabel (symbol * label, ast * stmnt)
4326 char name[SDCC_NAME_MAX + 1];
4329 /* must create fresh symbol if the symbol name */
4330 /* exists in the symbol table, since there can */
4331 /* be a variable with the same name as the labl */
4332 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4333 (csym->level == label->level))
4334 label = newSymbol (label->name, label->level);
4336 /* change the name before putting it in add _ */
4337 SNPRINTF(name, sizeof(name), "%s", label->name);
4339 /* put the label in the LabelSymbol table */
4340 /* but first check if a label of the same */
4342 if ((csym = findSym (LabelTab, NULL, name)))
4343 werror (E_DUPLICATE_LABEL, label->name);
4345 addSym (LabelTab, label, name, label->level, 0, 0);
4348 label->key = labelKey++;
4349 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4355 /*-----------------------------------------------------------------*/
4356 /* createCase - generates the parsetree for a case statement */
4357 /*-----------------------------------------------------------------*/
4359 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4361 char caseLbl[SDCC_NAME_MAX + 1];
4365 /* if the switch statement does not exist */
4366 /* then case is out of context */
4369 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4373 caseVal = decorateType (resolveSymbols (caseVal), RESULT_CHECK);
4374 /* if not a constant then error */
4375 if (!IS_LITERAL (caseVal->ftype))
4377 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4381 /* if not a integer than error */
4382 if (!IS_INTEGRAL (caseVal->ftype))
4384 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4388 /* find the end of the switch values chain */
4389 if (!(val = swStat->values.switchVals.swVals))
4390 swStat->values.switchVals.swVals = caseVal->opval.val;
4393 /* also order the cases according to value */
4395 int cVal = (int) floatFromVal (caseVal->opval.val);
4396 while (val && (int) floatFromVal (val) < cVal)
4402 /* if we reached the end then */
4405 pval->next = caseVal->opval.val;
4407 else if ((int) floatFromVal (val) == cVal)
4409 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4415 /* we found a value greater than */
4416 /* the current value we must add this */
4417 /* before the value */
4418 caseVal->opval.val->next = val;
4420 /* if this was the first in chain */
4421 if (swStat->values.switchVals.swVals == val)
4422 swStat->values.switchVals.swVals =
4425 pval->next = caseVal->opval.val;
4430 /* create the case label */
4431 SNPRINTF(caseLbl, sizeof(caseLbl),
4433 swStat->values.switchVals.swNum,
4434 (int) floatFromVal (caseVal->opval.val));
4436 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4441 /*-----------------------------------------------------------------*/
4442 /* createDefault - creates the parse tree for the default statement */
4443 /*-----------------------------------------------------------------*/
4445 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4447 char defLbl[SDCC_NAME_MAX + 1];
4449 /* if the switch statement does not exist */
4450 /* then case is out of context */
4453 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4457 if (swStat->values.switchVals.swDefault)
4459 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4464 /* turn on the default flag */
4465 swStat->values.switchVals.swDefault = 1;
4467 /* create the label */
4468 SNPRINTF (defLbl, sizeof(defLbl),
4469 "_default_%d", swStat->values.switchVals.swNum);
4470 return createLabel (newSymbol (defLbl, 0), stmnt);
4473 /*-----------------------------------------------------------------*/
4474 /* createIf - creates the parsetree for the if statement */
4475 /*-----------------------------------------------------------------*/
4477 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4479 static int Lblnum = 0;
4481 symbol *ifTrue, *ifFalse, *ifEnd;
4483 /* if neither exists */
4484 if (!elseBody && !ifBody) {
4485 // if there are no side effects (i++, j() etc)
4486 if (!hasSEFcalls(condAst)) {
4491 /* create the labels */
4492 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4493 ifFalse = newSymbol (buffer, NestLevel);
4494 /* if no else body then end == false */
4499 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4500 ifEnd = newSymbol (buffer, NestLevel);
4503 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4504 ifTrue = newSymbol (buffer, NestLevel);
4508 /* attach the ifTrue label to the top of it body */
4509 ifBody = createLabel (ifTrue, ifBody);
4510 /* attach a goto end to the ifBody if else is present */
4513 ifBody = newNode (NULLOP, ifBody,
4515 newAst_VALUE (symbolVal (ifEnd)),
4517 /* put the elseLabel on the else body */
4518 elseBody = createLabel (ifFalse, elseBody);
4519 /* out the end at the end of the body */
4520 elseBody = newNode (NULLOP,
4522 createLabel (ifEnd, NULL));
4526 ifBody = newNode (NULLOP, ifBody,
4527 createLabel (ifFalse, NULL));
4529 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4530 if (IS_IFX (condAst))
4533 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4535 return newNode (NULLOP, ifTree,
4536 newNode (NULLOP, ifBody, elseBody));
4540 /*-----------------------------------------------------------------*/
4541 /* createDo - creates parse tree for do */
4544 /* _docontinue_n: */
4545 /* condition_expression +-> trueLabel -> _dobody_n */
4547 /* +-> falseLabel-> _dobreak_n */
4549 /*-----------------------------------------------------------------*/
4551 createDo (symbol * trueLabel, symbol * continueLabel,
4552 symbol * falseLabel, ast * condAst, ast * doBody)
4557 /* if the body does not exist then it is simple */
4560 condAst = backPatchLabels (condAst, continueLabel, NULL);
4561 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4562 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4563 doTree->trueLabel = continueLabel;
4564 doTree->falseLabel = NULL;
4568 /* otherwise we have a body */
4569 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4571 /* attach the body label to the top */
4572 doBody = createLabel (trueLabel, doBody);
4573 /* attach the continue label to end of body */
4574 doBody = newNode (NULLOP, doBody,
4575 createLabel (continueLabel, NULL));
4577 /* now put the break label at the end */
4578 if (IS_IFX (condAst))
4581 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4583 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4585 /* putting it together */
4586 return newNode (NULLOP, doBody, doTree);
4589 /*-----------------------------------------------------------------*/
4590 /* createFor - creates parse tree for 'for' statement */
4593 /* condExpr +-> trueLabel -> _forbody_n */
4595 /* +-> falseLabel-> _forbreak_n */
4598 /* _forcontinue_n: */
4600 /* goto _forcond_n ; */
4602 /*-----------------------------------------------------------------*/
4604 createFor (symbol * trueLabel, symbol * continueLabel,
4605 symbol * falseLabel, symbol * condLabel,
4606 ast * initExpr, ast * condExpr, ast * loopExpr,
4611 /* if loopexpression not present then we can generate it */
4612 /* the same way as a while */
4614 return newNode (NULLOP, initExpr,
4615 createWhile (trueLabel, continueLabel,
4616 falseLabel, condExpr, forBody));
4617 /* vanilla for statement */
4618 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4620 if (condExpr && !IS_IFX (condExpr))
4621 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4624 /* attach condition label to condition */
4625 condExpr = createLabel (condLabel, condExpr);
4627 /* attach body label to body */
4628 forBody = createLabel (trueLabel, forBody);
4630 /* attach continue to forLoop expression & attach */
4631 /* goto the forcond @ and of loopExpression */
4632 loopExpr = createLabel (continueLabel,
4636 newAst_VALUE (symbolVal (condLabel)),
4638 /* now start putting them together */
4639 forTree = newNode (NULLOP, initExpr, condExpr);
4640 forTree = newNode (NULLOP, forTree, forBody);
4641 forTree = newNode (NULLOP, forTree, loopExpr);
4642 /* finally add the break label */
4643 forTree = newNode (NULLOP, forTree,
4644 createLabel (falseLabel, NULL));
4648 /*-----------------------------------------------------------------*/
4649 /* createWhile - creates parse tree for while statement */
4650 /* the while statement will be created as follows */
4652 /* _while_continue_n: */
4653 /* condition_expression +-> trueLabel -> _while_boby_n */
4655 /* +-> falseLabel -> _while_break_n */
4656 /* _while_body_n: */
4658 /* goto _while_continue_n */
4659 /* _while_break_n: */
4660 /*-----------------------------------------------------------------*/
4662 createWhile (symbol * trueLabel, symbol * continueLabel,
4663 symbol * falseLabel, ast * condExpr, ast * whileBody)
4667 /* put the continue label */
4668 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4669 condExpr = createLabel (continueLabel, condExpr);
4670 condExpr->lineno = 0;
4672 /* put the body label in front of the body */
4673 whileBody = createLabel (trueLabel, whileBody);
4674 whileBody->lineno = 0;
4675 /* put a jump to continue at the end of the body */
4676 /* and put break label at the end of the body */
4677 whileBody = newNode (NULLOP,
4680 newAst_VALUE (symbolVal (continueLabel)),
4681 createLabel (falseLabel, NULL)));
4683 /* put it all together */
4684 if (IS_IFX (condExpr))
4685 whileTree = condExpr;
4688 whileTree = newNode (IFX, condExpr, NULL);
4689 /* put the true & false labels in place */
4690 whileTree->trueLabel = trueLabel;
4691 whileTree->falseLabel = falseLabel;
4694 return newNode (NULLOP, whileTree, whileBody);
4697 /*-----------------------------------------------------------------*/
4698 /* optimizeGetHbit - get highest order bit of the expression */
4699 /*-----------------------------------------------------------------*/
4701 optimizeGetHbit (ast * tree)
4704 /* if this is not a bit and */
4705 if (!IS_BITAND (tree))
4708 /* will look for tree of the form
4709 ( expr >> ((sizeof expr) -1) ) & 1 */
4710 if (!IS_AST_LIT_VALUE (tree->right))
4713 if (AST_LIT_VALUE (tree->right) != 1)
4716 if (!IS_RIGHT_OP (tree->left))
4719 if (!IS_AST_LIT_VALUE (tree->left->right))
4722 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4723 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4726 /* make sure the port supports GETHBIT */
4727 if (port->hasExtBitOp
4728 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4731 return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_CHECK);
4735 /*-----------------------------------------------------------------*/
4736 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4737 /*-----------------------------------------------------------------*/
4739 optimizeRRCRLC (ast * root)
4741 /* will look for trees of the form
4742 (?expr << 1) | (?expr >> 7) or
4743 (?expr >> 7) | (?expr << 1) will make that
4744 into a RLC : operation ..
4746 (?expr >> 1) | (?expr << 7) or
4747 (?expr << 7) | (?expr >> 1) will make that
4748 into a RRC operation
4749 note : by 7 I mean (number of bits required to hold the
4751 /* if the root operations is not a | operation the not */
4752 if (!IS_BITOR (root))
4755 /* I have to think of a better way to match patterns this sucks */
4756 /* that aside let start looking for the first case : I use a the
4757 negative check a lot to improve the efficiency */
4758 /* (?expr << 1) | (?expr >> 7) */
4759 if (IS_LEFT_OP (root->left) &&
4760 IS_RIGHT_OP (root->right))
4763 if (!SPEC_USIGN (TETYPE (root->left->left)))
4766 if (!IS_AST_LIT_VALUE (root->left->right) ||
4767 !IS_AST_LIT_VALUE (root->right->right))
4770 /* make sure it is the same expression */
4771 if (!isAstEqual (root->left->left,
4775 if (AST_LIT_VALUE (root->left->right) != 1)
4778 if (AST_LIT_VALUE (root->right->right) !=
4779 (getSize (TTYPE (root->left->left)) * 8 - 1))
4782 /* make sure the port supports RLC */
4783 if (port->hasExtBitOp
4784 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4787 /* whew got the first case : create the AST */
4788 return newNode (RLC, root->left->left, NULL);
4792 /* check for second case */
4793 /* (?expr >> 7) | (?expr << 1) */
4794 if (IS_LEFT_OP (root->right) &&
4795 IS_RIGHT_OP (root->left))
4798 if (!SPEC_USIGN (TETYPE (root->left->left)))
4801 if (!IS_AST_LIT_VALUE (root->left->right) ||
4802 !IS_AST_LIT_VALUE (root->right->right))
4805 /* make sure it is the same symbol */
4806 if (!isAstEqual (root->left->left,
4810 if (AST_LIT_VALUE (root->right->right) != 1)
4813 if (AST_LIT_VALUE (root->left->right) !=
4814 (getSize (TTYPE (root->left->left)) * 8 - 1))
4817 /* make sure the port supports RLC */
4818 if (port->hasExtBitOp
4819 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4822 /* whew got the first case : create the AST */
4823 return newNode (RLC, root->left->left, NULL);
4828 /* third case for RRC */
4829 /* (?symbol >> 1) | (?symbol << 7) */
4830 if (IS_LEFT_OP (root->right) &&
4831 IS_RIGHT_OP (root->left))
4834 if (!SPEC_USIGN (TETYPE (root->left->left)))
4837 if (!IS_AST_LIT_VALUE (root->left->right) ||
4838 !IS_AST_LIT_VALUE (root->right->right))
4841 /* make sure it is the same symbol */
4842 if (!isAstEqual (root->left->left,
4846 if (AST_LIT_VALUE (root->left->right) != 1)
4849 if (AST_LIT_VALUE (root->right->right) !=
4850 (getSize (TTYPE (root->left->left)) * 8 - 1))
4853 /* make sure the port supports RRC */
4854 if (port->hasExtBitOp
4855 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4858 /* whew got the first case : create the AST */
4859 return newNode (RRC, root->left->left, NULL);
4863 /* fourth and last case for now */
4864 /* (?symbol << 7) | (?symbol >> 1) */
4865 if (IS_RIGHT_OP (root->right) &&
4866 IS_LEFT_OP (root->left))
4869 if (!SPEC_USIGN (TETYPE (root->left->left)))
4872 if (!IS_AST_LIT_VALUE (root->left->right) ||
4873 !IS_AST_LIT_VALUE (root->right->right))
4876 /* make sure it is the same symbol */
4877 if (!isAstEqual (root->left->left,
4881 if (AST_LIT_VALUE (root->right->right) != 1)
4884 if (AST_LIT_VALUE (root->left->right) !=
4885 (getSize (TTYPE (root->left->left)) * 8 - 1))
4888 /* make sure the port supports RRC */
4889 if (port->hasExtBitOp
4890 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4893 /* whew got the first case : create the AST */
4894 return newNode (RRC, root->left->left, NULL);
4898 /* not found return root */
4902 /*-----------------------------------------------------------------*/
4903 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
4904 /*-----------------------------------------------------------------*/
4906 optimizeSWAP (ast * root)
4908 /* will look for trees of the form
4909 (?expr << 4) | (?expr >> 4) or
4910 (?expr >> 4) | (?expr << 4) will make that
4911 into a SWAP : operation ..
4912 note : by 4 I mean (number of bits required to hold the
4914 /* if the root operations is not a | operation the not */
4915 if (!IS_BITOR (root))
4918 /* (?expr << 4) | (?expr >> 4) */
4919 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
4920 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
4923 if (!SPEC_USIGN (TETYPE (root->left->left)))
4926 if (!IS_AST_LIT_VALUE (root->left->right) ||
4927 !IS_AST_LIT_VALUE (root->right->right))
4930 /* make sure it is the same expression */
4931 if (!isAstEqual (root->left->left,
4935 if (AST_LIT_VALUE (root->left->right) !=
4936 (getSize (TTYPE (root->left->left)) * 4))
4939 if (AST_LIT_VALUE (root->right->right) !=
4940 (getSize (TTYPE (root->left->left)) * 4))
4943 /* make sure the port supports SWAP */
4944 if (port->hasExtBitOp
4945 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
4948 /* found it : create the AST */
4949 return newNode (SWAP, root->left->left, NULL);
4953 /* not found return root */
4957 /*-----------------------------------------------------------------*/
4958 /* optimizeCompare - otimizes compares for bit variables */
4959 /*-----------------------------------------------------------------*/
4961 optimizeCompare (ast * root)
4963 ast *optExpr = NULL;
4966 unsigned int litValue;
4968 /* if nothing then return nothing */
4972 /* if not a compare op then do leaves */
4973 if (!IS_COMPARE_OP (root))
4975 root->left = optimizeCompare (root->left);
4976 root->right = optimizeCompare (root->right);
4980 /* if left & right are the same then depending
4981 of the operation do */
4982 if (isAstEqual (root->left, root->right))
4984 switch (root->opval.op)
4989 optExpr = newAst_VALUE (constVal ("0"));
4994 optExpr = newAst_VALUE (constVal ("1"));
4998 return decorateType (optExpr, RESULT_CHECK);
5001 vleft = (root->left->type == EX_VALUE ?
5002 root->left->opval.val : NULL);
5004 vright = (root->right->type == EX_VALUE ?
5005 root->right->opval.val : NULL);
5007 /* if left is a BITVAR in BITSPACE */
5008 /* and right is a LITERAL then opt- */
5009 /* imize else do nothing */
5010 if (vleft && vright &&
5011 IS_BITVAR (vleft->etype) &&
5012 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5013 IS_LITERAL (vright->etype))
5016 /* if right side > 1 then comparison may never succeed */
5017 if ((litValue = (int) floatFromVal (vright)) > 1)
5019 werror (W_BAD_COMPARE);
5025 switch (root->opval.op)
5027 case '>': /* bit value greater than 1 cannot be */
5028 werror (W_BAD_COMPARE);
5032 case '<': /* bit value < 1 means 0 */
5034 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5037 case LE_OP: /* bit value <= 1 means no check */
5038 optExpr = newAst_VALUE (vright);
5041 case GE_OP: /* bit value >= 1 means only check for = */
5043 optExpr = newAst_VALUE (vleft);
5048 { /* literal is zero */
5049 switch (root->opval.op)
5051 case '<': /* bit value < 0 cannot be */
5052 werror (W_BAD_COMPARE);
5056 case '>': /* bit value > 0 means 1 */
5058 optExpr = newAst_VALUE (vleft);
5061 case LE_OP: /* bit value <= 0 means no check */
5062 case GE_OP: /* bit value >= 0 means no check */
5063 werror (W_BAD_COMPARE);
5067 case EQ_OP: /* bit == 0 means ! of bit */
5068 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5072 return decorateType (resolveSymbols (optExpr), RESULT_CHECK);
5073 } /* end-of-if of BITVAR */
5078 /*-----------------------------------------------------------------*/
5079 /* addSymToBlock : adds the symbol to the first block we find */
5080 /*-----------------------------------------------------------------*/
5082 addSymToBlock (symbol * sym, ast * tree)
5084 /* reached end of tree or a leaf */
5085 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5089 if (IS_AST_OP (tree) &&
5090 tree->opval.op == BLOCK)
5093 symbol *lsym = copySymbol (sym);
5095 lsym->next = AST_VALUES (tree, sym);
5096 AST_VALUES (tree, sym) = lsym;
5100 addSymToBlock (sym, tree->left);
5101 addSymToBlock (sym, tree->right);
5104 /*-----------------------------------------------------------------*/
5105 /* processRegParms - do processing for register parameters */
5106 /*-----------------------------------------------------------------*/
5108 processRegParms (value * args, ast * body)
5112 if (IS_REGPARM (args->etype))
5113 addSymToBlock (args->sym, body);
5118 /*-----------------------------------------------------------------*/
5119 /* resetParmKey - resets the operandkeys for the symbols */
5120 /*-----------------------------------------------------------------*/
5121 DEFSETFUNC (resetParmKey)
5132 /*-----------------------------------------------------------------*/
5133 /* createFunction - This is the key node that calls the iCode for */
5134 /* generating the code for a function. Note code */
5135 /* is generated function by function, later when */
5136 /* add inter-procedural analysis this will change */
5137 /*-----------------------------------------------------------------*/
5139 createFunction (symbol * name, ast * body)
5145 iCode *piCode = NULL;
5147 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5148 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5150 /* if check function return 0 then some problem */
5151 if (checkFunction (name, NULL) == 0)
5154 /* create a dummy block if none exists */
5156 body = newNode (BLOCK, NULL, NULL);
5160 /* check if the function name already in the symbol table */
5161 if ((csym = findSym (SymbolTab, NULL, name->name)))
5164 /* special case for compiler defined functions
5165 we need to add the name to the publics list : this
5166 actually means we are now compiling the compiler
5170 addSet (&publics, name);
5176 allocVariables (name);
5178 name->lastLine = mylineno;
5181 /* set the stack pointer */
5182 /* PENDING: check this for the mcs51 */
5183 stackPtr = -port->stack.direction * port->stack.call_overhead;
5184 if (IFFUNC_ISISR (name->type))
5185 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5186 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5187 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5189 xstackPtr = -port->stack.direction * port->stack.call_overhead;
5191 fetype = getSpec (name->type); /* get the specifier for the function */
5192 /* if this is a reentrant function then */
5193 if (IFFUNC_ISREENT (name->type))
5196 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5198 /* do processing for parameters that are passed in registers */
5199 processRegParms (FUNC_ARGS(name->type), body);
5201 /* set the stack pointer */
5205 /* allocate & autoinit the block variables */
5206 processBlockVars (body, &stack, ALLOCATE);
5208 /* save the stack information */
5209 if (options.useXstack)
5210 name->xstack = SPEC_STAK (fetype) = stack;
5212 name->stack = SPEC_STAK (fetype) = stack;
5214 /* name needs to be mangled */
5215 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5217 body = resolveSymbols (body); /* resolve the symbols */
5218 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5221 ex = newAst_VALUE (symbolVal (name)); /* create name */
5222 ex = newNode (FUNCTION, ex, body);
5223 ex->values.args = FUNC_ARGS(name->type);
5225 if (options.dump_tree) PA(ex);
5228 werror (E_FUNC_NO_CODE, name->name);
5232 /* create the node & generate intermediate code */
5234 codeOutFile = code->oFile;
5235 piCode = iCodeFromAst (ex);
5239 werror (E_FUNC_NO_CODE, name->name);
5243 eBBlockFromiCode (piCode);
5245 /* if there are any statics then do them */
5248 GcurMemmap = statsg;
5249 codeOutFile = statsg->oFile;
5250 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_CHECK)));
5256 /* dealloc the block variables */
5257 processBlockVars (body, &stack, DEALLOCATE);
5258 outputDebugStackSymbols();
5259 /* deallocate paramaters */
5260 deallocParms (FUNC_ARGS(name->type));
5262 if (IFFUNC_ISREENT (name->type))
5265 /* we are done freeup memory & cleanup */
5267 if (port->reset_labelKey) labelKey = 1;
5269 FUNC_HASBODY(name->type) = 1;
5270 addSet (&operKeyReset, name);
5271 applyToSet (operKeyReset, resetParmKey);
5276 cleanUpLevel (LabelTab, 0);
5277 cleanUpBlock (StructTab, 1);
5278 cleanUpBlock (TypedefTab, 1);
5280 xstack->syms = NULL;
5281 istack->syms = NULL;
5286 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5287 /*-----------------------------------------------------------------*/
5288 /* ast_print : prints the ast (for debugging purposes) */
5289 /*-----------------------------------------------------------------*/
5291 void ast_print (ast * tree, FILE *outfile, int indent)
5296 /* can print only decorated trees */
5297 if (!tree->decorated) return;
5299 /* if any child is an error | this one is an error do nothing */
5300 if (tree->isError ||
5301 (tree->left && tree->left->isError) ||
5302 (tree->right && tree->right->isError)) {
5303 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5307 /* print the line */
5308 /* if not block & function */
5309 if (tree->type == EX_OP &&
5310 (tree->opval.op != FUNCTION &&
5311 tree->opval.op != BLOCK &&
5312 tree->opval.op != NULLOP)) {
5315 if (tree->opval.op == FUNCTION) {
5317 value *args=FUNC_ARGS(tree->left->opval.val->type);
5318 fprintf(outfile,"FUNCTION (%s=%p) type (",
5319 tree->left->opval.val->name, tree);
5320 printTypeChain (tree->left->opval.val->type->next,outfile);
5321 fprintf(outfile,") args (");
5324 fprintf (outfile, ", ");
5326 printTypeChain (args ? args->type : NULL, outfile);
5328 args= args ? args->next : NULL;
5330 fprintf(outfile,")\n");
5331 ast_print(tree->left,outfile,indent);
5332 ast_print(tree->right,outfile,indent);
5335 if (tree->opval.op == BLOCK) {
5336 symbol *decls = tree->values.sym;
5337 INDENT(indent,outfile);
5338 fprintf(outfile,"{\n");
5340 INDENT(indent+2,outfile);
5341 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5342 decls->name, decls);
5343 printTypeChain(decls->type,outfile);
5344 fprintf(outfile,")\n");
5346 decls = decls->next;
5348 ast_print(tree->right,outfile,indent+2);
5349 INDENT(indent,outfile);
5350 fprintf(outfile,"}\n");
5353 if (tree->opval.op == NULLOP) {
5354 ast_print(tree->left,outfile,indent);
5355 ast_print(tree->right,outfile,indent);
5358 INDENT(indent,outfile);
5360 /*------------------------------------------------------------------*/
5361 /*----------------------------*/
5362 /* leaf has been reached */
5363 /*----------------------------*/
5364 /* if this is of type value */
5365 /* just get the type */
5366 if (tree->type == EX_VALUE) {
5368 if (IS_LITERAL (tree->opval.val->etype)) {
5369 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5370 if (SPEC_USIGN (tree->opval.val->etype))
5371 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5373 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5374 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5375 floatFromVal(tree->opval.val));
5376 } else if (tree->opval.val->sym) {
5377 /* if the undefined flag is set then give error message */
5378 if (tree->opval.val->sym->undefined) {
5379 fprintf(outfile,"UNDEFINED SYMBOL ");
5381 fprintf(outfile,"SYMBOL ");
5383 fprintf(outfile,"(%s=%p)",
5384 tree->opval.val->sym->name,tree);
5387 fprintf(outfile," type (");
5388 printTypeChain(tree->ftype,outfile);
5389 fprintf(outfile,")\n");
5391 fprintf(outfile,"\n");
5396 /* if type link for the case of cast */
5397 if (tree->type == EX_LINK) {
5398 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5399 printTypeChain(tree->opval.lnk,outfile);
5400 fprintf(outfile,")\n");
5405 /* depending on type of operator do */
5407 switch (tree->opval.op) {
5408 /*------------------------------------------------------------------*/
5409 /*----------------------------*/
5411 /*----------------------------*/
5413 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5414 printTypeChain(tree->ftype,outfile);
5415 fprintf(outfile,")\n");
5416 ast_print(tree->left,outfile,indent+2);
5417 ast_print(tree->right,outfile,indent+2);
5420 /*------------------------------------------------------------------*/
5421 /*----------------------------*/
5423 /*----------------------------*/
5425 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5426 printTypeChain(tree->ftype,outfile);
5427 fprintf(outfile,")\n");
5428 ast_print(tree->left,outfile,indent+2);
5429 ast_print(tree->right,outfile,indent+2);
5432 /*------------------------------------------------------------------*/
5433 /*----------------------------*/
5434 /* struct/union pointer */
5435 /*----------------------------*/
5437 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5438 printTypeChain(tree->ftype,outfile);
5439 fprintf(outfile,")\n");
5440 ast_print(tree->left,outfile,indent+2);
5441 ast_print(tree->right,outfile,indent+2);
5444 /*------------------------------------------------------------------*/
5445 /*----------------------------*/
5446 /* ++/-- operation */
5447 /*----------------------------*/
5450 fprintf(outfile,"post-");
5452 fprintf(outfile,"pre-");
5453 fprintf(outfile,"INC_OP (%p) type (",tree);
5454 printTypeChain(tree->ftype,outfile);
5455 fprintf(outfile,")\n");
5456 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5457 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5462 fprintf(outfile,"post-");
5464 fprintf(outfile,"pre-");
5465 fprintf(outfile,"DEC_OP (%p) type (",tree);
5466 printTypeChain(tree->ftype,outfile);
5467 fprintf(outfile,")\n");
5468 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5469 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5472 /*------------------------------------------------------------------*/
5473 /*----------------------------*/
5475 /*----------------------------*/
5478 fprintf(outfile,"& (%p) type (",tree);
5479 printTypeChain(tree->ftype,outfile);
5480 fprintf(outfile,")\n");
5481 ast_print(tree->left,outfile,indent+2);
5482 ast_print(tree->right,outfile,indent+2);
5484 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5485 printTypeChain(tree->ftype,outfile);
5486 fprintf(outfile,")\n");
5487 ast_print(tree->left,outfile,indent+2);
5488 ast_print(tree->right,outfile,indent+2);
5491 /*----------------------------*/
5493 /*----------------------------*/
5495 fprintf(outfile,"OR (%p) type (",tree);
5496 printTypeChain(tree->ftype,outfile);
5497 fprintf(outfile,")\n");
5498 ast_print(tree->left,outfile,indent+2);
5499 ast_print(tree->right,outfile,indent+2);
5501 /*------------------------------------------------------------------*/
5502 /*----------------------------*/
5504 /*----------------------------*/
5506 fprintf(outfile,"XOR (%p) type (",tree);
5507 printTypeChain(tree->ftype,outfile);
5508 fprintf(outfile,")\n");
5509 ast_print(tree->left,outfile,indent+2);
5510 ast_print(tree->right,outfile,indent+2);
5513 /*------------------------------------------------------------------*/
5514 /*----------------------------*/
5516 /*----------------------------*/
5518 fprintf(outfile,"DIV (%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);
5524 /*------------------------------------------------------------------*/
5525 /*----------------------------*/
5527 /*----------------------------*/
5529 fprintf(outfile,"MOD (%p) type (",tree);
5530 printTypeChain(tree->ftype,outfile);
5531 fprintf(outfile,")\n");
5532 ast_print(tree->left,outfile,indent+2);
5533 ast_print(tree->right,outfile,indent+2);
5536 /*------------------------------------------------------------------*/
5537 /*----------------------------*/
5538 /* address dereference */
5539 /*----------------------------*/
5540 case '*': /* can be unary : if right is null then unary operation */
5542 fprintf(outfile,"DEREF (%p) type (",tree);
5543 printTypeChain(tree->ftype,outfile);
5544 fprintf(outfile,")\n");
5545 ast_print(tree->left,outfile,indent+2);
5548 /*------------------------------------------------------------------*/
5549 /*----------------------------*/
5550 /* multiplication */
5551 /*----------------------------*/
5552 fprintf(outfile,"MULT (%p) type (",tree);
5553 printTypeChain(tree->ftype,outfile);
5554 fprintf(outfile,")\n");
5555 ast_print(tree->left,outfile,indent+2);
5556 ast_print(tree->right,outfile,indent+2);
5560 /*------------------------------------------------------------------*/
5561 /*----------------------------*/
5562 /* unary '+' operator */
5563 /*----------------------------*/
5567 fprintf(outfile,"UPLUS (%p) type (",tree);
5568 printTypeChain(tree->ftype,outfile);
5569 fprintf(outfile,")\n");
5570 ast_print(tree->left,outfile,indent+2);
5572 /*------------------------------------------------------------------*/
5573 /*----------------------------*/
5575 /*----------------------------*/
5576 fprintf(outfile,"ADD (%p) type (",tree);
5577 printTypeChain(tree->ftype,outfile);
5578 fprintf(outfile,")\n");
5579 ast_print(tree->left,outfile,indent+2);
5580 ast_print(tree->right,outfile,indent+2);
5583 /*------------------------------------------------------------------*/
5584 /*----------------------------*/
5586 /*----------------------------*/
5587 case '-': /* can be unary */
5589 fprintf(outfile,"UMINUS (%p) type (",tree);
5590 printTypeChain(tree->ftype,outfile);
5591 fprintf(outfile,")\n");
5592 ast_print(tree->left,outfile,indent+2);
5594 /*------------------------------------------------------------------*/
5595 /*----------------------------*/
5597 /*----------------------------*/
5598 fprintf(outfile,"SUB (%p) type (",tree);
5599 printTypeChain(tree->ftype,outfile);
5600 fprintf(outfile,")\n");
5601 ast_print(tree->left,outfile,indent+2);
5602 ast_print(tree->right,outfile,indent+2);
5605 /*------------------------------------------------------------------*/
5606 /*----------------------------*/
5608 /*----------------------------*/
5610 fprintf(outfile,"COMPL (%p) type (",tree);
5611 printTypeChain(tree->ftype,outfile);
5612 fprintf(outfile,")\n");
5613 ast_print(tree->left,outfile,indent+2);
5615 /*------------------------------------------------------------------*/
5616 /*----------------------------*/
5618 /*----------------------------*/
5620 fprintf(outfile,"NOT (%p) type (",tree);
5621 printTypeChain(tree->ftype,outfile);
5622 fprintf(outfile,")\n");
5623 ast_print(tree->left,outfile,indent+2);
5625 /*------------------------------------------------------------------*/
5626 /*----------------------------*/
5628 /*----------------------------*/
5630 fprintf(outfile,"RRC (%p) type (",tree);
5631 printTypeChain(tree->ftype,outfile);
5632 fprintf(outfile,")\n");
5633 ast_print(tree->left,outfile,indent+2);
5637 fprintf(outfile,"RLC (%p) type (",tree);
5638 printTypeChain(tree->ftype,outfile);
5639 fprintf(outfile,")\n");
5640 ast_print(tree->left,outfile,indent+2);
5643 fprintf(outfile,"SWAP (%p) type (",tree);
5644 printTypeChain(tree->ftype,outfile);
5645 fprintf(outfile,")\n");
5646 ast_print(tree->left,outfile,indent+2);
5649 fprintf(outfile,"GETHBIT (%p) type (",tree);
5650 printTypeChain(tree->ftype,outfile);
5651 fprintf(outfile,")\n");
5652 ast_print(tree->left,outfile,indent+2);
5655 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5656 printTypeChain(tree->ftype,outfile);
5657 fprintf(outfile,")\n");
5658 ast_print(tree->left,outfile,indent+2);
5659 ast_print(tree->right,outfile,indent+2);
5662 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5663 printTypeChain(tree->ftype,outfile);
5664 fprintf(outfile,")\n");
5665 ast_print(tree->left,outfile,indent+2);
5666 ast_print(tree->right,outfile,indent+2);
5668 /*------------------------------------------------------------------*/
5669 /*----------------------------*/
5671 /*----------------------------*/
5672 case CAST: /* change the type */
5673 fprintf(outfile,"CAST (%p) from type (",tree);
5674 printTypeChain(tree->right->ftype,outfile);
5675 fprintf(outfile,") to type (");
5676 printTypeChain(tree->ftype,outfile);
5677 fprintf(outfile,")\n");
5678 ast_print(tree->right,outfile,indent+2);
5682 fprintf(outfile,"ANDAND (%p) type (",tree);
5683 printTypeChain(tree->ftype,outfile);
5684 fprintf(outfile,")\n");
5685 ast_print(tree->left,outfile,indent+2);
5686 ast_print(tree->right,outfile,indent+2);
5689 fprintf(outfile,"OROR (%p) type (",tree);
5690 printTypeChain(tree->ftype,outfile);
5691 fprintf(outfile,")\n");
5692 ast_print(tree->left,outfile,indent+2);
5693 ast_print(tree->right,outfile,indent+2);
5696 /*------------------------------------------------------------------*/
5697 /*----------------------------*/
5698 /* comparison operators */
5699 /*----------------------------*/
5701 fprintf(outfile,"GT(>) (%p) type (",tree);
5702 printTypeChain(tree->ftype,outfile);
5703 fprintf(outfile,")\n");
5704 ast_print(tree->left,outfile,indent+2);
5705 ast_print(tree->right,outfile,indent+2);
5708 fprintf(outfile,"LT(<) (%p) type (",tree);
5709 printTypeChain(tree->ftype,outfile);
5710 fprintf(outfile,")\n");
5711 ast_print(tree->left,outfile,indent+2);
5712 ast_print(tree->right,outfile,indent+2);
5715 fprintf(outfile,"LE(<=) (%p) type (",tree);
5716 printTypeChain(tree->ftype,outfile);
5717 fprintf(outfile,")\n");
5718 ast_print(tree->left,outfile,indent+2);
5719 ast_print(tree->right,outfile,indent+2);
5722 fprintf(outfile,"GE(>=) (%p) type (",tree);
5723 printTypeChain(tree->ftype,outfile);
5724 fprintf(outfile,")\n");
5725 ast_print(tree->left,outfile,indent+2);
5726 ast_print(tree->right,outfile,indent+2);
5729 fprintf(outfile,"EQ(==) (%p) type (",tree);
5730 printTypeChain(tree->ftype,outfile);
5731 fprintf(outfile,")\n");
5732 ast_print(tree->left,outfile,indent+2);
5733 ast_print(tree->right,outfile,indent+2);
5736 fprintf(outfile,"NE(!=) (%p) type (",tree);
5737 printTypeChain(tree->ftype,outfile);
5738 fprintf(outfile,")\n");
5739 ast_print(tree->left,outfile,indent+2);
5740 ast_print(tree->right,outfile,indent+2);
5741 /*------------------------------------------------------------------*/
5742 /*----------------------------*/
5744 /*----------------------------*/
5745 case SIZEOF: /* evaluate wihout code generation */
5746 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5749 /*------------------------------------------------------------------*/
5750 /*----------------------------*/
5751 /* conditional operator '?' */
5752 /*----------------------------*/
5754 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5755 printTypeChain(tree->ftype,outfile);
5756 fprintf(outfile,")\n");
5757 ast_print(tree->left,outfile,indent+2);
5758 ast_print(tree->right,outfile,indent+2);
5762 fprintf(outfile,"COLON(:) (%p) type (",tree);
5763 printTypeChain(tree->ftype,outfile);
5764 fprintf(outfile,")\n");
5765 ast_print(tree->left,outfile,indent+2);
5766 ast_print(tree->right,outfile,indent+2);
5769 /*------------------------------------------------------------------*/
5770 /*----------------------------*/
5771 /* assignment operators */
5772 /*----------------------------*/
5774 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5775 printTypeChain(tree->ftype,outfile);
5776 fprintf(outfile,")\n");
5777 ast_print(tree->left,outfile,indent+2);
5778 ast_print(tree->right,outfile,indent+2);
5781 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5782 printTypeChain(tree->ftype,outfile);
5783 fprintf(outfile,")\n");
5784 ast_print(tree->left,outfile,indent+2);
5785 ast_print(tree->right,outfile,indent+2);
5788 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5789 printTypeChain(tree->ftype,outfile);
5790 fprintf(outfile,")\n");
5791 ast_print(tree->left,outfile,indent+2);
5792 ast_print(tree->right,outfile,indent+2);
5795 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5796 printTypeChain(tree->ftype,outfile);
5797 fprintf(outfile,")\n");
5798 ast_print(tree->left,outfile,indent+2);
5799 ast_print(tree->right,outfile,indent+2);
5802 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5803 printTypeChain(tree->ftype,outfile);
5804 fprintf(outfile,")\n");
5805 ast_print(tree->left,outfile,indent+2);
5806 ast_print(tree->right,outfile,indent+2);
5809 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5810 printTypeChain(tree->ftype,outfile);
5811 fprintf(outfile,")\n");
5812 ast_print(tree->left,outfile,indent+2);
5813 ast_print(tree->right,outfile,indent+2);
5816 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5817 printTypeChain(tree->ftype,outfile);
5818 fprintf(outfile,")\n");
5819 ast_print(tree->left,outfile,indent+2);
5820 ast_print(tree->right,outfile,indent+2);
5822 /*------------------------------------------------------------------*/
5823 /*----------------------------*/
5825 /*----------------------------*/
5827 fprintf(outfile,"SUBASS(-=) (%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);
5833 /*------------------------------------------------------------------*/
5834 /*----------------------------*/
5836 /*----------------------------*/
5838 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5839 printTypeChain(tree->ftype,outfile);
5840 fprintf(outfile,")\n");
5841 ast_print(tree->left,outfile,indent+2);
5842 ast_print(tree->right,outfile,indent+2);
5844 /*------------------------------------------------------------------*/
5845 /*----------------------------*/
5846 /* straight assignemnt */
5847 /*----------------------------*/
5849 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5850 printTypeChain(tree->ftype,outfile);
5851 fprintf(outfile,")\n");
5852 ast_print(tree->left,outfile,indent+2);
5853 ast_print(tree->right,outfile,indent+2);
5855 /*------------------------------------------------------------------*/
5856 /*----------------------------*/
5857 /* comma operator */
5858 /*----------------------------*/
5860 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5861 printTypeChain(tree->ftype,outfile);
5862 fprintf(outfile,")\n");
5863 ast_print(tree->left,outfile,indent+2);
5864 ast_print(tree->right,outfile,indent+2);
5866 /*------------------------------------------------------------------*/
5867 /*----------------------------*/
5869 /*----------------------------*/
5872 fprintf(outfile,"CALL (%p) type (",tree);
5873 printTypeChain(tree->ftype,outfile);
5874 fprintf(outfile,")\n");
5875 ast_print(tree->left,outfile,indent+2);
5876 ast_print(tree->right,outfile,indent+2);
5879 fprintf(outfile,"PARMS\n");
5880 ast_print(tree->left,outfile,indent+2);
5881 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5882 ast_print(tree->right,outfile,indent+2);
5885 /*------------------------------------------------------------------*/
5886 /*----------------------------*/
5887 /* return statement */
5888 /*----------------------------*/
5890 fprintf(outfile,"RETURN (%p) type (",tree);
5892 printTypeChain(tree->right->ftype,outfile);
5894 fprintf(outfile,")\n");
5895 ast_print(tree->right,outfile,indent+2);
5897 /*------------------------------------------------------------------*/
5898 /*----------------------------*/
5899 /* label statement */
5900 /*----------------------------*/
5902 fprintf(outfile,"LABEL (%p)\n",tree);
5903 ast_print(tree->left,outfile,indent+2);
5904 ast_print(tree->right,outfile,indent);
5906 /*------------------------------------------------------------------*/
5907 /*----------------------------*/
5908 /* switch statement */
5909 /*----------------------------*/
5913 fprintf(outfile,"SWITCH (%p) ",tree);
5914 ast_print(tree->left,outfile,0);
5915 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5916 INDENT(indent+2,outfile);
5917 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5918 (int) floatFromVal(val),
5919 tree->values.switchVals.swNum,
5920 (int) floatFromVal(val));
5922 ast_print(tree->right,outfile,indent);
5925 /*------------------------------------------------------------------*/
5926 /*----------------------------*/
5928 /*----------------------------*/
5930 fprintf(outfile,"IF (%p) \n",tree);
5931 ast_print(tree->left,outfile,indent+2);
5932 if (tree->trueLabel) {
5933 INDENT(indent+2,outfile);
5934 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5936 if (tree->falseLabel) {
5937 INDENT(indent+2,outfile);
5938 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5940 ast_print(tree->right,outfile,indent+2);
5942 /*----------------------------*/
5943 /* goto Statement */
5944 /*----------------------------*/
5946 fprintf(outfile,"GOTO (%p) \n",tree);
5947 ast_print(tree->left,outfile,indent+2);
5948 fprintf(outfile,"\n");
5950 /*------------------------------------------------------------------*/
5951 /*----------------------------*/
5953 /*----------------------------*/
5955 fprintf(outfile,"FOR (%p) \n",tree);
5956 if (AST_FOR( tree, initExpr)) {
5957 INDENT(indent+2,outfile);
5958 fprintf(outfile,"INIT EXPR ");
5959 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5961 if (AST_FOR( tree, condExpr)) {
5962 INDENT(indent+2,outfile);
5963 fprintf(outfile,"COND EXPR ");
5964 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5966 if (AST_FOR( tree, loopExpr)) {
5967 INDENT(indent+2,outfile);
5968 fprintf(outfile,"LOOP EXPR ");
5969 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5971 fprintf(outfile,"FOR LOOP BODY \n");
5972 ast_print(tree->left,outfile,indent+2);
5975 fprintf(outfile,"CRITICAL (%p) \n",tree);
5976 ast_print(tree->left,outfile,indent+2);
5984 ast_print(t,stdout,0);
5989 /*-----------------------------------------------------------------*/
5990 /* astErrors : returns non-zero if errors present in tree */
5991 /*-----------------------------------------------------------------*/
5992 int astErrors(ast *t)
6001 if (t->type == EX_VALUE
6002 && t->opval.val->sym
6003 && t->opval.val->sym->undefined)
6006 errors += astErrors(t->left);
6007 errors += astErrors(t->right);