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;
657 /* if none of them exist */
658 if (!defParm && !actParm)
663 if (getenv("DEBUG_SANITY"))
665 fprintf (stderr, "processParms: %s ", defParm->name);
667 /* make sure the type is complete and sane */
668 checkTypeSanity(defParm->etype, defParm->name);
671 if (IS_CODEPTR (func->ftype))
672 functype = func->ftype->next;
674 functype = func->ftype;
676 /* if the function is being called via a pointer & */
677 /* it has not been defined a reentrant then we cannot */
678 /* have parameters */
679 if (func->type != EX_VALUE && !IFFUNC_ISREENT (functype) && !options.stackAuto)
681 werror (W_NONRENT_ARGS);
685 /* if defined parameters ended but actual parameters */
686 /* exist and this is not defined as a variable arg */
687 if (!defParm && actParm && !IFFUNC_HASVARARGS(functype))
689 werror (E_TOO_MANY_PARMS);
693 /* if defined parameters present but no actual parameters */
694 if (defParm && !actParm)
696 werror (E_TOO_FEW_PARMS);
700 /* if this is a PARAM node then match left & right */
701 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
703 actParm->decorated = 1;
704 return (processParms (func, defParm,
705 actParm->left, parmNumber, FALSE) ||
706 processParms (func, defParm ? defParm->next : NULL,
707 actParm->right, parmNumber, rightmost));
709 else if (defParm) /* not vararg */
711 /* If we have found a value node by following only right-hand links,
712 * then we know that there are no more values after us.
714 * Therefore, if there are more defined parameters, the caller didn't
717 if (rightmost && defParm->next)
719 werror (E_TOO_FEW_PARMS);
724 /* decorate parameter */
725 resultType = defParm ? getResultTypeFromType (defParm->etype) :
727 actParm = decorateType (actParm, resultType);
729 if (IS_VOID(actParm->ftype))
731 werror (E_VOID_VALUE_USED);
735 /* If this is a varargs function... */
736 if (!defParm && actParm && IFFUNC_HASVARARGS(functype))
741 if (IS_CAST_OP (actParm)
742 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
744 /* Parameter was explicitly typecast; don't touch it. */
748 ftype = actParm->ftype;
750 /* If it's a char, upcast to int. */
751 if (IS_INTEGRAL (ftype)
752 && (getSize (ftype) < (unsigned) INTSIZE))
754 newType = newAst_LINK(INTTYPE);
757 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
759 newType = newAst_LINK (copyLinkChain(ftype));
760 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
763 if (IS_AGGREGATE (ftype))
765 newType = newAst_LINK (copyLinkChain (ftype));
766 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
771 /* cast required; change this op to a cast. */
772 ast *parmCopy = resolveSymbols (copyAst (actParm));
774 actParm->type = EX_OP;
775 actParm->opval.op = CAST;
776 actParm->left = newType;
777 actParm->right = parmCopy;
778 actParm->decorated = 0; /* force typechecking */
779 decorateType (actParm, RESULT_TYPE_NONE);
784 /* if defined parameters ended but actual has not & */
786 if (!defParm && actParm &&
787 (options.stackAuto || IFFUNC_ISREENT (functype)))
790 resolveSymbols (actParm);
792 /* the parameter type must be at least castable */
793 if (compareType (defParm->type, actParm->ftype) == 0)
795 werror (E_INCOMPAT_TYPES);
796 printFromToType (actParm->ftype, defParm->type);
800 /* if the parameter is castable then add the cast */
801 if (compareType (defParm->type, actParm->ftype) < 0)
805 resultType = getResultTypeFromType (defParm->etype);
806 pTree = resolveSymbols (copyAst (actParm));
808 /* now change the current one to a cast */
809 actParm->type = EX_OP;
810 actParm->opval.op = CAST;
811 actParm->left = newAst_LINK (defParm->type);
812 actParm->right = pTree;
813 actParm->decorated = 0; /* force typechecking */
814 decorateType (actParm, resultType);
817 /* make a copy and change the regparm type to the defined parm */
818 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
819 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
820 SPEC_ARGREG (actParm->etype) = SPEC_ARGREG (defParm->etype);
825 /*-----------------------------------------------------------------*/
826 /* createIvalType - generates ival for basic types */
827 /*-----------------------------------------------------------------*/
829 createIvalType (ast * sym, sym_link * type, initList * ilist)
833 /* if initList is deep */
834 if (ilist->type == INIT_DEEP)
835 ilist = ilist->init.deep;
837 iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK);
838 return decorateType (newNode ('=', sym, iExpr), RESULT_CHECK);
841 /*-----------------------------------------------------------------*/
842 /* createIvalStruct - generates initial value for structures */
843 /*-----------------------------------------------------------------*/
845 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
852 sflds = SPEC_STRUCT (type)->fields;
853 if (ilist->type != INIT_DEEP)
855 werror (E_INIT_STRUCT, "");
859 iloop = ilist->init.deep;
861 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
863 /* if we have come to end */
867 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
868 lAst = decorateType (resolveSymbols (lAst), RESULT_CHECK);
869 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)), RESULT_CHECK);
873 werrorfl (filename, sym->opval.val->sym->lineDef,
874 W_EXCESS_INITIALIZERS, "struct",
875 sym->opval.val->sym->name);
882 /*-----------------------------------------------------------------*/
883 /* createIvalArray - generates code for array initialization */
884 /*-----------------------------------------------------------------*/
886 createIvalArray (ast * sym, sym_link * type, initList * ilist)
890 int lcnt = 0, size = 0;
891 literalList *literalL;
893 /* take care of the special case */
894 /* array of characters can be init */
896 if (IS_CHAR (type->next))
897 if ((rast = createIvalCharPtr (sym,
899 decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK))))
901 return decorateType (resolveSymbols (rast), RESULT_CHECK);
903 /* not the special case */
904 if (ilist->type != INIT_DEEP)
906 werror (E_INIT_STRUCT, "");
910 iloop = ilist->init.deep;
911 lcnt = DCL_ELEM (type);
913 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
917 aSym = decorateType (resolveSymbols(sym), RESULT_CHECK);
919 rast = newNode(ARRAYINIT, aSym, NULL);
920 rast->values.constlist = literalL;
922 // Make sure size is set to length of initializer list.
929 if (lcnt && size > lcnt)
931 // Array size was specified, and we have more initializers than needed.
932 char *name=sym->opval.val->sym->name;
933 int lineno=sym->opval.val->sym->lineDef;
935 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
944 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
945 aSym = decorateType (resolveSymbols (aSym), RESULT_CHECK);
946 rast = createIval (aSym, type->next, iloop, rast);
947 iloop = (iloop ? iloop->next : NULL);
953 /* no of elements given and we */
954 /* have generated for all of them */
957 // there has to be a better way
958 char *name=sym->opval.val->sym->name;
959 int lineno=sym->opval.val->sym->lineDef;
960 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
967 /* if we have not been given a size */
968 if (!DCL_ELEM (type))
970 DCL_ELEM (type) = size;
973 return decorateType (resolveSymbols (rast), RESULT_CHECK);
977 /*-----------------------------------------------------------------*/
978 /* createIvalCharPtr - generates initial values for char pointers */
979 /*-----------------------------------------------------------------*/
981 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
985 /* if this is a pointer & right is a literal array then */
986 /* just assignment will do */
987 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
988 SPEC_SCLS (iexpr->etype) == S_CODE)
989 && IS_ARRAY (iexpr->ftype)))
990 return newNode ('=', sym, iexpr);
992 /* left side is an array so we have to assign each */
994 if ((IS_LITERAL (iexpr->etype) ||
995 SPEC_SCLS (iexpr->etype) == S_CODE)
996 && IS_ARRAY (iexpr->ftype))
998 /* for each character generate an assignment */
999 /* to the array element */
1000 char *s = SPEC_CVAL (iexpr->etype).v_char;
1002 int size = getSize (iexpr->ftype);
1003 int symsize = getSize (type);
1007 if (size>(symsize+1))
1008 werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1009 "string", sym->opval.val->sym->name);
1013 for (i=0;i<size;i++)
1015 rast = newNode (NULLOP,
1019 newAst_VALUE (valueFromLit ((float) i))),
1020 newAst_VALUE (valueFromLit (*s))));
1024 // now WE don't need iexpr's symbol anymore
1025 freeStringSymbol(AST_SYMBOL(iexpr));
1027 return decorateType (resolveSymbols (rast), RESULT_CHECK);
1033 /*-----------------------------------------------------------------*/
1034 /* createIvalPtr - generates initial value for pointers */
1035 /*-----------------------------------------------------------------*/
1037 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
1043 if (ilist->type == INIT_DEEP)
1044 ilist = ilist->init.deep;
1046 iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK);
1048 /* if character pointer */
1049 if (IS_CHAR (type->next))
1050 if ((rast = createIvalCharPtr (sym, type, iexpr)))
1053 return newNode ('=', sym, iexpr);
1056 /*-----------------------------------------------------------------*/
1057 /* createIval - generates code for initial value */
1058 /*-----------------------------------------------------------------*/
1060 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1067 /* if structure then */
1068 if (IS_STRUCT (type))
1069 rast = createIvalStruct (sym, type, ilist);
1071 /* if this is a pointer */
1073 rast = createIvalPtr (sym, type, ilist);
1075 /* if this is an array */
1076 if (IS_ARRAY (type))
1077 rast = createIvalArray (sym, type, ilist);
1079 /* if type is SPECIFIER */
1081 rast = createIvalType (sym, type, ilist);
1084 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_CHECK);
1086 return decorateType (resolveSymbols (rast), RESULT_CHECK);
1089 /*-----------------------------------------------------------------*/
1090 /* initAggregates - initialises aggregate variables with initv */
1091 /*-----------------------------------------------------------------*/
1092 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1093 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1096 /*-----------------------------------------------------------------*/
1097 /* gatherAutoInit - creates assignment expressions for initial */
1099 /*-----------------------------------------------------------------*/
1101 gatherAutoInit (symbol * autoChain)
1108 for (sym = autoChain; sym; sym = sym->next)
1111 /* resolve the symbols in the ival */
1113 resolveIvalSym (sym->ival, sym->type);
1115 /* if this is a static variable & has an */
1116 /* initial value the code needs to be lifted */
1117 /* here to the main portion since they can be */
1118 /* initialised only once at the start */
1119 if (IS_STATIC (sym->etype) && sym->ival &&
1120 SPEC_SCLS (sym->etype) != S_CODE)
1124 /* insert the symbol into the symbol table */
1125 /* with level = 0 & name = rname */
1126 newSym = copySymbol (sym);
1127 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1129 /* now lift the code to main */
1130 if (IS_AGGREGATE (sym->type)) {
1131 work = initAggregates (sym, sym->ival, NULL);
1133 if (getNelements(sym->type, sym->ival)>1) {
1134 werrorfl (filename, sym->lineDef,
1135 W_EXCESS_INITIALIZERS, "scalar",
1138 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1139 list2expr (sym->ival));
1142 setAstLineno (work, sym->lineDef);
1146 staticAutos = newNode (NULLOP, staticAutos, work);
1153 /* if there is an initial value */
1154 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1156 initList *ilist=sym->ival;
1158 while (ilist->type == INIT_DEEP) {
1159 ilist = ilist->init.deep;
1162 /* update lineno for error msg */
1163 lineno=sym->lineDef;
1164 setAstLineno (ilist->init.node, lineno);
1166 if (IS_AGGREGATE (sym->type)) {
1167 work = initAggregates (sym, sym->ival, NULL);
1169 if (getNelements(sym->type, sym->ival)>1) {
1170 werrorfl (filename, sym->lineDef,
1171 W_EXCESS_INITIALIZERS, "scalar",
1174 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1175 list2expr (sym->ival));
1179 setAstLineno (work, sym->lineDef);
1183 init = newNode (NULLOP, init, work);
1192 /*-----------------------------------------------------------------*/
1193 /* freeStringSymbol - delete a literal string if no more usage */
1194 /*-----------------------------------------------------------------*/
1195 void freeStringSymbol(symbol *sym) {
1196 /* make sure this is a literal string */
1197 assert (sym->isstrlit);
1198 if (--sym->isstrlit == 0) { // lower the usage count
1199 memmap *segment=SPEC_OCLS(sym->etype);
1201 deleteSetItem(&segment->syms, sym);
1206 /*-----------------------------------------------------------------*/
1207 /* stringToSymbol - creates a symbol from a literal string */
1208 /*-----------------------------------------------------------------*/
1210 stringToSymbol (value * val)
1212 char name[SDCC_NAME_MAX + 1];
1213 static int charLbl = 0;
1218 // have we heard this before?
1219 for (sp=statsg->syms; sp; sp=sp->next) {
1221 size = getSize (sym->type);
1222 if (sym->isstrlit && size == getSize (val->type) &&
1223 !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1224 // yes, this is old news. Don't publish it again.
1225 sym->isstrlit++; // but raise the usage count
1226 return symbolVal(sym);
1230 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1231 sym = newSymbol (name, 0); /* make it @ level 0 */
1232 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1234 /* copy the type from the value passed */
1235 sym->type = copyLinkChain (val->type);
1236 sym->etype = getSpec (sym->type);
1237 /* change to storage class & output class */
1238 SPEC_SCLS (sym->etype) = S_CODE;
1239 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1240 SPEC_STAT (sym->etype) = 1;
1241 /* make the level & block = 0 */
1242 sym->block = sym->level = 0;
1244 /* create an ival */
1245 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1250 allocVariables (sym);
1253 return symbolVal (sym);
1257 /*-----------------------------------------------------------------*/
1258 /* processBlockVars - will go thru the ast looking for block if */
1259 /* a block is found then will allocate the syms */
1260 /* will also gather the auto inits present */
1261 /*-----------------------------------------------------------------*/
1263 processBlockVars (ast * tree, int *stack, int action)
1268 /* if this is a block */
1269 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1273 if (action == ALLOCATE)
1275 *stack += allocVariables (tree->values.sym);
1276 autoInit = gatherAutoInit (tree->values.sym);
1278 /* if there are auto inits then do them */
1280 tree->left = newNode (NULLOP, autoInit, tree->left);
1282 else /* action is deallocate */
1283 deallocLocal (tree->values.sym);
1286 processBlockVars (tree->left, stack, action);
1287 processBlockVars (tree->right, stack, action);
1292 /*-------------------------------------------------------------*/
1293 /* constExprTree - returns TRUE if this tree is a constant */
1295 /*-------------------------------------------------------------*/
1296 bool constExprTree (ast *cexpr) {
1302 cexpr = decorateType (resolveSymbols (cexpr), RESULT_CHECK);
1304 switch (cexpr->type)
1307 if (IS_AST_LIT_VALUE(cexpr)) {
1308 // this is a literal
1311 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1312 // a function's address will never change
1315 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1316 // an array's address will never change
1319 if (IS_AST_SYM_VALUE(cexpr) &&
1320 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1321 // a symbol in code space will never change
1322 // This is only for the 'char *s="hallo"' case and will have to leave
1323 //printf(" code space symbol");
1328 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1329 "unexpected link in expression tree\n");
1332 if (cexpr->opval.op==ARRAYINIT) {
1333 // this is a list of literals
1336 if (cexpr->opval.op=='=') {
1337 return constExprTree(cexpr->right);
1339 if (cexpr->opval.op==CAST) {
1340 // cast ignored, maybe we should throw a warning here?
1341 return constExprTree(cexpr->right);
1343 if (cexpr->opval.op=='&') {
1346 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1349 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1354 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1359 /*-----------------------------------------------------------------*/
1360 /* constExprValue - returns the value of a constant expression */
1361 /* or NULL if it is not a constant expression */
1362 /*-----------------------------------------------------------------*/
1364 constExprValue (ast * cexpr, int check)
1366 cexpr = decorateType (resolveSymbols (cexpr), RESULT_CHECK);
1368 /* if this is not a constant then */
1369 if (!IS_LITERAL (cexpr->ftype))
1371 /* then check if this is a literal array
1373 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1374 SPEC_CVAL (cexpr->etype).v_char &&
1375 IS_ARRAY (cexpr->ftype))
1377 value *val = valFromType (cexpr->ftype);
1378 SPEC_SCLS (val->etype) = S_LITERAL;
1379 val->sym = cexpr->opval.val->sym;
1380 val->sym->type = copyLinkChain (cexpr->ftype);
1381 val->sym->etype = getSpec (val->sym->type);
1382 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1386 /* if we are casting a literal value then */
1387 if (IS_AST_OP (cexpr) &&
1388 cexpr->opval.op == CAST &&
1389 IS_LITERAL (cexpr->right->ftype))
1391 return valCastLiteral (cexpr->ftype,
1392 floatFromVal (cexpr->right->opval.val));
1395 if (IS_AST_VALUE (cexpr))
1397 return cexpr->opval.val;
1401 werror (E_CONST_EXPECTED, "found expression");
1406 /* return the value */
1407 return cexpr->opval.val;
1411 /*-----------------------------------------------------------------*/
1412 /* isLabelInAst - will return true if a given label is found */
1413 /*-----------------------------------------------------------------*/
1415 isLabelInAst (symbol * label, ast * tree)
1417 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1420 if (IS_AST_OP (tree) &&
1421 tree->opval.op == LABEL &&
1422 isSymbolEqual (AST_SYMBOL (tree->left), label))
1425 return isLabelInAst (label, tree->right) &&
1426 isLabelInAst (label, tree->left);
1430 /*-----------------------------------------------------------------*/
1431 /* isLoopCountable - return true if the loop count can be determi- */
1432 /* -ned at compile time . */
1433 /*-----------------------------------------------------------------*/
1435 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1436 symbol ** sym, ast ** init, ast ** end)
1439 /* the loop is considered countable if the following
1440 conditions are true :-
1442 a) initExpr :- <sym> = <const>
1443 b) condExpr :- <sym> < <const1>
1444 c) loopExpr :- <sym> ++
1447 /* first check the initExpr */
1448 if (IS_AST_OP (initExpr) &&
1449 initExpr->opval.op == '=' && /* is assignment */
1450 IS_AST_SYM_VALUE (initExpr->left))
1451 { /* left is a symbol */
1453 *sym = AST_SYMBOL (initExpr->left);
1454 *init = initExpr->right;
1459 /* for now the symbol has to be of
1461 if (!IS_INTEGRAL ((*sym)->type))
1464 /* now check condExpr */
1465 if (IS_AST_OP (condExpr))
1468 switch (condExpr->opval.op)
1471 if (IS_AST_SYM_VALUE (condExpr->left) &&
1472 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1473 IS_AST_LIT_VALUE (condExpr->right))
1475 *end = condExpr->right;
1481 if (IS_AST_OP (condExpr->left) &&
1482 condExpr->left->opval.op == '>' &&
1483 IS_AST_LIT_VALUE (condExpr->left->right) &&
1484 IS_AST_SYM_VALUE (condExpr->left->left) &&
1485 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1488 *end = newNode ('+', condExpr->left->right,
1489 newAst_VALUE (constVal ("1")));
1500 /* check loop expression is of the form <sym>++ */
1501 if (!IS_AST_OP (loopExpr))
1504 /* check if <sym> ++ */
1505 if (loopExpr->opval.op == INC_OP)
1511 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1512 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1519 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1520 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1528 if (loopExpr->opval.op == ADD_ASSIGN)
1531 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1532 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1533 IS_AST_LIT_VALUE (loopExpr->right) &&
1534 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1542 /*-----------------------------------------------------------------*/
1543 /* astHasVolatile - returns true if ast contains any volatile */
1544 /*-----------------------------------------------------------------*/
1546 astHasVolatile (ast * tree)
1551 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1554 if (IS_AST_OP (tree))
1555 return astHasVolatile (tree->left) ||
1556 astHasVolatile (tree->right);
1561 /*-----------------------------------------------------------------*/
1562 /* astHasPointer - return true if the ast contains any ptr variable */
1563 /*-----------------------------------------------------------------*/
1565 astHasPointer (ast * tree)
1570 if (IS_AST_LINK (tree))
1573 /* if we hit an array expression then check
1574 only the left side */
1575 if (IS_AST_OP (tree) && tree->opval.op == '[')
1576 return astHasPointer (tree->left);
1578 if (IS_AST_VALUE (tree))
1579 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1581 return astHasPointer (tree->left) ||
1582 astHasPointer (tree->right);
1586 /*-----------------------------------------------------------------*/
1587 /* astHasSymbol - return true if the ast has the given symbol */
1588 /*-----------------------------------------------------------------*/
1590 astHasSymbol (ast * tree, symbol * sym)
1592 if (!tree || IS_AST_LINK (tree))
1595 if (IS_AST_VALUE (tree))
1597 if (IS_AST_SYM_VALUE (tree))
1598 return isSymbolEqual (AST_SYMBOL (tree), sym);
1603 return astHasSymbol (tree->left, sym) ||
1604 astHasSymbol (tree->right, sym);
1607 /*-----------------------------------------------------------------*/
1608 /* astHasDeref - return true if the ast has an indirect access */
1609 /*-----------------------------------------------------------------*/
1611 astHasDeref (ast * tree)
1613 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1616 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1618 return astHasDeref (tree->left) || astHasDeref (tree->right);
1621 /*-----------------------------------------------------------------*/
1622 /* isConformingBody - the loop body has to conform to a set of rules */
1623 /* for the loop to be considered reversible read on for rules */
1624 /*-----------------------------------------------------------------*/
1626 isConformingBody (ast * pbody, symbol * sym, ast * body)
1629 /* we are going to do a pre-order traversal of the
1630 tree && check for the following conditions. (essentially
1631 a set of very shallow tests )
1632 a) the sym passed does not participate in
1633 any arithmetic operation
1634 b) There are no function calls
1635 c) all jumps are within the body
1636 d) address of loop control variable not taken
1637 e) if an assignment has a pointer on the
1638 left hand side make sure right does not have
1639 loop control variable */
1641 /* if we reach the end or a leaf then true */
1642 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1645 /* if anything else is "volatile" */
1646 if (IS_VOLATILE (TETYPE (pbody)))
1649 /* we will walk the body in a pre-order traversal for
1651 switch (pbody->opval.op)
1653 /*------------------------------------------------------------------*/
1655 // if the loopvar is used as an index
1656 if (astHasSymbol(pbody->right, sym)) {
1659 return isConformingBody (pbody->right, sym, body);
1661 /*------------------------------------------------------------------*/
1666 /*------------------------------------------------------------------*/
1670 /* sure we are not sym is not modified */
1672 IS_AST_SYM_VALUE (pbody->left) &&
1673 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1677 IS_AST_SYM_VALUE (pbody->right) &&
1678 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1683 /*------------------------------------------------------------------*/
1685 case '*': /* can be unary : if right is null then unary operation */
1690 /* if right is NULL then unary operation */
1691 /*------------------------------------------------------------------*/
1692 /*----------------------------*/
1694 /*----------------------------*/
1697 if (IS_AST_SYM_VALUE (pbody->left) &&
1698 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1701 return isConformingBody (pbody->left, sym, body);
1705 if (astHasSymbol (pbody->left, sym) ||
1706 astHasSymbol (pbody->right, sym))
1711 /*------------------------------------------------------------------*/
1719 if (IS_AST_SYM_VALUE (pbody->left) &&
1720 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1723 if (IS_AST_SYM_VALUE (pbody->right) &&
1724 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1727 return isConformingBody (pbody->left, sym, body) &&
1728 isConformingBody (pbody->right, sym, body);
1736 if (IS_AST_SYM_VALUE (pbody->left) &&
1737 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1739 return isConformingBody (pbody->left, sym, body);
1741 /*------------------------------------------------------------------*/
1753 case SIZEOF: /* evaluate wihout code generation */
1755 if (IS_AST_SYM_VALUE (pbody->left) &&
1756 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1759 if (IS_AST_SYM_VALUE (pbody->right) &&
1760 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1763 return isConformingBody (pbody->left, sym, body) &&
1764 isConformingBody (pbody->right, sym, body);
1766 /*------------------------------------------------------------------*/
1769 /* if left has a pointer & right has loop
1770 control variable then we cannot */
1771 if (astHasPointer (pbody->left) &&
1772 astHasSymbol (pbody->right, sym))
1774 if (astHasVolatile (pbody->left))
1777 if (IS_AST_SYM_VALUE (pbody->left)) {
1778 // if the loopvar has an assignment
1779 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1781 // if the loopvar is used in another (maybe conditional) block
1782 if (astHasSymbol (pbody->right, sym) &&
1783 (pbody->level >= body->level)) {
1788 if (astHasVolatile (pbody->left))
1791 if (astHasDeref(pbody->right)) return FALSE;
1793 return isConformingBody (pbody->left, sym, body) &&
1794 isConformingBody (pbody->right, sym, body);
1805 assert ("Parser should not have generated this\n");
1807 /*------------------------------------------------------------------*/
1808 /*----------------------------*/
1809 /* comma operator */
1810 /*----------------------------*/
1812 return isConformingBody (pbody->left, sym, body) &&
1813 isConformingBody (pbody->right, sym, body);
1815 /*------------------------------------------------------------------*/
1816 /*----------------------------*/
1818 /*----------------------------*/
1820 /* if local & not passed as paramater then ok */
1821 if (sym->level && !astHasSymbol(pbody->right,sym))
1825 /*------------------------------------------------------------------*/
1826 /*----------------------------*/
1827 /* return statement */
1828 /*----------------------------*/
1833 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1838 if (astHasSymbol (pbody->left, sym))
1845 return isConformingBody (pbody->left, sym, body) &&
1846 isConformingBody (pbody->right, sym, body);
1852 /*-----------------------------------------------------------------*/
1853 /* isLoopReversible - takes a for loop as input && returns true */
1854 /* if the for loop is reversible. If yes will set the value of */
1855 /* the loop control var & init value & termination value */
1856 /*-----------------------------------------------------------------*/
1858 isLoopReversible (ast * loop, symbol ** loopCntrl,
1859 ast ** init, ast ** end)
1861 /* if option says don't do it then don't */
1862 if (optimize.noLoopReverse)
1864 /* there are several tests to determine this */
1866 /* for loop has to be of the form
1867 for ( <sym> = <const1> ;
1868 [<sym> < <const2>] ;
1869 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1871 if (!isLoopCountable (AST_FOR (loop, initExpr),
1872 AST_FOR (loop, condExpr),
1873 AST_FOR (loop, loopExpr),
1874 loopCntrl, init, end))
1877 /* now do some serious checking on the body of the loop
1880 return isConformingBody (loop->left, *loopCntrl, loop->left);
1884 /*-----------------------------------------------------------------*/
1885 /* replLoopSym - replace the loop sym by loop sym -1 */
1886 /*-----------------------------------------------------------------*/
1888 replLoopSym (ast * body, symbol * sym)
1891 if (!body || IS_AST_LINK (body))
1894 if (IS_AST_SYM_VALUE (body))
1897 if (isSymbolEqual (AST_SYMBOL (body), sym))
1901 body->opval.op = '-';
1902 body->left = newAst_VALUE (symbolVal (sym));
1903 body->right = newAst_VALUE (constVal ("1"));
1911 replLoopSym (body->left, sym);
1912 replLoopSym (body->right, sym);
1916 /*-----------------------------------------------------------------*/
1917 /* reverseLoop - do the actual loop reversal */
1918 /*-----------------------------------------------------------------*/
1920 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1924 /* create the following tree
1929 if (sym) goto for_continue ;
1932 /* put it together piece by piece */
1933 rloop = newNode (NULLOP,
1934 createIf (newAst_VALUE (symbolVal (sym)),
1936 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1939 newAst_VALUE (symbolVal (sym)),
1942 replLoopSym (loop->left, sym);
1943 setAstLineno (rloop, init->lineno);
1945 rloop = newNode (NULLOP,
1947 newAst_VALUE (symbolVal (sym)),
1948 newNode ('-', end, init)),
1949 createLabel (AST_FOR (loop, continueLabel),
1953 newNode (SUB_ASSIGN,
1954 newAst_VALUE (symbolVal (sym)),
1955 newAst_VALUE (constVal ("1"))),
1958 rloop->lineno=init->lineno;
1959 return decorateType (rloop, RESULT_CHECK);
1963 /*-----------------------------------------------------------------*/
1964 /* searchLitOp - search tree (*ops only) for an ast with literal */
1965 /*-----------------------------------------------------------------*/
1967 searchLitOp (ast *tree, ast **parent, const char *ops)
1971 if (tree && optimize.global_cse)
1973 /* is there a literal operand? */
1975 IS_AST_OP(tree->right) &&
1976 tree->right->right &&
1977 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
1979 if (IS_LITERAL (RTYPE (tree->right)) ^
1980 IS_LITERAL (LTYPE (tree->right)))
1982 tree->right->decorated = 0;
1983 tree->decorated = 0;
1987 ret = searchLitOp (tree->right, parent, ops);
1992 IS_AST_OP(tree->left) &&
1993 tree->left->right &&
1994 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
1996 if (IS_LITERAL (RTYPE (tree->left)) ^
1997 IS_LITERAL (LTYPE (tree->left)))
1999 tree->left->decorated = 0;
2000 tree->decorated = 0;
2004 ret = searchLitOp (tree->left, parent, ops);
2012 /*-----------------------------------------------------------------*/
2013 /* getResultFromType */
2014 /*-----------------------------------------------------------------*/
2016 getResultTypeFromType (sym_link *type)
2018 /* type = getSpec (type); */
2019 if (IS_BITVAR (type))
2020 return RESULT_TYPE_BIT;
2021 if (IS_BITFIELD (type))
2022 return RESULT_TYPE_CHAR;
2024 return RESULT_TYPE_CHAR;
2027 return RESULT_TYPE_INT;
2028 return RESULT_TYPE_OTHER;
2031 /*-----------------------------------------------------------------*/
2032 /* addCast - adds casts to a type specified by RESULT_TYPE */
2033 /*-----------------------------------------------------------------*/
2035 addCast (ast *tree, RESULT_TYPE resultType, bool upcast)
2038 bool upCasted = FALSE;
2042 case RESULT_TYPE_NONE:
2043 /* char: promote to int */
2045 getSize (tree->etype) >= INTSIZE)
2047 newLink = newIntLink();
2050 case RESULT_TYPE_CHAR:
2051 if (getSize (tree->etype) <= 1)
2053 newLink = newCharLink();
2055 case RESULT_TYPE_INT:
2057 if (getSize (tree->etype) > INTSIZE)
2059 /* warn ("Loosing significant digits"); */
2063 /* char: promote to int */
2065 getSize (tree->etype) >= INTSIZE)
2067 newLink = newIntLink();
2070 case RESULT_TYPE_OTHER:
2073 /* return type is long, float: promote char to int */
2074 if (getSize (tree->etype) >= INTSIZE)
2076 newLink = newIntLink();
2082 tree->decorated = 0;
2083 tree = newNode (CAST, newAst_LINK (newLink), tree);
2084 /* keep unsigned type during cast to smaller type,
2085 but not when promoting from char to int */
2087 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2088 return decorateType (tree, resultType);
2091 /*-----------------------------------------------------------------*/
2092 /* resultTypePropagate - decides if resultType can be propagated */
2093 /*-----------------------------------------------------------------*/
2095 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2097 switch (tree->opval.op)
2108 return RESULT_TYPE_NONE;
2112 return RESULT_TYPE_NONE;
2116 /*-----------------------------------------------------------------*/
2117 /* getLeftResultType - gets type from left branch for propagation */
2118 /*-----------------------------------------------------------------*/
2120 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2122 switch (tree->opval.op)
2126 if (IS_PTR (LTYPE (tree)))
2127 return RESULT_TYPE_NONE;
2129 return getResultTypeFromType (LETYPE (tree));
2131 if (IS_PTR (currFunc->type->next))
2132 return RESULT_TYPE_NONE;
2134 return getResultTypeFromType (currFunc->type->next);
2136 if (!IS_ARRAY (LTYPE (tree)))
2138 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256)
2139 return RESULT_TYPE_CHAR;
2146 /*--------------------------------------------------------------------*/
2147 /* decorateType - compute type for this tree, also does type checking.*/
2148 /* This is done bottom up, since type has to flow upwards. */
2149 /* resultType flows top-down and forces e.g. char-arithmetik, if the */
2150 /* result is a char and the operand(s) are int's. */
2151 /* It also does constant folding, and parameter checking. */
2152 /*--------------------------------------------------------------------*/
2154 decorateType (ast * tree, RESULT_TYPE resultType)
2158 RESULT_TYPE resultTypeProp;
2163 /* if already has type then do nothing */
2164 if (tree->decorated)
2167 tree->decorated = 1;
2170 /* print the line */
2171 /* if not block & function */
2172 if (tree->type == EX_OP &&
2173 (tree->opval.op != FUNCTION &&
2174 tree->opval.op != BLOCK &&
2175 tree->opval.op != NULLOP))
2177 filename = tree->filename;
2178 lineno = tree->lineno;
2182 /* if any child is an error | this one is an error do nothing */
2183 if (tree->isError ||
2184 (tree->left && tree->left->isError) ||
2185 (tree->right && tree->right->isError))
2188 /*------------------------------------------------------------------*/
2189 /*----------------------------*/
2190 /* leaf has been reached */
2191 /*----------------------------*/
2192 lineno=tree->lineno;
2193 /* if this is of type value */
2194 /* just get the type */
2195 if (tree->type == EX_VALUE)
2198 if (IS_LITERAL (tree->opval.val->etype))
2201 /* if this is a character array then declare it */
2202 if (IS_ARRAY (tree->opval.val->type))
2203 tree->opval.val = stringToSymbol (tree->opval.val);
2205 /* otherwise just copy the type information */
2206 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2210 if (tree->opval.val->sym)
2212 /* if the undefined flag is set then give error message */
2213 if (tree->opval.val->sym->undefined)
2215 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2217 TTYPE (tree) = TETYPE (tree) =
2218 tree->opval.val->type = tree->opval.val->sym->type =
2219 tree->opval.val->etype = tree->opval.val->sym->etype =
2220 copyLinkChain (INTTYPE);
2225 /* if impilicit i.e. struct/union member then no type */
2226 if (tree->opval.val->sym->implicit)
2227 TTYPE (tree) = TETYPE (tree) = NULL;
2232 /* else copy the type */
2233 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2235 /* and mark it as referenced */
2236 tree->opval.val->sym->isref = 1;
2244 /* if type link for the case of cast */
2245 if (tree->type == EX_LINK)
2247 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2255 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2257 if (tree->left && tree->left->type == EX_OPERAND
2258 && (tree->left->opval.op == INC_OP
2259 || tree->left->opval.op == DEC_OP)
2260 && tree->left->left)
2262 tree->left->right = tree->left->left;
2263 tree->left->left = NULL;
2265 if (tree->right && tree->right->type == EX_OPERAND
2266 && (tree->right->opval.op == INC_OP
2267 || tree->right->opval.op == DEC_OP)
2268 && tree->right->left)
2270 tree->right->right = tree->right->left;
2271 tree->right->left = NULL;
2276 /* Before decorating the left branch we've to decide in dependence
2277 upon tree->opval.op, if resultType can be propagated */
2278 resultTypeProp = resultTypePropagate (tree, resultType);
2280 dtl = decorateType (tree->left, resultTypeProp);
2282 /* if an array node, we may need to swap branches */
2283 if (tree->opval.op == '[')
2285 /* determine which is the array & which the index */
2286 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2287 IS_INTEGRAL (LTYPE (tree)))
2289 ast *tempTree = tree->left;
2290 tree->left = tree->right;
2291 tree->right = tempTree;
2295 /* After decorating the left branch there's type information available
2296 in tree->left->?type. If the op is e.g. '=' we extract the type
2297 information from there and propagate it to the right branch. */
2298 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2300 switch (tree->opval.op)
2303 /* delay right side for '?' operator since conditional macro
2304 expansions might rely on this */
2308 /* decorate right side for CALL (parameter list) in processParms();
2309 there is resultType available */
2313 dtr = decorateType (tree->right, resultTypeProp);
2317 /* this is to take care of situations
2318 when the tree gets rewritten */
2319 if (dtl != tree->left)
2321 if (dtr != tree->right)
2323 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2327 /* depending on type of operator do */
2329 switch (tree->opval.op)
2331 /*------------------------------------------------------------------*/
2332 /*----------------------------*/
2334 /*----------------------------*/
2337 /* first check if this is a array or a pointer */
2338 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2340 werror (E_NEED_ARRAY_PTR, "[]");
2341 goto errorTreeReturn;
2344 /* check if the type of the idx */
2345 if (!IS_INTEGRAL (RTYPE (tree)))
2347 werror (E_IDX_NOT_INT);
2348 goto errorTreeReturn;
2351 /* if the left is an rvalue then error */
2354 werror (E_LVALUE_REQUIRED, "array access");
2355 goto errorTreeReturn;
2358 if (IS_LITERAL (RTYPE (tree)))
2360 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2361 int arraySize = DCL_ELEM (LTYPE (tree));
2362 if (arraySize && arrayIndex >= arraySize)
2364 werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2369 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2372 /*------------------------------------------------------------------*/
2373 /*----------------------------*/
2375 /*----------------------------*/
2377 /* if this is not a structure */
2378 if (!IS_STRUCT (LTYPE (tree)))
2380 werror (E_STRUCT_UNION, ".");
2381 goto errorTreeReturn;
2383 TTYPE (tree) = structElemType (LTYPE (tree),
2384 (tree->right->type == EX_VALUE ?
2385 tree->right->opval.val : NULL));
2386 TETYPE (tree) = getSpec (TTYPE (tree));
2389 /*------------------------------------------------------------------*/
2390 /*----------------------------*/
2391 /* struct/union pointer */
2392 /*----------------------------*/
2394 /* if not pointer to a structure */
2395 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2397 werror (E_PTR_REQD);
2398 goto errorTreeReturn;
2401 if (!IS_STRUCT (LTYPE (tree)->next))
2403 werror (E_STRUCT_UNION, "->");
2404 goto errorTreeReturn;
2407 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2408 (tree->right->type == EX_VALUE ?
2409 tree->right->opval.val : NULL));
2410 TETYPE (tree) = getSpec (TTYPE (tree));
2412 /* adjust the storage class */
2413 switch (DCL_TYPE(tree->left->ftype)) {
2415 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2418 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2421 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2424 SPEC_SCLS (TETYPE (tree)) = 0;
2427 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2430 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2433 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2436 SPEC_SCLS (TETYPE (tree)) = 0;
2443 /* This breaks with extern declarations, bitfields, and perhaps other */
2444 /* cases (gcse). Let's leave this optimization disabled for now and */
2445 /* ponder if there's a safe way to do this. -- EEP */
2447 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2448 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2450 /* If defined struct type at addr var
2451 then rewrite (&struct var)->member
2453 and define membertype at (addr+offsetof(struct var,member)) temp
2456 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2457 AST_SYMBOL(tree->right));
2459 sym = newSymbol(genSymName (0), 0);
2460 sym->type = TTYPE (tree);
2461 sym->etype = getSpec(sym->type);
2462 sym->lineDef = tree->lineno;
2465 SPEC_STAT (sym->etype) = 1;
2466 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2468 SPEC_ABSA(sym->etype) = 1;
2469 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2472 AST_VALUE (tree) = symbolVal(sym);
2475 tree->type = EX_VALUE;
2483 /*------------------------------------------------------------------*/
2484 /*----------------------------*/
2485 /* ++/-- operation */
2486 /*----------------------------*/
2490 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2491 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2492 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2493 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2502 /*------------------------------------------------------------------*/
2503 /*----------------------------*/
2505 /*----------------------------*/
2506 case '&': /* can be unary */
2507 /* if right is NULL then unary operation */
2508 if (tree->right) /* not an unary operation */
2511 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2513 werror (E_BITWISE_OP);
2514 werror (W_CONTINUE, "left & right types are ");
2515 printTypeChain (LTYPE (tree), stderr);
2516 fprintf (stderr, ",");
2517 printTypeChain (RTYPE (tree), stderr);
2518 fprintf (stderr, "\n");
2519 goto errorTreeReturn;
2522 /* if they are both literal */
2523 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2525 tree->type = EX_VALUE;
2526 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2527 valFromType (RETYPE (tree)), '&');
2529 tree->right = tree->left = NULL;
2530 TETYPE (tree) = tree->opval.val->etype;
2531 TTYPE (tree) = tree->opval.val->type;
2535 /* see if this is a GETHBIT operation if yes
2538 ast *otree = optimizeGetHbit (tree);
2541 return decorateType (otree, RESULT_CHECK);
2544 tree->left = addCast (tree->left, resultType, FALSE);
2545 tree->right = addCast (tree->right, resultType, FALSE);
2546 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
2547 TETYPE (tree) = getSpec (TTYPE (tree));
2549 /* if left is a literal exchange left & right */
2550 if (IS_LITERAL (LTYPE (tree)))
2552 ast *tTree = tree->left;
2553 tree->left = tree->right;
2554 tree->right = tTree;
2557 /* if right is a literal and */
2558 /* we can find a 2nd literal in a and-tree then */
2559 /* rearrange the tree */
2560 if (IS_LITERAL (RTYPE (tree)))
2563 ast *litTree = searchLitOp (tree, &parent, "&");
2566 ast *tTree = litTree->left;
2567 litTree->left = tree->right;
2568 tree->right = tTree;
2569 /* both operands in tTree are literal now */
2570 decorateType (parent, RESULT_CHECK);
2574 LRVAL (tree) = RRVAL (tree) = 1;
2579 /*------------------------------------------------------------------*/
2580 /*----------------------------*/
2582 /*----------------------------*/
2583 p = newLink (DECLARATOR);
2584 /* if bit field then error */
2585 if (IS_BITVAR (tree->left->etype))
2587 werror (E_ILLEGAL_ADDR, "address of bit variable");
2588 goto errorTreeReturn;
2591 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2593 werror (E_ILLEGAL_ADDR, "address of register variable");
2594 goto errorTreeReturn;
2597 if (IS_FUNC (LTYPE (tree)))
2599 // this ought to be ignored
2600 return (tree->left);
2603 if (IS_LITERAL(LTYPE(tree)))
2605 werror (E_ILLEGAL_ADDR, "address of literal");
2606 goto errorTreeReturn;
2611 werror (E_LVALUE_REQUIRED, "address of");
2612 goto errorTreeReturn;
2615 DCL_TYPE (p) = POINTER;
2616 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2617 DCL_TYPE (p) = CPOINTER;
2618 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2619 DCL_TYPE (p) = FPOINTER;
2620 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2621 DCL_TYPE (p) = PPOINTER;
2622 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2623 DCL_TYPE (p) = IPOINTER;
2624 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2625 DCL_TYPE (p) = EEPPOINTER;
2626 else if (SPEC_OCLS(tree->left->etype))
2627 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2629 DCL_TYPE (p) = POINTER;
2631 if (IS_AST_SYM_VALUE (tree->left))
2633 AST_SYMBOL (tree->left)->addrtaken = 1;
2634 AST_SYMBOL (tree->left)->allocreq = 1;
2637 p->next = LTYPE (tree);
2639 TETYPE (tree) = getSpec (TTYPE (tree));
2644 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2645 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2647 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2648 AST_SYMBOL(tree->left->right));
2649 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2650 valueFromLit(element->offset));
2653 tree->type = EX_VALUE;
2654 tree->values.literalFromCast = 1;
2660 /*------------------------------------------------------------------*/
2661 /*----------------------------*/
2663 /*----------------------------*/
2665 /* if the rewrite succeeds then don't go any furthur */
2667 ast *wtree = optimizeRRCRLC (tree);
2669 return decorateType (wtree, RESULT_CHECK);
2671 wtree = optimizeSWAP (tree);
2673 return decorateType (wtree, RESULT_CHECK);
2676 /* if left is a literal exchange left & right */
2677 if (IS_LITERAL (LTYPE (tree)))
2679 ast *tTree = tree->left;
2680 tree->left = tree->right;
2681 tree->right = tTree;
2684 /* if right is a literal and */
2685 /* we can find a 2nd literal in a or-tree then */
2686 /* rearrange the tree */
2687 if (IS_LITERAL (RTYPE (tree)))
2690 ast *litTree = searchLitOp (tree, &parent, "|");
2693 ast *tTree = litTree->left;
2694 litTree->left = tree->right;
2695 tree->right = tTree;
2696 /* both operands in tTree are literal now */
2697 decorateType (parent, RESULT_CHECK);
2702 /*------------------------------------------------------------------*/
2703 /*----------------------------*/
2705 /*----------------------------*/
2707 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2709 werror (E_BITWISE_OP);
2710 werror (W_CONTINUE, "left & right types are ");
2711 printTypeChain (LTYPE (tree), stderr);
2712 fprintf (stderr, ",");
2713 printTypeChain (RTYPE (tree), stderr);
2714 fprintf (stderr, "\n");
2715 goto errorTreeReturn;
2718 /* if they are both literal then */
2719 /* rewrite the tree */
2720 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2722 tree->type = EX_VALUE;
2723 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2724 valFromType (RETYPE (tree)),
2726 tree->right = tree->left = NULL;
2727 TETYPE (tree) = tree->opval.val->etype;
2728 TTYPE (tree) = tree->opval.val->type;
2732 /* if left is a literal exchange left & right */
2733 if (IS_LITERAL (LTYPE (tree)))
2735 ast *tTree = tree->left;
2736 tree->left = tree->right;
2737 tree->right = tTree;
2740 /* if right is a literal and */
2741 /* we can find a 2nd literal in a xor-tree then */
2742 /* rearrange the tree */
2743 if (IS_LITERAL (RTYPE (tree)) &&
2744 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2747 ast *litTree = searchLitOp (tree, &parent, "^");
2750 ast *tTree = litTree->left;
2751 litTree->left = tree->right;
2752 tree->right = tTree;
2753 /* both operands in litTree are literal now */
2754 decorateType (parent, RESULT_CHECK);
2758 LRVAL (tree) = RRVAL (tree) = 1;
2759 tree->left = addCast (tree->left, resultType, FALSE);
2760 tree->right = addCast (tree->right, resultType, FALSE);
2761 TETYPE (tree) = getSpec (TTYPE (tree) =
2762 computeType (LTYPE (tree),
2768 /*------------------------------------------------------------------*/
2769 /*----------------------------*/
2771 /*----------------------------*/
2773 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2775 werror (E_INVALID_OP, "divide");
2776 goto errorTreeReturn;
2778 /* if they are both literal then */
2779 /* rewrite the tree */
2780 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2782 tree->type = EX_VALUE;
2783 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2784 valFromType (RETYPE (tree)));
2785 tree->right = tree->left = NULL;
2786 TETYPE (tree) = getSpec (TTYPE (tree) =
2787 tree->opval.val->type);
2791 LRVAL (tree) = RRVAL (tree) = 1;
2792 TETYPE (tree) = getSpec (TTYPE (tree) =
2793 computeType (LTYPE (tree),
2795 ! (IS_UNSIGNED (LTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)))));
2797 /* if right is a literal and */
2798 /* left is also a division by a literal then */
2799 /* rearrange the tree */
2800 if (IS_LITERAL (RTYPE (tree))
2801 /* avoid infinite loop */
2802 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2805 ast *litTree = searchLitOp (tree, &parent, "/");
2808 if (IS_LITERAL (RTYPE (litTree)))
2811 litTree->right = newNode ('*', litTree->right, tree->right);
2812 litTree->right->lineno = tree->lineno;
2814 tree->right->opval.val = constVal ("1");
2815 decorateType (parent, RESULT_CHECK);
2819 /* litTree->left is literal: no gcse possible.
2820 We can't call decorateType(parent, RESULT_CHECK), because
2821 this would cause an infinit loop. */
2822 parent->decorated = 1;
2823 decorateType (litTree, RESULT_CHECK);
2830 /*------------------------------------------------------------------*/
2831 /*----------------------------*/
2833 /*----------------------------*/
2835 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2837 werror (E_BITWISE_OP);
2838 werror (W_CONTINUE, "left & right types are ");
2839 printTypeChain (LTYPE (tree), stderr);
2840 fprintf (stderr, ",");
2841 printTypeChain (RTYPE (tree), stderr);
2842 fprintf (stderr, "\n");
2843 goto errorTreeReturn;
2845 /* if they are both literal then */
2846 /* rewrite the tree */
2847 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2849 tree->type = EX_VALUE;
2850 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2851 valFromType (RETYPE (tree)));
2852 tree->right = tree->left = NULL;
2853 TETYPE (tree) = getSpec (TTYPE (tree) =
2854 tree->opval.val->type);
2857 LRVAL (tree) = RRVAL (tree) = 1;
2858 TETYPE (tree) = getSpec (TTYPE (tree) =
2859 computeType (LTYPE (tree),
2861 ! (IS_UNSIGNED (LTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)))));
2864 /*------------------------------------------------------------------*/
2865 /*----------------------------*/
2866 /* address dereference */
2867 /*----------------------------*/
2868 case '*': /* can be unary : if right is null then unary operation */
2871 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2873 werror (E_PTR_REQD);
2874 goto errorTreeReturn;
2879 werror (E_LVALUE_REQUIRED, "pointer deref");
2880 goto errorTreeReturn;
2882 if (IS_ADDRESS_OF_OP(tree->left))
2884 /* replace *&obj with obj */
2885 return tree->left->left;
2887 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2888 TETYPE (tree) = getSpec (TTYPE (tree));
2889 /* adjust the storage class */
2890 switch (DCL_TYPE(tree->left->ftype)) {
2892 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2895 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2898 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2901 SPEC_SCLS (TETYPE (tree)) = 0;
2904 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2907 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2910 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2913 SPEC_SCLS (TETYPE (tree)) = 0;
2922 /*------------------------------------------------------------------*/
2923 /*----------------------------*/
2924 /* multiplication */
2925 /*----------------------------*/
2926 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2928 werror (E_INVALID_OP, "multiplication");
2929 goto errorTreeReturn;
2932 /* if they are both literal then */
2933 /* rewrite the tree */
2934 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2936 tree->type = EX_VALUE;
2937 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2938 valFromType (RETYPE (tree)));
2939 tree->right = tree->left = NULL;
2940 TETYPE (tree) = getSpec (TTYPE (tree) =
2941 tree->opval.val->type);
2945 /* if left is a literal exchange left & right */
2946 if (IS_LITERAL (LTYPE (tree)))
2948 ast *tTree = tree->left;
2949 tree->left = tree->right;
2950 tree->right = tTree;
2953 /* if right is a literal and */
2954 /* we can find a 2nd literal in a mul-tree then */
2955 /* rearrange the tree */
2956 if (IS_LITERAL (RTYPE (tree)))
2959 ast *litTree = searchLitOp (tree, &parent, "*");
2962 ast *tTree = litTree->left;
2963 litTree->left = tree->right;
2964 tree->right = tTree;
2965 /* both operands in litTree are literal now */
2966 decorateType (parent, RESULT_CHECK);
2970 LRVAL (tree) = RRVAL (tree) = 1;
2971 tree->left = addCast (tree->left, resultType, FALSE);
2972 tree->right = addCast (tree->right, resultType, FALSE);
2973 TETYPE (tree) = getSpec (TTYPE (tree) =
2974 computeType (LTYPE (tree),
2976 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
2980 /*------------------------------------------------------------------*/
2981 /*----------------------------*/
2982 /* unary '+' operator */
2983 /*----------------------------*/
2988 if (!IS_ARITHMETIC (LTYPE (tree)))
2990 werror (E_UNARY_OP, '+');
2991 goto errorTreeReturn;
2994 /* if left is a literal then do it */
2995 if (IS_LITERAL (LTYPE (tree)))
2997 tree->type = EX_VALUE;
2998 tree->opval.val = valFromType (LETYPE (tree));
3000 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3004 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3008 /*------------------------------------------------------------------*/
3009 /*----------------------------*/
3011 /*----------------------------*/
3013 /* this is not a unary operation */
3014 /* if both pointers then problem */
3015 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3016 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3018 werror (E_PTR_PLUS_PTR);
3019 goto errorTreeReturn;
3022 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3023 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3025 werror (E_PLUS_INVALID, "+");
3026 goto errorTreeReturn;
3029 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3030 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3032 werror (E_PLUS_INVALID, "+");
3033 goto errorTreeReturn;
3035 /* if they are both literal then */
3036 /* rewrite the tree */
3037 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3039 tree->type = EX_VALUE;
3040 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3041 valFromType (RETYPE (tree)));
3042 tree->right = tree->left = NULL;
3043 TETYPE (tree) = getSpec (TTYPE (tree) =
3044 tree->opval.val->type);
3048 /* if the right is a pointer or left is a literal
3049 xchange left & right */
3050 if (IS_ARRAY (RTYPE (tree)) ||
3051 IS_PTR (RTYPE (tree)) ||
3052 IS_LITERAL (LTYPE (tree)))
3054 ast *tTree = tree->left;
3055 tree->left = tree->right;
3056 tree->right = tTree;
3059 /* if right is a literal and */
3060 /* left is also an addition/subtraction with a literal then */
3061 /* rearrange the tree */
3062 if (IS_LITERAL (RTYPE (tree)))
3064 ast *litTree, *parent;
3065 litTree = searchLitOp (tree, &parent, "+-");
3068 if (litTree->opval.op == '+')
3071 ast *tTree = litTree->left;
3072 litTree->left = tree->right;
3073 tree->right = tree->left;
3076 else if (litTree->opval.op == '-')
3078 if (IS_LITERAL (RTYPE (litTree)))
3081 ast *tTree = litTree->left;
3082 litTree->left = tree->right;
3083 tree->right = tTree;
3088 ast *tTree = litTree->right;
3089 litTree->right = tree->right;
3090 tree->right = tTree;
3091 litTree->opval.op = '+';
3092 tree->opval.op = '-';
3095 decorateType (parent, RESULT_CHECK);
3099 LRVAL (tree) = RRVAL (tree) = 1;
3100 /* if the left is a pointer */
3101 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3102 TETYPE (tree) = getSpec (TTYPE (tree) =
3106 tree->left = addCast (tree->left, resultType, TRUE);
3107 tree->right = addCast (tree->right, resultType, TRUE);
3108 TETYPE (tree) = getSpec (TTYPE (tree) =
3109 computeType (LTYPE (tree),
3111 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
3116 /*------------------------------------------------------------------*/
3117 /*----------------------------*/
3119 /*----------------------------*/
3120 case '-': /* can be unary */
3121 /* if right is null then unary */
3125 if (!IS_ARITHMETIC (LTYPE (tree)))
3127 werror (E_UNARY_OP, tree->opval.op);
3128 goto errorTreeReturn;
3131 /* if left is a literal then do it */
3132 if (IS_LITERAL (LTYPE (tree)))
3134 tree->type = EX_VALUE;
3135 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3137 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3138 SPEC_USIGN(TETYPE(tree)) = 0;
3142 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3146 /*------------------------------------------------------------------*/
3147 /*----------------------------*/
3149 /*----------------------------*/
3151 if (!(IS_PTR (LTYPE (tree)) ||
3152 IS_ARRAY (LTYPE (tree)) ||
3153 IS_ARITHMETIC (LTYPE (tree))))
3155 werror (E_PLUS_INVALID, "-");
3156 goto errorTreeReturn;
3159 if (!(IS_PTR (RTYPE (tree)) ||
3160 IS_ARRAY (RTYPE (tree)) ||
3161 IS_ARITHMETIC (RTYPE (tree))))
3163 werror (E_PLUS_INVALID, "-");
3164 goto errorTreeReturn;
3167 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3168 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3169 IS_INTEGRAL (RTYPE (tree))))
3171 werror (E_PLUS_INVALID, "-");
3172 goto errorTreeReturn;
3175 /* if they are both literal then */
3176 /* rewrite the tree */
3177 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3179 tree->type = EX_VALUE;
3180 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3181 valFromType (RETYPE (tree)));
3182 tree->right = tree->left = NULL;
3183 TETYPE (tree) = getSpec (TTYPE (tree) =
3184 tree->opval.val->type);
3188 /* if the left & right are equal then zero */
3189 if (isAstEqual (tree->left, tree->right))
3191 tree->type = EX_VALUE;
3192 tree->left = tree->right = NULL;
3193 tree->opval.val = constVal ("0");
3194 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3198 /* if both of them are pointers or arrays then */
3199 /* the result is going to be an integer */
3200 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3201 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3202 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3204 /* if only the left is a pointer */
3205 /* then result is a pointer */
3206 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3207 TETYPE (tree) = getSpec (TTYPE (tree) =
3211 tree->left = addCast (tree->left, resultType, TRUE);
3212 tree->right = addCast (tree->right, resultType, TRUE);
3213 TETYPE (tree) = getSpec (TTYPE (tree) =
3214 computeType (LTYPE (tree),
3216 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
3219 LRVAL (tree) = RRVAL (tree) = 1;
3221 /* if right is a literal and */
3222 /* left is also an addition/subtraction with a literal then */
3223 /* rearrange the tree */
3224 if (IS_LITERAL (RTYPE (tree))
3225 /* avoid infinite loop */
3226 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3228 ast *litTree, *litParent;
3229 litTree = searchLitOp (tree, &litParent, "+-");
3232 if (litTree->opval.op == '+')
3235 litTree->right = newNode ('-', litTree->right, tree->right);
3236 litTree->right->lineno = tree->lineno;
3238 tree->right->opval.val = constVal ("0");
3240 else if (litTree->opval.op == '-')
3242 if (IS_LITERAL (RTYPE (litTree)))
3245 litTree->right = newNode ('+', tree->right, litTree->right);
3246 litTree->right->lineno = tree->lineno;
3248 tree->right->opval.val = constVal ("0");
3253 ast *tTree = litTree->right;
3254 litTree->right = tree->right;
3255 tree->right = tTree;
3258 decorateType (litParent, RESULT_CHECK);
3263 /*------------------------------------------------------------------*/
3264 /*----------------------------*/
3266 /*----------------------------*/
3268 /* can be only integral type */
3269 if (!IS_INTEGRAL (LTYPE (tree)))
3271 werror (E_UNARY_OP, tree->opval.op);
3272 goto errorTreeReturn;
3275 /* if left is a literal then do it */
3276 if (IS_LITERAL (LTYPE (tree)))
3278 tree->type = EX_VALUE;
3279 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3281 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3285 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3288 /*------------------------------------------------------------------*/
3289 /*----------------------------*/
3291 /*----------------------------*/
3293 /* can be pointer */
3294 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3295 !IS_PTR (LTYPE (tree)) &&
3296 !IS_ARRAY (LTYPE (tree)))
3298 werror (E_UNARY_OP, tree->opval.op);
3299 goto errorTreeReturn;
3302 /* if left is a literal then do it */
3303 if (IS_LITERAL (LTYPE (tree)))
3305 tree->type = EX_VALUE;
3306 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3308 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3312 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3315 /*------------------------------------------------------------------*/
3316 /*----------------------------*/
3318 /*----------------------------*/
3322 TTYPE (tree) = LTYPE (tree);
3323 TETYPE (tree) = LETYPE (tree);
3327 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3332 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3334 werror (E_SHIFT_OP_INVALID);
3335 werror (W_CONTINUE, "left & right types are ");
3336 printTypeChain (LTYPE (tree), stderr);
3337 fprintf (stderr, ",");
3338 printTypeChain (RTYPE (tree), stderr);
3339 fprintf (stderr, "\n");
3340 goto errorTreeReturn;
3343 /* if they are both literal then */
3344 /* rewrite the tree */
3345 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3347 tree->type = EX_VALUE;
3348 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3349 valFromType (RETYPE (tree)),
3350 (tree->opval.op == LEFT_OP ? 1 : 0));
3351 tree->right = tree->left = NULL;
3352 TETYPE (tree) = getSpec (TTYPE (tree) =
3353 tree->opval.val->type);
3357 LRVAL (tree) = RRVAL (tree) = 1;
3358 if (tree->opval.op == LEFT_OP)
3360 tree->left = addCast (tree->left, resultType, TRUE);
3361 TETYPE (tree) = getSpec (TTYPE (tree) =
3362 computeType (LTYPE (tree),
3364 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
3368 /* no promotion necessary */
3369 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3370 if (IS_LITERAL (TTYPE (tree)))
3371 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3374 /* if only the right side is a literal & we are
3375 shifting more than size of the left operand then zero */
3376 if (IS_LITERAL (RTYPE (tree)) &&
3377 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3378 (getSize (TETYPE (tree)) * 8))
3380 if (tree->opval.op==LEFT_OP ||
3381 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3383 lineno=tree->lineno;
3384 werror (W_SHIFT_CHANGED,
3385 (tree->opval.op == LEFT_OP ? "left" : "right"));
3386 tree->type = EX_VALUE;
3387 tree->left = tree->right = NULL;
3388 tree->opval.val = constVal ("0");
3389 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3396 /*------------------------------------------------------------------*/
3397 /*----------------------------*/
3399 /*----------------------------*/
3400 case CAST: /* change the type */
3401 /* cannot cast to an aggregate type */
3402 if (IS_AGGREGATE (LTYPE (tree)))
3404 werror (E_CAST_ILLEGAL);
3405 goto errorTreeReturn;
3408 /* make sure the type is complete and sane */
3409 checkTypeSanity(LETYPE(tree), "(cast)");
3411 /* If code memory is read only, then pointers to code memory */
3412 /* implicitly point to constants -- make this explicit */
3414 sym_link *t = LTYPE(tree);
3415 while (t && t->next)
3417 if (IS_CODEPTR(t) && port->mem.code_ro)
3419 if (IS_SPEC(t->next))
3420 SPEC_CONST (t->next) = 1;
3422 DCL_PTR_CONST (t->next) = 1;
3429 /* if the right is a literal replace the tree */
3430 if (IS_LITERAL (RETYPE (tree))) {
3431 if (!IS_PTR (LTYPE (tree))) {
3432 tree->type = EX_VALUE;
3434 valCastLiteral (LTYPE (tree),
3435 floatFromVal (valFromType (RETYPE (tree))));
3438 TTYPE (tree) = tree->opval.val->type;
3439 tree->values.literalFromCast = 1;
3440 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3441 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3442 sym_link *rest = LTYPE(tree)->next;
3443 werror(W_LITERAL_GENERIC);
3444 TTYPE(tree) = newLink(DECLARATOR);
3445 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3446 TTYPE(tree)->next = rest;
3447 tree->left->opval.lnk = TTYPE(tree);
3450 TTYPE (tree) = LTYPE (tree);
3454 TTYPE (tree) = LTYPE (tree);
3458 #if 0 // this is already checked, now this could be explicit
3459 /* if pointer to struct then check names */
3460 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3461 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3462 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3464 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3465 SPEC_STRUCT(LETYPE(tree))->tag);
3468 if (IS_ADDRESS_OF_OP(tree->right)
3469 && IS_AST_SYM_VALUE (tree->right->left)
3470 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3472 tree->type = EX_VALUE;
3474 valCastLiteral (LTYPE (tree),
3475 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3476 TTYPE (tree) = tree->opval.val->type;
3477 TETYPE (tree) = getSpec (TTYPE (tree));
3480 tree->values.literalFromCast = 1;
3484 /* handle offsetof macro: */
3485 /* #define offsetof(TYPE, MEMBER) \ */
3486 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3487 if (IS_ADDRESS_OF_OP(tree->right)
3488 && IS_AST_OP (tree->right->left)
3489 && tree->right->left->opval.op == PTR_OP
3490 && IS_AST_OP (tree->right->left->left)
3491 && tree->right->left->left->opval.op == CAST
3492 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3494 symbol *element = getStructElement (
3495 SPEC_STRUCT (LETYPE(tree->right->left)),
3496 AST_SYMBOL(tree->right->left->right)
3500 tree->type = EX_VALUE;
3501 tree->opval.val = valCastLiteral (
3504 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3507 TTYPE (tree) = tree->opval.val->type;
3508 TETYPE (tree) = getSpec (TTYPE (tree));
3515 /* if the right is a literal replace the tree */
3516 if (IS_LITERAL (RETYPE (tree))) {
3518 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3519 /* rewrite (type *)litaddr
3521 and define type at litaddr temp
3522 (but only if type's storage class is not generic)
3524 ast *newTree = newNode ('&', NULL, NULL);
3527 TTYPE (newTree) = LTYPE (tree);
3528 TETYPE (newTree) = getSpec(LTYPE (tree));
3530 /* define a global symbol at the casted address*/
3531 sym = newSymbol(genSymName (0), 0);
3532 sym->type = LTYPE (tree)->next;
3534 sym->type = newLink (V_VOID);
3535 sym->etype = getSpec(sym->type);
3536 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3537 sym->lineDef = tree->lineno;
3540 SPEC_STAT (sym->etype) = 1;
3541 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3542 SPEC_ABSA(sym->etype) = 1;
3543 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3546 newTree->left = newAst_VALUE(symbolVal(sym));
3547 newTree->left->lineno = tree->lineno;
3548 LTYPE (newTree) = sym->type;
3549 LETYPE (newTree) = sym->etype;
3550 LLVAL (newTree) = 1;
3551 LRVAL (newTree) = 0;
3552 TLVAL (newTree) = 1;
3556 if (!IS_PTR (LTYPE (tree))) {
3557 tree->type = EX_VALUE;
3559 valCastLiteral (LTYPE (tree),
3560 floatFromVal (valFromType (RTYPE (tree))));
3561 TTYPE (tree) = tree->opval.val->type;
3564 tree->values.literalFromCast = 1;
3565 TETYPE (tree) = getSpec (TTYPE (tree));
3569 TTYPE (tree) = LTYPE (tree);
3573 TETYPE (tree) = getSpec (TTYPE (tree));
3577 /*------------------------------------------------------------------*/
3578 /*----------------------------*/
3579 /* logical &&, || */
3580 /*----------------------------*/
3583 /* each must me arithmetic type or be a pointer */
3584 if (!IS_PTR (LTYPE (tree)) &&
3585 !IS_ARRAY (LTYPE (tree)) &&
3586 !IS_INTEGRAL (LTYPE (tree)))
3588 werror (E_COMPARE_OP);
3589 goto errorTreeReturn;
3592 if (!IS_PTR (RTYPE (tree)) &&
3593 !IS_ARRAY (RTYPE (tree)) &&
3594 !IS_INTEGRAL (RTYPE (tree)))
3596 werror (E_COMPARE_OP);
3597 goto errorTreeReturn;
3599 /* if they are both literal then */
3600 /* rewrite the tree */
3601 if (IS_LITERAL (RTYPE (tree)) &&
3602 IS_LITERAL (LTYPE (tree)))
3604 tree->type = EX_VALUE;
3605 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3606 valFromType (RTYPE (tree)),
3608 tree->right = tree->left = NULL;
3609 TETYPE (tree) = getSpec (TTYPE (tree) =
3610 tree->opval.val->type);
3613 LRVAL (tree) = RRVAL (tree) = 1;
3614 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3617 /*------------------------------------------------------------------*/
3618 /*----------------------------*/
3619 /* comparison operators */
3620 /*----------------------------*/
3628 ast *lt = optimizeCompare (tree);
3634 /* if they are pointers they must be castable */
3635 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3637 if (tree->opval.op==EQ_OP &&
3638 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3639 // we cannot cast a gptr to a !gptr: switch the leaves
3640 struct ast *s=tree->left;
3641 tree->left=tree->right;
3644 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3646 werror (E_COMPARE_OP);
3647 fprintf (stderr, "comparing type ");
3648 printTypeChain (LTYPE (tree), stderr);
3649 fprintf (stderr, "to type ");
3650 printTypeChain (RTYPE (tree), stderr);
3651 fprintf (stderr, "\n");
3652 goto errorTreeReturn;
3655 /* else they should be promotable to one another */
3658 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3659 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3661 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3663 werror (E_COMPARE_OP);
3664 fprintf (stderr, "comparing type ");
3665 printTypeChain (LTYPE (tree), stderr);
3666 fprintf (stderr, "to type ");
3667 printTypeChain (RTYPE (tree), stderr);
3668 fprintf (stderr, "\n");
3669 goto errorTreeReturn;
3672 /* if unsigned value < 0 then always false */
3673 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3674 if (SPEC_USIGN(LETYPE(tree)) &&
3675 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3676 IS_LITERAL(RTYPE(tree)) &&
3677 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3679 if (tree->opval.op == '<')
3683 if (tree->opval.op == '>')
3685 /* if the parent is an ifx, then we could do */
3686 /* return tree->left; */
3687 tree->opval.op = '?';
3688 tree->right = newNode (':',
3689 newAst_VALUE (constVal ("1")),
3690 tree->right); /* val 0 */
3691 tree->right->lineno = tree->lineno;
3692 tree->right->left->lineno = tree->lineno;
3693 decorateType (tree->right, RESULT_CHECK);
3696 /* if they are both literal then */
3697 /* rewrite the tree */
3698 if (IS_LITERAL (RTYPE (tree)) &&
3699 IS_LITERAL (LTYPE (tree)))
3701 tree->type = EX_VALUE;
3702 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3703 valFromType (RETYPE (tree)),
3705 tree->right = tree->left = NULL;
3706 TETYPE (tree) = getSpec (TTYPE (tree) =
3707 tree->opval.val->type);
3710 LRVAL (tree) = RRVAL (tree) = 1;
3711 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3714 /*------------------------------------------------------------------*/
3715 /*----------------------------*/
3717 /*----------------------------*/
3718 case SIZEOF: /* evaluate wihout code generation */
3719 /* change the type to a integer */
3721 int size = getSize (tree->right->ftype);
3722 SNPRINTF(buffer, sizeof(buffer), "%d", size);
3723 if (!size && !IS_VOID(tree->right->ftype))
3724 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
3726 tree->type = EX_VALUE;
3727 tree->opval.val = constVal (buffer);
3728 tree->right = tree->left = NULL;
3729 TETYPE (tree) = getSpec (TTYPE (tree) =
3730 tree->opval.val->type);
3733 /*------------------------------------------------------------------*/
3734 /*----------------------------*/
3736 /*----------------------------*/
3738 /* return typeof enum value */
3739 tree->type = EX_VALUE;
3742 if (IS_SPEC(tree->right->ftype)) {
3743 switch (SPEC_NOUN(tree->right->ftype)) {
3745 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3746 else typeofv = TYPEOF_INT;
3749 typeofv = TYPEOF_FLOAT;
3752 typeofv = TYPEOF_CHAR;
3755 typeofv = TYPEOF_VOID;
3758 typeofv = TYPEOF_STRUCT;
3761 typeofv = TYPEOF_BITFIELD;
3764 typeofv = TYPEOF_BIT;
3767 typeofv = TYPEOF_SBIT;
3773 switch (DCL_TYPE(tree->right->ftype)) {
3775 typeofv = TYPEOF_POINTER;
3778 typeofv = TYPEOF_FPOINTER;
3781 typeofv = TYPEOF_CPOINTER;
3784 typeofv = TYPEOF_GPOINTER;
3787 typeofv = TYPEOF_PPOINTER;
3790 typeofv = TYPEOF_IPOINTER;
3793 typeofv = TYPEOF_ARRAY;
3796 typeofv = TYPEOF_FUNCTION;
3802 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3803 tree->opval.val = constVal (buffer);
3804 tree->right = tree->left = NULL;
3805 TETYPE (tree) = getSpec (TTYPE (tree) =
3806 tree->opval.val->type);
3809 /*------------------------------------------------------------------*/
3810 /*----------------------------*/
3811 /* conditional operator '?' */
3812 /*----------------------------*/
3814 /* the type is value of the colon operator (on the right) */
3815 assert (IS_COLON_OP (tree->right));
3816 /* if already known then replace the tree : optimizer will do it
3817 but faster to do it here */
3818 if (IS_LITERAL (LTYPE (tree)))
3820 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
3821 return decorateType (tree->right->left, resultTypeProp);
3823 return decorateType (tree->right->right, resultTypeProp);
3827 tree->right = decorateType (tree->right, resultTypeProp);
3828 TTYPE (tree) = RTYPE (tree);
3829 TETYPE (tree) = getSpec (TTYPE (tree));
3834 /* if they don't match we have a problem */
3835 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3837 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3838 goto errorTreeReturn;
3841 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
3842 TETYPE (tree) = getSpec (TTYPE (tree));
3846 #if 0 // assignment operators are converted by the parser
3847 /*------------------------------------------------------------------*/
3848 /*----------------------------*/
3849 /* assignment operators */
3850 /*----------------------------*/
3853 /* for these it must be both must be integral */
3854 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3855 !IS_ARITHMETIC (RTYPE (tree)))
3857 werror (E_OPS_INTEGRAL);
3858 goto errorTreeReturn;
3861 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3863 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3864 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3868 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3869 goto errorTreeReturn;
3880 /* for these it must be both must be integral */
3881 if (!IS_INTEGRAL (LTYPE (tree)) ||
3882 !IS_INTEGRAL (RTYPE (tree)))
3884 werror (E_OPS_INTEGRAL);
3885 goto errorTreeReturn;
3888 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3890 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3891 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3895 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3896 goto errorTreeReturn;
3902 /*------------------------------------------------------------------*/
3903 /*----------------------------*/
3905 /*----------------------------*/
3907 if (!(IS_PTR (LTYPE (tree)) ||
3908 IS_ARITHMETIC (LTYPE (tree))))
3910 werror (E_PLUS_INVALID, "-=");
3911 goto errorTreeReturn;
3914 if (!(IS_PTR (RTYPE (tree)) ||
3915 IS_ARITHMETIC (RTYPE (tree))))
3917 werror (E_PLUS_INVALID, "-=");
3918 goto errorTreeReturn;
3921 TETYPE (tree) = getSpec (TTYPE (tree) =
3922 computeType (LTYPE (tree),
3926 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3927 werror (E_CODE_WRITE, "-=");
3931 werror (E_LVALUE_REQUIRED, "-=");
3932 goto errorTreeReturn;
3938 /*------------------------------------------------------------------*/
3939 /*----------------------------*/
3941 /*----------------------------*/
3943 /* this is not a unary operation */
3944 /* if both pointers then problem */
3945 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3947 werror (E_PTR_PLUS_PTR);
3948 goto errorTreeReturn;
3951 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3953 werror (E_PLUS_INVALID, "+=");
3954 goto errorTreeReturn;
3957 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3959 werror (E_PLUS_INVALID, "+=");
3960 goto errorTreeReturn;
3963 TETYPE (tree) = getSpec (TTYPE (tree) =
3964 computeType (LTYPE (tree),
3968 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3969 werror (E_CODE_WRITE, "+=");
3973 werror (E_LVALUE_REQUIRED, "+=");
3974 goto errorTreeReturn;
3977 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_CHECK);
3978 tree->opval.op = '=';
3983 /*------------------------------------------------------------------*/
3984 /*----------------------------*/
3985 /* straight assignemnt */
3986 /*----------------------------*/
3988 /* cannot be an aggregate */
3989 if (IS_AGGREGATE (LTYPE (tree)))
3991 werror (E_AGGR_ASSIGN);
3992 goto errorTreeReturn;
3995 /* they should either match or be castable */
3996 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3998 werror (E_TYPE_MISMATCH, "assignment", " ");
3999 printFromToType(RTYPE(tree),LTYPE(tree));
4002 /* if the left side of the tree is of type void
4003 then report error */
4004 if (IS_VOID (LTYPE (tree)))
4006 werror (E_CAST_ZERO);
4007 printFromToType(RTYPE(tree), LTYPE(tree));
4010 TETYPE (tree) = getSpec (TTYPE (tree) =
4014 if (!tree->initMode ) {
4015 if (IS_CONSTANT(LTYPE(tree)))
4016 werror (E_CODE_WRITE, "=");
4020 werror (E_LVALUE_REQUIRED, "=");
4021 goto errorTreeReturn;
4026 /*------------------------------------------------------------------*/
4027 /*----------------------------*/
4028 /* comma operator */
4029 /*----------------------------*/
4031 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4034 /*------------------------------------------------------------------*/
4035 /*----------------------------*/
4037 /*----------------------------*/
4040 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4041 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4043 if (tree->left->opval.op == '*' && !tree->left->right)
4044 tree->left = tree->left->left;
4047 /* require a function or pointer to function */
4048 if (!IS_FUNC (LTYPE (tree))
4049 && !(IS_CODEPTR (LTYPE (tree)) && IS_FUNC (LTYPE (tree)->next)))
4051 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4052 goto errorTreeReturn;
4059 if (IS_CODEPTR(LTYPE(tree)))
4060 functype = LTYPE (tree)->next;
4062 functype = LTYPE (tree);
4064 if (processParms (tree->left, FUNC_ARGS(functype),
4065 tree->right, &parmNumber, TRUE)) {
4066 goto errorTreeReturn;
4069 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4070 !IFFUNC_ISBUILTIN(functype))
4072 reverseParms (tree->right);
4075 TTYPE (tree) = functype->next;
4076 TETYPE (tree) = getSpec (TTYPE (tree));
4080 /*------------------------------------------------------------------*/
4081 /*----------------------------*/
4082 /* return statement */
4083 /*----------------------------*/
4088 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4090 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4091 printFromToType (RTYPE(tree), currFunc->type->next);
4092 goto errorTreeReturn;
4095 if (IS_VOID (currFunc->type->next)
4097 !IS_VOID (RTYPE (tree)))
4099 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4100 goto errorTreeReturn;
4103 /* if there is going to be a casting required then add it */
4104 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4107 decorateType (newNode (CAST,
4108 newAst_LINK (copyLinkChain (currFunc->type->next)),
4118 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4120 werror (W_VOID_FUNC, currFunc->name);
4121 goto errorTreeReturn;
4124 TTYPE (tree) = TETYPE (tree) = NULL;
4127 /*------------------------------------------------------------------*/
4128 /*----------------------------*/
4129 /* switch statement */
4130 /*----------------------------*/
4132 /* the switch value must be an integer */
4133 if (!IS_INTEGRAL (LTYPE (tree)))
4135 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4136 goto errorTreeReturn;
4139 TTYPE (tree) = TETYPE (tree) = NULL;
4142 /*------------------------------------------------------------------*/
4143 /*----------------------------*/
4145 /*----------------------------*/
4147 tree->left = backPatchLabels (tree->left,
4150 TTYPE (tree) = TETYPE (tree) = NULL;
4153 /*------------------------------------------------------------------*/
4154 /*----------------------------*/
4156 /*----------------------------*/
4159 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_CHECK);
4160 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_CHECK);
4161 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_CHECK);
4163 /* if the for loop is reversible then
4164 reverse it otherwise do what we normally
4170 if (isLoopReversible (tree, &sym, &init, &end))
4171 return reverseLoop (tree, sym, init, end);
4173 return decorateType (createFor (AST_FOR (tree, trueLabel),
4174 AST_FOR (tree, continueLabel),
4175 AST_FOR (tree, falseLabel),
4176 AST_FOR (tree, condLabel),
4177 AST_FOR (tree, initExpr),
4178 AST_FOR (tree, condExpr),
4179 AST_FOR (tree, loopExpr),
4180 tree->left), RESULT_CHECK);
4183 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4184 "node PARAM shouldn't be processed here");
4185 /* but in processParams() */
4188 TTYPE (tree) = TETYPE (tree) = NULL;
4192 /* some error found this tree will be killed */
4194 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4195 tree->opval.op = NULLOP;
4201 /*-----------------------------------------------------------------*/
4202 /* sizeofOp - processes size of operation */
4203 /*-----------------------------------------------------------------*/
4205 sizeofOp (sym_link * type)
4210 /* make sure the type is complete and sane */
4211 checkTypeSanity(type, "(sizeof)");
4213 /* get the size and convert it to character */
4214 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4215 if (!size && !IS_VOID(type))
4216 werror (E_SIZEOF_INCOMPLETE_TYPE);
4218 /* now convert into value */
4219 return constVal (buff);
4223 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4224 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4225 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4226 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4227 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4228 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4229 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4231 /*-----------------------------------------------------------------*/
4232 /* backPatchLabels - change and or not operators to flow control */
4233 /*-----------------------------------------------------------------*/
4235 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4241 if (!(IS_ANDORNOT (tree)))
4244 /* if this an and */
4247 static int localLbl = 0;
4250 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4251 localLabel = newSymbol (buffer, NestLevel);
4253 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4255 /* if left is already a IFX then just change the if true label in that */
4256 if (!IS_IFX (tree->left))
4257 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4259 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4260 /* right is a IFX then just join */
4261 if (IS_IFX (tree->right))
4262 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4264 tree->right = createLabel (localLabel, tree->right);
4265 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4267 return newNode (NULLOP, tree->left, tree->right);
4270 /* if this is an or operation */
4273 static int localLbl = 0;
4276 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4277 localLabel = newSymbol (buffer, NestLevel);
4279 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4281 /* if left is already a IFX then just change the if true label in that */
4282 if (!IS_IFX (tree->left))
4283 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4285 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4286 /* right is a IFX then just join */
4287 if (IS_IFX (tree->right))
4288 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4290 tree->right = createLabel (localLabel, tree->right);
4291 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4293 return newNode (NULLOP, tree->left, tree->right);
4299 int wasnot = IS_NOT (tree->left);
4300 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4302 /* if the left is already a IFX */
4303 if (!IS_IFX (tree->left))
4304 tree->left = newNode (IFX, tree->left, NULL);
4308 tree->left->trueLabel = trueLabel;
4309 tree->left->falseLabel = falseLabel;
4313 tree->left->trueLabel = falseLabel;
4314 tree->left->falseLabel = trueLabel;
4321 tree->trueLabel = trueLabel;
4322 tree->falseLabel = falseLabel;
4329 /*-----------------------------------------------------------------*/
4330 /* createBlock - create expression tree for block */
4331 /*-----------------------------------------------------------------*/
4333 createBlock (symbol * decl, ast * body)
4337 /* if the block has nothing */
4341 ex = newNode (BLOCK, NULL, body);
4342 ex->values.sym = decl;
4344 ex->right = ex->right;
4350 /*-----------------------------------------------------------------*/
4351 /* createLabel - creates the expression tree for labels */
4352 /*-----------------------------------------------------------------*/
4354 createLabel (symbol * label, ast * stmnt)
4357 char name[SDCC_NAME_MAX + 1];
4360 /* must create fresh symbol if the symbol name */
4361 /* exists in the symbol table, since there can */
4362 /* be a variable with the same name as the labl */
4363 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4364 (csym->level == label->level))
4365 label = newSymbol (label->name, label->level);
4367 /* change the name before putting it in add _ */
4368 SNPRINTF(name, sizeof(name), "%s", label->name);
4370 /* put the label in the LabelSymbol table */
4371 /* but first check if a label of the same */
4373 if ((csym = findSym (LabelTab, NULL, name)))
4374 werror (E_DUPLICATE_LABEL, label->name);
4376 addSym (LabelTab, label, name, label->level, 0, 0);
4379 label->key = labelKey++;
4380 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4386 /*-----------------------------------------------------------------*/
4387 /* createCase - generates the parsetree for a case statement */
4388 /*-----------------------------------------------------------------*/
4390 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4392 char caseLbl[SDCC_NAME_MAX + 1];
4396 /* if the switch statement does not exist */
4397 /* then case is out of context */
4400 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4404 caseVal = decorateType (resolveSymbols (caseVal), RESULT_CHECK);
4405 /* if not a constant then error */
4406 if (!IS_LITERAL (caseVal->ftype))
4408 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4412 /* if not a integer than error */
4413 if (!IS_INTEGRAL (caseVal->ftype))
4415 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4419 /* find the end of the switch values chain */
4420 if (!(val = swStat->values.switchVals.swVals))
4421 swStat->values.switchVals.swVals = caseVal->opval.val;
4424 /* also order the cases according to value */
4426 int cVal = (int) floatFromVal (caseVal->opval.val);
4427 while (val && (int) floatFromVal (val) < cVal)
4433 /* if we reached the end then */
4436 pval->next = caseVal->opval.val;
4438 else if ((int) floatFromVal (val) == cVal)
4440 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4446 /* we found a value greater than */
4447 /* the current value we must add this */
4448 /* before the value */
4449 caseVal->opval.val->next = val;
4451 /* if this was the first in chain */
4452 if (swStat->values.switchVals.swVals == val)
4453 swStat->values.switchVals.swVals =
4456 pval->next = caseVal->opval.val;
4461 /* create the case label */
4462 SNPRINTF(caseLbl, sizeof(caseLbl),
4464 swStat->values.switchVals.swNum,
4465 (int) floatFromVal (caseVal->opval.val));
4467 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4472 /*-----------------------------------------------------------------*/
4473 /* createDefault - creates the parse tree for the default statement */
4474 /*-----------------------------------------------------------------*/
4476 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4478 char defLbl[SDCC_NAME_MAX + 1];
4480 /* if the switch statement does not exist */
4481 /* then case is out of context */
4484 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4488 if (swStat->values.switchVals.swDefault)
4490 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4495 /* turn on the default flag */
4496 swStat->values.switchVals.swDefault = 1;
4498 /* create the label */
4499 SNPRINTF (defLbl, sizeof(defLbl),
4500 "_default_%d", swStat->values.switchVals.swNum);
4501 return createLabel (newSymbol (defLbl, 0), stmnt);
4504 /*-----------------------------------------------------------------*/
4505 /* createIf - creates the parsetree for the if statement */
4506 /*-----------------------------------------------------------------*/
4508 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4510 static int Lblnum = 0;
4512 symbol *ifTrue, *ifFalse, *ifEnd;
4514 /* if neither exists */
4515 if (!elseBody && !ifBody) {
4516 // if there are no side effects (i++, j() etc)
4517 if (!hasSEFcalls(condAst)) {
4522 /* create the labels */
4523 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4524 ifFalse = newSymbol (buffer, NestLevel);
4525 /* if no else body then end == false */
4530 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4531 ifEnd = newSymbol (buffer, NestLevel);
4534 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4535 ifTrue = newSymbol (buffer, NestLevel);
4539 /* attach the ifTrue label to the top of it body */
4540 ifBody = createLabel (ifTrue, ifBody);
4541 /* attach a goto end to the ifBody if else is present */
4544 ifBody = newNode (NULLOP, ifBody,
4546 newAst_VALUE (symbolVal (ifEnd)),
4548 /* put the elseLabel on the else body */
4549 elseBody = createLabel (ifFalse, elseBody);
4550 /* out the end at the end of the body */
4551 elseBody = newNode (NULLOP,
4553 createLabel (ifEnd, NULL));
4557 ifBody = newNode (NULLOP, ifBody,
4558 createLabel (ifFalse, NULL));
4560 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4561 if (IS_IFX (condAst))
4564 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4566 return newNode (NULLOP, ifTree,
4567 newNode (NULLOP, ifBody, elseBody));
4571 /*-----------------------------------------------------------------*/
4572 /* createDo - creates parse tree for do */
4575 /* _docontinue_n: */
4576 /* condition_expression +-> trueLabel -> _dobody_n */
4578 /* +-> falseLabel-> _dobreak_n */
4580 /*-----------------------------------------------------------------*/
4582 createDo (symbol * trueLabel, symbol * continueLabel,
4583 symbol * falseLabel, ast * condAst, ast * doBody)
4588 /* if the body does not exist then it is simple */
4591 condAst = backPatchLabels (condAst, continueLabel, NULL);
4592 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4593 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4594 doTree->trueLabel = continueLabel;
4595 doTree->falseLabel = NULL;
4599 /* otherwise we have a body */
4600 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4602 /* attach the body label to the top */
4603 doBody = createLabel (trueLabel, doBody);
4604 /* attach the continue label to end of body */
4605 doBody = newNode (NULLOP, doBody,
4606 createLabel (continueLabel, NULL));
4608 /* now put the break label at the end */
4609 if (IS_IFX (condAst))
4612 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4614 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4616 /* putting it together */
4617 return newNode (NULLOP, doBody, doTree);
4620 /*-----------------------------------------------------------------*/
4621 /* createFor - creates parse tree for 'for' statement */
4624 /* condExpr +-> trueLabel -> _forbody_n */
4626 /* +-> falseLabel-> _forbreak_n */
4629 /* _forcontinue_n: */
4631 /* goto _forcond_n ; */
4633 /*-----------------------------------------------------------------*/
4635 createFor (symbol * trueLabel, symbol * continueLabel,
4636 symbol * falseLabel, symbol * condLabel,
4637 ast * initExpr, ast * condExpr, ast * loopExpr,
4642 /* if loopexpression not present then we can generate it */
4643 /* the same way as a while */
4645 return newNode (NULLOP, initExpr,
4646 createWhile (trueLabel, continueLabel,
4647 falseLabel, condExpr, forBody));
4648 /* vanilla for statement */
4649 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4651 if (condExpr && !IS_IFX (condExpr))
4652 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4655 /* attach condition label to condition */
4656 condExpr = createLabel (condLabel, condExpr);
4658 /* attach body label to body */
4659 forBody = createLabel (trueLabel, forBody);
4661 /* attach continue to forLoop expression & attach */
4662 /* goto the forcond @ and of loopExpression */
4663 loopExpr = createLabel (continueLabel,
4667 newAst_VALUE (symbolVal (condLabel)),
4669 /* now start putting them together */
4670 forTree = newNode (NULLOP, initExpr, condExpr);
4671 forTree = newNode (NULLOP, forTree, forBody);
4672 forTree = newNode (NULLOP, forTree, loopExpr);
4673 /* finally add the break label */
4674 forTree = newNode (NULLOP, forTree,
4675 createLabel (falseLabel, NULL));
4679 /*-----------------------------------------------------------------*/
4680 /* createWhile - creates parse tree for while statement */
4681 /* the while statement will be created as follows */
4683 /* _while_continue_n: */
4684 /* condition_expression +-> trueLabel -> _while_boby_n */
4686 /* +-> falseLabel -> _while_break_n */
4687 /* _while_body_n: */
4689 /* goto _while_continue_n */
4690 /* _while_break_n: */
4691 /*-----------------------------------------------------------------*/
4693 createWhile (symbol * trueLabel, symbol * continueLabel,
4694 symbol * falseLabel, ast * condExpr, ast * whileBody)
4698 /* put the continue label */
4699 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4700 condExpr = createLabel (continueLabel, condExpr);
4701 condExpr->lineno = 0;
4703 /* put the body label in front of the body */
4704 whileBody = createLabel (trueLabel, whileBody);
4705 whileBody->lineno = 0;
4706 /* put a jump to continue at the end of the body */
4707 /* and put break label at the end of the body */
4708 whileBody = newNode (NULLOP,
4711 newAst_VALUE (symbolVal (continueLabel)),
4712 createLabel (falseLabel, NULL)));
4714 /* put it all together */
4715 if (IS_IFX (condExpr))
4716 whileTree = condExpr;
4719 whileTree = newNode (IFX, condExpr, NULL);
4720 /* put the true & false labels in place */
4721 whileTree->trueLabel = trueLabel;
4722 whileTree->falseLabel = falseLabel;
4725 return newNode (NULLOP, whileTree, whileBody);
4728 /*-----------------------------------------------------------------*/
4729 /* optimizeGetHbit - get highest order bit of the expression */
4730 /*-----------------------------------------------------------------*/
4732 optimizeGetHbit (ast * tree)
4735 /* if this is not a bit and */
4736 if (!IS_BITAND (tree))
4739 /* will look for tree of the form
4740 ( expr >> ((sizeof expr) -1) ) & 1 */
4741 if (!IS_AST_LIT_VALUE (tree->right))
4744 if (AST_LIT_VALUE (tree->right) != 1)
4747 if (!IS_RIGHT_OP (tree->left))
4750 if (!IS_AST_LIT_VALUE (tree->left->right))
4753 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4754 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4757 /* make sure the port supports GETHBIT */
4758 if (port->hasExtBitOp
4759 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4762 return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_CHECK);
4766 /*-----------------------------------------------------------------*/
4767 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4768 /*-----------------------------------------------------------------*/
4770 optimizeRRCRLC (ast * root)
4772 /* will look for trees of the form
4773 (?expr << 1) | (?expr >> 7) or
4774 (?expr >> 7) | (?expr << 1) will make that
4775 into a RLC : operation ..
4777 (?expr >> 1) | (?expr << 7) or
4778 (?expr << 7) | (?expr >> 1) will make that
4779 into a RRC operation
4780 note : by 7 I mean (number of bits required to hold the
4782 /* if the root operations is not a | operation the not */
4783 if (!IS_BITOR (root))
4786 /* I have to think of a better way to match patterns this sucks */
4787 /* that aside let start looking for the first case : I use a the
4788 negative check a lot to improve the efficiency */
4789 /* (?expr << 1) | (?expr >> 7) */
4790 if (IS_LEFT_OP (root->left) &&
4791 IS_RIGHT_OP (root->right))
4794 if (!SPEC_USIGN (TETYPE (root->left->left)))
4797 if (!IS_AST_LIT_VALUE (root->left->right) ||
4798 !IS_AST_LIT_VALUE (root->right->right))
4801 /* make sure it is the same expression */
4802 if (!isAstEqual (root->left->left,
4806 if (AST_LIT_VALUE (root->left->right) != 1)
4809 if (AST_LIT_VALUE (root->right->right) !=
4810 (getSize (TTYPE (root->left->left)) * 8 - 1))
4813 /* make sure the port supports RLC */
4814 if (port->hasExtBitOp
4815 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4818 /* whew got the first case : create the AST */
4819 return newNode (RLC, root->left->left, NULL);
4823 /* check for second case */
4824 /* (?expr >> 7) | (?expr << 1) */
4825 if (IS_LEFT_OP (root->right) &&
4826 IS_RIGHT_OP (root->left))
4829 if (!SPEC_USIGN (TETYPE (root->left->left)))
4832 if (!IS_AST_LIT_VALUE (root->left->right) ||
4833 !IS_AST_LIT_VALUE (root->right->right))
4836 /* make sure it is the same symbol */
4837 if (!isAstEqual (root->left->left,
4841 if (AST_LIT_VALUE (root->right->right) != 1)
4844 if (AST_LIT_VALUE (root->left->right) !=
4845 (getSize (TTYPE (root->left->left)) * 8 - 1))
4848 /* make sure the port supports RLC */
4849 if (port->hasExtBitOp
4850 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4853 /* whew got the first case : create the AST */
4854 return newNode (RLC, root->left->left, NULL);
4859 /* third case for RRC */
4860 /* (?symbol >> 1) | (?symbol << 7) */
4861 if (IS_LEFT_OP (root->right) &&
4862 IS_RIGHT_OP (root->left))
4865 if (!SPEC_USIGN (TETYPE (root->left->left)))
4868 if (!IS_AST_LIT_VALUE (root->left->right) ||
4869 !IS_AST_LIT_VALUE (root->right->right))
4872 /* make sure it is the same symbol */
4873 if (!isAstEqual (root->left->left,
4877 if (AST_LIT_VALUE (root->left->right) != 1)
4880 if (AST_LIT_VALUE (root->right->right) !=
4881 (getSize (TTYPE (root->left->left)) * 8 - 1))
4884 /* make sure the port supports RRC */
4885 if (port->hasExtBitOp
4886 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4889 /* whew got the first case : create the AST */
4890 return newNode (RRC, root->left->left, NULL);
4894 /* fourth and last case for now */
4895 /* (?symbol << 7) | (?symbol >> 1) */
4896 if (IS_RIGHT_OP (root->right) &&
4897 IS_LEFT_OP (root->left))
4900 if (!SPEC_USIGN (TETYPE (root->left->left)))
4903 if (!IS_AST_LIT_VALUE (root->left->right) ||
4904 !IS_AST_LIT_VALUE (root->right->right))
4907 /* make sure it is the same symbol */
4908 if (!isAstEqual (root->left->left,
4912 if (AST_LIT_VALUE (root->right->right) != 1)
4915 if (AST_LIT_VALUE (root->left->right) !=
4916 (getSize (TTYPE (root->left->left)) * 8 - 1))
4919 /* make sure the port supports RRC */
4920 if (port->hasExtBitOp
4921 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4924 /* whew got the first case : create the AST */
4925 return newNode (RRC, root->left->left, NULL);
4929 /* not found return root */
4933 /*-----------------------------------------------------------------*/
4934 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
4935 /*-----------------------------------------------------------------*/
4937 optimizeSWAP (ast * root)
4939 /* will look for trees of the form
4940 (?expr << 4) | (?expr >> 4) or
4941 (?expr >> 4) | (?expr << 4) will make that
4942 into a SWAP : operation ..
4943 note : by 4 I mean (number of bits required to hold the
4945 /* if the root operations is not a | operation the not */
4946 if (!IS_BITOR (root))
4949 /* (?expr << 4) | (?expr >> 4) */
4950 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
4951 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
4954 if (!SPEC_USIGN (TETYPE (root->left->left)))
4957 if (!IS_AST_LIT_VALUE (root->left->right) ||
4958 !IS_AST_LIT_VALUE (root->right->right))
4961 /* make sure it is the same expression */
4962 if (!isAstEqual (root->left->left,
4966 if (AST_LIT_VALUE (root->left->right) !=
4967 (getSize (TTYPE (root->left->left)) * 4))
4970 if (AST_LIT_VALUE (root->right->right) !=
4971 (getSize (TTYPE (root->left->left)) * 4))
4974 /* make sure the port supports SWAP */
4975 if (port->hasExtBitOp
4976 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
4979 /* found it : create the AST */
4980 return newNode (SWAP, root->left->left, NULL);
4984 /* not found return root */
4988 /*-----------------------------------------------------------------*/
4989 /* optimizeCompare - otimizes compares for bit variables */
4990 /*-----------------------------------------------------------------*/
4992 optimizeCompare (ast * root)
4994 ast *optExpr = NULL;
4997 unsigned int litValue;
4999 /* if nothing then return nothing */
5003 /* if not a compare op then do leaves */
5004 if (!IS_COMPARE_OP (root))
5006 root->left = optimizeCompare (root->left);
5007 root->right = optimizeCompare (root->right);
5011 /* if left & right are the same then depending
5012 of the operation do */
5013 if (isAstEqual (root->left, root->right))
5015 switch (root->opval.op)
5020 optExpr = newAst_VALUE (constVal ("0"));
5025 optExpr = newAst_VALUE (constVal ("1"));
5029 return decorateType (optExpr, RESULT_CHECK);
5032 vleft = (root->left->type == EX_VALUE ?
5033 root->left->opval.val : NULL);
5035 vright = (root->right->type == EX_VALUE ?
5036 root->right->opval.val : NULL);
5038 /* if left is a BITVAR in BITSPACE */
5039 /* and right is a LITERAL then opt- */
5040 /* imize else do nothing */
5041 if (vleft && vright &&
5042 IS_BITVAR (vleft->etype) &&
5043 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5044 IS_LITERAL (vright->etype))
5047 /* if right side > 1 then comparison may never succeed */
5048 if ((litValue = (int) floatFromVal (vright)) > 1)
5050 werror (W_BAD_COMPARE);
5056 switch (root->opval.op)
5058 case '>': /* bit value greater than 1 cannot be */
5059 werror (W_BAD_COMPARE);
5063 case '<': /* bit value < 1 means 0 */
5065 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5068 case LE_OP: /* bit value <= 1 means no check */
5069 optExpr = newAst_VALUE (vright);
5072 case GE_OP: /* bit value >= 1 means only check for = */
5074 optExpr = newAst_VALUE (vleft);
5079 { /* literal is zero */
5080 switch (root->opval.op)
5082 case '<': /* bit value < 0 cannot be */
5083 werror (W_BAD_COMPARE);
5087 case '>': /* bit value > 0 means 1 */
5089 optExpr = newAst_VALUE (vleft);
5092 case LE_OP: /* bit value <= 0 means no check */
5093 case GE_OP: /* bit value >= 0 means no check */
5094 werror (W_BAD_COMPARE);
5098 case EQ_OP: /* bit == 0 means ! of bit */
5099 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5103 return decorateType (resolveSymbols (optExpr), RESULT_CHECK);
5104 } /* end-of-if of BITVAR */
5109 /*-----------------------------------------------------------------*/
5110 /* addSymToBlock : adds the symbol to the first block we find */
5111 /*-----------------------------------------------------------------*/
5113 addSymToBlock (symbol * sym, ast * tree)
5115 /* reached end of tree or a leaf */
5116 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5120 if (IS_AST_OP (tree) &&
5121 tree->opval.op == BLOCK)
5124 symbol *lsym = copySymbol (sym);
5126 lsym->next = AST_VALUES (tree, sym);
5127 AST_VALUES (tree, sym) = lsym;
5131 addSymToBlock (sym, tree->left);
5132 addSymToBlock (sym, tree->right);
5135 /*-----------------------------------------------------------------*/
5136 /* processRegParms - do processing for register parameters */
5137 /*-----------------------------------------------------------------*/
5139 processRegParms (value * args, ast * body)
5143 if (IS_REGPARM (args->etype))
5144 addSymToBlock (args->sym, body);
5149 /*-----------------------------------------------------------------*/
5150 /* resetParmKey - resets the operandkeys for the symbols */
5151 /*-----------------------------------------------------------------*/
5152 DEFSETFUNC (resetParmKey)
5163 /*-----------------------------------------------------------------*/
5164 /* createFunction - This is the key node that calls the iCode for */
5165 /* generating the code for a function. Note code */
5166 /* is generated function by function, later when */
5167 /* add inter-procedural analysis this will change */
5168 /*-----------------------------------------------------------------*/
5170 createFunction (symbol * name, ast * body)
5176 iCode *piCode = NULL;
5178 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5179 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5181 /* if check function return 0 then some problem */
5182 if (checkFunction (name, NULL) == 0)
5185 /* create a dummy block if none exists */
5187 body = newNode (BLOCK, NULL, NULL);
5191 /* check if the function name already in the symbol table */
5192 if ((csym = findSym (SymbolTab, NULL, name->name)))
5195 /* special case for compiler defined functions
5196 we need to add the name to the publics list : this
5197 actually means we are now compiling the compiler
5201 addSet (&publics, name);
5207 allocVariables (name);
5209 name->lastLine = mylineno;
5212 /* set the stack pointer */
5213 /* PENDING: check this for the mcs51 */
5214 stackPtr = -port->stack.direction * port->stack.call_overhead;
5215 if (IFFUNC_ISISR (name->type))
5216 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5217 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5218 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5220 xstackPtr = -port->stack.direction * port->stack.call_overhead;
5222 fetype = getSpec (name->type); /* get the specifier for the function */
5223 /* if this is a reentrant function then */
5224 if (IFFUNC_ISREENT (name->type))
5227 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5229 /* do processing for parameters that are passed in registers */
5230 processRegParms (FUNC_ARGS(name->type), body);
5232 /* set the stack pointer */
5236 /* allocate & autoinit the block variables */
5237 processBlockVars (body, &stack, ALLOCATE);
5239 /* save the stack information */
5240 if (options.useXstack)
5241 name->xstack = SPEC_STAK (fetype) = stack;
5243 name->stack = SPEC_STAK (fetype) = stack;
5245 /* name needs to be mangled */
5246 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5248 body = resolveSymbols (body); /* resolve the symbols */
5249 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5252 ex = newAst_VALUE (symbolVal (name)); /* create name */
5253 ex = newNode (FUNCTION, ex, body);
5254 ex->values.args = FUNC_ARGS(name->type);
5256 if (options.dump_tree) PA(ex);
5259 werror (E_FUNC_NO_CODE, name->name);
5263 /* create the node & generate intermediate code */
5265 codeOutFile = code->oFile;
5266 piCode = iCodeFromAst (ex);
5270 werror (E_FUNC_NO_CODE, name->name);
5274 eBBlockFromiCode (piCode);
5276 /* if there are any statics then do them */
5279 GcurMemmap = statsg;
5280 codeOutFile = statsg->oFile;
5281 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_CHECK)));
5287 /* dealloc the block variables */
5288 processBlockVars (body, &stack, DEALLOCATE);
5289 outputDebugStackSymbols();
5290 /* deallocate paramaters */
5291 deallocParms (FUNC_ARGS(name->type));
5293 if (IFFUNC_ISREENT (name->type))
5296 /* we are done freeup memory & cleanup */
5298 if (port->reset_labelKey) labelKey = 1;
5300 FUNC_HASBODY(name->type) = 1;
5301 addSet (&operKeyReset, name);
5302 applyToSet (operKeyReset, resetParmKey);
5307 cleanUpLevel (LabelTab, 0);
5308 cleanUpBlock (StructTab, 1);
5309 cleanUpBlock (TypedefTab, 1);
5311 xstack->syms = NULL;
5312 istack->syms = NULL;
5317 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5318 /*-----------------------------------------------------------------*/
5319 /* ast_print : prints the ast (for debugging purposes) */
5320 /*-----------------------------------------------------------------*/
5322 void ast_print (ast * tree, FILE *outfile, int indent)
5327 /* can print only decorated trees */
5328 if (!tree->decorated) return;
5330 /* if any child is an error | this one is an error do nothing */
5331 if (tree->isError ||
5332 (tree->left && tree->left->isError) ||
5333 (tree->right && tree->right->isError)) {
5334 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5338 /* print the line */
5339 /* if not block & function */
5340 if (tree->type == EX_OP &&
5341 (tree->opval.op != FUNCTION &&
5342 tree->opval.op != BLOCK &&
5343 tree->opval.op != NULLOP)) {
5346 if (tree->opval.op == FUNCTION) {
5348 value *args=FUNC_ARGS(tree->left->opval.val->type);
5349 fprintf(outfile,"FUNCTION (%s=%p) type (",
5350 tree->left->opval.val->name, tree);
5351 printTypeChain (tree->left->opval.val->type->next,outfile);
5352 fprintf(outfile,") args (");
5355 fprintf (outfile, ", ");
5357 printTypeChain (args ? args->type : NULL, outfile);
5359 args= args ? args->next : NULL;
5361 fprintf(outfile,")\n");
5362 ast_print(tree->left,outfile,indent);
5363 ast_print(tree->right,outfile,indent);
5366 if (tree->opval.op == BLOCK) {
5367 symbol *decls = tree->values.sym;
5368 INDENT(indent,outfile);
5369 fprintf(outfile,"{\n");
5371 INDENT(indent+2,outfile);
5372 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5373 decls->name, decls);
5374 printTypeChain(decls->type,outfile);
5375 fprintf(outfile,")\n");
5377 decls = decls->next;
5379 ast_print(tree->right,outfile,indent+2);
5380 INDENT(indent,outfile);
5381 fprintf(outfile,"}\n");
5384 if (tree->opval.op == NULLOP) {
5385 ast_print(tree->left,outfile,indent);
5386 ast_print(tree->right,outfile,indent);
5389 INDENT(indent,outfile);
5391 /*------------------------------------------------------------------*/
5392 /*----------------------------*/
5393 /* leaf has been reached */
5394 /*----------------------------*/
5395 /* if this is of type value */
5396 /* just get the type */
5397 if (tree->type == EX_VALUE) {
5399 if (IS_LITERAL (tree->opval.val->etype)) {
5400 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5401 if (SPEC_USIGN (tree->opval.val->etype))
5402 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5404 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5405 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5406 floatFromVal(tree->opval.val));
5407 } else if (tree->opval.val->sym) {
5408 /* if the undefined flag is set then give error message */
5409 if (tree->opval.val->sym->undefined) {
5410 fprintf(outfile,"UNDEFINED SYMBOL ");
5412 fprintf(outfile,"SYMBOL ");
5414 fprintf(outfile,"(%s=%p)",
5415 tree->opval.val->sym->name,tree);
5418 fprintf(outfile," type (");
5419 printTypeChain(tree->ftype,outfile);
5420 fprintf(outfile,")\n");
5422 fprintf(outfile,"\n");
5427 /* if type link for the case of cast */
5428 if (tree->type == EX_LINK) {
5429 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5430 printTypeChain(tree->opval.lnk,outfile);
5431 fprintf(outfile,")\n");
5436 /* depending on type of operator do */
5438 switch (tree->opval.op) {
5439 /*------------------------------------------------------------------*/
5440 /*----------------------------*/
5442 /*----------------------------*/
5444 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5445 printTypeChain(tree->ftype,outfile);
5446 fprintf(outfile,")\n");
5447 ast_print(tree->left,outfile,indent+2);
5448 ast_print(tree->right,outfile,indent+2);
5451 /*------------------------------------------------------------------*/
5452 /*----------------------------*/
5454 /*----------------------------*/
5456 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5457 printTypeChain(tree->ftype,outfile);
5458 fprintf(outfile,")\n");
5459 ast_print(tree->left,outfile,indent+2);
5460 ast_print(tree->right,outfile,indent+2);
5463 /*------------------------------------------------------------------*/
5464 /*----------------------------*/
5465 /* struct/union pointer */
5466 /*----------------------------*/
5468 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5469 printTypeChain(tree->ftype,outfile);
5470 fprintf(outfile,")\n");
5471 ast_print(tree->left,outfile,indent+2);
5472 ast_print(tree->right,outfile,indent+2);
5475 /*------------------------------------------------------------------*/
5476 /*----------------------------*/
5477 /* ++/-- operation */
5478 /*----------------------------*/
5481 fprintf(outfile,"post-");
5483 fprintf(outfile,"pre-");
5484 fprintf(outfile,"INC_OP (%p) type (",tree);
5485 printTypeChain(tree->ftype,outfile);
5486 fprintf(outfile,")\n");
5487 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5488 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5493 fprintf(outfile,"post-");
5495 fprintf(outfile,"pre-");
5496 fprintf(outfile,"DEC_OP (%p) type (",tree);
5497 printTypeChain(tree->ftype,outfile);
5498 fprintf(outfile,")\n");
5499 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5500 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5503 /*------------------------------------------------------------------*/
5504 /*----------------------------*/
5506 /*----------------------------*/
5509 fprintf(outfile,"& (%p) type (",tree);
5510 printTypeChain(tree->ftype,outfile);
5511 fprintf(outfile,")\n");
5512 ast_print(tree->left,outfile,indent+2);
5513 ast_print(tree->right,outfile,indent+2);
5515 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5516 printTypeChain(tree->ftype,outfile);
5517 fprintf(outfile,")\n");
5518 ast_print(tree->left,outfile,indent+2);
5519 ast_print(tree->right,outfile,indent+2);
5522 /*----------------------------*/
5524 /*----------------------------*/
5526 fprintf(outfile,"OR (%p) type (",tree);
5527 printTypeChain(tree->ftype,outfile);
5528 fprintf(outfile,")\n");
5529 ast_print(tree->left,outfile,indent+2);
5530 ast_print(tree->right,outfile,indent+2);
5532 /*------------------------------------------------------------------*/
5533 /*----------------------------*/
5535 /*----------------------------*/
5537 fprintf(outfile,"XOR (%p) type (",tree);
5538 printTypeChain(tree->ftype,outfile);
5539 fprintf(outfile,")\n");
5540 ast_print(tree->left,outfile,indent+2);
5541 ast_print(tree->right,outfile,indent+2);
5544 /*------------------------------------------------------------------*/
5545 /*----------------------------*/
5547 /*----------------------------*/
5549 fprintf(outfile,"DIV (%p) type (",tree);
5550 printTypeChain(tree->ftype,outfile);
5551 fprintf(outfile,")\n");
5552 ast_print(tree->left,outfile,indent+2);
5553 ast_print(tree->right,outfile,indent+2);
5555 /*------------------------------------------------------------------*/
5556 /*----------------------------*/
5558 /*----------------------------*/
5560 fprintf(outfile,"MOD (%p) type (",tree);
5561 printTypeChain(tree->ftype,outfile);
5562 fprintf(outfile,")\n");
5563 ast_print(tree->left,outfile,indent+2);
5564 ast_print(tree->right,outfile,indent+2);
5567 /*------------------------------------------------------------------*/
5568 /*----------------------------*/
5569 /* address dereference */
5570 /*----------------------------*/
5571 case '*': /* can be unary : if right is null then unary operation */
5573 fprintf(outfile,"DEREF (%p) type (",tree);
5574 printTypeChain(tree->ftype,outfile);
5575 fprintf(outfile,")\n");
5576 ast_print(tree->left,outfile,indent+2);
5579 /*------------------------------------------------------------------*/
5580 /*----------------------------*/
5581 /* multiplication */
5582 /*----------------------------*/
5583 fprintf(outfile,"MULT (%p) type (",tree);
5584 printTypeChain(tree->ftype,outfile);
5585 fprintf(outfile,")\n");
5586 ast_print(tree->left,outfile,indent+2);
5587 ast_print(tree->right,outfile,indent+2);
5591 /*------------------------------------------------------------------*/
5592 /*----------------------------*/
5593 /* unary '+' operator */
5594 /*----------------------------*/
5598 fprintf(outfile,"UPLUS (%p) type (",tree);
5599 printTypeChain(tree->ftype,outfile);
5600 fprintf(outfile,")\n");
5601 ast_print(tree->left,outfile,indent+2);
5603 /*------------------------------------------------------------------*/
5604 /*----------------------------*/
5606 /*----------------------------*/
5607 fprintf(outfile,"ADD (%p) type (",tree);
5608 printTypeChain(tree->ftype,outfile);
5609 fprintf(outfile,")\n");
5610 ast_print(tree->left,outfile,indent+2);
5611 ast_print(tree->right,outfile,indent+2);
5614 /*------------------------------------------------------------------*/
5615 /*----------------------------*/
5617 /*----------------------------*/
5618 case '-': /* can be unary */
5620 fprintf(outfile,"UMINUS (%p) type (",tree);
5621 printTypeChain(tree->ftype,outfile);
5622 fprintf(outfile,")\n");
5623 ast_print(tree->left,outfile,indent+2);
5625 /*------------------------------------------------------------------*/
5626 /*----------------------------*/
5628 /*----------------------------*/
5629 fprintf(outfile,"SUB (%p) type (",tree);
5630 printTypeChain(tree->ftype,outfile);
5631 fprintf(outfile,")\n");
5632 ast_print(tree->left,outfile,indent+2);
5633 ast_print(tree->right,outfile,indent+2);
5636 /*------------------------------------------------------------------*/
5637 /*----------------------------*/
5639 /*----------------------------*/
5641 fprintf(outfile,"COMPL (%p) type (",tree);
5642 printTypeChain(tree->ftype,outfile);
5643 fprintf(outfile,")\n");
5644 ast_print(tree->left,outfile,indent+2);
5646 /*------------------------------------------------------------------*/
5647 /*----------------------------*/
5649 /*----------------------------*/
5651 fprintf(outfile,"NOT (%p) type (",tree);
5652 printTypeChain(tree->ftype,outfile);
5653 fprintf(outfile,")\n");
5654 ast_print(tree->left,outfile,indent+2);
5656 /*------------------------------------------------------------------*/
5657 /*----------------------------*/
5659 /*----------------------------*/
5661 fprintf(outfile,"RRC (%p) type (",tree);
5662 printTypeChain(tree->ftype,outfile);
5663 fprintf(outfile,")\n");
5664 ast_print(tree->left,outfile,indent+2);
5668 fprintf(outfile,"RLC (%p) type (",tree);
5669 printTypeChain(tree->ftype,outfile);
5670 fprintf(outfile,")\n");
5671 ast_print(tree->left,outfile,indent+2);
5674 fprintf(outfile,"SWAP (%p) type (",tree);
5675 printTypeChain(tree->ftype,outfile);
5676 fprintf(outfile,")\n");
5677 ast_print(tree->left,outfile,indent+2);
5680 fprintf(outfile,"GETHBIT (%p) type (",tree);
5681 printTypeChain(tree->ftype,outfile);
5682 fprintf(outfile,")\n");
5683 ast_print(tree->left,outfile,indent+2);
5686 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5687 printTypeChain(tree->ftype,outfile);
5688 fprintf(outfile,")\n");
5689 ast_print(tree->left,outfile,indent+2);
5690 ast_print(tree->right,outfile,indent+2);
5693 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5694 printTypeChain(tree->ftype,outfile);
5695 fprintf(outfile,")\n");
5696 ast_print(tree->left,outfile,indent+2);
5697 ast_print(tree->right,outfile,indent+2);
5699 /*------------------------------------------------------------------*/
5700 /*----------------------------*/
5702 /*----------------------------*/
5703 case CAST: /* change the type */
5704 fprintf(outfile,"CAST (%p) from type (",tree);
5705 printTypeChain(tree->right->ftype,outfile);
5706 fprintf(outfile,") to type (");
5707 printTypeChain(tree->ftype,outfile);
5708 fprintf(outfile,")\n");
5709 ast_print(tree->right,outfile,indent+2);
5713 fprintf(outfile,"ANDAND (%p) type (",tree);
5714 printTypeChain(tree->ftype,outfile);
5715 fprintf(outfile,")\n");
5716 ast_print(tree->left,outfile,indent+2);
5717 ast_print(tree->right,outfile,indent+2);
5720 fprintf(outfile,"OROR (%p) type (",tree);
5721 printTypeChain(tree->ftype,outfile);
5722 fprintf(outfile,")\n");
5723 ast_print(tree->left,outfile,indent+2);
5724 ast_print(tree->right,outfile,indent+2);
5727 /*------------------------------------------------------------------*/
5728 /*----------------------------*/
5729 /* comparison operators */
5730 /*----------------------------*/
5732 fprintf(outfile,"GT(>) (%p) type (",tree);
5733 printTypeChain(tree->ftype,outfile);
5734 fprintf(outfile,")\n");
5735 ast_print(tree->left,outfile,indent+2);
5736 ast_print(tree->right,outfile,indent+2);
5739 fprintf(outfile,"LT(<) (%p) type (",tree);
5740 printTypeChain(tree->ftype,outfile);
5741 fprintf(outfile,")\n");
5742 ast_print(tree->left,outfile,indent+2);
5743 ast_print(tree->right,outfile,indent+2);
5746 fprintf(outfile,"LE(<=) (%p) type (",tree);
5747 printTypeChain(tree->ftype,outfile);
5748 fprintf(outfile,")\n");
5749 ast_print(tree->left,outfile,indent+2);
5750 ast_print(tree->right,outfile,indent+2);
5753 fprintf(outfile,"GE(>=) (%p) type (",tree);
5754 printTypeChain(tree->ftype,outfile);
5755 fprintf(outfile,")\n");
5756 ast_print(tree->left,outfile,indent+2);
5757 ast_print(tree->right,outfile,indent+2);
5760 fprintf(outfile,"EQ(==) (%p) type (",tree);
5761 printTypeChain(tree->ftype,outfile);
5762 fprintf(outfile,")\n");
5763 ast_print(tree->left,outfile,indent+2);
5764 ast_print(tree->right,outfile,indent+2);
5767 fprintf(outfile,"NE(!=) (%p) type (",tree);
5768 printTypeChain(tree->ftype,outfile);
5769 fprintf(outfile,")\n");
5770 ast_print(tree->left,outfile,indent+2);
5771 ast_print(tree->right,outfile,indent+2);
5772 /*------------------------------------------------------------------*/
5773 /*----------------------------*/
5775 /*----------------------------*/
5776 case SIZEOF: /* evaluate wihout code generation */
5777 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5780 /*------------------------------------------------------------------*/
5781 /*----------------------------*/
5782 /* conditional operator '?' */
5783 /*----------------------------*/
5785 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5786 printTypeChain(tree->ftype,outfile);
5787 fprintf(outfile,")\n");
5788 ast_print(tree->left,outfile,indent+2);
5789 ast_print(tree->right,outfile,indent+2);
5793 fprintf(outfile,"COLON(:) (%p) type (",tree);
5794 printTypeChain(tree->ftype,outfile);
5795 fprintf(outfile,")\n");
5796 ast_print(tree->left,outfile,indent+2);
5797 ast_print(tree->right,outfile,indent+2);
5800 /*------------------------------------------------------------------*/
5801 /*----------------------------*/
5802 /* assignment operators */
5803 /*----------------------------*/
5805 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5806 printTypeChain(tree->ftype,outfile);
5807 fprintf(outfile,")\n");
5808 ast_print(tree->left,outfile,indent+2);
5809 ast_print(tree->right,outfile,indent+2);
5812 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5813 printTypeChain(tree->ftype,outfile);
5814 fprintf(outfile,")\n");
5815 ast_print(tree->left,outfile,indent+2);
5816 ast_print(tree->right,outfile,indent+2);
5819 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5820 printTypeChain(tree->ftype,outfile);
5821 fprintf(outfile,")\n");
5822 ast_print(tree->left,outfile,indent+2);
5823 ast_print(tree->right,outfile,indent+2);
5826 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5827 printTypeChain(tree->ftype,outfile);
5828 fprintf(outfile,")\n");
5829 ast_print(tree->left,outfile,indent+2);
5830 ast_print(tree->right,outfile,indent+2);
5833 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5834 printTypeChain(tree->ftype,outfile);
5835 fprintf(outfile,")\n");
5836 ast_print(tree->left,outfile,indent+2);
5837 ast_print(tree->right,outfile,indent+2);
5840 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5841 printTypeChain(tree->ftype,outfile);
5842 fprintf(outfile,")\n");
5843 ast_print(tree->left,outfile,indent+2);
5844 ast_print(tree->right,outfile,indent+2);
5847 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5848 printTypeChain(tree->ftype,outfile);
5849 fprintf(outfile,")\n");
5850 ast_print(tree->left,outfile,indent+2);
5851 ast_print(tree->right,outfile,indent+2);
5853 /*------------------------------------------------------------------*/
5854 /*----------------------------*/
5856 /*----------------------------*/
5858 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5859 printTypeChain(tree->ftype,outfile);
5860 fprintf(outfile,")\n");
5861 ast_print(tree->left,outfile,indent+2);
5862 ast_print(tree->right,outfile,indent+2);
5864 /*------------------------------------------------------------------*/
5865 /*----------------------------*/
5867 /*----------------------------*/
5869 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5870 printTypeChain(tree->ftype,outfile);
5871 fprintf(outfile,")\n");
5872 ast_print(tree->left,outfile,indent+2);
5873 ast_print(tree->right,outfile,indent+2);
5875 /*------------------------------------------------------------------*/
5876 /*----------------------------*/
5877 /* straight assignemnt */
5878 /*----------------------------*/
5880 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5881 printTypeChain(tree->ftype,outfile);
5882 fprintf(outfile,")\n");
5883 ast_print(tree->left,outfile,indent+2);
5884 ast_print(tree->right,outfile,indent+2);
5886 /*------------------------------------------------------------------*/
5887 /*----------------------------*/
5888 /* comma operator */
5889 /*----------------------------*/
5891 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5892 printTypeChain(tree->ftype,outfile);
5893 fprintf(outfile,")\n");
5894 ast_print(tree->left,outfile,indent+2);
5895 ast_print(tree->right,outfile,indent+2);
5897 /*------------------------------------------------------------------*/
5898 /*----------------------------*/
5900 /*----------------------------*/
5903 fprintf(outfile,"CALL (%p) type (",tree);
5904 printTypeChain(tree->ftype,outfile);
5905 fprintf(outfile,")\n");
5906 ast_print(tree->left,outfile,indent+2);
5907 ast_print(tree->right,outfile,indent+2);
5910 fprintf(outfile,"PARMS\n");
5911 ast_print(tree->left,outfile,indent+2);
5912 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5913 ast_print(tree->right,outfile,indent+2);
5916 /*------------------------------------------------------------------*/
5917 /*----------------------------*/
5918 /* return statement */
5919 /*----------------------------*/
5921 fprintf(outfile,"RETURN (%p) type (",tree);
5923 printTypeChain(tree->right->ftype,outfile);
5925 fprintf(outfile,")\n");
5926 ast_print(tree->right,outfile,indent+2);
5928 /*------------------------------------------------------------------*/
5929 /*----------------------------*/
5930 /* label statement */
5931 /*----------------------------*/
5933 fprintf(outfile,"LABEL (%p)\n",tree);
5934 ast_print(tree->left,outfile,indent+2);
5935 ast_print(tree->right,outfile,indent);
5937 /*------------------------------------------------------------------*/
5938 /*----------------------------*/
5939 /* switch statement */
5940 /*----------------------------*/
5944 fprintf(outfile,"SWITCH (%p) ",tree);
5945 ast_print(tree->left,outfile,0);
5946 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5947 INDENT(indent+2,outfile);
5948 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5949 (int) floatFromVal(val),
5950 tree->values.switchVals.swNum,
5951 (int) floatFromVal(val));
5953 ast_print(tree->right,outfile,indent);
5956 /*------------------------------------------------------------------*/
5957 /*----------------------------*/
5959 /*----------------------------*/
5961 fprintf(outfile,"IF (%p) \n",tree);
5962 ast_print(tree->left,outfile,indent+2);
5963 if (tree->trueLabel) {
5964 INDENT(indent+2,outfile);
5965 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5967 if (tree->falseLabel) {
5968 INDENT(indent+2,outfile);
5969 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5971 ast_print(tree->right,outfile,indent+2);
5973 /*----------------------------*/
5974 /* goto Statement */
5975 /*----------------------------*/
5977 fprintf(outfile,"GOTO (%p) \n",tree);
5978 ast_print(tree->left,outfile,indent+2);
5979 fprintf(outfile,"\n");
5981 /*------------------------------------------------------------------*/
5982 /*----------------------------*/
5984 /*----------------------------*/
5986 fprintf(outfile,"FOR (%p) \n",tree);
5987 if (AST_FOR( tree, initExpr)) {
5988 INDENT(indent+2,outfile);
5989 fprintf(outfile,"INIT EXPR ");
5990 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5992 if (AST_FOR( tree, condExpr)) {
5993 INDENT(indent+2,outfile);
5994 fprintf(outfile,"COND EXPR ");
5995 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5997 if (AST_FOR( tree, loopExpr)) {
5998 INDENT(indent+2,outfile);
5999 fprintf(outfile,"LOOP EXPR ");
6000 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6002 fprintf(outfile,"FOR LOOP BODY \n");
6003 ast_print(tree->left,outfile,indent+2);
6006 fprintf(outfile,"CRITICAL (%p) \n",tree);
6007 ast_print(tree->left,outfile,indent+2);
6015 ast_print(t,stdout,0);
6020 /*-----------------------------------------------------------------*/
6021 /* astErrors : returns non-zero if errors present in tree */
6022 /*-----------------------------------------------------------------*/
6023 int astErrors(ast *t)
6032 if (t->type == EX_VALUE
6033 && t->opval.val->sym
6034 && t->opval.val->sym->undefined)
6037 errors += astErrors(t->left);
6038 errors += astErrors(t->right);