1 /*-------------------------------------------------------------------------
2 SDCCast.c - source file for parser support & all ast related routines
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
25 #define DEBUG_CF(x) /* puts(x); */
31 set *operKeyReset = NULL;
32 ast *staticAutos = NULL;
35 #define LRVAL(x) x->left->rvalue
36 #define RRVAL(x) x->right->rvalue
37 #define TRVAL(x) x->rvalue
38 #define LLVAL(x) x->left->lvalue
39 #define RLVAL(x) x->right->lvalue
40 #define TLVAL(x) x->lvalue
41 #define RTYPE(x) x->right->ftype
42 #define RETYPE(x) x->right->etype
43 #define LTYPE(x) x->left->ftype
44 #define LETYPE(x) x->left->etype
45 #define TTYPE(x) x->ftype
46 #define TETYPE(x) x->etype
52 symbol *currFunc=NULL;
53 static ast *createIval (ast *, sym_link *, initList *, ast *);
54 static ast *createIvalCharPtr (ast *, sym_link *, ast *);
55 static ast *optimizeCompare (ast *);
56 ast *optimizeRRCRLC (ast *);
57 ast *optimizeSWAP (ast *);
58 ast *optimizeGetHbit (ast *);
59 ast *backPatchLabels (ast *, symbol *, symbol *);
62 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
67 printTypeChain (tree->ftype, stdout);
72 /*-----------------------------------------------------------------*/
73 /* newAst - creates a fresh node for an expression tree */
74 /*-----------------------------------------------------------------*/
76 newAst_ (unsigned type)
79 static int oldLineno = 0;
81 ex = Safe_alloc ( sizeof (ast));
84 ex->lineno = (noLineno ? oldLineno : mylineno);
85 ex->filename = currFname;
86 ex->level = NestLevel;
87 ex->block = currBlockno;
88 ex->initMode = inInitMode;
89 ex->seqPoint = seqPointNo;
94 newAst_VALUE (value * val)
96 ast *ex = newAst_ (EX_VALUE);
102 newAst_OP (unsigned op)
104 ast *ex = newAst_ (EX_OP);
110 newAst_LINK (sym_link * val)
112 ast *ex = newAst_ (EX_LINK);
117 /*-----------------------------------------------------------------*/
118 /* newNode - creates a new node */
119 /*-----------------------------------------------------------------*/
121 newNode (long op, ast * left, ast * right)
132 /*-----------------------------------------------------------------*/
133 /* newIfxNode - creates a new Ifx Node */
134 /*-----------------------------------------------------------------*/
136 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
140 /* if this is a literal then we already know the result */
141 if (condAst->etype && IS_LITERAL (condAst->etype))
143 /* then depending on the expression value */
144 if (floatFromVal (condAst->opval.val))
145 ifxNode = newNode (GOTO,
146 newAst_VALUE (symbolVal (trueLabel)),
149 ifxNode = newNode (GOTO,
150 newAst_VALUE (symbolVal (falseLabel)),
155 ifxNode = newNode (IFX, condAst, NULL);
156 ifxNode->trueLabel = trueLabel;
157 ifxNode->falseLabel = falseLabel;
163 /*-----------------------------------------------------------------*/
164 /* copyAstValues - copies value portion of ast if needed */
165 /*-----------------------------------------------------------------*/
167 copyAstValues (ast * dest, ast * src)
169 switch (src->opval.op)
172 dest->values.sym = copySymbolChain (src->values.sym);
176 dest->values.switchVals.swVals =
177 copyValue (src->values.switchVals.swVals);
178 dest->values.switchVals.swDefault =
179 src->values.switchVals.swDefault;
180 dest->values.switchVals.swNum =
181 src->values.switchVals.swNum;
185 dest->values.inlineasm = Safe_strdup(src->values.inlineasm);
189 dest->values.constlist = copyLiteralList(src->values.constlist);
193 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
194 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
195 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
196 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
197 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
198 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
199 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
204 /*-----------------------------------------------------------------*/
205 /* copyAst - makes a copy of a given astession */
206 /*-----------------------------------------------------------------*/
215 dest = Safe_alloc ( sizeof (ast));
217 dest->type = src->type;
218 dest->lineno = src->lineno;
219 dest->level = src->level;
220 dest->funcName = src->funcName;
221 dest->reversed = src->reversed;
224 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
226 /* if this is a leaf */
228 if (src->type == EX_VALUE)
230 dest->opval.val = copyValue (src->opval.val);
235 if (src->type == EX_LINK)
237 dest->opval.lnk = copyLinkChain (src->opval.lnk);
241 dest->opval.op = src->opval.op;
243 /* if this is a node that has special values */
244 copyAstValues (dest, src);
246 dest->trueLabel = copySymbol (src->trueLabel);
247 dest->falseLabel = copySymbol (src->falseLabel);
248 dest->left = copyAst (src->left);
249 dest->right = copyAst (src->right);
255 /*-----------------------------------------------------------------*/
256 /* removeIncDecOps: remove for side effects in *_ASSIGN's */
257 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
258 /*-----------------------------------------------------------------*/
259 ast *removeIncDecOps (ast * tree) {
261 // traverse the tree and remove inc/dec ops
266 if (tree->type == EX_OP &&
267 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
274 tree->left=removeIncDecOps(tree->left);
275 tree->right=removeIncDecOps(tree->right);
280 /*-----------------------------------------------------------------*/
281 /* removePreIncDecOps: remove for side effects in *_ASSIGN's */
282 /* "*++s += 3" -> "*++s = *++s + 3" */
283 /*-----------------------------------------------------------------*/
284 ast *removePreIncDecOps (ast * tree) {
286 // traverse the tree and remove pre-inc/dec ops
291 if (tree->type == EX_OP &&
292 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
297 tree->left=removePreIncDecOps(tree->left);
298 tree->right=removePreIncDecOps(tree->right);
303 /*-----------------------------------------------------------------*/
304 /* removePostIncDecOps: remove for side effects in *_ASSIGN's */
305 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
306 /*-----------------------------------------------------------------*/
307 ast *removePostIncDecOps (ast * tree) {
309 // traverse the tree and remove pre-inc/dec ops
314 if (tree->type == EX_OP &&
315 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
320 tree->left=removePostIncDecOps(tree->left);
321 tree->right=removePostIncDecOps(tree->right);
326 /*-----------------------------------------------------------------*/
327 /* hasSEFcalls - returns TRUE if tree has a function call */
328 /*-----------------------------------------------------------------*/
330 hasSEFcalls (ast * tree)
335 if (tree->type == EX_OP &&
336 (tree->opval.op == CALL ||
337 tree->opval.op == PCALL ||
338 tree->opval.op == '=' ||
339 tree->opval.op == INC_OP ||
340 tree->opval.op == DEC_OP))
343 return (hasSEFcalls (tree->left) |
344 hasSEFcalls (tree->right));
347 /*-----------------------------------------------------------------*/
348 /* isAstEqual - compares two asts & returns 1 if they are equal */
349 /*-----------------------------------------------------------------*/
351 isAstEqual (ast * t1, ast * t2)
360 if (t1->type != t2->type)
366 if (t1->opval.op != t2->opval.op)
368 return (isAstEqual (t1->left, t2->left) &&
369 isAstEqual (t1->right, t2->right));
373 if (t1->opval.val->sym)
375 if (!t2->opval.val->sym)
378 return isSymbolEqual (t1->opval.val->sym,
383 if (t2->opval.val->sym)
386 return (floatFromVal (t1->opval.val) ==
387 floatFromVal (t2->opval.val));
391 /* only compare these two types */
399 /*-----------------------------------------------------------------*/
400 /* resolveSymbols - resolve symbols from the symbol table */
401 /*-----------------------------------------------------------------*/
403 resolveSymbols (ast * tree)
405 /* walk the entire tree and check for values */
406 /* with symbols if we find one then replace */
407 /* symbol with that from the symbol table */
414 /* if not block & function */
415 if (tree->type == EX_OP &&
416 (tree->opval.op != FUNCTION &&
417 tree->opval.op != BLOCK &&
418 tree->opval.op != NULLOP))
420 filename = tree->filename;
421 lineno = tree->lineno;
425 /* make sure we resolve the true & false labels for ifx */
426 if (tree->type == EX_OP && tree->opval.op == IFX)
432 if ((csym = findSym (LabelTab, tree->trueLabel,
433 tree->trueLabel->name)))
434 tree->trueLabel = csym;
436 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
437 tree->trueLabel->name);
440 if (tree->falseLabel)
442 if ((csym = findSym (LabelTab,
444 tree->falseLabel->name)))
445 tree->falseLabel = csym;
447 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
448 tree->falseLabel->name);
453 /* if this is a label resolve it from the labelTab */
454 if (IS_AST_VALUE (tree) &&
455 tree->opval.val->sym &&
456 tree->opval.val->sym->islbl)
459 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
460 tree->opval.val->sym->name);
463 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
464 tree->opval.val->sym->name);
466 tree->opval.val->sym = csym;
468 goto resolveChildren;
471 /* do only for leafs */
472 if (IS_AST_VALUE (tree) &&
473 tree->opval.val->sym &&
474 !tree->opval.val->sym->implicit)
477 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
479 /* if found in the symbol table & they r not the same */
480 if (csym && tree->opval.val->sym != csym)
482 tree->opval.val->sym = csym;
483 tree->opval.val->type = csym->type;
484 tree->opval.val->etype = csym->etype;
487 /* if not found in the symbol table */
488 /* mark it as undefined assume it is */
489 /* an integer in data space */
490 if (!csym && !tree->opval.val->sym->implicit)
493 /* if this is a function name then */
494 /* mark it as returning an int */
497 tree->opval.val->sym->type = newLink (DECLARATOR);
498 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
499 tree->opval.val->sym->type->next =
500 tree->opval.val->sym->etype = newIntLink ();
501 tree->opval.val->etype = tree->opval.val->etype;
502 tree->opval.val->type = tree->opval.val->sym->type;
503 werrorfl (tree->filename, tree->lineno, W_IMPLICIT_FUNC,
504 tree->opval.val->sym->name);
505 //tree->opval.val->sym->undefined = 1;
506 allocVariables (tree->opval.val->sym);
510 tree->opval.val->sym->undefined = 1;
511 tree->opval.val->type =
512 tree->opval.val->etype = newIntLink ();
513 tree->opval.val->sym->type =
514 tree->opval.val->sym->etype = newIntLink ();
520 resolveSymbols (tree->left);
521 resolveSymbols (tree->right);
526 /*-----------------------------------------------------------------*/
527 /* setAstLineno - walks a ast tree & sets the line number */
528 /*-----------------------------------------------------------------*/
529 int setAstLineno (ast * tree, int lineno)
534 tree->lineno = lineno;
535 setAstLineno (tree->left, lineno);
536 setAstLineno (tree->right, lineno);
540 /*-----------------------------------------------------------------*/
541 /* funcOfType :- function of type with name */
542 /*-----------------------------------------------------------------*/
544 funcOfType (char *name, sym_link * type, sym_link * argType,
548 /* create the symbol */
549 sym = newSymbol (name, 0);
551 /* setup return value */
552 sym->type = newLink (DECLARATOR);
553 DCL_TYPE (sym->type) = FUNCTION;
554 sym->type->next = copyLinkChain (type);
555 sym->etype = getSpec (sym->type);
556 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
558 /* if arguments required */
562 args = FUNC_ARGS(sym->type) = newValue ();
566 args->type = copyLinkChain (argType);
567 args->etype = getSpec (args->type);
568 SPEC_EXTR(args->etype)=1;
571 args = args->next = newValue ();
578 allocVariables (sym);
583 /*-----------------------------------------------------------------*/
584 /* funcOfTypeVarg :- function of type with name and argtype */
585 /*-----------------------------------------------------------------*/
587 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
592 /* create the symbol */
593 sym = newSymbol (name, 0);
595 /* setup return value */
596 sym->type = newLink (DECLARATOR);
597 DCL_TYPE (sym->type) = FUNCTION;
598 sym->type->next = typeFromStr(rtype);
599 sym->etype = getSpec (sym->type);
601 /* if arguments required */
604 args = FUNC_ARGS(sym->type) = newValue ();
606 for ( i = 0 ; i < nArgs ; i++ ) {
607 args->type = typeFromStr(atypes[i]);
608 args->etype = getSpec (args->type);
609 SPEC_EXTR(args->etype)=1;
610 if ((i + 1) == nArgs) break;
611 args = args->next = newValue ();
618 allocVariables (sym);
623 /*-----------------------------------------------------------------*/
624 /* reverseParms - will reverse a parameter tree */
625 /*-----------------------------------------------------------------*/
627 reverseParms (ast * ptree)
633 /* top down if we find a nonParm tree then quit */
634 if (ptree->type == EX_OP && ptree->opval.op == PARAM && !ptree->reversed)
636 /* The various functions expect the parameter tree to be right heavy. */
637 /* Rotate the tree to be left heavy so that after reversal it is */
638 /* right heavy again. */
639 while ((ttree = ptree->right) && ttree->type == EX_OP &&
640 ttree->opval.op == PARAM)
642 ptree->right = ttree->right;
643 ttree->right = ttree->left;
644 ttree->left = ptree->left;
650 ptree->left = ptree->right;
651 ptree->right = ttree;
653 reverseParms (ptree->left);
654 reverseParms (ptree->right);
660 /*-----------------------------------------------------------------*/
661 /* processParms - makes sure the parameters are okay and do some */
662 /* processing with them */
663 /*-----------------------------------------------------------------*/
665 processParms (ast *func,
668 int *parmNumber, /* unused, although updated */
671 RESULT_TYPE resultType;
674 /* if none of them exist */
675 if (!defParm && !*actParm)
680 if (getenv("DEBUG_SANITY"))
682 fprintf (stderr, "processParms: %s ", defParm->name);
684 /* make sure the type is complete and sane */
685 checkTypeSanity(defParm->etype, defParm->name);
688 if (IS_CODEPTR (func->ftype))
689 functype = func->ftype->next;
691 functype = func->ftype;
693 /* if the function is being called via a pointer & */
694 /* it has not been defined a reentrant then we cannot */
695 /* have parameters */
696 /* PIC16 port can... */
697 if (!TARGET_IS_PIC16)
699 if (func->type != EX_VALUE && !IFFUNC_ISREENT (functype) && !options.stackAuto)
701 werror (W_NONRENT_ARGS);
707 /* if defined parameters ended but actual parameters */
708 /* exist and this is not defined as a variable arg */
709 if (!defParm && *actParm && !IFFUNC_HASVARARGS(functype))
711 werror (E_TOO_MANY_PARMS);
715 /* if defined parameters present but no actual parameters */
716 if (defParm && !*actParm)
718 werror (E_TOO_FEW_PARMS);
722 /* if this is a PARAM node then match left & right */
723 if ((*actParm)->type == EX_OP && (*actParm)->opval.op == PARAM)
725 (*actParm)->decorated = 1;
726 return (processParms (func, defParm,
727 &(*actParm)->left, parmNumber, FALSE) ||
728 processParms (func, defParm ? defParm->next : NULL,
729 &(*actParm)->right, parmNumber, rightmost));
731 else if (defParm) /* not vararg */
733 /* If we have found a value node by following only right-hand links,
734 * then we know that there are no more values after us.
736 * Therefore, if there are more defined parameters, the caller didn't
739 if (rightmost && defParm->next)
741 werror (E_TOO_FEW_PARMS);
746 /* decorate parameter */
747 resultType = defParm ? getResultTypeFromType (defParm->etype) :
749 *actParm = decorateType (*actParm, resultType);
751 if (IS_VOID((*actParm)->ftype))
753 werror (E_VOID_VALUE_USED);
757 /* If this is a varargs function... */
758 if (!defParm && *actParm && IFFUNC_HASVARARGS(functype))
763 if (IS_CAST_OP (*actParm)
764 || (IS_AST_LIT_VALUE (*actParm) && (*actParm)->values.literalFromCast))
766 /* Parameter was explicitly typecast; don't touch it. */
770 ftype = (*actParm)->ftype;
772 /* If it's a char, upcast to int. */
773 if (IS_INTEGRAL (ftype)
774 && (getSize (ftype) < (unsigned) INTSIZE))
776 newType = newAst_LINK(INTTYPE);
779 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
781 newType = newAst_LINK (copyLinkChain(ftype));
782 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
785 if (IS_AGGREGATE (ftype))
787 newType = newAst_LINK (copyLinkChain (ftype));
788 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
793 /* cast required; change this op to a cast. */
794 (*actParm)->decorated = 0;
795 *actParm = newNode (CAST, newType, *actParm);
796 (*actParm)->lineno = (*actParm)->right->lineno;
798 decorateType (*actParm, RESULT_TYPE_NONE);
803 /* if defined parameters ended but actual has not & */
805 if (!defParm && *actParm &&
806 (options.stackAuto || IFFUNC_ISREENT (functype)))
809 resolveSymbols (*actParm);
811 /* the parameter type must be at least castable */
812 if (compareType (defParm->type, (*actParm)->ftype) == 0)
814 werror (E_INCOMPAT_TYPES);
815 printFromToType ((*actParm)->ftype, defParm->type);
819 /* if the parameter is castable then add the cast */
820 if (compareType (defParm->type, (*actParm)->ftype) < 0)
824 resultType = getResultTypeFromType (defParm->etype);
825 pTree = resolveSymbols (copyAst (*actParm));
827 /* now change the current one to a cast */
828 (*actParm)->type = EX_OP;
829 (*actParm)->opval.op = CAST;
830 (*actParm)->left = newAst_LINK (defParm->type);
831 (*actParm)->right = pTree;
832 (*actParm)->decorated = 0; /* force typechecking */
833 decorateType (*actParm, resultType);
836 /* make a copy and change the regparm type to the defined parm */
837 (*actParm)->etype = getSpec ((*actParm)->ftype = copyLinkChain ((*actParm)->ftype));
838 SPEC_REGPARM ((*actParm)->etype) = SPEC_REGPARM (defParm->etype);
839 SPEC_ARGREG ((*actParm)->etype) = SPEC_ARGREG (defParm->etype);
844 /*-----------------------------------------------------------------*/
845 /* createIvalType - generates ival for basic types */
846 /*-----------------------------------------------------------------*/
848 createIvalType (ast * sym, sym_link * type, initList * ilist)
852 /* if initList is deep */
853 if (ilist->type == INIT_DEEP)
854 ilist = ilist->init.deep;
856 iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
857 return decorateType (newNode ('=', sym, iExpr), RESULT_TYPE_NONE);
860 /*-----------------------------------------------------------------*/
861 /* createIvalStruct - generates initial value for structures */
862 /*-----------------------------------------------------------------*/
864 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
871 sflds = SPEC_STRUCT (type)->fields;
872 if (ilist->type != INIT_DEEP)
874 werror (E_INIT_STRUCT, "");
878 iloop = ilist->init.deep;
880 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
882 /* if we have come to end */
886 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
887 lAst = decorateType (resolveSymbols (lAst), RESULT_TYPE_NONE);
888 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)), RESULT_TYPE_NONE);
892 werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
893 W_EXCESS_INITIALIZERS, "struct",
894 sym->opval.val->sym->name);
901 /*-----------------------------------------------------------------*/
902 /* createIvalArray - generates code for array initialization */
903 /*-----------------------------------------------------------------*/
905 createIvalArray (ast * sym, sym_link * type, initList * ilist)
909 int lcnt = 0, size = 0;
910 literalList *literalL;
912 /* take care of the special case */
913 /* array of characters can be init */
915 if (IS_CHAR (type->next))
916 if ((rast = createIvalCharPtr (sym,
918 decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE))))
920 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
922 /* not the special case */
923 if (ilist->type != INIT_DEEP)
925 werror (E_INIT_STRUCT, "");
929 iloop = ilist->init.deep;
930 lcnt = DCL_ELEM (type);
932 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
936 aSym = decorateType (resolveSymbols(sym), RESULT_TYPE_NONE);
938 rast = newNode(ARRAYINIT, aSym, NULL);
939 rast->values.constlist = literalL;
941 // Make sure size is set to length of initializer list.
948 if (lcnt && size > lcnt)
950 // Array size was specified, and we have more initializers than needed.
951 char *name=sym->opval.val->sym->name;
952 int lineno=sym->opval.val->sym->lineDef;
953 char *filename=sym->opval.val->sym->fileDef;
955 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
964 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
965 aSym = decorateType (resolveSymbols (aSym), RESULT_TYPE_NONE);
966 rast = createIval (aSym, type->next, iloop, rast);
967 iloop = (iloop ? iloop->next : NULL);
973 /* no of elements given and we */
974 /* have generated for all of them */
977 // is this a better way? at least it won't crash
978 char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
979 int lineno = iloop->lineno;
980 char *filename = iloop->filename;
981 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
988 /* if we have not been given a size */
989 if (!DCL_ELEM (type))
991 /* but this still updates the typedef instead of the instance ! see bug 770487 */
992 DCL_ELEM (type) = size;
995 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
999 /*-----------------------------------------------------------------*/
1000 /* createIvalCharPtr - generates initial values for char pointers */
1001 /*-----------------------------------------------------------------*/
1003 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
1007 /* if this is a pointer & right is a literal array then */
1008 /* just assignment will do */
1009 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
1010 SPEC_SCLS (iexpr->etype) == S_CODE)
1011 && IS_ARRAY (iexpr->ftype)))
1012 return newNode ('=', sym, iexpr);
1014 /* left side is an array so we have to assign each */
1016 if ((IS_LITERAL (iexpr->etype) ||
1017 SPEC_SCLS (iexpr->etype) == S_CODE)
1018 && IS_ARRAY (iexpr->ftype))
1020 /* for each character generate an assignment */
1021 /* to the array element */
1022 char *s = SPEC_CVAL (iexpr->etype).v_char;
1024 int size = getSize (iexpr->ftype);
1025 int symsize = getSize (type);
1029 if (size>(symsize+1))
1030 werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1031 "string", sym->opval.val->sym->name);
1035 for (i=0;i<size;i++)
1037 rast = newNode (NULLOP,
1041 newAst_VALUE (valueFromLit ((float) i))),
1042 newAst_VALUE (valueFromLit (*s))));
1046 // now WE don't need iexpr's symbol anymore
1047 freeStringSymbol(AST_SYMBOL(iexpr));
1049 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1055 /*-----------------------------------------------------------------*/
1056 /* createIvalPtr - generates initial value for pointers */
1057 /*-----------------------------------------------------------------*/
1059 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
1065 if (ilist->type == INIT_DEEP)
1066 ilist = ilist->init.deep;
1068 iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
1070 /* if character pointer */
1071 if (IS_CHAR (type->next))
1072 if ((rast = createIvalCharPtr (sym, type, iexpr)))
1075 return newNode ('=', sym, iexpr);
1078 /*-----------------------------------------------------------------*/
1079 /* createIval - generates code for initial value */
1080 /*-----------------------------------------------------------------*/
1082 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1089 /* if structure then */
1090 if (IS_STRUCT (type))
1091 rast = createIvalStruct (sym, type, ilist);
1093 /* if this is a pointer */
1095 rast = createIvalPtr (sym, type, ilist);
1097 /* if this is an array */
1098 if (IS_ARRAY (type))
1099 rast = createIvalArray (sym, type, ilist);
1101 /* if type is SPECIFIER */
1103 rast = createIvalType (sym, type, ilist);
1106 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_TYPE_NONE);
1108 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1111 /*-----------------------------------------------------------------*/
1112 /* initAggregates - initialises aggregate variables with initv */
1113 /*-----------------------------------------------------------------*/
1114 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1115 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1118 /*-----------------------------------------------------------------*/
1119 /* gatherAutoInit - creates assignment expressions for initial */
1121 /*-----------------------------------------------------------------*/
1123 gatherAutoInit (symbol * autoChain)
1130 for (sym = autoChain; sym; sym = sym->next)
1133 /* resolve the symbols in the ival */
1135 resolveIvalSym (sym->ival, sym->type);
1138 /* if we are PIC16 port,
1139 * and this is a static,
1140 * and have initial value,
1141 * and not S_CODE, don't emit in gs segment,
1142 * but allow glue.c:pic16emitRegularMap to put symbol
1143 * in idata section */
1144 if(TARGET_IS_PIC16 &&
1145 IS_STATIC (sym->etype) && sym->ival
1146 && SPEC_SCLS(sym->etype) != S_CODE) {
1147 SPEC_SCLS (sym->etype) = S_DATA;
1152 /* if this is a static variable & has an */
1153 /* initial value the code needs to be lifted */
1154 /* here to the main portion since they can be */
1155 /* initialised only once at the start */
1156 if (IS_STATIC (sym->etype) && sym->ival &&
1157 SPEC_SCLS (sym->etype) != S_CODE)
1161 /* insert the symbol into the symbol table */
1162 /* with level = 0 & name = rname */
1163 newSym = copySymbol (sym);
1164 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1166 /* now lift the code to main */
1167 if (IS_AGGREGATE (sym->type)) {
1168 work = initAggregates (sym, sym->ival, NULL);
1170 if (getNelements(sym->type, sym->ival)>1) {
1171 werrorfl (sym->fileDef, sym->lineDef,
1172 W_EXCESS_INITIALIZERS, "scalar",
1175 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1176 list2expr (sym->ival));
1179 setAstLineno (work, sym->lineDef);
1183 staticAutos = newNode (NULLOP, staticAutos, work);
1190 /* if there is an initial value */
1191 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1193 initList *ilist=sym->ival;
1195 while (ilist->type == INIT_DEEP) {
1196 ilist = ilist->init.deep;
1199 /* update lineno for error msg */
1200 lineno=sym->lineDef;
1201 setAstLineno (ilist->init.node, lineno);
1203 if (IS_AGGREGATE (sym->type)) {
1204 work = initAggregates (sym, sym->ival, NULL);
1206 if (getNelements(sym->type, sym->ival)>1) {
1207 werrorfl (sym->fileDef, sym->lineDef,
1208 W_EXCESS_INITIALIZERS, "scalar",
1211 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1212 list2expr (sym->ival));
1216 setAstLineno (work, sym->lineDef);
1220 init = newNode (NULLOP, init, work);
1229 /*-----------------------------------------------------------------*/
1230 /* freeStringSymbol - delete a literal string if no more usage */
1231 /*-----------------------------------------------------------------*/
1232 void freeStringSymbol(symbol *sym) {
1233 /* make sure this is a literal string */
1234 assert (sym->isstrlit);
1235 if (--sym->isstrlit == 0) { // lower the usage count
1236 memmap *segment=SPEC_OCLS(sym->etype);
1238 deleteSetItem(&segment->syms, sym);
1243 /*-----------------------------------------------------------------*/
1244 /* stringToSymbol - creates a symbol from a literal string */
1245 /*-----------------------------------------------------------------*/
1247 stringToSymbol (value * val)
1249 char name[SDCC_NAME_MAX + 1];
1250 static int charLbl = 0;
1255 // have we heard this before?
1256 for (sp=statsg->syms; sp; sp=sp->next) {
1258 size = getSize (sym->type);
1259 if (sym->isstrlit && size == getSize (val->type) &&
1260 !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1261 // yes, this is old news. Don't publish it again.
1262 sym->isstrlit++; // but raise the usage count
1263 return symbolVal(sym);
1267 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1268 sym = newSymbol (name, 0); /* make it @ level 0 */
1269 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1271 /* copy the type from the value passed */
1272 sym->type = copyLinkChain (val->type);
1273 sym->etype = getSpec (sym->type);
1274 /* change to storage class & output class */
1275 SPEC_SCLS (sym->etype) = S_CODE;
1276 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1277 SPEC_STAT (sym->etype) = 1;
1278 /* make the level & block = 0 */
1279 sym->block = sym->level = 0;
1281 /* create an ival */
1282 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1287 allocVariables (sym);
1290 return symbolVal (sym);
1294 /*-----------------------------------------------------------------*/
1295 /* processBlockVars - will go thru the ast looking for block if */
1296 /* a block is found then will allocate the syms */
1297 /* will also gather the auto inits present */
1298 /*-----------------------------------------------------------------*/
1300 processBlockVars (ast * tree, int *stack, int action)
1305 /* if this is a block */
1306 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1310 if (action == ALLOCATE)
1312 *stack += allocVariables (tree->values.sym);
1313 autoInit = gatherAutoInit (tree->values.sym);
1315 /* if there are auto inits then do them */
1317 tree->left = newNode (NULLOP, autoInit, tree->left);
1319 else /* action is deallocate */
1320 deallocLocal (tree->values.sym);
1323 processBlockVars (tree->left, stack, action);
1324 processBlockVars (tree->right, stack, action);
1329 /*-------------------------------------------------------------*/
1330 /* constExprTree - returns TRUE if this tree is a constant */
1332 /*-------------------------------------------------------------*/
1333 bool constExprTree (ast *cexpr) {
1339 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1341 switch (cexpr->type)
1344 if (IS_AST_LIT_VALUE(cexpr)) {
1345 // this is a literal
1348 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1349 // a function's address will never change
1352 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1353 // an array's address will never change
1356 if (IS_AST_SYM_VALUE(cexpr) &&
1357 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1358 // a symbol in code space will never change
1359 // This is only for the 'char *s="hallo"' case and will have to leave
1360 //printf(" code space symbol");
1365 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1366 "unexpected link in expression tree\n");
1369 if (cexpr->opval.op==ARRAYINIT) {
1370 // this is a list of literals
1373 if (cexpr->opval.op=='=') {
1374 return constExprTree(cexpr->right);
1376 if (cexpr->opval.op==CAST) {
1377 // cast ignored, maybe we should throw a warning here?
1378 return constExprTree(cexpr->right);
1380 if (cexpr->opval.op=='&') {
1383 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1386 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1391 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1396 /*-----------------------------------------------------------------*/
1397 /* constExprValue - returns the value of a constant expression */
1398 /* or NULL if it is not a constant expression */
1399 /*-----------------------------------------------------------------*/
1401 constExprValue (ast * cexpr, int check)
1403 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1405 /* if this is not a constant then */
1406 if (!IS_LITERAL (cexpr->ftype))
1408 /* then check if this is a literal array
1410 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1411 SPEC_CVAL (cexpr->etype).v_char &&
1412 IS_ARRAY (cexpr->ftype))
1414 value *val = valFromType (cexpr->ftype);
1415 SPEC_SCLS (val->etype) = S_LITERAL;
1416 val->sym = cexpr->opval.val->sym;
1417 val->sym->type = copyLinkChain (cexpr->ftype);
1418 val->sym->etype = getSpec (val->sym->type);
1419 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1423 /* if we are casting a literal value then */
1424 if (IS_AST_OP (cexpr) &&
1425 cexpr->opval.op == CAST &&
1426 IS_LITERAL (cexpr->right->ftype))
1428 return valCastLiteral (cexpr->ftype,
1429 floatFromVal (cexpr->right->opval.val));
1432 if (IS_AST_VALUE (cexpr))
1434 return cexpr->opval.val;
1438 werror (E_CONST_EXPECTED, "found expression");
1443 /* return the value */
1444 return cexpr->opval.val;
1448 /*-----------------------------------------------------------------*/
1449 /* isLabelInAst - will return true if a given label is found */
1450 /*-----------------------------------------------------------------*/
1452 isLabelInAst (symbol * label, ast * tree)
1454 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1457 if (IS_AST_OP (tree) &&
1458 tree->opval.op == LABEL &&
1459 isSymbolEqual (AST_SYMBOL (tree->left), label))
1462 return isLabelInAst (label, tree->right) &&
1463 isLabelInAst (label, tree->left);
1467 /*-----------------------------------------------------------------*/
1468 /* isLoopCountable - return true if the loop count can be determi- */
1469 /* -ned at compile time . */
1470 /*-----------------------------------------------------------------*/
1472 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1473 symbol ** sym, ast ** init, ast ** end)
1476 /* the loop is considered countable if the following
1477 conditions are true :-
1479 a) initExpr :- <sym> = <const>
1480 b) condExpr :- <sym> < <const1>
1481 c) loopExpr :- <sym> ++
1484 /* first check the initExpr */
1485 if (IS_AST_OP (initExpr) &&
1486 initExpr->opval.op == '=' && /* is assignment */
1487 IS_AST_SYM_VALUE (initExpr->left))
1488 { /* left is a symbol */
1490 *sym = AST_SYMBOL (initExpr->left);
1491 *init = initExpr->right;
1496 /* for now the symbol has to be of
1498 if (!IS_INTEGRAL ((*sym)->type))
1501 /* now check condExpr */
1502 if (IS_AST_OP (condExpr))
1505 switch (condExpr->opval.op)
1508 if (IS_AST_SYM_VALUE (condExpr->left) &&
1509 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1510 IS_AST_LIT_VALUE (condExpr->right))
1512 *end = condExpr->right;
1518 if (IS_AST_OP (condExpr->left) &&
1519 condExpr->left->opval.op == '>' &&
1520 IS_AST_LIT_VALUE (condExpr->left->right) &&
1521 IS_AST_SYM_VALUE (condExpr->left->left) &&
1522 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1525 *end = newNode ('+', condExpr->left->right,
1526 newAst_VALUE (constVal ("1")));
1539 /* check loop expression is of the form <sym>++ */
1540 if (!IS_AST_OP (loopExpr))
1543 /* check if <sym> ++ */
1544 if (loopExpr->opval.op == INC_OP)
1550 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1551 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1558 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1559 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1567 if (loopExpr->opval.op == ADD_ASSIGN)
1570 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1571 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1572 IS_AST_LIT_VALUE (loopExpr->right) &&
1573 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1581 /*-----------------------------------------------------------------*/
1582 /* astHasVolatile - returns true if ast contains any volatile */
1583 /*-----------------------------------------------------------------*/
1585 astHasVolatile (ast * tree)
1590 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1593 if (IS_AST_OP (tree))
1594 return astHasVolatile (tree->left) ||
1595 astHasVolatile (tree->right);
1600 /*-----------------------------------------------------------------*/
1601 /* astHasPointer - return true if the ast contains any ptr variable */
1602 /*-----------------------------------------------------------------*/
1604 astHasPointer (ast * tree)
1609 if (IS_AST_LINK (tree))
1612 /* if we hit an array expression then check
1613 only the left side */
1614 if (IS_AST_OP (tree) && tree->opval.op == '[')
1615 return astHasPointer (tree->left);
1617 if (IS_AST_VALUE (tree))
1618 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1620 return astHasPointer (tree->left) ||
1621 astHasPointer (tree->right);
1625 /*-----------------------------------------------------------------*/
1626 /* astHasSymbol - return true if the ast has the given symbol */
1627 /*-----------------------------------------------------------------*/
1629 astHasSymbol (ast * tree, symbol * sym)
1631 if (!tree || IS_AST_LINK (tree))
1634 if (IS_AST_VALUE (tree))
1636 if (IS_AST_SYM_VALUE (tree))
1637 return isSymbolEqual (AST_SYMBOL (tree), sym);
1642 return astHasSymbol (tree->left, sym) ||
1643 astHasSymbol (tree->right, sym);
1646 /*-----------------------------------------------------------------*/
1647 /* astHasDeref - return true if the ast has an indirect access */
1648 /*-----------------------------------------------------------------*/
1650 astHasDeref (ast * tree)
1652 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1655 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1657 return astHasDeref (tree->left) || astHasDeref (tree->right);
1660 /*-----------------------------------------------------------------*/
1661 /* isConformingBody - the loop body has to conform to a set of rules */
1662 /* for the loop to be considered reversible read on for rules */
1663 /*-----------------------------------------------------------------*/
1665 isConformingBody (ast * pbody, symbol * sym, ast * body)
1668 /* we are going to do a pre-order traversal of the
1669 tree && check for the following conditions. (essentially
1670 a set of very shallow tests )
1671 a) the sym passed does not participate in
1672 any arithmetic operation
1673 b) There are no function calls
1674 c) all jumps are within the body
1675 d) address of loop control variable not taken
1676 e) if an assignment has a pointer on the
1677 left hand side make sure right does not have
1678 loop control variable */
1680 /* if we reach the end or a leaf then true */
1681 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1684 /* if anything else is "volatile" */
1685 if (IS_VOLATILE (TETYPE (pbody)))
1688 /* we will walk the body in a pre-order traversal for
1690 switch (pbody->opval.op)
1692 /*------------------------------------------------------------------*/
1694 // if the loopvar is used as an index
1695 /* array op is commutative -- must check both left & right */
1696 if (astHasSymbol(pbody->right, sym) || astHasSymbol(pbody->left, sym)) {
1699 return isConformingBody (pbody->right, sym, body)
1700 && isConformingBody (pbody->left, sym, body);
1702 /*------------------------------------------------------------------*/
1707 /*------------------------------------------------------------------*/
1711 /* sure we are not sym is not modified */
1713 IS_AST_SYM_VALUE (pbody->left) &&
1714 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1718 IS_AST_SYM_VALUE (pbody->right) &&
1719 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1724 /*------------------------------------------------------------------*/
1726 case '*': /* can be unary : if right is null then unary operation */
1731 /* if right is NULL then unary operation */
1732 /*------------------------------------------------------------------*/
1733 /*----------------------------*/
1735 /*----------------------------*/
1738 if (IS_AST_SYM_VALUE (pbody->left) &&
1739 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1742 return isConformingBody (pbody->left, sym, body);
1746 if (astHasSymbol (pbody->left, sym) ||
1747 astHasSymbol (pbody->right, sym))
1752 /*------------------------------------------------------------------*/
1760 if (IS_AST_SYM_VALUE (pbody->left) &&
1761 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1764 if (IS_AST_SYM_VALUE (pbody->right) &&
1765 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1768 return isConformingBody (pbody->left, sym, body) &&
1769 isConformingBody (pbody->right, sym, body);
1777 if (IS_AST_SYM_VALUE (pbody->left) &&
1778 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1780 return isConformingBody (pbody->left, sym, body);
1782 /*------------------------------------------------------------------*/
1794 case SIZEOF: /* evaluate wihout code generation */
1796 if (IS_AST_SYM_VALUE (pbody->left) &&
1797 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1800 if (IS_AST_SYM_VALUE (pbody->right) &&
1801 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1804 return isConformingBody (pbody->left, sym, body) &&
1805 isConformingBody (pbody->right, sym, body);
1807 /*------------------------------------------------------------------*/
1810 /* if left has a pointer & right has loop
1811 control variable then we cannot */
1812 if (astHasPointer (pbody->left) &&
1813 astHasSymbol (pbody->right, sym))
1815 if (astHasVolatile (pbody->left))
1818 if (IS_AST_SYM_VALUE (pbody->left)) {
1819 // if the loopvar has an assignment
1820 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1822 // if the loopvar is used in another (maybe conditional) block
1823 if (astHasSymbol (pbody->right, sym) &&
1824 (pbody->level >= body->level)) {
1829 if (astHasVolatile (pbody->left))
1832 if (astHasDeref(pbody->right)) return FALSE;
1834 return isConformingBody (pbody->left, sym, body) &&
1835 isConformingBody (pbody->right, sym, body);
1846 assert ("Parser should not have generated this\n");
1848 /*------------------------------------------------------------------*/
1849 /*----------------------------*/
1850 /* comma operator */
1851 /*----------------------------*/
1853 return isConformingBody (pbody->left, sym, body) &&
1854 isConformingBody (pbody->right, sym, body);
1856 /*------------------------------------------------------------------*/
1857 /*----------------------------*/
1859 /*----------------------------*/
1861 /* if local & not passed as paramater then ok */
1862 if (sym->level && !astHasSymbol(pbody->right,sym))
1866 /*------------------------------------------------------------------*/
1867 /*----------------------------*/
1868 /* return statement */
1869 /*----------------------------*/
1874 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1879 if (astHasSymbol (pbody->left, sym))
1886 return isConformingBody (pbody->left, sym, body) &&
1887 isConformingBody (pbody->right, sym, body);
1893 /*-----------------------------------------------------------------*/
1894 /* isLoopReversible - takes a for loop as input && returns true */
1895 /* if the for loop is reversible. If yes will set the value of */
1896 /* the loop control var & init value & termination value */
1897 /*-----------------------------------------------------------------*/
1899 isLoopReversible (ast * loop, symbol ** loopCntrl,
1900 ast ** init, ast ** end)
1902 /* if option says don't do it then don't */
1903 if (optimize.noLoopReverse)
1905 /* there are several tests to determine this */
1907 /* for loop has to be of the form
1908 for ( <sym> = <const1> ;
1909 [<sym> < <const2>] ;
1910 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1912 if (!isLoopCountable (AST_FOR (loop, initExpr),
1913 AST_FOR (loop, condExpr),
1914 AST_FOR (loop, loopExpr),
1915 loopCntrl, init, end))
1918 /* now do some serious checking on the body of the loop
1921 return isConformingBody (loop->left, *loopCntrl, loop->left);
1925 /*-----------------------------------------------------------------*/
1926 /* replLoopSym - replace the loop sym by loop sym -1 */
1927 /*-----------------------------------------------------------------*/
1929 replLoopSym (ast * body, symbol * sym)
1932 if (!body || IS_AST_LINK (body))
1935 if (IS_AST_SYM_VALUE (body))
1938 if (isSymbolEqual (AST_SYMBOL (body), sym))
1942 body->opval.op = '-';
1943 body->left = newAst_VALUE (symbolVal (sym));
1944 body->right = newAst_VALUE (constVal ("1"));
1952 replLoopSym (body->left, sym);
1953 replLoopSym (body->right, sym);
1957 /*-----------------------------------------------------------------*/
1958 /* reverseLoop - do the actual loop reversal */
1959 /*-----------------------------------------------------------------*/
1961 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1965 /* create the following tree
1970 if (sym) goto for_continue ;
1973 /* put it together piece by piece */
1974 rloop = newNode (NULLOP,
1975 createIf (newAst_VALUE (symbolVal (sym)),
1977 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1980 newAst_VALUE (symbolVal (sym)),
1983 replLoopSym (loop->left, sym);
1984 setAstLineno (rloop, init->lineno);
1986 rloop = newNode (NULLOP,
1988 newAst_VALUE (symbolVal (sym)),
1989 newNode ('-', end, init)),
1990 createLabel (AST_FOR (loop, continueLabel),
1994 newNode (SUB_ASSIGN,
1995 newAst_VALUE (symbolVal (sym)),
1996 newAst_VALUE (constVal ("1"))),
1999 rloop->lineno=init->lineno;
2000 return decorateType (rloop, RESULT_TYPE_NONE);
2004 /*-----------------------------------------------------------------*/
2005 /* searchLitOp - search tree (*ops only) for an ast with literal */
2006 /*-----------------------------------------------------------------*/
2008 searchLitOp (ast *tree, ast **parent, const unsigned char *ops)
2012 if (tree && optimize.global_cse)
2014 /* is there a literal operand? */
2016 IS_AST_OP(tree->right) &&
2017 tree->right->right &&
2018 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
2020 if (IS_LITERAL (RTYPE (tree->right)) !=
2021 IS_LITERAL (LTYPE (tree->right)))
2023 tree->right->decorated = 0;
2024 tree->decorated = 0;
2028 ret = searchLitOp (tree->right, parent, ops);
2033 IS_AST_OP(tree->left) &&
2034 tree->left->right &&
2035 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
2037 if (IS_LITERAL (RTYPE (tree->left)) !=
2038 IS_LITERAL (LTYPE (tree->left)))
2040 tree->left->decorated = 0;
2041 tree->decorated = 0;
2045 ret = searchLitOp (tree->left, parent, ops);
2053 /*-----------------------------------------------------------------*/
2054 /* getResultFromType */
2055 /*-----------------------------------------------------------------*/
2057 getResultTypeFromType (sym_link *type)
2059 /* type = getSpec (type); */
2061 return RESULT_TYPE_BIT;
2062 if (IS_BITFIELD (type))
2064 int blen = SPEC_BLEN (type);
2067 return RESULT_TYPE_BIT;
2069 return RESULT_TYPE_CHAR;
2070 return RESULT_TYPE_INT;
2073 return RESULT_TYPE_CHAR;
2076 return RESULT_TYPE_INT;
2077 return RESULT_TYPE_OTHER;
2080 /*-----------------------------------------------------------------*/
2081 /* addCast - adds casts to a type specified by RESULT_TYPE */
2082 /*-----------------------------------------------------------------*/
2084 addCast (ast *tree, RESULT_TYPE resultType, bool upcast)
2087 bool upCasted = FALSE;
2091 case RESULT_TYPE_NONE:
2092 /* char: promote to int */
2094 getSize (tree->etype) >= INTSIZE)
2096 newLink = newIntLink();
2099 case RESULT_TYPE_CHAR:
2100 if (IS_CHAR (tree->etype) ||
2101 IS_FLOAT(tree->etype))
2103 newLink = newCharLink();
2105 case RESULT_TYPE_INT:
2107 if (getSize (tree->etype) > INTSIZE)
2109 /* warn ("Loosing significant digits"); */
2113 /* char: promote to int */
2115 getSize (tree->etype) >= INTSIZE)
2117 newLink = newIntLink();
2120 case RESULT_TYPE_OTHER:
2123 /* return type is long, float: promote char to int */
2124 if (getSize (tree->etype) >= INTSIZE)
2126 newLink = newIntLink();
2132 tree->decorated = 0;
2133 tree = newNode (CAST, newAst_LINK (newLink), tree);
2134 tree->lineno = tree->right->lineno;
2135 /* keep unsigned type during cast to smaller type,
2136 but not when promoting from char to int */
2138 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2139 return decorateType (tree, resultType);
2142 /*-----------------------------------------------------------------*/
2143 /* resultTypePropagate - decides if resultType can be propagated */
2144 /*-----------------------------------------------------------------*/
2146 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2148 switch (tree->opval.op)
2164 return RESULT_TYPE_NONE;
2168 return RESULT_TYPE_IFX;
2170 return RESULT_TYPE_NONE;
2174 /*-----------------------------------------------------------------*/
2175 /* getLeftResultType - gets type from left branch for propagation */
2176 /*-----------------------------------------------------------------*/
2178 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2180 switch (tree->opval.op)
2184 if (IS_PTR (LTYPE (tree)))
2185 return RESULT_TYPE_NONE;
2187 return getResultTypeFromType (LETYPE (tree));
2189 if (IS_PTR (currFunc->type->next))
2190 return RESULT_TYPE_NONE;
2192 return getResultTypeFromType (currFunc->type->next);
2194 if (!IS_ARRAY (LTYPE (tree)))
2196 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256)
2197 return RESULT_TYPE_CHAR;
2204 /*--------------------------------------------------------------------*/
2205 /* decorateType - compute type for this tree, also does type checking.*/
2206 /* This is done bottom up, since type has to flow upwards. */
2207 /* resultType flows top-down and forces e.g. char-arithmetik, if the */
2208 /* result is a char and the operand(s) are int's. */
2209 /* It also does constant folding, and parameter checking. */
2210 /*--------------------------------------------------------------------*/
2212 decorateType (ast * tree, RESULT_TYPE resultType)
2216 RESULT_TYPE resultTypeProp;
2221 /* if already has type then do nothing */
2222 if (tree->decorated)
2225 tree->decorated = 1;
2228 /* print the line */
2229 /* if not block & function */
2230 if (tree->type == EX_OP &&
2231 (tree->opval.op != FUNCTION &&
2232 tree->opval.op != BLOCK &&
2233 tree->opval.op != NULLOP))
2235 filename = tree->filename;
2236 lineno = tree->lineno;
2240 /* if any child is an error | this one is an error do nothing */
2241 if (tree->isError ||
2242 (tree->left && tree->left->isError) ||
2243 (tree->right && tree->right->isError))
2246 /*------------------------------------------------------------------*/
2247 /*----------------------------*/
2248 /* leaf has been reached */
2249 /*----------------------------*/
2250 lineno=tree->lineno;
2251 /* if this is of type value */
2252 /* just get the type */
2253 if (tree->type == EX_VALUE)
2256 if (IS_LITERAL (tree->opval.val->etype))
2259 /* if this is a character array then declare it */
2260 if (IS_ARRAY (tree->opval.val->type))
2261 tree->opval.val = stringToSymbol (tree->opval.val);
2263 /* otherwise just copy the type information */
2264 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2268 if (tree->opval.val->sym)
2270 /* if the undefined flag is set then give error message */
2271 if (tree->opval.val->sym->undefined)
2273 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2275 TTYPE (tree) = TETYPE (tree) =
2276 tree->opval.val->type = tree->opval.val->sym->type =
2277 tree->opval.val->etype = tree->opval.val->sym->etype =
2278 copyLinkChain (INTTYPE);
2283 /* if impilicit i.e. struct/union member then no type */
2284 if (tree->opval.val->sym->implicit)
2285 TTYPE (tree) = TETYPE (tree) = NULL;
2290 /* else copy the type */
2291 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2293 /* and mark it as referenced */
2294 tree->opval.val->sym->isref = 1;
2302 /* if type link for the case of cast */
2303 if (tree->type == EX_LINK)
2305 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2313 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2315 if (tree->left && tree->left->type == EX_OPERAND
2316 && (tree->left->opval.op == INC_OP
2317 || tree->left->opval.op == DEC_OP)
2318 && tree->left->left)
2320 tree->left->right = tree->left->left;
2321 tree->left->left = NULL;
2323 if (tree->right && tree->right->type == EX_OPERAND
2324 && (tree->right->opval.op == INC_OP
2325 || tree->right->opval.op == DEC_OP)
2326 && tree->right->left)
2328 tree->right->right = tree->right->left;
2329 tree->right->left = NULL;
2334 /* Before decorating the left branch we've to decide in dependence
2335 upon tree->opval.op, if resultType can be propagated */
2336 resultTypeProp = resultTypePropagate (tree, resultType);
2338 if (tree->opval.op == '?')
2339 dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2341 dtl = decorateType (tree->left, resultTypeProp);
2343 /* if an array node, we may need to swap branches */
2344 if (tree->opval.op == '[')
2346 /* determine which is the array & which the index */
2347 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2348 IS_INTEGRAL (LTYPE (tree)))
2350 ast *tempTree = tree->left;
2351 tree->left = tree->right;
2352 tree->right = tempTree;
2356 /* After decorating the left branch there's type information available
2357 in tree->left->?type. If the op is e.g. '=' we extract the type
2358 information from there and propagate it to the right branch. */
2359 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2361 switch (tree->opval.op)
2364 /* delay right side for '?' operator since conditional macro
2365 expansions might rely on this */
2369 /* decorate right side for CALL (parameter list) in processParms();
2370 there is resultType available */
2374 dtr = decorateType (tree->right, resultTypeProp);
2378 /* this is to take care of situations
2379 when the tree gets rewritten */
2380 if (dtl != tree->left)
2382 if (dtr != tree->right)
2384 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2388 /* depending on type of operator do */
2390 switch (tree->opval.op)
2392 /*------------------------------------------------------------------*/
2393 /*----------------------------*/
2395 /*----------------------------*/
2398 /* first check if this is a array or a pointer */
2399 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2401 werror (E_NEED_ARRAY_PTR, "[]");
2402 goto errorTreeReturn;
2405 /* check if the type of the idx */
2406 if (!IS_INTEGRAL (RTYPE (tree)))
2408 werror (E_IDX_NOT_INT);
2409 goto errorTreeReturn;
2412 /* if the left is an rvalue then error */
2415 werror (E_LVALUE_REQUIRED, "array access");
2416 goto errorTreeReturn;
2419 if (IS_LITERAL (RTYPE (tree)))
2421 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2422 int arraySize = DCL_ELEM (LTYPE (tree));
2423 if (arraySize && arrayIndex >= arraySize)
2425 werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2430 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2433 /*------------------------------------------------------------------*/
2434 /*----------------------------*/
2436 /*----------------------------*/
2438 /* if this is not a structure */
2439 if (!IS_STRUCT (LTYPE (tree)))
2441 werror (E_STRUCT_UNION, ".");
2442 goto errorTreeReturn;
2444 TTYPE (tree) = structElemType (LTYPE (tree),
2445 (tree->right->type == EX_VALUE ?
2446 tree->right->opval.val : NULL));
2447 TETYPE (tree) = getSpec (TTYPE (tree));
2450 /*------------------------------------------------------------------*/
2451 /*----------------------------*/
2452 /* struct/union pointer */
2453 /*----------------------------*/
2455 /* if not pointer to a structure */
2456 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2458 werror (E_PTR_REQD);
2459 goto errorTreeReturn;
2462 if (!IS_STRUCT (LTYPE (tree)->next))
2464 werror (E_STRUCT_UNION, "->");
2465 goto errorTreeReturn;
2468 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2469 (tree->right->type == EX_VALUE ?
2470 tree->right->opval.val : NULL));
2471 TETYPE (tree) = getSpec (TTYPE (tree));
2473 /* adjust the storage class */
2474 switch (DCL_TYPE(tree->left->ftype)) {
2476 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2479 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2482 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2485 SPEC_SCLS (TETYPE (tree)) = 0;
2488 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2491 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2494 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2497 SPEC_SCLS (TETYPE (tree)) = 0;
2504 /* This breaks with extern declarations, bitfields, and perhaps other */
2505 /* cases (gcse). Let's leave this optimization disabled for now and */
2506 /* ponder if there's a safe way to do this. -- EEP */
2508 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2509 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2511 /* If defined struct type at addr var
2512 then rewrite (&struct var)->member
2514 and define membertype at (addr+offsetof(struct var,member)) temp
2517 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2518 AST_SYMBOL(tree->right));
2520 sym = newSymbol(genSymName (0), 0);
2521 sym->type = TTYPE (tree);
2522 sym->etype = getSpec(sym->type);
2523 sym->lineDef = tree->lineno;
2526 SPEC_STAT (sym->etype) = 1;
2527 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2529 SPEC_ABSA(sym->etype) = 1;
2530 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2533 AST_VALUE (tree) = symbolVal(sym);
2536 tree->type = EX_VALUE;
2544 /*------------------------------------------------------------------*/
2545 /*----------------------------*/
2546 /* ++/-- operation */
2547 /*----------------------------*/
2551 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2552 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2553 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2554 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2563 /*------------------------------------------------------------------*/
2564 /*----------------------------*/
2566 /*----------------------------*/
2567 case '&': /* can be unary */
2568 /* if right is NULL then unary operation */
2569 if (tree->right) /* not an unary operation */
2572 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2574 werror (E_BITWISE_OP);
2575 werror (W_CONTINUE, "left & right types are ");
2576 printTypeChain (LTYPE (tree), stderr);
2577 fprintf (stderr, ",");
2578 printTypeChain (RTYPE (tree), stderr);
2579 fprintf (stderr, "\n");
2580 goto errorTreeReturn;
2583 /* if they are both literal */
2584 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2586 tree->type = EX_VALUE;
2587 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2588 valFromType (RETYPE (tree)), '&');
2590 tree->right = tree->left = NULL;
2591 TETYPE (tree) = tree->opval.val->etype;
2592 TTYPE (tree) = tree->opval.val->type;
2596 /* see if this is a GETHBIT operation if yes
2599 ast *otree = optimizeGetHbit (tree);
2602 return decorateType (otree, RESULT_TYPE_NONE);
2605 /* if left is a literal exchange left & right */
2606 if (IS_LITERAL (LTYPE (tree)))
2608 ast *tTree = tree->left;
2609 tree->left = tree->right;
2610 tree->right = tTree;
2613 /* if right is a literal and */
2614 /* we can find a 2nd literal in an and-tree then */
2615 /* rearrange the tree */
2616 if (IS_LITERAL (RTYPE (tree)))
2619 ast *litTree = searchLitOp (tree, &parent, "&");
2623 ast *tTree = litTree->left;
2624 litTree->left = tree->right;
2625 tree->right = tTree;
2626 /* both operands in litTree are literal now */
2627 decorateType (parent, resultType);
2631 LRVAL (tree) = RRVAL (tree) = 1;
2633 TTYPE (tree) = computeType (LTYPE (tree),
2637 TETYPE (tree) = getSpec (TTYPE (tree));
2642 /*------------------------------------------------------------------*/
2643 /*----------------------------*/
2645 /*----------------------------*/
2646 p = newLink (DECLARATOR);
2647 /* if bit field then error */
2648 if (IS_BITVAR (tree->left->etype))
2650 werror (E_ILLEGAL_ADDR, "address of bit variable");
2651 goto errorTreeReturn;
2654 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2656 werror (E_ILLEGAL_ADDR, "address of register variable");
2657 goto errorTreeReturn;
2660 if (IS_FUNC (LTYPE (tree)))
2662 // this ought to be ignored
2663 return (tree->left);
2666 if (IS_LITERAL(LTYPE(tree)))
2668 werror (E_ILLEGAL_ADDR, "address of literal");
2669 goto errorTreeReturn;
2674 werror (E_LVALUE_REQUIRED, "address of");
2675 goto errorTreeReturn;
2678 DCL_TYPE (p) = POINTER;
2679 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2680 DCL_TYPE (p) = CPOINTER;
2681 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2682 DCL_TYPE (p) = FPOINTER;
2683 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2684 DCL_TYPE (p) = PPOINTER;
2685 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2686 DCL_TYPE (p) = IPOINTER;
2687 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2688 DCL_TYPE (p) = EEPPOINTER;
2689 else if (SPEC_OCLS(tree->left->etype))
2690 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2692 DCL_TYPE (p) = POINTER;
2694 if (IS_AST_SYM_VALUE (tree->left))
2696 AST_SYMBOL (tree->left)->addrtaken = 1;
2697 AST_SYMBOL (tree->left)->allocreq = 1;
2700 p->next = LTYPE (tree);
2702 TETYPE (tree) = getSpec (TTYPE (tree));
2707 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2708 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2710 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2711 AST_SYMBOL(tree->left->right));
2712 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2713 valueFromLit(element->offset));
2716 tree->type = EX_VALUE;
2717 tree->values.literalFromCast = 1;
2723 /*------------------------------------------------------------------*/
2724 /*----------------------------*/
2726 /*----------------------------*/
2728 /* if the rewrite succeeds then don't go any furthur */
2730 ast *wtree = optimizeRRCRLC (tree);
2732 return decorateType (wtree, RESULT_TYPE_NONE);
2734 wtree = optimizeSWAP (tree);
2736 return decorateType (wtree, RESULT_TYPE_NONE);
2739 /* if left is a literal exchange left & right */
2740 if (IS_LITERAL (LTYPE (tree)))
2742 ast *tTree = tree->left;
2743 tree->left = tree->right;
2744 tree->right = tTree;
2747 /* if right is a literal and */
2748 /* we can find a 2nd literal in an or-tree then */
2749 /* rearrange the tree */
2750 if (IS_LITERAL (RTYPE (tree)))
2753 ast *litTree = searchLitOp (tree, &parent, "|");
2757 ast *tTree = litTree->left;
2758 litTree->left = tree->right;
2759 tree->right = tTree;
2760 /* both operands in tTree are literal now */
2761 decorateType (parent, resultType);
2766 /*------------------------------------------------------------------*/
2767 /*----------------------------*/
2769 /*----------------------------*/
2771 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2773 werror (E_BITWISE_OP);
2774 werror (W_CONTINUE, "left & right types are ");
2775 printTypeChain (LTYPE (tree), stderr);
2776 fprintf (stderr, ",");
2777 printTypeChain (RTYPE (tree), stderr);
2778 fprintf (stderr, "\n");
2779 goto errorTreeReturn;
2782 /* if they are both literal then rewrite the tree */
2783 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2785 tree->type = EX_VALUE;
2786 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2787 valFromType (RETYPE (tree)),
2789 tree->right = tree->left = NULL;
2790 TETYPE (tree) = tree->opval.val->etype;
2791 TTYPE (tree) = tree->opval.val->type;
2795 /* if left is a literal exchange left & right */
2796 if (IS_LITERAL (LTYPE (tree)))
2798 ast *tTree = tree->left;
2799 tree->left = tree->right;
2800 tree->right = tTree;
2803 /* if right is a literal and */
2804 /* we can find a 2nd literal in a xor-tree then */
2805 /* rearrange the tree */
2806 if (IS_LITERAL (RTYPE (tree)) &&
2807 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2810 ast *litTree = searchLitOp (tree, &parent, "^");
2814 ast *tTree = litTree->left;
2815 litTree->left = tree->right;
2816 tree->right = tTree;
2817 /* both operands in litTree are literal now */
2818 decorateType (parent, resultType);
2822 LRVAL (tree) = RRVAL (tree) = 1;
2824 TTYPE (tree) = computeType (LTYPE (tree),
2828 TETYPE (tree) = getSpec (TTYPE (tree));
2832 /*------------------------------------------------------------------*/
2833 /*----------------------------*/
2835 /*----------------------------*/
2837 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2839 werror (E_INVALID_OP, "divide");
2840 goto errorTreeReturn;
2842 /* if they are both literal then */
2843 /* rewrite the tree */
2844 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2846 tree->type = EX_VALUE;
2847 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2848 valFromType (RETYPE (tree)));
2849 tree->right = tree->left = NULL;
2850 TETYPE (tree) = getSpec (TTYPE (tree) =
2851 tree->opval.val->type);
2855 LRVAL (tree) = RRVAL (tree) = 1;
2857 TETYPE (tree) = getSpec (TTYPE (tree) =
2858 computeType (LTYPE (tree),
2863 /* if right is a literal and */
2864 /* left is also a division by a literal then */
2865 /* rearrange the tree */
2866 if (IS_LITERAL (RTYPE (tree))
2867 /* avoid infinite loop */
2868 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2871 ast *litTree = searchLitOp (tree, &parent, "/");
2874 if (IS_LITERAL (RTYPE (litTree)))
2878 litTree->right = newNode ('*',
2880 copyAst (tree->right));
2881 litTree->right->lineno = tree->lineno;
2883 tree->right->opval.val = constVal ("1");
2884 decorateType (parent, resultType);
2888 /* litTree->left is literal: no gcse possible.
2889 We can't call decorateType(parent, RESULT_TYPE_NONE), because
2890 this would cause an infinit loop. */
2891 parent->decorated = 1;
2892 decorateType (litTree, resultType);
2899 /*------------------------------------------------------------------*/
2900 /*----------------------------*/
2902 /*----------------------------*/
2904 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2906 werror (E_BITWISE_OP);
2907 werror (W_CONTINUE, "left & right types are ");
2908 printTypeChain (LTYPE (tree), stderr);
2909 fprintf (stderr, ",");
2910 printTypeChain (RTYPE (tree), stderr);
2911 fprintf (stderr, "\n");
2912 goto errorTreeReturn;
2914 /* if they are both literal then */
2915 /* rewrite the tree */
2916 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2918 tree->type = EX_VALUE;
2919 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2920 valFromType (RETYPE (tree)));
2921 tree->right = tree->left = NULL;
2922 TETYPE (tree) = getSpec (TTYPE (tree) =
2923 tree->opval.val->type);
2926 LRVAL (tree) = RRVAL (tree) = 1;
2927 TETYPE (tree) = getSpec (TTYPE (tree) =
2928 computeType (LTYPE (tree),
2934 /*------------------------------------------------------------------*/
2935 /*----------------------------*/
2936 /* address dereference */
2937 /*----------------------------*/
2938 case '*': /* can be unary : if right is null then unary operation */
2941 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2943 werror (E_PTR_REQD);
2944 goto errorTreeReturn;
2949 werror (E_LVALUE_REQUIRED, "pointer deref");
2950 goto errorTreeReturn;
2952 if (IS_ADDRESS_OF_OP(tree->left))
2954 /* replace *&obj with obj */
2955 return tree->left->left;
2957 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2958 TETYPE (tree) = getSpec (TTYPE (tree));
2959 /* adjust the storage class */
2960 switch (DCL_TYPE(tree->left->ftype)) {
2962 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2965 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2968 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2971 SPEC_SCLS (TETYPE (tree)) = 0;
2974 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2977 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2980 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2983 SPEC_SCLS (TETYPE (tree)) = 0;
2992 /*------------------------------------------------------------------*/
2993 /*----------------------------*/
2994 /* multiplication */
2995 /*----------------------------*/
2996 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2998 werror (E_INVALID_OP, "multiplication");
2999 goto errorTreeReturn;
3002 /* if they are both literal then */
3003 /* rewrite the tree */
3004 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3006 tree->type = EX_VALUE;
3007 tree->opval.val = valMult (valFromType (LETYPE (tree)),
3008 valFromType (RETYPE (tree)));
3009 tree->right = tree->left = NULL;
3010 TETYPE (tree) = getSpec (TTYPE (tree) =
3011 tree->opval.val->type);
3015 /* if left is a literal exchange left & right */
3016 if (IS_LITERAL (LTYPE (tree)))
3018 ast *tTree = tree->left;
3019 tree->left = tree->right;
3020 tree->right = tTree;
3023 /* if right is a literal and */
3024 /* we can find a 2nd literal in a mul-tree then */
3025 /* rearrange the tree */
3026 if (IS_LITERAL (RTYPE (tree)))
3029 ast *litTree = searchLitOp (tree, &parent, "*");
3033 ast *tTree = litTree->left;
3034 litTree->left = tree->right;
3035 tree->right = tTree;
3036 /* both operands in litTree are literal now */
3037 decorateType (parent, resultType);
3041 LRVAL (tree) = RRVAL (tree) = 1;
3042 tree->left = addCast (tree->left, resultType, FALSE);
3043 tree->right = addCast (tree->right, resultType, FALSE);
3044 TETYPE (tree) = getSpec (TTYPE (tree) =
3045 computeType (LTYPE (tree),
3052 /*------------------------------------------------------------------*/
3053 /*----------------------------*/
3054 /* unary '+' operator */
3055 /*----------------------------*/
3060 if (!IS_ARITHMETIC (LTYPE (tree)))
3062 werror (E_UNARY_OP, '+');
3063 goto errorTreeReturn;
3066 /* if left is a literal then do it */
3067 if (IS_LITERAL (LTYPE (tree)))
3069 tree->type = EX_VALUE;
3070 tree->opval.val = valFromType (LETYPE (tree));
3072 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3076 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3080 /*------------------------------------------------------------------*/
3081 /*----------------------------*/
3083 /*----------------------------*/
3085 /* this is not a unary operation */
3086 /* if both pointers then problem */
3087 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3088 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3090 werror (E_PTR_PLUS_PTR);
3091 goto errorTreeReturn;
3094 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3095 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3097 werror (E_PLUS_INVALID, "+");
3098 goto errorTreeReturn;
3101 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3102 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3104 werror (E_PLUS_INVALID, "+");
3105 goto errorTreeReturn;
3107 /* if they are both literal then */
3108 /* rewrite the tree */
3109 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3111 tree->type = EX_VALUE;
3112 tree->left = addCast (tree->left, resultType, TRUE);
3113 tree->right = addCast (tree->right, resultType, TRUE);
3114 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3115 valFromType (RETYPE (tree)));
3116 tree->right = tree->left = NULL;
3117 TETYPE (tree) = getSpec (TTYPE (tree) =
3118 tree->opval.val->type);
3122 /* if the right is a pointer or left is a literal
3123 xchange left & right */
3124 if (IS_ARRAY (RTYPE (tree)) ||
3125 IS_PTR (RTYPE (tree)) ||
3126 IS_LITERAL (LTYPE (tree)))
3128 ast *tTree = tree->left;
3129 tree->left = tree->right;
3130 tree->right = tTree;
3133 /* if right is a literal and */
3134 /* left is also an addition/subtraction with a literal then */
3135 /* rearrange the tree */
3136 if (IS_LITERAL (RTYPE (tree)))
3138 ast *litTree, *parent;
3139 litTree = searchLitOp (tree, &parent, "+-");
3142 if (litTree->opval.op == '+')
3146 ast *tTree = litTree->left;
3147 litTree->left = tree->right;
3148 tree->right = tree->left;
3151 else if (litTree->opval.op == '-')
3153 if (IS_LITERAL (RTYPE (litTree)))
3157 ast *tTree = litTree->left;
3158 litTree->left = tree->right;
3159 tree->right = tTree;
3165 ast *tTree = litTree->right;
3166 litTree->right = tree->right;
3167 tree->right = tTree;
3168 litTree->opval.op = '+';
3169 tree->opval.op = '-';
3172 decorateType (parent, resultType);
3176 LRVAL (tree) = RRVAL (tree) = 1;
3177 /* if the left is a pointer */
3178 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3179 TETYPE (tree) = getSpec (TTYPE (tree) =
3183 tree->left = addCast (tree->left, resultType, TRUE);
3184 tree->right = addCast (tree->right, resultType, TRUE);
3185 TETYPE (tree) = getSpec (TTYPE (tree) =
3186 computeType (LTYPE (tree),
3194 /*------------------------------------------------------------------*/
3195 /*----------------------------*/
3197 /*----------------------------*/
3198 case '-': /* can be unary */
3199 /* if right is null then unary */
3203 if (!IS_ARITHMETIC (LTYPE (tree)))
3205 werror (E_UNARY_OP, tree->opval.op);
3206 goto errorTreeReturn;
3209 /* if left is a literal then do it */
3210 if (IS_LITERAL (LTYPE (tree)))
3212 tree->type = EX_VALUE;
3213 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3215 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3216 SPEC_USIGN(TETYPE(tree)) = 0;
3220 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3224 /*------------------------------------------------------------------*/
3225 /*----------------------------*/
3227 /*----------------------------*/
3229 if (!(IS_PTR (LTYPE (tree)) ||
3230 IS_ARRAY (LTYPE (tree)) ||
3231 IS_ARITHMETIC (LTYPE (tree))))
3233 werror (E_PLUS_INVALID, "-");
3234 goto errorTreeReturn;
3237 if (!(IS_PTR (RTYPE (tree)) ||
3238 IS_ARRAY (RTYPE (tree)) ||
3239 IS_ARITHMETIC (RTYPE (tree))))
3241 werror (E_PLUS_INVALID, "-");
3242 goto errorTreeReturn;
3245 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3246 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3247 IS_INTEGRAL (RTYPE (tree))))
3249 werror (E_PLUS_INVALID, "-");
3250 goto errorTreeReturn;
3253 /* if they are both literal then */
3254 /* rewrite the tree */
3255 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3257 tree->type = EX_VALUE;
3258 tree->left = addCast (tree->left, resultType, TRUE);
3259 tree->right = addCast (tree->right, resultType, TRUE);
3260 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3261 valFromType (RETYPE (tree)));
3262 tree->right = tree->left = NULL;
3263 TETYPE (tree) = getSpec (TTYPE (tree) =
3264 tree->opval.val->type);
3268 /* if the left & right are equal then zero */
3269 if (isAstEqual (tree->left, tree->right))
3271 tree->type = EX_VALUE;
3272 tree->left = tree->right = NULL;
3273 tree->opval.val = constVal ("0");
3274 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3278 /* if both of them are pointers or arrays then */
3279 /* the result is going to be an integer */
3280 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3281 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3282 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3284 /* if only the left is a pointer */
3285 /* then result is a pointer */
3286 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3287 TETYPE (tree) = getSpec (TTYPE (tree) =
3291 tree->left = addCast (tree->left, resultType, TRUE);
3292 tree->right = addCast (tree->right, resultType, TRUE);
3294 TETYPE (tree) = getSpec (TTYPE (tree) =
3295 computeType (LTYPE (tree),
3301 LRVAL (tree) = RRVAL (tree) = 1;
3303 /* if right is a literal and */
3304 /* left is also an addition/subtraction with a literal then */
3305 /* rearrange the tree */
3306 if (IS_LITERAL (RTYPE (tree))
3307 /* avoid infinite loop */
3308 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3310 ast *litTree, *litParent;
3311 litTree = searchLitOp (tree, &litParent, "+-");
3314 if (litTree->opval.op == '+')
3318 ast *tTree = litTree->left;
3319 litTree->left = litTree->right;
3320 litTree->right = tree->right;
3321 tree->right = tTree;
3322 tree->opval.op = '+';
3323 litTree->opval.op = '-';
3325 else if (litTree->opval.op == '-')
3327 if (IS_LITERAL (RTYPE (litTree)))
3331 ast *tTree = litTree->left;
3332 litTree->left = tree->right;
3333 tree->right = litParent->left;
3334 litParent->left = tTree;
3335 litTree->opval.op = '+';
3337 tree->decorated = 0;
3338 decorateType (tree, resultType);
3344 ast *tTree = litTree->right;
3345 litTree->right = tree->right;
3346 tree->right = tTree;
3349 decorateType (litParent, resultType);
3354 /*------------------------------------------------------------------*/
3355 /*----------------------------*/
3357 /*----------------------------*/
3359 /* can be only integral type */
3360 if (!IS_INTEGRAL (LTYPE (tree)))
3362 werror (E_UNARY_OP, tree->opval.op);
3363 goto errorTreeReturn;
3366 /* if left is a literal then do it */
3367 if (IS_LITERAL (LTYPE (tree)))
3369 tree->type = EX_VALUE;
3370 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3372 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3373 return addCast (tree, resultType, TRUE);
3375 tree->left = addCast (tree->left, resultType, TRUE);
3377 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3380 /*------------------------------------------------------------------*/
3381 /*----------------------------*/
3383 /*----------------------------*/
3385 /* can be pointer */
3386 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3387 !IS_PTR (LTYPE (tree)) &&
3388 !IS_ARRAY (LTYPE (tree)))
3390 werror (E_UNARY_OP, tree->opval.op);
3391 goto errorTreeReturn;
3394 /* if left is a literal then do it */
3395 if (IS_LITERAL (LTYPE (tree)))
3397 tree->type = EX_VALUE;
3398 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3400 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3404 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3407 /*------------------------------------------------------------------*/
3408 /*----------------------------*/
3410 /*----------------------------*/
3414 TTYPE (tree) = LTYPE (tree);
3415 TETYPE (tree) = LETYPE (tree);
3419 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3424 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3426 werror (E_SHIFT_OP_INVALID);
3427 werror (W_CONTINUE, "left & right types are ");
3428 printTypeChain (LTYPE (tree), stderr);
3429 fprintf (stderr, ",");
3430 printTypeChain (RTYPE (tree), stderr);
3431 fprintf (stderr, "\n");
3432 goto errorTreeReturn;
3435 /* make smaller type only if it's a LEFT_OP */
3436 if (tree->opval.op == LEFT_OP)
3437 tree->left = addCast (tree->left, resultType, TRUE);
3439 /* if they are both literal then */
3440 /* rewrite the tree */
3441 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3443 tree->type = EX_VALUE;
3444 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3445 valFromType (RETYPE (tree)),
3446 (tree->opval.op == LEFT_OP ? 1 : 0));
3447 tree->right = tree->left = NULL;
3448 TETYPE (tree) = getSpec (TTYPE (tree) =
3449 tree->opval.val->type);
3453 LRVAL (tree) = RRVAL (tree) = 1;
3454 if (tree->opval.op == LEFT_OP)
3456 TETYPE (tree) = getSpec (TTYPE (tree) =
3457 computeType (LTYPE (tree),
3464 /* no promotion necessary */
3465 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3466 if (IS_LITERAL (TTYPE (tree)))
3467 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3470 /* if only the right side is a literal & we are
3471 shifting more than size of the left operand then zero */
3472 if (IS_LITERAL (RTYPE (tree)) &&
3473 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3474 (getSize (TETYPE (tree)) * 8))
3476 if (tree->opval.op==LEFT_OP ||
3477 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3479 lineno=tree->lineno;
3480 werror (W_SHIFT_CHANGED,
3481 (tree->opval.op == LEFT_OP ? "left" : "right"));
3482 tree->type = EX_VALUE;
3483 tree->left = tree->right = NULL;
3484 tree->opval.val = constVal ("0");
3485 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3492 /*------------------------------------------------------------------*/
3493 /*----------------------------*/
3495 /*----------------------------*/
3496 case CAST: /* change the type */
3497 /* cannot cast to an aggregate type */
3498 if (IS_AGGREGATE (LTYPE (tree)))
3500 werror (E_CAST_ILLEGAL);
3501 goto errorTreeReturn;
3504 /* make sure the type is complete and sane */
3505 changePointer(LTYPE(tree));
3506 checkTypeSanity(LETYPE(tree), "(cast)");
3508 /* If code memory is read only, then pointers to code memory */
3509 /* implicitly point to constants -- make this explicit */
3511 sym_link *t = LTYPE(tree);
3512 while (t && t->next)
3514 if (IS_CODEPTR(t) && port->mem.code_ro)
3516 if (IS_SPEC(t->next))
3517 SPEC_CONST (t->next) = 1;
3519 DCL_PTR_CONST (t->next) = 1;
3526 /* if the right is a literal replace the tree */
3527 if (IS_LITERAL (RETYPE (tree))) {
3528 if (!IS_PTR (LTYPE (tree))) {
3529 tree->type = EX_VALUE;
3531 valCastLiteral (LTYPE (tree),
3532 floatFromVal (valFromType (RETYPE (tree))));
3535 TTYPE (tree) = tree->opval.val->type;
3536 tree->values.literalFromCast = 1;
3537 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3538 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3539 sym_link *rest = LTYPE(tree)->next;
3540 werror(W_LITERAL_GENERIC);
3541 TTYPE(tree) = newLink(DECLARATOR);
3542 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3543 TTYPE(tree)->next = rest;
3544 tree->left->opval.lnk = TTYPE(tree);
3547 TTYPE (tree) = LTYPE (tree);
3551 TTYPE (tree) = LTYPE (tree);
3555 #if 0 // this is already checked, now this could be explicit
3556 /* if pointer to struct then check names */
3557 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3558 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3559 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3561 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3562 SPEC_STRUCT(LETYPE(tree))->tag);
3565 if (IS_ADDRESS_OF_OP(tree->right)
3566 && IS_AST_SYM_VALUE (tree->right->left)
3567 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3569 symbol * sym = AST_SYMBOL (tree->right->left);
3570 unsigned int gptype = 0;
3571 unsigned int addr = SPEC_ADDR (sym->etype);
3573 if (IS_GENPTR (LTYPE (tree)) && GPTRSIZE > FPTRSIZE)
3575 switch (SPEC_SCLS (sym->etype))
3578 gptype = GPTYPE_CODE;
3581 gptype = GPTYPE_FAR;
3585 gptype = GPTYPE_NEAR;
3588 gptype = GPTYPE_XSTACK;
3593 addr |= gptype << (8*(GPTRSIZE - 1));
3596 tree->type = EX_VALUE;
3598 valCastLiteral (LTYPE (tree), addr);
3599 TTYPE (tree) = tree->opval.val->type;
3600 TETYPE (tree) = getSpec (TTYPE (tree));
3603 tree->values.literalFromCast = 1;
3607 /* handle offsetof macro: */
3608 /* #define offsetof(TYPE, MEMBER) \ */
3609 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3610 if (IS_ADDRESS_OF_OP(tree->right)
3611 && IS_AST_OP (tree->right->left)
3612 && tree->right->left->opval.op == PTR_OP
3613 && IS_AST_OP (tree->right->left->left)
3614 && tree->right->left->left->opval.op == CAST
3615 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3617 symbol *element = getStructElement (
3618 SPEC_STRUCT (LETYPE(tree->right->left)),
3619 AST_SYMBOL(tree->right->left->right)
3623 tree->type = EX_VALUE;
3624 tree->opval.val = valCastLiteral (
3627 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3630 TTYPE (tree) = tree->opval.val->type;
3631 TETYPE (tree) = getSpec (TTYPE (tree));
3638 /* if the right is a literal replace the tree */
3639 if (IS_LITERAL (RETYPE (tree))) {
3641 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3642 /* rewrite (type *)litaddr
3644 and define type at litaddr temp
3645 (but only if type's storage class is not generic)
3647 ast *newTree = newNode ('&', NULL, NULL);
3650 TTYPE (newTree) = LTYPE (tree);
3651 TETYPE (newTree) = getSpec(LTYPE (tree));
3653 /* define a global symbol at the casted address*/
3654 sym = newSymbol(genSymName (0), 0);
3655 sym->type = LTYPE (tree)->next;
3657 sym->type = newLink (V_VOID);
3658 sym->etype = getSpec(sym->type);
3659 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3660 sym->lineDef = tree->lineno;
3663 SPEC_STAT (sym->etype) = 1;
3664 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3665 SPEC_ABSA(sym->etype) = 1;
3666 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3669 newTree->left = newAst_VALUE(symbolVal(sym));
3670 newTree->left->lineno = tree->lineno;
3671 LTYPE (newTree) = sym->type;
3672 LETYPE (newTree) = sym->etype;
3673 LLVAL (newTree) = 1;
3674 LRVAL (newTree) = 0;
3675 TLVAL (newTree) = 1;
3679 if (!IS_PTR (LTYPE (tree))) {
3680 tree->type = EX_VALUE;
3682 valCastLiteral (LTYPE (tree),
3683 floatFromVal (valFromType (RTYPE (tree))));
3684 TTYPE (tree) = tree->opval.val->type;
3687 tree->values.literalFromCast = 1;
3688 TETYPE (tree) = getSpec (TTYPE (tree));
3692 TTYPE (tree) = LTYPE (tree);
3696 TETYPE (tree) = getSpec (TTYPE (tree));
3700 /*------------------------------------------------------------------*/
3701 /*----------------------------*/
3702 /* logical &&, || */
3703 /*----------------------------*/
3706 /* each must be arithmetic type or be a pointer */
3707 if (!IS_PTR (LTYPE (tree)) &&
3708 !IS_ARRAY (LTYPE (tree)) &&
3709 !IS_INTEGRAL (LTYPE (tree)))
3711 werror (E_COMPARE_OP);
3712 goto errorTreeReturn;
3715 if (!IS_PTR (RTYPE (tree)) &&
3716 !IS_ARRAY (RTYPE (tree)) &&
3717 !IS_INTEGRAL (RTYPE (tree)))
3719 werror (E_COMPARE_OP);
3720 goto errorTreeReturn;
3722 /* if they are both literal then */
3723 /* rewrite the tree */
3724 if (IS_LITERAL (RTYPE (tree)) &&
3725 IS_LITERAL (LTYPE (tree)))
3727 tree->type = EX_VALUE;
3728 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3729 valFromType (RTYPE (tree)),
3731 tree->right = tree->left = NULL;
3732 TETYPE (tree) = getSpec (TTYPE (tree) =
3733 tree->opval.val->type);
3736 LRVAL (tree) = RRVAL (tree) = 1;
3737 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3740 /*------------------------------------------------------------------*/
3741 /*----------------------------*/
3742 /* comparison operators */
3743 /*----------------------------*/
3751 ast *lt = optimizeCompare (tree);
3757 /* if they are pointers they must be castable */
3758 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3760 if (tree->opval.op==EQ_OP &&
3761 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3762 // we cannot cast a gptr to a !gptr: switch the leaves
3763 struct ast *s=tree->left;
3764 tree->left=tree->right;
3767 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3769 werror (E_COMPARE_OP);
3770 fprintf (stderr, "comparing type ");
3771 printTypeChain (LTYPE (tree), stderr);
3772 fprintf (stderr, "to type ");
3773 printTypeChain (RTYPE (tree), stderr);
3774 fprintf (stderr, "\n");
3775 goto errorTreeReturn;
3778 /* else they should be promotable to one another */
3781 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3782 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3784 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3786 werror (E_COMPARE_OP);
3787 fprintf (stderr, "comparing type ");
3788 printTypeChain (LTYPE (tree), stderr);
3789 fprintf (stderr, "to type ");
3790 printTypeChain (RTYPE (tree), stderr);
3791 fprintf (stderr, "\n");
3792 goto errorTreeReturn;
3795 /* if unsigned value < 0 then always false */
3796 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3797 if (SPEC_USIGN(LETYPE(tree)) &&
3798 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3799 IS_LITERAL(RTYPE(tree)) &&
3800 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3802 if (tree->opval.op == '<')
3806 if (tree->opval.op == '>')
3808 if (resultType == RESULT_TYPE_IFX)
3810 /* the parent is an ifx: */
3811 /* if (unsigned value) */
3815 /* (unsigned value) ? 1 : 0 */
3816 tree->opval.op = '?';
3817 tree->right = newNode (':',
3818 newAst_VALUE (constVal ("1")),
3819 tree->right); /* val 0 */
3820 tree->right->lineno = tree->lineno;
3821 tree->right->left->lineno = tree->lineno;
3822 decorateType (tree->right, RESULT_TYPE_NONE);
3825 /* if they are both literal then */
3826 /* rewrite the tree */
3827 if (IS_LITERAL (RTYPE (tree)) &&
3828 IS_LITERAL (LTYPE (tree)))
3830 tree->type = EX_VALUE;
3831 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3832 valFromType (RETYPE (tree)),
3834 tree->right = tree->left = NULL;
3835 TETYPE (tree) = getSpec (TTYPE (tree) =
3836 tree->opval.val->type);
3839 LRVAL (tree) = RRVAL (tree) = 1;
3840 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3843 /*------------------------------------------------------------------*/
3844 /*----------------------------*/
3846 /*----------------------------*/
3847 case SIZEOF: /* evaluate wihout code generation */
3848 /* change the type to a integer */
3850 int size = getSize (tree->right->ftype);
3851 SNPRINTF(buffer, sizeof(buffer), "%d", size);
3852 if (!size && !IS_VOID(tree->right->ftype))
3853 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
3855 tree->type = EX_VALUE;
3856 tree->opval.val = constVal (buffer);
3857 tree->right = tree->left = NULL;
3858 TETYPE (tree) = getSpec (TTYPE (tree) =
3859 tree->opval.val->type);
3862 /*------------------------------------------------------------------*/
3863 /*----------------------------*/
3865 /*----------------------------*/
3867 /* return typeof enum value */
3868 tree->type = EX_VALUE;
3871 if (IS_SPEC(tree->right->ftype)) {
3872 switch (SPEC_NOUN(tree->right->ftype)) {
3874 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3875 else typeofv = TYPEOF_INT;
3878 typeofv = TYPEOF_FLOAT;
3881 typeofv = TYPEOF_CHAR;
3884 typeofv = TYPEOF_VOID;
3887 typeofv = TYPEOF_STRUCT;
3890 typeofv = TYPEOF_BITFIELD;
3893 typeofv = TYPEOF_BIT;
3896 typeofv = TYPEOF_SBIT;
3902 switch (DCL_TYPE(tree->right->ftype)) {
3904 typeofv = TYPEOF_POINTER;
3907 typeofv = TYPEOF_FPOINTER;
3910 typeofv = TYPEOF_CPOINTER;
3913 typeofv = TYPEOF_GPOINTER;
3916 typeofv = TYPEOF_PPOINTER;
3919 typeofv = TYPEOF_IPOINTER;
3922 typeofv = TYPEOF_ARRAY;
3925 typeofv = TYPEOF_FUNCTION;
3931 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3932 tree->opval.val = constVal (buffer);
3933 tree->right = tree->left = NULL;
3934 TETYPE (tree) = getSpec (TTYPE (tree) =
3935 tree->opval.val->type);
3938 /*------------------------------------------------------------------*/
3939 /*----------------------------*/
3940 /* conditional operator '?' */
3941 /*----------------------------*/
3943 /* the type is value of the colon operator (on the right) */
3944 assert (IS_COLON_OP (tree->right));
3945 /* if already known then replace the tree : optimizer will do it
3946 but faster to do it here */
3947 if (IS_LITERAL (LTYPE (tree)))
3949 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
3950 return decorateType (tree->right->left, resultTypeProp);
3952 return decorateType (tree->right->right, resultTypeProp);
3956 tree->right = decorateType (tree->right, resultTypeProp);
3957 TTYPE (tree) = RTYPE (tree);
3958 TETYPE (tree) = getSpec (TTYPE (tree));
3963 /* if they don't match we have a problem */
3964 if ((compareType (LTYPE (tree), RTYPE (tree)) == 0) &&
3965 (compareType (RTYPE (tree), LTYPE (tree)) == 0))
3967 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3968 goto errorTreeReturn;
3971 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
3972 resultType, tree->opval.op);
3973 TETYPE (tree) = getSpec (TTYPE (tree));
3977 #if 0 // assignment operators are converted by the parser
3978 /*------------------------------------------------------------------*/
3979 /*----------------------------*/
3980 /* assignment operators */
3981 /*----------------------------*/
3984 /* for these it must be both must be integral */
3985 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3986 !IS_ARITHMETIC (RTYPE (tree)))
3988 werror (E_OPS_INTEGRAL);
3989 goto errorTreeReturn;
3992 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3994 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3995 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3999 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4000 goto errorTreeReturn;
4011 /* for these it must be both must be integral */
4012 if (!IS_INTEGRAL (LTYPE (tree)) ||
4013 !IS_INTEGRAL (RTYPE (tree)))
4015 werror (E_OPS_INTEGRAL);
4016 goto errorTreeReturn;
4019 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4021 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4022 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
4026 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
4027 goto errorTreeReturn;
4033 /*------------------------------------------------------------------*/
4034 /*----------------------------*/
4036 /*----------------------------*/
4038 if (!(IS_PTR (LTYPE (tree)) ||
4039 IS_ARITHMETIC (LTYPE (tree))))
4041 werror (E_PLUS_INVALID, "-=");
4042 goto errorTreeReturn;
4045 if (!(IS_PTR (RTYPE (tree)) ||
4046 IS_ARITHMETIC (RTYPE (tree))))
4048 werror (E_PLUS_INVALID, "-=");
4049 goto errorTreeReturn;
4052 TETYPE (tree) = getSpec (TTYPE (tree) =
4053 computeType (LTYPE (tree),
4058 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4059 werror (E_CODE_WRITE, "-=");
4063 werror (E_LVALUE_REQUIRED, "-=");
4064 goto errorTreeReturn;
4070 /*------------------------------------------------------------------*/
4071 /*----------------------------*/
4073 /*----------------------------*/
4075 /* this is not a unary operation */
4076 /* if both pointers then problem */
4077 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4079 werror (E_PTR_PLUS_PTR);
4080 goto errorTreeReturn;
4083 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4085 werror (E_PLUS_INVALID, "+=");
4086 goto errorTreeReturn;
4089 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4091 werror (E_PLUS_INVALID, "+=");
4092 goto errorTreeReturn;
4095 TETYPE (tree) = getSpec (TTYPE (tree) =
4096 computeType (LTYPE (tree),
4101 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4102 werror (E_CODE_WRITE, "+=");
4106 werror (E_LVALUE_REQUIRED, "+=");
4107 goto errorTreeReturn;
4110 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE);
4111 tree->opval.op = '=';
4116 /*------------------------------------------------------------------*/
4117 /*----------------------------*/
4118 /* straight assignemnt */
4119 /*----------------------------*/
4121 /* cannot be an aggregate */
4122 if (IS_AGGREGATE (LTYPE (tree)))
4124 werror (E_AGGR_ASSIGN);
4125 goto errorTreeReturn;
4128 /* they should either match or be castable */
4129 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4131 werror (E_TYPE_MISMATCH, "assignment", " ");
4132 printFromToType(RTYPE(tree),LTYPE(tree));
4135 /* if the left side of the tree is of type void
4136 then report error */
4137 if (IS_VOID (LTYPE (tree)))
4139 werror (E_CAST_ZERO);
4140 printFromToType(RTYPE(tree), LTYPE(tree));
4143 TETYPE (tree) = getSpec (TTYPE (tree) =
4147 if (!tree->initMode ) {
4148 if (IS_CONSTANT(LTYPE(tree)))
4149 werror (E_CODE_WRITE, "=");
4153 werror (E_LVALUE_REQUIRED, "=");
4154 goto errorTreeReturn;
4159 /*------------------------------------------------------------------*/
4160 /*----------------------------*/
4161 /* comma operator */
4162 /*----------------------------*/
4164 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4167 /*------------------------------------------------------------------*/
4168 /*----------------------------*/
4170 /*----------------------------*/
4173 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4174 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4176 if (tree->left->opval.op == '*' && !tree->left->right)
4177 tree->left = tree->left->left;
4180 /* require a function or pointer to function */
4181 if (!IS_FUNC (LTYPE (tree)) && !IS_FUNCPTR (LTYPE (tree)))
4183 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4184 goto errorTreeReturn;
4187 /* if there are parms, make sure that
4188 parms are decorate / process / reverse only once */
4190 !tree->right->decorated)
4195 if (IS_FUNCPTR (LTYPE (tree)))
4196 functype = LTYPE (tree)->next;
4198 functype = LTYPE (tree);
4200 if (processParms (tree->left, FUNC_ARGS(functype),
4201 &tree->right, &parmNumber, TRUE))
4203 goto errorTreeReturn;
4206 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4207 !IFFUNC_ISBUILTIN(functype))
4209 reverseParms (tree->right);
4212 TTYPE (tree) = functype->next;
4213 TETYPE (tree) = getSpec (TTYPE (tree));
4217 /*------------------------------------------------------------------*/
4218 /*----------------------------*/
4219 /* return statement */
4220 /*----------------------------*/
4225 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4227 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4228 printFromToType (RTYPE(tree), currFunc->type->next);
4229 goto errorTreeReturn;
4232 if (IS_VOID (currFunc->type->next)
4234 !IS_VOID (RTYPE (tree)))
4236 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4237 goto errorTreeReturn;
4240 /* if there is going to be a casting required then add it */
4241 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4244 decorateType (newNode (CAST,
4245 newAst_LINK (copyLinkChain (currFunc->type->next)),
4255 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4257 werror (W_VOID_FUNC, currFunc->name);
4258 goto errorTreeReturn;
4261 TTYPE (tree) = TETYPE (tree) = NULL;
4264 /*------------------------------------------------------------------*/
4265 /*----------------------------*/
4266 /* switch statement */
4267 /*----------------------------*/
4269 /* the switch value must be an integer */
4270 if (!IS_INTEGRAL (LTYPE (tree)))
4272 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4273 goto errorTreeReturn;
4276 TTYPE (tree) = TETYPE (tree) = NULL;
4279 /*------------------------------------------------------------------*/
4280 /*----------------------------*/
4282 /*----------------------------*/
4284 tree->left = backPatchLabels (tree->left,
4287 TTYPE (tree) = TETYPE (tree) = NULL;
4290 /*------------------------------------------------------------------*/
4291 /*----------------------------*/
4293 /*----------------------------*/
4296 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE);
4297 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE);
4298 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE);
4300 /* if the for loop is reversible then
4301 reverse it otherwise do what we normally
4307 if (isLoopReversible (tree, &sym, &init, &end))
4308 return reverseLoop (tree, sym, init, end);
4310 return decorateType (createFor (AST_FOR (tree, trueLabel),
4311 AST_FOR (tree, continueLabel),
4312 AST_FOR (tree, falseLabel),
4313 AST_FOR (tree, condLabel),
4314 AST_FOR (tree, initExpr),
4315 AST_FOR (tree, condExpr),
4316 AST_FOR (tree, loopExpr),
4317 tree->left), RESULT_TYPE_NONE);
4320 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4321 "node PARAM shouldn't be processed here");
4322 /* but in processParams() */
4325 TTYPE (tree) = TETYPE (tree) = NULL;
4329 /* some error found this tree will be killed */
4331 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4332 tree->opval.op = NULLOP;
4338 /*-----------------------------------------------------------------*/
4339 /* sizeofOp - processes size of operation */
4340 /*-----------------------------------------------------------------*/
4342 sizeofOp (sym_link * type)
4347 /* make sure the type is complete and sane */
4348 checkTypeSanity(type, "(sizeof)");
4350 /* get the size and convert it to character */
4351 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4352 if (!size && !IS_VOID(type))
4353 werror (E_SIZEOF_INCOMPLETE_TYPE);
4355 /* now convert into value */
4356 return constVal (buff);
4360 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4361 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4362 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4363 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4364 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4365 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4366 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4368 /*-----------------------------------------------------------------*/
4369 /* backPatchLabels - change and or not operators to flow control */
4370 /*-----------------------------------------------------------------*/
4372 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4378 if (!(IS_ANDORNOT (tree)))
4381 /* if this an and */
4384 static int localLbl = 0;
4387 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4388 localLabel = newSymbol (buffer, NestLevel);
4390 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4392 /* if left is already a IFX then just change the if true label in that */
4393 if (!IS_IFX (tree->left))
4394 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4396 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4397 /* right is a IFX then just join */
4398 if (IS_IFX (tree->right))
4399 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4401 tree->right = createLabel (localLabel, tree->right);
4402 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4404 return newNode (NULLOP, tree->left, tree->right);
4407 /* if this is an or operation */
4410 static int localLbl = 0;
4413 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4414 localLabel = newSymbol (buffer, NestLevel);
4416 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4418 /* if left is already a IFX then just change the if true label in that */
4419 if (!IS_IFX (tree->left))
4420 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4422 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4423 /* right is a IFX then just join */
4424 if (IS_IFX (tree->right))
4425 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4427 tree->right = createLabel (localLabel, tree->right);
4428 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4430 return newNode (NULLOP, tree->left, tree->right);
4436 int wasnot = IS_NOT (tree->left);
4437 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4439 /* if the left is already a IFX */
4440 if (!IS_IFX (tree->left))
4441 tree->left = newNode (IFX, tree->left, NULL);
4445 tree->left->trueLabel = trueLabel;
4446 tree->left->falseLabel = falseLabel;
4450 tree->left->trueLabel = falseLabel;
4451 tree->left->falseLabel = trueLabel;
4458 tree->trueLabel = trueLabel;
4459 tree->falseLabel = falseLabel;
4466 /*-----------------------------------------------------------------*/
4467 /* createBlock - create expression tree for block */
4468 /*-----------------------------------------------------------------*/
4470 createBlock (symbol * decl, ast * body)
4474 /* if the block has nothing */
4478 ex = newNode (BLOCK, NULL, body);
4479 ex->values.sym = decl;
4486 /*-----------------------------------------------------------------*/
4487 /* createLabel - creates the expression tree for labels */
4488 /*-----------------------------------------------------------------*/
4490 createLabel (symbol * label, ast * stmnt)
4493 char name[SDCC_NAME_MAX + 1];
4496 /* must create fresh symbol if the symbol name */
4497 /* exists in the symbol table, since there can */
4498 /* be a variable with the same name as the labl */
4499 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4500 (csym->level == label->level))
4501 label = newSymbol (label->name, label->level);
4503 /* change the name before putting it in add _ */
4504 SNPRINTF(name, sizeof(name), "%s", label->name);
4506 /* put the label in the LabelSymbol table */
4507 /* but first check if a label of the same */
4509 if ((csym = findSym (LabelTab, NULL, name)))
4510 werror (E_DUPLICATE_LABEL, label->name);
4512 addSym (LabelTab, label, name, label->level, 0, 0);
4516 label->key = labelKey++;
4517 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4523 /*-----------------------------------------------------------------*/
4524 /* createCase - generates the parsetree for a case statement */
4525 /*-----------------------------------------------------------------*/
4527 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4529 char caseLbl[SDCC_NAME_MAX + 1];
4533 /* if the switch statement does not exist */
4534 /* then case is out of context */
4537 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4541 caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE);
4542 /* if not a constant then error */
4543 if (!IS_LITERAL (caseVal->ftype))
4545 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4549 /* if not a integer than error */
4550 if (!IS_INTEGRAL (caseVal->ftype))
4552 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4556 /* find the end of the switch values chain */
4557 if (!(val = swStat->values.switchVals.swVals))
4558 swStat->values.switchVals.swVals = caseVal->opval.val;
4561 /* also order the cases according to value */
4563 int cVal = (int) floatFromVal (caseVal->opval.val);
4564 while (val && (int) floatFromVal (val) < cVal)
4570 /* if we reached the end then */
4573 pval->next = caseVal->opval.val;
4575 else if ((int) floatFromVal (val) == cVal)
4577 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4583 /* we found a value greater than */
4584 /* the current value we must add this */
4585 /* before the value */
4586 caseVal->opval.val->next = val;
4588 /* if this was the first in chain */
4589 if (swStat->values.switchVals.swVals == val)
4590 swStat->values.switchVals.swVals =
4593 pval->next = caseVal->opval.val;
4598 /* create the case label */
4599 SNPRINTF(caseLbl, sizeof(caseLbl),
4601 swStat->values.switchVals.swNum,
4602 (int) floatFromVal (caseVal->opval.val));
4604 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4609 /*-----------------------------------------------------------------*/
4610 /* createDefault - creates the parse tree for the default statement */
4611 /*-----------------------------------------------------------------*/
4613 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4615 char defLbl[SDCC_NAME_MAX + 1];
4617 /* if the switch statement does not exist */
4618 /* then case is out of context */
4621 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4625 if (swStat->values.switchVals.swDefault)
4627 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4632 /* turn on the default flag */
4633 swStat->values.switchVals.swDefault = 1;
4635 /* create the label */
4636 SNPRINTF (defLbl, sizeof(defLbl),
4637 "_default_%d", swStat->values.switchVals.swNum);
4638 return createLabel (newSymbol (defLbl, 0), stmnt);
4641 /*-----------------------------------------------------------------*/
4642 /* createIf - creates the parsetree for the if statement */
4643 /*-----------------------------------------------------------------*/
4645 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4647 static int Lblnum = 0;
4649 symbol *ifTrue, *ifFalse, *ifEnd;
4651 /* if neither exists */
4652 if (!elseBody && !ifBody) {
4653 // if there are no side effects (i++, j() etc)
4654 if (!hasSEFcalls(condAst)) {
4659 /* create the labels */
4660 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4661 ifFalse = newSymbol (buffer, NestLevel);
4662 /* if no else body then end == false */
4667 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4668 ifEnd = newSymbol (buffer, NestLevel);
4671 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4672 ifTrue = newSymbol (buffer, NestLevel);
4676 /* attach the ifTrue label to the top of it body */
4677 ifBody = createLabel (ifTrue, ifBody);
4678 /* attach a goto end to the ifBody if else is present */
4681 ifBody = newNode (NULLOP, ifBody,
4683 newAst_VALUE (symbolVal (ifEnd)),
4685 /* put the elseLabel on the else body */
4686 elseBody = createLabel (ifFalse, elseBody);
4687 /* out the end at the end of the body */
4688 elseBody = newNode (NULLOP,
4690 createLabel (ifEnd, NULL));
4694 ifBody = newNode (NULLOP, ifBody,
4695 createLabel (ifFalse, NULL));
4697 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4698 if (IS_IFX (condAst))
4701 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4703 return newNode (NULLOP, ifTree,
4704 newNode (NULLOP, ifBody, elseBody));
4708 /*-----------------------------------------------------------------*/
4709 /* createDo - creates parse tree for do */
4712 /* _docontinue_n: */
4713 /* condition_expression +-> trueLabel -> _dobody_n */
4715 /* +-> falseLabel-> _dobreak_n */
4717 /*-----------------------------------------------------------------*/
4719 createDo (symbol * trueLabel, symbol * continueLabel,
4720 symbol * falseLabel, ast * condAst, ast * doBody)
4725 /* if the body does not exist then it is simple */
4728 condAst = backPatchLabels (condAst, continueLabel, NULL);
4729 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4730 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4731 doTree->trueLabel = continueLabel;
4732 doTree->falseLabel = NULL;
4736 /* otherwise we have a body */
4737 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4739 /* attach the body label to the top */
4740 doBody = createLabel (trueLabel, doBody);
4741 /* attach the continue label to end of body */
4742 doBody = newNode (NULLOP, doBody,
4743 createLabel (continueLabel, NULL));
4745 /* now put the break label at the end */
4746 if (IS_IFX (condAst))
4749 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4751 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4753 /* putting it together */
4754 return newNode (NULLOP, doBody, doTree);
4757 /*-----------------------------------------------------------------*/
4758 /* createFor - creates parse tree for 'for' statement */
4761 /* condExpr +-> trueLabel -> _forbody_n */
4763 /* +-> falseLabel-> _forbreak_n */
4766 /* _forcontinue_n: */
4768 /* goto _forcond_n ; */
4770 /*-----------------------------------------------------------------*/
4772 createFor (symbol * trueLabel, symbol * continueLabel,
4773 symbol * falseLabel, symbol * condLabel,
4774 ast * initExpr, ast * condExpr, ast * loopExpr,
4779 /* if loopexpression not present then we can generate it */
4780 /* the same way as a while */
4782 return newNode (NULLOP, initExpr,
4783 createWhile (trueLabel, continueLabel,
4784 falseLabel, condExpr, forBody));
4785 /* vanilla for statement */
4786 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4788 if (condExpr && !IS_IFX (condExpr))
4789 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4792 /* attach condition label to condition */
4793 condExpr = createLabel (condLabel, condExpr);
4795 /* attach body label to body */
4796 forBody = createLabel (trueLabel, forBody);
4798 /* attach continue to forLoop expression & attach */
4799 /* goto the forcond @ and of loopExpression */
4800 loopExpr = createLabel (continueLabel,
4804 newAst_VALUE (symbolVal (condLabel)),
4806 /* now start putting them together */
4807 forTree = newNode (NULLOP, initExpr, condExpr);
4808 forTree = newNode (NULLOP, forTree, forBody);
4809 forTree = newNode (NULLOP, forTree, loopExpr);
4810 /* finally add the break label */
4811 forTree = newNode (NULLOP, forTree,
4812 createLabel (falseLabel, NULL));
4816 /*-----------------------------------------------------------------*/
4817 /* createWhile - creates parse tree for while statement */
4818 /* the while statement will be created as follows */
4820 /* _while_continue_n: */
4821 /* condition_expression +-> trueLabel -> _while_boby_n */
4823 /* +-> falseLabel -> _while_break_n */
4824 /* _while_body_n: */
4826 /* goto _while_continue_n */
4827 /* _while_break_n: */
4828 /*-----------------------------------------------------------------*/
4830 createWhile (symbol * trueLabel, symbol * continueLabel,
4831 symbol * falseLabel, ast * condExpr, ast * whileBody)
4835 /* put the continue label */
4836 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4837 condExpr = createLabel (continueLabel, condExpr);
4838 condExpr->lineno = 0;
4840 /* put the body label in front of the body */
4841 whileBody = createLabel (trueLabel, whileBody);
4842 whileBody->lineno = 0;
4843 /* put a jump to continue at the end of the body */
4844 /* and put break label at the end of the body */
4845 whileBody = newNode (NULLOP,
4848 newAst_VALUE (symbolVal (continueLabel)),
4849 createLabel (falseLabel, NULL)));
4851 /* put it all together */
4852 if (IS_IFX (condExpr))
4853 whileTree = condExpr;
4856 whileTree = newNode (IFX, condExpr, NULL);
4857 /* put the true & false labels in place */
4858 whileTree->trueLabel = trueLabel;
4859 whileTree->falseLabel = falseLabel;
4862 return newNode (NULLOP, whileTree, whileBody);
4865 /*-----------------------------------------------------------------*/
4866 /* optimizeGetHbit - get highest order bit of the expression */
4867 /*-----------------------------------------------------------------*/
4869 optimizeGetHbit (ast * tree)
4872 /* if this is not a bit and */
4873 if (!IS_BITAND (tree))
4876 /* will look for tree of the form
4877 ( expr >> ((sizeof expr) -1) ) & 1 */
4878 if (!IS_AST_LIT_VALUE (tree->right))
4881 if (AST_LIT_VALUE (tree->right) != 1)
4884 if (!IS_RIGHT_OP (tree->left))
4887 if (!IS_AST_LIT_VALUE (tree->left->right))
4890 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4891 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4894 /* make sure the port supports GETHBIT */
4895 if (port->hasExtBitOp
4896 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4899 return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_TYPE_NONE);
4903 /*-----------------------------------------------------------------*/
4904 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4905 /*-----------------------------------------------------------------*/
4907 optimizeRRCRLC (ast * root)
4909 /* will look for trees of the form
4910 (?expr << 1) | (?expr >> 7) or
4911 (?expr >> 7) | (?expr << 1) will make that
4912 into a RLC : operation ..
4914 (?expr >> 1) | (?expr << 7) or
4915 (?expr << 7) | (?expr >> 1) will make that
4916 into a RRC operation
4917 note : by 7 I mean (number of bits required to hold the
4919 /* if the root operations is not a | operation the not */
4920 if (!IS_BITOR (root))
4923 /* I have to think of a better way to match patterns this sucks */
4924 /* that aside let start looking for the first case : I use a the
4925 negative check a lot to improve the efficiency */
4926 /* (?expr << 1) | (?expr >> 7) */
4927 if (IS_LEFT_OP (root->left) &&
4928 IS_RIGHT_OP (root->right))
4931 if (!SPEC_USIGN (TETYPE (root->left->left)))
4934 if (!IS_AST_LIT_VALUE (root->left->right) ||
4935 !IS_AST_LIT_VALUE (root->right->right))
4938 /* make sure it is the same expression */
4939 if (!isAstEqual (root->left->left,
4943 if (AST_LIT_VALUE (root->left->right) != 1)
4946 if (AST_LIT_VALUE (root->right->right) !=
4947 (getSize (TTYPE (root->left->left)) * 8 - 1))
4950 /* make sure the port supports RLC */
4951 if (port->hasExtBitOp
4952 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4955 /* whew got the first case : create the AST */
4956 return newNode (RLC, root->left->left, NULL);
4960 /* check for second case */
4961 /* (?expr >> 7) | (?expr << 1) */
4962 if (IS_LEFT_OP (root->right) &&
4963 IS_RIGHT_OP (root->left))
4966 if (!SPEC_USIGN (TETYPE (root->left->left)))
4969 if (!IS_AST_LIT_VALUE (root->left->right) ||
4970 !IS_AST_LIT_VALUE (root->right->right))
4973 /* make sure it is the same symbol */
4974 if (!isAstEqual (root->left->left,
4978 if (AST_LIT_VALUE (root->right->right) != 1)
4981 if (AST_LIT_VALUE (root->left->right) !=
4982 (getSize (TTYPE (root->left->left)) * 8 - 1))
4985 /* make sure the port supports RLC */
4986 if (port->hasExtBitOp
4987 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4990 /* whew got the first case : create the AST */
4991 return newNode (RLC, root->left->left, NULL);
4996 /* third case for RRC */
4997 /* (?symbol >> 1) | (?symbol << 7) */
4998 if (IS_LEFT_OP (root->right) &&
4999 IS_RIGHT_OP (root->left))
5002 if (!SPEC_USIGN (TETYPE (root->left->left)))
5005 if (!IS_AST_LIT_VALUE (root->left->right) ||
5006 !IS_AST_LIT_VALUE (root->right->right))
5009 /* make sure it is the same symbol */
5010 if (!isAstEqual (root->left->left,
5014 if (AST_LIT_VALUE (root->left->right) != 1)
5017 if (AST_LIT_VALUE (root->right->right) !=
5018 (getSize (TTYPE (root->left->left)) * 8 - 1))
5021 /* make sure the port supports RRC */
5022 if (port->hasExtBitOp
5023 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5026 /* whew got the first case : create the AST */
5027 return newNode (RRC, root->left->left, NULL);
5031 /* fourth and last case for now */
5032 /* (?symbol << 7) | (?symbol >> 1) */
5033 if (IS_RIGHT_OP (root->right) &&
5034 IS_LEFT_OP (root->left))
5037 if (!SPEC_USIGN (TETYPE (root->left->left)))
5040 if (!IS_AST_LIT_VALUE (root->left->right) ||
5041 !IS_AST_LIT_VALUE (root->right->right))
5044 /* make sure it is the same symbol */
5045 if (!isAstEqual (root->left->left,
5049 if (AST_LIT_VALUE (root->right->right) != 1)
5052 if (AST_LIT_VALUE (root->left->right) !=
5053 (getSize (TTYPE (root->left->left)) * 8 - 1))
5056 /* make sure the port supports RRC */
5057 if (port->hasExtBitOp
5058 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5061 /* whew got the first case : create the AST */
5062 return newNode (RRC, root->left->left, NULL);
5066 /* not found return root */
5070 /*-----------------------------------------------------------------*/
5071 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
5072 /*-----------------------------------------------------------------*/
5074 optimizeSWAP (ast * root)
5076 /* will look for trees of the form
5077 (?expr << 4) | (?expr >> 4) or
5078 (?expr >> 4) | (?expr << 4) will make that
5079 into a SWAP : operation ..
5080 note : by 4 I mean (number of bits required to hold the
5082 /* if the root operations is not a | operation the not */
5083 if (!IS_BITOR (root))
5086 /* (?expr << 4) | (?expr >> 4) */
5087 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5088 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5091 if (!SPEC_USIGN (TETYPE (root->left->left)))
5094 if (!IS_AST_LIT_VALUE (root->left->right) ||
5095 !IS_AST_LIT_VALUE (root->right->right))
5098 /* make sure it is the same expression */
5099 if (!isAstEqual (root->left->left,
5103 if (AST_LIT_VALUE (root->left->right) !=
5104 (getSize (TTYPE (root->left->left)) * 4))
5107 if (AST_LIT_VALUE (root->right->right) !=
5108 (getSize (TTYPE (root->left->left)) * 4))
5111 /* make sure the port supports SWAP */
5112 if (port->hasExtBitOp
5113 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5116 /* found it : create the AST */
5117 return newNode (SWAP, root->left->left, NULL);
5121 /* not found return root */
5125 /*-----------------------------------------------------------------*/
5126 /* optimizeCompare - otimizes compares for bit variables */
5127 /*-----------------------------------------------------------------*/
5129 optimizeCompare (ast * root)
5131 ast *optExpr = NULL;
5134 unsigned int litValue;
5136 /* if nothing then return nothing */
5140 /* if not a compare op then do leaves */
5141 if (!IS_COMPARE_OP (root))
5143 root->left = optimizeCompare (root->left);
5144 root->right = optimizeCompare (root->right);
5148 /* if left & right are the same then depending
5149 of the operation do */
5150 if (isAstEqual (root->left, root->right))
5152 switch (root->opval.op)
5157 optExpr = newAst_VALUE (constVal ("0"));
5162 optExpr = newAst_VALUE (constVal ("1"));
5166 return decorateType (optExpr, RESULT_TYPE_NONE);
5169 vleft = (root->left->type == EX_VALUE ?
5170 root->left->opval.val : NULL);
5172 vright = (root->right->type == EX_VALUE ?
5173 root->right->opval.val : NULL);
5175 /* if left is a BITVAR in BITSPACE */
5176 /* and right is a LITERAL then opt- */
5177 /* imize else do nothing */
5178 if (vleft && vright &&
5179 IS_BITVAR (vleft->etype) &&
5180 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5181 IS_LITERAL (vright->etype))
5184 /* if right side > 1 then comparison may never succeed */
5185 if ((litValue = (int) floatFromVal (vright)) > 1)
5187 werror (W_BAD_COMPARE);
5193 switch (root->opval.op)
5195 case '>': /* bit value greater than 1 cannot be */
5196 werror (W_BAD_COMPARE);
5200 case '<': /* bit value < 1 means 0 */
5202 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5205 case LE_OP: /* bit value <= 1 means no check */
5206 optExpr = newAst_VALUE (vright);
5209 case GE_OP: /* bit value >= 1 means only check for = */
5211 optExpr = newAst_VALUE (vleft);
5216 { /* literal is zero */
5217 switch (root->opval.op)
5219 case '<': /* bit value < 0 cannot be */
5220 werror (W_BAD_COMPARE);
5224 case '>': /* bit value > 0 means 1 */
5226 optExpr = newAst_VALUE (vleft);
5229 case LE_OP: /* bit value <= 0 means no check */
5230 case GE_OP: /* bit value >= 0 means no check */
5231 werror (W_BAD_COMPARE);
5235 case EQ_OP: /* bit == 0 means ! of bit */
5236 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5240 return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE);
5241 } /* end-of-if of BITVAR */
5246 /*-----------------------------------------------------------------*/
5247 /* addSymToBlock : adds the symbol to the first block we find */
5248 /*-----------------------------------------------------------------*/
5250 addSymToBlock (symbol * sym, ast * tree)
5252 /* reached end of tree or a leaf */
5253 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5257 if (IS_AST_OP (tree) &&
5258 tree->opval.op == BLOCK)
5261 symbol *lsym = copySymbol (sym);
5263 lsym->next = AST_VALUES (tree, sym);
5264 AST_VALUES (tree, sym) = lsym;
5268 addSymToBlock (sym, tree->left);
5269 addSymToBlock (sym, tree->right);
5272 /*-----------------------------------------------------------------*/
5273 /* processRegParms - do processing for register parameters */
5274 /*-----------------------------------------------------------------*/
5276 processRegParms (value * args, ast * body)
5280 if (IS_REGPARM (args->etype))
5281 addSymToBlock (args->sym, body);
5286 /*-----------------------------------------------------------------*/
5287 /* resetParmKey - resets the operandkeys for the symbols */
5288 /*-----------------------------------------------------------------*/
5289 DEFSETFUNC (resetParmKey)
5300 /*-----------------------------------------------------------------*/
5301 /* createFunction - This is the key node that calls the iCode for */
5302 /* generating the code for a function. Note code */
5303 /* is generated function by function, later when */
5304 /* add inter-procedural analysis this will change */
5305 /*-----------------------------------------------------------------*/
5307 createFunction (symbol * name, ast * body)
5313 iCode *piCode = NULL;
5315 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5316 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5318 /* if check function return 0 then some problem */
5319 if (checkFunction (name, NULL) == 0)
5322 /* create a dummy block if none exists */
5324 body = newNode (BLOCK, NULL, NULL);
5328 /* check if the function name already in the symbol table */
5329 if ((csym = findSym (SymbolTab, NULL, name->name)))
5332 /* special case for compiler defined functions
5333 we need to add the name to the publics list : this
5334 actually means we are now compiling the compiler
5338 addSet (&publics, name);
5343 addSymChain (&name);
5344 allocVariables (name);
5346 name->lastLine = mylineno;
5349 /* set the stack pointer */
5350 stackPtr = -port->stack.direction * port->stack.call_overhead;
5353 if (IFFUNC_ISISR (name->type))
5354 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5356 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5358 if (options.useXstack)
5359 xstackPtr -= port->stack.direction * port->stack.reent_overhead;
5361 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5364 fetype = getSpec (name->type); /* get the specifier for the function */
5365 /* if this is a reentrant function then */
5366 if (IFFUNC_ISREENT (name->type))
5369 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5371 /* do processing for parameters that are passed in registers */
5372 processRegParms (FUNC_ARGS(name->type), body);
5374 /* set the stack pointer */
5378 /* allocate & autoinit the block variables */
5379 processBlockVars (body, &stack, ALLOCATE);
5381 /* save the stack information */
5382 if (options.useXstack)
5383 name->xstack = SPEC_STAK (fetype) = stack;
5385 name->stack = SPEC_STAK (fetype) = stack;
5387 /* name needs to be mangled */
5388 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5390 body = resolveSymbols (body); /* resolve the symbols */
5391 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5394 ex = newAst_VALUE (symbolVal (name)); /* create name */
5395 ex = newNode (FUNCTION, ex, body);
5396 ex->values.args = FUNC_ARGS(name->type);
5398 if (options.dump_tree) PA(ex);
5401 werror (E_FUNC_NO_CODE, name->name);
5405 /* create the node & generate intermediate code */
5407 codeOutFile = code->oFile;
5408 piCode = iCodeFromAst (ex);
5412 werror (E_FUNC_NO_CODE, name->name);
5416 eBBlockFromiCode (piCode);
5418 /* if there are any statics then do them */
5421 GcurMemmap = statsg;
5422 codeOutFile = statsg->oFile;
5423 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE)));
5429 /* dealloc the block variables */
5430 processBlockVars (body, &stack, DEALLOCATE);
5431 outputDebugStackSymbols();
5432 /* deallocate paramaters */
5433 deallocParms (FUNC_ARGS(name->type));
5435 if (IFFUNC_ISREENT (name->type))
5438 /* we are done freeup memory & cleanup */
5440 if (port->reset_labelKey) labelKey = 1;
5442 FUNC_HASBODY(name->type) = 1;
5443 addSet (&operKeyReset, name);
5444 applyToSet (operKeyReset, resetParmKey);
5449 cleanUpLevel (LabelTab, 0);
5450 cleanUpBlock (StructTab, 1);
5451 cleanUpBlock (TypedefTab, 1);
5453 xstack->syms = NULL;
5454 istack->syms = NULL;
5459 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5460 /*-----------------------------------------------------------------*/
5461 /* ast_print : prints the ast (for debugging purposes) */
5462 /*-----------------------------------------------------------------*/
5464 void ast_print (ast * tree, FILE *outfile, int indent)
5469 /* can print only decorated trees */
5470 if (!tree->decorated) return;
5472 /* if any child is an error | this one is an error do nothing */
5473 if (tree->isError ||
5474 (tree->left && tree->left->isError) ||
5475 (tree->right && tree->right->isError)) {
5476 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5480 /* print the line */
5481 /* if not block & function */
5482 if (tree->type == EX_OP &&
5483 (tree->opval.op != FUNCTION &&
5484 tree->opval.op != BLOCK &&
5485 tree->opval.op != NULLOP)) {
5488 if (tree->opval.op == FUNCTION) {
5490 value *args=FUNC_ARGS(tree->left->opval.val->type);
5491 fprintf(outfile,"FUNCTION (%s=%p) type (",
5492 tree->left->opval.val->name, tree);
5493 printTypeChain (tree->left->opval.val->type->next,outfile);
5494 fprintf(outfile,") args (");
5497 fprintf (outfile, ", ");
5499 printTypeChain (args ? args->type : NULL, outfile);
5501 args= args ? args->next : NULL;
5503 fprintf(outfile,")\n");
5504 ast_print(tree->left,outfile,indent);
5505 ast_print(tree->right,outfile,indent);
5508 if (tree->opval.op == BLOCK) {
5509 symbol *decls = tree->values.sym;
5510 INDENT(indent,outfile);
5511 fprintf(outfile,"{\n");
5513 INDENT(indent+2,outfile);
5514 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5515 decls->name, decls);
5516 printTypeChain(decls->type,outfile);
5517 fprintf(outfile,")\n");
5519 decls = decls->next;
5521 ast_print(tree->right,outfile,indent+2);
5522 INDENT(indent,outfile);
5523 fprintf(outfile,"}\n");
5526 if (tree->opval.op == NULLOP) {
5527 ast_print(tree->left,outfile,indent);
5528 ast_print(tree->right,outfile,indent);
5531 INDENT(indent,outfile);
5533 /*------------------------------------------------------------------*/
5534 /*----------------------------*/
5535 /* leaf has been reached */
5536 /*----------------------------*/
5537 /* if this is of type value */
5538 /* just get the type */
5539 if (tree->type == EX_VALUE) {
5541 if (IS_LITERAL (tree->opval.val->etype)) {
5542 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5543 if (SPEC_USIGN (tree->opval.val->etype))
5544 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5546 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5547 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5548 floatFromVal(tree->opval.val));
5549 } else if (tree->opval.val->sym) {
5550 /* if the undefined flag is set then give error message */
5551 if (tree->opval.val->sym->undefined) {
5552 fprintf(outfile,"UNDEFINED SYMBOL ");
5554 fprintf(outfile,"SYMBOL ");
5556 fprintf(outfile,"(%s=%p)",
5557 tree->opval.val->sym->name,tree);
5560 fprintf(outfile," type (");
5561 printTypeChain(tree->ftype,outfile);
5562 fprintf(outfile,")\n");
5564 fprintf(outfile,"\n");
5569 /* if type link for the case of cast */
5570 if (tree->type == EX_LINK) {
5571 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5572 printTypeChain(tree->opval.lnk,outfile);
5573 fprintf(outfile,")\n");
5578 /* depending on type of operator do */
5580 switch (tree->opval.op) {
5581 /*------------------------------------------------------------------*/
5582 /*----------------------------*/
5584 /*----------------------------*/
5586 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5587 printTypeChain(tree->ftype,outfile);
5588 fprintf(outfile,")\n");
5589 ast_print(tree->left,outfile,indent+2);
5590 ast_print(tree->right,outfile,indent+2);
5593 /*------------------------------------------------------------------*/
5594 /*----------------------------*/
5596 /*----------------------------*/
5598 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5599 printTypeChain(tree->ftype,outfile);
5600 fprintf(outfile,")\n");
5601 ast_print(tree->left,outfile,indent+2);
5602 ast_print(tree->right,outfile,indent+2);
5605 /*------------------------------------------------------------------*/
5606 /*----------------------------*/
5607 /* struct/union pointer */
5608 /*----------------------------*/
5610 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5611 printTypeChain(tree->ftype,outfile);
5612 fprintf(outfile,")\n");
5613 ast_print(tree->left,outfile,indent+2);
5614 ast_print(tree->right,outfile,indent+2);
5617 /*------------------------------------------------------------------*/
5618 /*----------------------------*/
5619 /* ++/-- operation */
5620 /*----------------------------*/
5623 fprintf(outfile,"post-");
5625 fprintf(outfile,"pre-");
5626 fprintf(outfile,"INC_OP (%p) type (",tree);
5627 printTypeChain(tree->ftype,outfile);
5628 fprintf(outfile,")\n");
5629 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5630 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5635 fprintf(outfile,"post-");
5637 fprintf(outfile,"pre-");
5638 fprintf(outfile,"DEC_OP (%p) type (",tree);
5639 printTypeChain(tree->ftype,outfile);
5640 fprintf(outfile,")\n");
5641 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5642 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5645 /*------------------------------------------------------------------*/
5646 /*----------------------------*/
5648 /*----------------------------*/
5651 fprintf(outfile,"& (%p) type (",tree);
5652 printTypeChain(tree->ftype,outfile);
5653 fprintf(outfile,")\n");
5654 ast_print(tree->left,outfile,indent+2);
5655 ast_print(tree->right,outfile,indent+2);
5657 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5658 printTypeChain(tree->ftype,outfile);
5659 fprintf(outfile,")\n");
5660 ast_print(tree->left,outfile,indent+2);
5661 ast_print(tree->right,outfile,indent+2);
5664 /*----------------------------*/
5666 /*----------------------------*/
5668 fprintf(outfile,"OR (%p) type (",tree);
5669 printTypeChain(tree->ftype,outfile);
5670 fprintf(outfile,")\n");
5671 ast_print(tree->left,outfile,indent+2);
5672 ast_print(tree->right,outfile,indent+2);
5674 /*------------------------------------------------------------------*/
5675 /*----------------------------*/
5677 /*----------------------------*/
5679 fprintf(outfile,"XOR (%p) type (",tree);
5680 printTypeChain(tree->ftype,outfile);
5681 fprintf(outfile,")\n");
5682 ast_print(tree->left,outfile,indent+2);
5683 ast_print(tree->right,outfile,indent+2);
5686 /*------------------------------------------------------------------*/
5687 /*----------------------------*/
5689 /*----------------------------*/
5691 fprintf(outfile,"DIV (%p) type (",tree);
5692 printTypeChain(tree->ftype,outfile);
5693 fprintf(outfile,")\n");
5694 ast_print(tree->left,outfile,indent+2);
5695 ast_print(tree->right,outfile,indent+2);
5697 /*------------------------------------------------------------------*/
5698 /*----------------------------*/
5700 /*----------------------------*/
5702 fprintf(outfile,"MOD (%p) type (",tree);
5703 printTypeChain(tree->ftype,outfile);
5704 fprintf(outfile,")\n");
5705 ast_print(tree->left,outfile,indent+2);
5706 ast_print(tree->right,outfile,indent+2);
5709 /*------------------------------------------------------------------*/
5710 /*----------------------------*/
5711 /* address dereference */
5712 /*----------------------------*/
5713 case '*': /* can be unary : if right is null then unary operation */
5715 fprintf(outfile,"DEREF (%p) type (",tree);
5716 printTypeChain(tree->ftype,outfile);
5717 fprintf(outfile,")\n");
5718 ast_print(tree->left,outfile,indent+2);
5721 /*------------------------------------------------------------------*/
5722 /*----------------------------*/
5723 /* multiplication */
5724 /*----------------------------*/
5725 fprintf(outfile,"MULT (%p) type (",tree);
5726 printTypeChain(tree->ftype,outfile);
5727 fprintf(outfile,")\n");
5728 ast_print(tree->left,outfile,indent+2);
5729 ast_print(tree->right,outfile,indent+2);
5733 /*------------------------------------------------------------------*/
5734 /*----------------------------*/
5735 /* unary '+' operator */
5736 /*----------------------------*/
5740 fprintf(outfile,"UPLUS (%p) type (",tree);
5741 printTypeChain(tree->ftype,outfile);
5742 fprintf(outfile,")\n");
5743 ast_print(tree->left,outfile,indent+2);
5745 /*------------------------------------------------------------------*/
5746 /*----------------------------*/
5748 /*----------------------------*/
5749 fprintf(outfile,"ADD (%p) type (",tree);
5750 printTypeChain(tree->ftype,outfile);
5751 fprintf(outfile,")\n");
5752 ast_print(tree->left,outfile,indent+2);
5753 ast_print(tree->right,outfile,indent+2);
5756 /*------------------------------------------------------------------*/
5757 /*----------------------------*/
5759 /*----------------------------*/
5760 case '-': /* can be unary */
5762 fprintf(outfile,"UMINUS (%p) type (",tree);
5763 printTypeChain(tree->ftype,outfile);
5764 fprintf(outfile,")\n");
5765 ast_print(tree->left,outfile,indent+2);
5767 /*------------------------------------------------------------------*/
5768 /*----------------------------*/
5770 /*----------------------------*/
5771 fprintf(outfile,"SUB (%p) type (",tree);
5772 printTypeChain(tree->ftype,outfile);
5773 fprintf(outfile,")\n");
5774 ast_print(tree->left,outfile,indent+2);
5775 ast_print(tree->right,outfile,indent+2);
5778 /*------------------------------------------------------------------*/
5779 /*----------------------------*/
5781 /*----------------------------*/
5783 fprintf(outfile,"COMPL (%p) type (",tree);
5784 printTypeChain(tree->ftype,outfile);
5785 fprintf(outfile,")\n");
5786 ast_print(tree->left,outfile,indent+2);
5788 /*------------------------------------------------------------------*/
5789 /*----------------------------*/
5791 /*----------------------------*/
5793 fprintf(outfile,"NOT (%p) type (",tree);
5794 printTypeChain(tree->ftype,outfile);
5795 fprintf(outfile,")\n");
5796 ast_print(tree->left,outfile,indent+2);
5798 /*------------------------------------------------------------------*/
5799 /*----------------------------*/
5801 /*----------------------------*/
5803 fprintf(outfile,"RRC (%p) type (",tree);
5804 printTypeChain(tree->ftype,outfile);
5805 fprintf(outfile,")\n");
5806 ast_print(tree->left,outfile,indent+2);
5810 fprintf(outfile,"RLC (%p) type (",tree);
5811 printTypeChain(tree->ftype,outfile);
5812 fprintf(outfile,")\n");
5813 ast_print(tree->left,outfile,indent+2);
5816 fprintf(outfile,"SWAP (%p) type (",tree);
5817 printTypeChain(tree->ftype,outfile);
5818 fprintf(outfile,")\n");
5819 ast_print(tree->left,outfile,indent+2);
5822 fprintf(outfile,"GETHBIT (%p) type (",tree);
5823 printTypeChain(tree->ftype,outfile);
5824 fprintf(outfile,")\n");
5825 ast_print(tree->left,outfile,indent+2);
5828 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5829 printTypeChain(tree->ftype,outfile);
5830 fprintf(outfile,")\n");
5831 ast_print(tree->left,outfile,indent+2);
5832 ast_print(tree->right,outfile,indent+2);
5835 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5836 printTypeChain(tree->ftype,outfile);
5837 fprintf(outfile,")\n");
5838 ast_print(tree->left,outfile,indent+2);
5839 ast_print(tree->right,outfile,indent+2);
5841 /*------------------------------------------------------------------*/
5842 /*----------------------------*/
5844 /*----------------------------*/
5845 case CAST: /* change the type */
5846 fprintf(outfile,"CAST (%p) from type (",tree);
5847 printTypeChain(tree->right->ftype,outfile);
5848 fprintf(outfile,") to type (");
5849 printTypeChain(tree->ftype,outfile);
5850 fprintf(outfile,")\n");
5851 ast_print(tree->right,outfile,indent+2);
5855 fprintf(outfile,"ANDAND (%p) type (",tree);
5856 printTypeChain(tree->ftype,outfile);
5857 fprintf(outfile,")\n");
5858 ast_print(tree->left,outfile,indent+2);
5859 ast_print(tree->right,outfile,indent+2);
5862 fprintf(outfile,"OROR (%p) type (",tree);
5863 printTypeChain(tree->ftype,outfile);
5864 fprintf(outfile,")\n");
5865 ast_print(tree->left,outfile,indent+2);
5866 ast_print(tree->right,outfile,indent+2);
5869 /*------------------------------------------------------------------*/
5870 /*----------------------------*/
5871 /* comparison operators */
5872 /*----------------------------*/
5874 fprintf(outfile,"GT(>) (%p) type (",tree);
5875 printTypeChain(tree->ftype,outfile);
5876 fprintf(outfile,")\n");
5877 ast_print(tree->left,outfile,indent+2);
5878 ast_print(tree->right,outfile,indent+2);
5881 fprintf(outfile,"LT(<) (%p) type (",tree);
5882 printTypeChain(tree->ftype,outfile);
5883 fprintf(outfile,")\n");
5884 ast_print(tree->left,outfile,indent+2);
5885 ast_print(tree->right,outfile,indent+2);
5888 fprintf(outfile,"LE(<=) (%p) type (",tree);
5889 printTypeChain(tree->ftype,outfile);
5890 fprintf(outfile,")\n");
5891 ast_print(tree->left,outfile,indent+2);
5892 ast_print(tree->right,outfile,indent+2);
5895 fprintf(outfile,"GE(>=) (%p) type (",tree);
5896 printTypeChain(tree->ftype,outfile);
5897 fprintf(outfile,")\n");
5898 ast_print(tree->left,outfile,indent+2);
5899 ast_print(tree->right,outfile,indent+2);
5902 fprintf(outfile,"EQ(==) (%p) type (",tree);
5903 printTypeChain(tree->ftype,outfile);
5904 fprintf(outfile,")\n");
5905 ast_print(tree->left,outfile,indent+2);
5906 ast_print(tree->right,outfile,indent+2);
5909 fprintf(outfile,"NE(!=) (%p) type (",tree);
5910 printTypeChain(tree->ftype,outfile);
5911 fprintf(outfile,")\n");
5912 ast_print(tree->left,outfile,indent+2);
5913 ast_print(tree->right,outfile,indent+2);
5914 /*------------------------------------------------------------------*/
5915 /*----------------------------*/
5917 /*----------------------------*/
5918 case SIZEOF: /* evaluate wihout code generation */
5919 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5922 /*------------------------------------------------------------------*/
5923 /*----------------------------*/
5924 /* conditional operator '?' */
5925 /*----------------------------*/
5927 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5928 printTypeChain(tree->ftype,outfile);
5929 fprintf(outfile,")\n");
5930 ast_print(tree->left,outfile,indent+2);
5931 ast_print(tree->right,outfile,indent+2);
5935 fprintf(outfile,"COLON(:) (%p) type (",tree);
5936 printTypeChain(tree->ftype,outfile);
5937 fprintf(outfile,")\n");
5938 ast_print(tree->left,outfile,indent+2);
5939 ast_print(tree->right,outfile,indent+2);
5942 /*------------------------------------------------------------------*/
5943 /*----------------------------*/
5944 /* assignment operators */
5945 /*----------------------------*/
5947 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5948 printTypeChain(tree->ftype,outfile);
5949 fprintf(outfile,")\n");
5950 ast_print(tree->left,outfile,indent+2);
5951 ast_print(tree->right,outfile,indent+2);
5954 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5955 printTypeChain(tree->ftype,outfile);
5956 fprintf(outfile,")\n");
5957 ast_print(tree->left,outfile,indent+2);
5958 ast_print(tree->right,outfile,indent+2);
5961 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5962 printTypeChain(tree->ftype,outfile);
5963 fprintf(outfile,")\n");
5964 ast_print(tree->left,outfile,indent+2);
5965 ast_print(tree->right,outfile,indent+2);
5968 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5969 printTypeChain(tree->ftype,outfile);
5970 fprintf(outfile,")\n");
5971 ast_print(tree->left,outfile,indent+2);
5972 ast_print(tree->right,outfile,indent+2);
5975 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5976 printTypeChain(tree->ftype,outfile);
5977 fprintf(outfile,")\n");
5978 ast_print(tree->left,outfile,indent+2);
5979 ast_print(tree->right,outfile,indent+2);
5982 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5983 printTypeChain(tree->ftype,outfile);
5984 fprintf(outfile,")\n");
5985 ast_print(tree->left,outfile,indent+2);
5986 ast_print(tree->right,outfile,indent+2);
5989 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5990 printTypeChain(tree->ftype,outfile);
5991 fprintf(outfile,")\n");
5992 ast_print(tree->left,outfile,indent+2);
5993 ast_print(tree->right,outfile,indent+2);
5995 /*------------------------------------------------------------------*/
5996 /*----------------------------*/
5998 /*----------------------------*/
6000 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
6001 printTypeChain(tree->ftype,outfile);
6002 fprintf(outfile,")\n");
6003 ast_print(tree->left,outfile,indent+2);
6004 ast_print(tree->right,outfile,indent+2);
6006 /*------------------------------------------------------------------*/
6007 /*----------------------------*/
6009 /*----------------------------*/
6011 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
6012 printTypeChain(tree->ftype,outfile);
6013 fprintf(outfile,")\n");
6014 ast_print(tree->left,outfile,indent+2);
6015 ast_print(tree->right,outfile,indent+2);
6017 /*------------------------------------------------------------------*/
6018 /*----------------------------*/
6019 /* straight assignemnt */
6020 /*----------------------------*/
6022 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
6023 printTypeChain(tree->ftype,outfile);
6024 fprintf(outfile,")\n");
6025 ast_print(tree->left,outfile,indent+2);
6026 ast_print(tree->right,outfile,indent+2);
6028 /*------------------------------------------------------------------*/
6029 /*----------------------------*/
6030 /* comma operator */
6031 /*----------------------------*/
6033 fprintf(outfile,"COMMA(,) (%p) type (",tree);
6034 printTypeChain(tree->ftype,outfile);
6035 fprintf(outfile,")\n");
6036 ast_print(tree->left,outfile,indent+2);
6037 ast_print(tree->right,outfile,indent+2);
6039 /*------------------------------------------------------------------*/
6040 /*----------------------------*/
6042 /*----------------------------*/
6045 fprintf(outfile,"CALL (%p) type (",tree);
6046 printTypeChain(tree->ftype,outfile);
6047 fprintf(outfile,")\n");
6048 ast_print(tree->left,outfile,indent+2);
6049 ast_print(tree->right,outfile,indent+2);
6052 fprintf(outfile,"PARMS\n");
6053 ast_print(tree->left,outfile,indent+2);
6054 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
6055 ast_print(tree->right,outfile,indent+2);
6058 /*------------------------------------------------------------------*/
6059 /*----------------------------*/
6060 /* return statement */
6061 /*----------------------------*/
6063 fprintf(outfile,"RETURN (%p) type (",tree);
6065 printTypeChain(tree->right->ftype,outfile);
6067 fprintf(outfile,")\n");
6068 ast_print(tree->right,outfile,indent+2);
6070 /*------------------------------------------------------------------*/
6071 /*----------------------------*/
6072 /* label statement */
6073 /*----------------------------*/
6075 fprintf(outfile,"LABEL (%p)\n",tree);
6076 ast_print(tree->left,outfile,indent+2);
6077 ast_print(tree->right,outfile,indent);
6079 /*------------------------------------------------------------------*/
6080 /*----------------------------*/
6081 /* switch statement */
6082 /*----------------------------*/
6086 fprintf(outfile,"SWITCH (%p) ",tree);
6087 ast_print(tree->left,outfile,0);
6088 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
6089 INDENT(indent+2,outfile);
6090 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
6091 (int) floatFromVal(val),
6092 tree->values.switchVals.swNum,
6093 (int) floatFromVal(val));
6095 ast_print(tree->right,outfile,indent);
6098 /*------------------------------------------------------------------*/
6099 /*----------------------------*/
6101 /*----------------------------*/
6103 fprintf(outfile,"IF (%p) \n",tree);
6104 ast_print(tree->left,outfile,indent+2);
6105 if (tree->trueLabel) {
6106 INDENT(indent+2,outfile);
6107 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
6109 if (tree->falseLabel) {
6110 INDENT(indent+2,outfile);
6111 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
6113 ast_print(tree->right,outfile,indent+2);
6115 /*----------------------------*/
6116 /* goto Statement */
6117 /*----------------------------*/
6119 fprintf(outfile,"GOTO (%p) \n",tree);
6120 ast_print(tree->left,outfile,indent+2);
6121 fprintf(outfile,"\n");
6123 /*------------------------------------------------------------------*/
6124 /*----------------------------*/
6126 /*----------------------------*/
6128 fprintf(outfile,"FOR (%p) \n",tree);
6129 if (AST_FOR( tree, initExpr)) {
6130 INDENT(indent+2,outfile);
6131 fprintf(outfile,"INIT EXPR ");
6132 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6134 if (AST_FOR( tree, condExpr)) {
6135 INDENT(indent+2,outfile);
6136 fprintf(outfile,"COND EXPR ");
6137 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6139 if (AST_FOR( tree, loopExpr)) {
6140 INDENT(indent+2,outfile);
6141 fprintf(outfile,"LOOP EXPR ");
6142 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6144 fprintf(outfile,"FOR LOOP BODY \n");
6145 ast_print(tree->left,outfile,indent+2);
6148 fprintf(outfile,"CRITICAL (%p) \n",tree);
6149 ast_print(tree->left,outfile,indent+2);
6157 ast_print(t,stdout,0);
6162 /*-----------------------------------------------------------------*/
6163 /* astErrors : returns non-zero if errors present in tree */
6164 /*-----------------------------------------------------------------*/
6165 int astErrors(ast *t)
6174 if (t->type == EX_VALUE
6175 && t->opval.val->sym
6176 && t->opval.val->sym->undefined)
6179 errors += astErrors(t->left);
6180 errors += astErrors(t->right);