1 /*-------------------------------------------------------------------------
2 SDCCast.c - source file for parser support & all ast related routines
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
25 #define DEBUG_CF(x) /* puts(x); */
31 set *operKeyReset = NULL;
32 ast *staticAutos = NULL;
35 #define LRVAL(x) x->left->rvalue
36 #define RRVAL(x) x->right->rvalue
37 #define TRVAL(x) x->rvalue
38 #define LLVAL(x) x->left->lvalue
39 #define RLVAL(x) x->right->lvalue
40 #define TLVAL(x) x->lvalue
41 #define RTYPE(x) x->right->ftype
42 #define RETYPE(x) x->right->etype
43 #define LTYPE(x) x->left->ftype
44 #define LETYPE(x) x->left->etype
45 #define TTYPE(x) x->ftype
46 #define TETYPE(x) x->etype
52 symbol *currFunc=NULL;
53 static ast *createIval (ast *, sym_link *, initList *, ast *);
54 static ast *createIvalCharPtr (ast *, sym_link *, ast *);
55 static ast *optimizeCompare (ast *);
56 ast *optimizeRRCRLC (ast *);
57 ast *optimizeSWAP (ast *);
58 ast *optimizeGetHbit (ast *);
59 ast *backPatchLabels (ast *, symbol *, symbol *);
62 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
67 printTypeChain (tree->ftype, stdout);
72 /*-----------------------------------------------------------------*/
73 /* newAst - creates a fresh node for an expression tree */
74 /*-----------------------------------------------------------------*/
76 newAst_ (unsigned type)
79 static int oldLineno = 0;
81 ex = Safe_alloc ( sizeof (ast));
84 ex->lineno = (noLineno ? oldLineno : mylineno);
85 ex->filename = currFname;
86 ex->level = NestLevel;
87 ex->block = currBlockno;
88 ex->initMode = inInitMode;
89 ex->seqPoint = seqPointNo;
94 newAst_VALUE (value * val)
96 ast *ex = newAst_ (EX_VALUE);
102 newAst_OP (unsigned op)
104 ast *ex = newAst_ (EX_OP);
110 newAst_LINK (sym_link * val)
112 ast *ex = newAst_ (EX_LINK);
117 /*-----------------------------------------------------------------*/
118 /* newNode - creates a new node */
119 /*-----------------------------------------------------------------*/
121 newNode (long op, ast * left, ast * right)
132 /*-----------------------------------------------------------------*/
133 /* newIfxNode - creates a new Ifx Node */
134 /*-----------------------------------------------------------------*/
136 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
140 /* if this is a literal then we already know the result */
141 if (condAst->etype && IS_LITERAL (condAst->etype))
143 /* then depending on the expression value */
144 if (floatFromVal (condAst->opval.val))
145 ifxNode = newNode (GOTO,
146 newAst_VALUE (symbolVal (trueLabel)),
149 ifxNode = newNode (GOTO,
150 newAst_VALUE (symbolVal (falseLabel)),
155 ifxNode = newNode (IFX, condAst, NULL);
156 ifxNode->trueLabel = trueLabel;
157 ifxNode->falseLabel = falseLabel;
163 /*-----------------------------------------------------------------*/
164 /* copyAstValues - copies value portion of ast if needed */
165 /*-----------------------------------------------------------------*/
167 copyAstValues (ast * dest, ast * src)
169 switch (src->opval.op)
172 dest->values.sym = copySymbolChain (src->values.sym);
176 dest->values.switchVals.swVals =
177 copyValue (src->values.switchVals.swVals);
178 dest->values.switchVals.swDefault =
179 src->values.switchVals.swDefault;
180 dest->values.switchVals.swNum =
181 src->values.switchVals.swNum;
185 dest->values.inlineasm = Safe_strdup(src->values.inlineasm);
189 dest->values.constlist = copyLiteralList(src->values.constlist);
193 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
194 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
195 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
196 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
197 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
198 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
199 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
204 /*-----------------------------------------------------------------*/
205 /* copyAst - makes a copy of a given astession */
206 /*-----------------------------------------------------------------*/
215 dest = Safe_alloc ( sizeof (ast));
217 dest->type = src->type;
218 dest->lineno = src->lineno;
219 dest->level = src->level;
220 dest->funcName = src->funcName;
221 dest->reversed = src->reversed;
224 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
226 /* if this is a leaf */
228 if (src->type == EX_VALUE)
230 dest->opval.val = copyValue (src->opval.val);
235 if (src->type == EX_LINK)
237 dest->opval.lnk = copyLinkChain (src->opval.lnk);
241 dest->opval.op = src->opval.op;
243 /* if this is a node that has special values */
244 copyAstValues (dest, src);
246 dest->trueLabel = copySymbol (src->trueLabel);
247 dest->falseLabel = copySymbol (src->falseLabel);
248 dest->left = copyAst (src->left);
249 dest->right = copyAst (src->right);
255 /*-----------------------------------------------------------------*/
256 /* removeIncDecOps: remove for side effects in *_ASSIGN's */
257 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
258 /*-----------------------------------------------------------------*/
259 ast *removeIncDecOps (ast * tree) {
261 // traverse the tree and remove inc/dec ops
266 if (tree->type == EX_OP &&
267 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
274 tree->left=removeIncDecOps(tree->left);
275 tree->right=removeIncDecOps(tree->right);
280 /*-----------------------------------------------------------------*/
281 /* removePreIncDecOps: remove for side effects in *_ASSIGN's */
282 /* "*++s += 3" -> "*++s = *++s + 3" */
283 /*-----------------------------------------------------------------*/
284 ast *removePreIncDecOps (ast * tree) {
286 // traverse the tree and remove pre-inc/dec ops
291 if (tree->type == EX_OP &&
292 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
297 tree->left=removePreIncDecOps(tree->left);
298 tree->right=removePreIncDecOps(tree->right);
303 /*-----------------------------------------------------------------*/
304 /* removePostIncDecOps: remove for side effects in *_ASSIGN's */
305 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
306 /*-----------------------------------------------------------------*/
307 ast *removePostIncDecOps (ast * tree) {
309 // traverse the tree and remove pre-inc/dec ops
314 if (tree->type == EX_OP &&
315 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
320 tree->left=removePostIncDecOps(tree->left);
321 tree->right=removePostIncDecOps(tree->right);
326 /*-----------------------------------------------------------------*/
327 /* hasSEFcalls - returns TRUE if tree has a function call */
328 /*-----------------------------------------------------------------*/
330 hasSEFcalls (ast * tree)
335 if (tree->type == EX_OP &&
336 (tree->opval.op == CALL ||
337 tree->opval.op == PCALL ||
338 tree->opval.op == '=' ||
339 tree->opval.op == INC_OP ||
340 tree->opval.op == DEC_OP))
343 return (hasSEFcalls (tree->left) |
344 hasSEFcalls (tree->right));
347 /*-----------------------------------------------------------------*/
348 /* isAstEqual - compares two asts & returns 1 if they are equal */
349 /*-----------------------------------------------------------------*/
351 isAstEqual (ast * t1, ast * t2)
360 if (t1->type != t2->type)
366 if (t1->opval.op != t2->opval.op)
368 return (isAstEqual (t1->left, t2->left) &&
369 isAstEqual (t1->right, t2->right));
373 if (t1->opval.val->sym)
375 if (!t2->opval.val->sym)
378 return isSymbolEqual (t1->opval.val->sym,
383 if (t2->opval.val->sym)
386 return (floatFromVal (t1->opval.val) ==
387 floatFromVal (t2->opval.val));
391 /* only compare these two types */
399 /*-----------------------------------------------------------------*/
400 /* resolveSymbols - resolve symbols from the symbol table */
401 /*-----------------------------------------------------------------*/
403 resolveSymbols (ast * tree)
405 /* walk the entire tree and check for values */
406 /* with symbols if we find one then replace */
407 /* symbol with that from the symbol table */
414 /* if not block & function */
415 if (tree->type == EX_OP &&
416 (tree->opval.op != FUNCTION &&
417 tree->opval.op != BLOCK &&
418 tree->opval.op != NULLOP))
420 filename = tree->filename;
421 lineno = tree->lineno;
425 /* make sure we resolve the true & false labels for ifx */
426 if (tree->type == EX_OP && tree->opval.op == IFX)
432 if ((csym = findSym (LabelTab, tree->trueLabel,
433 tree->trueLabel->name)))
434 tree->trueLabel = csym;
436 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
437 tree->trueLabel->name);
440 if (tree->falseLabel)
442 if ((csym = findSym (LabelTab,
444 tree->falseLabel->name)))
445 tree->falseLabel = csym;
447 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
448 tree->falseLabel->name);
453 /* if this is a label resolve it from the labelTab */
454 if (IS_AST_VALUE (tree) &&
455 tree->opval.val->sym &&
456 tree->opval.val->sym->islbl)
459 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
460 tree->opval.val->sym->name);
463 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
464 tree->opval.val->sym->name);
466 tree->opval.val->sym = csym;
468 goto resolveChildren;
471 /* do only for leafs */
472 if (IS_AST_VALUE (tree) &&
473 tree->opval.val->sym &&
474 !tree->opval.val->sym->implicit)
477 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
479 /* if found in the symbol table & they r not the same */
480 if (csym && tree->opval.val->sym != csym)
482 tree->opval.val->sym = csym;
483 tree->opval.val->type = csym->type;
484 tree->opval.val->etype = csym->etype;
487 /* if not found in the symbol table */
488 /* mark it as undefined assume it is */
489 /* an integer in data space */
490 if (!csym && !tree->opval.val->sym->implicit)
493 /* if this is a function name then */
494 /* mark it as returning an int */
497 tree->opval.val->sym->type = newLink (DECLARATOR);
498 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
499 tree->opval.val->sym->type->next =
500 tree->opval.val->sym->etype = newIntLink ();
501 tree->opval.val->etype = tree->opval.val->etype;
502 tree->opval.val->type = tree->opval.val->sym->type;
503 werrorfl (tree->filename, tree->lineno, W_IMPLICIT_FUNC,
504 tree->opval.val->sym->name);
505 //tree->opval.val->sym->undefined = 1;
506 allocVariables (tree->opval.val->sym);
510 tree->opval.val->sym->undefined = 1;
511 tree->opval.val->type =
512 tree->opval.val->etype = newIntLink ();
513 tree->opval.val->sym->type =
514 tree->opval.val->sym->etype = newIntLink ();
520 resolveSymbols (tree->left);
521 resolveSymbols (tree->right);
526 /*-----------------------------------------------------------------*/
527 /* setAstLineno - walks a ast tree & sets the line number */
528 /*-----------------------------------------------------------------*/
529 int setAstLineno (ast * tree, int lineno)
534 tree->lineno = lineno;
535 setAstLineno (tree->left, lineno);
536 setAstLineno (tree->right, lineno);
540 /*-----------------------------------------------------------------*/
541 /* funcOfType :- function of type with name */
542 /*-----------------------------------------------------------------*/
544 funcOfType (char *name, sym_link * type, sym_link * argType,
548 /* create the symbol */
549 sym = newSymbol (name, 0);
551 /* setup return value */
552 sym->type = newLink (DECLARATOR);
553 DCL_TYPE (sym->type) = FUNCTION;
554 sym->type->next = copyLinkChain (type);
555 sym->etype = getSpec (sym->type);
556 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
558 /* if arguments required */
562 args = FUNC_ARGS(sym->type) = newValue ();
566 args->type = copyLinkChain (argType);
567 args->etype = getSpec (args->type);
568 SPEC_EXTR(args->etype)=1;
571 args = args->next = newValue ();
578 allocVariables (sym);
583 /*-----------------------------------------------------------------*/
584 /* funcOfTypeVarg :- function of type with name and argtype */
585 /*-----------------------------------------------------------------*/
587 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
592 /* create the symbol */
593 sym = newSymbol (name, 0);
595 /* setup return value */
596 sym->type = newLink (DECLARATOR);
597 DCL_TYPE (sym->type) = FUNCTION;
598 sym->type->next = typeFromStr(rtype);
599 sym->etype = getSpec (sym->type);
601 /* if arguments required */
604 args = FUNC_ARGS(sym->type) = newValue ();
606 for ( i = 0 ; i < nArgs ; i++ ) {
607 args->type = typeFromStr(atypes[i]);
608 args->etype = getSpec (args->type);
609 SPEC_EXTR(args->etype)=1;
610 if ((i + 1) == nArgs) break;
611 args = args->next = newValue ();
618 allocVariables (sym);
623 /*-----------------------------------------------------------------*/
624 /* reverseParms - will reverse a parameter tree */
625 /*-----------------------------------------------------------------*/
627 reverseParms (ast * ptree)
633 /* top down if we find a nonParm tree then quit */
634 if (ptree->type == EX_OP && ptree->opval.op == PARAM && !ptree->reversed)
636 /* The various functions expect the parameter tree to be right heavy. */
637 /* Rotate the tree to be left heavy so that after reversal it is */
638 /* right heavy again. */
639 while ((ttree = ptree->right) && ttree->type == EX_OP &&
640 ttree->opval.op == PARAM)
642 ptree->right = ttree->right;
643 ttree->right = ttree->left;
644 ttree->left = ptree->left;
650 ptree->left = ptree->right;
651 ptree->right = ttree;
653 reverseParms (ptree->left);
654 reverseParms (ptree->right);
660 /*-----------------------------------------------------------------*/
661 /* processParms - makes sure the parameters are okay and do some */
662 /* processing with them */
663 /*-----------------------------------------------------------------*/
665 processParms (ast *func,
668 int *parmNumber, /* unused, although updated */
671 RESULT_TYPE resultType;
674 /* if none of them exist */
675 if (!defParm && !*actParm)
680 if (getenv("DEBUG_SANITY"))
682 fprintf (stderr, "processParms: %s ", defParm->name);
684 /* make sure the type is complete and sane */
685 checkTypeSanity(defParm->etype, defParm->name);
688 if (IS_CODEPTR (func->ftype))
689 functype = func->ftype->next;
691 functype = func->ftype;
693 /* if the function is being called via a pointer & */
694 /* it has not been defined a reentrant then we cannot */
695 /* have parameters */
696 /* PIC16 port can... */
697 if (!TARGET_IS_PIC16)
699 if (func->type != EX_VALUE && !IFFUNC_ISREENT (functype) && !options.stackAuto)
701 werror (W_NONRENT_ARGS);
707 /* if defined parameters ended but actual parameters */
708 /* exist and this is not defined as a variable arg */
709 if (!defParm && *actParm && !IFFUNC_HASVARARGS(functype))
711 werror (E_TOO_MANY_PARMS);
715 /* if defined parameters present but no actual parameters */
716 if (defParm && !*actParm)
718 werror (E_TOO_FEW_PARMS);
722 /* if this is a PARAM node then match left & right */
723 if ((*actParm)->type == EX_OP && (*actParm)->opval.op == PARAM)
725 (*actParm)->decorated = 1;
726 return (processParms (func, defParm,
727 &(*actParm)->left, parmNumber, FALSE) ||
728 processParms (func, defParm ? defParm->next : NULL,
729 &(*actParm)->right, parmNumber, rightmost));
731 else if (defParm) /* not vararg */
733 /* If we have found a value node by following only right-hand links,
734 * then we know that there are no more values after us.
736 * Therefore, if there are more defined parameters, the caller didn't
739 if (rightmost && defParm->next)
741 werror (E_TOO_FEW_PARMS);
746 /* decorate parameter */
747 resultType = defParm ? getResultTypeFromType (defParm->etype) :
749 *actParm = decorateType (*actParm, resultType);
751 if (IS_VOID((*actParm)->ftype))
753 werror (E_VOID_VALUE_USED);
757 /* If this is a varargs function... */
758 if (!defParm && *actParm && IFFUNC_HASVARARGS(functype))
763 if (IS_CAST_OP (*actParm)
764 || (IS_AST_LIT_VALUE (*actParm) && (*actParm)->values.literalFromCast))
766 /* Parameter was explicitly typecast; don't touch it. */
770 ftype = (*actParm)->ftype;
772 /* If it's a char, upcast to int. */
773 if (IS_INTEGRAL (ftype)
774 && (getSize (ftype) < (unsigned) INTSIZE))
776 newType = newAst_LINK(INTTYPE);
779 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
781 newType = newAst_LINK (copyLinkChain(ftype));
782 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
785 if (IS_AGGREGATE (ftype))
787 newType = newAst_LINK (copyLinkChain (ftype));
788 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
793 /* cast required; change this op to a cast. */
794 (*actParm)->decorated = 0;
795 *actParm = newNode (CAST, newType, *actParm);
796 (*actParm)->lineno = (*actParm)->right->lineno;
798 decorateType (*actParm, RESULT_TYPE_NONE);
803 /* if defined parameters ended but actual has not & */
805 if (!defParm && *actParm &&
806 (options.stackAuto || IFFUNC_ISREENT (functype)))
809 resolveSymbols (*actParm);
811 /* the parameter type must be at least castable */
812 if (compareType (defParm->type, (*actParm)->ftype) == 0)
814 werror (E_INCOMPAT_TYPES);
815 printFromToType ((*actParm)->ftype, defParm->type);
819 /* if the parameter is castable then add the cast */
820 if (compareType (defParm->type, (*actParm)->ftype) < 0)
824 resultType = getResultTypeFromType (defParm->etype);
825 pTree = resolveSymbols (copyAst (*actParm));
827 /* now change the current one to a cast */
828 (*actParm)->type = EX_OP;
829 (*actParm)->opval.op = CAST;
830 (*actParm)->left = newAst_LINK (defParm->type);
831 (*actParm)->right = pTree;
832 (*actParm)->decorated = 0; /* force typechecking */
833 decorateType (*actParm, resultType);
836 /* make a copy and change the regparm type to the defined parm */
837 (*actParm)->etype = getSpec ((*actParm)->ftype = copyLinkChain ((*actParm)->ftype));
838 SPEC_REGPARM ((*actParm)->etype) = SPEC_REGPARM (defParm->etype);
839 SPEC_ARGREG ((*actParm)->etype) = SPEC_ARGREG (defParm->etype);
844 /*-----------------------------------------------------------------*/
845 /* createIvalType - generates ival for basic types */
846 /*-----------------------------------------------------------------*/
848 createIvalType (ast * sym, sym_link * type, initList * ilist)
852 /* if initList is deep */
853 if (ilist->type == INIT_DEEP)
854 ilist = ilist->init.deep;
856 iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
857 return decorateType (newNode ('=', sym, iExpr), RESULT_TYPE_NONE);
860 /*-----------------------------------------------------------------*/
861 /* createIvalStruct - generates initial value for structures */
862 /*-----------------------------------------------------------------*/
864 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
871 sflds = SPEC_STRUCT (type)->fields;
872 if (ilist->type != INIT_DEEP)
874 werror (E_INIT_STRUCT, "");
878 iloop = ilist->init.deep;
880 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
882 /* if we have come to end */
886 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
887 lAst = decorateType (resolveSymbols (lAst), RESULT_TYPE_NONE);
888 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)), RESULT_TYPE_NONE);
892 werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
893 W_EXCESS_INITIALIZERS, "struct",
894 sym->opval.val->sym->name);
901 /*-----------------------------------------------------------------*/
902 /* createIvalArray - generates code for array initialization */
903 /*-----------------------------------------------------------------*/
905 createIvalArray (ast * sym, sym_link * type, initList * ilist)
909 int lcnt = 0, size = 0;
910 literalList *literalL;
912 /* take care of the special case */
913 /* array of characters can be init */
915 if (IS_CHAR (type->next))
916 if ((rast = createIvalCharPtr (sym,
918 decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE))))
920 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
922 /* not the special case */
923 if (ilist->type != INIT_DEEP)
925 werror (E_INIT_STRUCT, "");
929 iloop = ilist->init.deep;
930 lcnt = DCL_ELEM (type);
932 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
936 aSym = decorateType (resolveSymbols(sym), RESULT_TYPE_NONE);
938 rast = newNode(ARRAYINIT, aSym, NULL);
939 rast->values.constlist = literalL;
941 // Make sure size is set to length of initializer list.
948 if (lcnt && size > lcnt)
950 // Array size was specified, and we have more initializers than needed.
951 char *name=sym->opval.val->sym->name;
952 int lineno=sym->opval.val->sym->lineDef;
953 char *filename=sym->opval.val->sym->fileDef;
955 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
964 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
965 aSym = decorateType (resolveSymbols (aSym), RESULT_TYPE_NONE);
966 rast = createIval (aSym, type->next, iloop, rast);
967 iloop = (iloop ? iloop->next : NULL);
973 /* no of elements given and we */
974 /* have generated for all of them */
977 // is this a better way? at least it won't crash
978 char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
979 int lineno = iloop->lineno;
980 char *filename = iloop->filename;
981 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
988 /* if we have not been given a size */
989 if (!DCL_ELEM (type))
991 /* but this still updates the typedef instead of the instance ! see bug 770487 */
992 DCL_ELEM (type) = size;
995 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
999 /*-----------------------------------------------------------------*/
1000 /* createIvalCharPtr - generates initial values for char pointers */
1001 /*-----------------------------------------------------------------*/
1003 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
1007 /* if this is a pointer & right is a literal array then */
1008 /* just assignment will do */
1009 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
1010 SPEC_SCLS (iexpr->etype) == S_CODE)
1011 && IS_ARRAY (iexpr->ftype)))
1012 return newNode ('=', sym, iexpr);
1014 /* left side is an array so we have to assign each */
1016 if ((IS_LITERAL (iexpr->etype) ||
1017 SPEC_SCLS (iexpr->etype) == S_CODE)
1018 && IS_ARRAY (iexpr->ftype))
1020 /* for each character generate an assignment */
1021 /* to the array element */
1022 char *s = SPEC_CVAL (iexpr->etype).v_char;
1024 int size = getSize (iexpr->ftype);
1025 int symsize = getSize (type);
1029 if (size>(symsize+1))
1030 werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1031 "string", sym->opval.val->sym->name);
1035 for (i=0;i<size;i++)
1037 rast = newNode (NULLOP,
1041 newAst_VALUE (valueFromLit ((float) i))),
1042 newAst_VALUE (valueFromLit (*s))));
1046 // now WE don't need iexpr's symbol anymore
1047 freeStringSymbol(AST_SYMBOL(iexpr));
1049 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1055 /*-----------------------------------------------------------------*/
1056 /* createIvalPtr - generates initial value for pointers */
1057 /*-----------------------------------------------------------------*/
1059 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
1065 if (ilist->type == INIT_DEEP)
1066 ilist = ilist->init.deep;
1068 iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
1070 /* if character pointer */
1071 if (IS_CHAR (type->next))
1072 if ((rast = createIvalCharPtr (sym, type, iexpr)))
1075 return newNode ('=', sym, iexpr);
1078 /*-----------------------------------------------------------------*/
1079 /* createIval - generates code for initial value */
1080 /*-----------------------------------------------------------------*/
1082 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1089 /* if structure then */
1090 if (IS_STRUCT (type))
1091 rast = createIvalStruct (sym, type, ilist);
1093 /* if this is a pointer */
1095 rast = createIvalPtr (sym, type, ilist);
1097 /* if this is an array */
1098 if (IS_ARRAY (type))
1099 rast = createIvalArray (sym, type, ilist);
1101 /* if type is SPECIFIER */
1103 rast = createIvalType (sym, type, ilist);
1106 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_TYPE_NONE);
1108 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1111 /*-----------------------------------------------------------------*/
1112 /* initAggregates - initialises aggregate variables with initv */
1113 /*-----------------------------------------------------------------*/
1114 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1115 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1118 /*-----------------------------------------------------------------*/
1119 /* gatherAutoInit - creates assignment expressions for initial */
1121 /*-----------------------------------------------------------------*/
1123 gatherAutoInit (symbol * autoChain)
1130 for (sym = autoChain; sym; sym = sym->next)
1133 /* resolve the symbols in the ival */
1135 resolveIvalSym (sym->ival, sym->type);
1138 /* if we are PIC16 port,
1139 * and this is a static,
1140 * and have initial value,
1141 * and not S_CODE, don't emit in gs segment,
1142 * but allow glue.c:pic16emitRegularMap to put symbol
1143 * in idata section */
1144 if(TARGET_IS_PIC16 &&
1145 IS_STATIC (sym->etype) && sym->ival
1146 && SPEC_SCLS(sym->etype) != S_CODE) {
1147 SPEC_SCLS (sym->etype) = S_DATA;
1152 /* if this is a static variable & has an */
1153 /* initial value the code needs to be lifted */
1154 /* here to the main portion since they can be */
1155 /* initialised only once at the start */
1156 if (IS_STATIC (sym->etype) && sym->ival &&
1157 SPEC_SCLS (sym->etype) != S_CODE)
1161 /* insert the symbol into the symbol table */
1162 /* with level = 0 & name = rname */
1163 newSym = copySymbol (sym);
1164 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1166 /* now lift the code to main */
1167 if (IS_AGGREGATE (sym->type)) {
1168 work = initAggregates (sym, sym->ival, NULL);
1170 if (getNelements(sym->type, sym->ival)>1) {
1171 werrorfl (sym->fileDef, sym->lineDef,
1172 W_EXCESS_INITIALIZERS, "scalar",
1175 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1176 list2expr (sym->ival));
1179 setAstLineno (work, sym->lineDef);
1183 staticAutos = newNode (NULLOP, staticAutos, work);
1190 /* if there is an initial value */
1191 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1193 initList *ilist=sym->ival;
1195 while (ilist->type == INIT_DEEP) {
1196 ilist = ilist->init.deep;
1199 /* update lineno for error msg */
1200 lineno=sym->lineDef;
1201 setAstLineno (ilist->init.node, lineno);
1203 if (IS_AGGREGATE (sym->type)) {
1204 work = initAggregates (sym, sym->ival, NULL);
1206 if (getNelements(sym->type, sym->ival)>1) {
1207 werrorfl (sym->fileDef, sym->lineDef,
1208 W_EXCESS_INITIALIZERS, "scalar",
1211 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1212 list2expr (sym->ival));
1216 setAstLineno (work, sym->lineDef);
1220 init = newNode (NULLOP, init, work);
1229 /*-----------------------------------------------------------------*/
1230 /* freeStringSymbol - delete a literal string if no more usage */
1231 /*-----------------------------------------------------------------*/
1232 void freeStringSymbol(symbol *sym) {
1233 /* make sure this is a literal string */
1234 assert (sym->isstrlit);
1235 if (--sym->isstrlit == 0) { // lower the usage count
1236 memmap *segment=SPEC_OCLS(sym->etype);
1238 deleteSetItem(&segment->syms, sym);
1243 /*-----------------------------------------------------------------*/
1244 /* stringToSymbol - creates a symbol from a literal string */
1245 /*-----------------------------------------------------------------*/
1247 stringToSymbol (value * val)
1249 char name[SDCC_NAME_MAX + 1];
1250 static int charLbl = 0;
1255 // have we heard this before?
1256 for (sp=statsg->syms; sp; sp=sp->next) {
1258 size = getSize (sym->type);
1259 if (sym->isstrlit && size == getSize (val->type) &&
1260 !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1261 // yes, this is old news. Don't publish it again.
1262 sym->isstrlit++; // but raise the usage count
1263 return symbolVal(sym);
1267 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1268 sym = newSymbol (name, 0); /* make it @ level 0 */
1269 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1271 /* copy the type from the value passed */
1272 sym->type = copyLinkChain (val->type);
1273 sym->etype = getSpec (sym->type);
1274 /* change to storage class & output class */
1275 SPEC_SCLS (sym->etype) = S_CODE;
1276 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1277 SPEC_STAT (sym->etype) = 1;
1278 /* make the level & block = 0 */
1279 sym->block = sym->level = 0;
1281 /* create an ival */
1282 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1287 allocVariables (sym);
1290 return symbolVal (sym);
1294 /*-----------------------------------------------------------------*/
1295 /* processBlockVars - will go thru the ast looking for block if */
1296 /* a block is found then will allocate the syms */
1297 /* will also gather the auto inits present */
1298 /*-----------------------------------------------------------------*/
1300 processBlockVars (ast * tree, int *stack, int action)
1305 /* if this is a block */
1306 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1310 if (action == ALLOCATE)
1312 *stack += allocVariables (tree->values.sym);
1313 autoInit = gatherAutoInit (tree->values.sym);
1315 /* if there are auto inits then do them */
1317 tree->left = newNode (NULLOP, autoInit, tree->left);
1319 else /* action is deallocate */
1320 deallocLocal (tree->values.sym);
1323 processBlockVars (tree->left, stack, action);
1324 processBlockVars (tree->right, stack, action);
1329 /*-------------------------------------------------------------*/
1330 /* constExprTree - returns TRUE if this tree is a constant */
1332 /*-------------------------------------------------------------*/
1333 bool constExprTree (ast *cexpr) {
1339 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1341 switch (cexpr->type)
1344 if (IS_AST_LIT_VALUE(cexpr)) {
1345 // this is a literal
1348 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1349 // a function's address will never change
1352 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1353 // an array's address will never change
1356 if (IS_AST_SYM_VALUE(cexpr) &&
1357 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1358 // a symbol in code space will never change
1359 // This is only for the 'char *s="hallo"' case and will have to leave
1360 //printf(" code space symbol");
1365 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1366 "unexpected link in expression tree\n");
1369 if (cexpr->opval.op==ARRAYINIT) {
1370 // this is a list of literals
1373 if (cexpr->opval.op=='=') {
1374 return constExprTree(cexpr->right);
1376 if (cexpr->opval.op==CAST) {
1377 // cast ignored, maybe we should throw a warning here?
1378 return constExprTree(cexpr->right);
1380 if (cexpr->opval.op=='&') {
1383 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1386 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1391 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1396 /*-----------------------------------------------------------------*/
1397 /* constExprValue - returns the value of a constant expression */
1398 /* or NULL if it is not a constant expression */
1399 /*-----------------------------------------------------------------*/
1401 constExprValue (ast * cexpr, int check)
1403 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1405 /* if this is not a constant then */
1406 if (!IS_LITERAL (cexpr->ftype))
1408 /* then check if this is a literal array
1410 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1411 SPEC_CVAL (cexpr->etype).v_char &&
1412 IS_ARRAY (cexpr->ftype))
1414 value *val = valFromType (cexpr->ftype);
1415 SPEC_SCLS (val->etype) = S_LITERAL;
1416 val->sym = cexpr->opval.val->sym;
1417 val->sym->type = copyLinkChain (cexpr->ftype);
1418 val->sym->etype = getSpec (val->sym->type);
1419 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1423 /* if we are casting a literal value then */
1424 if (IS_AST_OP (cexpr) &&
1425 cexpr->opval.op == CAST &&
1426 IS_LITERAL (cexpr->right->ftype))
1428 return valCastLiteral (cexpr->ftype,
1429 floatFromVal (cexpr->right->opval.val));
1432 if (IS_AST_VALUE (cexpr))
1434 return cexpr->opval.val;
1438 werror (E_CONST_EXPECTED, "found expression");
1443 /* return the value */
1444 return cexpr->opval.val;
1448 /*-----------------------------------------------------------------*/
1449 /* isLabelInAst - will return true if a given label is found */
1450 /*-----------------------------------------------------------------*/
1452 isLabelInAst (symbol * label, ast * tree)
1454 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1457 if (IS_AST_OP (tree) &&
1458 tree->opval.op == LABEL &&
1459 isSymbolEqual (AST_SYMBOL (tree->left), label))
1462 return isLabelInAst (label, tree->right) &&
1463 isLabelInAst (label, tree->left);
1467 /*-----------------------------------------------------------------*/
1468 /* isLoopCountable - return true if the loop count can be determi- */
1469 /* -ned at compile time . */
1470 /*-----------------------------------------------------------------*/
1472 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1473 symbol ** sym, ast ** init, ast ** end)
1476 /* the loop is considered countable if the following
1477 conditions are true :-
1479 a) initExpr :- <sym> = <const>
1480 b) condExpr :- <sym> < <const1>
1481 c) loopExpr :- <sym> ++
1484 /* first check the initExpr */
1485 if (IS_AST_OP (initExpr) &&
1486 initExpr->opval.op == '=' && /* is assignment */
1487 IS_AST_SYM_VALUE (initExpr->left))
1488 { /* left is a symbol */
1490 *sym = AST_SYMBOL (initExpr->left);
1491 *init = initExpr->right;
1496 /* for now the symbol has to be of
1498 if (!IS_INTEGRAL ((*sym)->type))
1501 /* now check condExpr */
1502 if (IS_AST_OP (condExpr))
1505 switch (condExpr->opval.op)
1508 if (IS_AST_SYM_VALUE (condExpr->left) &&
1509 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1510 IS_AST_LIT_VALUE (condExpr->right))
1512 *end = condExpr->right;
1518 if (IS_AST_OP (condExpr->left) &&
1519 condExpr->left->opval.op == '>' &&
1520 IS_AST_LIT_VALUE (condExpr->left->right) &&
1521 IS_AST_SYM_VALUE (condExpr->left->left) &&
1522 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1525 *end = newNode ('+', condExpr->left->right,
1526 newAst_VALUE (constVal ("1")));
1539 /* check loop expression is of the form <sym>++ */
1540 if (!IS_AST_OP (loopExpr))
1543 /* check if <sym> ++ */
1544 if (loopExpr->opval.op == INC_OP)
1550 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1551 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1558 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1559 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1567 if (loopExpr->opval.op == ADD_ASSIGN)
1570 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1571 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1572 IS_AST_LIT_VALUE (loopExpr->right) &&
1573 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1581 /*-----------------------------------------------------------------*/
1582 /* astHasVolatile - returns true if ast contains any volatile */
1583 /*-----------------------------------------------------------------*/
1585 astHasVolatile (ast * tree)
1590 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1593 if (IS_AST_OP (tree))
1594 return astHasVolatile (tree->left) ||
1595 astHasVolatile (tree->right);
1600 /*-----------------------------------------------------------------*/
1601 /* astHasPointer - return true if the ast contains any ptr variable */
1602 /*-----------------------------------------------------------------*/
1604 astHasPointer (ast * tree)
1609 if (IS_AST_LINK (tree))
1612 /* if we hit an array expression then check
1613 only the left side */
1614 if (IS_AST_OP (tree) && tree->opval.op == '[')
1615 return astHasPointer (tree->left);
1617 if (IS_AST_VALUE (tree))
1618 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1620 return astHasPointer (tree->left) ||
1621 astHasPointer (tree->right);
1625 /*-----------------------------------------------------------------*/
1626 /* astHasSymbol - return true if the ast has the given symbol */
1627 /*-----------------------------------------------------------------*/
1629 astHasSymbol (ast * tree, symbol * sym)
1631 if (!tree || IS_AST_LINK (tree))
1634 if (IS_AST_VALUE (tree))
1636 if (IS_AST_SYM_VALUE (tree))
1637 return isSymbolEqual (AST_SYMBOL (tree), sym);
1642 return astHasSymbol (tree->left, sym) ||
1643 astHasSymbol (tree->right, sym);
1646 /*-----------------------------------------------------------------*/
1647 /* astHasDeref - return true if the ast has an indirect access */
1648 /*-----------------------------------------------------------------*/
1650 astHasDeref (ast * tree)
1652 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1655 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1657 return astHasDeref (tree->left) || astHasDeref (tree->right);
1660 /*-----------------------------------------------------------------*/
1661 /* isConformingBody - the loop body has to conform to a set of rules */
1662 /* for the loop to be considered reversible read on for rules */
1663 /*-----------------------------------------------------------------*/
1665 isConformingBody (ast * pbody, symbol * sym, ast * body)
1668 /* we are going to do a pre-order traversal of the
1669 tree && check for the following conditions. (essentially
1670 a set of very shallow tests )
1671 a) the sym passed does not participate in
1672 any arithmetic operation
1673 b) There are no function calls
1674 c) all jumps are within the body
1675 d) address of loop control variable not taken
1676 e) if an assignment has a pointer on the
1677 left hand side make sure right does not have
1678 loop control variable */
1680 /* if we reach the end or a leaf then true */
1681 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1684 /* if anything else is "volatile" */
1685 if (IS_VOLATILE (TETYPE (pbody)))
1688 /* we will walk the body in a pre-order traversal for
1690 switch (pbody->opval.op)
1692 /*------------------------------------------------------------------*/
1694 // if the loopvar is used as an index
1695 /* array op is commutative -- must check both left & right */
1696 if (astHasSymbol(pbody->right, sym) || astHasSymbol(pbody->left, sym)) {
1699 return isConformingBody (pbody->right, sym, body)
1700 && isConformingBody (pbody->left, sym, body);
1702 /*------------------------------------------------------------------*/
1707 /*------------------------------------------------------------------*/
1711 /* sure we are not sym is not modified */
1713 IS_AST_SYM_VALUE (pbody->left) &&
1714 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1718 IS_AST_SYM_VALUE (pbody->right) &&
1719 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1724 /*------------------------------------------------------------------*/
1726 case '*': /* can be unary : if right is null then unary operation */
1731 /* if right is NULL then unary operation */
1732 /*------------------------------------------------------------------*/
1733 /*----------------------------*/
1735 /*----------------------------*/
1738 if (IS_AST_SYM_VALUE (pbody->left) &&
1739 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1742 return isConformingBody (pbody->left, sym, body);
1746 if (astHasSymbol (pbody->left, sym) ||
1747 astHasSymbol (pbody->right, sym))
1752 /*------------------------------------------------------------------*/
1760 if (IS_AST_SYM_VALUE (pbody->left) &&
1761 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1764 if (IS_AST_SYM_VALUE (pbody->right) &&
1765 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1768 return isConformingBody (pbody->left, sym, body) &&
1769 isConformingBody (pbody->right, sym, body);
1777 if (IS_AST_SYM_VALUE (pbody->left) &&
1778 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1780 return isConformingBody (pbody->left, sym, body);
1782 /*------------------------------------------------------------------*/
1794 case SIZEOF: /* evaluate wihout code generation */
1796 if (IS_AST_SYM_VALUE (pbody->left) &&
1797 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1800 if (IS_AST_SYM_VALUE (pbody->right) &&
1801 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1804 return isConformingBody (pbody->left, sym, body) &&
1805 isConformingBody (pbody->right, sym, body);
1807 /*------------------------------------------------------------------*/
1810 /* if left has a pointer & right has loop
1811 control variable then we cannot */
1812 if (astHasPointer (pbody->left) &&
1813 astHasSymbol (pbody->right, sym))
1815 if (astHasVolatile (pbody->left))
1818 if (IS_AST_SYM_VALUE (pbody->left)) {
1819 // if the loopvar has an assignment
1820 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1822 // if the loopvar is used in another (maybe conditional) block
1823 if (astHasSymbol (pbody->right, sym) &&
1824 (pbody->level >= body->level)) {
1829 if (astHasVolatile (pbody->left))
1832 if (astHasDeref(pbody->right)) return FALSE;
1834 return isConformingBody (pbody->left, sym, body) &&
1835 isConformingBody (pbody->right, sym, body);
1846 assert ("Parser should not have generated this\n");
1848 /*------------------------------------------------------------------*/
1849 /*----------------------------*/
1850 /* comma operator */
1851 /*----------------------------*/
1853 return isConformingBody (pbody->left, sym, body) &&
1854 isConformingBody (pbody->right, sym, body);
1856 /*------------------------------------------------------------------*/
1857 /*----------------------------*/
1859 /*----------------------------*/
1861 /* if local & not passed as paramater then ok */
1862 if (sym->level && !astHasSymbol(pbody->right,sym))
1866 /*------------------------------------------------------------------*/
1867 /*----------------------------*/
1868 /* return statement */
1869 /*----------------------------*/
1874 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1879 if (astHasSymbol (pbody->left, sym))
1886 return isConformingBody (pbody->left, sym, body) &&
1887 isConformingBody (pbody->right, sym, body);
1893 /*-----------------------------------------------------------------*/
1894 /* isLoopReversible - takes a for loop as input && returns true */
1895 /* if the for loop is reversible. If yes will set the value of */
1896 /* the loop control var & init value & termination value */
1897 /*-----------------------------------------------------------------*/
1899 isLoopReversible (ast * loop, symbol ** loopCntrl,
1900 ast ** init, ast ** end)
1902 /* if option says don't do it then don't */
1903 if (optimize.noLoopReverse)
1905 /* there are several tests to determine this */
1907 /* for loop has to be of the form
1908 for ( <sym> = <const1> ;
1909 [<sym> < <const2>] ;
1910 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1912 if (!isLoopCountable (AST_FOR (loop, initExpr),
1913 AST_FOR (loop, condExpr),
1914 AST_FOR (loop, loopExpr),
1915 loopCntrl, init, end))
1918 /* now do some serious checking on the body of the loop
1921 return isConformingBody (loop->left, *loopCntrl, loop->left);
1925 /*-----------------------------------------------------------------*/
1926 /* replLoopSym - replace the loop sym by loop sym -1 */
1927 /*-----------------------------------------------------------------*/
1929 replLoopSym (ast * body, symbol * sym)
1932 if (!body || IS_AST_LINK (body))
1935 if (IS_AST_SYM_VALUE (body))
1938 if (isSymbolEqual (AST_SYMBOL (body), sym))
1942 body->opval.op = '-';
1943 body->left = newAst_VALUE (symbolVal (sym));
1944 body->right = newAst_VALUE (constVal ("1"));
1952 replLoopSym (body->left, sym);
1953 replLoopSym (body->right, sym);
1957 /*-----------------------------------------------------------------*/
1958 /* reverseLoop - do the actual loop reversal */
1959 /*-----------------------------------------------------------------*/
1961 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1965 /* create the following tree
1970 if (sym) goto for_continue ;
1973 /* put it together piece by piece */
1974 rloop = newNode (NULLOP,
1975 createIf (newAst_VALUE (symbolVal (sym)),
1977 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1980 newAst_VALUE (symbolVal (sym)),
1983 replLoopSym (loop->left, sym);
1984 setAstLineno (rloop, init->lineno);
1986 rloop = newNode (NULLOP,
1988 newAst_VALUE (symbolVal (sym)),
1989 newNode ('-', end, init)),
1990 createLabel (AST_FOR (loop, continueLabel),
1994 newNode (SUB_ASSIGN,
1995 newAst_VALUE (symbolVal (sym)),
1996 newAst_VALUE (constVal ("1"))),
1999 rloop->lineno=init->lineno;
2000 return decorateType (rloop, RESULT_TYPE_NONE);
2004 /*-----------------------------------------------------------------*/
2005 /* searchLitOp - search tree (*ops only) for an ast with literal */
2006 /*-----------------------------------------------------------------*/
2008 searchLitOp (ast *tree, ast **parent, const unsigned char *ops)
2012 if (tree && optimize.global_cse)
2014 /* is there a literal operand? */
2016 IS_AST_OP(tree->right) &&
2017 tree->right->right &&
2018 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
2020 if (IS_LITERAL (RTYPE (tree->right)) !=
2021 IS_LITERAL (LTYPE (tree->right)))
2023 tree->right->decorated = 0;
2024 tree->decorated = 0;
2028 ret = searchLitOp (tree->right, parent, ops);
2033 IS_AST_OP(tree->left) &&
2034 tree->left->right &&
2035 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
2037 if (IS_LITERAL (RTYPE (tree->left)) !=
2038 IS_LITERAL (LTYPE (tree->left)))
2040 tree->left->decorated = 0;
2041 tree->decorated = 0;
2045 ret = searchLitOp (tree->left, parent, ops);
2053 /*-----------------------------------------------------------------*/
2054 /* getResultFromType */
2055 /*-----------------------------------------------------------------*/
2057 getResultTypeFromType (sym_link *type)
2059 /* type = getSpec (type); */
2061 return RESULT_TYPE_BIT;
2062 if (IS_BITFIELD (type))
2064 int blen = SPEC_BLEN (type);
2067 return RESULT_TYPE_BIT;
2069 return RESULT_TYPE_CHAR;
2070 return RESULT_TYPE_INT;
2073 return RESULT_TYPE_CHAR;
2076 return RESULT_TYPE_INT;
2077 return RESULT_TYPE_OTHER;
2080 /*-----------------------------------------------------------------*/
2081 /* addCast - adds casts to a type specified by RESULT_TYPE */
2082 /*-----------------------------------------------------------------*/
2084 addCast (ast *tree, RESULT_TYPE resultType, bool upcast)
2087 bool upCasted = FALSE;
2091 case RESULT_TYPE_NONE:
2092 /* char: promote to int */
2094 getSize (tree->etype) >= INTSIZE)
2096 newLink = newIntLink();
2099 case RESULT_TYPE_CHAR:
2100 if (IS_CHAR (tree->etype) ||
2101 IS_FLOAT(tree->etype))
2103 newLink = newCharLink();
2105 case RESULT_TYPE_INT:
2107 if (getSize (tree->etype) > INTSIZE)
2109 /* warn ("Loosing significant digits"); */
2113 /* char: promote to int */
2115 getSize (tree->etype) >= INTSIZE)
2117 newLink = newIntLink();
2120 case RESULT_TYPE_OTHER:
2123 /* return type is long, float: promote char to int */
2124 if (getSize (tree->etype) >= INTSIZE)
2126 newLink = newIntLink();
2132 tree->decorated = 0;
2133 tree = newNode (CAST, newAst_LINK (newLink), tree);
2134 tree->lineno = tree->right->lineno;
2135 /* keep unsigned type during cast to smaller type,
2136 but not when promoting from char to int */
2138 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2139 return decorateType (tree, resultType);
2142 /*-----------------------------------------------------------------*/
2143 /* resultTypePropagate - decides if resultType can be propagated */
2144 /*-----------------------------------------------------------------*/
2146 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2148 switch (tree->opval.op)
2164 return RESULT_TYPE_NONE;
2168 return RESULT_TYPE_IFX;
2170 return RESULT_TYPE_NONE;
2174 /*-----------------------------------------------------------------*/
2175 /* getLeftResultType - gets type from left branch for propagation */
2176 /*-----------------------------------------------------------------*/
2178 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2180 switch (tree->opval.op)
2184 if (IS_PTR (LTYPE (tree)))
2185 return RESULT_TYPE_NONE;
2187 return getResultTypeFromType (LETYPE (tree));
2189 if (IS_PTR (currFunc->type->next))
2190 return RESULT_TYPE_NONE;
2192 return getResultTypeFromType (currFunc->type->next);
2194 if (!IS_ARRAY (LTYPE (tree)))
2196 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256)
2197 return RESULT_TYPE_CHAR;
2204 /*--------------------------------------------------------------------*/
2205 /* decorateType - compute type for this tree, also does type checking.*/
2206 /* This is done bottom up, since type has to flow upwards. */
2207 /* resultType flows top-down and forces e.g. char-arithmetik, if the */
2208 /* result is a char and the operand(s) are int's. */
2209 /* It also does constant folding, and parameter checking. */
2210 /*--------------------------------------------------------------------*/
2212 decorateType (ast * tree, RESULT_TYPE resultType)
2216 RESULT_TYPE resultTypeProp;
2221 /* if already has type then do nothing */
2222 if (tree->decorated)
2225 tree->decorated = 1;
2228 /* print the line */
2229 /* if not block & function */
2230 if (tree->type == EX_OP &&
2231 (tree->opval.op != FUNCTION &&
2232 tree->opval.op != BLOCK &&
2233 tree->opval.op != NULLOP))
2235 filename = tree->filename;
2236 lineno = tree->lineno;
2240 /* if any child is an error | this one is an error do nothing */
2241 if (tree->isError ||
2242 (tree->left && tree->left->isError) ||
2243 (tree->right && tree->right->isError))
2246 /*------------------------------------------------------------------*/
2247 /*----------------------------*/
2248 /* leaf has been reached */
2249 /*----------------------------*/
2250 lineno=tree->lineno;
2251 /* if this is of type value */
2252 /* just get the type */
2253 if (tree->type == EX_VALUE)
2256 if (IS_LITERAL (tree->opval.val->etype))
2259 /* if this is a character array then declare it */
2260 if (IS_ARRAY (tree->opval.val->type))
2261 tree->opval.val = stringToSymbol (tree->opval.val);
2263 /* otherwise just copy the type information */
2264 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2268 if (tree->opval.val->sym)
2270 /* if the undefined flag is set then give error message */
2271 if (tree->opval.val->sym->undefined)
2273 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2275 TTYPE (tree) = TETYPE (tree) =
2276 tree->opval.val->type = tree->opval.val->sym->type =
2277 tree->opval.val->etype = tree->opval.val->sym->etype =
2278 copyLinkChain (INTTYPE);
2283 /* if impilicit i.e. struct/union member then no type */
2284 if (tree->opval.val->sym->implicit)
2285 TTYPE (tree) = TETYPE (tree) = NULL;
2290 /* else copy the type */
2291 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2293 /* and mark it as referenced */
2294 tree->opval.val->sym->isref = 1;
2302 /* if type link for the case of cast */
2303 if (tree->type == EX_LINK)
2305 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2313 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2315 if (tree->left && tree->left->type == EX_OPERAND
2316 && (tree->left->opval.op == INC_OP
2317 || tree->left->opval.op == DEC_OP)
2318 && tree->left->left)
2320 tree->left->right = tree->left->left;
2321 tree->left->left = NULL;
2323 if (tree->right && tree->right->type == EX_OPERAND
2324 && (tree->right->opval.op == INC_OP
2325 || tree->right->opval.op == DEC_OP)
2326 && tree->right->left)
2328 tree->right->right = tree->right->left;
2329 tree->right->left = NULL;
2334 /* Before decorating the left branch we've to decide in dependence
2335 upon tree->opval.op, if resultType can be propagated */
2336 resultTypeProp = resultTypePropagate (tree, resultType);
2338 if (tree->opval.op == '?')
2339 dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2341 dtl = decorateType (tree->left, resultTypeProp);
2343 /* if an array node, we may need to swap branches */
2344 if (tree->opval.op == '[')
2346 /* determine which is the array & which the index */
2347 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2348 IS_INTEGRAL (LTYPE (tree)))
2350 ast *tempTree = tree->left;
2351 tree->left = tree->right;
2352 tree->right = tempTree;
2356 /* After decorating the left branch there's type information available
2357 in tree->left->?type. If the op is e.g. '=' we extract the type
2358 information from there and propagate it to the right branch. */
2359 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2361 switch (tree->opval.op)
2364 /* delay right side for '?' operator since conditional macro
2365 expansions might rely on this */
2369 /* decorate right side for CALL (parameter list) in processParms();
2370 there is resultType available */
2374 dtr = decorateType (tree->right, resultTypeProp);
2378 /* this is to take care of situations
2379 when the tree gets rewritten */
2380 if (dtl != tree->left)
2382 if (dtr != tree->right)
2384 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2388 /* depending on type of operator do */
2390 switch (tree->opval.op)
2392 /*------------------------------------------------------------------*/
2393 /*----------------------------*/
2395 /*----------------------------*/
2398 /* first check if this is a array or a pointer */
2399 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2401 werror (E_NEED_ARRAY_PTR, "[]");
2402 goto errorTreeReturn;
2405 /* check if the type of the idx */
2406 if (!IS_INTEGRAL (RTYPE (tree)))
2408 werror (E_IDX_NOT_INT);
2409 goto errorTreeReturn;
2412 /* if the left is an rvalue then error */
2415 werror (E_LVALUE_REQUIRED, "array access");
2416 goto errorTreeReturn;
2419 if (IS_LITERAL (RTYPE (tree)))
2421 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2422 int arraySize = DCL_ELEM (LTYPE (tree));
2423 if (arraySize && arrayIndex >= arraySize)
2425 werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2430 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2433 /*------------------------------------------------------------------*/
2434 /*----------------------------*/
2436 /*----------------------------*/
2438 /* if this is not a structure */
2439 if (!IS_STRUCT (LTYPE (tree)))
2441 werror (E_STRUCT_UNION, ".");
2442 goto errorTreeReturn;
2444 TTYPE (tree) = structElemType (LTYPE (tree),
2445 (tree->right->type == EX_VALUE ?
2446 tree->right->opval.val : NULL));
2447 TETYPE (tree) = getSpec (TTYPE (tree));
2450 /*------------------------------------------------------------------*/
2451 /*----------------------------*/
2452 /* struct/union pointer */
2453 /*----------------------------*/
2455 /* if not pointer to a structure */
2456 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2458 werror (E_PTR_REQD);
2459 goto errorTreeReturn;
2462 if (!IS_STRUCT (LTYPE (tree)->next))
2464 werror (E_STRUCT_UNION, "->");
2465 goto errorTreeReturn;
2468 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2469 (tree->right->type == EX_VALUE ?
2470 tree->right->opval.val : NULL));
2471 TETYPE (tree) = getSpec (TTYPE (tree));
2473 /* adjust the storage class */
2474 switch (DCL_TYPE(tree->left->ftype)) {
2476 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2479 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2482 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2485 SPEC_SCLS (TETYPE (tree)) = 0;
2488 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2491 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2494 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2497 SPEC_SCLS (TETYPE (tree)) = 0;
2504 /* This breaks with extern declarations, bitfields, and perhaps other */
2505 /* cases (gcse). Let's leave this optimization disabled for now and */
2506 /* ponder if there's a safe way to do this. -- EEP */
2508 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2509 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2511 /* If defined struct type at addr var
2512 then rewrite (&struct var)->member
2514 and define membertype at (addr+offsetof(struct var,member)) temp
2517 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2518 AST_SYMBOL(tree->right));
2520 sym = newSymbol(genSymName (0), 0);
2521 sym->type = TTYPE (tree);
2522 sym->etype = getSpec(sym->type);
2523 sym->lineDef = tree->lineno;
2526 SPEC_STAT (sym->etype) = 1;
2527 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2529 SPEC_ABSA(sym->etype) = 1;
2530 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2533 AST_VALUE (tree) = symbolVal(sym);
2536 tree->type = EX_VALUE;
2544 /*------------------------------------------------------------------*/
2545 /*----------------------------*/
2546 /* ++/-- operation */
2547 /*----------------------------*/
2551 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2552 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2553 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2554 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2563 /*------------------------------------------------------------------*/
2564 /*----------------------------*/
2566 /*----------------------------*/
2567 case '&': /* can be unary */
2568 /* if right is NULL then unary operation */
2569 if (tree->right) /* not an unary operation */
2572 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2574 werror (E_BITWISE_OP);
2575 werror (W_CONTINUE, "left & right types are ");
2576 printTypeChain (LTYPE (tree), stderr);
2577 fprintf (stderr, ",");
2578 printTypeChain (RTYPE (tree), stderr);
2579 fprintf (stderr, "\n");
2580 goto errorTreeReturn;
2583 /* if they are both literal */
2584 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2586 tree->type = EX_VALUE;
2587 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2588 valFromType (RETYPE (tree)), '&');
2590 tree->right = tree->left = NULL;
2591 TETYPE (tree) = tree->opval.val->etype;
2592 TTYPE (tree) = tree->opval.val->type;
2596 /* see if this is a GETHBIT operation if yes
2599 ast *otree = optimizeGetHbit (tree);
2602 return decorateType (otree, RESULT_TYPE_NONE);
2605 /* if left is a literal exchange left & right */
2606 if (IS_LITERAL (LTYPE (tree)))
2608 ast *tTree = tree->left;
2609 tree->left = tree->right;
2610 tree->right = tTree;
2613 /* if right is a literal and */
2614 /* we can find a 2nd literal in an and-tree then */
2615 /* rearrange the tree */
2616 if (IS_LITERAL (RTYPE (tree)))
2619 ast *litTree = searchLitOp (tree, &parent, "&");
2623 ast *tTree = litTree->left;
2624 litTree->left = tree->right;
2625 tree->right = tTree;
2626 /* both operands in litTree are literal now */
2627 decorateType (parent, resultType);
2631 LRVAL (tree) = RRVAL (tree) = 1;
2633 TTYPE (tree) = computeType (LTYPE (tree),
2637 TETYPE (tree) = getSpec (TTYPE (tree));
2642 /*------------------------------------------------------------------*/
2643 /*----------------------------*/
2645 /*----------------------------*/
2646 p = newLink (DECLARATOR);
2647 /* if bit field then error */
2648 if (IS_BITVAR (tree->left->etype))
2650 werror (E_ILLEGAL_ADDR, "address of bit variable");
2651 goto errorTreeReturn;
2654 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2656 werror (E_ILLEGAL_ADDR, "address of register variable");
2657 goto errorTreeReturn;
2660 if (IS_FUNC (LTYPE (tree)))
2662 // this ought to be ignored
2663 return (tree->left);
2666 if (IS_LITERAL(LTYPE(tree)))
2668 werror (E_ILLEGAL_ADDR, "address of literal");
2669 goto errorTreeReturn;
2674 werror (E_LVALUE_REQUIRED, "address of");
2675 goto errorTreeReturn;
2678 DCL_TYPE (p) = POINTER;
2679 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2680 DCL_TYPE (p) = CPOINTER;
2681 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2682 DCL_TYPE (p) = FPOINTER;
2683 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2684 DCL_TYPE (p) = PPOINTER;
2685 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2686 DCL_TYPE (p) = IPOINTER;
2687 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2688 DCL_TYPE (p) = EEPPOINTER;
2689 else if (SPEC_OCLS(tree->left->etype))
2690 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2692 DCL_TYPE (p) = POINTER;
2694 if (IS_AST_SYM_VALUE (tree->left))
2696 AST_SYMBOL (tree->left)->addrtaken = 1;
2697 AST_SYMBOL (tree->left)->allocreq = 1;
2700 p->next = LTYPE (tree);
2702 TETYPE (tree) = getSpec (TTYPE (tree));
2707 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2708 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2710 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2711 AST_SYMBOL(tree->left->right));
2712 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2713 valueFromLit(element->offset));
2716 tree->type = EX_VALUE;
2717 tree->values.literalFromCast = 1;
2723 /*------------------------------------------------------------------*/
2724 /*----------------------------*/
2726 /*----------------------------*/
2728 /* if the rewrite succeeds then don't go any furthur */
2730 ast *wtree = optimizeRRCRLC (tree);
2732 return decorateType (wtree, RESULT_TYPE_NONE);
2734 wtree = optimizeSWAP (tree);
2736 return decorateType (wtree, RESULT_TYPE_NONE);
2739 /* if left is a literal exchange left & right */
2740 if (IS_LITERAL (LTYPE (tree)))
2742 ast *tTree = tree->left;
2743 tree->left = tree->right;
2744 tree->right = tTree;
2747 /* if right is a literal and */
2748 /* we can find a 2nd literal in an or-tree then */
2749 /* rearrange the tree */
2750 if (IS_LITERAL (RTYPE (tree)))
2753 ast *litTree = searchLitOp (tree, &parent, "|");
2757 ast *tTree = litTree->left;
2758 litTree->left = tree->right;
2759 tree->right = tTree;
2760 /* both operands in tTree are literal now */
2761 decorateType (parent, resultType);
2766 /*------------------------------------------------------------------*/
2767 /*----------------------------*/
2769 /*----------------------------*/
2771 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2773 werror (E_BITWISE_OP);
2774 werror (W_CONTINUE, "left & right types are ");
2775 printTypeChain (LTYPE (tree), stderr);
2776 fprintf (stderr, ",");
2777 printTypeChain (RTYPE (tree), stderr);
2778 fprintf (stderr, "\n");
2779 goto errorTreeReturn;
2782 /* if they are both literal then rewrite the tree */
2783 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2785 tree->type = EX_VALUE;
2786 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2787 valFromType (RETYPE (tree)),
2789 tree->right = tree->left = NULL;
2790 TETYPE (tree) = tree->opval.val->etype;
2791 TTYPE (tree) = tree->opval.val->type;
2795 /* if left is a literal exchange left & right */
2796 if (IS_LITERAL (LTYPE (tree)))
2798 ast *tTree = tree->left;
2799 tree->left = tree->right;
2800 tree->right = tTree;
2803 /* if right is a literal and */
2804 /* we can find a 2nd literal in a xor-tree then */
2805 /* rearrange the tree */
2806 if (IS_LITERAL (RTYPE (tree)) &&
2807 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2810 ast *litTree = searchLitOp (tree, &parent, "^");
2814 ast *tTree = litTree->left;
2815 litTree->left = tree->right;
2816 tree->right = tTree;
2817 /* both operands in litTree are literal now */
2818 decorateType (parent, resultType);
2822 LRVAL (tree) = RRVAL (tree) = 1;
2824 TTYPE (tree) = computeType (LTYPE (tree),
2828 TETYPE (tree) = getSpec (TTYPE (tree));
2832 /*------------------------------------------------------------------*/
2833 /*----------------------------*/
2835 /*----------------------------*/
2837 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2839 werror (E_INVALID_OP, "divide");
2840 goto errorTreeReturn;
2842 /* if they are both literal then */
2843 /* rewrite the tree */
2844 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2846 tree->type = EX_VALUE;
2847 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2848 valFromType (RETYPE (tree)));
2849 tree->right = tree->left = NULL;
2850 TETYPE (tree) = getSpec (TTYPE (tree) =
2851 tree->opval.val->type);
2855 LRVAL (tree) = RRVAL (tree) = 1;
2857 TETYPE (tree) = getSpec (TTYPE (tree) =
2858 computeType (LTYPE (tree),
2863 /* if right is a literal and */
2864 /* left is also a division by a literal then */
2865 /* rearrange the tree */
2866 if (IS_LITERAL (RTYPE (tree))
2867 /* avoid infinite loop */
2868 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2871 ast *litTree = searchLitOp (tree, &parent, "/");
2874 if (IS_LITERAL (RTYPE (litTree)))
2878 litTree->right = newNode ('*',
2880 copyAst (tree->right));
2881 litTree->right->lineno = tree->lineno;
2883 tree->right->opval.val = constVal ("1");
2884 decorateType (parent, resultType);
2888 /* litTree->left is literal: no gcse possible.
2889 We can't call decorateType(parent, RESULT_TYPE_NONE), because
2890 this would cause an infinit loop. */
2891 parent->decorated = 1;
2892 decorateType (litTree, resultType);
2899 /*------------------------------------------------------------------*/
2900 /*----------------------------*/
2902 /*----------------------------*/
2904 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2906 werror (E_BITWISE_OP);
2907 werror (W_CONTINUE, "left & right types are ");
2908 printTypeChain (LTYPE (tree), stderr);
2909 fprintf (stderr, ",");
2910 printTypeChain (RTYPE (tree), stderr);
2911 fprintf (stderr, "\n");
2912 goto errorTreeReturn;
2914 /* if they are both literal then */
2915 /* rewrite the tree */
2916 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2918 tree->type = EX_VALUE;
2919 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2920 valFromType (RETYPE (tree)));
2921 tree->right = tree->left = NULL;
2922 TETYPE (tree) = getSpec (TTYPE (tree) =
2923 tree->opval.val->type);
2926 LRVAL (tree) = RRVAL (tree) = 1;
2927 TETYPE (tree) = getSpec (TTYPE (tree) =
2928 computeType (LTYPE (tree),
2934 /*------------------------------------------------------------------*/
2935 /*----------------------------*/
2936 /* address dereference */
2937 /*----------------------------*/
2938 case '*': /* can be unary : if right is null then unary operation */
2941 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2943 werror (E_PTR_REQD);
2944 goto errorTreeReturn;
2949 werror (E_LVALUE_REQUIRED, "pointer deref");
2950 goto errorTreeReturn;
2952 if (IS_ADDRESS_OF_OP(tree->left))
2954 /* replace *&obj with obj */
2955 return tree->left->left;
2957 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2958 TETYPE (tree) = getSpec (TTYPE (tree));
2959 /* adjust the storage class */
2960 switch (DCL_TYPE(tree->left->ftype)) {
2962 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2965 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2968 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2971 SPEC_SCLS (TETYPE (tree)) = 0;
2974 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2977 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2980 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2983 SPEC_SCLS (TETYPE (tree)) = 0;
2992 /*------------------------------------------------------------------*/
2993 /*----------------------------*/
2994 /* multiplication */
2995 /*----------------------------*/
2996 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2998 werror (E_INVALID_OP, "multiplication");
2999 goto errorTreeReturn;
3002 /* if they are both literal then */
3003 /* rewrite the tree */
3004 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3006 tree->type = EX_VALUE;
3007 tree->opval.val = valMult (valFromType (LETYPE (tree)),
3008 valFromType (RETYPE (tree)));
3009 tree->right = tree->left = NULL;
3010 TETYPE (tree) = getSpec (TTYPE (tree) =
3011 tree->opval.val->type);
3015 /* if left is a literal exchange left & right */
3016 if (IS_LITERAL (LTYPE (tree)))
3018 ast *tTree = tree->left;
3019 tree->left = tree->right;
3020 tree->right = tTree;
3023 /* if right is a literal and */
3024 /* we can find a 2nd literal in a mul-tree then */
3025 /* rearrange the tree */
3026 if (IS_LITERAL (RTYPE (tree)))
3029 ast *litTree = searchLitOp (tree, &parent, "*");
3033 ast *tTree = litTree->left;
3034 litTree->left = tree->right;
3035 tree->right = tTree;
3036 /* both operands in litTree are literal now */
3037 decorateType (parent, resultType);
3041 LRVAL (tree) = RRVAL (tree) = 1;
3042 tree->left = addCast (tree->left, resultType, FALSE);
3043 tree->right = addCast (tree->right, resultType, FALSE);
3044 TETYPE (tree) = getSpec (TTYPE (tree) =
3045 computeType (LTYPE (tree),
3052 /*------------------------------------------------------------------*/
3053 /*----------------------------*/
3054 /* unary '+' operator */
3055 /*----------------------------*/
3060 if (!IS_ARITHMETIC (LTYPE (tree)))
3062 werror (E_UNARY_OP, '+');
3063 goto errorTreeReturn;
3066 /* if left is a literal then do it */
3067 if (IS_LITERAL (LTYPE (tree)))
3069 tree->type = EX_VALUE;
3070 tree->opval.val = valFromType (LETYPE (tree));
3072 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3076 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3080 /*------------------------------------------------------------------*/
3081 /*----------------------------*/
3083 /*----------------------------*/
3085 /* this is not a unary operation */
3086 /* if both pointers then problem */
3087 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3088 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3090 werror (E_PTR_PLUS_PTR);
3091 goto errorTreeReturn;
3094 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3095 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3097 werror (E_PLUS_INVALID, "+");
3098 goto errorTreeReturn;
3101 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3102 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3104 werror (E_PLUS_INVALID, "+");
3105 goto errorTreeReturn;
3107 /* if they are both literal then */
3108 /* rewrite the tree */
3109 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3111 tree->type = EX_VALUE;
3112 tree->left = addCast (tree->left, resultType, TRUE);
3113 tree->right = addCast (tree->right, resultType, TRUE);
3114 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3115 valFromType (RETYPE (tree)));
3116 tree->right = tree->left = NULL;
3117 TETYPE (tree) = getSpec (TTYPE (tree) =
3118 tree->opval.val->type);
3122 /* if the right is a pointer or left is a literal
3123 xchange left & right */
3124 if (IS_ARRAY (RTYPE (tree)) ||
3125 IS_PTR (RTYPE (tree)) ||
3126 IS_LITERAL (LTYPE (tree)))
3128 ast *tTree = tree->left;
3129 tree->left = tree->right;
3130 tree->right = tTree;
3133 /* if right is a literal and */
3134 /* left is also an addition/subtraction with a literal then */
3135 /* rearrange the tree */
3136 if (IS_LITERAL (RTYPE (tree)))
3138 ast *litTree, *parent;
3139 litTree = searchLitOp (tree, &parent, "+-");
3142 if (litTree->opval.op == '+')
3146 ast *tTree = litTree->left;
3147 litTree->left = tree->right;
3148 tree->right = tree->left;
3151 else if (litTree->opval.op == '-')
3153 if (IS_LITERAL (RTYPE (litTree)))
3157 ast *tTree = litTree->left;
3158 litTree->left = tree->right;
3159 tree->right = tTree;
3165 ast *tTree = litTree->right;
3166 litTree->right = tree->right;
3167 tree->right = tTree;
3168 litTree->opval.op = '+';
3169 tree->opval.op = '-';
3172 decorateType (parent, resultType);
3176 LRVAL (tree) = RRVAL (tree) = 1;
3177 /* if the left is a pointer */
3178 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3179 TETYPE (tree) = getSpec (TTYPE (tree) =
3183 tree->left = addCast (tree->left, resultType, TRUE);
3184 tree->right = addCast (tree->right, resultType, TRUE);
3185 TETYPE (tree) = getSpec (TTYPE (tree) =
3186 computeType (LTYPE (tree),
3194 /*------------------------------------------------------------------*/
3195 /*----------------------------*/
3197 /*----------------------------*/
3198 case '-': /* can be unary */
3199 /* if right is null then unary */
3203 if (!IS_ARITHMETIC (LTYPE (tree)))
3205 werror (E_UNARY_OP, tree->opval.op);
3206 goto errorTreeReturn;
3209 /* if left is a literal then do it */
3210 if (IS_LITERAL (LTYPE (tree)))
3212 tree->type = EX_VALUE;
3213 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3215 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3216 SPEC_USIGN(TETYPE(tree)) = 0;
3220 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3224 /*------------------------------------------------------------------*/
3225 /*----------------------------*/
3227 /*----------------------------*/
3229 if (!(IS_PTR (LTYPE (tree)) ||
3230 IS_ARRAY (LTYPE (tree)) ||
3231 IS_ARITHMETIC (LTYPE (tree))))
3233 werror (E_PLUS_INVALID, "-");
3234 goto errorTreeReturn;
3237 if (!(IS_PTR (RTYPE (tree)) ||
3238 IS_ARRAY (RTYPE (tree)) ||
3239 IS_ARITHMETIC (RTYPE (tree))))
3241 werror (E_PLUS_INVALID, "-");
3242 goto errorTreeReturn;
3245 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3246 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3247 IS_INTEGRAL (RTYPE (tree))))
3249 werror (E_PLUS_INVALID, "-");
3250 goto errorTreeReturn;
3253 /* if they are both literal then */
3254 /* rewrite the tree */
3255 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3257 tree->type = EX_VALUE;
3258 tree->left = addCast (tree->left, resultType, TRUE);
3259 tree->right = addCast (tree->right, resultType, TRUE);
3260 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3261 valFromType (RETYPE (tree)));
3262 tree->right = tree->left = NULL;
3263 TETYPE (tree) = getSpec (TTYPE (tree) =
3264 tree->opval.val->type);
3268 /* if the left & right are equal then zero */
3269 if (isAstEqual (tree->left, tree->right))
3271 tree->type = EX_VALUE;
3272 tree->left = tree->right = NULL;
3273 tree->opval.val = constVal ("0");
3274 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3278 /* if both of them are pointers or arrays then */
3279 /* the result is going to be an integer */
3280 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3281 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3282 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3284 /* if only the left is a pointer */
3285 /* then result is a pointer */
3286 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3287 TETYPE (tree) = getSpec (TTYPE (tree) =
3291 tree->left = addCast (tree->left, resultType, TRUE);
3292 tree->right = addCast (tree->right, resultType, TRUE);
3294 TETYPE (tree) = getSpec (TTYPE (tree) =
3295 computeType (LTYPE (tree),
3301 LRVAL (tree) = RRVAL (tree) = 1;
3303 /* if right is a literal and */
3304 /* left is also an addition/subtraction with a literal then */
3305 /* rearrange the tree */
3306 if (IS_LITERAL (RTYPE (tree))
3307 /* avoid infinite loop */
3308 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3310 ast *litTree, *litParent;
3311 litTree = searchLitOp (tree, &litParent, "+-");
3314 if (litTree->opval.op == '+')
3318 ast *tTree = litTree->left;
3319 litTree->left = litTree->right;
3320 litTree->right = tree->right;
3321 tree->right = tTree;
3322 tree->opval.op = '+';
3323 litTree->opval.op = '-';
3325 else if (litTree->opval.op == '-')
3327 if (IS_LITERAL (RTYPE (litTree)))
3331 ast *tTree = litTree->left;
3332 litTree->left = tree->right;
3333 tree->right = litParent->left;
3334 litParent->left = tTree;
3335 litTree->opval.op = '+';
3337 tree->decorated = 0;
3338 decorateType (tree, resultType);
3344 ast *tTree = litTree->right;
3345 litTree->right = tree->right;
3346 tree->right = tTree;
3349 decorateType (litParent, resultType);
3354 /*------------------------------------------------------------------*/
3355 /*----------------------------*/
3357 /*----------------------------*/
3359 /* can be only integral type */
3360 if (!IS_INTEGRAL (LTYPE (tree)))
3362 werror (E_UNARY_OP, tree->opval.op);
3363 goto errorTreeReturn;
3366 /* if left is a literal then do it */
3367 if (IS_LITERAL (LTYPE (tree)))
3369 tree->type = EX_VALUE;
3370 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3372 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3373 return addCast (tree, resultType, TRUE);
3375 tree->left = addCast (tree->left, resultType, TRUE);
3377 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3380 /*------------------------------------------------------------------*/
3381 /*----------------------------*/
3383 /*----------------------------*/
3385 /* can be pointer */
3386 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3387 !IS_PTR (LTYPE (tree)) &&
3388 !IS_ARRAY (LTYPE (tree)))
3390 werror (E_UNARY_OP, tree->opval.op);
3391 goto errorTreeReturn;
3394 /* if left is a literal then do it */
3395 if (IS_LITERAL (LTYPE (tree)))
3397 tree->type = EX_VALUE;
3398 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3400 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3404 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3407 /*------------------------------------------------------------------*/
3408 /*----------------------------*/
3410 /*----------------------------*/
3414 TTYPE (tree) = LTYPE (tree);
3415 TETYPE (tree) = LETYPE (tree);
3419 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3424 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3426 werror (E_SHIFT_OP_INVALID);
3427 werror (W_CONTINUE, "left & right types are ");
3428 printTypeChain (LTYPE (tree), stderr);
3429 fprintf (stderr, ",");
3430 printTypeChain (RTYPE (tree), stderr);
3431 fprintf (stderr, "\n");
3432 goto errorTreeReturn;
3435 /* make smaller type only if it's a LEFT_OP */
3436 if (tree->opval.op == LEFT_OP)
3437 tree->left = addCast (tree->left, resultType, TRUE);
3439 /* if they are both literal then */
3440 /* rewrite the tree */
3441 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3443 tree->type = EX_VALUE;
3444 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3445 valFromType (RETYPE (tree)),
3446 (tree->opval.op == LEFT_OP ? 1 : 0));
3447 tree->right = tree->left = NULL;
3448 TETYPE (tree) = getSpec (TTYPE (tree) =
3449 tree->opval.val->type);
3453 LRVAL (tree) = RRVAL (tree) = 1;
3454 if (tree->opval.op == LEFT_OP)
3456 TETYPE (tree) = getSpec (TTYPE (tree) =
3457 computeType (LTYPE (tree),
3464 /* no promotion necessary */
3465 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3466 if (IS_LITERAL (TTYPE (tree)))
3467 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3470 /* if only the right side is a literal & we are
3471 shifting more than size of the left operand then zero */
3472 if (IS_LITERAL (RTYPE (tree)) &&
3473 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3474 (getSize (TETYPE (tree)) * 8))
3476 if (tree->opval.op==LEFT_OP ||
3477 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3479 lineno=tree->lineno;
3480 werror (W_SHIFT_CHANGED,
3481 (tree->opval.op == LEFT_OP ? "left" : "right"));
3482 tree->type = EX_VALUE;
3483 tree->left = tree->right = NULL;
3484 tree->opval.val = constVal ("0");
3485 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3492 /*------------------------------------------------------------------*/
3493 /*----------------------------*/
3495 /*----------------------------*/
3496 case CAST: /* change the type */
3497 /* cannot cast to an aggregate type */
3498 if (IS_AGGREGATE (LTYPE (tree)))
3500 werror (E_CAST_ILLEGAL);
3501 goto errorTreeReturn;
3504 /* make sure the type is complete and sane */
3505 changePointer(LTYPE(tree));
3506 checkTypeSanity(LETYPE(tree), "(cast)");
3508 /* If code memory is read only, then pointers to code memory */
3509 /* implicitly point to constants -- make this explicit */
3511 sym_link *t = LTYPE(tree);
3512 while (t && t->next)
3514 if (IS_CODEPTR(t) && port->mem.code_ro)
3516 if (IS_SPEC(t->next))
3517 SPEC_CONST (t->next) = 1;
3519 DCL_PTR_CONST (t->next) = 1;
3526 /* if the right is a literal replace the tree */
3527 if (IS_LITERAL (RETYPE (tree))) {
3528 if (!IS_PTR (LTYPE (tree))) {
3529 tree->type = EX_VALUE;
3531 valCastLiteral (LTYPE (tree),
3532 floatFromVal (valFromType (RETYPE (tree))));
3535 TTYPE (tree) = tree->opval.val->type;
3536 tree->values.literalFromCast = 1;
3537 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3538 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3539 sym_link *rest = LTYPE(tree)->next;
3540 werror(W_LITERAL_GENERIC);
3541 TTYPE(tree) = newLink(DECLARATOR);
3542 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3543 TTYPE(tree)->next = rest;
3544 tree->left->opval.lnk = TTYPE(tree);
3547 TTYPE (tree) = LTYPE (tree);
3551 TTYPE (tree) = LTYPE (tree);
3555 #if 0 // this is already checked, now this could be explicit
3556 /* if pointer to struct then check names */
3557 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3558 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3559 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3561 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3562 SPEC_STRUCT(LETYPE(tree))->tag);
3565 if (IS_ADDRESS_OF_OP(tree->right)
3566 && IS_AST_SYM_VALUE (tree->right->left)
3567 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3569 symbol * sym = AST_SYMBOL (tree->right->left);
3570 unsigned int gptype = 0;
3571 unsigned int addr = SPEC_ADDR (sym->etype);
3573 if (IS_GENPTR (LTYPE (tree)) && GPTRSIZE > FPTRSIZE)
3575 switch (SPEC_SCLS (sym->etype))
3578 gptype = GPTYPE_CODE;
3581 gptype = GPTYPE_FAR;
3584 gptype = GPTYPE_NEAR;
3587 gptype = GPTYPE_IDATA;
3590 gptype = GPTYPE_XSTACK;
3595 addr |= gptype << (8*(GPTRSIZE - 1));
3598 tree->type = EX_VALUE;
3600 valCastLiteral (LTYPE (tree), addr);
3601 TTYPE (tree) = tree->opval.val->type;
3602 TETYPE (tree) = getSpec (TTYPE (tree));
3605 tree->values.literalFromCast = 1;
3609 /* handle offsetof macro: */
3610 /* #define offsetof(TYPE, MEMBER) \ */
3611 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3612 if (IS_ADDRESS_OF_OP(tree->right)
3613 && IS_AST_OP (tree->right->left)
3614 && tree->right->left->opval.op == PTR_OP
3615 && IS_AST_OP (tree->right->left->left)
3616 && tree->right->left->left->opval.op == CAST
3617 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3619 symbol *element = getStructElement (
3620 SPEC_STRUCT (LETYPE(tree->right->left)),
3621 AST_SYMBOL(tree->right->left->right)
3625 tree->type = EX_VALUE;
3626 tree->opval.val = valCastLiteral (
3629 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3632 TTYPE (tree) = tree->opval.val->type;
3633 TETYPE (tree) = getSpec (TTYPE (tree));
3640 /* if the right is a literal replace the tree */
3641 if (IS_LITERAL (RETYPE (tree))) {
3643 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3644 /* rewrite (type *)litaddr
3646 and define type at litaddr temp
3647 (but only if type's storage class is not generic)
3649 ast *newTree = newNode ('&', NULL, NULL);
3652 TTYPE (newTree) = LTYPE (tree);
3653 TETYPE (newTree) = getSpec(LTYPE (tree));
3655 /* define a global symbol at the casted address*/
3656 sym = newSymbol(genSymName (0), 0);
3657 sym->type = LTYPE (tree)->next;
3659 sym->type = newLink (V_VOID);
3660 sym->etype = getSpec(sym->type);
3661 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3662 sym->lineDef = tree->lineno;
3665 SPEC_STAT (sym->etype) = 1;
3666 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3667 SPEC_ABSA(sym->etype) = 1;
3668 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3671 newTree->left = newAst_VALUE(symbolVal(sym));
3672 newTree->left->lineno = tree->lineno;
3673 LTYPE (newTree) = sym->type;
3674 LETYPE (newTree) = sym->etype;
3675 LLVAL (newTree) = 1;
3676 LRVAL (newTree) = 0;
3677 TLVAL (newTree) = 1;
3681 if (!IS_PTR (LTYPE (tree))) {
3682 tree->type = EX_VALUE;
3684 valCastLiteral (LTYPE (tree),
3685 floatFromVal (valFromType (RTYPE (tree))));
3686 TTYPE (tree) = tree->opval.val->type;
3689 tree->values.literalFromCast = 1;
3690 TETYPE (tree) = getSpec (TTYPE (tree));
3694 TTYPE (tree) = LTYPE (tree);
3698 TETYPE (tree) = getSpec (TTYPE (tree));
3702 /*------------------------------------------------------------------*/
3703 /*----------------------------*/
3704 /* logical &&, || */
3705 /*----------------------------*/
3708 /* each must be arithmetic type or be a pointer */
3709 if (!IS_PTR (LTYPE (tree)) &&
3710 !IS_ARRAY (LTYPE (tree)) &&
3711 !IS_INTEGRAL (LTYPE (tree)))
3713 werror (E_COMPARE_OP);
3714 goto errorTreeReturn;
3717 if (!IS_PTR (RTYPE (tree)) &&
3718 !IS_ARRAY (RTYPE (tree)) &&
3719 !IS_INTEGRAL (RTYPE (tree)))
3721 werror (E_COMPARE_OP);
3722 goto errorTreeReturn;
3724 /* if they are both literal then */
3725 /* rewrite the tree */
3726 if (IS_LITERAL (RTYPE (tree)) &&
3727 IS_LITERAL (LTYPE (tree)))
3729 tree->type = EX_VALUE;
3730 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3731 valFromType (RTYPE (tree)),
3733 tree->right = tree->left = NULL;
3734 TETYPE (tree) = getSpec (TTYPE (tree) =
3735 tree->opval.val->type);
3738 LRVAL (tree) = RRVAL (tree) = 1;
3739 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3742 /*------------------------------------------------------------------*/
3743 /*----------------------------*/
3744 /* comparison operators */
3745 /*----------------------------*/
3753 ast *lt = optimizeCompare (tree);
3759 /* if they are pointers they must be castable */
3760 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3762 if (tree->opval.op==EQ_OP &&
3763 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3764 // we cannot cast a gptr to a !gptr: switch the leaves
3765 struct ast *s=tree->left;
3766 tree->left=tree->right;
3769 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3771 werror (E_COMPARE_OP);
3772 fprintf (stderr, "comparing type ");
3773 printTypeChain (LTYPE (tree), stderr);
3774 fprintf (stderr, "to type ");
3775 printTypeChain (RTYPE (tree), stderr);
3776 fprintf (stderr, "\n");
3777 goto errorTreeReturn;
3780 /* else they should be promotable to one another */
3783 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3784 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3786 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3788 werror (E_COMPARE_OP);
3789 fprintf (stderr, "comparing type ");
3790 printTypeChain (LTYPE (tree), stderr);
3791 fprintf (stderr, "to type ");
3792 printTypeChain (RTYPE (tree), stderr);
3793 fprintf (stderr, "\n");
3794 goto errorTreeReturn;
3797 /* if unsigned value < 0 then always false */
3798 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3799 if (SPEC_USIGN(LETYPE(tree)) &&
3800 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3801 IS_LITERAL(RTYPE(tree)) &&
3802 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3804 if (tree->opval.op == '<')
3808 if (tree->opval.op == '>')
3810 if (resultType == RESULT_TYPE_IFX)
3812 /* the parent is an ifx: */
3813 /* if (unsigned value) */
3817 /* (unsigned value) ? 1 : 0 */
3818 tree->opval.op = '?';
3819 tree->right = newNode (':',
3820 newAst_VALUE (constVal ("1")),
3821 tree->right); /* val 0 */
3822 tree->right->lineno = tree->lineno;
3823 tree->right->left->lineno = tree->lineno;
3824 decorateType (tree->right, RESULT_TYPE_NONE);
3827 /* if they are both literal then */
3828 /* rewrite the tree */
3829 if (IS_LITERAL (RTYPE (tree)) &&
3830 IS_LITERAL (LTYPE (tree)))
3832 tree->type = EX_VALUE;
3833 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3834 valFromType (RETYPE (tree)),
3836 tree->right = tree->left = NULL;
3837 TETYPE (tree) = getSpec (TTYPE (tree) =
3838 tree->opval.val->type);
3841 LRVAL (tree) = RRVAL (tree) = 1;
3842 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3845 /*------------------------------------------------------------------*/
3846 /*----------------------------*/
3848 /*----------------------------*/
3849 case SIZEOF: /* evaluate wihout code generation */
3850 /* change the type to a integer */
3852 int size = getSize (tree->right->ftype);
3853 SNPRINTF(buffer, sizeof(buffer), "%d", size);
3854 if (!size && !IS_VOID(tree->right->ftype))
3855 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
3857 tree->type = EX_VALUE;
3858 tree->opval.val = constVal (buffer);
3859 tree->right = tree->left = NULL;
3860 TETYPE (tree) = getSpec (TTYPE (tree) =
3861 tree->opval.val->type);
3864 /*------------------------------------------------------------------*/
3865 /*----------------------------*/
3867 /*----------------------------*/
3869 /* return typeof enum value */
3870 tree->type = EX_VALUE;
3873 if (IS_SPEC(tree->right->ftype)) {
3874 switch (SPEC_NOUN(tree->right->ftype)) {
3876 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3877 else typeofv = TYPEOF_INT;
3880 typeofv = TYPEOF_FLOAT;
3883 typeofv = TYPEOF_CHAR;
3886 typeofv = TYPEOF_VOID;
3889 typeofv = TYPEOF_STRUCT;
3892 typeofv = TYPEOF_BITFIELD;
3895 typeofv = TYPEOF_BIT;
3898 typeofv = TYPEOF_SBIT;
3904 switch (DCL_TYPE(tree->right->ftype)) {
3906 typeofv = TYPEOF_POINTER;
3909 typeofv = TYPEOF_FPOINTER;
3912 typeofv = TYPEOF_CPOINTER;
3915 typeofv = TYPEOF_GPOINTER;
3918 typeofv = TYPEOF_PPOINTER;
3921 typeofv = TYPEOF_IPOINTER;
3924 typeofv = TYPEOF_ARRAY;
3927 typeofv = TYPEOF_FUNCTION;
3933 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3934 tree->opval.val = constVal (buffer);
3935 tree->right = tree->left = NULL;
3936 TETYPE (tree) = getSpec (TTYPE (tree) =
3937 tree->opval.val->type);
3940 /*------------------------------------------------------------------*/
3941 /*----------------------------*/
3942 /* conditional operator '?' */
3943 /*----------------------------*/
3945 /* the type is value of the colon operator (on the right) */
3946 assert (IS_COLON_OP (tree->right));
3947 /* if already known then replace the tree : optimizer will do it
3948 but faster to do it here */
3949 if (IS_LITERAL (LTYPE (tree)))
3951 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
3952 return decorateType (tree->right->left, resultTypeProp);
3954 return decorateType (tree->right->right, resultTypeProp);
3958 tree->right = decorateType (tree->right, resultTypeProp);
3959 TTYPE (tree) = RTYPE (tree);
3960 TETYPE (tree) = getSpec (TTYPE (tree));
3965 /* if they don't match we have a problem */
3966 if ((compareType (LTYPE (tree), RTYPE (tree)) == 0) &&
3967 (compareType (RTYPE (tree), LTYPE (tree)) == 0))
3969 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3970 goto errorTreeReturn;
3973 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
3974 resultType, tree->opval.op);
3975 TETYPE (tree) = getSpec (TTYPE (tree));
3979 #if 0 // assignment operators are converted by the parser
3980 /*------------------------------------------------------------------*/
3981 /*----------------------------*/
3982 /* assignment operators */
3983 /*----------------------------*/
3986 /* for these it must be both must be integral */
3987 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3988 !IS_ARITHMETIC (RTYPE (tree)))
3990 werror (E_OPS_INTEGRAL);
3991 goto errorTreeReturn;
3994 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3996 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3997 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4001 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4002 goto errorTreeReturn;
4013 /* for these it must be both must be integral */
4014 if (!IS_INTEGRAL (LTYPE (tree)) ||
4015 !IS_INTEGRAL (RTYPE (tree)))
4017 werror (E_OPS_INTEGRAL);
4018 goto errorTreeReturn;
4021 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4023 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4024 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
4028 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
4029 goto errorTreeReturn;
4035 /*------------------------------------------------------------------*/
4036 /*----------------------------*/
4038 /*----------------------------*/
4040 if (!(IS_PTR (LTYPE (tree)) ||
4041 IS_ARITHMETIC (LTYPE (tree))))
4043 werror (E_PLUS_INVALID, "-=");
4044 goto errorTreeReturn;
4047 if (!(IS_PTR (RTYPE (tree)) ||
4048 IS_ARITHMETIC (RTYPE (tree))))
4050 werror (E_PLUS_INVALID, "-=");
4051 goto errorTreeReturn;
4054 TETYPE (tree) = getSpec (TTYPE (tree) =
4055 computeType (LTYPE (tree),
4060 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4061 werror (E_CODE_WRITE, "-=");
4065 werror (E_LVALUE_REQUIRED, "-=");
4066 goto errorTreeReturn;
4072 /*------------------------------------------------------------------*/
4073 /*----------------------------*/
4075 /*----------------------------*/
4077 /* this is not a unary operation */
4078 /* if both pointers then problem */
4079 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4081 werror (E_PTR_PLUS_PTR);
4082 goto errorTreeReturn;
4085 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4087 werror (E_PLUS_INVALID, "+=");
4088 goto errorTreeReturn;
4091 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4093 werror (E_PLUS_INVALID, "+=");
4094 goto errorTreeReturn;
4097 TETYPE (tree) = getSpec (TTYPE (tree) =
4098 computeType (LTYPE (tree),
4103 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4104 werror (E_CODE_WRITE, "+=");
4108 werror (E_LVALUE_REQUIRED, "+=");
4109 goto errorTreeReturn;
4112 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE);
4113 tree->opval.op = '=';
4118 /*------------------------------------------------------------------*/
4119 /*----------------------------*/
4120 /* straight assignemnt */
4121 /*----------------------------*/
4123 /* cannot be an aggregate */
4124 if (IS_AGGREGATE (LTYPE (tree)))
4126 werror (E_AGGR_ASSIGN);
4127 goto errorTreeReturn;
4130 /* they should either match or be castable */
4131 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4133 werror (E_TYPE_MISMATCH, "assignment", " ");
4134 printFromToType(RTYPE(tree),LTYPE(tree));
4137 /* if the left side of the tree is of type void
4138 then report error */
4139 if (IS_VOID (LTYPE (tree)))
4141 werror (E_CAST_ZERO);
4142 printFromToType(RTYPE(tree), LTYPE(tree));
4145 TETYPE (tree) = getSpec (TTYPE (tree) =
4149 if (!tree->initMode ) {
4150 if (IS_CONSTANT(LTYPE(tree)))
4151 werror (E_CODE_WRITE, "=");
4155 werror (E_LVALUE_REQUIRED, "=");
4156 goto errorTreeReturn;
4161 /*------------------------------------------------------------------*/
4162 /*----------------------------*/
4163 /* comma operator */
4164 /*----------------------------*/
4166 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4169 /*------------------------------------------------------------------*/
4170 /*----------------------------*/
4172 /*----------------------------*/
4175 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4176 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4178 if (tree->left->opval.op == '*' && !tree->left->right)
4179 tree->left = tree->left->left;
4182 /* require a function or pointer to function */
4183 if (!IS_FUNC (LTYPE (tree))
4184 && !(IS_CODEPTR (LTYPE (tree)) && IS_FUNC (LTYPE (tree)->next)))
4186 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4187 goto errorTreeReturn;
4190 /* if there are parms, make sure that
4191 parms are decorate / process / reverse only once */
4193 !tree->right->decorated)
4198 if (IS_CODEPTR(LTYPE(tree)))
4199 functype = LTYPE (tree)->next;
4201 functype = LTYPE (tree);
4203 if (processParms (tree->left, FUNC_ARGS(functype),
4204 &tree->right, &parmNumber, TRUE))
4206 goto errorTreeReturn;
4209 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4210 !IFFUNC_ISBUILTIN(functype))
4212 reverseParms (tree->right);
4215 TTYPE (tree) = functype->next;
4216 TETYPE (tree) = getSpec (TTYPE (tree));
4220 /*------------------------------------------------------------------*/
4221 /*----------------------------*/
4222 /* return statement */
4223 /*----------------------------*/
4228 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4230 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4231 printFromToType (RTYPE(tree), currFunc->type->next);
4232 goto errorTreeReturn;
4235 if (IS_VOID (currFunc->type->next)
4237 !IS_VOID (RTYPE (tree)))
4239 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4240 goto errorTreeReturn;
4243 /* if there is going to be a casting required then add it */
4244 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4247 decorateType (newNode (CAST,
4248 newAst_LINK (copyLinkChain (currFunc->type->next)),
4258 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4260 werror (W_VOID_FUNC, currFunc->name);
4261 goto errorTreeReturn;
4264 TTYPE (tree) = TETYPE (tree) = NULL;
4267 /*------------------------------------------------------------------*/
4268 /*----------------------------*/
4269 /* switch statement */
4270 /*----------------------------*/
4272 /* the switch value must be an integer */
4273 if (!IS_INTEGRAL (LTYPE (tree)))
4275 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4276 goto errorTreeReturn;
4279 TTYPE (tree) = TETYPE (tree) = NULL;
4282 /*------------------------------------------------------------------*/
4283 /*----------------------------*/
4285 /*----------------------------*/
4287 tree->left = backPatchLabels (tree->left,
4290 TTYPE (tree) = TETYPE (tree) = NULL;
4293 /*------------------------------------------------------------------*/
4294 /*----------------------------*/
4296 /*----------------------------*/
4299 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE);
4300 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE);
4301 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE);
4303 /* if the for loop is reversible then
4304 reverse it otherwise do what we normally
4310 if (isLoopReversible (tree, &sym, &init, &end))
4311 return reverseLoop (tree, sym, init, end);
4313 return decorateType (createFor (AST_FOR (tree, trueLabel),
4314 AST_FOR (tree, continueLabel),
4315 AST_FOR (tree, falseLabel),
4316 AST_FOR (tree, condLabel),
4317 AST_FOR (tree, initExpr),
4318 AST_FOR (tree, condExpr),
4319 AST_FOR (tree, loopExpr),
4320 tree->left), RESULT_TYPE_NONE);
4323 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4324 "node PARAM shouldn't be processed here");
4325 /* but in processParams() */
4328 TTYPE (tree) = TETYPE (tree) = NULL;
4332 /* some error found this tree will be killed */
4334 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4335 tree->opval.op = NULLOP;
4341 /*-----------------------------------------------------------------*/
4342 /* sizeofOp - processes size of operation */
4343 /*-----------------------------------------------------------------*/
4345 sizeofOp (sym_link * type)
4350 /* make sure the type is complete and sane */
4351 checkTypeSanity(type, "(sizeof)");
4353 /* get the size and convert it to character */
4354 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4355 if (!size && !IS_VOID(type))
4356 werror (E_SIZEOF_INCOMPLETE_TYPE);
4358 /* now convert into value */
4359 return constVal (buff);
4363 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4364 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4365 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4366 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4367 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4368 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4369 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4371 /*-----------------------------------------------------------------*/
4372 /* backPatchLabels - change and or not operators to flow control */
4373 /*-----------------------------------------------------------------*/
4375 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4381 if (!(IS_ANDORNOT (tree)))
4384 /* if this an and */
4387 static int localLbl = 0;
4390 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4391 localLabel = newSymbol (buffer, NestLevel);
4393 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4395 /* if left is already a IFX then just change the if true label in that */
4396 if (!IS_IFX (tree->left))
4397 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4399 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4400 /* right is a IFX then just join */
4401 if (IS_IFX (tree->right))
4402 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4404 tree->right = createLabel (localLabel, tree->right);
4405 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4407 return newNode (NULLOP, tree->left, tree->right);
4410 /* if this is an or operation */
4413 static int localLbl = 0;
4416 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4417 localLabel = newSymbol (buffer, NestLevel);
4419 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4421 /* if left is already a IFX then just change the if true label in that */
4422 if (!IS_IFX (tree->left))
4423 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4425 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4426 /* right is a IFX then just join */
4427 if (IS_IFX (tree->right))
4428 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4430 tree->right = createLabel (localLabel, tree->right);
4431 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4433 return newNode (NULLOP, tree->left, tree->right);
4439 int wasnot = IS_NOT (tree->left);
4440 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4442 /* if the left is already a IFX */
4443 if (!IS_IFX (tree->left))
4444 tree->left = newNode (IFX, tree->left, NULL);
4448 tree->left->trueLabel = trueLabel;
4449 tree->left->falseLabel = falseLabel;
4453 tree->left->trueLabel = falseLabel;
4454 tree->left->falseLabel = trueLabel;
4461 tree->trueLabel = trueLabel;
4462 tree->falseLabel = falseLabel;
4469 /*-----------------------------------------------------------------*/
4470 /* createBlock - create expression tree for block */
4471 /*-----------------------------------------------------------------*/
4473 createBlock (symbol * decl, ast * body)
4477 /* if the block has nothing */
4481 ex = newNode (BLOCK, NULL, body);
4482 ex->values.sym = decl;
4489 /*-----------------------------------------------------------------*/
4490 /* createLabel - creates the expression tree for labels */
4491 /*-----------------------------------------------------------------*/
4493 createLabel (symbol * label, ast * stmnt)
4496 char name[SDCC_NAME_MAX + 1];
4499 /* must create fresh symbol if the symbol name */
4500 /* exists in the symbol table, since there can */
4501 /* be a variable with the same name as the labl */
4502 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4503 (csym->level == label->level))
4504 label = newSymbol (label->name, label->level);
4506 /* change the name before putting it in add _ */
4507 SNPRINTF(name, sizeof(name), "%s", label->name);
4509 /* put the label in the LabelSymbol table */
4510 /* but first check if a label of the same */
4512 if ((csym = findSym (LabelTab, NULL, name)))
4513 werror (E_DUPLICATE_LABEL, label->name);
4515 addSym (LabelTab, label, name, label->level, 0, 0);
4519 label->key = labelKey++;
4520 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4526 /*-----------------------------------------------------------------*/
4527 /* createCase - generates the parsetree for a case statement */
4528 /*-----------------------------------------------------------------*/
4530 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4532 char caseLbl[SDCC_NAME_MAX + 1];
4536 /* if the switch statement does not exist */
4537 /* then case is out of context */
4540 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4544 caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE);
4545 /* if not a constant then error */
4546 if (!IS_LITERAL (caseVal->ftype))
4548 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4552 /* if not a integer than error */
4553 if (!IS_INTEGRAL (caseVal->ftype))
4555 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4559 /* find the end of the switch values chain */
4560 if (!(val = swStat->values.switchVals.swVals))
4561 swStat->values.switchVals.swVals = caseVal->opval.val;
4564 /* also order the cases according to value */
4566 int cVal = (int) floatFromVal (caseVal->opval.val);
4567 while (val && (int) floatFromVal (val) < cVal)
4573 /* if we reached the end then */
4576 pval->next = caseVal->opval.val;
4578 else if ((int) floatFromVal (val) == cVal)
4580 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4586 /* we found a value greater than */
4587 /* the current value we must add this */
4588 /* before the value */
4589 caseVal->opval.val->next = val;
4591 /* if this was the first in chain */
4592 if (swStat->values.switchVals.swVals == val)
4593 swStat->values.switchVals.swVals =
4596 pval->next = caseVal->opval.val;
4601 /* create the case label */
4602 SNPRINTF(caseLbl, sizeof(caseLbl),
4604 swStat->values.switchVals.swNum,
4605 (int) floatFromVal (caseVal->opval.val));
4607 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4612 /*-----------------------------------------------------------------*/
4613 /* createDefault - creates the parse tree for the default statement */
4614 /*-----------------------------------------------------------------*/
4616 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4618 char defLbl[SDCC_NAME_MAX + 1];
4620 /* if the switch statement does not exist */
4621 /* then case is out of context */
4624 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4628 if (swStat->values.switchVals.swDefault)
4630 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4635 /* turn on the default flag */
4636 swStat->values.switchVals.swDefault = 1;
4638 /* create the label */
4639 SNPRINTF (defLbl, sizeof(defLbl),
4640 "_default_%d", swStat->values.switchVals.swNum);
4641 return createLabel (newSymbol (defLbl, 0), stmnt);
4644 /*-----------------------------------------------------------------*/
4645 /* createIf - creates the parsetree for the if statement */
4646 /*-----------------------------------------------------------------*/
4648 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4650 static int Lblnum = 0;
4652 symbol *ifTrue, *ifFalse, *ifEnd;
4654 /* if neither exists */
4655 if (!elseBody && !ifBody) {
4656 // if there are no side effects (i++, j() etc)
4657 if (!hasSEFcalls(condAst)) {
4662 /* create the labels */
4663 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4664 ifFalse = newSymbol (buffer, NestLevel);
4665 /* if no else body then end == false */
4670 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4671 ifEnd = newSymbol (buffer, NestLevel);
4674 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4675 ifTrue = newSymbol (buffer, NestLevel);
4679 /* attach the ifTrue label to the top of it body */
4680 ifBody = createLabel (ifTrue, ifBody);
4681 /* attach a goto end to the ifBody if else is present */
4684 ifBody = newNode (NULLOP, ifBody,
4686 newAst_VALUE (symbolVal (ifEnd)),
4688 /* put the elseLabel on the else body */
4689 elseBody = createLabel (ifFalse, elseBody);
4690 /* out the end at the end of the body */
4691 elseBody = newNode (NULLOP,
4693 createLabel (ifEnd, NULL));
4697 ifBody = newNode (NULLOP, ifBody,
4698 createLabel (ifFalse, NULL));
4700 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4701 if (IS_IFX (condAst))
4704 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4706 return newNode (NULLOP, ifTree,
4707 newNode (NULLOP, ifBody, elseBody));
4711 /*-----------------------------------------------------------------*/
4712 /* createDo - creates parse tree for do */
4715 /* _docontinue_n: */
4716 /* condition_expression +-> trueLabel -> _dobody_n */
4718 /* +-> falseLabel-> _dobreak_n */
4720 /*-----------------------------------------------------------------*/
4722 createDo (symbol * trueLabel, symbol * continueLabel,
4723 symbol * falseLabel, ast * condAst, ast * doBody)
4728 /* if the body does not exist then it is simple */
4731 condAst = backPatchLabels (condAst, continueLabel, NULL);
4732 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4733 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4734 doTree->trueLabel = continueLabel;
4735 doTree->falseLabel = NULL;
4739 /* otherwise we have a body */
4740 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4742 /* attach the body label to the top */
4743 doBody = createLabel (trueLabel, doBody);
4744 /* attach the continue label to end of body */
4745 doBody = newNode (NULLOP, doBody,
4746 createLabel (continueLabel, NULL));
4748 /* now put the break label at the end */
4749 if (IS_IFX (condAst))
4752 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4754 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4756 /* putting it together */
4757 return newNode (NULLOP, doBody, doTree);
4760 /*-----------------------------------------------------------------*/
4761 /* createFor - creates parse tree for 'for' statement */
4764 /* condExpr +-> trueLabel -> _forbody_n */
4766 /* +-> falseLabel-> _forbreak_n */
4769 /* _forcontinue_n: */
4771 /* goto _forcond_n ; */
4773 /*-----------------------------------------------------------------*/
4775 createFor (symbol * trueLabel, symbol * continueLabel,
4776 symbol * falseLabel, symbol * condLabel,
4777 ast * initExpr, ast * condExpr, ast * loopExpr,
4782 /* if loopexpression not present then we can generate it */
4783 /* the same way as a while */
4785 return newNode (NULLOP, initExpr,
4786 createWhile (trueLabel, continueLabel,
4787 falseLabel, condExpr, forBody));
4788 /* vanilla for statement */
4789 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4791 if (condExpr && !IS_IFX (condExpr))
4792 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4795 /* attach condition label to condition */
4796 condExpr = createLabel (condLabel, condExpr);
4798 /* attach body label to body */
4799 forBody = createLabel (trueLabel, forBody);
4801 /* attach continue to forLoop expression & attach */
4802 /* goto the forcond @ and of loopExpression */
4803 loopExpr = createLabel (continueLabel,
4807 newAst_VALUE (symbolVal (condLabel)),
4809 /* now start putting them together */
4810 forTree = newNode (NULLOP, initExpr, condExpr);
4811 forTree = newNode (NULLOP, forTree, forBody);
4812 forTree = newNode (NULLOP, forTree, loopExpr);
4813 /* finally add the break label */
4814 forTree = newNode (NULLOP, forTree,
4815 createLabel (falseLabel, NULL));
4819 /*-----------------------------------------------------------------*/
4820 /* createWhile - creates parse tree for while statement */
4821 /* the while statement will be created as follows */
4823 /* _while_continue_n: */
4824 /* condition_expression +-> trueLabel -> _while_boby_n */
4826 /* +-> falseLabel -> _while_break_n */
4827 /* _while_body_n: */
4829 /* goto _while_continue_n */
4830 /* _while_break_n: */
4831 /*-----------------------------------------------------------------*/
4833 createWhile (symbol * trueLabel, symbol * continueLabel,
4834 symbol * falseLabel, ast * condExpr, ast * whileBody)
4838 /* put the continue label */
4839 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4840 condExpr = createLabel (continueLabel, condExpr);
4841 condExpr->lineno = 0;
4843 /* put the body label in front of the body */
4844 whileBody = createLabel (trueLabel, whileBody);
4845 whileBody->lineno = 0;
4846 /* put a jump to continue at the end of the body */
4847 /* and put break label at the end of the body */
4848 whileBody = newNode (NULLOP,
4851 newAst_VALUE (symbolVal (continueLabel)),
4852 createLabel (falseLabel, NULL)));
4854 /* put it all together */
4855 if (IS_IFX (condExpr))
4856 whileTree = condExpr;
4859 whileTree = newNode (IFX, condExpr, NULL);
4860 /* put the true & false labels in place */
4861 whileTree->trueLabel = trueLabel;
4862 whileTree->falseLabel = falseLabel;
4865 return newNode (NULLOP, whileTree, whileBody);
4868 /*-----------------------------------------------------------------*/
4869 /* optimizeGetHbit - get highest order bit of the expression */
4870 /*-----------------------------------------------------------------*/
4872 optimizeGetHbit (ast * tree)
4875 /* if this is not a bit and */
4876 if (!IS_BITAND (tree))
4879 /* will look for tree of the form
4880 ( expr >> ((sizeof expr) -1) ) & 1 */
4881 if (!IS_AST_LIT_VALUE (tree->right))
4884 if (AST_LIT_VALUE (tree->right) != 1)
4887 if (!IS_RIGHT_OP (tree->left))
4890 if (!IS_AST_LIT_VALUE (tree->left->right))
4893 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4894 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4897 /* make sure the port supports GETHBIT */
4898 if (port->hasExtBitOp
4899 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4902 return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_TYPE_NONE);
4906 /*-----------------------------------------------------------------*/
4907 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4908 /*-----------------------------------------------------------------*/
4910 optimizeRRCRLC (ast * root)
4912 /* will look for trees of the form
4913 (?expr << 1) | (?expr >> 7) or
4914 (?expr >> 7) | (?expr << 1) will make that
4915 into a RLC : operation ..
4917 (?expr >> 1) | (?expr << 7) or
4918 (?expr << 7) | (?expr >> 1) will make that
4919 into a RRC operation
4920 note : by 7 I mean (number of bits required to hold the
4922 /* if the root operations is not a | operation the not */
4923 if (!IS_BITOR (root))
4926 /* I have to think of a better way to match patterns this sucks */
4927 /* that aside let start looking for the first case : I use a the
4928 negative check a lot to improve the efficiency */
4929 /* (?expr << 1) | (?expr >> 7) */
4930 if (IS_LEFT_OP (root->left) &&
4931 IS_RIGHT_OP (root->right))
4934 if (!SPEC_USIGN (TETYPE (root->left->left)))
4937 if (!IS_AST_LIT_VALUE (root->left->right) ||
4938 !IS_AST_LIT_VALUE (root->right->right))
4941 /* make sure it is the same expression */
4942 if (!isAstEqual (root->left->left,
4946 if (AST_LIT_VALUE (root->left->right) != 1)
4949 if (AST_LIT_VALUE (root->right->right) !=
4950 (getSize (TTYPE (root->left->left)) * 8 - 1))
4953 /* make sure the port supports RLC */
4954 if (port->hasExtBitOp
4955 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4958 /* whew got the first case : create the AST */
4959 return newNode (RLC, root->left->left, NULL);
4963 /* check for second case */
4964 /* (?expr >> 7) | (?expr << 1) */
4965 if (IS_LEFT_OP (root->right) &&
4966 IS_RIGHT_OP (root->left))
4969 if (!SPEC_USIGN (TETYPE (root->left->left)))
4972 if (!IS_AST_LIT_VALUE (root->left->right) ||
4973 !IS_AST_LIT_VALUE (root->right->right))
4976 /* make sure it is the same symbol */
4977 if (!isAstEqual (root->left->left,
4981 if (AST_LIT_VALUE (root->right->right) != 1)
4984 if (AST_LIT_VALUE (root->left->right) !=
4985 (getSize (TTYPE (root->left->left)) * 8 - 1))
4988 /* make sure the port supports RLC */
4989 if (port->hasExtBitOp
4990 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4993 /* whew got the first case : create the AST */
4994 return newNode (RLC, root->left->left, NULL);
4999 /* third case for RRC */
5000 /* (?symbol >> 1) | (?symbol << 7) */
5001 if (IS_LEFT_OP (root->right) &&
5002 IS_RIGHT_OP (root->left))
5005 if (!SPEC_USIGN (TETYPE (root->left->left)))
5008 if (!IS_AST_LIT_VALUE (root->left->right) ||
5009 !IS_AST_LIT_VALUE (root->right->right))
5012 /* make sure it is the same symbol */
5013 if (!isAstEqual (root->left->left,
5017 if (AST_LIT_VALUE (root->left->right) != 1)
5020 if (AST_LIT_VALUE (root->right->right) !=
5021 (getSize (TTYPE (root->left->left)) * 8 - 1))
5024 /* make sure the port supports RRC */
5025 if (port->hasExtBitOp
5026 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5029 /* whew got the first case : create the AST */
5030 return newNode (RRC, root->left->left, NULL);
5034 /* fourth and last case for now */
5035 /* (?symbol << 7) | (?symbol >> 1) */
5036 if (IS_RIGHT_OP (root->right) &&
5037 IS_LEFT_OP (root->left))
5040 if (!SPEC_USIGN (TETYPE (root->left->left)))
5043 if (!IS_AST_LIT_VALUE (root->left->right) ||
5044 !IS_AST_LIT_VALUE (root->right->right))
5047 /* make sure it is the same symbol */
5048 if (!isAstEqual (root->left->left,
5052 if (AST_LIT_VALUE (root->right->right) != 1)
5055 if (AST_LIT_VALUE (root->left->right) !=
5056 (getSize (TTYPE (root->left->left)) * 8 - 1))
5059 /* make sure the port supports RRC */
5060 if (port->hasExtBitOp
5061 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5064 /* whew got the first case : create the AST */
5065 return newNode (RRC, root->left->left, NULL);
5069 /* not found return root */
5073 /*-----------------------------------------------------------------*/
5074 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
5075 /*-----------------------------------------------------------------*/
5077 optimizeSWAP (ast * root)
5079 /* will look for trees of the form
5080 (?expr << 4) | (?expr >> 4) or
5081 (?expr >> 4) | (?expr << 4) will make that
5082 into a SWAP : operation ..
5083 note : by 4 I mean (number of bits required to hold the
5085 /* if the root operations is not a | operation the not */
5086 if (!IS_BITOR (root))
5089 /* (?expr << 4) | (?expr >> 4) */
5090 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5091 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5094 if (!SPEC_USIGN (TETYPE (root->left->left)))
5097 if (!IS_AST_LIT_VALUE (root->left->right) ||
5098 !IS_AST_LIT_VALUE (root->right->right))
5101 /* make sure it is the same expression */
5102 if (!isAstEqual (root->left->left,
5106 if (AST_LIT_VALUE (root->left->right) !=
5107 (getSize (TTYPE (root->left->left)) * 4))
5110 if (AST_LIT_VALUE (root->right->right) !=
5111 (getSize (TTYPE (root->left->left)) * 4))
5114 /* make sure the port supports SWAP */
5115 if (port->hasExtBitOp
5116 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5119 /* found it : create the AST */
5120 return newNode (SWAP, root->left->left, NULL);
5124 /* not found return root */
5128 /*-----------------------------------------------------------------*/
5129 /* optimizeCompare - otimizes compares for bit variables */
5130 /*-----------------------------------------------------------------*/
5132 optimizeCompare (ast * root)
5134 ast *optExpr = NULL;
5137 unsigned int litValue;
5139 /* if nothing then return nothing */
5143 /* if not a compare op then do leaves */
5144 if (!IS_COMPARE_OP (root))
5146 root->left = optimizeCompare (root->left);
5147 root->right = optimizeCompare (root->right);
5151 /* if left & right are the same then depending
5152 of the operation do */
5153 if (isAstEqual (root->left, root->right))
5155 switch (root->opval.op)
5160 optExpr = newAst_VALUE (constVal ("0"));
5165 optExpr = newAst_VALUE (constVal ("1"));
5169 return decorateType (optExpr, RESULT_TYPE_NONE);
5172 vleft = (root->left->type == EX_VALUE ?
5173 root->left->opval.val : NULL);
5175 vright = (root->right->type == EX_VALUE ?
5176 root->right->opval.val : NULL);
5178 /* if left is a BITVAR in BITSPACE */
5179 /* and right is a LITERAL then opt- */
5180 /* imize else do nothing */
5181 if (vleft && vright &&
5182 IS_BITVAR (vleft->etype) &&
5183 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5184 IS_LITERAL (vright->etype))
5187 /* if right side > 1 then comparison may never succeed */
5188 if ((litValue = (int) floatFromVal (vright)) > 1)
5190 werror (W_BAD_COMPARE);
5196 switch (root->opval.op)
5198 case '>': /* bit value greater than 1 cannot be */
5199 werror (W_BAD_COMPARE);
5203 case '<': /* bit value < 1 means 0 */
5205 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5208 case LE_OP: /* bit value <= 1 means no check */
5209 optExpr = newAst_VALUE (vright);
5212 case GE_OP: /* bit value >= 1 means only check for = */
5214 optExpr = newAst_VALUE (vleft);
5219 { /* literal is zero */
5220 switch (root->opval.op)
5222 case '<': /* bit value < 0 cannot be */
5223 werror (W_BAD_COMPARE);
5227 case '>': /* bit value > 0 means 1 */
5229 optExpr = newAst_VALUE (vleft);
5232 case LE_OP: /* bit value <= 0 means no check */
5233 case GE_OP: /* bit value >= 0 means no check */
5234 werror (W_BAD_COMPARE);
5238 case EQ_OP: /* bit == 0 means ! of bit */
5239 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5243 return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE);
5244 } /* end-of-if of BITVAR */
5249 /*-----------------------------------------------------------------*/
5250 /* addSymToBlock : adds the symbol to the first block we find */
5251 /*-----------------------------------------------------------------*/
5253 addSymToBlock (symbol * sym, ast * tree)
5255 /* reached end of tree or a leaf */
5256 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5260 if (IS_AST_OP (tree) &&
5261 tree->opval.op == BLOCK)
5264 symbol *lsym = copySymbol (sym);
5266 lsym->next = AST_VALUES (tree, sym);
5267 AST_VALUES (tree, sym) = lsym;
5271 addSymToBlock (sym, tree->left);
5272 addSymToBlock (sym, tree->right);
5275 /*-----------------------------------------------------------------*/
5276 /* processRegParms - do processing for register parameters */
5277 /*-----------------------------------------------------------------*/
5279 processRegParms (value * args, ast * body)
5283 if (IS_REGPARM (args->etype))
5284 addSymToBlock (args->sym, body);
5289 /*-----------------------------------------------------------------*/
5290 /* resetParmKey - resets the operandkeys for the symbols */
5291 /*-----------------------------------------------------------------*/
5292 DEFSETFUNC (resetParmKey)
5303 /*-----------------------------------------------------------------*/
5304 /* createFunction - This is the key node that calls the iCode for */
5305 /* generating the code for a function. Note code */
5306 /* is generated function by function, later when */
5307 /* add inter-procedural analysis this will change */
5308 /*-----------------------------------------------------------------*/
5310 createFunction (symbol * name, ast * body)
5316 iCode *piCode = NULL;
5318 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5319 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5321 /* if check function return 0 then some problem */
5322 if (checkFunction (name, NULL) == 0)
5325 /* create a dummy block if none exists */
5327 body = newNode (BLOCK, NULL, NULL);
5331 /* check if the function name already in the symbol table */
5332 if ((csym = findSym (SymbolTab, NULL, name->name)))
5335 /* special case for compiler defined functions
5336 we need to add the name to the publics list : this
5337 actually means we are now compiling the compiler
5341 addSet (&publics, name);
5347 allocVariables (name);
5349 name->lastLine = mylineno;
5352 /* set the stack pointer */
5353 stackPtr = -port->stack.direction * port->stack.call_overhead;
5354 xstackPtr = -port->stack.direction * port->stack.call_overhead;
5356 if (IFFUNC_ISISR (name->type))
5357 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5359 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5361 if (options.useXstack)
5362 xstackPtr -= port->stack.direction * port->stack.reent_overhead;
5364 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5367 fetype = getSpec (name->type); /* get the specifier for the function */
5368 /* if this is a reentrant function then */
5369 if (IFFUNC_ISREENT (name->type))
5372 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5374 /* do processing for parameters that are passed in registers */
5375 processRegParms (FUNC_ARGS(name->type), body);
5377 /* set the stack pointer */
5381 /* allocate & autoinit the block variables */
5382 processBlockVars (body, &stack, ALLOCATE);
5384 /* save the stack information */
5385 if (options.useXstack)
5386 name->xstack = SPEC_STAK (fetype) = stack;
5388 name->stack = SPEC_STAK (fetype) = stack;
5390 /* name needs to be mangled */
5391 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5393 body = resolveSymbols (body); /* resolve the symbols */
5394 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5397 ex = newAst_VALUE (symbolVal (name)); /* create name */
5398 ex = newNode (FUNCTION, ex, body);
5399 ex->values.args = FUNC_ARGS(name->type);
5401 if (options.dump_tree) PA(ex);
5404 werror (E_FUNC_NO_CODE, name->name);
5408 /* create the node & generate intermediate code */
5410 codeOutFile = code->oFile;
5411 piCode = iCodeFromAst (ex);
5415 werror (E_FUNC_NO_CODE, name->name);
5419 eBBlockFromiCode (piCode);
5421 /* if there are any statics then do them */
5424 GcurMemmap = statsg;
5425 codeOutFile = statsg->oFile;
5426 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE)));
5432 /* dealloc the block variables */
5433 processBlockVars (body, &stack, DEALLOCATE);
5434 outputDebugStackSymbols();
5435 /* deallocate paramaters */
5436 deallocParms (FUNC_ARGS(name->type));
5438 if (IFFUNC_ISREENT (name->type))
5441 /* we are done freeup memory & cleanup */
5443 if (port->reset_labelKey) labelKey = 1;
5445 FUNC_HASBODY(name->type) = 1;
5446 addSet (&operKeyReset, name);
5447 applyToSet (operKeyReset, resetParmKey);
5452 cleanUpLevel (LabelTab, 0);
5453 cleanUpBlock (StructTab, 1);
5454 cleanUpBlock (TypedefTab, 1);
5456 xstack->syms = NULL;
5457 istack->syms = NULL;
5462 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5463 /*-----------------------------------------------------------------*/
5464 /* ast_print : prints the ast (for debugging purposes) */
5465 /*-----------------------------------------------------------------*/
5467 void ast_print (ast * tree, FILE *outfile, int indent)
5472 /* can print only decorated trees */
5473 if (!tree->decorated) return;
5475 /* if any child is an error | this one is an error do nothing */
5476 if (tree->isError ||
5477 (tree->left && tree->left->isError) ||
5478 (tree->right && tree->right->isError)) {
5479 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5483 /* print the line */
5484 /* if not block & function */
5485 if (tree->type == EX_OP &&
5486 (tree->opval.op != FUNCTION &&
5487 tree->opval.op != BLOCK &&
5488 tree->opval.op != NULLOP)) {
5491 if (tree->opval.op == FUNCTION) {
5493 value *args=FUNC_ARGS(tree->left->opval.val->type);
5494 fprintf(outfile,"FUNCTION (%s=%p) type (",
5495 tree->left->opval.val->name, tree);
5496 printTypeChain (tree->left->opval.val->type->next,outfile);
5497 fprintf(outfile,") args (");
5500 fprintf (outfile, ", ");
5502 printTypeChain (args ? args->type : NULL, outfile);
5504 args= args ? args->next : NULL;
5506 fprintf(outfile,")\n");
5507 ast_print(tree->left,outfile,indent);
5508 ast_print(tree->right,outfile,indent);
5511 if (tree->opval.op == BLOCK) {
5512 symbol *decls = tree->values.sym;
5513 INDENT(indent,outfile);
5514 fprintf(outfile,"{\n");
5516 INDENT(indent+2,outfile);
5517 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5518 decls->name, decls);
5519 printTypeChain(decls->type,outfile);
5520 fprintf(outfile,")\n");
5522 decls = decls->next;
5524 ast_print(tree->right,outfile,indent+2);
5525 INDENT(indent,outfile);
5526 fprintf(outfile,"}\n");
5529 if (tree->opval.op == NULLOP) {
5530 ast_print(tree->left,outfile,indent);
5531 ast_print(tree->right,outfile,indent);
5534 INDENT(indent,outfile);
5536 /*------------------------------------------------------------------*/
5537 /*----------------------------*/
5538 /* leaf has been reached */
5539 /*----------------------------*/
5540 /* if this is of type value */
5541 /* just get the type */
5542 if (tree->type == EX_VALUE) {
5544 if (IS_LITERAL (tree->opval.val->etype)) {
5545 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5546 if (SPEC_USIGN (tree->opval.val->etype))
5547 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5549 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5550 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5551 floatFromVal(tree->opval.val));
5552 } else if (tree->opval.val->sym) {
5553 /* if the undefined flag is set then give error message */
5554 if (tree->opval.val->sym->undefined) {
5555 fprintf(outfile,"UNDEFINED SYMBOL ");
5557 fprintf(outfile,"SYMBOL ");
5559 fprintf(outfile,"(%s=%p)",
5560 tree->opval.val->sym->name,tree);
5563 fprintf(outfile," type (");
5564 printTypeChain(tree->ftype,outfile);
5565 fprintf(outfile,")\n");
5567 fprintf(outfile,"\n");
5572 /* if type link for the case of cast */
5573 if (tree->type == EX_LINK) {
5574 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5575 printTypeChain(tree->opval.lnk,outfile);
5576 fprintf(outfile,")\n");
5581 /* depending on type of operator do */
5583 switch (tree->opval.op) {
5584 /*------------------------------------------------------------------*/
5585 /*----------------------------*/
5587 /*----------------------------*/
5589 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5590 printTypeChain(tree->ftype,outfile);
5591 fprintf(outfile,")\n");
5592 ast_print(tree->left,outfile,indent+2);
5593 ast_print(tree->right,outfile,indent+2);
5596 /*------------------------------------------------------------------*/
5597 /*----------------------------*/
5599 /*----------------------------*/
5601 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5602 printTypeChain(tree->ftype,outfile);
5603 fprintf(outfile,")\n");
5604 ast_print(tree->left,outfile,indent+2);
5605 ast_print(tree->right,outfile,indent+2);
5608 /*------------------------------------------------------------------*/
5609 /*----------------------------*/
5610 /* struct/union pointer */
5611 /*----------------------------*/
5613 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5614 printTypeChain(tree->ftype,outfile);
5615 fprintf(outfile,")\n");
5616 ast_print(tree->left,outfile,indent+2);
5617 ast_print(tree->right,outfile,indent+2);
5620 /*------------------------------------------------------------------*/
5621 /*----------------------------*/
5622 /* ++/-- operation */
5623 /*----------------------------*/
5626 fprintf(outfile,"post-");
5628 fprintf(outfile,"pre-");
5629 fprintf(outfile,"INC_OP (%p) type (",tree);
5630 printTypeChain(tree->ftype,outfile);
5631 fprintf(outfile,")\n");
5632 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5633 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5638 fprintf(outfile,"post-");
5640 fprintf(outfile,"pre-");
5641 fprintf(outfile,"DEC_OP (%p) type (",tree);
5642 printTypeChain(tree->ftype,outfile);
5643 fprintf(outfile,")\n");
5644 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5645 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5648 /*------------------------------------------------------------------*/
5649 /*----------------------------*/
5651 /*----------------------------*/
5654 fprintf(outfile,"& (%p) type (",tree);
5655 printTypeChain(tree->ftype,outfile);
5656 fprintf(outfile,")\n");
5657 ast_print(tree->left,outfile,indent+2);
5658 ast_print(tree->right,outfile,indent+2);
5660 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5661 printTypeChain(tree->ftype,outfile);
5662 fprintf(outfile,")\n");
5663 ast_print(tree->left,outfile,indent+2);
5664 ast_print(tree->right,outfile,indent+2);
5667 /*----------------------------*/
5669 /*----------------------------*/
5671 fprintf(outfile,"OR (%p) type (",tree);
5672 printTypeChain(tree->ftype,outfile);
5673 fprintf(outfile,")\n");
5674 ast_print(tree->left,outfile,indent+2);
5675 ast_print(tree->right,outfile,indent+2);
5677 /*------------------------------------------------------------------*/
5678 /*----------------------------*/
5680 /*----------------------------*/
5682 fprintf(outfile,"XOR (%p) type (",tree);
5683 printTypeChain(tree->ftype,outfile);
5684 fprintf(outfile,")\n");
5685 ast_print(tree->left,outfile,indent+2);
5686 ast_print(tree->right,outfile,indent+2);
5689 /*------------------------------------------------------------------*/
5690 /*----------------------------*/
5692 /*----------------------------*/
5694 fprintf(outfile,"DIV (%p) type (",tree);
5695 printTypeChain(tree->ftype,outfile);
5696 fprintf(outfile,")\n");
5697 ast_print(tree->left,outfile,indent+2);
5698 ast_print(tree->right,outfile,indent+2);
5700 /*------------------------------------------------------------------*/
5701 /*----------------------------*/
5703 /*----------------------------*/
5705 fprintf(outfile,"MOD (%p) type (",tree);
5706 printTypeChain(tree->ftype,outfile);
5707 fprintf(outfile,")\n");
5708 ast_print(tree->left,outfile,indent+2);
5709 ast_print(tree->right,outfile,indent+2);
5712 /*------------------------------------------------------------------*/
5713 /*----------------------------*/
5714 /* address dereference */
5715 /*----------------------------*/
5716 case '*': /* can be unary : if right is null then unary operation */
5718 fprintf(outfile,"DEREF (%p) type (",tree);
5719 printTypeChain(tree->ftype,outfile);
5720 fprintf(outfile,")\n");
5721 ast_print(tree->left,outfile,indent+2);
5724 /*------------------------------------------------------------------*/
5725 /*----------------------------*/
5726 /* multiplication */
5727 /*----------------------------*/
5728 fprintf(outfile,"MULT (%p) type (",tree);
5729 printTypeChain(tree->ftype,outfile);
5730 fprintf(outfile,")\n");
5731 ast_print(tree->left,outfile,indent+2);
5732 ast_print(tree->right,outfile,indent+2);
5736 /*------------------------------------------------------------------*/
5737 /*----------------------------*/
5738 /* unary '+' operator */
5739 /*----------------------------*/
5743 fprintf(outfile,"UPLUS (%p) type (",tree);
5744 printTypeChain(tree->ftype,outfile);
5745 fprintf(outfile,")\n");
5746 ast_print(tree->left,outfile,indent+2);
5748 /*------------------------------------------------------------------*/
5749 /*----------------------------*/
5751 /*----------------------------*/
5752 fprintf(outfile,"ADD (%p) type (",tree);
5753 printTypeChain(tree->ftype,outfile);
5754 fprintf(outfile,")\n");
5755 ast_print(tree->left,outfile,indent+2);
5756 ast_print(tree->right,outfile,indent+2);
5759 /*------------------------------------------------------------------*/
5760 /*----------------------------*/
5762 /*----------------------------*/
5763 case '-': /* can be unary */
5765 fprintf(outfile,"UMINUS (%p) type (",tree);
5766 printTypeChain(tree->ftype,outfile);
5767 fprintf(outfile,")\n");
5768 ast_print(tree->left,outfile,indent+2);
5770 /*------------------------------------------------------------------*/
5771 /*----------------------------*/
5773 /*----------------------------*/
5774 fprintf(outfile,"SUB (%p) type (",tree);
5775 printTypeChain(tree->ftype,outfile);
5776 fprintf(outfile,")\n");
5777 ast_print(tree->left,outfile,indent+2);
5778 ast_print(tree->right,outfile,indent+2);
5781 /*------------------------------------------------------------------*/
5782 /*----------------------------*/
5784 /*----------------------------*/
5786 fprintf(outfile,"COMPL (%p) type (",tree);
5787 printTypeChain(tree->ftype,outfile);
5788 fprintf(outfile,")\n");
5789 ast_print(tree->left,outfile,indent+2);
5791 /*------------------------------------------------------------------*/
5792 /*----------------------------*/
5794 /*----------------------------*/
5796 fprintf(outfile,"NOT (%p) type (",tree);
5797 printTypeChain(tree->ftype,outfile);
5798 fprintf(outfile,")\n");
5799 ast_print(tree->left,outfile,indent+2);
5801 /*------------------------------------------------------------------*/
5802 /*----------------------------*/
5804 /*----------------------------*/
5806 fprintf(outfile,"RRC (%p) type (",tree);
5807 printTypeChain(tree->ftype,outfile);
5808 fprintf(outfile,")\n");
5809 ast_print(tree->left,outfile,indent+2);
5813 fprintf(outfile,"RLC (%p) type (",tree);
5814 printTypeChain(tree->ftype,outfile);
5815 fprintf(outfile,")\n");
5816 ast_print(tree->left,outfile,indent+2);
5819 fprintf(outfile,"SWAP (%p) type (",tree);
5820 printTypeChain(tree->ftype,outfile);
5821 fprintf(outfile,")\n");
5822 ast_print(tree->left,outfile,indent+2);
5825 fprintf(outfile,"GETHBIT (%p) type (",tree);
5826 printTypeChain(tree->ftype,outfile);
5827 fprintf(outfile,")\n");
5828 ast_print(tree->left,outfile,indent+2);
5831 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5832 printTypeChain(tree->ftype,outfile);
5833 fprintf(outfile,")\n");
5834 ast_print(tree->left,outfile,indent+2);
5835 ast_print(tree->right,outfile,indent+2);
5838 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5839 printTypeChain(tree->ftype,outfile);
5840 fprintf(outfile,")\n");
5841 ast_print(tree->left,outfile,indent+2);
5842 ast_print(tree->right,outfile,indent+2);
5844 /*------------------------------------------------------------------*/
5845 /*----------------------------*/
5847 /*----------------------------*/
5848 case CAST: /* change the type */
5849 fprintf(outfile,"CAST (%p) from type (",tree);
5850 printTypeChain(tree->right->ftype,outfile);
5851 fprintf(outfile,") to type (");
5852 printTypeChain(tree->ftype,outfile);
5853 fprintf(outfile,")\n");
5854 ast_print(tree->right,outfile,indent+2);
5858 fprintf(outfile,"ANDAND (%p) type (",tree);
5859 printTypeChain(tree->ftype,outfile);
5860 fprintf(outfile,")\n");
5861 ast_print(tree->left,outfile,indent+2);
5862 ast_print(tree->right,outfile,indent+2);
5865 fprintf(outfile,"OROR (%p) type (",tree);
5866 printTypeChain(tree->ftype,outfile);
5867 fprintf(outfile,")\n");
5868 ast_print(tree->left,outfile,indent+2);
5869 ast_print(tree->right,outfile,indent+2);
5872 /*------------------------------------------------------------------*/
5873 /*----------------------------*/
5874 /* comparison operators */
5875 /*----------------------------*/
5877 fprintf(outfile,"GT(>) (%p) type (",tree);
5878 printTypeChain(tree->ftype,outfile);
5879 fprintf(outfile,")\n");
5880 ast_print(tree->left,outfile,indent+2);
5881 ast_print(tree->right,outfile,indent+2);
5884 fprintf(outfile,"LT(<) (%p) type (",tree);
5885 printTypeChain(tree->ftype,outfile);
5886 fprintf(outfile,")\n");
5887 ast_print(tree->left,outfile,indent+2);
5888 ast_print(tree->right,outfile,indent+2);
5891 fprintf(outfile,"LE(<=) (%p) type (",tree);
5892 printTypeChain(tree->ftype,outfile);
5893 fprintf(outfile,")\n");
5894 ast_print(tree->left,outfile,indent+2);
5895 ast_print(tree->right,outfile,indent+2);
5898 fprintf(outfile,"GE(>=) (%p) type (",tree);
5899 printTypeChain(tree->ftype,outfile);
5900 fprintf(outfile,")\n");
5901 ast_print(tree->left,outfile,indent+2);
5902 ast_print(tree->right,outfile,indent+2);
5905 fprintf(outfile,"EQ(==) (%p) type (",tree);
5906 printTypeChain(tree->ftype,outfile);
5907 fprintf(outfile,")\n");
5908 ast_print(tree->left,outfile,indent+2);
5909 ast_print(tree->right,outfile,indent+2);
5912 fprintf(outfile,"NE(!=) (%p) type (",tree);
5913 printTypeChain(tree->ftype,outfile);
5914 fprintf(outfile,")\n");
5915 ast_print(tree->left,outfile,indent+2);
5916 ast_print(tree->right,outfile,indent+2);
5917 /*------------------------------------------------------------------*/
5918 /*----------------------------*/
5920 /*----------------------------*/
5921 case SIZEOF: /* evaluate wihout code generation */
5922 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5925 /*------------------------------------------------------------------*/
5926 /*----------------------------*/
5927 /* conditional operator '?' */
5928 /*----------------------------*/
5930 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5931 printTypeChain(tree->ftype,outfile);
5932 fprintf(outfile,")\n");
5933 ast_print(tree->left,outfile,indent+2);
5934 ast_print(tree->right,outfile,indent+2);
5938 fprintf(outfile,"COLON(:) (%p) type (",tree);
5939 printTypeChain(tree->ftype,outfile);
5940 fprintf(outfile,")\n");
5941 ast_print(tree->left,outfile,indent+2);
5942 ast_print(tree->right,outfile,indent+2);
5945 /*------------------------------------------------------------------*/
5946 /*----------------------------*/
5947 /* assignment operators */
5948 /*----------------------------*/
5950 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5951 printTypeChain(tree->ftype,outfile);
5952 fprintf(outfile,")\n");
5953 ast_print(tree->left,outfile,indent+2);
5954 ast_print(tree->right,outfile,indent+2);
5957 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5958 printTypeChain(tree->ftype,outfile);
5959 fprintf(outfile,")\n");
5960 ast_print(tree->left,outfile,indent+2);
5961 ast_print(tree->right,outfile,indent+2);
5964 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5965 printTypeChain(tree->ftype,outfile);
5966 fprintf(outfile,")\n");
5967 ast_print(tree->left,outfile,indent+2);
5968 ast_print(tree->right,outfile,indent+2);
5971 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5972 printTypeChain(tree->ftype,outfile);
5973 fprintf(outfile,")\n");
5974 ast_print(tree->left,outfile,indent+2);
5975 ast_print(tree->right,outfile,indent+2);
5978 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5979 printTypeChain(tree->ftype,outfile);
5980 fprintf(outfile,")\n");
5981 ast_print(tree->left,outfile,indent+2);
5982 ast_print(tree->right,outfile,indent+2);
5985 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5986 printTypeChain(tree->ftype,outfile);
5987 fprintf(outfile,")\n");
5988 ast_print(tree->left,outfile,indent+2);
5989 ast_print(tree->right,outfile,indent+2);
5992 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5993 printTypeChain(tree->ftype,outfile);
5994 fprintf(outfile,")\n");
5995 ast_print(tree->left,outfile,indent+2);
5996 ast_print(tree->right,outfile,indent+2);
5998 /*------------------------------------------------------------------*/
5999 /*----------------------------*/
6001 /*----------------------------*/
6003 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
6004 printTypeChain(tree->ftype,outfile);
6005 fprintf(outfile,")\n");
6006 ast_print(tree->left,outfile,indent+2);
6007 ast_print(tree->right,outfile,indent+2);
6009 /*------------------------------------------------------------------*/
6010 /*----------------------------*/
6012 /*----------------------------*/
6014 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
6015 printTypeChain(tree->ftype,outfile);
6016 fprintf(outfile,")\n");
6017 ast_print(tree->left,outfile,indent+2);
6018 ast_print(tree->right,outfile,indent+2);
6020 /*------------------------------------------------------------------*/
6021 /*----------------------------*/
6022 /* straight assignemnt */
6023 /*----------------------------*/
6025 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
6026 printTypeChain(tree->ftype,outfile);
6027 fprintf(outfile,")\n");
6028 ast_print(tree->left,outfile,indent+2);
6029 ast_print(tree->right,outfile,indent+2);
6031 /*------------------------------------------------------------------*/
6032 /*----------------------------*/
6033 /* comma operator */
6034 /*----------------------------*/
6036 fprintf(outfile,"COMMA(,) (%p) type (",tree);
6037 printTypeChain(tree->ftype,outfile);
6038 fprintf(outfile,")\n");
6039 ast_print(tree->left,outfile,indent+2);
6040 ast_print(tree->right,outfile,indent+2);
6042 /*------------------------------------------------------------------*/
6043 /*----------------------------*/
6045 /*----------------------------*/
6048 fprintf(outfile,"CALL (%p) type (",tree);
6049 printTypeChain(tree->ftype,outfile);
6050 fprintf(outfile,")\n");
6051 ast_print(tree->left,outfile,indent+2);
6052 ast_print(tree->right,outfile,indent+2);
6055 fprintf(outfile,"PARMS\n");
6056 ast_print(tree->left,outfile,indent+2);
6057 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
6058 ast_print(tree->right,outfile,indent+2);
6061 /*------------------------------------------------------------------*/
6062 /*----------------------------*/
6063 /* return statement */
6064 /*----------------------------*/
6066 fprintf(outfile,"RETURN (%p) type (",tree);
6068 printTypeChain(tree->right->ftype,outfile);
6070 fprintf(outfile,")\n");
6071 ast_print(tree->right,outfile,indent+2);
6073 /*------------------------------------------------------------------*/
6074 /*----------------------------*/
6075 /* label statement */
6076 /*----------------------------*/
6078 fprintf(outfile,"LABEL (%p)\n",tree);
6079 ast_print(tree->left,outfile,indent+2);
6080 ast_print(tree->right,outfile,indent);
6082 /*------------------------------------------------------------------*/
6083 /*----------------------------*/
6084 /* switch statement */
6085 /*----------------------------*/
6089 fprintf(outfile,"SWITCH (%p) ",tree);
6090 ast_print(tree->left,outfile,0);
6091 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
6092 INDENT(indent+2,outfile);
6093 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
6094 (int) floatFromVal(val),
6095 tree->values.switchVals.swNum,
6096 (int) floatFromVal(val));
6098 ast_print(tree->right,outfile,indent);
6101 /*------------------------------------------------------------------*/
6102 /*----------------------------*/
6104 /*----------------------------*/
6106 fprintf(outfile,"IF (%p) \n",tree);
6107 ast_print(tree->left,outfile,indent+2);
6108 if (tree->trueLabel) {
6109 INDENT(indent+2,outfile);
6110 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
6112 if (tree->falseLabel) {
6113 INDENT(indent+2,outfile);
6114 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
6116 ast_print(tree->right,outfile,indent+2);
6118 /*----------------------------*/
6119 /* goto Statement */
6120 /*----------------------------*/
6122 fprintf(outfile,"GOTO (%p) \n",tree);
6123 ast_print(tree->left,outfile,indent+2);
6124 fprintf(outfile,"\n");
6126 /*------------------------------------------------------------------*/
6127 /*----------------------------*/
6129 /*----------------------------*/
6131 fprintf(outfile,"FOR (%p) \n",tree);
6132 if (AST_FOR( tree, initExpr)) {
6133 INDENT(indent+2,outfile);
6134 fprintf(outfile,"INIT EXPR ");
6135 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6137 if (AST_FOR( tree, condExpr)) {
6138 INDENT(indent+2,outfile);
6139 fprintf(outfile,"COND EXPR ");
6140 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6142 if (AST_FOR( tree, loopExpr)) {
6143 INDENT(indent+2,outfile);
6144 fprintf(outfile,"LOOP EXPR ");
6145 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6147 fprintf(outfile,"FOR LOOP BODY \n");
6148 ast_print(tree->left,outfile,indent+2);
6151 fprintf(outfile,"CRITICAL (%p) \n",tree);
6152 ast_print(tree->left,outfile,indent+2);
6160 ast_print(t,stdout,0);
6165 /*-----------------------------------------------------------------*/
6166 /* astErrors : returns non-zero if errors present in tree */
6167 /*-----------------------------------------------------------------*/
6168 int astErrors(ast *t)
6177 if (t->type == EX_VALUE
6178 && t->opval.val->sym
6179 && t->opval.val->sym->undefined)
6182 errors += astErrors(t->left);
6183 errors += astErrors(t->right);