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)
2168 return RESULT_TYPE_NONE;
2172 return RESULT_TYPE_IFX;
2174 return RESULT_TYPE_NONE;
2178 /*-----------------------------------------------------------------*/
2179 /* getLeftResultType - gets type from left branch for propagation */
2180 /*-----------------------------------------------------------------*/
2182 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2184 switch (tree->opval.op)
2188 if (IS_PTR (LTYPE (tree)))
2189 return RESULT_TYPE_NONE;
2191 return getResultTypeFromType (LETYPE (tree));
2193 if (IS_PTR (currFunc->type->next))
2194 return RESULT_TYPE_NONE;
2196 return getResultTypeFromType (currFunc->type->next);
2198 if (!IS_ARRAY (LTYPE (tree)))
2200 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256)
2201 return RESULT_TYPE_CHAR;
2208 /*--------------------------------------------------------------------*/
2209 /* decorateType - compute type for this tree, also does type checking.*/
2210 /* This is done bottom up, since type has to flow upwards. */
2211 /* resultType flows top-down and forces e.g. char-arithmetik, if the */
2212 /* result is a char and the operand(s) are int's. */
2213 /* It also does constant folding, and parameter checking. */
2214 /*--------------------------------------------------------------------*/
2216 decorateType (ast * tree, RESULT_TYPE resultType)
2220 RESULT_TYPE resultTypeProp;
2225 /* if already has type then do nothing */
2226 if (tree->decorated)
2229 tree->decorated = 1;
2232 /* print the line */
2233 /* if not block & function */
2234 if (tree->type == EX_OP &&
2235 (tree->opval.op != FUNCTION &&
2236 tree->opval.op != BLOCK &&
2237 tree->opval.op != NULLOP))
2239 filename = tree->filename;
2240 lineno = tree->lineno;
2244 /* if any child is an error | this one is an error do nothing */
2245 if (tree->isError ||
2246 (tree->left && tree->left->isError) ||
2247 (tree->right && tree->right->isError))
2250 /*------------------------------------------------------------------*/
2251 /*----------------------------*/
2252 /* leaf has been reached */
2253 /*----------------------------*/
2254 lineno=tree->lineno;
2255 /* if this is of type value */
2256 /* just get the type */
2257 if (tree->type == EX_VALUE)
2260 if (IS_LITERAL (tree->opval.val->etype))
2263 /* if this is a character array then declare it */
2264 if (IS_ARRAY (tree->opval.val->type))
2265 tree->opval.val = stringToSymbol (tree->opval.val);
2267 /* otherwise just copy the type information */
2268 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2272 if (tree->opval.val->sym)
2274 /* if the undefined flag is set then give error message */
2275 if (tree->opval.val->sym->undefined)
2277 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2279 TTYPE (tree) = TETYPE (tree) =
2280 tree->opval.val->type = tree->opval.val->sym->type =
2281 tree->opval.val->etype = tree->opval.val->sym->etype =
2282 copyLinkChain (INTTYPE);
2287 /* if impilicit i.e. struct/union member then no type */
2288 if (tree->opval.val->sym->implicit)
2289 TTYPE (tree) = TETYPE (tree) = NULL;
2294 /* else copy the type */
2295 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2297 /* and mark it as referenced */
2298 tree->opval.val->sym->isref = 1;
2306 /* if type link for the case of cast */
2307 if (tree->type == EX_LINK)
2309 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2317 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2319 if (tree->left && tree->left->type == EX_OPERAND
2320 && (tree->left->opval.op == INC_OP
2321 || tree->left->opval.op == DEC_OP)
2322 && tree->left->left)
2324 tree->left->right = tree->left->left;
2325 tree->left->left = NULL;
2327 if (tree->right && tree->right->type == EX_OPERAND
2328 && (tree->right->opval.op == INC_OP
2329 || tree->right->opval.op == DEC_OP)
2330 && tree->right->left)
2332 tree->right->right = tree->right->left;
2333 tree->right->left = NULL;
2338 /* Before decorating the left branch we've to decide in dependence
2339 upon tree->opval.op, if resultType can be propagated */
2340 resultTypeProp = resultTypePropagate (tree, resultType);
2342 if (tree->opval.op == '?')
2343 dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2345 dtl = decorateType (tree->left, resultTypeProp);
2347 /* if an array node, we may need to swap branches */
2348 if (tree->opval.op == '[')
2350 /* determine which is the array & which the index */
2351 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2352 IS_INTEGRAL (LTYPE (tree)))
2354 ast *tempTree = tree->left;
2355 tree->left = tree->right;
2356 tree->right = tempTree;
2360 /* After decorating the left branch there's type information available
2361 in tree->left->?type. If the op is e.g. '=' we extract the type
2362 information from there and propagate it to the right branch. */
2363 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2365 switch (tree->opval.op)
2368 /* delay right side for '?' operator since conditional macro
2369 expansions might rely on this */
2373 /* decorate right side for CALL (parameter list) in processParms();
2374 there is resultType available */
2378 dtr = decorateType (tree->right, resultTypeProp);
2382 /* this is to take care of situations
2383 when the tree gets rewritten */
2384 if (dtl != tree->left)
2386 if (dtr != tree->right)
2388 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2392 /* depending on type of operator do */
2394 switch (tree->opval.op)
2396 /*------------------------------------------------------------------*/
2397 /*----------------------------*/
2399 /*----------------------------*/
2402 /* first check if this is a array or a pointer */
2403 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2405 werror (E_NEED_ARRAY_PTR, "[]");
2406 goto errorTreeReturn;
2409 /* check if the type of the idx */
2410 if (!IS_INTEGRAL (RTYPE (tree)))
2412 werror (E_IDX_NOT_INT);
2413 goto errorTreeReturn;
2416 /* if the left is an rvalue then error */
2419 werror (E_LVALUE_REQUIRED, "array access");
2420 goto errorTreeReturn;
2423 if (IS_LITERAL (RTYPE (tree)))
2425 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2426 int arraySize = DCL_ELEM (LTYPE (tree));
2427 if (arraySize && arrayIndex >= arraySize)
2429 werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2434 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2437 /*------------------------------------------------------------------*/
2438 /*----------------------------*/
2440 /*----------------------------*/
2442 /* if this is not a structure */
2443 if (!IS_STRUCT (LTYPE (tree)))
2445 werror (E_STRUCT_UNION, ".");
2446 goto errorTreeReturn;
2448 TTYPE (tree) = structElemType (LTYPE (tree),
2449 (tree->right->type == EX_VALUE ?
2450 tree->right->opval.val : NULL));
2451 TETYPE (tree) = getSpec (TTYPE (tree));
2454 /*------------------------------------------------------------------*/
2455 /*----------------------------*/
2456 /* struct/union pointer */
2457 /*----------------------------*/
2459 /* if not pointer to a structure */
2460 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2462 werror (E_PTR_REQD);
2463 goto errorTreeReturn;
2466 if (!IS_STRUCT (LTYPE (tree)->next))
2468 werror (E_STRUCT_UNION, "->");
2469 goto errorTreeReturn;
2472 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2473 (tree->right->type == EX_VALUE ?
2474 tree->right->opval.val : NULL));
2475 TETYPE (tree) = getSpec (TTYPE (tree));
2477 /* adjust the storage class */
2478 switch (DCL_TYPE(tree->left->ftype)) {
2480 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2483 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2486 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2489 SPEC_SCLS (TETYPE (tree)) = 0;
2492 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2495 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2498 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2501 SPEC_SCLS (TETYPE (tree)) = 0;
2508 /* This breaks with extern declarations, bitfields, and perhaps other */
2509 /* cases (gcse). Let's leave this optimization disabled for now and */
2510 /* ponder if there's a safe way to do this. -- EEP */
2512 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2513 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2515 /* If defined struct type at addr var
2516 then rewrite (&struct var)->member
2518 and define membertype at (addr+offsetof(struct var,member)) temp
2521 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2522 AST_SYMBOL(tree->right));
2524 sym = newSymbol(genSymName (0), 0);
2525 sym->type = TTYPE (tree);
2526 sym->etype = getSpec(sym->type);
2527 sym->lineDef = tree->lineno;
2530 SPEC_STAT (sym->etype) = 1;
2531 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2533 SPEC_ABSA(sym->etype) = 1;
2534 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2537 AST_VALUE (tree) = symbolVal(sym);
2540 tree->type = EX_VALUE;
2548 /*------------------------------------------------------------------*/
2549 /*----------------------------*/
2550 /* ++/-- operation */
2551 /*----------------------------*/
2555 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2556 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2557 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2558 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2567 /*------------------------------------------------------------------*/
2568 /*----------------------------*/
2570 /*----------------------------*/
2571 case '&': /* can be unary */
2572 /* if right is NULL then unary operation */
2573 if (tree->right) /* not an unary operation */
2576 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2578 werror (E_BITWISE_OP);
2579 werror (W_CONTINUE, "left & right types are ");
2580 printTypeChain (LTYPE (tree), stderr);
2581 fprintf (stderr, ",");
2582 printTypeChain (RTYPE (tree), stderr);
2583 fprintf (stderr, "\n");
2584 goto errorTreeReturn;
2587 /* if they are both literal */
2588 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2590 tree->type = EX_VALUE;
2591 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2592 valFromType (RETYPE (tree)), '&');
2594 tree->right = tree->left = NULL;
2595 TETYPE (tree) = tree->opval.val->etype;
2596 TTYPE (tree) = tree->opval.val->type;
2600 /* see if this is a GETHBIT operation if yes
2603 ast *otree = optimizeGetHbit (tree);
2606 return decorateType (otree, RESULT_TYPE_NONE);
2609 /* if left is a literal exchange left & right */
2610 if (IS_LITERAL (LTYPE (tree)))
2612 ast *tTree = tree->left;
2613 tree->left = tree->right;
2614 tree->right = tTree;
2617 /* if right is a literal and */
2618 /* we can find a 2nd literal in an and-tree then */
2619 /* rearrange the tree */
2620 if (IS_LITERAL (RTYPE (tree)))
2623 ast *litTree = searchLitOp (tree, &parent, "&");
2627 ast *tTree = litTree->left;
2628 litTree->left = tree->right;
2629 tree->right = tTree;
2630 /* both operands in litTree are literal now */
2631 decorateType (parent, resultType);
2635 LRVAL (tree) = RRVAL (tree) = 1;
2637 TTYPE (tree) = computeType (LTYPE (tree),
2641 TETYPE (tree) = getSpec (TTYPE (tree));
2646 /*------------------------------------------------------------------*/
2647 /*----------------------------*/
2649 /*----------------------------*/
2650 p = newLink (DECLARATOR);
2651 /* if bit field then error */
2652 if (IS_BITVAR (tree->left->etype))
2654 werror (E_ILLEGAL_ADDR, "address of bit variable");
2655 goto errorTreeReturn;
2658 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2660 werror (E_ILLEGAL_ADDR, "address of register variable");
2661 goto errorTreeReturn;
2664 if (IS_FUNC (LTYPE (tree)))
2666 // this ought to be ignored
2667 return (tree->left);
2670 if (IS_LITERAL(LTYPE(tree)))
2672 werror (E_ILLEGAL_ADDR, "address of literal");
2673 goto errorTreeReturn;
2678 werror (E_LVALUE_REQUIRED, "address of");
2679 goto errorTreeReturn;
2682 DCL_TYPE (p) = POINTER;
2683 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2684 DCL_TYPE (p) = CPOINTER;
2685 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2686 DCL_TYPE (p) = FPOINTER;
2687 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2688 DCL_TYPE (p) = PPOINTER;
2689 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2690 DCL_TYPE (p) = IPOINTER;
2691 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2692 DCL_TYPE (p) = EEPPOINTER;
2693 else if (SPEC_OCLS(tree->left->etype))
2694 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2696 DCL_TYPE (p) = POINTER;
2698 if (IS_AST_SYM_VALUE (tree->left))
2700 AST_SYMBOL (tree->left)->addrtaken = 1;
2701 AST_SYMBOL (tree->left)->allocreq = 1;
2704 p->next = LTYPE (tree);
2706 TETYPE (tree) = getSpec (TTYPE (tree));
2711 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2712 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2714 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2715 AST_SYMBOL(tree->left->right));
2716 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2717 valueFromLit(element->offset));
2720 tree->type = EX_VALUE;
2721 tree->values.literalFromCast = 1;
2727 /*------------------------------------------------------------------*/
2728 /*----------------------------*/
2730 /*----------------------------*/
2732 /* if the rewrite succeeds then don't go any furthur */
2734 ast *wtree = optimizeRRCRLC (tree);
2736 return decorateType (wtree, RESULT_TYPE_NONE);
2738 wtree = optimizeSWAP (tree);
2740 return decorateType (wtree, RESULT_TYPE_NONE);
2743 /* if left is a literal exchange left & right */
2744 if (IS_LITERAL (LTYPE (tree)))
2746 ast *tTree = tree->left;
2747 tree->left = tree->right;
2748 tree->right = tTree;
2751 /* if right is a literal and */
2752 /* we can find a 2nd literal in an or-tree then */
2753 /* rearrange the tree */
2754 if (IS_LITERAL (RTYPE (tree)))
2757 ast *litTree = searchLitOp (tree, &parent, "|");
2761 ast *tTree = litTree->left;
2762 litTree->left = tree->right;
2763 tree->right = tTree;
2764 /* both operands in tTree are literal now */
2765 decorateType (parent, resultType);
2770 /*------------------------------------------------------------------*/
2771 /*----------------------------*/
2773 /*----------------------------*/
2775 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2777 werror (E_BITWISE_OP);
2778 werror (W_CONTINUE, "left & right types are ");
2779 printTypeChain (LTYPE (tree), stderr);
2780 fprintf (stderr, ",");
2781 printTypeChain (RTYPE (tree), stderr);
2782 fprintf (stderr, "\n");
2783 goto errorTreeReturn;
2786 /* if they are both literal then rewrite the tree */
2787 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2789 tree->type = EX_VALUE;
2790 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2791 valFromType (RETYPE (tree)),
2793 tree->right = tree->left = NULL;
2794 TETYPE (tree) = tree->opval.val->etype;
2795 TTYPE (tree) = tree->opval.val->type;
2799 /* if left is a literal exchange left & right */
2800 if (IS_LITERAL (LTYPE (tree)))
2802 ast *tTree = tree->left;
2803 tree->left = tree->right;
2804 tree->right = tTree;
2807 /* if right is a literal and */
2808 /* we can find a 2nd literal in a xor-tree then */
2809 /* rearrange the tree */
2810 if (IS_LITERAL (RTYPE (tree)) &&
2811 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2814 ast *litTree = searchLitOp (tree, &parent, "^");
2818 ast *tTree = litTree->left;
2819 litTree->left = tree->right;
2820 tree->right = tTree;
2821 /* both operands in litTree are literal now */
2822 decorateType (parent, resultType);
2826 LRVAL (tree) = RRVAL (tree) = 1;
2828 TTYPE (tree) = computeType (LTYPE (tree),
2832 TETYPE (tree) = getSpec (TTYPE (tree));
2836 /*------------------------------------------------------------------*/
2837 /*----------------------------*/
2839 /*----------------------------*/
2841 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2843 werror (E_INVALID_OP, "divide");
2844 goto errorTreeReturn;
2846 /* if they are both literal then */
2847 /* rewrite the tree */
2848 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2850 tree->type = EX_VALUE;
2851 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2852 valFromType (RETYPE (tree)));
2853 tree->right = tree->left = NULL;
2854 TETYPE (tree) = getSpec (TTYPE (tree) =
2855 tree->opval.val->type);
2859 LRVAL (tree) = RRVAL (tree) = 1;
2861 TETYPE (tree) = getSpec (TTYPE (tree) =
2862 computeType (LTYPE (tree),
2867 /* if right is a literal and */
2868 /* left is also a division by a literal then */
2869 /* rearrange the tree */
2870 if (IS_LITERAL (RTYPE (tree))
2871 /* avoid infinite loop */
2872 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2875 ast *litTree = searchLitOp (tree, &parent, "/");
2878 if (IS_LITERAL (RTYPE (litTree)))
2882 litTree->right = newNode ('*',
2884 copyAst (tree->right));
2885 litTree->right->lineno = tree->lineno;
2887 tree->right->opval.val = constVal ("1");
2888 decorateType (parent, resultType);
2892 /* litTree->left is literal: no gcse possible.
2893 We can't call decorateType(parent, RESULT_TYPE_NONE), because
2894 this would cause an infinit loop. */
2895 parent->decorated = 1;
2896 decorateType (litTree, resultType);
2903 /*------------------------------------------------------------------*/
2904 /*----------------------------*/
2906 /*----------------------------*/
2908 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2910 werror (E_BITWISE_OP);
2911 werror (W_CONTINUE, "left & right types are ");
2912 printTypeChain (LTYPE (tree), stderr);
2913 fprintf (stderr, ",");
2914 printTypeChain (RTYPE (tree), stderr);
2915 fprintf (stderr, "\n");
2916 goto errorTreeReturn;
2918 /* if they are both literal then */
2919 /* rewrite the tree */
2920 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2922 tree->type = EX_VALUE;
2923 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2924 valFromType (RETYPE (tree)));
2925 tree->right = tree->left = NULL;
2926 TETYPE (tree) = getSpec (TTYPE (tree) =
2927 tree->opval.val->type);
2930 LRVAL (tree) = RRVAL (tree) = 1;
2931 TETYPE (tree) = getSpec (TTYPE (tree) =
2932 computeType (LTYPE (tree),
2938 /*------------------------------------------------------------------*/
2939 /*----------------------------*/
2940 /* address dereference */
2941 /*----------------------------*/
2942 case '*': /* can be unary : if right is null then unary operation */
2945 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2947 werror (E_PTR_REQD);
2948 goto errorTreeReturn;
2953 werror (E_LVALUE_REQUIRED, "pointer deref");
2954 goto errorTreeReturn;
2956 if (IS_ADDRESS_OF_OP(tree->left))
2958 /* replace *&obj with obj */
2959 return tree->left->left;
2961 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2962 TETYPE (tree) = getSpec (TTYPE (tree));
2963 /* adjust the storage class */
2964 switch (DCL_TYPE(tree->left->ftype)) {
2966 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2969 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2972 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2975 SPEC_SCLS (TETYPE (tree)) = 0;
2978 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2981 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2984 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2987 SPEC_SCLS (TETYPE (tree)) = 0;
2996 /*------------------------------------------------------------------*/
2997 /*----------------------------*/
2998 /* multiplication */
2999 /*----------------------------*/
3000 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
3002 werror (E_INVALID_OP, "multiplication");
3003 goto errorTreeReturn;
3006 /* if they are both literal then */
3007 /* rewrite the tree */
3008 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3010 tree->type = EX_VALUE;
3011 tree->opval.val = valMult (valFromType (LETYPE (tree)),
3012 valFromType (RETYPE (tree)));
3013 tree->right = tree->left = NULL;
3014 TETYPE (tree) = getSpec (TTYPE (tree) =
3015 tree->opval.val->type);
3019 /* if left is a literal exchange left & right */
3020 if (IS_LITERAL (LTYPE (tree)))
3022 ast *tTree = tree->left;
3023 tree->left = tree->right;
3024 tree->right = tTree;
3027 /* if right is a literal and */
3028 /* we can find a 2nd literal in a mul-tree then */
3029 /* rearrange the tree */
3030 if (IS_LITERAL (RTYPE (tree)))
3033 ast *litTree = searchLitOp (tree, &parent, "*");
3037 ast *tTree = litTree->left;
3038 litTree->left = tree->right;
3039 tree->right = tTree;
3040 /* both operands in litTree are literal now */
3041 decorateType (parent, resultType);
3045 LRVAL (tree) = RRVAL (tree) = 1;
3046 tree->left = addCast (tree->left, resultType, FALSE);
3047 tree->right = addCast (tree->right, resultType, FALSE);
3048 TETYPE (tree) = getSpec (TTYPE (tree) =
3049 computeType (LTYPE (tree),
3056 /*------------------------------------------------------------------*/
3057 /*----------------------------*/
3058 /* unary '+' operator */
3059 /*----------------------------*/
3064 if (!IS_ARITHMETIC (LTYPE (tree)))
3066 werror (E_UNARY_OP, '+');
3067 goto errorTreeReturn;
3070 /* if left is a literal then do it */
3071 if (IS_LITERAL (LTYPE (tree)))
3073 tree->type = EX_VALUE;
3074 tree->opval.val = valFromType (LETYPE (tree));
3076 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3080 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3084 /*------------------------------------------------------------------*/
3085 /*----------------------------*/
3087 /*----------------------------*/
3089 /* this is not a unary operation */
3090 /* if both pointers then problem */
3091 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3092 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3094 werror (E_PTR_PLUS_PTR);
3095 goto errorTreeReturn;
3098 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3099 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3101 werror (E_PLUS_INVALID, "+");
3102 goto errorTreeReturn;
3105 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3106 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3108 werror (E_PLUS_INVALID, "+");
3109 goto errorTreeReturn;
3111 /* if they are both literal then */
3112 /* rewrite the tree */
3113 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3115 tree->type = EX_VALUE;
3116 tree->left = addCast (tree->left, resultType, TRUE);
3117 tree->right = addCast (tree->right, resultType, TRUE);
3118 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3119 valFromType (RETYPE (tree)));
3120 tree->right = tree->left = NULL;
3121 TETYPE (tree) = getSpec (TTYPE (tree) =
3122 tree->opval.val->type);
3126 /* if the right is a pointer or left is a literal
3127 xchange left & right */
3128 if (IS_ARRAY (RTYPE (tree)) ||
3129 IS_PTR (RTYPE (tree)) ||
3130 IS_LITERAL (LTYPE (tree)))
3132 ast *tTree = tree->left;
3133 tree->left = tree->right;
3134 tree->right = tTree;
3137 /* if right is a literal and */
3138 /* left is also an addition/subtraction with a literal then */
3139 /* rearrange the tree */
3140 if (IS_LITERAL (RTYPE (tree)))
3142 ast *litTree, *parent;
3143 litTree = searchLitOp (tree, &parent, "+-");
3146 if (litTree->opval.op == '+')
3150 ast *tTree = litTree->left;
3151 litTree->left = tree->right;
3152 tree->right = tree->left;
3155 else if (litTree->opval.op == '-')
3157 if (IS_LITERAL (RTYPE (litTree)))
3161 ast *tTree = litTree->left;
3162 litTree->left = tree->right;
3163 tree->right = tTree;
3169 ast *tTree = litTree->right;
3170 litTree->right = tree->right;
3171 tree->right = tTree;
3172 litTree->opval.op = '+';
3173 tree->opval.op = '-';
3176 decorateType (parent, resultType);
3180 LRVAL (tree) = RRVAL (tree) = 1;
3181 /* if the left is a pointer */
3182 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3183 TETYPE (tree) = getSpec (TTYPE (tree) =
3187 tree->left = addCast (tree->left, resultType, TRUE);
3188 tree->right = addCast (tree->right, resultType, TRUE);
3189 TETYPE (tree) = getSpec (TTYPE (tree) =
3190 computeType (LTYPE (tree),
3198 /*------------------------------------------------------------------*/
3199 /*----------------------------*/
3201 /*----------------------------*/
3202 case '-': /* can be unary */
3203 /* if right is null then unary */
3207 if (!IS_ARITHMETIC (LTYPE (tree)))
3209 werror (E_UNARY_OP, tree->opval.op);
3210 goto errorTreeReturn;
3213 /* if left is a literal then do it */
3214 if (IS_LITERAL (LTYPE (tree)))
3216 tree->type = EX_VALUE;
3217 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3219 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3220 SPEC_USIGN(TETYPE(tree)) = 0;
3224 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3228 /*------------------------------------------------------------------*/
3229 /*----------------------------*/
3231 /*----------------------------*/
3233 if (!(IS_PTR (LTYPE (tree)) ||
3234 IS_ARRAY (LTYPE (tree)) ||
3235 IS_ARITHMETIC (LTYPE (tree))))
3237 werror (E_PLUS_INVALID, "-");
3238 goto errorTreeReturn;
3241 if (!(IS_PTR (RTYPE (tree)) ||
3242 IS_ARRAY (RTYPE (tree)) ||
3243 IS_ARITHMETIC (RTYPE (tree))))
3245 werror (E_PLUS_INVALID, "-");
3246 goto errorTreeReturn;
3249 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3250 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3251 IS_INTEGRAL (RTYPE (tree))))
3253 werror (E_PLUS_INVALID, "-");
3254 goto errorTreeReturn;
3257 /* if they are both literal then */
3258 /* rewrite the tree */
3259 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3261 tree->type = EX_VALUE;
3262 tree->left = addCast (tree->left, resultType, TRUE);
3263 tree->right = addCast (tree->right, resultType, TRUE);
3264 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3265 valFromType (RETYPE (tree)));
3266 tree->right = tree->left = NULL;
3267 TETYPE (tree) = getSpec (TTYPE (tree) =
3268 tree->opval.val->type);
3272 /* if the left & right are equal then zero */
3273 if (isAstEqual (tree->left, tree->right))
3275 tree->type = EX_VALUE;
3276 tree->left = tree->right = NULL;
3277 tree->opval.val = constVal ("0");
3278 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3282 /* if both of them are pointers or arrays then */
3283 /* the result is going to be an integer */
3284 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3285 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3286 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3288 /* if only the left is a pointer */
3289 /* then result is a pointer */
3290 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3291 TETYPE (tree) = getSpec (TTYPE (tree) =
3295 tree->left = addCast (tree->left, resultType, TRUE);
3296 tree->right = addCast (tree->right, resultType, TRUE);
3298 TETYPE (tree) = getSpec (TTYPE (tree) =
3299 computeType (LTYPE (tree),
3305 LRVAL (tree) = RRVAL (tree) = 1;
3307 /* if right is a literal and */
3308 /* left is also an addition/subtraction with a literal then */
3309 /* rearrange the tree */
3310 if (IS_LITERAL (RTYPE (tree))
3311 /* avoid infinite loop */
3312 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3314 ast *litTree, *litParent;
3315 litTree = searchLitOp (tree, &litParent, "+-");
3318 if (litTree->opval.op == '+')
3322 ast *tTree = litTree->left;
3323 litTree->left = litTree->right;
3324 litTree->right = tree->right;
3325 tree->right = tTree;
3326 tree->opval.op = '+';
3327 litTree->opval.op = '-';
3329 else if (litTree->opval.op == '-')
3331 if (IS_LITERAL (RTYPE (litTree)))
3335 ast *tTree = litTree->left;
3336 litTree->left = tree->right;
3337 tree->right = litParent->left;
3338 litParent->left = tTree;
3339 litTree->opval.op = '+';
3341 tree->decorated = 0;
3342 decorateType (tree, resultType);
3348 ast *tTree = litTree->right;
3349 litTree->right = tree->right;
3350 tree->right = tTree;
3353 decorateType (litParent, resultType);
3358 /*------------------------------------------------------------------*/
3359 /*----------------------------*/
3361 /*----------------------------*/
3363 /* can be only integral type */
3364 if (!IS_INTEGRAL (LTYPE (tree)))
3366 werror (E_UNARY_OP, tree->opval.op);
3367 goto errorTreeReturn;
3370 /* if left is a literal then do it */
3371 if (IS_LITERAL (LTYPE (tree)))
3373 tree->type = EX_VALUE;
3374 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3376 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3377 return addCast (tree, resultType, TRUE);
3379 tree->left = addCast (tree->left, resultType, TRUE);
3381 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3384 /*------------------------------------------------------------------*/
3385 /*----------------------------*/
3387 /*----------------------------*/
3389 /* can be pointer */
3390 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3391 !IS_PTR (LTYPE (tree)) &&
3392 !IS_ARRAY (LTYPE (tree)))
3394 werror (E_UNARY_OP, tree->opval.op);
3395 goto errorTreeReturn;
3398 /* if left is a literal then do it */
3399 if (IS_LITERAL (LTYPE (tree)))
3401 tree->type = EX_VALUE;
3402 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3404 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3408 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3411 /*------------------------------------------------------------------*/
3412 /*----------------------------*/
3414 /*----------------------------*/
3418 TTYPE (tree) = LTYPE (tree);
3419 TETYPE (tree) = LETYPE (tree);
3423 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3428 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3430 werror (E_SHIFT_OP_INVALID);
3431 werror (W_CONTINUE, "left & right types are ");
3432 printTypeChain (LTYPE (tree), stderr);
3433 fprintf (stderr, ",");
3434 printTypeChain (RTYPE (tree), stderr);
3435 fprintf (stderr, "\n");
3436 goto errorTreeReturn;
3439 /* make smaller type only if it's a LEFT_OP */
3440 if (tree->opval.op == LEFT_OP)
3441 tree->left = addCast (tree->left, resultType, TRUE);
3443 /* if they are both literal then */
3444 /* rewrite the tree */
3445 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3447 tree->type = EX_VALUE;
3448 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3449 valFromType (RETYPE (tree)),
3450 (tree->opval.op == LEFT_OP ? 1 : 0));
3451 tree->right = tree->left = NULL;
3452 TETYPE (tree) = getSpec (TTYPE (tree) =
3453 tree->opval.val->type);
3457 LRVAL (tree) = RRVAL (tree) = 1;
3458 if (tree->opval.op == LEFT_OP)
3460 TETYPE (tree) = getSpec (TTYPE (tree) =
3461 computeType (LTYPE (tree),
3468 /* no promotion necessary */
3469 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3470 if (IS_LITERAL (TTYPE (tree)))
3471 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3474 /* if only the right side is a literal & we are
3475 shifting more than size of the left operand then zero */
3476 if (IS_LITERAL (RTYPE (tree)) &&
3477 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3478 (getSize (TETYPE (tree)) * 8))
3480 if (tree->opval.op==LEFT_OP ||
3481 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3483 lineno=tree->lineno;
3484 werror (W_SHIFT_CHANGED,
3485 (tree->opval.op == LEFT_OP ? "left" : "right"));
3486 tree->type = EX_VALUE;
3487 tree->left = tree->right = NULL;
3488 tree->opval.val = constVal ("0");
3489 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3496 /*------------------------------------------------------------------*/
3497 /*----------------------------*/
3499 /*----------------------------*/
3500 case CAST: /* change the type */
3501 /* cannot cast to an aggregate type */
3502 if (IS_AGGREGATE (LTYPE (tree)))
3504 werror (E_CAST_ILLEGAL);
3505 goto errorTreeReturn;
3508 /* make sure the type is complete and sane */
3509 changePointer(LTYPE(tree));
3510 checkTypeSanity(LETYPE(tree), "(cast)");
3512 /* If code memory is read only, then pointers to code memory */
3513 /* implicitly point to constants -- make this explicit */
3515 sym_link *t = LTYPE(tree);
3516 while (t && t->next)
3518 if (IS_CODEPTR(t) && port->mem.code_ro)
3520 if (IS_SPEC(t->next))
3521 SPEC_CONST (t->next) = 1;
3523 DCL_PTR_CONST (t->next) = 1;
3530 /* if the right is a literal replace the tree */
3531 if (IS_LITERAL (RETYPE (tree))) {
3532 if (!IS_PTR (LTYPE (tree))) {
3533 tree->type = EX_VALUE;
3535 valCastLiteral (LTYPE (tree),
3536 floatFromVal (valFromType (RETYPE (tree))));
3539 TTYPE (tree) = tree->opval.val->type;
3540 tree->values.literalFromCast = 1;
3541 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3542 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3543 sym_link *rest = LTYPE(tree)->next;
3544 werror(W_LITERAL_GENERIC);
3545 TTYPE(tree) = newLink(DECLARATOR);
3546 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3547 TTYPE(tree)->next = rest;
3548 tree->left->opval.lnk = TTYPE(tree);
3551 TTYPE (tree) = LTYPE (tree);
3555 TTYPE (tree) = LTYPE (tree);
3559 #if 0 // this is already checked, now this could be explicit
3560 /* if pointer to struct then check names */
3561 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3562 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3563 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3565 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3566 SPEC_STRUCT(LETYPE(tree))->tag);
3569 if (IS_ADDRESS_OF_OP(tree->right)
3570 && IS_AST_SYM_VALUE (tree->right->left)
3571 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3573 symbol * sym = AST_SYMBOL (tree->right->left);
3574 unsigned int gptype = 0;
3575 unsigned int addr = SPEC_ADDR (sym->etype);
3577 if (IS_GENPTR (LTYPE (tree)) && GPTRSIZE > FPTRSIZE)
3579 switch (SPEC_SCLS (sym->etype))
3582 gptype = GPTYPE_CODE;
3585 gptype = GPTYPE_FAR;
3589 gptype = GPTYPE_NEAR;
3592 gptype = GPTYPE_XSTACK;
3597 addr |= gptype << (8*(GPTRSIZE - 1));
3600 tree->type = EX_VALUE;
3602 valCastLiteral (LTYPE (tree), addr);
3603 TTYPE (tree) = tree->opval.val->type;
3604 TETYPE (tree) = getSpec (TTYPE (tree));
3607 tree->values.literalFromCast = 1;
3611 /* handle offsetof macro: */
3612 /* #define offsetof(TYPE, MEMBER) \ */
3613 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3614 if (IS_ADDRESS_OF_OP(tree->right)
3615 && IS_AST_OP (tree->right->left)
3616 && tree->right->left->opval.op == PTR_OP
3617 && IS_AST_OP (tree->right->left->left)
3618 && tree->right->left->left->opval.op == CAST
3619 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3621 symbol *element = getStructElement (
3622 SPEC_STRUCT (LETYPE(tree->right->left)),
3623 AST_SYMBOL(tree->right->left->right)
3627 tree->type = EX_VALUE;
3628 tree->opval.val = valCastLiteral (
3631 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3634 TTYPE (tree) = tree->opval.val->type;
3635 TETYPE (tree) = getSpec (TTYPE (tree));
3642 /* if the right is a literal replace the tree */
3643 if (IS_LITERAL (RETYPE (tree))) {
3645 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3646 /* rewrite (type *)litaddr
3648 and define type at litaddr temp
3649 (but only if type's storage class is not generic)
3651 ast *newTree = newNode ('&', NULL, NULL);
3654 TTYPE (newTree) = LTYPE (tree);
3655 TETYPE (newTree) = getSpec(LTYPE (tree));
3657 /* define a global symbol at the casted address*/
3658 sym = newSymbol(genSymName (0), 0);
3659 sym->type = LTYPE (tree)->next;
3661 sym->type = newLink (V_VOID);
3662 sym->etype = getSpec(sym->type);
3663 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3664 sym->lineDef = tree->lineno;
3667 SPEC_STAT (sym->etype) = 1;
3668 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3669 SPEC_ABSA(sym->etype) = 1;
3670 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3673 newTree->left = newAst_VALUE(symbolVal(sym));
3674 newTree->left->lineno = tree->lineno;
3675 LTYPE (newTree) = sym->type;
3676 LETYPE (newTree) = sym->etype;
3677 LLVAL (newTree) = 1;
3678 LRVAL (newTree) = 0;
3679 TLVAL (newTree) = 1;
3683 if (!IS_PTR (LTYPE (tree))) {
3684 tree->type = EX_VALUE;
3686 valCastLiteral (LTYPE (tree),
3687 floatFromVal (valFromType (RTYPE (tree))));
3688 TTYPE (tree) = tree->opval.val->type;
3691 tree->values.literalFromCast = 1;
3692 TETYPE (tree) = getSpec (TTYPE (tree));
3696 TTYPE (tree) = LTYPE (tree);
3700 TETYPE (tree) = getSpec (TTYPE (tree));
3704 /*------------------------------------------------------------------*/
3705 /*----------------------------*/
3706 /* logical &&, || */
3707 /*----------------------------*/
3710 /* each must be arithmetic type or be a pointer */
3711 if (!IS_PTR (LTYPE (tree)) &&
3712 !IS_ARRAY (LTYPE (tree)) &&
3713 !IS_INTEGRAL (LTYPE (tree)))
3715 werror (E_COMPARE_OP);
3716 goto errorTreeReturn;
3719 if (!IS_PTR (RTYPE (tree)) &&
3720 !IS_ARRAY (RTYPE (tree)) &&
3721 !IS_INTEGRAL (RTYPE (tree)))
3723 werror (E_COMPARE_OP);
3724 goto errorTreeReturn;
3726 /* if they are both literal then */
3727 /* rewrite the tree */
3728 if (IS_LITERAL (RTYPE (tree)) &&
3729 IS_LITERAL (LTYPE (tree)))
3731 tree->type = EX_VALUE;
3732 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3733 valFromType (RTYPE (tree)),
3735 tree->right = tree->left = NULL;
3736 TETYPE (tree) = getSpec (TTYPE (tree) =
3737 tree->opval.val->type);
3740 LRVAL (tree) = RRVAL (tree) = 1;
3741 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3744 /*------------------------------------------------------------------*/
3745 /*----------------------------*/
3746 /* comparison operators */
3747 /*----------------------------*/
3755 ast *lt = optimizeCompare (tree);
3761 /* if they are pointers they must be castable */
3762 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3764 if (tree->opval.op==EQ_OP &&
3765 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3766 // we cannot cast a gptr to a !gptr: switch the leaves
3767 struct ast *s=tree->left;
3768 tree->left=tree->right;
3771 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3773 werror (E_COMPARE_OP);
3774 fprintf (stderr, "comparing type ");
3775 printTypeChain (LTYPE (tree), stderr);
3776 fprintf (stderr, "to type ");
3777 printTypeChain (RTYPE (tree), stderr);
3778 fprintf (stderr, "\n");
3779 goto errorTreeReturn;
3782 /* else they should be promotable to one another */
3785 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3786 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3788 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3790 werror (E_COMPARE_OP);
3791 fprintf (stderr, "comparing type ");
3792 printTypeChain (LTYPE (tree), stderr);
3793 fprintf (stderr, "to type ");
3794 printTypeChain (RTYPE (tree), stderr);
3795 fprintf (stderr, "\n");
3796 goto errorTreeReturn;
3799 /* if unsigned value < 0 then always false */
3800 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3801 if (SPEC_USIGN(LETYPE(tree)) &&
3802 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3803 IS_LITERAL(RTYPE(tree)) &&
3804 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3806 if (tree->opval.op == '<')
3810 if (tree->opval.op == '>')
3812 if (resultType == RESULT_TYPE_IFX)
3814 /* the parent is an ifx: */
3815 /* if (unsigned value) */
3819 /* (unsigned value) ? 1 : 0 */
3820 tree->opval.op = '?';
3821 tree->right = newNode (':',
3822 newAst_VALUE (constVal ("1")),
3823 tree->right); /* val 0 */
3824 tree->right->lineno = tree->lineno;
3825 tree->right->left->lineno = tree->lineno;
3826 decorateType (tree->right, RESULT_TYPE_NONE);
3829 /* if they are both literal then */
3830 /* rewrite the tree */
3831 if (IS_LITERAL (RTYPE (tree)) &&
3832 IS_LITERAL (LTYPE (tree)))
3834 tree->type = EX_VALUE;
3835 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3836 valFromType (RETYPE (tree)),
3838 tree->right = tree->left = NULL;
3839 TETYPE (tree) = getSpec (TTYPE (tree) =
3840 tree->opval.val->type);
3843 LRVAL (tree) = RRVAL (tree) = 1;
3844 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3847 /*------------------------------------------------------------------*/
3848 /*----------------------------*/
3850 /*----------------------------*/
3851 case SIZEOF: /* evaluate wihout code generation */
3852 /* change the type to a integer */
3854 int size = getSize (tree->right->ftype);
3855 SNPRINTF(buffer, sizeof(buffer), "%d", size);
3856 if (!size && !IS_VOID(tree->right->ftype))
3857 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
3859 tree->type = EX_VALUE;
3860 tree->opval.val = constVal (buffer);
3861 tree->right = tree->left = NULL;
3862 TETYPE (tree) = getSpec (TTYPE (tree) =
3863 tree->opval.val->type);
3866 /*------------------------------------------------------------------*/
3867 /*----------------------------*/
3869 /*----------------------------*/
3871 /* return typeof enum value */
3872 tree->type = EX_VALUE;
3875 if (IS_SPEC(tree->right->ftype)) {
3876 switch (SPEC_NOUN(tree->right->ftype)) {
3878 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3879 else typeofv = TYPEOF_INT;
3882 typeofv = TYPEOF_FLOAT;
3885 typeofv = TYPEOF_FIXED16X16;
3888 typeofv = TYPEOF_CHAR;
3891 typeofv = TYPEOF_VOID;
3894 typeofv = TYPEOF_STRUCT;
3897 typeofv = TYPEOF_BITFIELD;
3900 typeofv = TYPEOF_BIT;
3903 typeofv = TYPEOF_SBIT;
3909 switch (DCL_TYPE(tree->right->ftype)) {
3911 typeofv = TYPEOF_POINTER;
3914 typeofv = TYPEOF_FPOINTER;
3917 typeofv = TYPEOF_CPOINTER;
3920 typeofv = TYPEOF_GPOINTER;
3923 typeofv = TYPEOF_PPOINTER;
3926 typeofv = TYPEOF_IPOINTER;
3929 typeofv = TYPEOF_ARRAY;
3932 typeofv = TYPEOF_FUNCTION;
3938 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3939 tree->opval.val = constVal (buffer);
3940 tree->right = tree->left = NULL;
3941 TETYPE (tree) = getSpec (TTYPE (tree) =
3942 tree->opval.val->type);
3945 /*------------------------------------------------------------------*/
3946 /*----------------------------*/
3947 /* conditional operator '?' */
3948 /*----------------------------*/
3950 /* the type is value of the colon operator (on the right) */
3951 assert (IS_COLON_OP (tree->right));
3952 /* if already known then replace the tree : optimizer will do it
3953 but faster to do it here */
3954 if (IS_LITERAL (LTYPE (tree)))
3956 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
3957 return decorateType (tree->right->left, resultTypeProp);
3959 return decorateType (tree->right->right, resultTypeProp);
3963 tree->right = decorateType (tree->right, resultTypeProp);
3964 TTYPE (tree) = RTYPE (tree);
3965 TETYPE (tree) = getSpec (TTYPE (tree));
3970 /* if they don't match we have a problem */
3971 if ((compareType (LTYPE (tree), RTYPE (tree)) == 0) &&
3972 (compareType (RTYPE (tree), LTYPE (tree)) == 0))
3974 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3975 goto errorTreeReturn;
3978 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
3979 resultType, tree->opval.op);
3980 TETYPE (tree) = getSpec (TTYPE (tree));
3984 #if 0 // assignment operators are converted by the parser
3985 /*------------------------------------------------------------------*/
3986 /*----------------------------*/
3987 /* assignment operators */
3988 /*----------------------------*/
3991 /* for these it must be both must be integral */
3992 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3993 !IS_ARITHMETIC (RTYPE (tree)))
3995 werror (E_OPS_INTEGRAL);
3996 goto errorTreeReturn;
3999 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4001 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
4002 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4006 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4007 goto errorTreeReturn;
4018 /* for these it must be both must be integral */
4019 if (!IS_INTEGRAL (LTYPE (tree)) ||
4020 !IS_INTEGRAL (RTYPE (tree)))
4022 werror (E_OPS_INTEGRAL);
4023 goto errorTreeReturn;
4026 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4028 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4029 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
4033 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
4034 goto errorTreeReturn;
4040 /*------------------------------------------------------------------*/
4041 /*----------------------------*/
4043 /*----------------------------*/
4045 if (!(IS_PTR (LTYPE (tree)) ||
4046 IS_ARITHMETIC (LTYPE (tree))))
4048 werror (E_PLUS_INVALID, "-=");
4049 goto errorTreeReturn;
4052 if (!(IS_PTR (RTYPE (tree)) ||
4053 IS_ARITHMETIC (RTYPE (tree))))
4055 werror (E_PLUS_INVALID, "-=");
4056 goto errorTreeReturn;
4059 TETYPE (tree) = getSpec (TTYPE (tree) =
4060 computeType (LTYPE (tree),
4065 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4066 werror (E_CODE_WRITE, "-=");
4070 werror (E_LVALUE_REQUIRED, "-=");
4071 goto errorTreeReturn;
4077 /*------------------------------------------------------------------*/
4078 /*----------------------------*/
4080 /*----------------------------*/
4082 /* this is not a unary operation */
4083 /* if both pointers then problem */
4084 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4086 werror (E_PTR_PLUS_PTR);
4087 goto errorTreeReturn;
4090 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4092 werror (E_PLUS_INVALID, "+=");
4093 goto errorTreeReturn;
4096 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4098 werror (E_PLUS_INVALID, "+=");
4099 goto errorTreeReturn;
4102 TETYPE (tree) = getSpec (TTYPE (tree) =
4103 computeType (LTYPE (tree),
4108 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4109 werror (E_CODE_WRITE, "+=");
4113 werror (E_LVALUE_REQUIRED, "+=");
4114 goto errorTreeReturn;
4117 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE);
4118 tree->opval.op = '=';
4123 /*------------------------------------------------------------------*/
4124 /*----------------------------*/
4125 /* straight assignemnt */
4126 /*----------------------------*/
4128 /* cannot be an aggregate */
4129 if (IS_AGGREGATE (LTYPE (tree)))
4131 werror (E_AGGR_ASSIGN);
4132 goto errorTreeReturn;
4135 /* they should either match or be castable */
4136 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4138 werror (E_TYPE_MISMATCH, "assignment", " ");
4139 printFromToType(RTYPE(tree),LTYPE(tree));
4142 /* if the left side of the tree is of type void
4143 then report error */
4144 if (IS_VOID (LTYPE (tree)))
4146 werror (E_CAST_ZERO);
4147 printFromToType(RTYPE(tree), LTYPE(tree));
4150 TETYPE (tree) = getSpec (TTYPE (tree) =
4154 if (!tree->initMode ) {
4155 if (IS_CONSTANT(LTYPE(tree)))
4156 werror (E_CODE_WRITE, "=");
4160 werror (E_LVALUE_REQUIRED, "=");
4161 goto errorTreeReturn;
4166 /*------------------------------------------------------------------*/
4167 /*----------------------------*/
4168 /* comma operator */
4169 /*----------------------------*/
4171 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4174 /*------------------------------------------------------------------*/
4175 /*----------------------------*/
4177 /*----------------------------*/
4180 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4181 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4183 if (tree->left->opval.op == '*' && !tree->left->right)
4184 tree->left = tree->left->left;
4187 /* require a function or pointer to function */
4188 if (!IS_FUNC (LTYPE (tree)) && !IS_FUNCPTR (LTYPE (tree)))
4190 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4191 goto errorTreeReturn;
4194 /* if there are parms, make sure that
4195 parms are decorate / process / reverse only once */
4197 !tree->right->decorated)
4202 if (IS_FUNCPTR (LTYPE (tree)))
4203 functype = LTYPE (tree)->next;
4205 functype = LTYPE (tree);
4207 if (processParms (tree->left, FUNC_ARGS(functype),
4208 &tree->right, &parmNumber, TRUE))
4210 goto errorTreeReturn;
4213 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4214 !IFFUNC_ISBUILTIN(functype))
4216 reverseParms (tree->right);
4219 TTYPE (tree) = functype->next;
4220 TETYPE (tree) = getSpec (TTYPE (tree));
4224 /*------------------------------------------------------------------*/
4225 /*----------------------------*/
4226 /* return statement */
4227 /*----------------------------*/
4232 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4234 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4235 printFromToType (RTYPE(tree), currFunc->type->next);
4236 goto errorTreeReturn;
4239 if (IS_VOID (currFunc->type->next)
4241 !IS_VOID (RTYPE (tree)))
4243 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4244 goto errorTreeReturn;
4247 /* if there is going to be a casting required then add it */
4248 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4251 decorateType (newNode (CAST,
4252 newAst_LINK (copyLinkChain (currFunc->type->next)),
4262 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4264 werror (W_VOID_FUNC, currFunc->name);
4265 goto errorTreeReturn;
4268 TTYPE (tree) = TETYPE (tree) = NULL;
4271 /*------------------------------------------------------------------*/
4272 /*----------------------------*/
4273 /* switch statement */
4274 /*----------------------------*/
4276 /* the switch value must be an integer */
4277 if (!IS_INTEGRAL (LTYPE (tree)))
4279 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4280 goto errorTreeReturn;
4283 TTYPE (tree) = TETYPE (tree) = NULL;
4286 /*------------------------------------------------------------------*/
4287 /*----------------------------*/
4289 /*----------------------------*/
4291 tree->left = backPatchLabels (tree->left,
4294 TTYPE (tree) = TETYPE (tree) = NULL;
4297 /*------------------------------------------------------------------*/
4298 /*----------------------------*/
4300 /*----------------------------*/
4303 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE);
4304 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE);
4305 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE);
4307 /* if the for loop is reversible then
4308 reverse it otherwise do what we normally
4314 if (isLoopReversible (tree, &sym, &init, &end))
4315 return reverseLoop (tree, sym, init, end);
4317 return decorateType (createFor (AST_FOR (tree, trueLabel),
4318 AST_FOR (tree, continueLabel),
4319 AST_FOR (tree, falseLabel),
4320 AST_FOR (tree, condLabel),
4321 AST_FOR (tree, initExpr),
4322 AST_FOR (tree, condExpr),
4323 AST_FOR (tree, loopExpr),
4324 tree->left), RESULT_TYPE_NONE);
4327 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4328 "node PARAM shouldn't be processed here");
4329 /* but in processParams() */
4332 TTYPE (tree) = TETYPE (tree) = NULL;
4336 /* some error found this tree will be killed */
4338 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4339 tree->opval.op = NULLOP;
4345 /*-----------------------------------------------------------------*/
4346 /* sizeofOp - processes size of operation */
4347 /*-----------------------------------------------------------------*/
4349 sizeofOp (sym_link * type)
4354 /* make sure the type is complete and sane */
4355 checkTypeSanity(type, "(sizeof)");
4357 /* get the size and convert it to character */
4358 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4359 if (!size && !IS_VOID(type))
4360 werror (E_SIZEOF_INCOMPLETE_TYPE);
4362 /* now convert into value */
4363 return constVal (buff);
4367 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4368 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4369 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4370 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4371 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4372 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4373 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4375 /*-----------------------------------------------------------------*/
4376 /* backPatchLabels - change and or not operators to flow control */
4377 /*-----------------------------------------------------------------*/
4379 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4385 if (!(IS_ANDORNOT (tree)))
4388 /* if this an and */
4391 static int localLbl = 0;
4394 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4395 localLabel = newSymbol (buffer, NestLevel);
4397 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4399 /* if left is already a IFX then just change the if true label in that */
4400 if (!IS_IFX (tree->left))
4401 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4403 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4404 /* right is a IFX then just join */
4405 if (IS_IFX (tree->right))
4406 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4408 tree->right = createLabel (localLabel, tree->right);
4409 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4411 return newNode (NULLOP, tree->left, tree->right);
4414 /* if this is an or operation */
4417 static int localLbl = 0;
4420 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4421 localLabel = newSymbol (buffer, NestLevel);
4423 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4425 /* if left is already a IFX then just change the if true label in that */
4426 if (!IS_IFX (tree->left))
4427 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4429 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4430 /* right is a IFX then just join */
4431 if (IS_IFX (tree->right))
4432 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4434 tree->right = createLabel (localLabel, tree->right);
4435 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4437 return newNode (NULLOP, tree->left, tree->right);
4443 int wasnot = IS_NOT (tree->left);
4444 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4446 /* if the left is already a IFX */
4447 if (!IS_IFX (tree->left))
4448 tree->left = newNode (IFX, tree->left, NULL);
4452 tree->left->trueLabel = trueLabel;
4453 tree->left->falseLabel = falseLabel;
4457 tree->left->trueLabel = falseLabel;
4458 tree->left->falseLabel = trueLabel;
4465 tree->trueLabel = trueLabel;
4466 tree->falseLabel = falseLabel;
4473 /*-----------------------------------------------------------------*/
4474 /* createBlock - create expression tree for block */
4475 /*-----------------------------------------------------------------*/
4477 createBlock (symbol * decl, ast * body)
4481 /* if the block has nothing */
4485 ex = newNode (BLOCK, NULL, body);
4486 ex->values.sym = decl;
4493 /*-----------------------------------------------------------------*/
4494 /* createLabel - creates the expression tree for labels */
4495 /*-----------------------------------------------------------------*/
4497 createLabel (symbol * label, ast * stmnt)
4500 char name[SDCC_NAME_MAX + 1];
4503 /* must create fresh symbol if the symbol name */
4504 /* exists in the symbol table, since there can */
4505 /* be a variable with the same name as the labl */
4506 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4507 (csym->level == label->level))
4508 label = newSymbol (label->name, label->level);
4510 /* change the name before putting it in add _ */
4511 SNPRINTF(name, sizeof(name), "%s", label->name);
4513 /* put the label in the LabelSymbol table */
4514 /* but first check if a label of the same */
4516 if ((csym = findSym (LabelTab, NULL, name)))
4517 werror (E_DUPLICATE_LABEL, label->name);
4519 addSym (LabelTab, label, name, label->level, 0, 0);
4523 label->key = labelKey++;
4524 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4530 /*-----------------------------------------------------------------*/
4531 /* createCase - generates the parsetree for a case statement */
4532 /*-----------------------------------------------------------------*/
4534 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4536 char caseLbl[SDCC_NAME_MAX + 1];
4540 /* if the switch statement does not exist */
4541 /* then case is out of context */
4544 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4548 caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE);
4549 /* if not a constant then error */
4550 if (!IS_LITERAL (caseVal->ftype))
4552 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4556 /* if not a integer than error */
4557 if (!IS_INTEGRAL (caseVal->ftype))
4559 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4563 /* find the end of the switch values chain */
4564 if (!(val = swStat->values.switchVals.swVals))
4565 swStat->values.switchVals.swVals = caseVal->opval.val;
4568 /* also order the cases according to value */
4570 int cVal = (int) floatFromVal (caseVal->opval.val);
4571 while (val && (int) floatFromVal (val) < cVal)
4577 /* if we reached the end then */
4580 pval->next = caseVal->opval.val;
4582 else if ((int) floatFromVal (val) == cVal)
4584 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4590 /* we found a value greater than */
4591 /* the current value we must add this */
4592 /* before the value */
4593 caseVal->opval.val->next = val;
4595 /* if this was the first in chain */
4596 if (swStat->values.switchVals.swVals == val)
4597 swStat->values.switchVals.swVals =
4600 pval->next = caseVal->opval.val;
4605 /* create the case label */
4606 SNPRINTF(caseLbl, sizeof(caseLbl),
4608 swStat->values.switchVals.swNum,
4609 (int) floatFromVal (caseVal->opval.val));
4611 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4616 /*-----------------------------------------------------------------*/
4617 /* createDefault - creates the parse tree for the default statement */
4618 /*-----------------------------------------------------------------*/
4620 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4622 char defLbl[SDCC_NAME_MAX + 1];
4624 /* if the switch statement does not exist */
4625 /* then case is out of context */
4628 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4632 if (swStat->values.switchVals.swDefault)
4634 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4639 /* turn on the default flag */
4640 swStat->values.switchVals.swDefault = 1;
4642 /* create the label */
4643 SNPRINTF (defLbl, sizeof(defLbl),
4644 "_default_%d", swStat->values.switchVals.swNum);
4645 return createLabel (newSymbol (defLbl, 0), stmnt);
4648 /*-----------------------------------------------------------------*/
4649 /* createIf - creates the parsetree for the if statement */
4650 /*-----------------------------------------------------------------*/
4652 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4654 static int Lblnum = 0;
4656 symbol *ifTrue, *ifFalse, *ifEnd;
4658 /* if neither exists */
4659 if (!elseBody && !ifBody) {
4660 // if there are no side effects (i++, j() etc)
4661 if (!hasSEFcalls(condAst)) {
4666 /* create the labels */
4667 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4668 ifFalse = newSymbol (buffer, NestLevel);
4669 /* if no else body then end == false */
4674 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4675 ifEnd = newSymbol (buffer, NestLevel);
4678 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4679 ifTrue = newSymbol (buffer, NestLevel);
4683 /* attach the ifTrue label to the top of it body */
4684 ifBody = createLabel (ifTrue, ifBody);
4685 /* attach a goto end to the ifBody if else is present */
4688 ifBody = newNode (NULLOP, ifBody,
4690 newAst_VALUE (symbolVal (ifEnd)),
4692 /* put the elseLabel on the else body */
4693 elseBody = createLabel (ifFalse, elseBody);
4694 /* out the end at the end of the body */
4695 elseBody = newNode (NULLOP,
4697 createLabel (ifEnd, NULL));
4701 ifBody = newNode (NULLOP, ifBody,
4702 createLabel (ifFalse, NULL));
4704 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4705 if (IS_IFX (condAst))
4708 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4710 return newNode (NULLOP, ifTree,
4711 newNode (NULLOP, ifBody, elseBody));
4715 /*-----------------------------------------------------------------*/
4716 /* createDo - creates parse tree for do */
4719 /* _docontinue_n: */
4720 /* condition_expression +-> trueLabel -> _dobody_n */
4722 /* +-> falseLabel-> _dobreak_n */
4724 /*-----------------------------------------------------------------*/
4726 createDo (symbol * trueLabel, symbol * continueLabel,
4727 symbol * falseLabel, ast * condAst, ast * doBody)
4732 /* if the body does not exist then it is simple */
4735 condAst = backPatchLabels (condAst, continueLabel, NULL);
4736 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4737 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4738 doTree->trueLabel = continueLabel;
4739 doTree->falseLabel = NULL;
4743 /* otherwise we have a body */
4744 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4746 /* attach the body label to the top */
4747 doBody = createLabel (trueLabel, doBody);
4748 /* attach the continue label to end of body */
4749 doBody = newNode (NULLOP, doBody,
4750 createLabel (continueLabel, NULL));
4752 /* now put the break label at the end */
4753 if (IS_IFX (condAst))
4756 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4758 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4760 /* putting it together */
4761 return newNode (NULLOP, doBody, doTree);
4764 /*-----------------------------------------------------------------*/
4765 /* createFor - creates parse tree for 'for' statement */
4768 /* condExpr +-> trueLabel -> _forbody_n */
4770 /* +-> falseLabel-> _forbreak_n */
4773 /* _forcontinue_n: */
4775 /* goto _forcond_n ; */
4777 /*-----------------------------------------------------------------*/
4779 createFor (symbol * trueLabel, symbol * continueLabel,
4780 symbol * falseLabel, symbol * condLabel,
4781 ast * initExpr, ast * condExpr, ast * loopExpr,
4786 /* if loopexpression not present then we can generate it */
4787 /* the same way as a while */
4789 return newNode (NULLOP, initExpr,
4790 createWhile (trueLabel, continueLabel,
4791 falseLabel, condExpr, forBody));
4792 /* vanilla for statement */
4793 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4795 if (condExpr && !IS_IFX (condExpr))
4796 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4799 /* attach condition label to condition */
4800 condExpr = createLabel (condLabel, condExpr);
4802 /* attach body label to body */
4803 forBody = createLabel (trueLabel, forBody);
4805 /* attach continue to forLoop expression & attach */
4806 /* goto the forcond @ and of loopExpression */
4807 loopExpr = createLabel (continueLabel,
4811 newAst_VALUE (symbolVal (condLabel)),
4813 /* now start putting them together */
4814 forTree = newNode (NULLOP, initExpr, condExpr);
4815 forTree = newNode (NULLOP, forTree, forBody);
4816 forTree = newNode (NULLOP, forTree, loopExpr);
4817 /* finally add the break label */
4818 forTree = newNode (NULLOP, forTree,
4819 createLabel (falseLabel, NULL));
4823 /*-----------------------------------------------------------------*/
4824 /* createWhile - creates parse tree for while statement */
4825 /* the while statement will be created as follows */
4827 /* _while_continue_n: */
4828 /* condition_expression +-> trueLabel -> _while_boby_n */
4830 /* +-> falseLabel -> _while_break_n */
4831 /* _while_body_n: */
4833 /* goto _while_continue_n */
4834 /* _while_break_n: */
4835 /*-----------------------------------------------------------------*/
4837 createWhile (symbol * trueLabel, symbol * continueLabel,
4838 symbol * falseLabel, ast * condExpr, ast * whileBody)
4842 /* put the continue label */
4843 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4844 condExpr = createLabel (continueLabel, condExpr);
4845 condExpr->lineno = 0;
4847 /* put the body label in front of the body */
4848 whileBody = createLabel (trueLabel, whileBody);
4849 whileBody->lineno = 0;
4850 /* put a jump to continue at the end of the body */
4851 /* and put break label at the end of the body */
4852 whileBody = newNode (NULLOP,
4855 newAst_VALUE (symbolVal (continueLabel)),
4856 createLabel (falseLabel, NULL)));
4858 /* put it all together */
4859 if (IS_IFX (condExpr))
4860 whileTree = condExpr;
4863 whileTree = newNode (IFX, condExpr, NULL);
4864 /* put the true & false labels in place */
4865 whileTree->trueLabel = trueLabel;
4866 whileTree->falseLabel = falseLabel;
4869 return newNode (NULLOP, whileTree, whileBody);
4872 /*-----------------------------------------------------------------*/
4873 /* optimizeGetHbit - get highest order bit of the expression */
4874 /*-----------------------------------------------------------------*/
4876 optimizeGetHbit (ast * tree)
4879 /* if this is not a bit and */
4880 if (!IS_BITAND (tree))
4883 /* will look for tree of the form
4884 ( expr >> ((sizeof expr) -1) ) & 1 */
4885 if (!IS_AST_LIT_VALUE (tree->right))
4888 if (AST_LIT_VALUE (tree->right) != 1)
4891 if (!IS_RIGHT_OP (tree->left))
4894 if (!IS_AST_LIT_VALUE (tree->left->right))
4897 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4898 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4901 /* make sure the port supports GETHBIT */
4902 if (port->hasExtBitOp
4903 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4906 return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_TYPE_NONE);
4910 /*-----------------------------------------------------------------*/
4911 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4912 /*-----------------------------------------------------------------*/
4914 optimizeRRCRLC (ast * root)
4916 /* will look for trees of the form
4917 (?expr << 1) | (?expr >> 7) or
4918 (?expr >> 7) | (?expr << 1) will make that
4919 into a RLC : operation ..
4921 (?expr >> 1) | (?expr << 7) or
4922 (?expr << 7) | (?expr >> 1) will make that
4923 into a RRC operation
4924 note : by 7 I mean (number of bits required to hold the
4926 /* if the root operations is not a | operation the not */
4927 if (!IS_BITOR (root))
4930 /* I have to think of a better way to match patterns this sucks */
4931 /* that aside let start looking for the first case : I use a the
4932 negative check a lot to improve the efficiency */
4933 /* (?expr << 1) | (?expr >> 7) */
4934 if (IS_LEFT_OP (root->left) &&
4935 IS_RIGHT_OP (root->right))
4938 if (!SPEC_USIGN (TETYPE (root->left->left)))
4941 if (!IS_AST_LIT_VALUE (root->left->right) ||
4942 !IS_AST_LIT_VALUE (root->right->right))
4945 /* make sure it is the same expression */
4946 if (!isAstEqual (root->left->left,
4950 if (AST_LIT_VALUE (root->left->right) != 1)
4953 if (AST_LIT_VALUE (root->right->right) !=
4954 (getSize (TTYPE (root->left->left)) * 8 - 1))
4957 /* make sure the port supports RLC */
4958 if (port->hasExtBitOp
4959 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4962 /* whew got the first case : create the AST */
4963 return newNode (RLC, root->left->left, NULL);
4967 /* check for second case */
4968 /* (?expr >> 7) | (?expr << 1) */
4969 if (IS_LEFT_OP (root->right) &&
4970 IS_RIGHT_OP (root->left))
4973 if (!SPEC_USIGN (TETYPE (root->left->left)))
4976 if (!IS_AST_LIT_VALUE (root->left->right) ||
4977 !IS_AST_LIT_VALUE (root->right->right))
4980 /* make sure it is the same symbol */
4981 if (!isAstEqual (root->left->left,
4985 if (AST_LIT_VALUE (root->right->right) != 1)
4988 if (AST_LIT_VALUE (root->left->right) !=
4989 (getSize (TTYPE (root->left->left)) * 8 - 1))
4992 /* make sure the port supports RLC */
4993 if (port->hasExtBitOp
4994 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4997 /* whew got the first case : create the AST */
4998 return newNode (RLC, root->left->left, NULL);
5003 /* third case for RRC */
5004 /* (?symbol >> 1) | (?symbol << 7) */
5005 if (IS_LEFT_OP (root->right) &&
5006 IS_RIGHT_OP (root->left))
5009 if (!SPEC_USIGN (TETYPE (root->left->left)))
5012 if (!IS_AST_LIT_VALUE (root->left->right) ||
5013 !IS_AST_LIT_VALUE (root->right->right))
5016 /* make sure it is the same symbol */
5017 if (!isAstEqual (root->left->left,
5021 if (AST_LIT_VALUE (root->left->right) != 1)
5024 if (AST_LIT_VALUE (root->right->right) !=
5025 (getSize (TTYPE (root->left->left)) * 8 - 1))
5028 /* make sure the port supports RRC */
5029 if (port->hasExtBitOp
5030 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5033 /* whew got the first case : create the AST */
5034 return newNode (RRC, root->left->left, NULL);
5038 /* fourth and last case for now */
5039 /* (?symbol << 7) | (?symbol >> 1) */
5040 if (IS_RIGHT_OP (root->right) &&
5041 IS_LEFT_OP (root->left))
5044 if (!SPEC_USIGN (TETYPE (root->left->left)))
5047 if (!IS_AST_LIT_VALUE (root->left->right) ||
5048 !IS_AST_LIT_VALUE (root->right->right))
5051 /* make sure it is the same symbol */
5052 if (!isAstEqual (root->left->left,
5056 if (AST_LIT_VALUE (root->right->right) != 1)
5059 if (AST_LIT_VALUE (root->left->right) !=
5060 (getSize (TTYPE (root->left->left)) * 8 - 1))
5063 /* make sure the port supports RRC */
5064 if (port->hasExtBitOp
5065 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5068 /* whew got the first case : create the AST */
5069 return newNode (RRC, root->left->left, NULL);
5073 /* not found return root */
5077 /*-----------------------------------------------------------------*/
5078 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
5079 /*-----------------------------------------------------------------*/
5081 optimizeSWAP (ast * root)
5083 /* will look for trees of the form
5084 (?expr << 4) | (?expr >> 4) or
5085 (?expr >> 4) | (?expr << 4) will make that
5086 into a SWAP : operation ..
5087 note : by 4 I mean (number of bits required to hold the
5089 /* if the root operations is not a | operation the not */
5090 if (!IS_BITOR (root))
5093 /* (?expr << 4) | (?expr >> 4) */
5094 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5095 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5098 if (!SPEC_USIGN (TETYPE (root->left->left)))
5101 if (!IS_AST_LIT_VALUE (root->left->right) ||
5102 !IS_AST_LIT_VALUE (root->right->right))
5105 /* make sure it is the same expression */
5106 if (!isAstEqual (root->left->left,
5110 if (AST_LIT_VALUE (root->left->right) !=
5111 (getSize (TTYPE (root->left->left)) * 4))
5114 if (AST_LIT_VALUE (root->right->right) !=
5115 (getSize (TTYPE (root->left->left)) * 4))
5118 /* make sure the port supports SWAP */
5119 if (port->hasExtBitOp
5120 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5123 /* found it : create the AST */
5124 return newNode (SWAP, root->left->left, NULL);
5128 /* not found return root */
5132 /*-----------------------------------------------------------------*/
5133 /* optimizeCompare - otimizes compares for bit variables */
5134 /*-----------------------------------------------------------------*/
5136 optimizeCompare (ast * root)
5138 ast *optExpr = NULL;
5141 unsigned int litValue;
5143 /* if nothing then return nothing */
5147 /* if not a compare op then do leaves */
5148 if (!IS_COMPARE_OP (root))
5150 root->left = optimizeCompare (root->left);
5151 root->right = optimizeCompare (root->right);
5155 /* if left & right are the same then depending
5156 of the operation do */
5157 if (isAstEqual (root->left, root->right))
5159 switch (root->opval.op)
5164 optExpr = newAst_VALUE (constVal ("0"));
5169 optExpr = newAst_VALUE (constVal ("1"));
5173 return decorateType (optExpr, RESULT_TYPE_NONE);
5176 vleft = (root->left->type == EX_VALUE ?
5177 root->left->opval.val : NULL);
5179 vright = (root->right->type == EX_VALUE ?
5180 root->right->opval.val : NULL);
5182 /* if left is a BITVAR in BITSPACE */
5183 /* and right is a LITERAL then opt- */
5184 /* imize else do nothing */
5185 if (vleft && vright &&
5186 IS_BITVAR (vleft->etype) &&
5187 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5188 IS_LITERAL (vright->etype))
5191 /* if right side > 1 then comparison may never succeed */
5192 if ((litValue = (int) floatFromVal (vright)) > 1)
5194 werror (W_BAD_COMPARE);
5200 switch (root->opval.op)
5202 case '>': /* bit value greater than 1 cannot be */
5203 werror (W_BAD_COMPARE);
5207 case '<': /* bit value < 1 means 0 */
5209 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5212 case LE_OP: /* bit value <= 1 means no check */
5213 optExpr = newAst_VALUE (vright);
5216 case GE_OP: /* bit value >= 1 means only check for = */
5218 optExpr = newAst_VALUE (vleft);
5223 { /* literal is zero */
5224 switch (root->opval.op)
5226 case '<': /* bit value < 0 cannot be */
5227 werror (W_BAD_COMPARE);
5231 case '>': /* bit value > 0 means 1 */
5233 optExpr = newAst_VALUE (vleft);
5236 case LE_OP: /* bit value <= 0 means no check */
5237 case GE_OP: /* bit value >= 0 means no check */
5238 werror (W_BAD_COMPARE);
5242 case EQ_OP: /* bit == 0 means ! of bit */
5243 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5247 return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE);
5248 } /* end-of-if of BITVAR */
5253 /*-----------------------------------------------------------------*/
5254 /* addSymToBlock : adds the symbol to the first block we find */
5255 /*-----------------------------------------------------------------*/
5257 addSymToBlock (symbol * sym, ast * tree)
5259 /* reached end of tree or a leaf */
5260 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5264 if (IS_AST_OP (tree) &&
5265 tree->opval.op == BLOCK)
5268 symbol *lsym = copySymbol (sym);
5270 lsym->next = AST_VALUES (tree, sym);
5271 AST_VALUES (tree, sym) = lsym;
5275 addSymToBlock (sym, tree->left);
5276 addSymToBlock (sym, tree->right);
5279 /*-----------------------------------------------------------------*/
5280 /* processRegParms - do processing for register parameters */
5281 /*-----------------------------------------------------------------*/
5283 processRegParms (value * args, ast * body)
5287 if (IS_REGPARM (args->etype))
5288 addSymToBlock (args->sym, body);
5293 /*-----------------------------------------------------------------*/
5294 /* resetParmKey - resets the operandkeys for the symbols */
5295 /*-----------------------------------------------------------------*/
5296 DEFSETFUNC (resetParmKey)
5307 /*-----------------------------------------------------------------*/
5308 /* createFunction - This is the key node that calls the iCode for */
5309 /* generating the code for a function. Note code */
5310 /* is generated function by function, later when */
5311 /* add inter-procedural analysis this will change */
5312 /*-----------------------------------------------------------------*/
5314 createFunction (symbol * name, ast * body)
5320 iCode *piCode = NULL;
5322 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5323 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5325 /* if check function return 0 then some problem */
5326 if (checkFunction (name, NULL) == 0)
5329 /* create a dummy block if none exists */
5331 body = newNode (BLOCK, NULL, NULL);
5335 /* check if the function name already in the symbol table */
5336 if ((csym = findSym (SymbolTab, NULL, name->name)))
5339 /* special case for compiler defined functions
5340 we need to add the name to the publics list : this
5341 actually means we are now compiling the compiler
5345 addSet (&publics, name);
5350 addSymChain (&name);
5351 allocVariables (name);
5353 name->lastLine = mylineno;
5356 /* set the stack pointer */
5357 stackPtr = -port->stack.direction * port->stack.call_overhead;
5360 if (IFFUNC_ISISR (name->type))
5361 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5363 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5365 if (options.useXstack)
5366 xstackPtr -= port->stack.direction * port->stack.reent_overhead;
5368 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5371 fetype = getSpec (name->type); /* get the specifier for the function */
5372 /* if this is a reentrant function then */
5373 if (IFFUNC_ISREENT (name->type))
5376 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5378 /* do processing for parameters that are passed in registers */
5379 processRegParms (FUNC_ARGS(name->type), body);
5381 /* set the stack pointer */
5385 /* allocate & autoinit the block variables */
5386 processBlockVars (body, &stack, ALLOCATE);
5388 /* save the stack information */
5389 if (options.useXstack)
5390 name->xstack = SPEC_STAK (fetype) = stack;
5392 name->stack = SPEC_STAK (fetype) = stack;
5394 /* name needs to be mangled */
5395 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5397 body = resolveSymbols (body); /* resolve the symbols */
5398 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5401 ex = newAst_VALUE (symbolVal (name)); /* create name */
5402 ex = newNode (FUNCTION, ex, body);
5403 ex->values.args = FUNC_ARGS(name->type);
5405 if (options.dump_tree) PA(ex);
5408 werror (E_FUNC_NO_CODE, name->name);
5412 /* create the node & generate intermediate code */
5414 codeOutFile = code->oFile;
5415 piCode = iCodeFromAst (ex);
5419 werror (E_FUNC_NO_CODE, name->name);
5423 eBBlockFromiCode (piCode);
5425 /* if there are any statics then do them */
5428 GcurMemmap = statsg;
5429 codeOutFile = statsg->oFile;
5430 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE)));
5436 /* dealloc the block variables */
5437 processBlockVars (body, &stack, DEALLOCATE);
5438 outputDebugStackSymbols();
5439 /* deallocate paramaters */
5440 deallocParms (FUNC_ARGS(name->type));
5442 if (IFFUNC_ISREENT (name->type))
5445 /* we are done freeup memory & cleanup */
5447 if (port->reset_labelKey) labelKey = 1;
5449 FUNC_HASBODY(name->type) = 1;
5450 addSet (&operKeyReset, name);
5451 applyToSet (operKeyReset, resetParmKey);
5456 cleanUpLevel (LabelTab, 0);
5457 cleanUpBlock (StructTab, 1);
5458 cleanUpBlock (TypedefTab, 1);
5460 xstack->syms = NULL;
5461 istack->syms = NULL;
5466 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5467 /*-----------------------------------------------------------------*/
5468 /* ast_print : prints the ast (for debugging purposes) */
5469 /*-----------------------------------------------------------------*/
5471 void ast_print (ast * tree, FILE *outfile, int indent)
5476 /* can print only decorated trees */
5477 if (!tree->decorated) return;
5479 /* if any child is an error | this one is an error do nothing */
5480 if (tree->isError ||
5481 (tree->left && tree->left->isError) ||
5482 (tree->right && tree->right->isError)) {
5483 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5487 /* print the line */
5488 /* if not block & function */
5489 if (tree->type == EX_OP &&
5490 (tree->opval.op != FUNCTION &&
5491 tree->opval.op != BLOCK &&
5492 tree->opval.op != NULLOP)) {
5495 if (tree->opval.op == FUNCTION) {
5497 value *args=FUNC_ARGS(tree->left->opval.val->type);
5498 fprintf(outfile,"FUNCTION (%s=%p) type (",
5499 tree->left->opval.val->name, tree);
5500 printTypeChain (tree->left->opval.val->type->next,outfile);
5501 fprintf(outfile,") args (");
5504 fprintf (outfile, ", ");
5506 printTypeChain (args ? args->type : NULL, outfile);
5508 args= args ? args->next : NULL;
5510 fprintf(outfile,")\n");
5511 ast_print(tree->left,outfile,indent);
5512 ast_print(tree->right,outfile,indent);
5515 if (tree->opval.op == BLOCK) {
5516 symbol *decls = tree->values.sym;
5517 INDENT(indent,outfile);
5518 fprintf(outfile,"{\n");
5520 INDENT(indent+2,outfile);
5521 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5522 decls->name, decls);
5523 printTypeChain(decls->type,outfile);
5524 fprintf(outfile,")\n");
5526 decls = decls->next;
5528 ast_print(tree->right,outfile,indent+2);
5529 INDENT(indent,outfile);
5530 fprintf(outfile,"}\n");
5533 if (tree->opval.op == NULLOP) {
5534 ast_print(tree->left,outfile,indent);
5535 ast_print(tree->right,outfile,indent);
5538 INDENT(indent,outfile);
5540 /*------------------------------------------------------------------*/
5541 /*----------------------------*/
5542 /* leaf has been reached */
5543 /*----------------------------*/
5544 /* if this is of type value */
5545 /* just get the type */
5546 if (tree->type == EX_VALUE) {
5548 if (IS_LITERAL (tree->opval.val->etype)) {
5549 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5550 if (SPEC_USIGN (tree->opval.val->etype))
5551 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5553 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5554 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5555 floatFromVal(tree->opval.val));
5556 } else if (tree->opval.val->sym) {
5557 /* if the undefined flag is set then give error message */
5558 if (tree->opval.val->sym->undefined) {
5559 fprintf(outfile,"UNDEFINED SYMBOL ");
5561 fprintf(outfile,"SYMBOL ");
5563 fprintf(outfile,"(%s=%p)",
5564 tree->opval.val->sym->name,tree);
5567 fprintf(outfile," type (");
5568 printTypeChain(tree->ftype,outfile);
5569 fprintf(outfile,")\n");
5571 fprintf(outfile,"\n");
5576 /* if type link for the case of cast */
5577 if (tree->type == EX_LINK) {
5578 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5579 printTypeChain(tree->opval.lnk,outfile);
5580 fprintf(outfile,")\n");
5585 /* depending on type of operator do */
5587 switch (tree->opval.op) {
5588 /*------------------------------------------------------------------*/
5589 /*----------------------------*/
5591 /*----------------------------*/
5593 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5594 printTypeChain(tree->ftype,outfile);
5595 fprintf(outfile,")\n");
5596 ast_print(tree->left,outfile,indent+2);
5597 ast_print(tree->right,outfile,indent+2);
5600 /*------------------------------------------------------------------*/
5601 /*----------------------------*/
5603 /*----------------------------*/
5605 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5606 printTypeChain(tree->ftype,outfile);
5607 fprintf(outfile,")\n");
5608 ast_print(tree->left,outfile,indent+2);
5609 ast_print(tree->right,outfile,indent+2);
5612 /*------------------------------------------------------------------*/
5613 /*----------------------------*/
5614 /* struct/union pointer */
5615 /*----------------------------*/
5617 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5618 printTypeChain(tree->ftype,outfile);
5619 fprintf(outfile,")\n");
5620 ast_print(tree->left,outfile,indent+2);
5621 ast_print(tree->right,outfile,indent+2);
5624 /*------------------------------------------------------------------*/
5625 /*----------------------------*/
5626 /* ++/-- operation */
5627 /*----------------------------*/
5630 fprintf(outfile,"post-");
5632 fprintf(outfile,"pre-");
5633 fprintf(outfile,"INC_OP (%p) type (",tree);
5634 printTypeChain(tree->ftype,outfile);
5635 fprintf(outfile,")\n");
5636 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5637 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5642 fprintf(outfile,"post-");
5644 fprintf(outfile,"pre-");
5645 fprintf(outfile,"DEC_OP (%p) type (",tree);
5646 printTypeChain(tree->ftype,outfile);
5647 fprintf(outfile,")\n");
5648 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5649 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5652 /*------------------------------------------------------------------*/
5653 /*----------------------------*/
5655 /*----------------------------*/
5658 fprintf(outfile,"& (%p) type (",tree);
5659 printTypeChain(tree->ftype,outfile);
5660 fprintf(outfile,")\n");
5661 ast_print(tree->left,outfile,indent+2);
5662 ast_print(tree->right,outfile,indent+2);
5664 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5665 printTypeChain(tree->ftype,outfile);
5666 fprintf(outfile,")\n");
5667 ast_print(tree->left,outfile,indent+2);
5668 ast_print(tree->right,outfile,indent+2);
5671 /*----------------------------*/
5673 /*----------------------------*/
5675 fprintf(outfile,"OR (%p) type (",tree);
5676 printTypeChain(tree->ftype,outfile);
5677 fprintf(outfile,")\n");
5678 ast_print(tree->left,outfile,indent+2);
5679 ast_print(tree->right,outfile,indent+2);
5681 /*------------------------------------------------------------------*/
5682 /*----------------------------*/
5684 /*----------------------------*/
5686 fprintf(outfile,"XOR (%p) type (",tree);
5687 printTypeChain(tree->ftype,outfile);
5688 fprintf(outfile,")\n");
5689 ast_print(tree->left,outfile,indent+2);
5690 ast_print(tree->right,outfile,indent+2);
5693 /*------------------------------------------------------------------*/
5694 /*----------------------------*/
5696 /*----------------------------*/
5698 fprintf(outfile,"DIV (%p) type (",tree);
5699 printTypeChain(tree->ftype,outfile);
5700 fprintf(outfile,")\n");
5701 ast_print(tree->left,outfile,indent+2);
5702 ast_print(tree->right,outfile,indent+2);
5704 /*------------------------------------------------------------------*/
5705 /*----------------------------*/
5707 /*----------------------------*/
5709 fprintf(outfile,"MOD (%p) type (",tree);
5710 printTypeChain(tree->ftype,outfile);
5711 fprintf(outfile,")\n");
5712 ast_print(tree->left,outfile,indent+2);
5713 ast_print(tree->right,outfile,indent+2);
5716 /*------------------------------------------------------------------*/
5717 /*----------------------------*/
5718 /* address dereference */
5719 /*----------------------------*/
5720 case '*': /* can be unary : if right is null then unary operation */
5722 fprintf(outfile,"DEREF (%p) type (",tree);
5723 printTypeChain(tree->ftype,outfile);
5724 fprintf(outfile,")\n");
5725 ast_print(tree->left,outfile,indent+2);
5728 /*------------------------------------------------------------------*/
5729 /*----------------------------*/
5730 /* multiplication */
5731 /*----------------------------*/
5732 fprintf(outfile,"MULT (%p) type (",tree);
5733 printTypeChain(tree->ftype,outfile);
5734 fprintf(outfile,")\n");
5735 ast_print(tree->left,outfile,indent+2);
5736 ast_print(tree->right,outfile,indent+2);
5740 /*------------------------------------------------------------------*/
5741 /*----------------------------*/
5742 /* unary '+' operator */
5743 /*----------------------------*/
5747 fprintf(outfile,"UPLUS (%p) type (",tree);
5748 printTypeChain(tree->ftype,outfile);
5749 fprintf(outfile,")\n");
5750 ast_print(tree->left,outfile,indent+2);
5752 /*------------------------------------------------------------------*/
5753 /*----------------------------*/
5755 /*----------------------------*/
5756 fprintf(outfile,"ADD (%p) type (",tree);
5757 printTypeChain(tree->ftype,outfile);
5758 fprintf(outfile,")\n");
5759 ast_print(tree->left,outfile,indent+2);
5760 ast_print(tree->right,outfile,indent+2);
5763 /*------------------------------------------------------------------*/
5764 /*----------------------------*/
5766 /*----------------------------*/
5767 case '-': /* can be unary */
5769 fprintf(outfile,"UMINUS (%p) type (",tree);
5770 printTypeChain(tree->ftype,outfile);
5771 fprintf(outfile,")\n");
5772 ast_print(tree->left,outfile,indent+2);
5774 /*------------------------------------------------------------------*/
5775 /*----------------------------*/
5777 /*----------------------------*/
5778 fprintf(outfile,"SUB (%p) type (",tree);
5779 printTypeChain(tree->ftype,outfile);
5780 fprintf(outfile,")\n");
5781 ast_print(tree->left,outfile,indent+2);
5782 ast_print(tree->right,outfile,indent+2);
5785 /*------------------------------------------------------------------*/
5786 /*----------------------------*/
5788 /*----------------------------*/
5790 fprintf(outfile,"COMPL (%p) type (",tree);
5791 printTypeChain(tree->ftype,outfile);
5792 fprintf(outfile,")\n");
5793 ast_print(tree->left,outfile,indent+2);
5795 /*------------------------------------------------------------------*/
5796 /*----------------------------*/
5798 /*----------------------------*/
5800 fprintf(outfile,"NOT (%p) type (",tree);
5801 printTypeChain(tree->ftype,outfile);
5802 fprintf(outfile,")\n");
5803 ast_print(tree->left,outfile,indent+2);
5805 /*------------------------------------------------------------------*/
5806 /*----------------------------*/
5808 /*----------------------------*/
5810 fprintf(outfile,"RRC (%p) type (",tree);
5811 printTypeChain(tree->ftype,outfile);
5812 fprintf(outfile,")\n");
5813 ast_print(tree->left,outfile,indent+2);
5817 fprintf(outfile,"RLC (%p) type (",tree);
5818 printTypeChain(tree->ftype,outfile);
5819 fprintf(outfile,")\n");
5820 ast_print(tree->left,outfile,indent+2);
5823 fprintf(outfile,"SWAP (%p) type (",tree);
5824 printTypeChain(tree->ftype,outfile);
5825 fprintf(outfile,")\n");
5826 ast_print(tree->left,outfile,indent+2);
5829 fprintf(outfile,"GETHBIT (%p) type (",tree);
5830 printTypeChain(tree->ftype,outfile);
5831 fprintf(outfile,")\n");
5832 ast_print(tree->left,outfile,indent+2);
5835 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5836 printTypeChain(tree->ftype,outfile);
5837 fprintf(outfile,")\n");
5838 ast_print(tree->left,outfile,indent+2);
5839 ast_print(tree->right,outfile,indent+2);
5842 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5843 printTypeChain(tree->ftype,outfile);
5844 fprintf(outfile,")\n");
5845 ast_print(tree->left,outfile,indent+2);
5846 ast_print(tree->right,outfile,indent+2);
5848 /*------------------------------------------------------------------*/
5849 /*----------------------------*/
5851 /*----------------------------*/
5852 case CAST: /* change the type */
5853 fprintf(outfile,"CAST (%p) from type (",tree);
5854 printTypeChain(tree->right->ftype,outfile);
5855 fprintf(outfile,") to type (");
5856 printTypeChain(tree->ftype,outfile);
5857 fprintf(outfile,")\n");
5858 ast_print(tree->right,outfile,indent+2);
5862 fprintf(outfile,"ANDAND (%p) type (",tree);
5863 printTypeChain(tree->ftype,outfile);
5864 fprintf(outfile,")\n");
5865 ast_print(tree->left,outfile,indent+2);
5866 ast_print(tree->right,outfile,indent+2);
5869 fprintf(outfile,"OROR (%p) type (",tree);
5870 printTypeChain(tree->ftype,outfile);
5871 fprintf(outfile,")\n");
5872 ast_print(tree->left,outfile,indent+2);
5873 ast_print(tree->right,outfile,indent+2);
5876 /*------------------------------------------------------------------*/
5877 /*----------------------------*/
5878 /* comparison operators */
5879 /*----------------------------*/
5881 fprintf(outfile,"GT(>) (%p) type (",tree);
5882 printTypeChain(tree->ftype,outfile);
5883 fprintf(outfile,")\n");
5884 ast_print(tree->left,outfile,indent+2);
5885 ast_print(tree->right,outfile,indent+2);
5888 fprintf(outfile,"LT(<) (%p) type (",tree);
5889 printTypeChain(tree->ftype,outfile);
5890 fprintf(outfile,")\n");
5891 ast_print(tree->left,outfile,indent+2);
5892 ast_print(tree->right,outfile,indent+2);
5895 fprintf(outfile,"LE(<=) (%p) type (",tree);
5896 printTypeChain(tree->ftype,outfile);
5897 fprintf(outfile,")\n");
5898 ast_print(tree->left,outfile,indent+2);
5899 ast_print(tree->right,outfile,indent+2);
5902 fprintf(outfile,"GE(>=) (%p) type (",tree);
5903 printTypeChain(tree->ftype,outfile);
5904 fprintf(outfile,")\n");
5905 ast_print(tree->left,outfile,indent+2);
5906 ast_print(tree->right,outfile,indent+2);
5909 fprintf(outfile,"EQ(==) (%p) type (",tree);
5910 printTypeChain(tree->ftype,outfile);
5911 fprintf(outfile,")\n");
5912 ast_print(tree->left,outfile,indent+2);
5913 ast_print(tree->right,outfile,indent+2);
5916 fprintf(outfile,"NE(!=) (%p) type (",tree);
5917 printTypeChain(tree->ftype,outfile);
5918 fprintf(outfile,")\n");
5919 ast_print(tree->left,outfile,indent+2);
5920 ast_print(tree->right,outfile,indent+2);
5921 /*------------------------------------------------------------------*/
5922 /*----------------------------*/
5924 /*----------------------------*/
5925 case SIZEOF: /* evaluate wihout code generation */
5926 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5929 /*------------------------------------------------------------------*/
5930 /*----------------------------*/
5931 /* conditional operator '?' */
5932 /*----------------------------*/
5934 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5935 printTypeChain(tree->ftype,outfile);
5936 fprintf(outfile,")\n");
5937 ast_print(tree->left,outfile,indent+2);
5938 ast_print(tree->right,outfile,indent+2);
5942 fprintf(outfile,"COLON(:) (%p) type (",tree);
5943 printTypeChain(tree->ftype,outfile);
5944 fprintf(outfile,")\n");
5945 ast_print(tree->left,outfile,indent+2);
5946 ast_print(tree->right,outfile,indent+2);
5949 /*------------------------------------------------------------------*/
5950 /*----------------------------*/
5951 /* assignment operators */
5952 /*----------------------------*/
5954 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5955 printTypeChain(tree->ftype,outfile);
5956 fprintf(outfile,")\n");
5957 ast_print(tree->left,outfile,indent+2);
5958 ast_print(tree->right,outfile,indent+2);
5961 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5962 printTypeChain(tree->ftype,outfile);
5963 fprintf(outfile,")\n");
5964 ast_print(tree->left,outfile,indent+2);
5965 ast_print(tree->right,outfile,indent+2);
5968 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5969 printTypeChain(tree->ftype,outfile);
5970 fprintf(outfile,")\n");
5971 ast_print(tree->left,outfile,indent+2);
5972 ast_print(tree->right,outfile,indent+2);
5975 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5976 printTypeChain(tree->ftype,outfile);
5977 fprintf(outfile,")\n");
5978 ast_print(tree->left,outfile,indent+2);
5979 ast_print(tree->right,outfile,indent+2);
5982 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5983 printTypeChain(tree->ftype,outfile);
5984 fprintf(outfile,")\n");
5985 ast_print(tree->left,outfile,indent+2);
5986 ast_print(tree->right,outfile,indent+2);
5989 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5990 printTypeChain(tree->ftype,outfile);
5991 fprintf(outfile,")\n");
5992 ast_print(tree->left,outfile,indent+2);
5993 ast_print(tree->right,outfile,indent+2);
5996 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5997 printTypeChain(tree->ftype,outfile);
5998 fprintf(outfile,")\n");
5999 ast_print(tree->left,outfile,indent+2);
6000 ast_print(tree->right,outfile,indent+2);
6002 /*------------------------------------------------------------------*/
6003 /*----------------------------*/
6005 /*----------------------------*/
6007 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
6008 printTypeChain(tree->ftype,outfile);
6009 fprintf(outfile,")\n");
6010 ast_print(tree->left,outfile,indent+2);
6011 ast_print(tree->right,outfile,indent+2);
6013 /*------------------------------------------------------------------*/
6014 /*----------------------------*/
6016 /*----------------------------*/
6018 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
6019 printTypeChain(tree->ftype,outfile);
6020 fprintf(outfile,")\n");
6021 ast_print(tree->left,outfile,indent+2);
6022 ast_print(tree->right,outfile,indent+2);
6024 /*------------------------------------------------------------------*/
6025 /*----------------------------*/
6026 /* straight assignemnt */
6027 /*----------------------------*/
6029 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
6030 printTypeChain(tree->ftype,outfile);
6031 fprintf(outfile,")\n");
6032 ast_print(tree->left,outfile,indent+2);
6033 ast_print(tree->right,outfile,indent+2);
6035 /*------------------------------------------------------------------*/
6036 /*----------------------------*/
6037 /* comma operator */
6038 /*----------------------------*/
6040 fprintf(outfile,"COMMA(,) (%p) type (",tree);
6041 printTypeChain(tree->ftype,outfile);
6042 fprintf(outfile,")\n");
6043 ast_print(tree->left,outfile,indent+2);
6044 ast_print(tree->right,outfile,indent+2);
6046 /*------------------------------------------------------------------*/
6047 /*----------------------------*/
6049 /*----------------------------*/
6052 fprintf(outfile,"CALL (%p) type (",tree);
6053 printTypeChain(tree->ftype,outfile);
6054 fprintf(outfile,")\n");
6055 ast_print(tree->left,outfile,indent+2);
6056 ast_print(tree->right,outfile,indent+2);
6059 fprintf(outfile,"PARMS\n");
6060 ast_print(tree->left,outfile,indent+2);
6061 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
6062 ast_print(tree->right,outfile,indent+2);
6065 /*------------------------------------------------------------------*/
6066 /*----------------------------*/
6067 /* return statement */
6068 /*----------------------------*/
6070 fprintf(outfile,"RETURN (%p) type (",tree);
6072 printTypeChain(tree->right->ftype,outfile);
6074 fprintf(outfile,")\n");
6075 ast_print(tree->right,outfile,indent+2);
6077 /*------------------------------------------------------------------*/
6078 /*----------------------------*/
6079 /* label statement */
6080 /*----------------------------*/
6082 fprintf(outfile,"LABEL (%p)\n",tree);
6083 ast_print(tree->left,outfile,indent+2);
6084 ast_print(tree->right,outfile,indent);
6086 /*------------------------------------------------------------------*/
6087 /*----------------------------*/
6088 /* switch statement */
6089 /*----------------------------*/
6093 fprintf(outfile,"SWITCH (%p) ",tree);
6094 ast_print(tree->left,outfile,0);
6095 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
6096 INDENT(indent+2,outfile);
6097 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
6098 (int) floatFromVal(val),
6099 tree->values.switchVals.swNum,
6100 (int) floatFromVal(val));
6102 ast_print(tree->right,outfile,indent);
6105 /*------------------------------------------------------------------*/
6106 /*----------------------------*/
6108 /*----------------------------*/
6110 fprintf(outfile,"IF (%p) \n",tree);
6111 ast_print(tree->left,outfile,indent+2);
6112 if (tree->trueLabel) {
6113 INDENT(indent+2,outfile);
6114 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
6116 if (tree->falseLabel) {
6117 INDENT(indent+2,outfile);
6118 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
6120 ast_print(tree->right,outfile,indent+2);
6122 /*----------------------------*/
6123 /* goto Statement */
6124 /*----------------------------*/
6126 fprintf(outfile,"GOTO (%p) \n",tree);
6127 ast_print(tree->left,outfile,indent+2);
6128 fprintf(outfile,"\n");
6130 /*------------------------------------------------------------------*/
6131 /*----------------------------*/
6133 /*----------------------------*/
6135 fprintf(outfile,"FOR (%p) \n",tree);
6136 if (AST_FOR( tree, initExpr)) {
6137 INDENT(indent+2,outfile);
6138 fprintf(outfile,"INIT EXPR ");
6139 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6141 if (AST_FOR( tree, condExpr)) {
6142 INDENT(indent+2,outfile);
6143 fprintf(outfile,"COND EXPR ");
6144 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6146 if (AST_FOR( tree, loopExpr)) {
6147 INDENT(indent+2,outfile);
6148 fprintf(outfile,"LOOP EXPR ");
6149 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6151 fprintf(outfile,"FOR LOOP BODY \n");
6152 ast_print(tree->left,outfile,indent+2);
6155 fprintf(outfile,"CRITICAL (%p) \n",tree);
6156 ast_print(tree->left,outfile,indent+2);
6164 ast_print(t,stdout,0);
6169 /*-----------------------------------------------------------------*/
6170 /* astErrors : returns non-zero if errors present in tree */
6171 /*-----------------------------------------------------------------*/
6172 int astErrors(ast *t)
6181 if (t->type == EX_VALUE
6182 && t->opval.val->sym
6183 && t->opval.val->sym->undefined)
6186 errors += astErrors(t->left);
6187 errors += astErrors(t->right);