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) ||
2102 IS_FIXED(tree->etype))
2104 newLink = newCharLink();
2106 case RESULT_TYPE_INT:
2108 if (getSize (tree->etype) > INTSIZE)
2110 /* warn ("Loosing significant digits"); */
2114 /* char: promote to int */
2116 getSize (tree->etype) >= INTSIZE)
2118 newLink = newIntLink();
2121 case RESULT_TYPE_OTHER:
2124 /* return type is long, float: promote char to int */
2125 if (getSize (tree->etype) >= INTSIZE)
2127 newLink = newIntLink();
2133 tree->decorated = 0;
2134 tree = newNode (CAST, newAst_LINK (newLink), tree);
2135 tree->lineno = tree->right->lineno;
2136 /* keep unsigned type during cast to smaller type,
2137 but not when promoting from char to int */
2139 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2140 return decorateType (tree, resultType);
2143 /*-----------------------------------------------------------------*/
2144 /* resultTypePropagate - decides if resultType can be propagated */
2145 /*-----------------------------------------------------------------*/
2147 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2149 switch (tree->opval.op)
2165 return RESULT_TYPE_NONE;
2169 return RESULT_TYPE_IFX;
2171 return RESULT_TYPE_NONE;
2175 /*-----------------------------------------------------------------*/
2176 /* getLeftResultType - gets type from left branch for propagation */
2177 /*-----------------------------------------------------------------*/
2179 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2181 switch (tree->opval.op)
2185 if (IS_PTR (LTYPE (tree)))
2186 return RESULT_TYPE_NONE;
2188 return getResultTypeFromType (LETYPE (tree));
2190 if (IS_PTR (currFunc->type->next))
2191 return RESULT_TYPE_NONE;
2193 return getResultTypeFromType (currFunc->type->next);
2195 if (!IS_ARRAY (LTYPE (tree)))
2197 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256)
2198 return RESULT_TYPE_CHAR;
2205 /*--------------------------------------------------------------------*/
2206 /* decorateType - compute type for this tree, also does type checking.*/
2207 /* This is done bottom up, since type has to flow upwards. */
2208 /* resultType flows top-down and forces e.g. char-arithmetik, if the */
2209 /* result is a char and the operand(s) are int's. */
2210 /* It also does constant folding, and parameter checking. */
2211 /*--------------------------------------------------------------------*/
2213 decorateType (ast * tree, RESULT_TYPE resultType)
2217 RESULT_TYPE resultTypeProp;
2222 /* if already has type then do nothing */
2223 if (tree->decorated)
2226 tree->decorated = 1;
2229 /* print the line */
2230 /* if not block & function */
2231 if (tree->type == EX_OP &&
2232 (tree->opval.op != FUNCTION &&
2233 tree->opval.op != BLOCK &&
2234 tree->opval.op != NULLOP))
2236 filename = tree->filename;
2237 lineno = tree->lineno;
2241 /* if any child is an error | this one is an error do nothing */
2242 if (tree->isError ||
2243 (tree->left && tree->left->isError) ||
2244 (tree->right && tree->right->isError))
2247 /*------------------------------------------------------------------*/
2248 /*----------------------------*/
2249 /* leaf has been reached */
2250 /*----------------------------*/
2251 lineno=tree->lineno;
2252 /* if this is of type value */
2253 /* just get the type */
2254 if (tree->type == EX_VALUE)
2257 if (IS_LITERAL (tree->opval.val->etype))
2260 /* if this is a character array then declare it */
2261 if (IS_ARRAY (tree->opval.val->type))
2262 tree->opval.val = stringToSymbol (tree->opval.val);
2264 /* otherwise just copy the type information */
2265 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2269 if (tree->opval.val->sym)
2271 /* if the undefined flag is set then give error message */
2272 if (tree->opval.val->sym->undefined)
2274 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2276 TTYPE (tree) = TETYPE (tree) =
2277 tree->opval.val->type = tree->opval.val->sym->type =
2278 tree->opval.val->etype = tree->opval.val->sym->etype =
2279 copyLinkChain (INTTYPE);
2284 /* if impilicit i.e. struct/union member then no type */
2285 if (tree->opval.val->sym->implicit)
2286 TTYPE (tree) = TETYPE (tree) = NULL;
2291 /* else copy the type */
2292 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2294 /* and mark it as referenced */
2295 tree->opval.val->sym->isref = 1;
2303 /* if type link for the case of cast */
2304 if (tree->type == EX_LINK)
2306 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2314 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2316 if (tree->left && tree->left->type == EX_OPERAND
2317 && (tree->left->opval.op == INC_OP
2318 || tree->left->opval.op == DEC_OP)
2319 && tree->left->left)
2321 tree->left->right = tree->left->left;
2322 tree->left->left = NULL;
2324 if (tree->right && tree->right->type == EX_OPERAND
2325 && (tree->right->opval.op == INC_OP
2326 || tree->right->opval.op == DEC_OP)
2327 && tree->right->left)
2329 tree->right->right = tree->right->left;
2330 tree->right->left = NULL;
2335 /* Before decorating the left branch we've to decide in dependence
2336 upon tree->opval.op, if resultType can be propagated */
2337 resultTypeProp = resultTypePropagate (tree, resultType);
2339 if (tree->opval.op == '?')
2340 dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2342 dtl = decorateType (tree->left, resultTypeProp);
2344 /* if an array node, we may need to swap branches */
2345 if (tree->opval.op == '[')
2347 /* determine which is the array & which the index */
2348 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2349 IS_INTEGRAL (LTYPE (tree)))
2351 ast *tempTree = tree->left;
2352 tree->left = tree->right;
2353 tree->right = tempTree;
2357 /* After decorating the left branch there's type information available
2358 in tree->left->?type. If the op is e.g. '=' we extract the type
2359 information from there and propagate it to the right branch. */
2360 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2362 switch (tree->opval.op)
2365 /* delay right side for '?' operator since conditional macro
2366 expansions might rely on this */
2370 /* decorate right side for CALL (parameter list) in processParms();
2371 there is resultType available */
2375 dtr = decorateType (tree->right, resultTypeProp);
2379 /* this is to take care of situations
2380 when the tree gets rewritten */
2381 if (dtl != tree->left)
2383 if (dtr != tree->right)
2385 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2389 /* depending on type of operator do */
2391 switch (tree->opval.op)
2393 /*------------------------------------------------------------------*/
2394 /*----------------------------*/
2396 /*----------------------------*/
2399 /* first check if this is a array or a pointer */
2400 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2402 werror (E_NEED_ARRAY_PTR, "[]");
2403 goto errorTreeReturn;
2406 /* check if the type of the idx */
2407 if (!IS_INTEGRAL (RTYPE (tree)))
2409 werror (E_IDX_NOT_INT);
2410 goto errorTreeReturn;
2413 /* if the left is an rvalue then error */
2416 werror (E_LVALUE_REQUIRED, "array access");
2417 goto errorTreeReturn;
2420 if (IS_LITERAL (RTYPE (tree)))
2422 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2423 int arraySize = DCL_ELEM (LTYPE (tree));
2424 if (arraySize && arrayIndex >= arraySize)
2426 werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2431 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2434 /*------------------------------------------------------------------*/
2435 /*----------------------------*/
2437 /*----------------------------*/
2439 /* if this is not a structure */
2440 if (!IS_STRUCT (LTYPE (tree)))
2442 werror (E_STRUCT_UNION, ".");
2443 goto errorTreeReturn;
2445 TTYPE (tree) = structElemType (LTYPE (tree),
2446 (tree->right->type == EX_VALUE ?
2447 tree->right->opval.val : NULL));
2448 TETYPE (tree) = getSpec (TTYPE (tree));
2451 /*------------------------------------------------------------------*/
2452 /*----------------------------*/
2453 /* struct/union pointer */
2454 /*----------------------------*/
2456 /* if not pointer to a structure */
2457 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2459 werror (E_PTR_REQD);
2460 goto errorTreeReturn;
2463 if (!IS_STRUCT (LTYPE (tree)->next))
2465 werror (E_STRUCT_UNION, "->");
2466 goto errorTreeReturn;
2469 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2470 (tree->right->type == EX_VALUE ?
2471 tree->right->opval.val : NULL));
2472 TETYPE (tree) = getSpec (TTYPE (tree));
2474 /* adjust the storage class */
2475 switch (DCL_TYPE(tree->left->ftype)) {
2477 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2480 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2483 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2486 SPEC_SCLS (TETYPE (tree)) = 0;
2489 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2492 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2495 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2498 SPEC_SCLS (TETYPE (tree)) = 0;
2505 /* This breaks with extern declarations, bitfields, and perhaps other */
2506 /* cases (gcse). Let's leave this optimization disabled for now and */
2507 /* ponder if there's a safe way to do this. -- EEP */
2509 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2510 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2512 /* If defined struct type at addr var
2513 then rewrite (&struct var)->member
2515 and define membertype at (addr+offsetof(struct var,member)) temp
2518 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2519 AST_SYMBOL(tree->right));
2521 sym = newSymbol(genSymName (0), 0);
2522 sym->type = TTYPE (tree);
2523 sym->etype = getSpec(sym->type);
2524 sym->lineDef = tree->lineno;
2527 SPEC_STAT (sym->etype) = 1;
2528 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2530 SPEC_ABSA(sym->etype) = 1;
2531 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2534 AST_VALUE (tree) = symbolVal(sym);
2537 tree->type = EX_VALUE;
2545 /*------------------------------------------------------------------*/
2546 /*----------------------------*/
2547 /* ++/-- operation */
2548 /*----------------------------*/
2552 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2553 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2554 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2555 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2564 /*------------------------------------------------------------------*/
2565 /*----------------------------*/
2567 /*----------------------------*/
2568 case '&': /* can be unary */
2569 /* if right is NULL then unary operation */
2570 if (tree->right) /* not an unary operation */
2573 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2575 werror (E_BITWISE_OP);
2576 werror (W_CONTINUE, "left & right types are ");
2577 printTypeChain (LTYPE (tree), stderr);
2578 fprintf (stderr, ",");
2579 printTypeChain (RTYPE (tree), stderr);
2580 fprintf (stderr, "\n");
2581 goto errorTreeReturn;
2584 /* if they are both literal */
2585 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2587 tree->type = EX_VALUE;
2588 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2589 valFromType (RETYPE (tree)), '&');
2591 tree->right = tree->left = NULL;
2592 TETYPE (tree) = tree->opval.val->etype;
2593 TTYPE (tree) = tree->opval.val->type;
2597 /* see if this is a GETHBIT operation if yes
2600 ast *otree = optimizeGetHbit (tree);
2603 return decorateType (otree, RESULT_TYPE_NONE);
2606 /* if left is a literal exchange left & right */
2607 if (IS_LITERAL (LTYPE (tree)))
2609 ast *tTree = tree->left;
2610 tree->left = tree->right;
2611 tree->right = tTree;
2614 /* if right is a literal and */
2615 /* we can find a 2nd literal in an and-tree then */
2616 /* rearrange the tree */
2617 if (IS_LITERAL (RTYPE (tree)))
2620 ast *litTree = searchLitOp (tree, &parent, "&");
2624 ast *tTree = litTree->left;
2625 litTree->left = tree->right;
2626 tree->right = tTree;
2627 /* both operands in litTree are literal now */
2628 decorateType (parent, resultType);
2632 LRVAL (tree) = RRVAL (tree) = 1;
2634 TTYPE (tree) = computeType (LTYPE (tree),
2638 TETYPE (tree) = getSpec (TTYPE (tree));
2643 /*------------------------------------------------------------------*/
2644 /*----------------------------*/
2646 /*----------------------------*/
2647 p = newLink (DECLARATOR);
2648 /* if bit field then error */
2649 if (IS_BITVAR (tree->left->etype))
2651 werror (E_ILLEGAL_ADDR, "address of bit variable");
2652 goto errorTreeReturn;
2655 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2657 werror (E_ILLEGAL_ADDR, "address of register variable");
2658 goto errorTreeReturn;
2661 if (IS_FUNC (LTYPE (tree)))
2663 // this ought to be ignored
2664 return (tree->left);
2667 if (IS_LITERAL(LTYPE(tree)))
2669 werror (E_ILLEGAL_ADDR, "address of literal");
2670 goto errorTreeReturn;
2675 werror (E_LVALUE_REQUIRED, "address of");
2676 goto errorTreeReturn;
2679 DCL_TYPE (p) = POINTER;
2680 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2681 DCL_TYPE (p) = CPOINTER;
2682 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2683 DCL_TYPE (p) = FPOINTER;
2684 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2685 DCL_TYPE (p) = PPOINTER;
2686 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2687 DCL_TYPE (p) = IPOINTER;
2688 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2689 DCL_TYPE (p) = EEPPOINTER;
2690 else if (SPEC_OCLS(tree->left->etype))
2691 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2693 DCL_TYPE (p) = POINTER;
2695 if (IS_AST_SYM_VALUE (tree->left))
2697 AST_SYMBOL (tree->left)->addrtaken = 1;
2698 AST_SYMBOL (tree->left)->allocreq = 1;
2701 p->next = LTYPE (tree);
2703 TETYPE (tree) = getSpec (TTYPE (tree));
2708 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2709 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2711 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2712 AST_SYMBOL(tree->left->right));
2713 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2714 valueFromLit(element->offset));
2717 tree->type = EX_VALUE;
2718 tree->values.literalFromCast = 1;
2724 /*------------------------------------------------------------------*/
2725 /*----------------------------*/
2727 /*----------------------------*/
2729 /* if the rewrite succeeds then don't go any furthur */
2731 ast *wtree = optimizeRRCRLC (tree);
2733 return decorateType (wtree, RESULT_TYPE_NONE);
2735 wtree = optimizeSWAP (tree);
2737 return decorateType (wtree, RESULT_TYPE_NONE);
2740 /* if left is a literal exchange left & right */
2741 if (IS_LITERAL (LTYPE (tree)))
2743 ast *tTree = tree->left;
2744 tree->left = tree->right;
2745 tree->right = tTree;
2748 /* if right is a literal and */
2749 /* we can find a 2nd literal in an or-tree then */
2750 /* rearrange the tree */
2751 if (IS_LITERAL (RTYPE (tree)))
2754 ast *litTree = searchLitOp (tree, &parent, "|");
2758 ast *tTree = litTree->left;
2759 litTree->left = tree->right;
2760 tree->right = tTree;
2761 /* both operands in tTree are literal now */
2762 decorateType (parent, resultType);
2767 /*------------------------------------------------------------------*/
2768 /*----------------------------*/
2770 /*----------------------------*/
2772 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2774 werror (E_BITWISE_OP);
2775 werror (W_CONTINUE, "left & right types are ");
2776 printTypeChain (LTYPE (tree), stderr);
2777 fprintf (stderr, ",");
2778 printTypeChain (RTYPE (tree), stderr);
2779 fprintf (stderr, "\n");
2780 goto errorTreeReturn;
2783 /* if they are both literal then rewrite the tree */
2784 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2786 tree->type = EX_VALUE;
2787 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2788 valFromType (RETYPE (tree)),
2790 tree->right = tree->left = NULL;
2791 TETYPE (tree) = tree->opval.val->etype;
2792 TTYPE (tree) = tree->opval.val->type;
2796 /* if left is a literal exchange left & right */
2797 if (IS_LITERAL (LTYPE (tree)))
2799 ast *tTree = tree->left;
2800 tree->left = tree->right;
2801 tree->right = tTree;
2804 /* if right is a literal and */
2805 /* we can find a 2nd literal in a xor-tree then */
2806 /* rearrange the tree */
2807 if (IS_LITERAL (RTYPE (tree)) &&
2808 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2811 ast *litTree = searchLitOp (tree, &parent, "^");
2815 ast *tTree = litTree->left;
2816 litTree->left = tree->right;
2817 tree->right = tTree;
2818 /* both operands in litTree are literal now */
2819 decorateType (parent, resultType);
2823 LRVAL (tree) = RRVAL (tree) = 1;
2825 TTYPE (tree) = computeType (LTYPE (tree),
2829 TETYPE (tree) = getSpec (TTYPE (tree));
2833 /*------------------------------------------------------------------*/
2834 /*----------------------------*/
2836 /*----------------------------*/
2838 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2840 werror (E_INVALID_OP, "divide");
2841 goto errorTreeReturn;
2843 /* if they are both literal then */
2844 /* rewrite the tree */
2845 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2847 tree->type = EX_VALUE;
2848 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2849 valFromType (RETYPE (tree)));
2850 tree->right = tree->left = NULL;
2851 TETYPE (tree) = getSpec (TTYPE (tree) =
2852 tree->opval.val->type);
2856 LRVAL (tree) = RRVAL (tree) = 1;
2858 TETYPE (tree) = getSpec (TTYPE (tree) =
2859 computeType (LTYPE (tree),
2864 /* if right is a literal and */
2865 /* left is also a division by a literal then */
2866 /* rearrange the tree */
2867 if (IS_LITERAL (RTYPE (tree))
2868 /* avoid infinite loop */
2869 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2872 ast *litTree = searchLitOp (tree, &parent, "/");
2875 if (IS_LITERAL (RTYPE (litTree)))
2879 litTree->right = newNode ('*',
2881 copyAst (tree->right));
2882 litTree->right->lineno = tree->lineno;
2884 tree->right->opval.val = constVal ("1");
2885 decorateType (parent, resultType);
2889 /* litTree->left is literal: no gcse possible.
2890 We can't call decorateType(parent, RESULT_TYPE_NONE), because
2891 this would cause an infinit loop. */
2892 parent->decorated = 1;
2893 decorateType (litTree, resultType);
2900 /*------------------------------------------------------------------*/
2901 /*----------------------------*/
2903 /*----------------------------*/
2905 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2907 werror (E_BITWISE_OP);
2908 werror (W_CONTINUE, "left & right types are ");
2909 printTypeChain (LTYPE (tree), stderr);
2910 fprintf (stderr, ",");
2911 printTypeChain (RTYPE (tree), stderr);
2912 fprintf (stderr, "\n");
2913 goto errorTreeReturn;
2915 /* if they are both literal then */
2916 /* rewrite the tree */
2917 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2919 tree->type = EX_VALUE;
2920 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2921 valFromType (RETYPE (tree)));
2922 tree->right = tree->left = NULL;
2923 TETYPE (tree) = getSpec (TTYPE (tree) =
2924 tree->opval.val->type);
2927 LRVAL (tree) = RRVAL (tree) = 1;
2928 TETYPE (tree) = getSpec (TTYPE (tree) =
2929 computeType (LTYPE (tree),
2935 /*------------------------------------------------------------------*/
2936 /*----------------------------*/
2937 /* address dereference */
2938 /*----------------------------*/
2939 case '*': /* can be unary : if right is null then unary operation */
2942 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2944 werror (E_PTR_REQD);
2945 goto errorTreeReturn;
2950 werror (E_LVALUE_REQUIRED, "pointer deref");
2951 goto errorTreeReturn;
2953 if (IS_ADDRESS_OF_OP(tree->left))
2955 /* replace *&obj with obj */
2956 return tree->left->left;
2958 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2959 TETYPE (tree) = getSpec (TTYPE (tree));
2960 /* adjust the storage class */
2961 switch (DCL_TYPE(tree->left->ftype)) {
2963 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2966 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2969 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2972 SPEC_SCLS (TETYPE (tree)) = 0;
2975 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2978 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2981 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2984 SPEC_SCLS (TETYPE (tree)) = 0;
2993 /*------------------------------------------------------------------*/
2994 /*----------------------------*/
2995 /* multiplication */
2996 /*----------------------------*/
2997 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2999 werror (E_INVALID_OP, "multiplication");
3000 goto errorTreeReturn;
3003 /* if they are both literal then */
3004 /* rewrite the tree */
3005 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3007 tree->type = EX_VALUE;
3008 tree->opval.val = valMult (valFromType (LETYPE (tree)),
3009 valFromType (RETYPE (tree)));
3010 tree->right = tree->left = NULL;
3011 TETYPE (tree) = getSpec (TTYPE (tree) =
3012 tree->opval.val->type);
3016 /* if left is a literal exchange left & right */
3017 if (IS_LITERAL (LTYPE (tree)))
3019 ast *tTree = tree->left;
3020 tree->left = tree->right;
3021 tree->right = tTree;
3024 /* if right is a literal and */
3025 /* we can find a 2nd literal in a mul-tree then */
3026 /* rearrange the tree */
3027 if (IS_LITERAL (RTYPE (tree)))
3030 ast *litTree = searchLitOp (tree, &parent, "*");
3034 ast *tTree = litTree->left;
3035 litTree->left = tree->right;
3036 tree->right = tTree;
3037 /* both operands in litTree are literal now */
3038 decorateType (parent, resultType);
3042 LRVAL (tree) = RRVAL (tree) = 1;
3043 tree->left = addCast (tree->left, resultType, FALSE);
3044 tree->right = addCast (tree->right, resultType, FALSE);
3045 TETYPE (tree) = getSpec (TTYPE (tree) =
3046 computeType (LTYPE (tree),
3053 /*------------------------------------------------------------------*/
3054 /*----------------------------*/
3055 /* unary '+' operator */
3056 /*----------------------------*/
3061 if (!IS_ARITHMETIC (LTYPE (tree)))
3063 werror (E_UNARY_OP, '+');
3064 goto errorTreeReturn;
3067 /* if left is a literal then do it */
3068 if (IS_LITERAL (LTYPE (tree)))
3070 tree->type = EX_VALUE;
3071 tree->opval.val = valFromType (LETYPE (tree));
3073 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3077 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3081 /*------------------------------------------------------------------*/
3082 /*----------------------------*/
3084 /*----------------------------*/
3086 /* this is not a unary operation */
3087 /* if both pointers then problem */
3088 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3089 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3091 werror (E_PTR_PLUS_PTR);
3092 goto errorTreeReturn;
3095 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3096 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3098 werror (E_PLUS_INVALID, "+");
3099 goto errorTreeReturn;
3102 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3103 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3105 werror (E_PLUS_INVALID, "+");
3106 goto errorTreeReturn;
3108 /* if they are both literal then */
3109 /* rewrite the tree */
3110 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3112 tree->type = EX_VALUE;
3113 tree->left = addCast (tree->left, resultType, TRUE);
3114 tree->right = addCast (tree->right, resultType, TRUE);
3115 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3116 valFromType (RETYPE (tree)));
3117 tree->right = tree->left = NULL;
3118 TETYPE (tree) = getSpec (TTYPE (tree) =
3119 tree->opval.val->type);
3123 /* if the right is a pointer or left is a literal
3124 xchange left & right */
3125 if (IS_ARRAY (RTYPE (tree)) ||
3126 IS_PTR (RTYPE (tree)) ||
3127 IS_LITERAL (LTYPE (tree)))
3129 ast *tTree = tree->left;
3130 tree->left = tree->right;
3131 tree->right = tTree;
3134 /* if right is a literal and */
3135 /* left is also an addition/subtraction with a literal then */
3136 /* rearrange the tree */
3137 if (IS_LITERAL (RTYPE (tree)))
3139 ast *litTree, *parent;
3140 litTree = searchLitOp (tree, &parent, "+-");
3143 if (litTree->opval.op == '+')
3147 ast *tTree = litTree->left;
3148 litTree->left = tree->right;
3149 tree->right = tree->left;
3152 else if (litTree->opval.op == '-')
3154 if (IS_LITERAL (RTYPE (litTree)))
3158 ast *tTree = litTree->left;
3159 litTree->left = tree->right;
3160 tree->right = tTree;
3166 ast *tTree = litTree->right;
3167 litTree->right = tree->right;
3168 tree->right = tTree;
3169 litTree->opval.op = '+';
3170 tree->opval.op = '-';
3173 decorateType (parent, resultType);
3177 LRVAL (tree) = RRVAL (tree) = 1;
3178 /* if the left is a pointer */
3179 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3180 TETYPE (tree) = getSpec (TTYPE (tree) =
3184 tree->left = addCast (tree->left, resultType, TRUE);
3185 tree->right = addCast (tree->right, resultType, TRUE);
3186 TETYPE (tree) = getSpec (TTYPE (tree) =
3187 computeType (LTYPE (tree),
3195 /*------------------------------------------------------------------*/
3196 /*----------------------------*/
3198 /*----------------------------*/
3199 case '-': /* can be unary */
3200 /* if right is null then unary */
3204 if (!IS_ARITHMETIC (LTYPE (tree)))
3206 werror (E_UNARY_OP, tree->opval.op);
3207 goto errorTreeReturn;
3210 /* if left is a literal then do it */
3211 if (IS_LITERAL (LTYPE (tree)))
3213 tree->type = EX_VALUE;
3214 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3216 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3217 SPEC_USIGN(TETYPE(tree)) = 0;
3221 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3225 /*------------------------------------------------------------------*/
3226 /*----------------------------*/
3228 /*----------------------------*/
3230 if (!(IS_PTR (LTYPE (tree)) ||
3231 IS_ARRAY (LTYPE (tree)) ||
3232 IS_ARITHMETIC (LTYPE (tree))))
3234 werror (E_PLUS_INVALID, "-");
3235 goto errorTreeReturn;
3238 if (!(IS_PTR (RTYPE (tree)) ||
3239 IS_ARRAY (RTYPE (tree)) ||
3240 IS_ARITHMETIC (RTYPE (tree))))
3242 werror (E_PLUS_INVALID, "-");
3243 goto errorTreeReturn;
3246 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3247 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3248 IS_INTEGRAL (RTYPE (tree))))
3250 werror (E_PLUS_INVALID, "-");
3251 goto errorTreeReturn;
3254 /* if they are both literal then */
3255 /* rewrite the tree */
3256 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3258 tree->type = EX_VALUE;
3259 tree->left = addCast (tree->left, resultType, TRUE);
3260 tree->right = addCast (tree->right, resultType, TRUE);
3261 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3262 valFromType (RETYPE (tree)));
3263 tree->right = tree->left = NULL;
3264 TETYPE (tree) = getSpec (TTYPE (tree) =
3265 tree->opval.val->type);
3269 /* if the left & right are equal then zero */
3270 if (isAstEqual (tree->left, tree->right))
3272 tree->type = EX_VALUE;
3273 tree->left = tree->right = NULL;
3274 tree->opval.val = constVal ("0");
3275 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3279 /* if both of them are pointers or arrays then */
3280 /* the result is going to be an integer */
3281 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3282 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3283 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3285 /* if only the left is a pointer */
3286 /* then result is a pointer */
3287 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3288 TETYPE (tree) = getSpec (TTYPE (tree) =
3292 tree->left = addCast (tree->left, resultType, TRUE);
3293 tree->right = addCast (tree->right, resultType, TRUE);
3295 TETYPE (tree) = getSpec (TTYPE (tree) =
3296 computeType (LTYPE (tree),
3302 LRVAL (tree) = RRVAL (tree) = 1;
3304 /* if right is a literal and */
3305 /* left is also an addition/subtraction with a literal then */
3306 /* rearrange the tree */
3307 if (IS_LITERAL (RTYPE (tree))
3308 /* avoid infinite loop */
3309 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3311 ast *litTree, *litParent;
3312 litTree = searchLitOp (tree, &litParent, "+-");
3315 if (litTree->opval.op == '+')
3319 ast *tTree = litTree->left;
3320 litTree->left = litTree->right;
3321 litTree->right = tree->right;
3322 tree->right = tTree;
3323 tree->opval.op = '+';
3324 litTree->opval.op = '-';
3326 else if (litTree->opval.op == '-')
3328 if (IS_LITERAL (RTYPE (litTree)))
3332 ast *tTree = litTree->left;
3333 litTree->left = tree->right;
3334 tree->right = litParent->left;
3335 litParent->left = tTree;
3336 litTree->opval.op = '+';
3338 tree->decorated = 0;
3339 decorateType (tree, resultType);
3345 ast *tTree = litTree->right;
3346 litTree->right = tree->right;
3347 tree->right = tTree;
3350 decorateType (litParent, resultType);
3355 /*------------------------------------------------------------------*/
3356 /*----------------------------*/
3358 /*----------------------------*/
3360 /* can be only integral type */
3361 if (!IS_INTEGRAL (LTYPE (tree)))
3363 werror (E_UNARY_OP, tree->opval.op);
3364 goto errorTreeReturn;
3367 /* if left is a literal then do it */
3368 if (IS_LITERAL (LTYPE (tree)))
3370 tree->type = EX_VALUE;
3371 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3373 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3374 return addCast (tree, resultType, TRUE);
3376 tree->left = addCast (tree->left, resultType, TRUE);
3378 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3381 /*------------------------------------------------------------------*/
3382 /*----------------------------*/
3384 /*----------------------------*/
3386 /* can be pointer */
3387 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3388 !IS_PTR (LTYPE (tree)) &&
3389 !IS_ARRAY (LTYPE (tree)))
3391 werror (E_UNARY_OP, tree->opval.op);
3392 goto errorTreeReturn;
3395 /* if left is a literal then do it */
3396 if (IS_LITERAL (LTYPE (tree)))
3398 tree->type = EX_VALUE;
3399 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3401 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3405 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3408 /*------------------------------------------------------------------*/
3409 /*----------------------------*/
3411 /*----------------------------*/
3415 TTYPE (tree) = LTYPE (tree);
3416 TETYPE (tree) = LETYPE (tree);
3420 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3425 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3427 werror (E_SHIFT_OP_INVALID);
3428 werror (W_CONTINUE, "left & right types are ");
3429 printTypeChain (LTYPE (tree), stderr);
3430 fprintf (stderr, ",");
3431 printTypeChain (RTYPE (tree), stderr);
3432 fprintf (stderr, "\n");
3433 goto errorTreeReturn;
3436 /* make smaller type only if it's a LEFT_OP */
3437 if (tree->opval.op == LEFT_OP)
3438 tree->left = addCast (tree->left, resultType, TRUE);
3440 /* if they are both literal then */
3441 /* rewrite the tree */
3442 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3444 tree->type = EX_VALUE;
3445 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3446 valFromType (RETYPE (tree)),
3447 (tree->opval.op == LEFT_OP ? 1 : 0));
3448 tree->right = tree->left = NULL;
3449 TETYPE (tree) = getSpec (TTYPE (tree) =
3450 tree->opval.val->type);
3454 LRVAL (tree) = RRVAL (tree) = 1;
3455 if (tree->opval.op == LEFT_OP)
3457 TETYPE (tree) = getSpec (TTYPE (tree) =
3458 computeType (LTYPE (tree),
3465 /* no promotion necessary */
3466 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3467 if (IS_LITERAL (TTYPE (tree)))
3468 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3471 /* if only the right side is a literal & we are
3472 shifting more than size of the left operand then zero */
3473 if (IS_LITERAL (RTYPE (tree)) &&
3474 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3475 (getSize (TETYPE (tree)) * 8))
3477 if (tree->opval.op==LEFT_OP ||
3478 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3480 lineno=tree->lineno;
3481 werror (W_SHIFT_CHANGED,
3482 (tree->opval.op == LEFT_OP ? "left" : "right"));
3483 tree->type = EX_VALUE;
3484 tree->left = tree->right = NULL;
3485 tree->opval.val = constVal ("0");
3486 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3493 /*------------------------------------------------------------------*/
3494 /*----------------------------*/
3496 /*----------------------------*/
3497 case CAST: /* change the type */
3498 /* cannot cast to an aggregate type */
3499 if (IS_AGGREGATE (LTYPE (tree)))
3501 werror (E_CAST_ILLEGAL);
3502 goto errorTreeReturn;
3505 /* make sure the type is complete and sane */
3506 changePointer(LTYPE(tree));
3507 checkTypeSanity(LETYPE(tree), "(cast)");
3509 /* If code memory is read only, then pointers to code memory */
3510 /* implicitly point to constants -- make this explicit */
3512 sym_link *t = LTYPE(tree);
3513 while (t && t->next)
3515 if (IS_CODEPTR(t) && port->mem.code_ro)
3517 if (IS_SPEC(t->next))
3518 SPEC_CONST (t->next) = 1;
3520 DCL_PTR_CONST (t->next) = 1;
3527 /* if the right is a literal replace the tree */
3528 if (IS_LITERAL (RETYPE (tree))) {
3529 if (!IS_PTR (LTYPE (tree))) {
3530 tree->type = EX_VALUE;
3532 valCastLiteral (LTYPE (tree),
3533 floatFromVal (valFromType (RETYPE (tree))));
3536 TTYPE (tree) = tree->opval.val->type;
3537 tree->values.literalFromCast = 1;
3538 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3539 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3540 sym_link *rest = LTYPE(tree)->next;
3541 werror(W_LITERAL_GENERIC);
3542 TTYPE(tree) = newLink(DECLARATOR);
3543 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3544 TTYPE(tree)->next = rest;
3545 tree->left->opval.lnk = TTYPE(tree);
3548 TTYPE (tree) = LTYPE (tree);
3552 TTYPE (tree) = LTYPE (tree);
3556 #if 0 // this is already checked, now this could be explicit
3557 /* if pointer to struct then check names */
3558 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3559 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3560 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3562 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3563 SPEC_STRUCT(LETYPE(tree))->tag);
3566 if (IS_ADDRESS_OF_OP(tree->right)
3567 && IS_AST_SYM_VALUE (tree->right->left)
3568 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3570 symbol * sym = AST_SYMBOL (tree->right->left);
3571 unsigned int gptype = 0;
3572 unsigned int addr = SPEC_ADDR (sym->etype);
3574 if (IS_GENPTR (LTYPE (tree)) && GPTRSIZE > FPTRSIZE)
3576 switch (SPEC_SCLS (sym->etype))
3579 gptype = GPTYPE_CODE;
3582 gptype = GPTYPE_FAR;
3586 gptype = GPTYPE_NEAR;
3589 gptype = GPTYPE_XSTACK;
3594 addr |= gptype << (8*(GPTRSIZE - 1));
3597 tree->type = EX_VALUE;
3599 valCastLiteral (LTYPE (tree), addr);
3600 TTYPE (tree) = tree->opval.val->type;
3601 TETYPE (tree) = getSpec (TTYPE (tree));
3604 tree->values.literalFromCast = 1;
3608 /* handle offsetof macro: */
3609 /* #define offsetof(TYPE, MEMBER) \ */
3610 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3611 if (IS_ADDRESS_OF_OP(tree->right)
3612 && IS_AST_OP (tree->right->left)
3613 && tree->right->left->opval.op == PTR_OP
3614 && IS_AST_OP (tree->right->left->left)
3615 && tree->right->left->left->opval.op == CAST
3616 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3618 symbol *element = getStructElement (
3619 SPEC_STRUCT (LETYPE(tree->right->left)),
3620 AST_SYMBOL(tree->right->left->right)
3624 tree->type = EX_VALUE;
3625 tree->opval.val = valCastLiteral (
3628 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3631 TTYPE (tree) = tree->opval.val->type;
3632 TETYPE (tree) = getSpec (TTYPE (tree));
3639 /* if the right is a literal replace the tree */
3640 if (IS_LITERAL (RETYPE (tree))) {
3642 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3643 /* rewrite (type *)litaddr
3645 and define type at litaddr temp
3646 (but only if type's storage class is not generic)
3648 ast *newTree = newNode ('&', NULL, NULL);
3651 TTYPE (newTree) = LTYPE (tree);
3652 TETYPE (newTree) = getSpec(LTYPE (tree));
3654 /* define a global symbol at the casted address*/
3655 sym = newSymbol(genSymName (0), 0);
3656 sym->type = LTYPE (tree)->next;
3658 sym->type = newLink (V_VOID);
3659 sym->etype = getSpec(sym->type);
3660 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3661 sym->lineDef = tree->lineno;
3664 SPEC_STAT (sym->etype) = 1;
3665 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3666 SPEC_ABSA(sym->etype) = 1;
3667 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3670 newTree->left = newAst_VALUE(symbolVal(sym));
3671 newTree->left->lineno = tree->lineno;
3672 LTYPE (newTree) = sym->type;
3673 LETYPE (newTree) = sym->etype;
3674 LLVAL (newTree) = 1;
3675 LRVAL (newTree) = 0;
3676 TLVAL (newTree) = 1;
3680 if (!IS_PTR (LTYPE (tree))) {
3681 tree->type = EX_VALUE;
3683 valCastLiteral (LTYPE (tree),
3684 floatFromVal (valFromType (RTYPE (tree))));
3685 TTYPE (tree) = tree->opval.val->type;
3688 tree->values.literalFromCast = 1;
3689 TETYPE (tree) = getSpec (TTYPE (tree));
3693 TTYPE (tree) = LTYPE (tree);
3697 TETYPE (tree) = getSpec (TTYPE (tree));
3701 /*------------------------------------------------------------------*/
3702 /*----------------------------*/
3703 /* logical &&, || */
3704 /*----------------------------*/
3707 /* each must be arithmetic type or be a pointer */
3708 if (!IS_PTR (LTYPE (tree)) &&
3709 !IS_ARRAY (LTYPE (tree)) &&
3710 !IS_INTEGRAL (LTYPE (tree)))
3712 werror (E_COMPARE_OP);
3713 goto errorTreeReturn;
3716 if (!IS_PTR (RTYPE (tree)) &&
3717 !IS_ARRAY (RTYPE (tree)) &&
3718 !IS_INTEGRAL (RTYPE (tree)))
3720 werror (E_COMPARE_OP);
3721 goto errorTreeReturn;
3723 /* if they are both literal then */
3724 /* rewrite the tree */
3725 if (IS_LITERAL (RTYPE (tree)) &&
3726 IS_LITERAL (LTYPE (tree)))
3728 tree->type = EX_VALUE;
3729 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3730 valFromType (RTYPE (tree)),
3732 tree->right = tree->left = NULL;
3733 TETYPE (tree) = getSpec (TTYPE (tree) =
3734 tree->opval.val->type);
3737 LRVAL (tree) = RRVAL (tree) = 1;
3738 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3741 /*------------------------------------------------------------------*/
3742 /*----------------------------*/
3743 /* comparison operators */
3744 /*----------------------------*/
3752 ast *lt = optimizeCompare (tree);
3758 /* if they are pointers they must be castable */
3759 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3761 if (tree->opval.op==EQ_OP &&
3762 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3763 // we cannot cast a gptr to a !gptr: switch the leaves
3764 struct ast *s=tree->left;
3765 tree->left=tree->right;
3768 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3770 werror (E_COMPARE_OP);
3771 fprintf (stderr, "comparing type ");
3772 printTypeChain (LTYPE (tree), stderr);
3773 fprintf (stderr, "to type ");
3774 printTypeChain (RTYPE (tree), stderr);
3775 fprintf (stderr, "\n");
3776 goto errorTreeReturn;
3779 /* else they should be promotable to one another */
3782 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3783 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3785 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3787 werror (E_COMPARE_OP);
3788 fprintf (stderr, "comparing type ");
3789 printTypeChain (LTYPE (tree), stderr);
3790 fprintf (stderr, "to type ");
3791 printTypeChain (RTYPE (tree), stderr);
3792 fprintf (stderr, "\n");
3793 goto errorTreeReturn;
3796 /* if unsigned value < 0 then always false */
3797 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3798 if (SPEC_USIGN(LETYPE(tree)) &&
3799 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3800 IS_LITERAL(RTYPE(tree)) &&
3801 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3803 if (tree->opval.op == '<')
3807 if (tree->opval.op == '>')
3809 if (resultType == RESULT_TYPE_IFX)
3811 /* the parent is an ifx: */
3812 /* if (unsigned value) */
3816 /* (unsigned value) ? 1 : 0 */
3817 tree->opval.op = '?';
3818 tree->right = newNode (':',
3819 newAst_VALUE (constVal ("1")),
3820 tree->right); /* val 0 */
3821 tree->right->lineno = tree->lineno;
3822 tree->right->left->lineno = tree->lineno;
3823 decorateType (tree->right, RESULT_TYPE_NONE);
3826 /* if they are both literal then */
3827 /* rewrite the tree */
3828 if (IS_LITERAL (RTYPE (tree)) &&
3829 IS_LITERAL (LTYPE (tree)))
3831 tree->type = EX_VALUE;
3832 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3833 valFromType (RETYPE (tree)),
3835 tree->right = tree->left = NULL;
3836 TETYPE (tree) = getSpec (TTYPE (tree) =
3837 tree->opval.val->type);
3840 LRVAL (tree) = RRVAL (tree) = 1;
3841 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3844 /*------------------------------------------------------------------*/
3845 /*----------------------------*/
3847 /*----------------------------*/
3848 case SIZEOF: /* evaluate wihout code generation */
3849 /* change the type to a integer */
3851 int size = getSize (tree->right->ftype);
3852 SNPRINTF(buffer, sizeof(buffer), "%d", size);
3853 if (!size && !IS_VOID(tree->right->ftype))
3854 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
3856 tree->type = EX_VALUE;
3857 tree->opval.val = constVal (buffer);
3858 tree->right = tree->left = NULL;
3859 TETYPE (tree) = getSpec (TTYPE (tree) =
3860 tree->opval.val->type);
3863 /*------------------------------------------------------------------*/
3864 /*----------------------------*/
3866 /*----------------------------*/
3868 /* return typeof enum value */
3869 tree->type = EX_VALUE;
3872 if (IS_SPEC(tree->right->ftype)) {
3873 switch (SPEC_NOUN(tree->right->ftype)) {
3875 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3876 else typeofv = TYPEOF_INT;
3879 typeofv = TYPEOF_FLOAT;
3882 typeofv = TYPEOF_FIXED16X16;
3885 typeofv = TYPEOF_CHAR;
3888 typeofv = TYPEOF_VOID;
3891 typeofv = TYPEOF_STRUCT;
3894 typeofv = TYPEOF_BITFIELD;
3897 typeofv = TYPEOF_BIT;
3900 typeofv = TYPEOF_SBIT;
3906 switch (DCL_TYPE(tree->right->ftype)) {
3908 typeofv = TYPEOF_POINTER;
3911 typeofv = TYPEOF_FPOINTER;
3914 typeofv = TYPEOF_CPOINTER;
3917 typeofv = TYPEOF_GPOINTER;
3920 typeofv = TYPEOF_PPOINTER;
3923 typeofv = TYPEOF_IPOINTER;
3926 typeofv = TYPEOF_ARRAY;
3929 typeofv = TYPEOF_FUNCTION;
3935 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3936 tree->opval.val = constVal (buffer);
3937 tree->right = tree->left = NULL;
3938 TETYPE (tree) = getSpec (TTYPE (tree) =
3939 tree->opval.val->type);
3942 /*------------------------------------------------------------------*/
3943 /*----------------------------*/
3944 /* conditional operator '?' */
3945 /*----------------------------*/
3947 /* the type is value of the colon operator (on the right) */
3948 assert (IS_COLON_OP (tree->right));
3949 /* if already known then replace the tree : optimizer will do it
3950 but faster to do it here */
3951 if (IS_LITERAL (LTYPE (tree)))
3953 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
3954 return decorateType (tree->right->left, resultTypeProp);
3956 return decorateType (tree->right->right, resultTypeProp);
3960 tree->right = decorateType (tree->right, resultTypeProp);
3961 TTYPE (tree) = RTYPE (tree);
3962 TETYPE (tree) = getSpec (TTYPE (tree));
3967 /* if they don't match we have a problem */
3968 if ((compareType (LTYPE (tree), RTYPE (tree)) == 0) &&
3969 (compareType (RTYPE (tree), LTYPE (tree)) == 0))
3971 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3972 goto errorTreeReturn;
3975 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
3976 resultType, tree->opval.op);
3977 TETYPE (tree) = getSpec (TTYPE (tree));
3981 #if 0 // assignment operators are converted by the parser
3982 /*------------------------------------------------------------------*/
3983 /*----------------------------*/
3984 /* assignment operators */
3985 /*----------------------------*/
3988 /* for these it must be both must be integral */
3989 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3990 !IS_ARITHMETIC (RTYPE (tree)))
3992 werror (E_OPS_INTEGRAL);
3993 goto errorTreeReturn;
3996 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3998 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3999 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4003 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4004 goto errorTreeReturn;
4015 /* for these it must be both must be integral */
4016 if (!IS_INTEGRAL (LTYPE (tree)) ||
4017 !IS_INTEGRAL (RTYPE (tree)))
4019 werror (E_OPS_INTEGRAL);
4020 goto errorTreeReturn;
4023 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4025 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4026 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
4030 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
4031 goto errorTreeReturn;
4037 /*------------------------------------------------------------------*/
4038 /*----------------------------*/
4040 /*----------------------------*/
4042 if (!(IS_PTR (LTYPE (tree)) ||
4043 IS_ARITHMETIC (LTYPE (tree))))
4045 werror (E_PLUS_INVALID, "-=");
4046 goto errorTreeReturn;
4049 if (!(IS_PTR (RTYPE (tree)) ||
4050 IS_ARITHMETIC (RTYPE (tree))))
4052 werror (E_PLUS_INVALID, "-=");
4053 goto errorTreeReturn;
4056 TETYPE (tree) = getSpec (TTYPE (tree) =
4057 computeType (LTYPE (tree),
4062 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4063 werror (E_CODE_WRITE, "-=");
4067 werror (E_LVALUE_REQUIRED, "-=");
4068 goto errorTreeReturn;
4074 /*------------------------------------------------------------------*/
4075 /*----------------------------*/
4077 /*----------------------------*/
4079 /* this is not a unary operation */
4080 /* if both pointers then problem */
4081 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4083 werror (E_PTR_PLUS_PTR);
4084 goto errorTreeReturn;
4087 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4089 werror (E_PLUS_INVALID, "+=");
4090 goto errorTreeReturn;
4093 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4095 werror (E_PLUS_INVALID, "+=");
4096 goto errorTreeReturn;
4099 TETYPE (tree) = getSpec (TTYPE (tree) =
4100 computeType (LTYPE (tree),
4105 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4106 werror (E_CODE_WRITE, "+=");
4110 werror (E_LVALUE_REQUIRED, "+=");
4111 goto errorTreeReturn;
4114 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE);
4115 tree->opval.op = '=';
4120 /*------------------------------------------------------------------*/
4121 /*----------------------------*/
4122 /* straight assignemnt */
4123 /*----------------------------*/
4125 /* cannot be an aggregate */
4126 if (IS_AGGREGATE (LTYPE (tree)))
4128 werror (E_AGGR_ASSIGN);
4129 goto errorTreeReturn;
4132 /* they should either match or be castable */
4133 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4135 werror (E_TYPE_MISMATCH, "assignment", " ");
4136 printFromToType(RTYPE(tree),LTYPE(tree));
4139 /* if the left side of the tree is of type void
4140 then report error */
4141 if (IS_VOID (LTYPE (tree)))
4143 werror (E_CAST_ZERO);
4144 printFromToType(RTYPE(tree), LTYPE(tree));
4147 TETYPE (tree) = getSpec (TTYPE (tree) =
4151 if (!tree->initMode ) {
4152 if (IS_CONSTANT(LTYPE(tree)))
4153 werror (E_CODE_WRITE, "=");
4157 werror (E_LVALUE_REQUIRED, "=");
4158 goto errorTreeReturn;
4163 /*------------------------------------------------------------------*/
4164 /*----------------------------*/
4165 /* comma operator */
4166 /*----------------------------*/
4168 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4171 /*------------------------------------------------------------------*/
4172 /*----------------------------*/
4174 /*----------------------------*/
4177 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4178 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4180 if (tree->left->opval.op == '*' && !tree->left->right)
4181 tree->left = tree->left->left;
4184 /* require a function or pointer to function */
4185 if (!IS_FUNC (LTYPE (tree)) && !IS_FUNCPTR (LTYPE (tree)))
4187 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4188 goto errorTreeReturn;
4191 /* if there are parms, make sure that
4192 parms are decorate / process / reverse only once */
4194 !tree->right->decorated)
4199 if (IS_FUNCPTR (LTYPE (tree)))
4200 functype = LTYPE (tree)->next;
4202 functype = LTYPE (tree);
4204 if (processParms (tree->left, FUNC_ARGS(functype),
4205 &tree->right, &parmNumber, TRUE))
4207 goto errorTreeReturn;
4210 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4211 !IFFUNC_ISBUILTIN(functype))
4213 reverseParms (tree->right);
4216 TTYPE (tree) = functype->next;
4217 TETYPE (tree) = getSpec (TTYPE (tree));
4221 /*------------------------------------------------------------------*/
4222 /*----------------------------*/
4223 /* return statement */
4224 /*----------------------------*/
4229 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4231 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4232 printFromToType (RTYPE(tree), currFunc->type->next);
4233 goto errorTreeReturn;
4236 if (IS_VOID (currFunc->type->next)
4238 !IS_VOID (RTYPE (tree)))
4240 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4241 goto errorTreeReturn;
4244 /* if there is going to be a casting required then add it */
4245 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4248 decorateType (newNode (CAST,
4249 newAst_LINK (copyLinkChain (currFunc->type->next)),
4259 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4261 werror (W_VOID_FUNC, currFunc->name);
4262 goto errorTreeReturn;
4265 TTYPE (tree) = TETYPE (tree) = NULL;
4268 /*------------------------------------------------------------------*/
4269 /*----------------------------*/
4270 /* switch statement */
4271 /*----------------------------*/
4273 /* the switch value must be an integer */
4274 if (!IS_INTEGRAL (LTYPE (tree)))
4276 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4277 goto errorTreeReturn;
4280 TTYPE (tree) = TETYPE (tree) = NULL;
4283 /*------------------------------------------------------------------*/
4284 /*----------------------------*/
4286 /*----------------------------*/
4288 tree->left = backPatchLabels (tree->left,
4291 TTYPE (tree) = TETYPE (tree) = NULL;
4294 /*------------------------------------------------------------------*/
4295 /*----------------------------*/
4297 /*----------------------------*/
4300 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE);
4301 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE);
4302 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE);
4304 /* if the for loop is reversible then
4305 reverse it otherwise do what we normally
4311 if (isLoopReversible (tree, &sym, &init, &end))
4312 return reverseLoop (tree, sym, init, end);
4314 return decorateType (createFor (AST_FOR (tree, trueLabel),
4315 AST_FOR (tree, continueLabel),
4316 AST_FOR (tree, falseLabel),
4317 AST_FOR (tree, condLabel),
4318 AST_FOR (tree, initExpr),
4319 AST_FOR (tree, condExpr),
4320 AST_FOR (tree, loopExpr),
4321 tree->left), RESULT_TYPE_NONE);
4324 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4325 "node PARAM shouldn't be processed here");
4326 /* but in processParams() */
4329 TTYPE (tree) = TETYPE (tree) = NULL;
4333 /* some error found this tree will be killed */
4335 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4336 tree->opval.op = NULLOP;
4342 /*-----------------------------------------------------------------*/
4343 /* sizeofOp - processes size of operation */
4344 /*-----------------------------------------------------------------*/
4346 sizeofOp (sym_link * type)
4351 /* make sure the type is complete and sane */
4352 checkTypeSanity(type, "(sizeof)");
4354 /* get the size and convert it to character */
4355 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4356 if (!size && !IS_VOID(type))
4357 werror (E_SIZEOF_INCOMPLETE_TYPE);
4359 /* now convert into value */
4360 return constVal (buff);
4364 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4365 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4366 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4367 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4368 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4369 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4370 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4372 /*-----------------------------------------------------------------*/
4373 /* backPatchLabels - change and or not operators to flow control */
4374 /*-----------------------------------------------------------------*/
4376 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4382 if (!(IS_ANDORNOT (tree)))
4385 /* if this an and */
4388 static int localLbl = 0;
4391 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4392 localLabel = newSymbol (buffer, NestLevel);
4394 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4396 /* if left is already a IFX then just change the if true label in that */
4397 if (!IS_IFX (tree->left))
4398 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4400 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4401 /* right is a IFX then just join */
4402 if (IS_IFX (tree->right))
4403 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4405 tree->right = createLabel (localLabel, tree->right);
4406 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4408 return newNode (NULLOP, tree->left, tree->right);
4411 /* if this is an or operation */
4414 static int localLbl = 0;
4417 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4418 localLabel = newSymbol (buffer, NestLevel);
4420 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4422 /* if left is already a IFX then just change the if true label in that */
4423 if (!IS_IFX (tree->left))
4424 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4426 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4427 /* right is a IFX then just join */
4428 if (IS_IFX (tree->right))
4429 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4431 tree->right = createLabel (localLabel, tree->right);
4432 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4434 return newNode (NULLOP, tree->left, tree->right);
4440 int wasnot = IS_NOT (tree->left);
4441 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4443 /* if the left is already a IFX */
4444 if (!IS_IFX (tree->left))
4445 tree->left = newNode (IFX, tree->left, NULL);
4449 tree->left->trueLabel = trueLabel;
4450 tree->left->falseLabel = falseLabel;
4454 tree->left->trueLabel = falseLabel;
4455 tree->left->falseLabel = trueLabel;
4462 tree->trueLabel = trueLabel;
4463 tree->falseLabel = falseLabel;
4470 /*-----------------------------------------------------------------*/
4471 /* createBlock - create expression tree for block */
4472 /*-----------------------------------------------------------------*/
4474 createBlock (symbol * decl, ast * body)
4478 /* if the block has nothing */
4482 ex = newNode (BLOCK, NULL, body);
4483 ex->values.sym = decl;
4490 /*-----------------------------------------------------------------*/
4491 /* createLabel - creates the expression tree for labels */
4492 /*-----------------------------------------------------------------*/
4494 createLabel (symbol * label, ast * stmnt)
4497 char name[SDCC_NAME_MAX + 1];
4500 /* must create fresh symbol if the symbol name */
4501 /* exists in the symbol table, since there can */
4502 /* be a variable with the same name as the labl */
4503 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4504 (csym->level == label->level))
4505 label = newSymbol (label->name, label->level);
4507 /* change the name before putting it in add _ */
4508 SNPRINTF(name, sizeof(name), "%s", label->name);
4510 /* put the label in the LabelSymbol table */
4511 /* but first check if a label of the same */
4513 if ((csym = findSym (LabelTab, NULL, name)))
4514 werror (E_DUPLICATE_LABEL, label->name);
4516 addSym (LabelTab, label, name, label->level, 0, 0);
4520 label->key = labelKey++;
4521 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4527 /*-----------------------------------------------------------------*/
4528 /* createCase - generates the parsetree for a case statement */
4529 /*-----------------------------------------------------------------*/
4531 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4533 char caseLbl[SDCC_NAME_MAX + 1];
4537 /* if the switch statement does not exist */
4538 /* then case is out of context */
4541 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4545 caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE);
4546 /* if not a constant then error */
4547 if (!IS_LITERAL (caseVal->ftype))
4549 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4553 /* if not a integer than error */
4554 if (!IS_INTEGRAL (caseVal->ftype))
4556 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4560 /* find the end of the switch values chain */
4561 if (!(val = swStat->values.switchVals.swVals))
4562 swStat->values.switchVals.swVals = caseVal->opval.val;
4565 /* also order the cases according to value */
4567 int cVal = (int) floatFromVal (caseVal->opval.val);
4568 while (val && (int) floatFromVal (val) < cVal)
4574 /* if we reached the end then */
4577 pval->next = caseVal->opval.val;
4579 else if ((int) floatFromVal (val) == cVal)
4581 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4587 /* we found a value greater than */
4588 /* the current value we must add this */
4589 /* before the value */
4590 caseVal->opval.val->next = val;
4592 /* if this was the first in chain */
4593 if (swStat->values.switchVals.swVals == val)
4594 swStat->values.switchVals.swVals =
4597 pval->next = caseVal->opval.val;
4602 /* create the case label */
4603 SNPRINTF(caseLbl, sizeof(caseLbl),
4605 swStat->values.switchVals.swNum,
4606 (int) floatFromVal (caseVal->opval.val));
4608 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4613 /*-----------------------------------------------------------------*/
4614 /* createDefault - creates the parse tree for the default statement */
4615 /*-----------------------------------------------------------------*/
4617 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4619 char defLbl[SDCC_NAME_MAX + 1];
4621 /* if the switch statement does not exist */
4622 /* then case is out of context */
4625 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4629 if (swStat->values.switchVals.swDefault)
4631 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4636 /* turn on the default flag */
4637 swStat->values.switchVals.swDefault = 1;
4639 /* create the label */
4640 SNPRINTF (defLbl, sizeof(defLbl),
4641 "_default_%d", swStat->values.switchVals.swNum);
4642 return createLabel (newSymbol (defLbl, 0), stmnt);
4645 /*-----------------------------------------------------------------*/
4646 /* createIf - creates the parsetree for the if statement */
4647 /*-----------------------------------------------------------------*/
4649 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4651 static int Lblnum = 0;
4653 symbol *ifTrue, *ifFalse, *ifEnd;
4655 /* if neither exists */
4656 if (!elseBody && !ifBody) {
4657 // if there are no side effects (i++, j() etc)
4658 if (!hasSEFcalls(condAst)) {
4663 /* create the labels */
4664 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4665 ifFalse = newSymbol (buffer, NestLevel);
4666 /* if no else body then end == false */
4671 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4672 ifEnd = newSymbol (buffer, NestLevel);
4675 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4676 ifTrue = newSymbol (buffer, NestLevel);
4680 /* attach the ifTrue label to the top of it body */
4681 ifBody = createLabel (ifTrue, ifBody);
4682 /* attach a goto end to the ifBody if else is present */
4685 ifBody = newNode (NULLOP, ifBody,
4687 newAst_VALUE (symbolVal (ifEnd)),
4689 /* put the elseLabel on the else body */
4690 elseBody = createLabel (ifFalse, elseBody);
4691 /* out the end at the end of the body */
4692 elseBody = newNode (NULLOP,
4694 createLabel (ifEnd, NULL));
4698 ifBody = newNode (NULLOP, ifBody,
4699 createLabel (ifFalse, NULL));
4701 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4702 if (IS_IFX (condAst))
4705 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4707 return newNode (NULLOP, ifTree,
4708 newNode (NULLOP, ifBody, elseBody));
4712 /*-----------------------------------------------------------------*/
4713 /* createDo - creates parse tree for do */
4716 /* _docontinue_n: */
4717 /* condition_expression +-> trueLabel -> _dobody_n */
4719 /* +-> falseLabel-> _dobreak_n */
4721 /*-----------------------------------------------------------------*/
4723 createDo (symbol * trueLabel, symbol * continueLabel,
4724 symbol * falseLabel, ast * condAst, ast * doBody)
4729 /* if the body does not exist then it is simple */
4732 condAst = backPatchLabels (condAst, continueLabel, NULL);
4733 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4734 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4735 doTree->trueLabel = continueLabel;
4736 doTree->falseLabel = NULL;
4740 /* otherwise we have a body */
4741 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4743 /* attach the body label to the top */
4744 doBody = createLabel (trueLabel, doBody);
4745 /* attach the continue label to end of body */
4746 doBody = newNode (NULLOP, doBody,
4747 createLabel (continueLabel, NULL));
4749 /* now put the break label at the end */
4750 if (IS_IFX (condAst))
4753 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4755 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4757 /* putting it together */
4758 return newNode (NULLOP, doBody, doTree);
4761 /*-----------------------------------------------------------------*/
4762 /* createFor - creates parse tree for 'for' statement */
4765 /* condExpr +-> trueLabel -> _forbody_n */
4767 /* +-> falseLabel-> _forbreak_n */
4770 /* _forcontinue_n: */
4772 /* goto _forcond_n ; */
4774 /*-----------------------------------------------------------------*/
4776 createFor (symbol * trueLabel, symbol * continueLabel,
4777 symbol * falseLabel, symbol * condLabel,
4778 ast * initExpr, ast * condExpr, ast * loopExpr,
4783 /* if loopexpression not present then we can generate it */
4784 /* the same way as a while */
4786 return newNode (NULLOP, initExpr,
4787 createWhile (trueLabel, continueLabel,
4788 falseLabel, condExpr, forBody));
4789 /* vanilla for statement */
4790 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4792 if (condExpr && !IS_IFX (condExpr))
4793 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4796 /* attach condition label to condition */
4797 condExpr = createLabel (condLabel, condExpr);
4799 /* attach body label to body */
4800 forBody = createLabel (trueLabel, forBody);
4802 /* attach continue to forLoop expression & attach */
4803 /* goto the forcond @ and of loopExpression */
4804 loopExpr = createLabel (continueLabel,
4808 newAst_VALUE (symbolVal (condLabel)),
4810 /* now start putting them together */
4811 forTree = newNode (NULLOP, initExpr, condExpr);
4812 forTree = newNode (NULLOP, forTree, forBody);
4813 forTree = newNode (NULLOP, forTree, loopExpr);
4814 /* finally add the break label */
4815 forTree = newNode (NULLOP, forTree,
4816 createLabel (falseLabel, NULL));
4820 /*-----------------------------------------------------------------*/
4821 /* createWhile - creates parse tree for while statement */
4822 /* the while statement will be created as follows */
4824 /* _while_continue_n: */
4825 /* condition_expression +-> trueLabel -> _while_boby_n */
4827 /* +-> falseLabel -> _while_break_n */
4828 /* _while_body_n: */
4830 /* goto _while_continue_n */
4831 /* _while_break_n: */
4832 /*-----------------------------------------------------------------*/
4834 createWhile (symbol * trueLabel, symbol * continueLabel,
4835 symbol * falseLabel, ast * condExpr, ast * whileBody)
4839 /* put the continue label */
4840 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4841 condExpr = createLabel (continueLabel, condExpr);
4842 condExpr->lineno = 0;
4844 /* put the body label in front of the body */
4845 whileBody = createLabel (trueLabel, whileBody);
4846 whileBody->lineno = 0;
4847 /* put a jump to continue at the end of the body */
4848 /* and put break label at the end of the body */
4849 whileBody = newNode (NULLOP,
4852 newAst_VALUE (symbolVal (continueLabel)),
4853 createLabel (falseLabel, NULL)));
4855 /* put it all together */
4856 if (IS_IFX (condExpr))
4857 whileTree = condExpr;
4860 whileTree = newNode (IFX, condExpr, NULL);
4861 /* put the true & false labels in place */
4862 whileTree->trueLabel = trueLabel;
4863 whileTree->falseLabel = falseLabel;
4866 return newNode (NULLOP, whileTree, whileBody);
4869 /*-----------------------------------------------------------------*/
4870 /* optimizeGetHbit - get highest order bit of the expression */
4871 /*-----------------------------------------------------------------*/
4873 optimizeGetHbit (ast * tree)
4876 /* if this is not a bit and */
4877 if (!IS_BITAND (tree))
4880 /* will look for tree of the form
4881 ( expr >> ((sizeof expr) -1) ) & 1 */
4882 if (!IS_AST_LIT_VALUE (tree->right))
4885 if (AST_LIT_VALUE (tree->right) != 1)
4888 if (!IS_RIGHT_OP (tree->left))
4891 if (!IS_AST_LIT_VALUE (tree->left->right))
4894 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4895 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4898 /* make sure the port supports GETHBIT */
4899 if (port->hasExtBitOp
4900 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4903 return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_TYPE_NONE);
4907 /*-----------------------------------------------------------------*/
4908 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4909 /*-----------------------------------------------------------------*/
4911 optimizeRRCRLC (ast * root)
4913 /* will look for trees of the form
4914 (?expr << 1) | (?expr >> 7) or
4915 (?expr >> 7) | (?expr << 1) will make that
4916 into a RLC : operation ..
4918 (?expr >> 1) | (?expr << 7) or
4919 (?expr << 7) | (?expr >> 1) will make that
4920 into a RRC operation
4921 note : by 7 I mean (number of bits required to hold the
4923 /* if the root operations is not a | operation the not */
4924 if (!IS_BITOR (root))
4927 /* I have to think of a better way to match patterns this sucks */
4928 /* that aside let start looking for the first case : I use a the
4929 negative check a lot to improve the efficiency */
4930 /* (?expr << 1) | (?expr >> 7) */
4931 if (IS_LEFT_OP (root->left) &&
4932 IS_RIGHT_OP (root->right))
4935 if (!SPEC_USIGN (TETYPE (root->left->left)))
4938 if (!IS_AST_LIT_VALUE (root->left->right) ||
4939 !IS_AST_LIT_VALUE (root->right->right))
4942 /* make sure it is the same expression */
4943 if (!isAstEqual (root->left->left,
4947 if (AST_LIT_VALUE (root->left->right) != 1)
4950 if (AST_LIT_VALUE (root->right->right) !=
4951 (getSize (TTYPE (root->left->left)) * 8 - 1))
4954 /* make sure the port supports RLC */
4955 if (port->hasExtBitOp
4956 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4959 /* whew got the first case : create the AST */
4960 return newNode (RLC, root->left->left, NULL);
4964 /* check for second case */
4965 /* (?expr >> 7) | (?expr << 1) */
4966 if (IS_LEFT_OP (root->right) &&
4967 IS_RIGHT_OP (root->left))
4970 if (!SPEC_USIGN (TETYPE (root->left->left)))
4973 if (!IS_AST_LIT_VALUE (root->left->right) ||
4974 !IS_AST_LIT_VALUE (root->right->right))
4977 /* make sure it is the same symbol */
4978 if (!isAstEqual (root->left->left,
4982 if (AST_LIT_VALUE (root->right->right) != 1)
4985 if (AST_LIT_VALUE (root->left->right) !=
4986 (getSize (TTYPE (root->left->left)) * 8 - 1))
4989 /* make sure the port supports RLC */
4990 if (port->hasExtBitOp
4991 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4994 /* whew got the first case : create the AST */
4995 return newNode (RLC, root->left->left, NULL);
5000 /* third case for RRC */
5001 /* (?symbol >> 1) | (?symbol << 7) */
5002 if (IS_LEFT_OP (root->right) &&
5003 IS_RIGHT_OP (root->left))
5006 if (!SPEC_USIGN (TETYPE (root->left->left)))
5009 if (!IS_AST_LIT_VALUE (root->left->right) ||
5010 !IS_AST_LIT_VALUE (root->right->right))
5013 /* make sure it is the same symbol */
5014 if (!isAstEqual (root->left->left,
5018 if (AST_LIT_VALUE (root->left->right) != 1)
5021 if (AST_LIT_VALUE (root->right->right) !=
5022 (getSize (TTYPE (root->left->left)) * 8 - 1))
5025 /* make sure the port supports RRC */
5026 if (port->hasExtBitOp
5027 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5030 /* whew got the first case : create the AST */
5031 return newNode (RRC, root->left->left, NULL);
5035 /* fourth and last case for now */
5036 /* (?symbol << 7) | (?symbol >> 1) */
5037 if (IS_RIGHT_OP (root->right) &&
5038 IS_LEFT_OP (root->left))
5041 if (!SPEC_USIGN (TETYPE (root->left->left)))
5044 if (!IS_AST_LIT_VALUE (root->left->right) ||
5045 !IS_AST_LIT_VALUE (root->right->right))
5048 /* make sure it is the same symbol */
5049 if (!isAstEqual (root->left->left,
5053 if (AST_LIT_VALUE (root->right->right) != 1)
5056 if (AST_LIT_VALUE (root->left->right) !=
5057 (getSize (TTYPE (root->left->left)) * 8 - 1))
5060 /* make sure the port supports RRC */
5061 if (port->hasExtBitOp
5062 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5065 /* whew got the first case : create the AST */
5066 return newNode (RRC, root->left->left, NULL);
5070 /* not found return root */
5074 /*-----------------------------------------------------------------*/
5075 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
5076 /*-----------------------------------------------------------------*/
5078 optimizeSWAP (ast * root)
5080 /* will look for trees of the form
5081 (?expr << 4) | (?expr >> 4) or
5082 (?expr >> 4) | (?expr << 4) will make that
5083 into a SWAP : operation ..
5084 note : by 4 I mean (number of bits required to hold the
5086 /* if the root operations is not a | operation the not */
5087 if (!IS_BITOR (root))
5090 /* (?expr << 4) | (?expr >> 4) */
5091 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5092 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5095 if (!SPEC_USIGN (TETYPE (root->left->left)))
5098 if (!IS_AST_LIT_VALUE (root->left->right) ||
5099 !IS_AST_LIT_VALUE (root->right->right))
5102 /* make sure it is the same expression */
5103 if (!isAstEqual (root->left->left,
5107 if (AST_LIT_VALUE (root->left->right) !=
5108 (getSize (TTYPE (root->left->left)) * 4))
5111 if (AST_LIT_VALUE (root->right->right) !=
5112 (getSize (TTYPE (root->left->left)) * 4))
5115 /* make sure the port supports SWAP */
5116 if (port->hasExtBitOp
5117 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5120 /* found it : create the AST */
5121 return newNode (SWAP, root->left->left, NULL);
5125 /* not found return root */
5129 /*-----------------------------------------------------------------*/
5130 /* optimizeCompare - otimizes compares for bit variables */
5131 /*-----------------------------------------------------------------*/
5133 optimizeCompare (ast * root)
5135 ast *optExpr = NULL;
5138 unsigned int litValue;
5140 /* if nothing then return nothing */
5144 /* if not a compare op then do leaves */
5145 if (!IS_COMPARE_OP (root))
5147 root->left = optimizeCompare (root->left);
5148 root->right = optimizeCompare (root->right);
5152 /* if left & right are the same then depending
5153 of the operation do */
5154 if (isAstEqual (root->left, root->right))
5156 switch (root->opval.op)
5161 optExpr = newAst_VALUE (constVal ("0"));
5166 optExpr = newAst_VALUE (constVal ("1"));
5170 return decorateType (optExpr, RESULT_TYPE_NONE);
5173 vleft = (root->left->type == EX_VALUE ?
5174 root->left->opval.val : NULL);
5176 vright = (root->right->type == EX_VALUE ?
5177 root->right->opval.val : NULL);
5179 /* if left is a BITVAR in BITSPACE */
5180 /* and right is a LITERAL then opt- */
5181 /* imize else do nothing */
5182 if (vleft && vright &&
5183 IS_BITVAR (vleft->etype) &&
5184 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5185 IS_LITERAL (vright->etype))
5188 /* if right side > 1 then comparison may never succeed */
5189 if ((litValue = (int) floatFromVal (vright)) > 1)
5191 werror (W_BAD_COMPARE);
5197 switch (root->opval.op)
5199 case '>': /* bit value greater than 1 cannot be */
5200 werror (W_BAD_COMPARE);
5204 case '<': /* bit value < 1 means 0 */
5206 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5209 case LE_OP: /* bit value <= 1 means no check */
5210 optExpr = newAst_VALUE (vright);
5213 case GE_OP: /* bit value >= 1 means only check for = */
5215 optExpr = newAst_VALUE (vleft);
5220 { /* literal is zero */
5221 switch (root->opval.op)
5223 case '<': /* bit value < 0 cannot be */
5224 werror (W_BAD_COMPARE);
5228 case '>': /* bit value > 0 means 1 */
5230 optExpr = newAst_VALUE (vleft);
5233 case LE_OP: /* bit value <= 0 means no check */
5234 case GE_OP: /* bit value >= 0 means no check */
5235 werror (W_BAD_COMPARE);
5239 case EQ_OP: /* bit == 0 means ! of bit */
5240 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5244 return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE);
5245 } /* end-of-if of BITVAR */
5250 /*-----------------------------------------------------------------*/
5251 /* addSymToBlock : adds the symbol to the first block we find */
5252 /*-----------------------------------------------------------------*/
5254 addSymToBlock (symbol * sym, ast * tree)
5256 /* reached end of tree or a leaf */
5257 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5261 if (IS_AST_OP (tree) &&
5262 tree->opval.op == BLOCK)
5265 symbol *lsym = copySymbol (sym);
5267 lsym->next = AST_VALUES (tree, sym);
5268 AST_VALUES (tree, sym) = lsym;
5272 addSymToBlock (sym, tree->left);
5273 addSymToBlock (sym, tree->right);
5276 /*-----------------------------------------------------------------*/
5277 /* processRegParms - do processing for register parameters */
5278 /*-----------------------------------------------------------------*/
5280 processRegParms (value * args, ast * body)
5284 if (IS_REGPARM (args->etype))
5285 addSymToBlock (args->sym, body);
5290 /*-----------------------------------------------------------------*/
5291 /* resetParmKey - resets the operandkeys for the symbols */
5292 /*-----------------------------------------------------------------*/
5293 DEFSETFUNC (resetParmKey)
5304 /*-----------------------------------------------------------------*/
5305 /* createFunction - This is the key node that calls the iCode for */
5306 /* generating the code for a function. Note code */
5307 /* is generated function by function, later when */
5308 /* add inter-procedural analysis this will change */
5309 /*-----------------------------------------------------------------*/
5311 createFunction (symbol * name, ast * body)
5317 iCode *piCode = NULL;
5319 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5320 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5322 /* if check function return 0 then some problem */
5323 if (checkFunction (name, NULL) == 0)
5326 /* create a dummy block if none exists */
5328 body = newNode (BLOCK, NULL, NULL);
5332 /* check if the function name already in the symbol table */
5333 if ((csym = findSym (SymbolTab, NULL, name->name)))
5336 /* special case for compiler defined functions
5337 we need to add the name to the publics list : this
5338 actually means we are now compiling the compiler
5342 addSet (&publics, name);
5347 addSymChain (&name);
5348 allocVariables (name);
5350 name->lastLine = mylineno;
5353 /* set the stack pointer */
5354 stackPtr = -port->stack.direction * port->stack.call_overhead;
5357 if (IFFUNC_ISISR (name->type))
5358 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5360 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5362 if (options.useXstack)
5363 xstackPtr -= port->stack.direction * port->stack.reent_overhead;
5365 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5368 fetype = getSpec (name->type); /* get the specifier for the function */
5369 /* if this is a reentrant function then */
5370 if (IFFUNC_ISREENT (name->type))
5373 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5375 /* do processing for parameters that are passed in registers */
5376 processRegParms (FUNC_ARGS(name->type), body);
5378 /* set the stack pointer */
5382 /* allocate & autoinit the block variables */
5383 processBlockVars (body, &stack, ALLOCATE);
5385 /* save the stack information */
5386 if (options.useXstack)
5387 name->xstack = SPEC_STAK (fetype) = stack;
5389 name->stack = SPEC_STAK (fetype) = stack;
5391 /* name needs to be mangled */
5392 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5394 body = resolveSymbols (body); /* resolve the symbols */
5395 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5398 ex = newAst_VALUE (symbolVal (name)); /* create name */
5399 ex = newNode (FUNCTION, ex, body);
5400 ex->values.args = FUNC_ARGS(name->type);
5402 if (options.dump_tree) PA(ex);
5405 werror (E_FUNC_NO_CODE, name->name);
5409 /* create the node & generate intermediate code */
5411 codeOutFile = code->oFile;
5412 piCode = iCodeFromAst (ex);
5416 werror (E_FUNC_NO_CODE, name->name);
5420 eBBlockFromiCode (piCode);
5422 /* if there are any statics then do them */
5425 GcurMemmap = statsg;
5426 codeOutFile = statsg->oFile;
5427 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE)));
5433 /* dealloc the block variables */
5434 processBlockVars (body, &stack, DEALLOCATE);
5435 outputDebugStackSymbols();
5436 /* deallocate paramaters */
5437 deallocParms (FUNC_ARGS(name->type));
5439 if (IFFUNC_ISREENT (name->type))
5442 /* we are done freeup memory & cleanup */
5444 if (port->reset_labelKey) labelKey = 1;
5446 FUNC_HASBODY(name->type) = 1;
5447 addSet (&operKeyReset, name);
5448 applyToSet (operKeyReset, resetParmKey);
5453 cleanUpLevel (LabelTab, 0);
5454 cleanUpBlock (StructTab, 1);
5455 cleanUpBlock (TypedefTab, 1);
5457 xstack->syms = NULL;
5458 istack->syms = NULL;
5463 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5464 /*-----------------------------------------------------------------*/
5465 /* ast_print : prints the ast (for debugging purposes) */
5466 /*-----------------------------------------------------------------*/
5468 void ast_print (ast * tree, FILE *outfile, int indent)
5473 /* can print only decorated trees */
5474 if (!tree->decorated) return;
5476 /* if any child is an error | this one is an error do nothing */
5477 if (tree->isError ||
5478 (tree->left && tree->left->isError) ||
5479 (tree->right && tree->right->isError)) {
5480 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5484 /* print the line */
5485 /* if not block & function */
5486 if (tree->type == EX_OP &&
5487 (tree->opval.op != FUNCTION &&
5488 tree->opval.op != BLOCK &&
5489 tree->opval.op != NULLOP)) {
5492 if (tree->opval.op == FUNCTION) {
5494 value *args=FUNC_ARGS(tree->left->opval.val->type);
5495 fprintf(outfile,"FUNCTION (%s=%p) type (",
5496 tree->left->opval.val->name, tree);
5497 printTypeChain (tree->left->opval.val->type->next,outfile);
5498 fprintf(outfile,") args (");
5501 fprintf (outfile, ", ");
5503 printTypeChain (args ? args->type : NULL, outfile);
5505 args= args ? args->next : NULL;
5507 fprintf(outfile,")\n");
5508 ast_print(tree->left,outfile,indent);
5509 ast_print(tree->right,outfile,indent);
5512 if (tree->opval.op == BLOCK) {
5513 symbol *decls = tree->values.sym;
5514 INDENT(indent,outfile);
5515 fprintf(outfile,"{\n");
5517 INDENT(indent+2,outfile);
5518 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5519 decls->name, decls);
5520 printTypeChain(decls->type,outfile);
5521 fprintf(outfile,")\n");
5523 decls = decls->next;
5525 ast_print(tree->right,outfile,indent+2);
5526 INDENT(indent,outfile);
5527 fprintf(outfile,"}\n");
5530 if (tree->opval.op == NULLOP) {
5531 ast_print(tree->left,outfile,indent);
5532 ast_print(tree->right,outfile,indent);
5535 INDENT(indent,outfile);
5537 /*------------------------------------------------------------------*/
5538 /*----------------------------*/
5539 /* leaf has been reached */
5540 /*----------------------------*/
5541 /* if this is of type value */
5542 /* just get the type */
5543 if (tree->type == EX_VALUE) {
5545 if (IS_LITERAL (tree->opval.val->etype)) {
5546 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5547 if (SPEC_USIGN (tree->opval.val->etype))
5548 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5550 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5551 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5552 floatFromVal(tree->opval.val));
5553 } else if (tree->opval.val->sym) {
5554 /* if the undefined flag is set then give error message */
5555 if (tree->opval.val->sym->undefined) {
5556 fprintf(outfile,"UNDEFINED SYMBOL ");
5558 fprintf(outfile,"SYMBOL ");
5560 fprintf(outfile,"(%s=%p)",
5561 tree->opval.val->sym->name,tree);
5564 fprintf(outfile," type (");
5565 printTypeChain(tree->ftype,outfile);
5566 fprintf(outfile,")\n");
5568 fprintf(outfile,"\n");
5573 /* if type link for the case of cast */
5574 if (tree->type == EX_LINK) {
5575 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5576 printTypeChain(tree->opval.lnk,outfile);
5577 fprintf(outfile,")\n");
5582 /* depending on type of operator do */
5584 switch (tree->opval.op) {
5585 /*------------------------------------------------------------------*/
5586 /*----------------------------*/
5588 /*----------------------------*/
5590 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5591 printTypeChain(tree->ftype,outfile);
5592 fprintf(outfile,")\n");
5593 ast_print(tree->left,outfile,indent+2);
5594 ast_print(tree->right,outfile,indent+2);
5597 /*------------------------------------------------------------------*/
5598 /*----------------------------*/
5600 /*----------------------------*/
5602 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5603 printTypeChain(tree->ftype,outfile);
5604 fprintf(outfile,")\n");
5605 ast_print(tree->left,outfile,indent+2);
5606 ast_print(tree->right,outfile,indent+2);
5609 /*------------------------------------------------------------------*/
5610 /*----------------------------*/
5611 /* struct/union pointer */
5612 /*----------------------------*/
5614 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5615 printTypeChain(tree->ftype,outfile);
5616 fprintf(outfile,")\n");
5617 ast_print(tree->left,outfile,indent+2);
5618 ast_print(tree->right,outfile,indent+2);
5621 /*------------------------------------------------------------------*/
5622 /*----------------------------*/
5623 /* ++/-- operation */
5624 /*----------------------------*/
5627 fprintf(outfile,"post-");
5629 fprintf(outfile,"pre-");
5630 fprintf(outfile,"INC_OP (%p) type (",tree);
5631 printTypeChain(tree->ftype,outfile);
5632 fprintf(outfile,")\n");
5633 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5634 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5639 fprintf(outfile,"post-");
5641 fprintf(outfile,"pre-");
5642 fprintf(outfile,"DEC_OP (%p) type (",tree);
5643 printTypeChain(tree->ftype,outfile);
5644 fprintf(outfile,")\n");
5645 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5646 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5649 /*------------------------------------------------------------------*/
5650 /*----------------------------*/
5652 /*----------------------------*/
5655 fprintf(outfile,"& (%p) type (",tree);
5656 printTypeChain(tree->ftype,outfile);
5657 fprintf(outfile,")\n");
5658 ast_print(tree->left,outfile,indent+2);
5659 ast_print(tree->right,outfile,indent+2);
5661 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5662 printTypeChain(tree->ftype,outfile);
5663 fprintf(outfile,")\n");
5664 ast_print(tree->left,outfile,indent+2);
5665 ast_print(tree->right,outfile,indent+2);
5668 /*----------------------------*/
5670 /*----------------------------*/
5672 fprintf(outfile,"OR (%p) type (",tree);
5673 printTypeChain(tree->ftype,outfile);
5674 fprintf(outfile,")\n");
5675 ast_print(tree->left,outfile,indent+2);
5676 ast_print(tree->right,outfile,indent+2);
5678 /*------------------------------------------------------------------*/
5679 /*----------------------------*/
5681 /*----------------------------*/
5683 fprintf(outfile,"XOR (%p) type (",tree);
5684 printTypeChain(tree->ftype,outfile);
5685 fprintf(outfile,")\n");
5686 ast_print(tree->left,outfile,indent+2);
5687 ast_print(tree->right,outfile,indent+2);
5690 /*------------------------------------------------------------------*/
5691 /*----------------------------*/
5693 /*----------------------------*/
5695 fprintf(outfile,"DIV (%p) type (",tree);
5696 printTypeChain(tree->ftype,outfile);
5697 fprintf(outfile,")\n");
5698 ast_print(tree->left,outfile,indent+2);
5699 ast_print(tree->right,outfile,indent+2);
5701 /*------------------------------------------------------------------*/
5702 /*----------------------------*/
5704 /*----------------------------*/
5706 fprintf(outfile,"MOD (%p) type (",tree);
5707 printTypeChain(tree->ftype,outfile);
5708 fprintf(outfile,")\n");
5709 ast_print(tree->left,outfile,indent+2);
5710 ast_print(tree->right,outfile,indent+2);
5713 /*------------------------------------------------------------------*/
5714 /*----------------------------*/
5715 /* address dereference */
5716 /*----------------------------*/
5717 case '*': /* can be unary : if right is null then unary operation */
5719 fprintf(outfile,"DEREF (%p) type (",tree);
5720 printTypeChain(tree->ftype,outfile);
5721 fprintf(outfile,")\n");
5722 ast_print(tree->left,outfile,indent+2);
5725 /*------------------------------------------------------------------*/
5726 /*----------------------------*/
5727 /* multiplication */
5728 /*----------------------------*/
5729 fprintf(outfile,"MULT (%p) type (",tree);
5730 printTypeChain(tree->ftype,outfile);
5731 fprintf(outfile,")\n");
5732 ast_print(tree->left,outfile,indent+2);
5733 ast_print(tree->right,outfile,indent+2);
5737 /*------------------------------------------------------------------*/
5738 /*----------------------------*/
5739 /* unary '+' operator */
5740 /*----------------------------*/
5744 fprintf(outfile,"UPLUS (%p) type (",tree);
5745 printTypeChain(tree->ftype,outfile);
5746 fprintf(outfile,")\n");
5747 ast_print(tree->left,outfile,indent+2);
5749 /*------------------------------------------------------------------*/
5750 /*----------------------------*/
5752 /*----------------------------*/
5753 fprintf(outfile,"ADD (%p) type (",tree);
5754 printTypeChain(tree->ftype,outfile);
5755 fprintf(outfile,")\n");
5756 ast_print(tree->left,outfile,indent+2);
5757 ast_print(tree->right,outfile,indent+2);
5760 /*------------------------------------------------------------------*/
5761 /*----------------------------*/
5763 /*----------------------------*/
5764 case '-': /* can be unary */
5766 fprintf(outfile,"UMINUS (%p) type (",tree);
5767 printTypeChain(tree->ftype,outfile);
5768 fprintf(outfile,")\n");
5769 ast_print(tree->left,outfile,indent+2);
5771 /*------------------------------------------------------------------*/
5772 /*----------------------------*/
5774 /*----------------------------*/
5775 fprintf(outfile,"SUB (%p) type (",tree);
5776 printTypeChain(tree->ftype,outfile);
5777 fprintf(outfile,")\n");
5778 ast_print(tree->left,outfile,indent+2);
5779 ast_print(tree->right,outfile,indent+2);
5782 /*------------------------------------------------------------------*/
5783 /*----------------------------*/
5785 /*----------------------------*/
5787 fprintf(outfile,"COMPL (%p) type (",tree);
5788 printTypeChain(tree->ftype,outfile);
5789 fprintf(outfile,")\n");
5790 ast_print(tree->left,outfile,indent+2);
5792 /*------------------------------------------------------------------*/
5793 /*----------------------------*/
5795 /*----------------------------*/
5797 fprintf(outfile,"NOT (%p) type (",tree);
5798 printTypeChain(tree->ftype,outfile);
5799 fprintf(outfile,")\n");
5800 ast_print(tree->left,outfile,indent+2);
5802 /*------------------------------------------------------------------*/
5803 /*----------------------------*/
5805 /*----------------------------*/
5807 fprintf(outfile,"RRC (%p) type (",tree);
5808 printTypeChain(tree->ftype,outfile);
5809 fprintf(outfile,")\n");
5810 ast_print(tree->left,outfile,indent+2);
5814 fprintf(outfile,"RLC (%p) type (",tree);
5815 printTypeChain(tree->ftype,outfile);
5816 fprintf(outfile,")\n");
5817 ast_print(tree->left,outfile,indent+2);
5820 fprintf(outfile,"SWAP (%p) type (",tree);
5821 printTypeChain(tree->ftype,outfile);
5822 fprintf(outfile,")\n");
5823 ast_print(tree->left,outfile,indent+2);
5826 fprintf(outfile,"GETHBIT (%p) type (",tree);
5827 printTypeChain(tree->ftype,outfile);
5828 fprintf(outfile,")\n");
5829 ast_print(tree->left,outfile,indent+2);
5832 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5833 printTypeChain(tree->ftype,outfile);
5834 fprintf(outfile,")\n");
5835 ast_print(tree->left,outfile,indent+2);
5836 ast_print(tree->right,outfile,indent+2);
5839 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5840 printTypeChain(tree->ftype,outfile);
5841 fprintf(outfile,")\n");
5842 ast_print(tree->left,outfile,indent+2);
5843 ast_print(tree->right,outfile,indent+2);
5845 /*------------------------------------------------------------------*/
5846 /*----------------------------*/
5848 /*----------------------------*/
5849 case CAST: /* change the type */
5850 fprintf(outfile,"CAST (%p) from type (",tree);
5851 printTypeChain(tree->right->ftype,outfile);
5852 fprintf(outfile,") to type (");
5853 printTypeChain(tree->ftype,outfile);
5854 fprintf(outfile,")\n");
5855 ast_print(tree->right,outfile,indent+2);
5859 fprintf(outfile,"ANDAND (%p) type (",tree);
5860 printTypeChain(tree->ftype,outfile);
5861 fprintf(outfile,")\n");
5862 ast_print(tree->left,outfile,indent+2);
5863 ast_print(tree->right,outfile,indent+2);
5866 fprintf(outfile,"OROR (%p) type (",tree);
5867 printTypeChain(tree->ftype,outfile);
5868 fprintf(outfile,")\n");
5869 ast_print(tree->left,outfile,indent+2);
5870 ast_print(tree->right,outfile,indent+2);
5873 /*------------------------------------------------------------------*/
5874 /*----------------------------*/
5875 /* comparison operators */
5876 /*----------------------------*/
5878 fprintf(outfile,"GT(>) (%p) type (",tree);
5879 printTypeChain(tree->ftype,outfile);
5880 fprintf(outfile,")\n");
5881 ast_print(tree->left,outfile,indent+2);
5882 ast_print(tree->right,outfile,indent+2);
5885 fprintf(outfile,"LT(<) (%p) type (",tree);
5886 printTypeChain(tree->ftype,outfile);
5887 fprintf(outfile,")\n");
5888 ast_print(tree->left,outfile,indent+2);
5889 ast_print(tree->right,outfile,indent+2);
5892 fprintf(outfile,"LE(<=) (%p) type (",tree);
5893 printTypeChain(tree->ftype,outfile);
5894 fprintf(outfile,")\n");
5895 ast_print(tree->left,outfile,indent+2);
5896 ast_print(tree->right,outfile,indent+2);
5899 fprintf(outfile,"GE(>=) (%p) type (",tree);
5900 printTypeChain(tree->ftype,outfile);
5901 fprintf(outfile,")\n");
5902 ast_print(tree->left,outfile,indent+2);
5903 ast_print(tree->right,outfile,indent+2);
5906 fprintf(outfile,"EQ(==) (%p) type (",tree);
5907 printTypeChain(tree->ftype,outfile);
5908 fprintf(outfile,")\n");
5909 ast_print(tree->left,outfile,indent+2);
5910 ast_print(tree->right,outfile,indent+2);
5913 fprintf(outfile,"NE(!=) (%p) type (",tree);
5914 printTypeChain(tree->ftype,outfile);
5915 fprintf(outfile,")\n");
5916 ast_print(tree->left,outfile,indent+2);
5917 ast_print(tree->right,outfile,indent+2);
5918 /*------------------------------------------------------------------*/
5919 /*----------------------------*/
5921 /*----------------------------*/
5922 case SIZEOF: /* evaluate wihout code generation */
5923 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5926 /*------------------------------------------------------------------*/
5927 /*----------------------------*/
5928 /* conditional operator '?' */
5929 /*----------------------------*/
5931 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5932 printTypeChain(tree->ftype,outfile);
5933 fprintf(outfile,")\n");
5934 ast_print(tree->left,outfile,indent+2);
5935 ast_print(tree->right,outfile,indent+2);
5939 fprintf(outfile,"COLON(:) (%p) type (",tree);
5940 printTypeChain(tree->ftype,outfile);
5941 fprintf(outfile,")\n");
5942 ast_print(tree->left,outfile,indent+2);
5943 ast_print(tree->right,outfile,indent+2);
5946 /*------------------------------------------------------------------*/
5947 /*----------------------------*/
5948 /* assignment operators */
5949 /*----------------------------*/
5951 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5952 printTypeChain(tree->ftype,outfile);
5953 fprintf(outfile,")\n");
5954 ast_print(tree->left,outfile,indent+2);
5955 ast_print(tree->right,outfile,indent+2);
5958 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5959 printTypeChain(tree->ftype,outfile);
5960 fprintf(outfile,")\n");
5961 ast_print(tree->left,outfile,indent+2);
5962 ast_print(tree->right,outfile,indent+2);
5965 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5966 printTypeChain(tree->ftype,outfile);
5967 fprintf(outfile,")\n");
5968 ast_print(tree->left,outfile,indent+2);
5969 ast_print(tree->right,outfile,indent+2);
5972 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5973 printTypeChain(tree->ftype,outfile);
5974 fprintf(outfile,")\n");
5975 ast_print(tree->left,outfile,indent+2);
5976 ast_print(tree->right,outfile,indent+2);
5979 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5980 printTypeChain(tree->ftype,outfile);
5981 fprintf(outfile,")\n");
5982 ast_print(tree->left,outfile,indent+2);
5983 ast_print(tree->right,outfile,indent+2);
5986 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5987 printTypeChain(tree->ftype,outfile);
5988 fprintf(outfile,")\n");
5989 ast_print(tree->left,outfile,indent+2);
5990 ast_print(tree->right,outfile,indent+2);
5993 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5994 printTypeChain(tree->ftype,outfile);
5995 fprintf(outfile,")\n");
5996 ast_print(tree->left,outfile,indent+2);
5997 ast_print(tree->right,outfile,indent+2);
5999 /*------------------------------------------------------------------*/
6000 /*----------------------------*/
6002 /*----------------------------*/
6004 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
6005 printTypeChain(tree->ftype,outfile);
6006 fprintf(outfile,")\n");
6007 ast_print(tree->left,outfile,indent+2);
6008 ast_print(tree->right,outfile,indent+2);
6010 /*------------------------------------------------------------------*/
6011 /*----------------------------*/
6013 /*----------------------------*/
6015 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
6016 printTypeChain(tree->ftype,outfile);
6017 fprintf(outfile,")\n");
6018 ast_print(tree->left,outfile,indent+2);
6019 ast_print(tree->right,outfile,indent+2);
6021 /*------------------------------------------------------------------*/
6022 /*----------------------------*/
6023 /* straight assignemnt */
6024 /*----------------------------*/
6026 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
6027 printTypeChain(tree->ftype,outfile);
6028 fprintf(outfile,")\n");
6029 ast_print(tree->left,outfile,indent+2);
6030 ast_print(tree->right,outfile,indent+2);
6032 /*------------------------------------------------------------------*/
6033 /*----------------------------*/
6034 /* comma operator */
6035 /*----------------------------*/
6037 fprintf(outfile,"COMMA(,) (%p) type (",tree);
6038 printTypeChain(tree->ftype,outfile);
6039 fprintf(outfile,")\n");
6040 ast_print(tree->left,outfile,indent+2);
6041 ast_print(tree->right,outfile,indent+2);
6043 /*------------------------------------------------------------------*/
6044 /*----------------------------*/
6046 /*----------------------------*/
6049 fprintf(outfile,"CALL (%p) type (",tree);
6050 printTypeChain(tree->ftype,outfile);
6051 fprintf(outfile,")\n");
6052 ast_print(tree->left,outfile,indent+2);
6053 ast_print(tree->right,outfile,indent+2);
6056 fprintf(outfile,"PARMS\n");
6057 ast_print(tree->left,outfile,indent+2);
6058 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
6059 ast_print(tree->right,outfile,indent+2);
6062 /*------------------------------------------------------------------*/
6063 /*----------------------------*/
6064 /* return statement */
6065 /*----------------------------*/
6067 fprintf(outfile,"RETURN (%p) type (",tree);
6069 printTypeChain(tree->right->ftype,outfile);
6071 fprintf(outfile,")\n");
6072 ast_print(tree->right,outfile,indent+2);
6074 /*------------------------------------------------------------------*/
6075 /*----------------------------*/
6076 /* label statement */
6077 /*----------------------------*/
6079 fprintf(outfile,"LABEL (%p)\n",tree);
6080 ast_print(tree->left,outfile,indent+2);
6081 ast_print(tree->right,outfile,indent);
6083 /*------------------------------------------------------------------*/
6084 /*----------------------------*/
6085 /* switch statement */
6086 /*----------------------------*/
6090 fprintf(outfile,"SWITCH (%p) ",tree);
6091 ast_print(tree->left,outfile,0);
6092 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
6093 INDENT(indent+2,outfile);
6094 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
6095 (int) floatFromVal(val),
6096 tree->values.switchVals.swNum,
6097 (int) floatFromVal(val));
6099 ast_print(tree->right,outfile,indent);
6102 /*------------------------------------------------------------------*/
6103 /*----------------------------*/
6105 /*----------------------------*/
6107 fprintf(outfile,"IF (%p) \n",tree);
6108 ast_print(tree->left,outfile,indent+2);
6109 if (tree->trueLabel) {
6110 INDENT(indent+2,outfile);
6111 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
6113 if (tree->falseLabel) {
6114 INDENT(indent+2,outfile);
6115 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
6117 ast_print(tree->right,outfile,indent+2);
6119 /*----------------------------*/
6120 /* goto Statement */
6121 /*----------------------------*/
6123 fprintf(outfile,"GOTO (%p) \n",tree);
6124 ast_print(tree->left,outfile,indent+2);
6125 fprintf(outfile,"\n");
6127 /*------------------------------------------------------------------*/
6128 /*----------------------------*/
6130 /*----------------------------*/
6132 fprintf(outfile,"FOR (%p) \n",tree);
6133 if (AST_FOR( tree, initExpr)) {
6134 INDENT(indent+2,outfile);
6135 fprintf(outfile,"INIT EXPR ");
6136 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6138 if (AST_FOR( tree, condExpr)) {
6139 INDENT(indent+2,outfile);
6140 fprintf(outfile,"COND EXPR ");
6141 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6143 if (AST_FOR( tree, loopExpr)) {
6144 INDENT(indent+2,outfile);
6145 fprintf(outfile,"LOOP EXPR ");
6146 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6148 fprintf(outfile,"FOR LOOP BODY \n");
6149 ast_print(tree->left,outfile,indent+2);
6152 fprintf(outfile,"CRITICAL (%p) \n",tree);
6153 ast_print(tree->left,outfile,indent+2);
6161 ast_print(t,stdout,0);
6166 /*-----------------------------------------------------------------*/
6167 /* astErrors : returns non-zero if errors present in tree */
6168 /*-----------------------------------------------------------------*/
6169 int astErrors(ast *t)
6178 if (t->type == EX_VALUE
6179 && t->opval.val->sym
6180 && t->opval.val->sym->undefined)
6183 errors += astErrors(t->left);
6184 errors += astErrors(t->right);